diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 000000000..adaa4f55f --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,17 @@ +language: "zh-CN" +reviews: + profile: "chill" + request_changes_workflow: false + high_level_summary: true + poem: false + review_status: true + collapse_walkthrough: true + path_instructions: + - path: "apps/web-antd/**" + instructions: "重点关注业务回归风险、路由权限、表单校验和上传逻辑。" + - path: "packages/**" + instructions: "重点关注公共 API 兼容性、类型安全、以及潜在破坏性变更。" + - path: "**/*.md" + instructions: "文档变更只做简要建议,不阻断。" +chat: + auto_reply: false diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 000000000..759b63648 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,48 @@ +docs: + - changed-files: + - any-glob-to-any-file: + - 'docs/**' + - 'README*' + - '**/*.md' + +ci: + - changed-files: + - any-glob-to-any-file: + - '.github/workflows/**' + - '.github/*.yml' + - '.github/*.yaml' + +web-antd: + - changed-files: + - any-glob-to-any-file: + - 'apps/web-antd/**' + +backend-mock: + - changed-files: + - any-glob-to-any-file: + - 'apps/backend-mock/**' + +packages: + - changed-files: + - any-glob-to-any-file: + - 'packages/**' + +internal: + - changed-files: + - any-glob-to-any-file: + - 'internal/**' + +scripts: + - changed-files: + - any-glob-to-any-file: + - 'scripts/**' + +config: + - changed-files: + - any-glob-to-any-file: + - 'package.json' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - 'turbo.json' + - 'tsconfig*.json' + - '.npmrc' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 000000000..3356d26b7 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,19 @@ +name: PR Labeler + +on: + pull_request_target: + branches: ["dev"] + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + +jobs: + label: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + configuration-path: .github/labeler.yml diff --git a/README.md b/README.md index 09c7177e3..c16c7c76d 100644 --- a/README.md +++ b/README.md @@ -86,10 +86,6 @@ pnpm install 参考 [菜单图标替换](https://dapdap.top/guide/quick-start.html#%E8%8F%9C%E5%8D%95%E5%9B%BE%E6%A0%87%E5%AF%BC%E5%85%A5) -- 关于代码生成 - -V5版本代码生成模板为付费功能 [详见](https://dapdap.top/other/template.html) - - 关于一些监控的地址配置(微服务版本可以跳过这一小节) 使用[RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus/tree/5.X/)注意 `已经去除 admin/snailjob 的.env 配置` 可自行修改 有两种方式 diff --git a/apps/web-antd/src/adapter/component/index.ts b/apps/web-antd/src/adapter/component/index.ts index ac8b74cdf..11edf6b53 100644 --- a/apps/web-antd/src/adapter/component/index.ts +++ b/apps/web-antd/src/adapter/component/index.ts @@ -3,60 +3,94 @@ * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, */ -import type { Component } from "vue"; +import type { Component } from 'vue'; -import type { BaseFormComponentType } from "@vben/common-ui"; -import type { Recordable } from "@vben/types"; +import type { BaseFormComponentType } from '@vben/common-ui'; +import type { Recordable } from '@vben/types'; -import { computed, defineAsyncComponent, defineComponent, h, ref } from "vue"; +import { computed, defineAsyncComponent, defineComponent, h, ref } from 'vue'; -import { ApiComponent, globalShareState, IconPicker } from "@vben/common-ui"; -import { $t } from "@vben/locales"; +import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; +import { $t } from '@vben/locales'; const RichTextarea = defineAsyncComponent(() => - import("#/components/tinymce/index").then((res) => res.Tinymce), + import('#/components/tinymce/index').then((res) => res.Tinymce), ); const FileUpload = defineAsyncComponent(() => - import("#/components/upload").then((res) => res.FileUpload), + import('#/components/upload').then((res) => res.FileUpload), ); const ImageUpload = defineAsyncComponent(() => - import("#/components/upload").then((res) => res.ImageUpload), + import('#/components/upload').then((res) => res.ImageUpload), ); -const Button = defineAsyncComponent(() => import("antdv-next/dist/button/index")); -const Cascader = defineAsyncComponent(() => import("antdv-next/dist/cascader/index")); -const Checkbox = defineAsyncComponent(() => import("antdv-next/dist/checkbox/index")); -const CheckboxGroup = defineAsyncComponent(() => import("antdv-next/dist/checkbox/Group")); -const DatePicker = defineAsyncComponent(() => import("antdv-next/dist/date-picker/index")); -const Divider = defineAsyncComponent(() => import("antdv-next/dist/divider/index")); -const Input = defineAsyncComponent(() => import("antdv-next/dist/input/index")); -const InputNumber = defineAsyncComponent(() => import("antdv-next/dist/input-number/index")); -const InputPassword = defineAsyncComponent(() => import("antdv-next/dist/input/Password")); -const Mentions = defineAsyncComponent(() => import("antdv-next/dist/mentions/index")); -const Radio = defineAsyncComponent(() => import("antdv-next/dist/radio/index")); +const Button = defineAsyncComponent( + () => import('antdv-next/dist/button/index'), +); +const Cascader = defineAsyncComponent( + () => import('antdv-next/dist/cascader/index'), +); +const Checkbox = defineAsyncComponent( + () => import('antdv-next/dist/checkbox/index'), +); +const CheckboxGroup = defineAsyncComponent( + () => import('antdv-next/dist/checkbox/Group'), +); +const DatePicker = defineAsyncComponent( + () => import('antdv-next/dist/date-picker/index'), +); +const Divider = defineAsyncComponent( + () => import('antdv-next/dist/divider/index'), +); +const Input = defineAsyncComponent(() => import('antdv-next/dist/input/index')); +const InputNumber = defineAsyncComponent( + () => import('antdv-next/dist/input-number/index'), +); +const InputPassword = defineAsyncComponent( + () => import('antdv-next/dist/input/Password'), +); +const Mentions = defineAsyncComponent( + () => import('antdv-next/dist/mentions/index'), +); +const Radio = defineAsyncComponent(() => import('antdv-next/dist/radio/index')); const RadioGroup = defineAsyncComponent(() => - import("antdv-next/dist/radio/index").then((res) => res.RadioGroup), + import('antdv-next/dist/radio/index').then((res) => res.RadioGroup), ); const RangePicker = defineAsyncComponent(() => - import("antdv-next/dist/date-picker/index").then((res) => res.DateRangePicker), + import('antdv-next/dist/date-picker/index').then( + (res) => res.DateRangePicker, + ), +); +const Rate = defineAsyncComponent(() => import('antdv-next/dist/rate/index')); +const Select = defineAsyncComponent( + () => import('antdv-next/dist/select/index'), +); +const Space = defineAsyncComponent(() => import('antdv-next/dist/space/index')); +const Switch = defineAsyncComponent( + () => import('antdv-next/dist/switch/index'), +); +const Textarea = defineAsyncComponent( + () => import('antdv-next/dist/input/TextArea'), +); +const TimePicker = defineAsyncComponent( + () => import('antdv-next/dist/time-picker/index'), ); -const Rate = defineAsyncComponent(() => import("antdv-next/dist/rate/index")); -const Select = defineAsyncComponent(() => import("antdv-next/dist/select/index")); -const Space = defineAsyncComponent(() => import("antdv-next/dist/space/index")); -const Switch = defineAsyncComponent(() => import("antdv-next/dist/switch/index")); -const Textarea = defineAsyncComponent(() => import("antdv-next/dist/input/TextArea")); -const TimePicker = defineAsyncComponent(() => import("antdv-next/dist/time-picker/index")); const TimeRangePicker = defineAsyncComponent(() => - import("antdv-next/dist/time-picker/index").then((res) => res.TimeRangePicker), + import('antdv-next/dist/time-picker/index').then( + (res) => res.TimeRangePicker, + ), +); +const TreeSelect = defineAsyncComponent( + () => import('antdv-next/dist/tree-select/index'), +); +const Upload = defineAsyncComponent( + () => import('antdv-next/dist/upload/Upload'), ); -const TreeSelect = defineAsyncComponent(() => import("antdv-next/dist/tree-select/index")); -const Upload = defineAsyncComponent(() => import("antdv-next/dist/upload/Upload")); const withDefaultPlaceholder = ( component: T, - type: "input" | "select", + type: 'input' | 'select', componentProps: Recordable = {}, ) => { return defineComponent({ @@ -65,7 +99,10 @@ const withDefaultPlaceholder = ( setup: (props: any, { attrs, expose, slots }) => { // 改为placeholder 解决在keepalive & 语言切换 & tab切换 显示不变的问题 const computedPlaceholder = computed( - () => props?.placeholder || attrs?.placeholder || $t(`ui.placeholder.${type}`), + () => + props?.placeholder || + attrs?.placeholder || + $t(`ui.placeholder.${type}`), ); // 透传组件暴露的方法 @@ -97,37 +134,37 @@ const withDefaultPlaceholder = ( // 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 export type ComponentType = - | "ApiCascader" - | "ApiSelect" - | "ApiTreeSelect" - | "AutoComplete" - | "Cascader" - | "Checkbox" - | "CheckboxGroup" - | "DatePicker" - | "DefaultButton" - | "Divider" - | "FileUpload" - | "IconPicker" - | "ImageUpload" - | "Input" - | "InputNumber" - | "InputPassword" - | "Mentions" - | "PrimaryButton" - | "Radio" - | "RadioGroup" - | "RangePicker" - | "Rate" - | "RichTextarea" - | "Select" - | "Space" - | "Switch" - | "Textarea" - | "TimePicker" - | "TimeRangePicker" - | "TreeSelect" - | "Upload" + | 'ApiCascader' + | 'ApiSelect' + | 'ApiTreeSelect' + | 'AutoComplete' + | 'Cascader' + | 'Checkbox' + | 'CheckboxGroup' + | 'DatePicker' + | 'DefaultButton' + | 'Divider' + | 'FileUpload' + | 'IconPicker' + | 'ImageUpload' + | 'Input' + | 'InputNumber' + | 'InputPassword' + | 'Mentions' + | 'PrimaryButton' + | 'Radio' + | 'RadioGroup' + | 'RangePicker' + | 'Rate' + | 'RichTextarea' + | 'Select' + | 'Space' + | 'Switch' + | 'Textarea' + | 'TimePicker' + | 'TimeRangePicker' + | 'TreeSelect' + | 'Upload' | BaseFormComponentType; async function initComponentAdapter() { @@ -136,74 +173,74 @@ async function initComponentAdapter() { // Button: () => // import('xxx').then((res) => res.Button), - ApiCascader: withDefaultPlaceholder(ApiComponent, "select", { + ApiCascader: withDefaultPlaceholder(ApiComponent, 'select', { component: Cascader, - fieldNames: { label: "label", value: "value", children: "children" }, - loadingSlot: "suffixIcon", - modelPropName: "value", - visibleEvent: "onVisibleChange", + fieldNames: { label: 'label', value: 'value', children: 'children' }, + loadingSlot: 'suffixIcon', + modelPropName: 'value', + visibleEvent: 'onVisibleChange', }), ApiSelect: withDefaultPlaceholder( { ...ApiComponent, - name: "ApiSelect", + name: 'ApiSelect', }, - "select", + 'select', { component: Select, - loadingSlot: "suffixIcon", - visibleEvent: "onDropdownVisibleChange", - modelPropName: "value", + loadingSlot: 'suffixIcon', + visibleEvent: 'onDropdownVisibleChange', + modelPropName: 'value', }, ), ApiTreeSelect: withDefaultPlaceholder( { ...ApiComponent, - name: "ApiTreeSelect", + name: 'ApiTreeSelect', }, - "select", + 'select', { component: TreeSelect, - fieldNames: { label: "label", value: "value", children: "children" }, - loadingSlot: "suffixIcon", - modelPropName: "value", - optionsPropName: "treeData", - visibleEvent: "onVisibleChange", + fieldNames: { label: 'label', value: 'value', children: 'children' }, + loadingSlot: 'suffixIcon', + modelPropName: 'value', + optionsPropName: 'treeData', + visibleEvent: 'onVisibleChange', }, ), - Cascader: withDefaultPlaceholder(Cascader, "select"), + Cascader: withDefaultPlaceholder(Cascader, 'select'), Checkbox, CheckboxGroup, DatePicker, // 自定义默认按钮 DefaultButton: (props, { attrs, slots }) => { - return h(Button, { ...props, attrs, type: "default" }, slots); + return h(Button, { ...props, attrs, type: 'default' }, slots); }, Divider, - IconPicker: withDefaultPlaceholder(IconPicker, "select", { - iconSlot: "addonAfter", + IconPicker: withDefaultPlaceholder(IconPicker, 'select', { + iconSlot: 'addonAfter', inputComponent: Input, - modelValueProp: "value", + modelValueProp: 'value', }), - Input: withDefaultPlaceholder(Input, "input"), - InputNumber: withDefaultPlaceholder(InputNumber, "input"), - InputPassword: withDefaultPlaceholder(InputPassword, "input"), - Mentions: withDefaultPlaceholder(Mentions, "input"), + Input: withDefaultPlaceholder(Input, 'input'), + InputNumber: withDefaultPlaceholder(InputNumber, 'input'), + InputPassword: withDefaultPlaceholder(InputPassword, 'input'), + Mentions: withDefaultPlaceholder(Mentions, 'input'), // 自定义主要按钮 PrimaryButton: (props, { attrs, slots }) => { - return h(Button, { ...props, attrs, type: "primary" }, slots); + return h(Button, { ...props, attrs, type: 'primary' }, slots); }, Radio, RadioGroup, RangePicker, Rate, - Select: withDefaultPlaceholder(Select, "select"), + Select: withDefaultPlaceholder(Select, 'select'), Space, Switch, - Textarea: withDefaultPlaceholder(Textarea, "input"), + Textarea: withDefaultPlaceholder(Textarea, 'input'), TimePicker, TimeRangePicker, - TreeSelect: withDefaultPlaceholder(TreeSelect, "select"), + TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'), Upload, ImageUpload, FileUpload, @@ -220,7 +257,7 @@ async function initComponentAdapter() { window.notification.success({ description: content, title, - placement: "bottomRight", + placement: 'bottomRight', }); }, }); diff --git a/cspell.json b/cspell.json index 7d8240560..a7fc9140c 100644 --- a/cspell.json +++ b/cspell.json @@ -15,8 +15,10 @@ "axios", "brotli", "cascader", + "cascader", "chatcmpl", "clientid", + "clientid", "clsx", "dedup", "defu", @@ -35,6 +37,7 @@ "ipaddr", "isequal", "jsencrypt", + "jsencrypt", "jspm", "lockb", "logininfor", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 242e3d625..c1b4ab2d4 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -75,7 +75,6 @@ catalog: '@vueuse/core': ^14.2.1 '@vueuse/integrations': ^14.2.1 '@vueuse/motion': ^3.0.3 - '@vxe-ui/plugin-render-antd': ^4.0.18 alova: ^3.4.1 antdv-next: ^1.1.7 archiver: ^7.0.1 diff --git a/vben-admin.code-workspace b/vben-admin.code-workspace index 97b9b72dc..1794287c9 100644 --- a/vben-admin.code-workspace +++ b/vben-admin.code-workspace @@ -2,31 +2,31 @@ "folders": [ { "name": "@vben/web-antd", - "path": "apps/web-antd", + "path": "apps/web-antd" }, { "name": "@vben/commitlint-config", - "path": "internal/lint-configs/commitlint-config", + "path": "internal/lint-configs/commitlint-config" }, { "name": "@vben/eslint-config", - "path": "internal/lint-configs/eslint-config", + "path": "internal/lint-configs/eslint-config" }, { "name": "@vben/oxfmt-config", - "path": "internal/lint-configs/oxfmt-config", + "path": "internal/lint-configs/oxfmt-config" }, { "name": "@vben/oxlint-config", - "path": "internal/lint-configs/oxlint-config", + "path": "internal/lint-configs/oxlint-config" }, { "name": "@vben/stylelint-config", - "path": "internal/lint-configs/stylelint-config", + "path": "internal/lint-configs/stylelint-config" }, { "name": "@vben/node-utils", - "path": "internal/node-utils", + "path": "internal/node-utils" }, { "name": "@vben/tailwind-config", @@ -34,123 +34,123 @@ }, { "name": "@vben/tsconfig", - "path": "internal/tsconfig", + "path": "internal/tsconfig" }, { "name": "@vben/vite-config", - "path": "internal/vite-config", + "path": "internal/vite-config" }, { "name": "@vben-core/design", - "path": "packages/@core/base/design", + "path": "packages/@core/base/design" }, { "name": "@vben-core/icons", - "path": "packages/@core/base/icons", + "path": "packages/@core/base/icons" }, { "name": "@vben-core/shared", - "path": "packages/@core/base/shared", + "path": "packages/@core/base/shared" }, { "name": "@vben-core/typings", - "path": "packages/@core/base/typings", + "path": "packages/@core/base/typings" }, { "name": "@vben-core/composables", - "path": "packages/@core/composables", + "path": "packages/@core/composables" }, { "name": "@vben-core/preferences", - "path": "packages/@core/preferences", + "path": "packages/@core/preferences" }, { "name": "@vben-core/form-ui", - "path": "packages/@core/ui-kit/form-ui", + "path": "packages/@core/ui-kit/form-ui" }, { "name": "@vben-core/layout-ui", - "path": "packages/@core/ui-kit/layout-ui", + "path": "packages/@core/ui-kit/layout-ui" }, { "name": "@vben-core/menu-ui", - "path": "packages/@core/ui-kit/menu-ui", + "path": "packages/@core/ui-kit/menu-ui" }, { "name": "@vben-core/popup-ui", - "path": "packages/@core/ui-kit/popup-ui", + "path": "packages/@core/ui-kit/popup-ui" }, { "name": "@vben-core/shadcn-ui", - "path": "packages/@core/ui-kit/shadcn-ui", + "path": "packages/@core/ui-kit/shadcn-ui" }, { "name": "@vben-core/tabs-ui", - "path": "packages/@core/ui-kit/tabs-ui", + "path": "packages/@core/ui-kit/tabs-ui" }, { "name": "@vben/constants", - "path": "packages/constants", + "path": "packages/constants" }, { "name": "@vben/access", - "path": "packages/effects/access", + "path": "packages/effects/access" }, { "name": "@vben/common-ui", - "path": "packages/effects/common-ui", + "path": "packages/effects/common-ui" }, { "name": "@vben/hooks", - "path": "packages/effects/hooks", + "path": "packages/effects/hooks" }, { "name": "@vben/layouts", - "path": "packages/effects/layouts", + "path": "packages/effects/layouts" }, { "name": "@vben/plugins", - "path": "packages/effects/plugins", + "path": "packages/effects/plugins" }, { "name": "@vben/request", - "path": "packages/effects/request", + "path": "packages/effects/request" }, { "name": "@vben/icons", - "path": "packages/icons", + "path": "packages/icons" }, { "name": "@vben/locales", - "path": "packages/locales", + "path": "packages/locales" }, { "name": "@vben/preferences", - "path": "packages/preferences", + "path": "packages/preferences" }, { "name": "@vben/stores", - "path": "packages/stores", + "path": "packages/stores" }, { "name": "@vben/styles", - "path": "packages/styles", + "path": "packages/styles" }, { "name": "@vben/types", - "path": "packages/types", + "path": "packages/types" }, { "name": "@vben/utils", - "path": "packages/utils", + "path": "packages/utils" }, { "name": "@vben/turbo-run", - "path": "scripts/turbo-run", + "path": "scripts/turbo-run" }, { "name": "@vben/vsh", - "path": "scripts/vsh", - }, - ], + "path": "scripts/vsh" + } + ] }