From b9bfa5f39875c9af6e675d3b8a99586b7d0d28bf Mon Sep 17 00:00:00 2001 From: ChenYi <296215406@outlook.com> Date: Tue, 27 May 2025 19:31:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .browserslistrc | 4 + .commitlintrc.js | 1 + .dockerignore | 7 + .editorconfig | 18 + .gitattributes | 11 + .gitconfig | 2 + .gitignore | 56 + .gitpod.yml | 6 + .husky/_/commit-msg | 69 + .husky/_/post-merge | 69 + .husky/_/pre-commit | 69 + .husky/_/prepare-commit-msg | 69 + .node-version | 1 + .npmrc | 13 + .prettierignore | 18 + .prettierrc.mjs | 1 + .stylelintignore | 4 + .vscode/extensions.json | 30 + .vscode/global.code-snippets | 37 + .vscode/launch.json | 42 + .vscode/settings.json | 241 + Dockerfile | 44 + _nginx/nginx.conf | 75 + apps/web-antd/.env | 8 + apps/web-antd/.env.analyze | 7 + apps/web-antd/.env.development | 37 + apps/web-antd/.env.production | 28 + apps/web-antd/index.html | 35 + apps/web-antd/package.json | 62 + apps/web-antd/postcss.config.mjs | 1 + apps/web-antd/public/avatar-v1.webp | Bin 0 -> 21586 bytes apps/web-antd/public/favicon.ico | Bin 0 -> 5430 bytes apps/web-antd/public/logo-v1.webp | Bin 0 -> 28846 bytes apps/web-antd/src/adapter/component/index.ts | 218 + apps/web-antd/src/adapter/form.ts | 47 + apps/web-antd/src/adapter/vxe-table.ts | 72 + apps/web-antd/src/api-client-config/config.ts | 7 + apps/web-antd/src/api-client-config/index.ts | 143 + apps/web-antd/src/api-client/index.ts | 4 + apps/web-antd/src/api-client/schemas.gen.ts | 8221 +++++++ apps/web-antd/src/api-client/services.gen.ts | 2947 +++ apps/web-antd/src/api-client/types.gen.ts | 5004 ++++ apps/web-antd/src/api/core/auth.ts | 51 + apps/web-antd/src/api/core/index.ts | 3 + apps/web-antd/src/api/core/menu.ts | 39 + apps/web-antd/src/api/core/user.ts | 10 + apps/web-antd/src/api/index.ts | 1 + apps/web-antd/src/api/request.ts | 113 + apps/web-antd/src/app.vue | 39 + apps/web-antd/src/bootstrap.ts | 81 + apps/web-antd/src/components/Loading/index.ts | 4 + .../src/components/Loading/src/Loading.vue | 78 + .../components/Loading/src/createLoading.ts | 84 + .../src/components/Loading/src/typing.ts | 14 + .../src/components/Loading/src/useLoading.ts | 62 + apps/web-antd/src/components/icon/icon.vue | 51 + apps/web-antd/src/components/icon/index.ts | 1 + .../src/components/table-action/index.ts | 2 + .../components/table-action/table-action.vue | 227 + .../src/components/table-action/types.d.ts | 26 + apps/web-antd/src/hooks/useLoadIcon.ts | 23 + apps/web-antd/src/hooks/useSignalR.ts | 127 + apps/web-antd/src/layouts/NotifyItem.vue | 207 + apps/web-antd/src/layouts/auth.vue | 23 + apps/web-antd/src/layouts/basic.vue | 281 + apps/web-antd/src/layouts/change-password.vue | 108 + apps/web-antd/src/layouts/index.ts | 6 + apps/web-antd/src/layouts/my-profile.vue | 403 + apps/web-antd/src/locales/README.md | 3 + apps/web-antd/src/locales/index.ts | 102 + .../web-antd/src/locales/langs/en-US/abp.json | 163 + .../src/locales/langs/en-US/code.json | 37 + .../src/locales/langs/en-US/common.json | 41 + .../src/locales/langs/en-US/demos.json | 12 + .../src/locales/langs/en-US/page.json | 15 + .../src/locales/langs/en-US/textTemplate.json | 8 + .../web-antd/src/locales/langs/zh-CN/abp.json | 163 + .../src/locales/langs/zh-CN/code.json | 37 + .../src/locales/langs/zh-CN/common.json | 41 + .../src/locales/langs/zh-CN/demos.json | 12 + .../src/locales/langs/zh-CN/page.json | 15 + .../src/locales/langs/zh-CN/textTemplate.json | 8 + apps/web-antd/src/main.ts | 34 + apps/web-antd/src/preferences.ts | 28 + apps/web-antd/src/router/access.ts | 43 + apps/web-antd/src/router/guard.ts | 138 + apps/web-antd/src/router/index.ts | 37 + apps/web-antd/src/router/routes/core.ts | 105 + apps/web-antd/src/router/routes/index.ts | 37 + .../src/router/routes/modules/code.ts | 82 + .../src/router/routes/modules/dashboard.ts | 38 + .../src/router/routes/modules/demos.ts | 41 + .../src/router/routes/modules/file.ts | 32 + .../src/router/routes/modules/system.ts | 154 + .../src/router/routes/modules/tenant.ts | 32 + .../src/router/routes/modules/textTemplate.ts | 32 + .../src/router/routes/modules/vben.ts | 94 + apps/web-antd/src/store/auth.ts | 158 + apps/web-antd/src/store/index.ts | 1 + apps/web-antd/src/views/_core/README.md | 3 + apps/web-antd/src/views/_core/about/index.vue | 9 + .../views/_core/authentication/code-login.vue | 69 + .../_core/authentication/forget-password.vue | 43 + .../src/views/_core/authentication/login.vue | 84 + .../views/_core/authentication/oidc-login.vue | 55 + .../_core/authentication/qrcode-login.vue | 10 + .../views/_core/authentication/register.vue | 96 + .../src/views/_core/fallback/coming-soon.vue | 7 + .../src/views/_core/fallback/forbidden.vue | 9 + .../views/_core/fallback/internal-error.vue | 9 + .../src/views/_core/fallback/not-found.vue | 9 + .../src/views/_core/fallback/offline.vue | 9 + .../src/views/code/generate/index.vue | 137 + .../src/views/code/generate/preview.vue | 186 + .../src/views/code/project/AddModal.vue | 54 + .../src/views/code/project/EditModal.vue | 63 + .../entityModel/AddAggregateRootModal.vue | 74 + .../entityModel/AddEditEntityModal.vue | 153 + .../AddEditEntityPropertyModal.vue | 190 + .../project/entityModel/AddEditEnumModal.vue | 96 + .../entityModel/AddEditEnumPropertyModal.vue | 121 + .../views/code/project/entityModel/index.vue | 806 + .../web-antd/src/views/code/project/index.vue | 173 + .../web-antd/src/views/code/project/schema.ts | 169 + .../code/template/AddEditTemplateModal.vue | 128 + .../src/views/code/template/AddModal.vue | 52 + .../src/views/code/template/CopyModal.vue | 74 + .../src/views/code/template/EditModal.vue | 63 + .../views/code/template/TemplateDetail.vue | 432 + .../src/views/code/template/index.vue | 212 + .../src/views/code/template/schema.ts | 80 + .../dashboard/analytics/analytics-trends.vue | 98 + .../analytics/analytics-visits-data.vue | 82 + .../analytics/analytics-visits-sales.vue | 46 + .../analytics/analytics-visits-source.vue | 65 + .../dashboard/analytics/analytics-visits.vue | 55 + .../src/views/dashboard/analytics/index.vue | 90 + .../src/views/dashboard/workspace/index.vue | 266 + apps/web-antd/src/views/demos/antd/index.vue | 66 + .../src/views/demos/listPage/AddEditModal.vue | 106 + .../src/views/demos/listPage/index.vue | 188 + .../web-antd/src/views/demos/listPage/mock.ts | 22 + .../DataDictionaryDetailModal.vue | 125 + .../abpdatadictionary/DataDictionaryModal.vue | 100 + .../views/system/abpdatadictionary/index.vue | 358 + .../src/views/system/abpfeature/index.vue | 134 + .../src/views/system/abpfiles/AddModal.vue | 39 + .../src/views/system/abpfiles/index.vue | 150 + .../src/views/system/abpfiles/schema.ts | 98 + .../abplanguage/AddLanguageTextModal.vue | 74 + .../abplanguage/EditLanguageTextModal.vue | 63 + .../src/views/system/abplanguage/language.vue | 72 + .../views/system/abplanguage/languagetext.vue | 147 + .../src/views/system/abplanguage/schema.ts | 175 + .../src/views/system/abplog/audit.vue | 96 + .../src/views/system/abplog/login.vue | 62 + .../src/views/system/abplog/schema.ts | 120 + .../src/views/system/abpmenu/AddModal.vue | 54 + .../src/views/system/abpmenu/EditModal.vue | 80 + .../src/views/system/abpmenu/index.vue | 180 + .../src/views/system/abpmenu/schema.ts | 483 + .../views/system/abpnotification/message.vue | 292 + .../system/abpnotification/notification.vue | 157 + .../views/system/abpnotification/schema.ts | 288 + .../abporganizationunit/ContextMenu.vue | 55 + .../abporganizationunit/OrgTreeAddModal.vue | 83 + .../abporganizationunit/OrgTreeEditModal.vue | 72 + .../system/abporganizationunit/index.vue | 705 + .../src/views/system/abprole/index.vue | 346 + .../src/views/system/abprole/schema.ts | 71 + .../src/views/system/abpsetting/index.vue | 138 + .../views/system/abptenant/AddEditModal.vue | 63 + .../abptenant/ConnectionStringModal.vue | 136 + .../system/abptenant/FeatureManageModal.vue | 132 + .../src/views/system/abptenant/index.vue | 245 + .../src/views/system/abptenant/schema.ts | 78 + .../src/views/system/abpuser/index.vue | 428 + .../src/views/system/abpuser/schema.ts | 170 + .../src/views/textTemplate/AddModal.vue | 58 + .../src/views/textTemplate/EditModal.vue | 67 + .../web-antd/src/views/textTemplate/index.vue | 176 + .../web-antd/src/views/textTemplate/schema.ts | 155 + apps/web-antd/tailwind.config.mjs | 1 + apps/web-antd/tsconfig.json | 12 + apps/web-antd/tsconfig.node.json | 10 + apps/web-antd/vite.config.mts | 32 + cspell.json | 68 + eslint.config.mjs | 5 + .../lint-configs/commitlint-config/index.mjs | 153 + .../commitlint-config/package.json | 33 + .../eslint-config/build.config.ts | 7 + .../lint-configs/eslint-config/package.json | 56 + .../eslint-config/src/configs/command.ts | 10 + .../eslint-config/src/configs/comments.ts | 24 + .../eslint-config/src/configs/disableds.ts | 28 + .../eslint-config/src/configs/ignores.ts | 52 + .../eslint-config/src/configs/import.ts | 25 + .../eslint-config/src/configs/index.ts | 17 + .../eslint-config/src/configs/javascript.ts | 241 + .../eslint-config/src/configs/jsdoc.ts | 34 + .../eslint-config/src/configs/jsonc.ts | 258 + .../eslint-config/src/configs/node.ts | 57 + .../src/configs/perfectionist.ts | 89 + .../eslint-config/src/configs/prettier.ts | 19 + .../eslint-config/src/configs/regexp.ts | 20 + .../eslint-config/src/configs/test.ts | 45 + .../eslint-config/src/configs/turbo.ts | 18 + .../eslint-config/src/configs/typescript.ts | 72 + .../eslint-config/src/configs/unicorn.ts | 45 + .../eslint-config/src/configs/vue.ts | 153 + .../eslint-config/src/custom-config.ts | 168 + .../lint-configs/eslint-config/src/index.ts | 60 + .../lint-configs/eslint-config/src/util.ts | 8 + .../lint-configs/eslint-config/tsconfig.json | 6 + .../lint-configs/prettier-config/index.mjs | 18 + .../lint-configs/prettier-config/package.json | 28 + .../lint-configs/stylelint-config/index.mjs | 141 + .../stylelint-config/package.json | 43 + internal/node-utils/build.config.ts | 7 + internal/node-utils/package.json | 43 + .../node-utils/src/__tests__/hash.test.ts | 52 + .../node-utils/src/__tests__/path.test.ts | 67 + internal/node-utils/src/constants.ts | 6 + internal/node-utils/src/date.ts | 12 + internal/node-utils/src/fs.ts | 39 + internal/node-utils/src/git.ts | 34 + internal/node-utils/src/hash.ts | 18 + internal/node-utils/src/index.ts | 19 + internal/node-utils/src/monorepo.ts | 46 + internal/node-utils/src/path.ts | 11 + internal/node-utils/src/prettier.ts | 21 + internal/node-utils/src/spinner.ts | 26 + internal/node-utils/tsconfig.json | 6 + internal/tailwind-config/build.config.ts | 10 + internal/tailwind-config/package.json | 66 + internal/tailwind-config/src/index.ts | 266 + internal/tailwind-config/src/module.d.ts | 3 + internal/tailwind-config/src/plugins/entry.ts | 53 + .../tailwind-config/src/postcss.config.ts | 15 + internal/tailwind-config/tsconfig.json | 9 + internal/tsconfig/base.json | 40 + internal/tsconfig/library.json | 13 + internal/tsconfig/node.json | 12 + internal/tsconfig/package.json | 25 + internal/tsconfig/web-app.json | 8 + internal/tsconfig/web.json | 14 + internal/vite-config/build.config.ts | 7 + internal/vite-config/package.json | 59 + .../vite-config/src/config/application.ts | 125 + internal/vite-config/src/config/common.ts | 13 + internal/vite-config/src/config/index.ts | 37 + internal/vite-config/src/config/library.ts | 59 + internal/vite-config/src/index.ts | 4 + internal/vite-config/src/options.ts | 45 + internal/vite-config/src/plugins/archiver.ts | 75 + .../src/plugins/extra-app-config.ts | 92 + internal/vite-config/src/plugins/importmap.ts | 245 + internal/vite-config/src/plugins/index.ts | 247 + .../src/plugins/inject-app-loading/README.md | 3 + .../default-loading-antd.html | 107 + .../inject-app-loading/default-loading.html | 113 + .../src/plugins/inject-app-loading/index.ts | 66 + .../src/plugins/inject-metadata.ts | 111 + internal/vite-config/src/plugins/license.ts | 63 + .../vite-config/src/plugins/nitro-mock.ts | 98 + internal/vite-config/src/plugins/print.ts | 28 + internal/vite-config/src/plugins/vxe-table.ts | 20 + internal/vite-config/src/typing.ts | 343 + internal/vite-config/src/utils/env.ts | 110 + internal/vite-config/tsconfig.json | 6 + lefthook.yml | 76 + package.json | 117 + packages/@core/README.md | 3 + packages/@core/base/README.md | 5 + packages/@core/base/design/package.json | 41 + packages/@core/base/design/src/css/global.css | 160 + .../@core/base/design/src/css/nprogress.css | 59 + .../@core/base/design/src/css/transition.css | 236 + packages/@core/base/design/src/css/ui.css | 87 + .../base/design/src/design-tokens/dark.css | 446 + .../base/design/src/design-tokens/default.css | 382 + .../base/design/src/design-tokens/index.ts | 4 + packages/@core/base/design/src/index.ts | 8 + .../@core/base/design/src/scss-bem/bem.scss | 34 + .../base/design/src/scss-bem/constants.scss | 5 + packages/@core/base/design/tsconfig.json | 6 + packages/@core/base/design/vite.config.mts | 9 + packages/@core/base/icons/build.config.ts | 7 + packages/@core/base/icons/package.json | 41 + packages/@core/base/icons/src/create-icon.ts | 14 + packages/@core/base/icons/src/index.ts | 11 + packages/@core/base/icons/src/lucide.ts | 68 + packages/@core/base/icons/tsconfig.json | 6 + packages/@core/base/shared/build.config.ts | 14 + packages/@core/base/shared/package.json | 103 + .../cache/__tests__/storage-manager.test.ts | 130 + packages/@core/base/shared/src/cache/index.ts | 1 + .../base/shared/src/cache/storage-manager.ts | 118 + packages/@core/base/shared/src/cache/types.ts | 17 + .../src/color/__tests__/convert.test.ts | 58 + packages/@core/base/shared/src/color/color.ts | 9 + .../@core/base/shared/src/color/convert.ts | 62 + .../@core/base/shared/src/color/generator.ts | 45 + packages/@core/base/shared/src/color/index.ts | 3 + .../base/shared/src/constants/globals.ts | 16 + .../@core/base/shared/src/constants/index.ts | 2 + .../@core/base/shared/src/constants/vben.ts | 26 + .../@core/base/shared/src/global-state.ts | 45 + packages/@core/base/shared/src/store.ts | 1 + .../shared/src/utils/__tests__/diff.test.ts | 53 + .../shared/src/utils/__tests__/dom.test.ts | 127 + .../src/utils/__tests__/inference.test.ts | 183 + .../shared/src/utils/__tests__/letter.test.ts | 116 + .../src/utils/__tests__/state-handler.test.ts | 60 + .../shared/src/utils/__tests__/tree.test.ts | 196 + .../shared/src/utils/__tests__/unique.test.ts | 60 + .../__tests__/update-css-variables.test.ts | 30 + .../shared/src/utils/__tests__/util.test.ts | 156 + .../shared/src/utils/__tests__/window.test.ts | 33 + packages/@core/base/shared/src/utils/cn.ts | 10 + packages/@core/base/shared/src/utils/date.ts | 26 + packages/@core/base/shared/src/utils/diff.ts | 96 + packages/@core/base/shared/src/utils/dom.ts | 95 + .../@core/base/shared/src/utils/download.ts | 157 + packages/@core/base/shared/src/utils/index.ts | 20 + .../@core/base/shared/src/utils/inference.ts | 165 + .../@core/base/shared/src/utils/letter.ts | 47 + packages/@core/base/shared/src/utils/merge.ts | 10 + .../@core/base/shared/src/utils/nprogress.ts | 43 + .../base/shared/src/utils/state-handler.ts | 50 + packages/@core/base/shared/src/utils/to.ts | 21 + packages/@core/base/shared/src/utils/tree.ts | 97 + .../@core/base/shared/src/utils/unique.ts | 15 + .../shared/src/utils/update-css-variables.ts | 35 + packages/@core/base/shared/src/utils/util.ts | 44 + .../@core/base/shared/src/utils/window.ts | 37 + packages/@core/base/shared/tsconfig.json | 6 + packages/@core/base/typings/build.config.ts | 7 + packages/@core/base/typings/package.json | 44 + packages/@core/base/typings/src/app.d.ts | 110 + packages/@core/base/typings/src/basic.d.ts | 35 + packages/@core/base/typings/src/helper.d.ts | 132 + packages/@core/base/typings/src/index.ts | 6 + .../@core/base/typings/src/menu-record.ts | 76 + packages/@core/base/typings/src/tabs.ts | 3 + .../@core/base/typings/src/vue-router.d.ts | 149 + packages/@core/base/typings/tsconfig.json | 6 + packages/@core/base/typings/vue-router.d.ts | 9 + packages/@core/composables/build.config.ts | 7 + packages/@core/composables/package.json | 47 + .../src/__tests__/use-sortable.test.ts | 48 + packages/@core/composables/src/index.ts | 13 + .../@core/composables/src/use-is-mobile.ts | 7 + .../@core/composables/src/use-layout-style.ts | 87 + .../@core/composables/src/use-namespace.ts | 106 + .../composables/src/use-priority-value.ts | 94 + .../@core/composables/src/use-scroll-lock.ts | 54 + .../src/use-simple-locale/README.md | 3 + .../src/use-simple-locale/index.ts | 27 + .../src/use-simple-locale/messages.ts | 24 + .../@core/composables/src/use-sortable.ts | 29 + packages/@core/composables/tsconfig.json | 6 + .../__snapshots__/config.test.ts.snap | 123 + .../preferences/__tests__/config.test.ts | 10 + .../preferences/__tests__/preferences.test.ts | 253 + packages/@core/preferences/build.config.ts | 7 + packages/@core/preferences/package.json | 37 + packages/@core/preferences/src/config.ts | 124 + packages/@core/preferences/src/constants.ts | 88 + packages/@core/preferences/src/index.ts | 35 + packages/@core/preferences/src/preferences.ts | 235 + packages/@core/preferences/src/types.ts | 298 + .../preferences/src/update-css-variables.ts | 116 + .../@core/preferences/src/use-preferences.ts | 254 + packages/@core/preferences/tsconfig.json | 6 + packages/@core/ui-kit/README.md | 3 + .../ui-kit/form-ui/__tests__/form-api.test.ts | 189 + packages/@core/ui-kit/form-ui/build.config.ts | 21 + packages/@core/ui-kit/form-ui/package.json | 52 + .../@core/ui-kit/form-ui/postcss.config.mjs | 1 + .../form-ui/src/components/form-actions.vue | 160 + packages/@core/ui-kit/form-ui/src/config.ts | 87 + packages/@core/ui-kit/form-ui/src/form-api.ts | 579 + .../ui-kit/form-ui/src/form-render/context.ts | 24 + .../form-ui/src/form-render/dependencies.ts | 124 + .../form-ui/src/form-render/expandable.ts | 105 + .../form-ui/src/form-render/form-field.vue | 394 + .../form-ui/src/form-render/form-label.vue | 31 + .../ui-kit/form-ui/src/form-render/form.vue | 165 + .../ui-kit/form-ui/src/form-render/helper.ts | 60 + .../ui-kit/form-ui/src/form-render/index.ts | 3 + packages/@core/ui-kit/form-ui/src/index.ts | 12 + packages/@core/ui-kit/form-ui/src/types.ts | 442 + .../ui-kit/form-ui/src/use-form-context.ts | 72 + .../@core/ui-kit/form-ui/src/use-vben-form.ts | 50 + .../@core/ui-kit/form-ui/src/vben-form.vue | 77 + .../ui-kit/form-ui/src/vben-use-form.vue | 148 + .../@core/ui-kit/form-ui/tailwind.config.mjs | 1 + packages/@core/ui-kit/form-ui/tsconfig.json | 6 + .../@core/ui-kit/layout-ui/build.config.ts | 21 + packages/@core/ui-kit/layout-ui/package.json | 48 + .../@core/ui-kit/layout-ui/postcss.config.mjs | 1 + .../ui-kit/layout-ui/src/components/index.ts | 5 + .../src/components/layout-content.vue | 64 + .../src/components/layout-footer.vue | 44 + .../src/components/layout-header.vue | 77 + .../src/components/layout-sidebar.vue | 322 + .../src/components/layout-tabbar.vue | 30 + .../layout-ui/src/components/widgets/index.ts | 2 + .../widgets/sidebar-collapse-button.vue | 19 + .../widgets/sidebar-fixed-button.vue | 19 + .../ui-kit/layout-ui/src/hooks/use-layout.ts | 53 + packages/@core/ui-kit/layout-ui/src/index.ts | 2 + .../@core/ui-kit/layout-ui/src/vben-layout.ts | 175 + .../ui-kit/layout-ui/src/vben-layout.vue | 616 + .../ui-kit/layout-ui/tailwind.config.mjs | 1 + packages/@core/ui-kit/layout-ui/tsconfig.json | 6 + packages/@core/ui-kit/menu-ui/README.md | 1 + packages/@core/ui-kit/menu-ui/build.config.ts | 26 + packages/@core/ui-kit/menu-ui/package.json | 48 + .../@core/ui-kit/menu-ui/postcss.config.mjs | 1 + .../src/components/collapse-transition.vue | 96 + .../ui-kit/menu-ui/src/components/index.ts | 4 + .../menu-ui/src/components/menu-badge-dot.vue | 28 + .../menu-ui/src/components/menu-badge.vue | 57 + .../menu-ui/src/components/menu-item.vue | 122 + .../ui-kit/menu-ui/src/components/menu.vue | 872 + .../src/components/normal-menu/index.ts | 2 + .../src/components/normal-menu/normal-menu.ts | 27 + .../components/normal-menu/normal-menu.vue | 161 + .../src/components/sub-menu-content.vue | 105 + .../menu-ui/src/components/sub-menu.vue | 275 + .../@core/ui-kit/menu-ui/src/hooks/index.ts | 2 + .../menu-ui/src/hooks/use-menu-context.ts | 55 + .../menu-ui/src/hooks/use-menu-scroll.ts | 46 + .../ui-kit/menu-ui/src/hooks/use-menu.ts | 48 + packages/@core/ui-kit/menu-ui/src/index.ts | 4 + packages/@core/ui-kit/menu-ui/src/menu.vue | 32 + .../@core/ui-kit/menu-ui/src/sub-menu.vue | 71 + packages/@core/ui-kit/menu-ui/src/types.ts | 145 + .../@core/ui-kit/menu-ui/src/utils/index.ts | 52 + .../@core/ui-kit/menu-ui/tailwind.config.mjs | 1 + packages/@core/ui-kit/menu-ui/tsconfig.json | 6 + .../@core/ui-kit/popup-ui/build.config.ts | 21 + packages/@core/ui-kit/popup-ui/package.json | 48 + .../@core/ui-kit/popup-ui/postcss.config.mjs | 1 + .../ui-kit/popup-ui/src/alert/AlertBuilder.ts | 244 + .../@core/ui-kit/popup-ui/src/alert/alert.ts | 99 + .../@core/ui-kit/popup-ui/src/alert/alert.vue | 211 + .../@core/ui-kit/popup-ui/src/alert/index.ts | 14 + .../src/drawer/__tests__/drawer-api.test.ts | 116 + .../ui-kit/popup-ui/src/drawer/drawer-api.ts | 183 + .../ui-kit/popup-ui/src/drawer/drawer.ts | 179 + .../ui-kit/popup-ui/src/drawer/drawer.vue | 314 + .../@core/ui-kit/popup-ui/src/drawer/index.ts | 3 + .../ui-kit/popup-ui/src/drawer/use-drawer.ts | 150 + packages/@core/ui-kit/popup-ui/src/index.ts | 3 + .../src/modal/__tests__/modal-api.test.ts | 117 + .../@core/ui-kit/popup-ui/src/modal/index.ts | 3 + .../ui-kit/popup-ui/src/modal/modal-api.ts | 192 + .../@core/ui-kit/popup-ui/src/modal/modal.ts | 189 + .../@core/ui-kit/popup-ui/src/modal/modal.vue | 336 + .../popup-ui/src/modal/use-modal-draggable.ts | 117 + .../ui-kit/popup-ui/src/modal/use-modal.ts | 157 + .../@core/ui-kit/popup-ui/tailwind.config.mjs | 1 + packages/@core/ui-kit/popup-ui/tsconfig.json | 6 + .../@core/ui-kit/shadcn-ui/build.config.ts | 27 + .../@core/ui-kit/shadcn-ui/components.json | 16 + packages/@core/ui-kit/shadcn-ui/package.json | 54 + .../@core/ui-kit/shadcn-ui/postcss.config.mjs | 1 + .../src/components/avatar/avatar.vue | 64 + .../shadcn-ui/src/components/avatar/index.ts | 1 + .../src/components/back-top/back-top.vue | 43 + .../src/components/back-top/backtop.ts | 38 + .../src/components/back-top/index.ts | 1 + .../src/components/back-top/use-backtop.ts | 45 + .../breadcrumb/breadcrumb-background.vue | 109 + .../components/breadcrumb/breadcrumb-view.vue | 39 + .../src/components/breadcrumb/breadcrumb.vue | 98 + .../src/components/breadcrumb/index.ts | 3 + .../src/components/breadcrumb/types.ts | 17 + .../src/components/button/button-group.vue | 98 + .../shadcn-ui/src/components/button/button.ts | 42 + .../src/components/button/button.vue | 42 + .../components/button/check-button-group.vue | 163 + .../src/components/button/icon-button.vue | 68 + .../shadcn-ui/src/components/button/index.ts | 5 + .../src/components/checkbox/checkbox.vue | 26 + .../src/components/checkbox/index.ts | 1 + .../components/context-menu/context-menu.vue | 97 + .../src/components/context-menu/index.ts | 3 + .../src/components/context-menu/interface.ts | 38 + .../count-to-animator/count-to-animator.vue | 128 + .../src/components/count-to-animator/index.ts | 1 + .../dropdown-menu/dropdown-menu.vue | 49 + .../dropdown-menu/dropdown-radio-menu.vue | 52 + .../src/components/dropdown-menu/index.ts | 4 + .../src/components/dropdown-menu/interface.ts | 32 + .../expandable-arrow/expandable-arrow.vue | 31 + .../src/components/expandable-arrow/index.ts | 1 + .../components/full-screen/full-screen.vue | 28 + .../src/components/full-screen/index.ts | 1 + .../src/components/hover-card/hover-card.vue | 55 + .../src/components/hover-card/index.ts | 2 + .../shadcn-ui/src/components/icon/icon.vue | 35 + .../shadcn-ui/src/components/icon/index.ts | 1 + .../ui-kit/shadcn-ui/src/components/index.ts | 23 + .../src/components/input-password/index.ts | 1 + .../input-password/input-password.vue | 57 + .../input-password/password-strength.vue | 66 + .../shadcn-ui/src/components/logo/index.ts | 1 + .../shadcn-ui/src/components/logo/logo.vue | 67 + .../src/components/pin-input/index.ts | 3 + .../src/components/pin-input/input.vue | 120 + .../src/components/pin-input/types.ts | 30 + .../shadcn-ui/src/components/popover/index.ts | 1 + .../src/components/popover/popover.vue | 60 + .../src/components/render-content/index.ts | 1 + .../render-content/render-content.vue | 56 + .../src/components/scrollbar/index.ts | 1 + .../src/components/scrollbar/scrollbar.vue | 165 + .../src/components/segmented/index.ts | 3 + .../src/components/segmented/segmented.vue | 59 + .../components/segmented/tabs-indicator.vue | 37 + .../src/components/segmented/types.ts | 6 + .../shadcn-ui/src/components/select/index.ts | 1 + .../src/components/select/select.vue | 57 + .../src/components/spine-text/index.ts | 1 + .../src/components/spine-text/spine-text.vue | 49 + .../shadcn-ui/src/components/spinner/index.ts | 2 + .../src/components/spinner/loading.vue | 140 + .../src/components/spinner/spinner.vue | 137 + .../src/components/tooltip/help-tooltip.vue | 31 + .../shadcn-ui/src/components/tooltip/index.ts | 2 + .../src/components/tooltip/tooltip.vue | 44 + packages/@core/ui-kit/shadcn-ui/src/index.ts | 3 + .../shadcn-ui/src/ui/accordion/Accordion.vue | 16 + .../src/ui/accordion/AccordionContent.vue | 28 + .../src/ui/accordion/AccordionItem.vue | 25 + .../src/ui/accordion/AccordionTrigger.vue | 39 + .../shadcn-ui/src/ui/accordion/index.ts | 4 + .../src/ui/alert-dialog/AlertDialog.vue | 16 + .../src/ui/alert-dialog/AlertDialogAction.vue | 13 + .../src/ui/alert-dialog/AlertDialogCancel.vue | 13 + .../ui/alert-dialog/AlertDialogContent.vue | 101 + .../alert-dialog/AlertDialogDescription.vue | 28 + .../ui/alert-dialog/AlertDialogOverlay.vue | 8 + .../src/ui/alert-dialog/AlertDialogTitle.vue | 30 + .../shadcn-ui/src/ui/alert-dialog/index.ts | 6 + .../ui-kit/shadcn-ui/src/ui/avatar/Avatar.vue | 27 + .../src/ui/avatar/AvatarFallback.vue | 13 + .../shadcn-ui/src/ui/avatar/AvatarImage.vue | 11 + .../ui-kit/shadcn-ui/src/ui/avatar/avatar.ts | 22 + .../ui-kit/shadcn-ui/src/ui/avatar/index.ts | 4 + .../ui-kit/shadcn-ui/src/ui/badge/Badge.vue | 18 + .../ui-kit/shadcn-ui/src/ui/badge/badge.ts | 25 + .../ui-kit/shadcn-ui/src/ui/badge/index.ts | 3 + .../src/ui/breadcrumb/Breadcrumb.vue | 11 + .../src/ui/breadcrumb/BreadcrumbEllipsis.vue | 22 + .../src/ui/breadcrumb/BreadcrumbItem.vue | 17 + .../src/ui/breadcrumb/BreadcrumbLink.vue | 21 + .../src/ui/breadcrumb/BreadcrumbList.vue | 20 + .../src/ui/breadcrumb/BreadcrumbPage.vue | 18 + .../src/ui/breadcrumb/BreadcrumbSeparator.vue | 21 + .../shadcn-ui/src/ui/breadcrumb/index.ts | 7 + .../ui-kit/shadcn-ui/src/ui/button/Button.vue | 32 + .../ui-kit/shadcn-ui/src/ui/button/button.ts | 34 + .../ui-kit/shadcn-ui/src/ui/button/index.ts | 5 + .../ui-kit/shadcn-ui/src/ui/button/types.ts | 20 + .../ui-kit/shadcn-ui/src/ui/card/Card.vue | 20 + .../shadcn-ui/src/ui/card/CardContent.vue | 13 + .../shadcn-ui/src/ui/card/CardDescription.vue | 13 + .../shadcn-ui/src/ui/card/CardFooter.vue | 13 + .../shadcn-ui/src/ui/card/CardHeader.vue | 13 + .../shadcn-ui/src/ui/card/CardTitle.vue | 13 + .../ui-kit/shadcn-ui/src/ui/card/index.ts | 6 + .../shadcn-ui/src/ui/checkbox/Checkbox.vue | 47 + .../ui-kit/shadcn-ui/src/ui/checkbox/index.ts | 1 + .../src/ui/context-menu/ContextMenu.vue | 18 + .../context-menu/ContextMenuCheckboxItem.vue | 47 + .../ui/context-menu/ContextMenuContent.vue | 43 + .../src/ui/context-menu/ContextMenuGroup.vue | 13 + .../src/ui/context-menu/ContextMenuItem.vue | 37 + .../src/ui/context-menu/ContextMenuLabel.vue | 34 + .../src/ui/context-menu/ContextMenuPortal.vue | 13 + .../ui/context-menu/ContextMenuRadioGroup.vue | 19 + .../ui/context-menu/ContextMenuRadioItem.vue | 47 + .../ui/context-menu/ContextMenuSeparator.vue | 24 + .../ui/context-menu/ContextMenuShortcut.vue | 17 + .../src/ui/context-menu/ContextMenuSub.vue | 16 + .../ui/context-menu/ContextMenuSubContent.vue | 37 + .../ui/context-menu/ContextMenuSubTrigger.vue | 41 + .../ui/context-menu/ContextMenuTrigger.vue | 15 + .../shadcn-ui/src/ui/context-menu/index.ts | 14 + .../ui-kit/shadcn-ui/src/ui/dialog/Dialog.vue | 16 + .../shadcn-ui/src/ui/dialog/DialogClose.vue | 13 + .../shadcn-ui/src/ui/dialog/DialogContent.vue | 125 + .../src/ui/dialog/DialogDescription.vue | 28 + .../shadcn-ui/src/ui/dialog/DialogFooter.vue | 15 + .../shadcn-ui/src/ui/dialog/DialogHeader.vue | 15 + .../shadcn-ui/src/ui/dialog/DialogOverlay.vue | 11 + .../src/ui/dialog/DialogScrollContent.vue | 71 + .../shadcn-ui/src/ui/dialog/DialogTitle.vue | 30 + .../shadcn-ui/src/ui/dialog/DialogTrigger.vue | 13 + .../ui-kit/shadcn-ui/src/ui/dialog/index.ts | 9 + .../src/ui/dropdown-menu/DropdownMenu.vue | 18 + .../DropdownMenuCheckboxItem.vue | 47 + .../ui/dropdown-menu/DropdownMenuContent.vue | 48 + .../ui/dropdown-menu/DropdownMenuGroup.vue | 13 + .../src/ui/dropdown-menu/DropdownMenuItem.vue | 36 + .../ui/dropdown-menu/DropdownMenuLabel.vue | 32 + .../dropdown-menu/DropdownMenuRadioGroup.vue | 19 + .../dropdown-menu/DropdownMenuRadioItem.vue | 48 + .../dropdown-menu/DropdownMenuSeparator.vue | 28 + .../ui/dropdown-menu/DropdownMenuShortcut.vue | 13 + .../src/ui/dropdown-menu/DropdownMenuSub.vue | 16 + .../dropdown-menu/DropdownMenuSubContent.vue | 37 + .../dropdown-menu/DropdownMenuSubTrigger.vue | 35 + .../ui/dropdown-menu/DropdownMenuTrigger.vue | 15 + .../shadcn-ui/src/ui/dropdown-menu/index.ts | 16 + .../shadcn-ui/src/ui/form/FormControl.vue | 19 + .../shadcn-ui/src/ui/form/FormDescription.vue | 20 + .../ui-kit/shadcn-ui/src/ui/form/FormItem.vue | 20 + .../shadcn-ui/src/ui/form/FormLabel.vue | 18 + .../shadcn-ui/src/ui/form/FormMessage.vue | 18 + .../ui-kit/shadcn-ui/src/ui/form/index.ts | 11 + .../shadcn-ui/src/ui/form/injectionKeys.ts | 4 + .../shadcn-ui/src/ui/form/useFormField.ts | 38 + .../shadcn-ui/src/ui/hover-card/HoverCard.vue | 16 + .../src/ui/hover-card/HoverCardContent.vue | 40 + .../src/ui/hover-card/HoverCardTrigger.vue | 13 + .../shadcn-ui/src/ui/hover-card/index.ts | 3 + .../@core/ui-kit/shadcn-ui/src/ui/index.ts | 31 + .../ui-kit/shadcn-ui/src/ui/input/Input.vue | 37 + .../ui-kit/shadcn-ui/src/ui/input/index.ts | 1 + .../ui-kit/shadcn-ui/src/ui/label/Label.vue | 31 + .../ui-kit/shadcn-ui/src/ui/label/index.ts | 1 + .../src/ui/number-field/NumberField.vue | 26 + .../ui/number-field/NumberFieldContent.vue | 20 + .../ui/number-field/NumberFieldDecrement.vue | 37 + .../ui/number-field/NumberFieldIncrement.vue | 37 + .../src/ui/number-field/NumberFieldInput.vue | 16 + .../shadcn-ui/src/ui/number-field/index.ts | 5 + .../src/ui/pagination/PaginationEllipsis.vue | 29 + .../src/ui/pagination/PaginationFirst.vue | 35 + .../src/ui/pagination/PaginationLast.vue | 35 + .../src/ui/pagination/PaginationNext.vue | 35 + .../src/ui/pagination/PaginationPrev.vue | 35 + .../shadcn-ui/src/ui/pagination/index.ts | 10 + .../shadcn-ui/src/ui/pin-input/PinInput.vue | 28 + .../src/ui/pin-input/PinInputGroup.vue | 25 + .../src/ui/pin-input/PinInputInput.vue | 30 + .../src/ui/pin-input/PinInputSeparator.vue | 17 + .../shadcn-ui/src/ui/pin-input/index.ts | 4 + .../shadcn-ui/src/ui/popover/Popover.vue | 16 + .../src/ui/popover/PopoverContent.vue | 46 + .../src/ui/popover/PopoverTrigger.vue | 13 + .../ui-kit/shadcn-ui/src/ui/popover/index.ts | 4 + .../src/ui/radio-group/RadioGroup.vue | 26 + .../src/ui/radio-group/RadioGroupItem.vue | 40 + .../shadcn-ui/src/ui/radio-group/index.ts | 2 + .../src/ui/resizable/ResizableHandle.vue | 50 + .../src/ui/resizable/ResizablePanelGroup.vue | 37 + .../shadcn-ui/src/ui/resizable/index.ts | 3 + .../src/ui/scroll-area/ScrollArea.vue | 50 + .../src/ui/scroll-area/ScrollBar.vue | 40 + .../shadcn-ui/src/ui/scroll-area/index.ts | 2 + .../ui-kit/shadcn-ui/src/ui/select/Select.vue | 16 + .../shadcn-ui/src/ui/select/SelectContent.vue | 67 + .../shadcn-ui/src/ui/select/SelectGroup.vue | 23 + .../shadcn-ui/src/ui/select/SelectItem.vue | 47 + .../src/ui/select/SelectItemText.vue | 13 + .../shadcn-ui/src/ui/select/SelectLabel.vue | 15 + .../src/ui/select/SelectScrollDownButton.vue | 33 + .../src/ui/select/SelectScrollUpButton.vue | 33 + .../src/ui/select/SelectSeparator.vue | 24 + .../shadcn-ui/src/ui/select/SelectTrigger.vue | 37 + .../shadcn-ui/src/ui/select/SelectValue.vue | 13 + .../ui-kit/shadcn-ui/src/ui/select/index.ts | 11 + .../shadcn-ui/src/ui/separator/Separator.vue | 44 + .../shadcn-ui/src/ui/separator/index.ts | 1 + .../ui-kit/shadcn-ui/src/ui/sheet/Sheet.vue | 16 + .../shadcn-ui/src/ui/sheet/SheetClose.vue | 13 + .../shadcn-ui/src/ui/sheet/SheetContent.vue | 107 + .../src/ui/sheet/SheetDescription.vue | 26 + .../shadcn-ui/src/ui/sheet/SheetFooter.vue | 15 + .../shadcn-ui/src/ui/sheet/SheetHeader.vue | 11 + .../shadcn-ui/src/ui/sheet/SheetOverlay.vue | 11 + .../shadcn-ui/src/ui/sheet/SheetTitle.vue | 26 + .../shadcn-ui/src/ui/sheet/SheetTrigger.vue | 13 + .../ui-kit/shadcn-ui/src/ui/sheet/index.ts | 10 + .../ui-kit/shadcn-ui/src/ui/sheet/sheet.ts | 24 + .../ui-kit/shadcn-ui/src/ui/switch/Switch.vue | 41 + .../ui-kit/shadcn-ui/src/ui/switch/index.ts | 1 + .../ui-kit/shadcn-ui/src/ui/tabs/Tabs.vue | 16 + .../shadcn-ui/src/ui/tabs/TabsContent.vue | 31 + .../ui-kit/shadcn-ui/src/ui/tabs/TabsList.vue | 31 + .../shadcn-ui/src/ui/tabs/TabsTrigger.vue | 33 + .../ui-kit/shadcn-ui/src/ui/tabs/index.ts | 5 + .../shadcn-ui/src/ui/textarea/Textarea.vue | 32 + .../ui-kit/shadcn-ui/src/ui/textarea/index.ts | 1 + .../src/ui/toggle-group/ToggleGroup.vue | 44 + .../src/ui/toggle-group/ToggleGroupItem.vue | 48 + .../shadcn-ui/src/ui/toggle-group/index.ts | 2 + .../ui-kit/shadcn-ui/src/ui/toggle/Toggle.vue | 47 + .../ui-kit/shadcn-ui/src/ui/toggle/index.ts | 2 + .../ui-kit/shadcn-ui/src/ui/toggle/toggle.ts | 27 + .../shadcn-ui/src/ui/tooltip/Tooltip.vue | 16 + .../src/ui/tooltip/TooltipContent.vue | 48 + .../src/ui/tooltip/TooltipProvider.vue | 13 + .../src/ui/tooltip/TooltipTrigger.vue | 13 + .../ui-kit/shadcn-ui/src/ui/tooltip/index.ts | 4 + .../ui-kit/shadcn-ui/src/ui/tree/index.ts | 2 + .../ui-kit/shadcn-ui/src/ui/tree/tree.vue | 334 + .../ui-kit/shadcn-ui/src/ui/tree/types.ts | 40 + .../ui-kit/shadcn-ui/tailwind.config.mjs | 1 + packages/@core/ui-kit/shadcn-ui/tsconfig.json | 12 + packages/@core/ui-kit/tabs-ui/build.config.ts | 21 + packages/@core/ui-kit/tabs-ui/package.json | 47 + .../@core/ui-kit/tabs-ui/postcss.config.mjs | 1 + .../ui-kit/tabs-ui/src/components/index.ts | 2 + .../src/components/tabs-chrome/tabs.vue | 209 + .../tabs-ui/src/components/tabs/tabs.vue | 148 + .../tabs-ui/src/components/widgets/index.ts | 2 + .../src/components/widgets/tool-more.vue | 18 + .../src/components/widgets/tool-screen.vue | 19 + packages/@core/ui-kit/tabs-ui/src/index.ts | 3 + .../@core/ui-kit/tabs-ui/src/tabs-view.vue | 106 + packages/@core/ui-kit/tabs-ui/src/types.ts | 73 + .../@core/ui-kit/tabs-ui/src/use-tabs-drag.ts | 124 + .../tabs-ui/src/use-tabs-view-scroll.ts | 202 + .../@core/ui-kit/tabs-ui/tailwind.config.mjs | 1 + packages/@core/ui-kit/tabs-ui/tsconfig.json | 6 + packages/constants/README.md | 19 + packages/constants/package.json | 25 + packages/constants/src/core.ts | 23 + packages/constants/src/index.ts | 2 + packages/constants/tsconfig.json | 6 + packages/effects/README.md | 10 + packages/effects/access/package.json | 29 + .../effects/access/src/access-control.vue | 47 + packages/effects/access/src/accessible.ts | 147 + packages/effects/access/src/directive.ts | 42 + packages/effects/access/src/index.ts | 4 + packages/effects/access/src/use-access.ts | 53 + packages/effects/access/tsconfig.json | 6 + packages/effects/common-ui/package.json | 53 + .../api-component/api-component.vue | 271 + .../src/components/api-component/index.ts | 1 + .../captcha/hooks/useCaptchaPoints.ts | 19 + .../common-ui/src/components/captcha/index.ts | 6 + .../captcha/point-selection-captcha/index.vue | 176 + .../point-selection-captcha-card.vue | 84 + .../captcha/slider-captcha/index.vue | 244 + .../slider-captcha/slider-captcha-action.vue | 65 + .../slider-captcha/slider-captcha-bar.vue | 40 + .../slider-captcha/slider-captcha-content.vue | 53 + .../captcha/slider-rotate-captcha/index.vue | 213 + .../common-ui/src/components/captcha/types.ts | 175 + .../src/components/col-page/col-page.vue | 107 + .../src/components/col-page/index.ts | 2 + .../src/components/col-page/types.ts | 26 + .../src/components/count-to/count-to.vue | 123 + .../src/components/count-to/index.ts | 2 + .../src/components/count-to/types.ts | 53 + .../ellipsis-text/ellipsis-text.vue | 148 + .../src/components/ellipsis-text/index.ts | 1 + .../components/icon-picker/icon-picker.vue | 320 + .../src/components/icon-picker/icons.ts | 56 + .../src/components/icon-picker/index.ts | 1 + .../effects/common-ui/src/components/index.ts | 32 + .../src/components/json-viewer/index.ts | 3 + .../src/components/json-viewer/index.vue | 98 + .../src/components/json-viewer/style.scss | 98 + .../src/components/json-viewer/types.ts | 44 + .../src/components/loading/directive.ts | 132 + .../common-ui/src/components/loading/index.ts | 3 + .../src/components/loading/loading.vue | 39 + .../src/components/loading/spinner.vue | 28 + .../components/page/__tests__/page.test.ts | 89 + .../common-ui/src/components/page/index.ts | 2 + .../common-ui/src/components/page/page.vue | 106 + .../common-ui/src/components/page/types.ts | 17 + .../common-ui/src/components/resize/index.ts | 1 + .../src/components/resize/resize.vue | 1122 + .../src/components/tippy/directive.ts | 100 + .../common-ui/src/components/tippy/index.ts | 67 + packages/effects/common-ui/src/index.ts | 2 + .../effects/common-ui/src/ui/about/about.ts | 14 + .../effects/common-ui/src/ui/about/about.vue | 183 + .../effects/common-ui/src/ui/about/index.ts | 1 + .../src/ui/authentication/auth-title.vue | 13 + .../src/ui/authentication/code-login.vue | 117 + .../src/ui/authentication/forget-password.vue | 116 + .../common-ui/src/ui/authentication/index.ts | 7 + .../ui/authentication/login-expired-modal.vue | 93 + .../common-ui/src/ui/authentication/login.vue | 205 + .../src/ui/authentication/qrcode-login.vue | 95 + .../src/ui/authentication/register.vue | 121 + .../ui/authentication/third-party-login.vue | 42 + .../common-ui/src/ui/authentication/types.ts | 80 + .../analysis/analysis-chart-card.vue | 24 + .../analysis/analysis-charts-tabs.vue | 40 + .../dashboard/analysis/analysis-overview.vue | 55 + .../src/ui/dashboard/analysis/index.ts | 3 + .../common-ui/src/ui/dashboard/index.ts | 3 + .../common-ui/src/ui/dashboard/typing.ts | 48 + .../src/ui/dashboard/workbench/index.ts | 5 + .../dashboard/workbench/workbench-header.vue | 46 + .../dashboard/workbench/workbench-project.vue | 65 + .../workbench/workbench-quick-nav.vue | 56 + .../ui/dashboard/workbench/workbench-todo.vue | 63 + .../dashboard/workbench/workbench-trends.vue | 64 + .../common-ui/src/ui/fallback/fallback.ts | 25 + .../common-ui/src/ui/fallback/fallback.vue | 164 + .../src/ui/fallback/icons/icon-403.vue | 151 + .../src/ui/fallback/icons/icon-404.vue | 154 + .../src/ui/fallback/icons/icon-500.vue | 215 + .../ui/fallback/icons/icon-coming-soon.vue | 262 + .../src/ui/fallback/icons/icon-offline.vue | 112 + .../src/ui/fallback/icons/warning.svg | 1 + .../common-ui/src/ui/fallback/index.ts | 2 + packages/effects/common-ui/src/ui/index.ts | 4 + packages/effects/common-ui/tsconfig.json | 6 + packages/effects/hooks/README.md | 19 + packages/effects/hooks/package.json | 34 + packages/effects/hooks/src/index.ts | 10 + packages/effects/hooks/src/use-app-config.ts | 23 + .../effects/hooks/src/use-content-maximize.ts | 24 + .../effects/hooks/src/use-design-tokens.ts | 281 + packages/effects/hooks/src/use-event-bus.ts | 45 + .../effects/hooks/src/use-hover-toggle.ts | 68 + packages/effects/hooks/src/use-pagination.ts | 58 + packages/effects/hooks/src/use-refresh.ts | 16 + packages/effects/hooks/src/use-tabs.ts | 115 + packages/effects/hooks/src/use-watermark.ts | 84 + packages/effects/hooks/tsconfig.json | 9 + packages/effects/layouts/package.json | 43 + .../src/authentication/authentication.vue | 162 + .../layouts/src/authentication/form.vue | 33 + .../src/authentication/icons/slogan.vue | 4568 ++++ .../layouts/src/authentication/index.ts | 1 + .../layouts/src/authentication/toolbar.vue | 49 + .../layouts/src/authentication/types.ts | 1 + packages/effects/layouts/src/basic/README.md | 7 + .../src/basic/content/content-spinner.vue | 12 + .../layouts/src/basic/content/content.vue | 148 + .../layouts/src/basic/content/index.ts | 2 + .../src/basic/content/use-content-spinner.ts | 50 + .../layouts/src/basic/copyright/copyright.vue | 48 + .../layouts/src/basic/copyright/index.ts | 1 + .../layouts/src/basic/footer/footer.vue | 11 + .../effects/layouts/src/basic/footer/index.ts | 1 + .../layouts/src/basic/header/header.vue | 185 + .../effects/layouts/src/basic/header/index.ts | 1 + packages/effects/layouts/src/basic/index.ts | 1 + packages/effects/layouts/src/basic/layout.vue | 371 + .../layouts/src/basic/menu/extra-menu.vue | 41 + .../effects/layouts/src/basic/menu/index.ts | 5 + .../effects/layouts/src/basic/menu/menu.vue | 45 + .../layouts/src/basic/menu/mixed-menu.vue | 46 + .../layouts/src/basic/menu/use-extra-menu.ts | 133 + .../layouts/src/basic/menu/use-mixed-menu.ts | 169 + .../layouts/src/basic/menu/use-navigation.ts | 63 + .../effects/layouts/src/basic/tabbar/index.ts | 2 + .../layouts/src/basic/tabbar/tabbar.vue | 75 + .../layouts/src/basic/tabbar/use-tabbar.ts | 223 + .../layouts/src/iframe/iframe-router-view.vue | 86 + .../layouts/src/iframe/iframe-view.vue | 3 + packages/effects/layouts/src/iframe/index.ts | 2 + packages/effects/layouts/src/index.ts | 4 + .../layouts/src/widgets/breadcrumb.vue | 74 + .../widgets/check-updates/check-updates.vue | 135 + .../src/widgets/check-updates/index.ts | 1 + .../layouts/src/widgets/color-toggle.vue | 64 + .../widgets/global-search/global-search.vue | 157 + .../src/widgets/global-search/index.ts | 1 + .../widgets/global-search/search-panel.vue | 288 + packages/effects/layouts/src/widgets/index.ts | 11 + .../layouts/src/widgets/language-toggle.vue | 39 + .../layouts/src/widgets/layout-toggle.vue | 64 + .../layouts/src/widgets/lock-screen/index.ts | 2 + .../widgets/lock-screen/lock-screen-modal.vue | 102 + .../src/widgets/lock-screen/lock-screen.vue | 156 + .../layouts/src/widgets/notification/index.ts | 3 + .../src/widgets/notification/notification.vue | 195 + .../layouts/src/widgets/notification/types.ts | 10 + .../src/widgets/preferences/blocks/block.vue | 22 + .../preferences/blocks/checkbox-item.vue | 63 + .../preferences/blocks/general/animation.vue | 51 + .../preferences/blocks/general/general.vue | 31 + .../src/widgets/preferences/blocks/index.ts | 19 + .../widgets/preferences/blocks/input-item.vue | 52 + .../preferences/blocks/layout/breadcrumb.vue | 56 + .../preferences/blocks/layout/content.vue | 53 + .../preferences/blocks/layout/copyright.vue | 44 + .../preferences/blocks/layout/footer.vue | 17 + .../preferences/blocks/layout/header.vue | 74 + .../preferences/blocks/layout/layout.vue | 112 + .../preferences/blocks/layout/navigation.vue | 45 + .../preferences/blocks/layout/sidebar.vue | 100 + .../preferences/blocks/layout/tabbar.vue | 94 + .../preferences/blocks/layout/widget.vue | 71 + .../preferences/blocks/number-field-item.vue | 74 + .../preferences/blocks/select-item.vue | 68 + .../blocks/shortcut-keys/global.vue | 50 + .../preferences/blocks/switch-item.vue | 55 + .../preferences/blocks/theme/builtin.vue | 161 + .../preferences/blocks/theme/color-mode.vue | 26 + .../preferences/blocks/theme/radius.vue | 38 + .../preferences/blocks/theme/theme.vue | 83 + .../preferences/blocks/toggle-item.vue | 46 + .../preferences/icons/content-compact.vue | 119 + .../preferences/icons/full-content.vue | 50 + .../preferences/icons/header-mixed-nav.vue | 202 + .../widgets/preferences/icons/header-nav.vue | 119 + .../preferences/icons/header-sidebar-nav.vue | 177 + .../src/widgets/preferences/icons/index.ts | 12 + .../widgets/preferences/icons/mixed-nav.vue | 161 + .../src/widgets/preferences/icons/setting.vue | 12 + .../preferences/icons/sidebar-mixed-nav.vue | 173 + .../widgets/preferences/icons/sidebar-nav.vue | 153 + .../layouts/src/widgets/preferences/index.ts | 3 + .../preferences/preferences-button.vue | 20 + .../preferences/preferences-drawer.vue | 449 + .../src/widgets/preferences/preferences.vue | 72 + .../preferences/use-open-preferences.ts | 16 + .../layouts/src/widgets/theme-toggle/index.ts | 1 + .../src/widgets/theme-toggle/theme-button.vue | 185 + .../src/widgets/theme-toggle/theme-toggle.vue | 83 + .../src/widgets/user-dropdown/index.ts | 1 + .../widgets/user-dropdown/user-dropdown.vue | 258 + packages/effects/layouts/tsconfig.json | 6 + packages/effects/plugins/README.md | 28 + packages/effects/plugins/package.json | 47 + .../plugins/src/echarts/echarts-ui.vue | 15 + .../effects/plugins/src/echarts/echarts.ts | 59 + packages/effects/plugins/src/echarts/index.ts | 3 + .../plugins/src/echarts/use-echarts.ts | 122 + packages/effects/plugins/src/motion/index.ts | 8 + packages/effects/plugins/src/motion/types.ts | 26 + packages/effects/plugins/src/vxe-table/api.ts | 128 + .../effects/plugins/src/vxe-table/extends.ts | 81 + .../effects/plugins/src/vxe-table/index.ts | 6 + .../effects/plugins/src/vxe-table/init.ts | 131 + .../effects/plugins/src/vxe-table/style.css | 117 + .../effects/plugins/src/vxe-table/types.ts | 86 + .../plugins/src/vxe-table/use-vxe-grid.ts | 45 + .../plugins/src/vxe-table/use-vxe-grid.vue | 470 + packages/effects/plugins/tsconfig.json | 6 + packages/effects/request/package.json | 32 + packages/effects/request/src/index.ts | 2 + .../request/src/request-client/index.ts | 3 + .../request-client/modules/downloader.test.ts | 86 + .../src/request-client/modules/downloader.ts | 41 + .../src/request-client/modules/interceptor.ts | 40 + .../request-client/modules/uploader.test.ts | 118 + .../src/request-client/modules/uploader.ts | 40 + .../src/request-client/preset-interceptors.ts | 165 + .../src/request-client/request-client.test.ts | 99 + .../src/request-client/request-client.ts | 150 + .../request/src/request-client/types.ts | 81 + packages/effects/request/tsconfig.json | 6 + packages/icons/README.md | 19 + packages/icons/package.json | 22 + packages/icons/src/iconify/index.ts | 17 + packages/icons/src/icons/empty-icon.vue | 27 + packages/icons/src/index.ts | 3 + packages/icons/src/svg/icons/antdv-logo.svg | 29 + packages/icons/src/svg/icons/avatar-1.svg | 1 + packages/icons/src/svg/icons/avatar-2.svg | 1 + packages/icons/src/svg/icons/avatar-3.svg | 1 + packages/icons/src/svg/icons/avatar-4.svg | 1 + packages/icons/src/svg/icons/bell.svg | 1 + packages/icons/src/svg/icons/cake.svg | 1 + packages/icons/src/svg/icons/card.svg | 1 + packages/icons/src/svg/icons/download.svg | 1 + packages/icons/src/svg/index.ts | 25 + packages/icons/src/svg/load.ts | 61 + packages/icons/tsconfig.json | 6 + packages/locales/package.json | 28 + packages/locales/src/i18n.ts | 147 + packages/locales/src/index.ts | 30 + .../src/langs/en-US/authentication.json | 56 + packages/locales/src/langs/en-US/common.json | 24 + .../locales/src/langs/en-US/preferences.json | 189 + packages/locales/src/langs/en-US/ui.json | 104 + .../src/langs/zh-CN/authentication.json | 56 + packages/locales/src/langs/zh-CN/common.json | 24 + .../locales/src/langs/zh-CN/preferences.json | 189 + packages/locales/src/langs/zh-CN/ui.json | 104 + packages/locales/src/typing.ts | 25 + packages/locales/tsconfig.json | 6 + packages/preferences/package.json | 26 + packages/preferences/src/index.ts | 17 + packages/preferences/tsconfig.json | 6 + packages/stores/package.json | 33 + packages/stores/shim-pinia.d.ts | 9 + packages/stores/src/index.ts | 3 + packages/stores/src/modules/access.test.ts | 46 + packages/stores/src/modules/access.ts | 137 + packages/stores/src/modules/index.ts | 3 + packages/stores/src/modules/tabbar.test.ts | 295 + packages/stores/src/modules/tabbar.ts | 592 + packages/stores/src/modules/user.test.ts | 37 + packages/stores/src/modules/user.ts | 119 + packages/stores/src/setup.ts | 60 + packages/stores/tsconfig.json | 5 + packages/styles/README.md | 19 + packages/styles/package.json | 34 + packages/styles/src/antd/index.css | 75 + packages/styles/src/ele/index.css | 44 + packages/styles/src/global/index.scss | 1 + packages/styles/src/index.ts | 1 + packages/styles/src/naive/index.css | 20 + packages/styles/tsconfig.json | 6 + packages/types/README.md | 20 + packages/types/global.d.ts | 22 + packages/types/package.json | 27 + packages/types/src/index.ts | 2 + packages/types/src/user.ts | 20 + packages/types/tsconfig.json | 6 + packages/utils/README.md | 19 + packages/utils/package.json | 27 + .../__tests__/find-menu-by-path.test.ts | 88 + .../helpers/__tests__/generate-menus.test.ts | 233 + .../generate-routes-frontend.test.ts | 105 + .../__tests__/merge-route-modules.test.ts | 68 + .../utils/src/helpers/find-menu-by-path.ts | 37 + packages/utils/src/helpers/generate-menus.ts | 90 + .../src/helpers/generate-routes-backend.ts | 86 + .../src/helpers/generate-routes-frontend.ts | 58 + .../utils/src/helpers/get-popup-container.ts | 10 + packages/utils/src/helpers/index.ts | 8 + .../utils/src/helpers/merge-route-modules.ts | 28 + packages/utils/src/helpers/reset-routes.ts | 31 + .../src/helpers/unmount-global-loading.ts | 31 + packages/utils/src/index.ts | 4 + packages/utils/tsconfig.json | 9 + pnpm-lock.yaml | 19742 ++++++++++++++++ pnpm-workspace.yaml | 193 + scripts/clean.mjs | 56 + scripts/deploy/Dockerfile | 37 + scripts/deploy/build-local-docker-image.sh | 55 + scripts/deploy/nginx.conf | 75 + scripts/turbo-run/README.md | 59 + scripts/turbo-run/bin/turbo-run.mjs | 3 + scripts/turbo-run/build.config.ts | 7 + scripts/turbo-run/package.json | 29 + scripts/turbo-run/src/index.ts | 29 + scripts/turbo-run/src/run.ts | 67 + scripts/turbo-run/tsconfig.json | 6 + scripts/vsh/README.md | 56 + scripts/vsh/bin/vsh.mjs | 3 + scripts/vsh/build.config.ts | 7 + scripts/vsh/package.json | 31 + scripts/vsh/src/check-circular/index.ts | 170 + scripts/vsh/src/check-dep/index.ts | 194 + scripts/vsh/src/code-workspace/index.ts | 78 + scripts/vsh/src/index.ts | 74 + scripts/vsh/src/lint/index.ts | 48 + scripts/vsh/src/publint/index.ts | 185 + scripts/vsh/tsconfig.json | 6 + stylelint.config.mjs | 4 + tea.yaml | 6 + turbo.json | 49 + vben-admin.code-workspace | 152 + vitest.config.ts | 11 + vitest.workspace.ts | 3 + 1069 files changed, 109962 insertions(+) create mode 100644 .browserslistrc create mode 100644 .commitlintrc.js create mode 100644 .dockerignore create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitconfig create mode 100644 .gitignore create mode 100644 .gitpod.yml create mode 100644 .husky/_/commit-msg create mode 100644 .husky/_/post-merge create mode 100644 .husky/_/pre-commit create mode 100644 .husky/_/prepare-commit-msg create mode 100644 .node-version create mode 100644 .npmrc create mode 100644 .prettierignore create mode 100644 .prettierrc.mjs create mode 100644 .stylelintignore create mode 100644 .vscode/extensions.json create mode 100644 .vscode/global.code-snippets create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 Dockerfile create mode 100644 _nginx/nginx.conf create mode 100644 apps/web-antd/.env create mode 100644 apps/web-antd/.env.analyze create mode 100644 apps/web-antd/.env.development create mode 100644 apps/web-antd/.env.production create mode 100644 apps/web-antd/index.html create mode 100644 apps/web-antd/package.json create mode 100644 apps/web-antd/postcss.config.mjs create mode 100644 apps/web-antd/public/avatar-v1.webp create mode 100644 apps/web-antd/public/favicon.ico create mode 100644 apps/web-antd/public/logo-v1.webp create mode 100644 apps/web-antd/src/adapter/component/index.ts create mode 100644 apps/web-antd/src/adapter/form.ts create mode 100644 apps/web-antd/src/adapter/vxe-table.ts create mode 100644 apps/web-antd/src/api-client-config/config.ts create mode 100644 apps/web-antd/src/api-client-config/index.ts create mode 100644 apps/web-antd/src/api-client/index.ts create mode 100644 apps/web-antd/src/api-client/schemas.gen.ts create mode 100644 apps/web-antd/src/api-client/services.gen.ts create mode 100644 apps/web-antd/src/api-client/types.gen.ts create mode 100644 apps/web-antd/src/api/core/auth.ts create mode 100644 apps/web-antd/src/api/core/index.ts create mode 100644 apps/web-antd/src/api/core/menu.ts create mode 100644 apps/web-antd/src/api/core/user.ts create mode 100644 apps/web-antd/src/api/index.ts create mode 100644 apps/web-antd/src/api/request.ts create mode 100644 apps/web-antd/src/app.vue create mode 100644 apps/web-antd/src/bootstrap.ts create mode 100644 apps/web-antd/src/components/Loading/index.ts create mode 100644 apps/web-antd/src/components/Loading/src/Loading.vue create mode 100644 apps/web-antd/src/components/Loading/src/createLoading.ts create mode 100644 apps/web-antd/src/components/Loading/src/typing.ts create mode 100644 apps/web-antd/src/components/Loading/src/useLoading.ts create mode 100644 apps/web-antd/src/components/icon/icon.vue create mode 100644 apps/web-antd/src/components/icon/index.ts create mode 100644 apps/web-antd/src/components/table-action/index.ts create mode 100644 apps/web-antd/src/components/table-action/table-action.vue create mode 100644 apps/web-antd/src/components/table-action/types.d.ts create mode 100644 apps/web-antd/src/hooks/useLoadIcon.ts create mode 100644 apps/web-antd/src/hooks/useSignalR.ts create mode 100644 apps/web-antd/src/layouts/NotifyItem.vue create mode 100644 apps/web-antd/src/layouts/auth.vue create mode 100644 apps/web-antd/src/layouts/basic.vue create mode 100644 apps/web-antd/src/layouts/change-password.vue create mode 100644 apps/web-antd/src/layouts/index.ts create mode 100644 apps/web-antd/src/layouts/my-profile.vue create mode 100644 apps/web-antd/src/locales/README.md create mode 100644 apps/web-antd/src/locales/index.ts create mode 100644 apps/web-antd/src/locales/langs/en-US/abp.json create mode 100644 apps/web-antd/src/locales/langs/en-US/code.json create mode 100644 apps/web-antd/src/locales/langs/en-US/common.json create mode 100644 apps/web-antd/src/locales/langs/en-US/demos.json create mode 100644 apps/web-antd/src/locales/langs/en-US/page.json create mode 100644 apps/web-antd/src/locales/langs/en-US/textTemplate.json create mode 100644 apps/web-antd/src/locales/langs/zh-CN/abp.json create mode 100644 apps/web-antd/src/locales/langs/zh-CN/code.json create mode 100644 apps/web-antd/src/locales/langs/zh-CN/common.json create mode 100644 apps/web-antd/src/locales/langs/zh-CN/demos.json create mode 100644 apps/web-antd/src/locales/langs/zh-CN/page.json create mode 100644 apps/web-antd/src/locales/langs/zh-CN/textTemplate.json create mode 100644 apps/web-antd/src/main.ts create mode 100644 apps/web-antd/src/preferences.ts create mode 100644 apps/web-antd/src/router/access.ts create mode 100644 apps/web-antd/src/router/guard.ts create mode 100644 apps/web-antd/src/router/index.ts create mode 100644 apps/web-antd/src/router/routes/core.ts create mode 100644 apps/web-antd/src/router/routes/index.ts create mode 100644 apps/web-antd/src/router/routes/modules/code.ts create mode 100644 apps/web-antd/src/router/routes/modules/dashboard.ts create mode 100644 apps/web-antd/src/router/routes/modules/demos.ts create mode 100644 apps/web-antd/src/router/routes/modules/file.ts create mode 100644 apps/web-antd/src/router/routes/modules/system.ts create mode 100644 apps/web-antd/src/router/routes/modules/tenant.ts create mode 100644 apps/web-antd/src/router/routes/modules/textTemplate.ts create mode 100644 apps/web-antd/src/router/routes/modules/vben.ts create mode 100644 apps/web-antd/src/store/auth.ts create mode 100644 apps/web-antd/src/store/index.ts create mode 100644 apps/web-antd/src/views/_core/README.md create mode 100644 apps/web-antd/src/views/_core/about/index.vue create mode 100644 apps/web-antd/src/views/_core/authentication/code-login.vue create mode 100644 apps/web-antd/src/views/_core/authentication/forget-password.vue create mode 100644 apps/web-antd/src/views/_core/authentication/login.vue create mode 100644 apps/web-antd/src/views/_core/authentication/oidc-login.vue create mode 100644 apps/web-antd/src/views/_core/authentication/qrcode-login.vue create mode 100644 apps/web-antd/src/views/_core/authentication/register.vue create mode 100644 apps/web-antd/src/views/_core/fallback/coming-soon.vue create mode 100644 apps/web-antd/src/views/_core/fallback/forbidden.vue create mode 100644 apps/web-antd/src/views/_core/fallback/internal-error.vue create mode 100644 apps/web-antd/src/views/_core/fallback/not-found.vue create mode 100644 apps/web-antd/src/views/_core/fallback/offline.vue create mode 100644 apps/web-antd/src/views/code/generate/index.vue create mode 100644 apps/web-antd/src/views/code/generate/preview.vue create mode 100644 apps/web-antd/src/views/code/project/AddModal.vue create mode 100644 apps/web-antd/src/views/code/project/EditModal.vue create mode 100644 apps/web-antd/src/views/code/project/entityModel/AddAggregateRootModal.vue create mode 100644 apps/web-antd/src/views/code/project/entityModel/AddEditEntityModal.vue create mode 100644 apps/web-antd/src/views/code/project/entityModel/AddEditEntityPropertyModal.vue create mode 100644 apps/web-antd/src/views/code/project/entityModel/AddEditEnumModal.vue create mode 100644 apps/web-antd/src/views/code/project/entityModel/AddEditEnumPropertyModal.vue create mode 100644 apps/web-antd/src/views/code/project/entityModel/index.vue create mode 100644 apps/web-antd/src/views/code/project/index.vue create mode 100644 apps/web-antd/src/views/code/project/schema.ts create mode 100644 apps/web-antd/src/views/code/template/AddEditTemplateModal.vue create mode 100644 apps/web-antd/src/views/code/template/AddModal.vue create mode 100644 apps/web-antd/src/views/code/template/CopyModal.vue create mode 100644 apps/web-antd/src/views/code/template/EditModal.vue create mode 100644 apps/web-antd/src/views/code/template/TemplateDetail.vue create mode 100644 apps/web-antd/src/views/code/template/index.vue create mode 100644 apps/web-antd/src/views/code/template/schema.ts create mode 100644 apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue create mode 100644 apps/web-antd/src/views/dashboard/analytics/analytics-visits-data.vue create mode 100644 apps/web-antd/src/views/dashboard/analytics/analytics-visits-sales.vue create mode 100644 apps/web-antd/src/views/dashboard/analytics/analytics-visits-source.vue create mode 100644 apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue create mode 100644 apps/web-antd/src/views/dashboard/analytics/index.vue create mode 100644 apps/web-antd/src/views/dashboard/workspace/index.vue create mode 100644 apps/web-antd/src/views/demos/antd/index.vue create mode 100644 apps/web-antd/src/views/demos/listPage/AddEditModal.vue create mode 100644 apps/web-antd/src/views/demos/listPage/index.vue create mode 100644 apps/web-antd/src/views/demos/listPage/mock.ts create mode 100644 apps/web-antd/src/views/system/abpdatadictionary/DataDictionaryDetailModal.vue create mode 100644 apps/web-antd/src/views/system/abpdatadictionary/DataDictionaryModal.vue create mode 100644 apps/web-antd/src/views/system/abpdatadictionary/index.vue create mode 100644 apps/web-antd/src/views/system/abpfeature/index.vue create mode 100644 apps/web-antd/src/views/system/abpfiles/AddModal.vue create mode 100644 apps/web-antd/src/views/system/abpfiles/index.vue create mode 100644 apps/web-antd/src/views/system/abpfiles/schema.ts create mode 100644 apps/web-antd/src/views/system/abplanguage/AddLanguageTextModal.vue create mode 100644 apps/web-antd/src/views/system/abplanguage/EditLanguageTextModal.vue create mode 100644 apps/web-antd/src/views/system/abplanguage/language.vue create mode 100644 apps/web-antd/src/views/system/abplanguage/languagetext.vue create mode 100644 apps/web-antd/src/views/system/abplanguage/schema.ts create mode 100644 apps/web-antd/src/views/system/abplog/audit.vue create mode 100644 apps/web-antd/src/views/system/abplog/login.vue create mode 100644 apps/web-antd/src/views/system/abplog/schema.ts create mode 100644 apps/web-antd/src/views/system/abpmenu/AddModal.vue create mode 100644 apps/web-antd/src/views/system/abpmenu/EditModal.vue create mode 100644 apps/web-antd/src/views/system/abpmenu/index.vue create mode 100644 apps/web-antd/src/views/system/abpmenu/schema.ts create mode 100644 apps/web-antd/src/views/system/abpnotification/message.vue create mode 100644 apps/web-antd/src/views/system/abpnotification/notification.vue create mode 100644 apps/web-antd/src/views/system/abpnotification/schema.ts create mode 100644 apps/web-antd/src/views/system/abporganizationunit/ContextMenu.vue create mode 100644 apps/web-antd/src/views/system/abporganizationunit/OrgTreeAddModal.vue create mode 100644 apps/web-antd/src/views/system/abporganizationunit/OrgTreeEditModal.vue create mode 100644 apps/web-antd/src/views/system/abporganizationunit/index.vue create mode 100644 apps/web-antd/src/views/system/abprole/index.vue create mode 100644 apps/web-antd/src/views/system/abprole/schema.ts create mode 100644 apps/web-antd/src/views/system/abpsetting/index.vue create mode 100644 apps/web-antd/src/views/system/abptenant/AddEditModal.vue create mode 100644 apps/web-antd/src/views/system/abptenant/ConnectionStringModal.vue create mode 100644 apps/web-antd/src/views/system/abptenant/FeatureManageModal.vue create mode 100644 apps/web-antd/src/views/system/abptenant/index.vue create mode 100644 apps/web-antd/src/views/system/abptenant/schema.ts create mode 100644 apps/web-antd/src/views/system/abpuser/index.vue create mode 100644 apps/web-antd/src/views/system/abpuser/schema.ts create mode 100644 apps/web-antd/src/views/textTemplate/AddModal.vue create mode 100644 apps/web-antd/src/views/textTemplate/EditModal.vue create mode 100644 apps/web-antd/src/views/textTemplate/index.vue create mode 100644 apps/web-antd/src/views/textTemplate/schema.ts create mode 100644 apps/web-antd/tailwind.config.mjs create mode 100644 apps/web-antd/tsconfig.json create mode 100644 apps/web-antd/tsconfig.node.json create mode 100644 apps/web-antd/vite.config.mts create mode 100644 cspell.json create mode 100644 eslint.config.mjs create mode 100644 internal/lint-configs/commitlint-config/index.mjs create mode 100644 internal/lint-configs/commitlint-config/package.json create mode 100644 internal/lint-configs/eslint-config/build.config.ts create mode 100644 internal/lint-configs/eslint-config/package.json create mode 100644 internal/lint-configs/eslint-config/src/configs/command.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/comments.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/disableds.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/ignores.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/import.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/index.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/javascript.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/jsdoc.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/jsonc.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/node.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/perfectionist.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/prettier.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/regexp.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/test.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/turbo.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/typescript.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/unicorn.ts create mode 100644 internal/lint-configs/eslint-config/src/configs/vue.ts create mode 100644 internal/lint-configs/eslint-config/src/custom-config.ts create mode 100644 internal/lint-configs/eslint-config/src/index.ts create mode 100644 internal/lint-configs/eslint-config/src/util.ts create mode 100644 internal/lint-configs/eslint-config/tsconfig.json create mode 100644 internal/lint-configs/prettier-config/index.mjs create mode 100644 internal/lint-configs/prettier-config/package.json create mode 100644 internal/lint-configs/stylelint-config/index.mjs create mode 100644 internal/lint-configs/stylelint-config/package.json create mode 100644 internal/node-utils/build.config.ts create mode 100644 internal/node-utils/package.json create mode 100644 internal/node-utils/src/__tests__/hash.test.ts create mode 100644 internal/node-utils/src/__tests__/path.test.ts create mode 100644 internal/node-utils/src/constants.ts create mode 100644 internal/node-utils/src/date.ts create mode 100644 internal/node-utils/src/fs.ts create mode 100644 internal/node-utils/src/git.ts create mode 100644 internal/node-utils/src/hash.ts create mode 100644 internal/node-utils/src/index.ts create mode 100644 internal/node-utils/src/monorepo.ts create mode 100644 internal/node-utils/src/path.ts create mode 100644 internal/node-utils/src/prettier.ts create mode 100644 internal/node-utils/src/spinner.ts create mode 100644 internal/node-utils/tsconfig.json create mode 100644 internal/tailwind-config/build.config.ts create mode 100644 internal/tailwind-config/package.json create mode 100644 internal/tailwind-config/src/index.ts create mode 100644 internal/tailwind-config/src/module.d.ts create mode 100644 internal/tailwind-config/src/plugins/entry.ts create mode 100644 internal/tailwind-config/src/postcss.config.ts create mode 100644 internal/tailwind-config/tsconfig.json create mode 100644 internal/tsconfig/base.json create mode 100644 internal/tsconfig/library.json create mode 100644 internal/tsconfig/node.json create mode 100644 internal/tsconfig/package.json create mode 100644 internal/tsconfig/web-app.json create mode 100644 internal/tsconfig/web.json create mode 100644 internal/vite-config/build.config.ts create mode 100644 internal/vite-config/package.json create mode 100644 internal/vite-config/src/config/application.ts create mode 100644 internal/vite-config/src/config/common.ts create mode 100644 internal/vite-config/src/config/index.ts create mode 100644 internal/vite-config/src/config/library.ts create mode 100644 internal/vite-config/src/index.ts create mode 100644 internal/vite-config/src/options.ts create mode 100644 internal/vite-config/src/plugins/archiver.ts create mode 100644 internal/vite-config/src/plugins/extra-app-config.ts create mode 100644 internal/vite-config/src/plugins/importmap.ts create mode 100644 internal/vite-config/src/plugins/index.ts create mode 100644 internal/vite-config/src/plugins/inject-app-loading/README.md create mode 100644 internal/vite-config/src/plugins/inject-app-loading/default-loading-antd.html create mode 100644 internal/vite-config/src/plugins/inject-app-loading/default-loading.html create mode 100644 internal/vite-config/src/plugins/inject-app-loading/index.ts create mode 100644 internal/vite-config/src/plugins/inject-metadata.ts create mode 100644 internal/vite-config/src/plugins/license.ts create mode 100644 internal/vite-config/src/plugins/nitro-mock.ts create mode 100644 internal/vite-config/src/plugins/print.ts create mode 100644 internal/vite-config/src/plugins/vxe-table.ts create mode 100644 internal/vite-config/src/typing.ts create mode 100644 internal/vite-config/src/utils/env.ts create mode 100644 internal/vite-config/tsconfig.json create mode 100644 lefthook.yml create mode 100644 package.json create mode 100644 packages/@core/README.md create mode 100644 packages/@core/base/README.md create mode 100644 packages/@core/base/design/package.json create mode 100644 packages/@core/base/design/src/css/global.css create mode 100644 packages/@core/base/design/src/css/nprogress.css create mode 100644 packages/@core/base/design/src/css/transition.css create mode 100644 packages/@core/base/design/src/css/ui.css create mode 100644 packages/@core/base/design/src/design-tokens/dark.css create mode 100644 packages/@core/base/design/src/design-tokens/default.css create mode 100644 packages/@core/base/design/src/design-tokens/index.ts create mode 100644 packages/@core/base/design/src/index.ts create mode 100644 packages/@core/base/design/src/scss-bem/bem.scss create mode 100644 packages/@core/base/design/src/scss-bem/constants.scss create mode 100644 packages/@core/base/design/tsconfig.json create mode 100644 packages/@core/base/design/vite.config.mts create mode 100644 packages/@core/base/icons/build.config.ts create mode 100644 packages/@core/base/icons/package.json create mode 100644 packages/@core/base/icons/src/create-icon.ts create mode 100644 packages/@core/base/icons/src/index.ts create mode 100644 packages/@core/base/icons/src/lucide.ts create mode 100644 packages/@core/base/icons/tsconfig.json create mode 100644 packages/@core/base/shared/build.config.ts create mode 100644 packages/@core/base/shared/package.json create mode 100644 packages/@core/base/shared/src/cache/__tests__/storage-manager.test.ts create mode 100644 packages/@core/base/shared/src/cache/index.ts create mode 100644 packages/@core/base/shared/src/cache/storage-manager.ts create mode 100644 packages/@core/base/shared/src/cache/types.ts create mode 100644 packages/@core/base/shared/src/color/__tests__/convert.test.ts create mode 100644 packages/@core/base/shared/src/color/color.ts create mode 100644 packages/@core/base/shared/src/color/convert.ts create mode 100644 packages/@core/base/shared/src/color/generator.ts create mode 100644 packages/@core/base/shared/src/color/index.ts create mode 100644 packages/@core/base/shared/src/constants/globals.ts create mode 100644 packages/@core/base/shared/src/constants/index.ts create mode 100644 packages/@core/base/shared/src/constants/vben.ts create mode 100644 packages/@core/base/shared/src/global-state.ts create mode 100644 packages/@core/base/shared/src/store.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/diff.test.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/dom.test.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/inference.test.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/letter.test.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/state-handler.test.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/tree.test.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/unique.test.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/update-css-variables.test.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/util.test.ts create mode 100644 packages/@core/base/shared/src/utils/__tests__/window.test.ts create mode 100644 packages/@core/base/shared/src/utils/cn.ts create mode 100644 packages/@core/base/shared/src/utils/date.ts create mode 100644 packages/@core/base/shared/src/utils/diff.ts create mode 100644 packages/@core/base/shared/src/utils/dom.ts create mode 100644 packages/@core/base/shared/src/utils/download.ts create mode 100644 packages/@core/base/shared/src/utils/index.ts create mode 100644 packages/@core/base/shared/src/utils/inference.ts create mode 100644 packages/@core/base/shared/src/utils/letter.ts create mode 100644 packages/@core/base/shared/src/utils/merge.ts create mode 100644 packages/@core/base/shared/src/utils/nprogress.ts create mode 100644 packages/@core/base/shared/src/utils/state-handler.ts create mode 100644 packages/@core/base/shared/src/utils/to.ts create mode 100644 packages/@core/base/shared/src/utils/tree.ts create mode 100644 packages/@core/base/shared/src/utils/unique.ts create mode 100644 packages/@core/base/shared/src/utils/update-css-variables.ts create mode 100644 packages/@core/base/shared/src/utils/util.ts create mode 100644 packages/@core/base/shared/src/utils/window.ts create mode 100644 packages/@core/base/shared/tsconfig.json create mode 100644 packages/@core/base/typings/build.config.ts create mode 100644 packages/@core/base/typings/package.json create mode 100644 packages/@core/base/typings/src/app.d.ts create mode 100644 packages/@core/base/typings/src/basic.d.ts create mode 100644 packages/@core/base/typings/src/helper.d.ts create mode 100644 packages/@core/base/typings/src/index.ts create mode 100644 packages/@core/base/typings/src/menu-record.ts create mode 100644 packages/@core/base/typings/src/tabs.ts create mode 100644 packages/@core/base/typings/src/vue-router.d.ts create mode 100644 packages/@core/base/typings/tsconfig.json create mode 100644 packages/@core/base/typings/vue-router.d.ts create mode 100644 packages/@core/composables/build.config.ts create mode 100644 packages/@core/composables/package.json create mode 100644 packages/@core/composables/src/__tests__/use-sortable.test.ts create mode 100644 packages/@core/composables/src/index.ts create mode 100644 packages/@core/composables/src/use-is-mobile.ts create mode 100644 packages/@core/composables/src/use-layout-style.ts create mode 100644 packages/@core/composables/src/use-namespace.ts create mode 100644 packages/@core/composables/src/use-priority-value.ts create mode 100644 packages/@core/composables/src/use-scroll-lock.ts create mode 100644 packages/@core/composables/src/use-simple-locale/README.md create mode 100644 packages/@core/composables/src/use-simple-locale/index.ts create mode 100644 packages/@core/composables/src/use-simple-locale/messages.ts create mode 100644 packages/@core/composables/src/use-sortable.ts create mode 100644 packages/@core/composables/tsconfig.json create mode 100644 packages/@core/preferences/__tests__/__snapshots__/config.test.ts.snap create mode 100644 packages/@core/preferences/__tests__/config.test.ts create mode 100644 packages/@core/preferences/__tests__/preferences.test.ts create mode 100644 packages/@core/preferences/build.config.ts create mode 100644 packages/@core/preferences/package.json create mode 100644 packages/@core/preferences/src/config.ts create mode 100644 packages/@core/preferences/src/constants.ts create mode 100644 packages/@core/preferences/src/index.ts create mode 100644 packages/@core/preferences/src/preferences.ts create mode 100644 packages/@core/preferences/src/types.ts create mode 100644 packages/@core/preferences/src/update-css-variables.ts create mode 100644 packages/@core/preferences/src/use-preferences.ts create mode 100644 packages/@core/preferences/tsconfig.json create mode 100644 packages/@core/ui-kit/README.md create mode 100644 packages/@core/ui-kit/form-ui/__tests__/form-api.test.ts create mode 100644 packages/@core/ui-kit/form-ui/build.config.ts create mode 100644 packages/@core/ui-kit/form-ui/package.json create mode 100644 packages/@core/ui-kit/form-ui/postcss.config.mjs create mode 100644 packages/@core/ui-kit/form-ui/src/components/form-actions.vue create mode 100644 packages/@core/ui-kit/form-ui/src/config.ts create mode 100644 packages/@core/ui-kit/form-ui/src/form-api.ts create mode 100644 packages/@core/ui-kit/form-ui/src/form-render/context.ts create mode 100644 packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts create mode 100644 packages/@core/ui-kit/form-ui/src/form-render/expandable.ts create mode 100644 packages/@core/ui-kit/form-ui/src/form-render/form-field.vue create mode 100644 packages/@core/ui-kit/form-ui/src/form-render/form-label.vue create mode 100644 packages/@core/ui-kit/form-ui/src/form-render/form.vue create mode 100644 packages/@core/ui-kit/form-ui/src/form-render/helper.ts create mode 100644 packages/@core/ui-kit/form-ui/src/form-render/index.ts create mode 100644 packages/@core/ui-kit/form-ui/src/index.ts create mode 100644 packages/@core/ui-kit/form-ui/src/types.ts create mode 100644 packages/@core/ui-kit/form-ui/src/use-form-context.ts create mode 100644 packages/@core/ui-kit/form-ui/src/use-vben-form.ts create mode 100644 packages/@core/ui-kit/form-ui/src/vben-form.vue create mode 100644 packages/@core/ui-kit/form-ui/src/vben-use-form.vue create mode 100644 packages/@core/ui-kit/form-ui/tailwind.config.mjs create mode 100644 packages/@core/ui-kit/form-ui/tsconfig.json create mode 100644 packages/@core/ui-kit/layout-ui/build.config.ts create mode 100644 packages/@core/ui-kit/layout-ui/package.json create mode 100644 packages/@core/ui-kit/layout-ui/postcss.config.mjs create mode 100644 packages/@core/ui-kit/layout-ui/src/components/index.ts create mode 100644 packages/@core/ui-kit/layout-ui/src/components/layout-content.vue create mode 100644 packages/@core/ui-kit/layout-ui/src/components/layout-footer.vue create mode 100644 packages/@core/ui-kit/layout-ui/src/components/layout-header.vue create mode 100644 packages/@core/ui-kit/layout-ui/src/components/layout-sidebar.vue create mode 100644 packages/@core/ui-kit/layout-ui/src/components/layout-tabbar.vue create mode 100644 packages/@core/ui-kit/layout-ui/src/components/widgets/index.ts create mode 100644 packages/@core/ui-kit/layout-ui/src/components/widgets/sidebar-collapse-button.vue create mode 100644 packages/@core/ui-kit/layout-ui/src/components/widgets/sidebar-fixed-button.vue create mode 100644 packages/@core/ui-kit/layout-ui/src/hooks/use-layout.ts create mode 100644 packages/@core/ui-kit/layout-ui/src/index.ts create mode 100644 packages/@core/ui-kit/layout-ui/src/vben-layout.ts create mode 100644 packages/@core/ui-kit/layout-ui/src/vben-layout.vue create mode 100644 packages/@core/ui-kit/layout-ui/tailwind.config.mjs create mode 100644 packages/@core/ui-kit/layout-ui/tsconfig.json create mode 100644 packages/@core/ui-kit/menu-ui/README.md create mode 100644 packages/@core/ui-kit/menu-ui/build.config.ts create mode 100644 packages/@core/ui-kit/menu-ui/package.json create mode 100644 packages/@core/ui-kit/menu-ui/postcss.config.mjs create mode 100644 packages/@core/ui-kit/menu-ui/src/components/collapse-transition.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/components/index.ts create mode 100644 packages/@core/ui-kit/menu-ui/src/components/menu-badge-dot.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/components/menu-badge.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/components/menu-item.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/components/menu.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/components/normal-menu/index.ts create mode 100644 packages/@core/ui-kit/menu-ui/src/components/normal-menu/normal-menu.ts create mode 100644 packages/@core/ui-kit/menu-ui/src/components/normal-menu/normal-menu.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/components/sub-menu-content.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/components/sub-menu.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/hooks/index.ts create mode 100644 packages/@core/ui-kit/menu-ui/src/hooks/use-menu-context.ts create mode 100644 packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts create mode 100644 packages/@core/ui-kit/menu-ui/src/hooks/use-menu.ts create mode 100644 packages/@core/ui-kit/menu-ui/src/index.ts create mode 100644 packages/@core/ui-kit/menu-ui/src/menu.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/sub-menu.vue create mode 100644 packages/@core/ui-kit/menu-ui/src/types.ts create mode 100644 packages/@core/ui-kit/menu-ui/src/utils/index.ts create mode 100644 packages/@core/ui-kit/menu-ui/tailwind.config.mjs create mode 100644 packages/@core/ui-kit/menu-ui/tsconfig.json create mode 100644 packages/@core/ui-kit/popup-ui/build.config.ts create mode 100644 packages/@core/ui-kit/popup-ui/package.json create mode 100644 packages/@core/ui-kit/popup-ui/postcss.config.mjs create mode 100644 packages/@core/ui-kit/popup-ui/src/alert/AlertBuilder.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/alert/alert.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/alert/alert.vue create mode 100644 packages/@core/ui-kit/popup-ui/src/alert/index.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/drawer/__tests__/drawer-api.test.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue create mode 100644 packages/@core/ui-kit/popup-ui/src/drawer/index.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/drawer/use-drawer.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/index.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/modal/__tests__/modal-api.test.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/modal/index.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/modal/modal.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/modal/modal.vue create mode 100644 packages/@core/ui-kit/popup-ui/src/modal/use-modal-draggable.ts create mode 100644 packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts create mode 100644 packages/@core/ui-kit/popup-ui/tailwind.config.mjs create mode 100644 packages/@core/ui-kit/popup-ui/tsconfig.json create mode 100644 packages/@core/ui-kit/shadcn-ui/build.config.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/components.json create mode 100644 packages/@core/ui-kit/shadcn-ui/package.json create mode 100644 packages/@core/ui-kit/shadcn-ui/postcss.config.mjs create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/avatar/avatar.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/avatar/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/back-top/backtop.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/back-top/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/back-top/use-backtop.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb-background.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb-view.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/types.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/button/button-group.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/button/button.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/button/button.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/button/check-button-group.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/button/icon-button.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/button/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/checkbox/checkbox.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/checkbox/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/context-menu/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/context-menu/interface.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/count-to-animator/count-to-animator.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/count-to-animator/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/dropdown-menu.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/dropdown-radio-menu.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/interface.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/expandable-arrow/expandable-arrow.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/expandable-arrow/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/full-screen/full-screen.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/full-screen/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/hover-card/hover-card.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/hover-card/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/icon/icon.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/icon/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/input-password/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/input-password/input-password.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/input-password/password-strength.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/logo/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/logo/logo.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/pin-input/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/pin-input/input.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/pin-input/types.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/popover/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/popover/popover.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/render-content/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/render-content/render-content.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/scrollbar/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/scrollbar/scrollbar.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/segmented/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/segmented/segmented.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/segmented/tabs-indicator.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/segmented/types.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/select/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/select/select.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/spine-text/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/spine-text/spine-text.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/spinner/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/spinner/loading.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/spinner/spinner.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/tooltip/help-tooltip.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/tooltip/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/components/tooltip/tooltip.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/accordion/Accordion.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/accordion/AccordionContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/accordion/AccordionItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/accordion/AccordionTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/accordion/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/alert-dialog/AlertDialog.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/alert-dialog/AlertDialogAction.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/alert-dialog/AlertDialogCancel.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/alert-dialog/AlertDialogContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/alert-dialog/AlertDialogDescription.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/alert-dialog/AlertDialogOverlay.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/alert-dialog/AlertDialogTitle.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/alert-dialog/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/avatar/Avatar.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/avatar/AvatarFallback.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/avatar/AvatarImage.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/avatar/avatar.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/avatar/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/badge/Badge.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/badge/badge.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/badge/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/breadcrumb/Breadcrumb.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/breadcrumb/BreadcrumbEllipsis.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/breadcrumb/BreadcrumbItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/breadcrumb/BreadcrumbLink.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/breadcrumb/BreadcrumbList.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/breadcrumb/BreadcrumbPage.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/breadcrumb/BreadcrumbSeparator.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/breadcrumb/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/button/Button.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/button/button.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/button/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/button/types.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/card/Card.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/card/CardContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/card/CardDescription.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/card/CardFooter.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/card/CardHeader.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/card/CardTitle.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/card/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/checkbox/Checkbox.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/checkbox/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenu.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuCheckboxItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuGroup.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuLabel.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuPortal.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuRadioGroup.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuRadioItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuSeparator.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuShortcut.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuSub.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuSubContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuSubTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/ContextMenuTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/context-menu/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/Dialog.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogClose.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogDescription.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogFooter.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogHeader.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogOverlay.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogScrollContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogTitle.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dialog/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenu.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuCheckboxItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuGroup.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuLabel.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuRadioGroup.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuRadioItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuSeparator.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuShortcut.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuSub.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuSubContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuSubTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/DropdownMenuTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/dropdown-menu/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/form/FormControl.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/form/FormDescription.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/form/FormItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/form/FormLabel.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/form/FormMessage.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/form/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/form/injectionKeys.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/form/useFormField.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/hover-card/HoverCard.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/hover-card/HoverCardContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/hover-card/HoverCardTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/hover-card/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/input/Input.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/input/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/label/Label.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/label/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/number-field/NumberField.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/number-field/NumberFieldContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/number-field/NumberFieldDecrement.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/number-field/NumberFieldIncrement.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/number-field/NumberFieldInput.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/number-field/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pagination/PaginationEllipsis.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pagination/PaginationFirst.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pagination/PaginationLast.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pagination/PaginationNext.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pagination/PaginationPrev.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pagination/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pin-input/PinInput.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pin-input/PinInputGroup.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pin-input/PinInputInput.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pin-input/PinInputSeparator.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/pin-input/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/popover/Popover.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/popover/PopoverContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/popover/PopoverTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/popover/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/radio-group/RadioGroup.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/radio-group/RadioGroupItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/radio-group/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/resizable/ResizableHandle.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/resizable/ResizablePanelGroup.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/resizable/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/scroll-area/ScrollArea.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/scroll-area/ScrollBar.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/scroll-area/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/Select.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectGroup.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectItemText.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectLabel.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectScrollDownButton.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectScrollUpButton.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectSeparator.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/SelectValue.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/select/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/separator/Separator.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/separator/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/Sheet.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetClose.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetDescription.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetFooter.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetHeader.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetOverlay.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetTitle.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/SheetTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/sheet/sheet.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/switch/Switch.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/switch/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tabs/Tabs.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tabs/TabsContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tabs/TabsList.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tabs/TabsTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tabs/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/textarea/Textarea.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/textarea/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/toggle-group/ToggleGroup.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/toggle-group/ToggleGroupItem.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/toggle-group/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/toggle/Toggle.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/toggle/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/toggle/toggle.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tooltip/Tooltip.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tooltip/TooltipContent.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tooltip/TooltipProvider.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tooltip/TooltipTrigger.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tooltip/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tree/index.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tree/tree.vue create mode 100644 packages/@core/ui-kit/shadcn-ui/src/ui/tree/types.ts create mode 100644 packages/@core/ui-kit/shadcn-ui/tailwind.config.mjs create mode 100644 packages/@core/ui-kit/shadcn-ui/tsconfig.json create mode 100644 packages/@core/ui-kit/tabs-ui/build.config.ts create mode 100644 packages/@core/ui-kit/tabs-ui/package.json create mode 100644 packages/@core/ui-kit/tabs-ui/postcss.config.mjs create mode 100644 packages/@core/ui-kit/tabs-ui/src/components/index.ts create mode 100644 packages/@core/ui-kit/tabs-ui/src/components/tabs-chrome/tabs.vue create mode 100644 packages/@core/ui-kit/tabs-ui/src/components/tabs/tabs.vue create mode 100644 packages/@core/ui-kit/tabs-ui/src/components/widgets/index.ts create mode 100644 packages/@core/ui-kit/tabs-ui/src/components/widgets/tool-more.vue create mode 100644 packages/@core/ui-kit/tabs-ui/src/components/widgets/tool-screen.vue create mode 100644 packages/@core/ui-kit/tabs-ui/src/index.ts create mode 100644 packages/@core/ui-kit/tabs-ui/src/tabs-view.vue create mode 100644 packages/@core/ui-kit/tabs-ui/src/types.ts create mode 100644 packages/@core/ui-kit/tabs-ui/src/use-tabs-drag.ts create mode 100644 packages/@core/ui-kit/tabs-ui/src/use-tabs-view-scroll.ts create mode 100644 packages/@core/ui-kit/tabs-ui/tailwind.config.mjs create mode 100644 packages/@core/ui-kit/tabs-ui/tsconfig.json create mode 100644 packages/constants/README.md create mode 100644 packages/constants/package.json create mode 100644 packages/constants/src/core.ts create mode 100644 packages/constants/src/index.ts create mode 100644 packages/constants/tsconfig.json create mode 100644 packages/effects/README.md create mode 100644 packages/effects/access/package.json create mode 100644 packages/effects/access/src/access-control.vue create mode 100644 packages/effects/access/src/accessible.ts create mode 100644 packages/effects/access/src/directive.ts create mode 100644 packages/effects/access/src/index.ts create mode 100644 packages/effects/access/src/use-access.ts create mode 100644 packages/effects/access/tsconfig.json create mode 100644 packages/effects/common-ui/package.json create mode 100644 packages/effects/common-ui/src/components/api-component/api-component.vue create mode 100644 packages/effects/common-ui/src/components/api-component/index.ts create mode 100644 packages/effects/common-ui/src/components/captcha/hooks/useCaptchaPoints.ts create mode 100644 packages/effects/common-ui/src/components/captcha/index.ts create mode 100644 packages/effects/common-ui/src/components/captcha/point-selection-captcha/index.vue create mode 100644 packages/effects/common-ui/src/components/captcha/point-selection-captcha/point-selection-captcha-card.vue create mode 100644 packages/effects/common-ui/src/components/captcha/slider-captcha/index.vue create mode 100644 packages/effects/common-ui/src/components/captcha/slider-captcha/slider-captcha-action.vue create mode 100644 packages/effects/common-ui/src/components/captcha/slider-captcha/slider-captcha-bar.vue create mode 100644 packages/effects/common-ui/src/components/captcha/slider-captcha/slider-captcha-content.vue create mode 100644 packages/effects/common-ui/src/components/captcha/slider-rotate-captcha/index.vue create mode 100644 packages/effects/common-ui/src/components/captcha/types.ts create mode 100644 packages/effects/common-ui/src/components/col-page/col-page.vue create mode 100644 packages/effects/common-ui/src/components/col-page/index.ts create mode 100644 packages/effects/common-ui/src/components/col-page/types.ts create mode 100644 packages/effects/common-ui/src/components/count-to/count-to.vue create mode 100644 packages/effects/common-ui/src/components/count-to/index.ts create mode 100644 packages/effects/common-ui/src/components/count-to/types.ts create mode 100644 packages/effects/common-ui/src/components/ellipsis-text/ellipsis-text.vue create mode 100644 packages/effects/common-ui/src/components/ellipsis-text/index.ts create mode 100644 packages/effects/common-ui/src/components/icon-picker/icon-picker.vue create mode 100644 packages/effects/common-ui/src/components/icon-picker/icons.ts create mode 100644 packages/effects/common-ui/src/components/icon-picker/index.ts create mode 100644 packages/effects/common-ui/src/components/index.ts create mode 100644 packages/effects/common-ui/src/components/json-viewer/index.ts create mode 100644 packages/effects/common-ui/src/components/json-viewer/index.vue create mode 100644 packages/effects/common-ui/src/components/json-viewer/style.scss create mode 100644 packages/effects/common-ui/src/components/json-viewer/types.ts create mode 100644 packages/effects/common-ui/src/components/loading/directive.ts create mode 100644 packages/effects/common-ui/src/components/loading/index.ts create mode 100644 packages/effects/common-ui/src/components/loading/loading.vue create mode 100644 packages/effects/common-ui/src/components/loading/spinner.vue create mode 100644 packages/effects/common-ui/src/components/page/__tests__/page.test.ts create mode 100644 packages/effects/common-ui/src/components/page/index.ts create mode 100644 packages/effects/common-ui/src/components/page/page.vue create mode 100644 packages/effects/common-ui/src/components/page/types.ts create mode 100644 packages/effects/common-ui/src/components/resize/index.ts create mode 100644 packages/effects/common-ui/src/components/resize/resize.vue create mode 100644 packages/effects/common-ui/src/components/tippy/directive.ts create mode 100644 packages/effects/common-ui/src/components/tippy/index.ts create mode 100644 packages/effects/common-ui/src/index.ts create mode 100644 packages/effects/common-ui/src/ui/about/about.ts create mode 100644 packages/effects/common-ui/src/ui/about/about.vue create mode 100644 packages/effects/common-ui/src/ui/about/index.ts create mode 100644 packages/effects/common-ui/src/ui/authentication/auth-title.vue create mode 100644 packages/effects/common-ui/src/ui/authentication/code-login.vue create mode 100644 packages/effects/common-ui/src/ui/authentication/forget-password.vue create mode 100644 packages/effects/common-ui/src/ui/authentication/index.ts create mode 100644 packages/effects/common-ui/src/ui/authentication/login-expired-modal.vue create mode 100644 packages/effects/common-ui/src/ui/authentication/login.vue create mode 100644 packages/effects/common-ui/src/ui/authentication/qrcode-login.vue create mode 100644 packages/effects/common-ui/src/ui/authentication/register.vue create mode 100644 packages/effects/common-ui/src/ui/authentication/third-party-login.vue create mode 100644 packages/effects/common-ui/src/ui/authentication/types.ts create mode 100644 packages/effects/common-ui/src/ui/dashboard/analysis/analysis-chart-card.vue create mode 100644 packages/effects/common-ui/src/ui/dashboard/analysis/analysis-charts-tabs.vue create mode 100644 packages/effects/common-ui/src/ui/dashboard/analysis/analysis-overview.vue create mode 100644 packages/effects/common-ui/src/ui/dashboard/analysis/index.ts create mode 100644 packages/effects/common-ui/src/ui/dashboard/index.ts create mode 100644 packages/effects/common-ui/src/ui/dashboard/typing.ts create mode 100644 packages/effects/common-ui/src/ui/dashboard/workbench/index.ts create mode 100644 packages/effects/common-ui/src/ui/dashboard/workbench/workbench-header.vue create mode 100644 packages/effects/common-ui/src/ui/dashboard/workbench/workbench-project.vue create mode 100644 packages/effects/common-ui/src/ui/dashboard/workbench/workbench-quick-nav.vue create mode 100644 packages/effects/common-ui/src/ui/dashboard/workbench/workbench-todo.vue create mode 100644 packages/effects/common-ui/src/ui/dashboard/workbench/workbench-trends.vue create mode 100644 packages/effects/common-ui/src/ui/fallback/fallback.ts create mode 100644 packages/effects/common-ui/src/ui/fallback/fallback.vue create mode 100644 packages/effects/common-ui/src/ui/fallback/icons/icon-403.vue create mode 100644 packages/effects/common-ui/src/ui/fallback/icons/icon-404.vue create mode 100644 packages/effects/common-ui/src/ui/fallback/icons/icon-500.vue create mode 100644 packages/effects/common-ui/src/ui/fallback/icons/icon-coming-soon.vue create mode 100644 packages/effects/common-ui/src/ui/fallback/icons/icon-offline.vue create mode 100644 packages/effects/common-ui/src/ui/fallback/icons/warning.svg create mode 100644 packages/effects/common-ui/src/ui/fallback/index.ts create mode 100644 packages/effects/common-ui/src/ui/index.ts create mode 100644 packages/effects/common-ui/tsconfig.json create mode 100644 packages/effects/hooks/README.md create mode 100644 packages/effects/hooks/package.json create mode 100644 packages/effects/hooks/src/index.ts create mode 100644 packages/effects/hooks/src/use-app-config.ts create mode 100644 packages/effects/hooks/src/use-content-maximize.ts create mode 100644 packages/effects/hooks/src/use-design-tokens.ts create mode 100644 packages/effects/hooks/src/use-event-bus.ts create mode 100644 packages/effects/hooks/src/use-hover-toggle.ts create mode 100644 packages/effects/hooks/src/use-pagination.ts create mode 100644 packages/effects/hooks/src/use-refresh.ts create mode 100644 packages/effects/hooks/src/use-tabs.ts create mode 100644 packages/effects/hooks/src/use-watermark.ts create mode 100644 packages/effects/hooks/tsconfig.json create mode 100644 packages/effects/layouts/package.json create mode 100644 packages/effects/layouts/src/authentication/authentication.vue create mode 100644 packages/effects/layouts/src/authentication/form.vue create mode 100644 packages/effects/layouts/src/authentication/icons/slogan.vue create mode 100644 packages/effects/layouts/src/authentication/index.ts create mode 100644 packages/effects/layouts/src/authentication/toolbar.vue create mode 100644 packages/effects/layouts/src/authentication/types.ts create mode 100644 packages/effects/layouts/src/basic/README.md create mode 100644 packages/effects/layouts/src/basic/content/content-spinner.vue create mode 100644 packages/effects/layouts/src/basic/content/content.vue create mode 100644 packages/effects/layouts/src/basic/content/index.ts create mode 100644 packages/effects/layouts/src/basic/content/use-content-spinner.ts create mode 100644 packages/effects/layouts/src/basic/copyright/copyright.vue create mode 100644 packages/effects/layouts/src/basic/copyright/index.ts create mode 100644 packages/effects/layouts/src/basic/footer/footer.vue create mode 100644 packages/effects/layouts/src/basic/footer/index.ts create mode 100644 packages/effects/layouts/src/basic/header/header.vue create mode 100644 packages/effects/layouts/src/basic/header/index.ts create mode 100644 packages/effects/layouts/src/basic/index.ts create mode 100644 packages/effects/layouts/src/basic/layout.vue create mode 100644 packages/effects/layouts/src/basic/menu/extra-menu.vue create mode 100644 packages/effects/layouts/src/basic/menu/index.ts create mode 100644 packages/effects/layouts/src/basic/menu/menu.vue create mode 100644 packages/effects/layouts/src/basic/menu/mixed-menu.vue create mode 100644 packages/effects/layouts/src/basic/menu/use-extra-menu.ts create mode 100644 packages/effects/layouts/src/basic/menu/use-mixed-menu.ts create mode 100644 packages/effects/layouts/src/basic/menu/use-navigation.ts create mode 100644 packages/effects/layouts/src/basic/tabbar/index.ts create mode 100644 packages/effects/layouts/src/basic/tabbar/tabbar.vue create mode 100644 packages/effects/layouts/src/basic/tabbar/use-tabbar.ts create mode 100644 packages/effects/layouts/src/iframe/iframe-router-view.vue create mode 100644 packages/effects/layouts/src/iframe/iframe-view.vue create mode 100644 packages/effects/layouts/src/iframe/index.ts create mode 100644 packages/effects/layouts/src/index.ts create mode 100644 packages/effects/layouts/src/widgets/breadcrumb.vue create mode 100644 packages/effects/layouts/src/widgets/check-updates/check-updates.vue create mode 100644 packages/effects/layouts/src/widgets/check-updates/index.ts create mode 100644 packages/effects/layouts/src/widgets/color-toggle.vue create mode 100644 packages/effects/layouts/src/widgets/global-search/global-search.vue create mode 100644 packages/effects/layouts/src/widgets/global-search/index.ts create mode 100644 packages/effects/layouts/src/widgets/global-search/search-panel.vue create mode 100644 packages/effects/layouts/src/widgets/index.ts create mode 100644 packages/effects/layouts/src/widgets/language-toggle.vue create mode 100644 packages/effects/layouts/src/widgets/layout-toggle.vue create mode 100644 packages/effects/layouts/src/widgets/lock-screen/index.ts create mode 100644 packages/effects/layouts/src/widgets/lock-screen/lock-screen-modal.vue create mode 100644 packages/effects/layouts/src/widgets/lock-screen/lock-screen.vue create mode 100644 packages/effects/layouts/src/widgets/notification/index.ts create mode 100644 packages/effects/layouts/src/widgets/notification/notification.vue create mode 100644 packages/effects/layouts/src/widgets/notification/types.ts create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/block.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/checkbox-item.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/general/animation.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/general/general.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/index.ts create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/input-item.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/breadcrumb.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/content.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/copyright.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/footer.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/header.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/layout.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/navigation.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/sidebar.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/tabbar.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/layout/widget.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/number-field-item.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/select-item.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/shortcut-keys/global.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/switch-item.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/theme/builtin.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/theme/color-mode.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/theme/radius.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/theme/theme.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/blocks/toggle-item.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/content-compact.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/full-content.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/header-mixed-nav.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/header-nav.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/header-sidebar-nav.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/index.ts create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/mixed-nav.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/setting.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/sidebar-mixed-nav.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/icons/sidebar-nav.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/index.ts create mode 100644 packages/effects/layouts/src/widgets/preferences/preferences-button.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/preferences-drawer.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/preferences.vue create mode 100644 packages/effects/layouts/src/widgets/preferences/use-open-preferences.ts create mode 100644 packages/effects/layouts/src/widgets/theme-toggle/index.ts create mode 100644 packages/effects/layouts/src/widgets/theme-toggle/theme-button.vue create mode 100644 packages/effects/layouts/src/widgets/theme-toggle/theme-toggle.vue create mode 100644 packages/effects/layouts/src/widgets/user-dropdown/index.ts create mode 100644 packages/effects/layouts/src/widgets/user-dropdown/user-dropdown.vue create mode 100644 packages/effects/layouts/tsconfig.json create mode 100644 packages/effects/plugins/README.md create mode 100644 packages/effects/plugins/package.json create mode 100644 packages/effects/plugins/src/echarts/echarts-ui.vue create mode 100644 packages/effects/plugins/src/echarts/echarts.ts create mode 100644 packages/effects/plugins/src/echarts/index.ts create mode 100644 packages/effects/plugins/src/echarts/use-echarts.ts create mode 100644 packages/effects/plugins/src/motion/index.ts create mode 100644 packages/effects/plugins/src/motion/types.ts create mode 100644 packages/effects/plugins/src/vxe-table/api.ts create mode 100644 packages/effects/plugins/src/vxe-table/extends.ts create mode 100644 packages/effects/plugins/src/vxe-table/index.ts create mode 100644 packages/effects/plugins/src/vxe-table/init.ts create mode 100644 packages/effects/plugins/src/vxe-table/style.css create mode 100644 packages/effects/plugins/src/vxe-table/types.ts create mode 100644 packages/effects/plugins/src/vxe-table/use-vxe-grid.ts create mode 100644 packages/effects/plugins/src/vxe-table/use-vxe-grid.vue create mode 100644 packages/effects/plugins/tsconfig.json create mode 100644 packages/effects/request/package.json create mode 100644 packages/effects/request/src/index.ts create mode 100644 packages/effects/request/src/request-client/index.ts create mode 100644 packages/effects/request/src/request-client/modules/downloader.test.ts create mode 100644 packages/effects/request/src/request-client/modules/downloader.ts create mode 100644 packages/effects/request/src/request-client/modules/interceptor.ts create mode 100644 packages/effects/request/src/request-client/modules/uploader.test.ts create mode 100644 packages/effects/request/src/request-client/modules/uploader.ts create mode 100644 packages/effects/request/src/request-client/preset-interceptors.ts create mode 100644 packages/effects/request/src/request-client/request-client.test.ts create mode 100644 packages/effects/request/src/request-client/request-client.ts create mode 100644 packages/effects/request/src/request-client/types.ts create mode 100644 packages/effects/request/tsconfig.json create mode 100644 packages/icons/README.md create mode 100644 packages/icons/package.json create mode 100644 packages/icons/src/iconify/index.ts create mode 100644 packages/icons/src/icons/empty-icon.vue create mode 100644 packages/icons/src/index.ts create mode 100644 packages/icons/src/svg/icons/antdv-logo.svg create mode 100644 packages/icons/src/svg/icons/avatar-1.svg create mode 100644 packages/icons/src/svg/icons/avatar-2.svg create mode 100644 packages/icons/src/svg/icons/avatar-3.svg create mode 100644 packages/icons/src/svg/icons/avatar-4.svg create mode 100644 packages/icons/src/svg/icons/bell.svg create mode 100644 packages/icons/src/svg/icons/cake.svg create mode 100644 packages/icons/src/svg/icons/card.svg create mode 100644 packages/icons/src/svg/icons/download.svg create mode 100644 packages/icons/src/svg/index.ts create mode 100644 packages/icons/src/svg/load.ts create mode 100644 packages/icons/tsconfig.json create mode 100644 packages/locales/package.json create mode 100644 packages/locales/src/i18n.ts create mode 100644 packages/locales/src/index.ts create mode 100644 packages/locales/src/langs/en-US/authentication.json create mode 100644 packages/locales/src/langs/en-US/common.json create mode 100644 packages/locales/src/langs/en-US/preferences.json create mode 100644 packages/locales/src/langs/en-US/ui.json create mode 100644 packages/locales/src/langs/zh-CN/authentication.json create mode 100644 packages/locales/src/langs/zh-CN/common.json create mode 100644 packages/locales/src/langs/zh-CN/preferences.json create mode 100644 packages/locales/src/langs/zh-CN/ui.json create mode 100644 packages/locales/src/typing.ts create mode 100644 packages/locales/tsconfig.json create mode 100644 packages/preferences/package.json create mode 100644 packages/preferences/src/index.ts create mode 100644 packages/preferences/tsconfig.json create mode 100644 packages/stores/package.json create mode 100644 packages/stores/shim-pinia.d.ts create mode 100644 packages/stores/src/index.ts create mode 100644 packages/stores/src/modules/access.test.ts create mode 100644 packages/stores/src/modules/access.ts create mode 100644 packages/stores/src/modules/index.ts create mode 100644 packages/stores/src/modules/tabbar.test.ts create mode 100644 packages/stores/src/modules/tabbar.ts create mode 100644 packages/stores/src/modules/user.test.ts create mode 100644 packages/stores/src/modules/user.ts create mode 100644 packages/stores/src/setup.ts create mode 100644 packages/stores/tsconfig.json create mode 100644 packages/styles/README.md create mode 100644 packages/styles/package.json create mode 100644 packages/styles/src/antd/index.css create mode 100644 packages/styles/src/ele/index.css create mode 100644 packages/styles/src/global/index.scss create mode 100644 packages/styles/src/index.ts create mode 100644 packages/styles/src/naive/index.css create mode 100644 packages/styles/tsconfig.json create mode 100644 packages/types/README.md create mode 100644 packages/types/global.d.ts create mode 100644 packages/types/package.json create mode 100644 packages/types/src/index.ts create mode 100644 packages/types/src/user.ts create mode 100644 packages/types/tsconfig.json create mode 100644 packages/utils/README.md create mode 100644 packages/utils/package.json create mode 100644 packages/utils/src/helpers/__tests__/find-menu-by-path.test.ts create mode 100644 packages/utils/src/helpers/__tests__/generate-menus.test.ts create mode 100644 packages/utils/src/helpers/__tests__/generate-routes-frontend.test.ts create mode 100644 packages/utils/src/helpers/__tests__/merge-route-modules.test.ts create mode 100644 packages/utils/src/helpers/find-menu-by-path.ts create mode 100644 packages/utils/src/helpers/generate-menus.ts create mode 100644 packages/utils/src/helpers/generate-routes-backend.ts create mode 100644 packages/utils/src/helpers/generate-routes-frontend.ts create mode 100644 packages/utils/src/helpers/get-popup-container.ts create mode 100644 packages/utils/src/helpers/index.ts create mode 100644 packages/utils/src/helpers/merge-route-modules.ts create mode 100644 packages/utils/src/helpers/reset-routes.ts create mode 100644 packages/utils/src/helpers/unmount-global-loading.ts create mode 100644 packages/utils/src/index.ts create mode 100644 packages/utils/tsconfig.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 scripts/clean.mjs create mode 100644 scripts/deploy/Dockerfile create mode 100644 scripts/deploy/build-local-docker-image.sh create mode 100644 scripts/deploy/nginx.conf create mode 100644 scripts/turbo-run/README.md create mode 100644 scripts/turbo-run/bin/turbo-run.mjs create mode 100644 scripts/turbo-run/build.config.ts create mode 100644 scripts/turbo-run/package.json create mode 100644 scripts/turbo-run/src/index.ts create mode 100644 scripts/turbo-run/src/run.ts create mode 100644 scripts/turbo-run/tsconfig.json create mode 100644 scripts/vsh/README.md create mode 100644 scripts/vsh/bin/vsh.mjs create mode 100644 scripts/vsh/build.config.ts create mode 100644 scripts/vsh/package.json create mode 100644 scripts/vsh/src/check-circular/index.ts create mode 100644 scripts/vsh/src/check-dep/index.ts create mode 100644 scripts/vsh/src/code-workspace/index.ts create mode 100644 scripts/vsh/src/index.ts create mode 100644 scripts/vsh/src/lint/index.ts create mode 100644 scripts/vsh/src/publint/index.ts create mode 100644 scripts/vsh/tsconfig.json create mode 100644 stylelint.config.mjs create mode 100644 tea.yaml create mode 100644 turbo.json create mode 100644 vben-admin.code-workspace create mode 100644 vitest.config.ts create mode 100644 vitest.workspace.ts diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..dc3bc09 --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,4 @@ +> 1% +last 2 versions +not dead +not ie 11 diff --git a/.commitlintrc.js b/.commitlintrc.js new file mode 100644 index 0000000..02e33fa --- /dev/null +++ b/.commitlintrc.js @@ -0,0 +1 @@ +export { default } from '@vben/commitlint-config'; diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..52b833a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +node_modules +.git +.gitignore +*.md +dist +.turbo +dist.zip diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..179aec6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset=utf-8 +end_of_line=lf +insert_final_newline=true +indent_style=space +indent_size=2 +max_line_length = 100 +trim_trailing_whitespace = true +quote_type = single + +[*.{yml,yaml,json}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d4e5bd3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# https://docs.github.com/cn/get-started/getting-started-with-git/configuring-git-to-handle-line-endings + +# Automatically normalize line endings (to LF) for all text-based files. +* text=auto eol=lf + +# Declare files that will always have CRLF line endings on checkout. +*.{cmd,[cC][mM][dD]} text eol=crlf +*.{bat,[bB][aA][tT]} text eol=crlf + +# Denote all files that are truly binary and should not be modified. +*.{ico,png,jpg,jpeg,gif,webp,svg,woff,woff2} binary \ No newline at end of file diff --git a/.gitconfig b/.gitconfig new file mode 100644 index 0000000..4b28a69 --- /dev/null +++ b/.gitconfig @@ -0,0 +1,2 @@ +[core] + ignorecase = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d49651 --- /dev/null +++ b/.gitignore @@ -0,0 +1,56 @@ +node_modules +.DS_Store +dist +dist-ssr +dist.zip +dist.tar +dist.war +.nitro +.output +*-dist.zip +*-dist.tar +*-dist.war +coverage +*.local +**/.vitepress/cache +.cache +.turbo +.temp +dev-dist +.stylelintcache +yarn.lock +package-lock.json +.VSCodeCounter +**/backend-mock/data + +# local env files +.env.local +.env.*.local +.eslintcache + +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* +vite.config.mts.* +vite.config.mjs.* +vite.config.js.* +vite.config.ts.* + +# Editor directories and files +.idea +# .vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +.history +/docs +/playground +/apps/backend-mock +/playground +/docs diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..5fda2cf --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,6 @@ +ports: + - port: 5555 + onOpen: open-preview +tasks: + - init: npm i -g corepack && pnpm install + command: pnpm run dev:play diff --git a/.husky/_/commit-msg b/.husky/_/commit-msg new file mode 100644 index 0000000..2defe5f --- /dev/null +++ b/.husky/_/commit-msg @@ -0,0 +1,69 @@ +#!/bin/sh + +if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then + set -x +fi + +if [ "$LEFTHOOK" = "0" ]; then + exit 0 +fi + +call_lefthook() +{ + if test -n "$LEFTHOOK_BIN" + then + "$LEFTHOOK_BIN" "$@" + elif lefthook.exe -h >/dev/null 2>&1 + then + lefthook.exe "$@" + elif lefthook.bat -h >/dev/null 2>&1 + then + lefthook.bat "$@" + else + dir="$(git rev-parse --show-toplevel)" + osArch=$(uname | tr '[:upper:]' '[:lower:]') + cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/') + if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook.exe" + then + "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook.exe" "$@" + elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook.exe" + then + "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook.exe" "$@" + elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook.exe" + then + "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook.exe" "$@" + elif test -f "$dir/node_modules/lefthook/bin/index.js" + then + "$dir/node_modules/lefthook/bin/index.js" "$@" + + elif go tool lefthook -h >/dev/null 2>&1 + then + go tool lefthook "$@" + elif bundle exec lefthook -h >/dev/null 2>&1 + then + bundle exec lefthook "$@" + elif yarn lefthook -h >/dev/null 2>&1 + then + yarn lefthook "$@" + elif pnpm lefthook -h >/dev/null 2>&1 + then + pnpm lefthook "$@" + elif swift package lefthook >/dev/null 2>&1 + then + swift package --build-path .build/lefthook --disable-sandbox lefthook "$@" + elif command -v mint >/dev/null 2>&1 + then + mint run csjones/lefthook-plugin "$@" + elif uv run lefthook -h >/dev/null 2>&1 + then + uv run lefthook "$@" + elif mise exec -- lefthook -h >/dev/null 2>&1 + then + mise exec -- lefthook "$@" + else + echo "Can't find lefthook in PATH" + fi + fi +} + +call_lefthook run "commit-msg" "$@" diff --git a/.husky/_/post-merge b/.husky/_/post-merge new file mode 100644 index 0000000..f8913fc --- /dev/null +++ b/.husky/_/post-merge @@ -0,0 +1,69 @@ +#!/bin/sh + +if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then + set -x +fi + +if [ "$LEFTHOOK" = "0" ]; then + exit 0 +fi + +call_lefthook() +{ + if test -n "$LEFTHOOK_BIN" + then + "$LEFTHOOK_BIN" "$@" + elif lefthook.exe -h >/dev/null 2>&1 + then + lefthook.exe "$@" + elif lefthook.bat -h >/dev/null 2>&1 + then + lefthook.bat "$@" + else + dir="$(git rev-parse --show-toplevel)" + osArch=$(uname | tr '[:upper:]' '[:lower:]') + cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/') + if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook.exe" + then + "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook.exe" "$@" + elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook.exe" + then + "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook.exe" "$@" + elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook.exe" + then + "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook.exe" "$@" + elif test -f "$dir/node_modules/lefthook/bin/index.js" + then + "$dir/node_modules/lefthook/bin/index.js" "$@" + + elif go tool lefthook -h >/dev/null 2>&1 + then + go tool lefthook "$@" + elif bundle exec lefthook -h >/dev/null 2>&1 + then + bundle exec lefthook "$@" + elif yarn lefthook -h >/dev/null 2>&1 + then + yarn lefthook "$@" + elif pnpm lefthook -h >/dev/null 2>&1 + then + pnpm lefthook "$@" + elif swift package lefthook >/dev/null 2>&1 + then + swift package --build-path .build/lefthook --disable-sandbox lefthook "$@" + elif command -v mint >/dev/null 2>&1 + then + mint run csjones/lefthook-plugin "$@" + elif uv run lefthook -h >/dev/null 2>&1 + then + uv run lefthook "$@" + elif mise exec -- lefthook -h >/dev/null 2>&1 + then + mise exec -- lefthook "$@" + else + echo "Can't find lefthook in PATH" + fi + fi +} + +call_lefthook run "post-merge" "$@" diff --git a/.husky/_/pre-commit b/.husky/_/pre-commit new file mode 100644 index 0000000..53ee229 --- /dev/null +++ b/.husky/_/pre-commit @@ -0,0 +1,69 @@ +#!/bin/sh + +if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then + set -x +fi + +if [ "$LEFTHOOK" = "0" ]; then + exit 0 +fi + +call_lefthook() +{ + if test -n "$LEFTHOOK_BIN" + then + "$LEFTHOOK_BIN" "$@" + elif lefthook.exe -h >/dev/null 2>&1 + then + lefthook.exe "$@" + elif lefthook.bat -h >/dev/null 2>&1 + then + lefthook.bat "$@" + else + dir="$(git rev-parse --show-toplevel)" + osArch=$(uname | tr '[:upper:]' '[:lower:]') + cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/') + if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook.exe" + then + "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook.exe" "$@" + elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook.exe" + then + "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook.exe" "$@" + elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook.exe" + then + "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook.exe" "$@" + elif test -f "$dir/node_modules/lefthook/bin/index.js" + then + "$dir/node_modules/lefthook/bin/index.js" "$@" + + elif go tool lefthook -h >/dev/null 2>&1 + then + go tool lefthook "$@" + elif bundle exec lefthook -h >/dev/null 2>&1 + then + bundle exec lefthook "$@" + elif yarn lefthook -h >/dev/null 2>&1 + then + yarn lefthook "$@" + elif pnpm lefthook -h >/dev/null 2>&1 + then + pnpm lefthook "$@" + elif swift package lefthook >/dev/null 2>&1 + then + swift package --build-path .build/lefthook --disable-sandbox lefthook "$@" + elif command -v mint >/dev/null 2>&1 + then + mint run csjones/lefthook-plugin "$@" + elif uv run lefthook -h >/dev/null 2>&1 + then + uv run lefthook "$@" + elif mise exec -- lefthook -h >/dev/null 2>&1 + then + mise exec -- lefthook "$@" + else + echo "Can't find lefthook in PATH" + fi + fi +} + +call_lefthook run "pre-commit" "$@" diff --git a/.husky/_/prepare-commit-msg b/.husky/_/prepare-commit-msg new file mode 100644 index 0000000..0415d12 --- /dev/null +++ b/.husky/_/prepare-commit-msg @@ -0,0 +1,69 @@ +#!/bin/sh + +if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then + set -x +fi + +if [ "$LEFTHOOK" = "0" ]; then + exit 0 +fi + +call_lefthook() +{ + if test -n "$LEFTHOOK_BIN" + then + "$LEFTHOOK_BIN" "$@" + elif lefthook.exe -h >/dev/null 2>&1 + then + lefthook.exe "$@" + elif lefthook.bat -h >/dev/null 2>&1 + then + lefthook.bat "$@" + else + dir="$(git rev-parse --show-toplevel)" + osArch=$(uname | tr '[:upper:]' '[:lower:]') + cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/') + if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook.exe" + then + "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook.exe" "$@" + elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook.exe" + then + "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook.exe" "$@" + elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook.exe" + then + "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook.exe" "$@" + elif test -f "$dir/node_modules/lefthook/bin/index.js" + then + "$dir/node_modules/lefthook/bin/index.js" "$@" + + elif go tool lefthook -h >/dev/null 2>&1 + then + go tool lefthook "$@" + elif bundle exec lefthook -h >/dev/null 2>&1 + then + bundle exec lefthook "$@" + elif yarn lefthook -h >/dev/null 2>&1 + then + yarn lefthook "$@" + elif pnpm lefthook -h >/dev/null 2>&1 + then + pnpm lefthook "$@" + elif swift package lefthook >/dev/null 2>&1 + then + swift package --build-path .build/lefthook --disable-sandbox lefthook "$@" + elif command -v mint >/dev/null 2>&1 + then + mint run csjones/lefthook-plugin "$@" + elif uv run lefthook -h >/dev/null 2>&1 + then + uv run lefthook "$@" + elif mise exec -- lefthook -h >/dev/null 2>&1 + then + mise exec -- lefthook "$@" + else + echo "Can't find lefthook in PATH" + fi + fi +} + +call_lefthook run "prepare-commit-msg" "$@" diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..ee5c244 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +22.1.0 diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..21147af --- /dev/null +++ b/.npmrc @@ -0,0 +1,13 @@ +registry = "https://registry.npmmirror.com" +public-hoist-pattern[]=lefthook +public-hoist-pattern[]=eslint +public-hoist-pattern[]=prettier +public-hoist-pattern[]=prettier-plugin-tailwindcss +public-hoist-pattern[]=stylelint +public-hoist-pattern[]=*postcss* +public-hoist-pattern[]=@commitlint/* +public-hoist-pattern[]=czg + +strict-peer-dependencies=false +auto-install-peers=true +dedupe-peer-dependents=true diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d0b0ca1 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,18 @@ +dist +dev-dist +.local +.output.js +node_modules +.nvmrc +coverage +CODEOWNERS +.nitro +.output + + +**/*.svg +**/*.sh + +public +.npmrc +*-lock.yaml diff --git a/.prettierrc.mjs b/.prettierrc.mjs new file mode 100644 index 0000000..3e25d2c --- /dev/null +++ b/.prettierrc.mjs @@ -0,0 +1 @@ +export { default } from '@vben/prettier-config'; diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 0000000..f4b2db2 --- /dev/null +++ b/.stylelintignore @@ -0,0 +1,4 @@ +dist +public +__tests__ +coverage diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..e8dc9ed --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,30 @@ +{ + "recommendations": [ + // Vue 3 的语言支持 + "Vue.volar", + // 将 ESLint JavaScript 集成到 VS Code 中。 + "dbaeumer.vscode-eslint", + // Visual Studio Code 的官方 Stylelint 扩展 + "stylelint.vscode-stylelint", + // 使用 Prettier 的代码格式化程序 + "esbenp.prettier-vscode", + // 支持 dotenv 文件语法 + "mikestead.dotenv", + // 源代码的拼写检查器 + "streetsidesoftware.code-spell-checker", + // Tailwind CSS 的官方 VS Code 插件 + "bradlc.vscode-tailwindcss", + // iconify 图标插件 + "antfu.iconify", + // i18n 插件 + "Lokalise.i18n-ally", + // CSS 变量提示 + "vunguyentuan.vscode-css-variables", + // 在 package.json 中显示 PNPM catalog 的版本 + "antfu.pnpm-catalog-lens" + ], + "unwantedRecommendations": [ + // 和 volar 冲突 + "octref.vetur" + ] +} diff --git a/.vscode/global.code-snippets b/.vscode/global.code-snippets new file mode 100644 index 0000000..7604b01 --- /dev/null +++ b/.vscode/global.code-snippets @@ -0,0 +1,37 @@ +{ + "import": { + "scope": "javascript,typescript", + "prefix": "im", + "body": ["import { $2 } from '$1';"], + "description": "Import a module", + }, + "export-all": { + "scope": "javascript,typescript", + "prefix": "ex", + "body": ["export * from '$1';"], + "description": "Export a module", + }, + "vue-script-setup": { + "scope": "vue", + "prefix": "", + "const props = defineProps<{", + " modelValue?: boolean,", + "}>()", + "$1", + "", + "", + "", + ], + }, + "vue-computed": { + "scope": "javascript,typescript,vue", + "prefix": "com", + "body": ["computed(() => { $1 })"], + }, +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e967330 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "name": "vben admin playground dev", + "request": "launch", + "url": "http://localhost:5555", + "env": { "NODE_ENV": "development" }, + "sourceMaps": true, + "webRoot": "${workspaceFolder}/playground" + }, + { + "type": "chrome", + "name": "vben admin antd dev", + "request": "launch", + "url": "http://localhost:5666", + "env": { "NODE_ENV": "development" }, + "sourceMaps": true, + "webRoot": "${workspaceFolder}/apps/web-antd" + }, + { + "type": "chrome", + "name": "vben admin ele dev", + "request": "launch", + "url": "http://localhost:5777", + "env": { "NODE_ENV": "development" }, + "sourceMaps": true, + "webRoot": "${workspaceFolder}/apps/web-ele" + }, + { + "type": "chrome", + "name": "vben admin naive dev", + "request": "launch", + "url": "http://localhost:5888", + "env": { "NODE_ENV": "development" }, + "sourceMaps": true, + "webRoot": "${workspaceFolder}/apps/web-naive" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1cfc017 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,241 @@ +{ + "tailwindCSS.experimental.configFile": "internal/tailwind-config/src/index.ts", + // workbench + "workbench.list.smoothScrolling": true, + "workbench.startupEditor": "newUntitledFile", + "workbench.tree.indent": 10, + "workbench.editor.highlightModifiedTabs": true, + "workbench.editor.closeOnFileDelete": true, + "workbench.editor.limit.enabled": true, + "workbench.editor.limit.perEditorGroup": true, + "workbench.editor.limit.value": 5, + + // editor + "editor.tabSize": 2, + "editor.detectIndentation": false, + "editor.cursorBlinking": "expand", + "editor.largeFileOptimizations": true, + "editor.accessibilitySupport": "off", + "editor.cursorSmoothCaretAnimation": "on", + "editor.guides.bracketPairs": "active", + "editor.inlineSuggest.enabled": true, + "editor.suggestSelection": "recentlyUsedByPrefix", + "editor.acceptSuggestionOnEnter": "smart", + "editor.suggest.snippetsPreventQuickSuggestions": false, + "editor.stickyScroll.enabled": true, + "editor.hover.sticky": true, + "editor.suggest.insertMode": "replace", + "editor.bracketPairColorization.enabled": true, + "editor.autoClosingBrackets": "beforeWhitespace", + "editor.autoClosingDelete": "always", + "editor.autoClosingOvertype": "always", + "editor.autoClosingQuotes": "beforeWhitespace", + "editor.wordSeparators": "`~!@#%^&*()=+[{]}\\|;:'\",.<>/?", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.fixAll.stylelint": "explicit", + "source.organizeImports": "never" + }, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[html]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[css]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[scss]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[markdown]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[vue]": { + "editor.defaultFormatter": "Vue.volar" + }, + // extensions + "extensions.ignoreRecommendations": true, + + // terminal + "terminal.integrated.cursorBlinking": true, + "terminal.integrated.persistentSessionReviveProcess": "never", + "terminal.integrated.tabs.enabled": true, + "terminal.integrated.scrollback": 10000, + "terminal.integrated.stickyScroll.enabled": true, + + // files + "files.eol": "\n", + "files.insertFinalNewline": true, + "files.simpleDialog.enable": true, + "files.associations": { + "*.ejs": "html", + "*.art": "html", + "**/tsconfig.json": "jsonc", + "*.json": "jsonc", + "package.json": "json" + }, + + "files.exclude": { + "**/.eslintcache": true, + "**/bower_components": true, + "**/.turbo": true, + "**/.idea": true, + "**/.vitepress": true, + "**/tmp": true, + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.stylelintcache": true, + "**/.DS_Store": true, + "**/vite.config.mts.*": true, + "**/tea.yaml": true + }, + "files.watcherExclude": { + "**/.git/objects/**": true, + "**/.git/subtree-cache/**": true, + "**/.vscode/**": true, + "**/node_modules/**": true, + "**/tmp/**": true, + "**/bower_components/**": true, + "**/dist/**": true, + "**/yarn.lock": true + }, + + "typescript.tsserver.exclude": ["**/node_modules", "**/dist", "**/.turbo"], + + // search + "search.searchEditor.singleClickBehaviour": "peekDefinition", + "search.followSymlinks": false, + // 在使用搜索功能时,将这些文件夹/文件排除在外 + "search.exclude": { + "**/node_modules": true, + "**/*.log": true, + "**/*.log*": true, + "**/bower_components": true, + "**/dist": true, + "**/elehukouben": true, + "**/.git": true, + "**/.github": true, + "**/.gitignore": true, + "**/.svn": true, + "**/.DS_Store": true, + "**/.vitepress/cache": true, + "**/.idea": true, + "**/.vscode": false, + "**/.yarn": true, + "**/tmp": true, + "*.xml": true, + "out": true, + "dist": true, + "node_modules": true, + "CHANGELOG.md": true, + "**/pnpm-lock.yaml": true, + "**/yarn.lock": true + }, + + "debug.onTaskErrors": "debugAnyway", + "diffEditor.ignoreTrimWhitespace": false, + "npm.packageManager": "pnpm", + + "css.validate": false, + "less.validate": false, + "scss.validate": false, + + // extension + "emmet.showSuggestionsAsSnippets": true, + "emmet.triggerExpansionOnTab": false, + + "errorLens.enabledDiagnosticLevels": ["warning", "error"], + "errorLens.excludeBySource": ["cSpell", "Grammarly", "eslint"], + + "stylelint.enable": true, + "stylelint.packageManager": "pnpm", + "stylelint.validate": ["css", "less", "postcss", "scss", "vue"], + "stylelint.customSyntax": "postcss-html", + "stylelint.snippet": ["css", "less", "postcss", "scss", "vue"], + + "typescript.inlayHints.enumMemberValues.enabled": true, + "typescript.preferences.preferTypeOnlyAutoImports": true, + "typescript.preferences.includePackageJsonAutoImports": "on", + + "eslint.validate": [ + "javascript", + "typescript", + "javascriptreact", + "typescriptreact", + "vue", + "html", + "markdown", + "json", + "jsonc", + "json5" + ], + + "tailwindCSS.experimental.classRegex": [ + ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"] + ], + + "github.copilot.enable": { + "*": true, + "markdown": true, + "plaintext": false, + "yaml": false + }, + + "cssVariables.lookupFiles": ["packages/core/base/design/src/**/*.css"], + + "i18n-ally.localesPaths": [ + "packages/locales/src/langs", + "playground/src/locales/langs", + "apps/*/src/locales/langs" + ], + "i18n-ally.pathMatcher": "{locale}/{namespace}.{ext}", + "i18n-ally.enabledParsers": ["json"], + "i18n-ally.sourceLanguage": "en", + "i18n-ally.displayLanguage": "zh-CN", + "i18n-ally.enabledFrameworks": ["vue", "react"], + "i18n-ally.keystyle": "nested", + "i18n-ally.sortKeys": true, + "i18n-ally.namespace": true, + + // 控制相关文件嵌套展示 + "explorer.fileNesting.enabled": true, + "explorer.fileNesting.expand": false, + "explorer.fileNesting.patterns": { + "*.ts": "$(capture).test.ts, $(capture).test.tsx, $(capture).spec.ts, $(capture).spec.tsx, $(capture).d.ts", + "*.tsx": "$(capture).test.ts, $(capture).test.tsx, $(capture).spec.ts, $(capture).spec.tsx,$(capture).d.ts", + "*.env": "$(capture).env.*", + "README.md": "README*,CHANGELOG*,LICENSE,CNAME", + "package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,.gitattributes,.gitignore,.gitpod.yml,.npmrc,.browserslistrc,.node-version,.git*,.tazerc.json", + "eslint.config.mjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,stylelint.config.*,.lintstagedrc.mjs,cspell.json,lefthook.yml", + "tailwind.config.mjs": "postcss.*" + }, + "commentTranslate.hover.enabled": false, + "commentTranslate.multiLineMerge": true, + "vue.server.hybridMode": true, + "typescript.tsdk": "node_modules/typescript/lib", + "oxc.enable": false, + "cSpell.words": [ + "archiver", + "axios", + "dotenv", + "isequal", + "jspm", + "napi", + "nolebase", + "rollup", + "vitest" + ] +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..82fd821 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,44 @@ +FROM node:20-slim AS builder +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +ENV NODE_OPTIONS=--max-old-space-size=8192 +ENV TZ=Asia/Shanghai + +RUN corepack enable + +WORKDIR /vben5 + +# copy package.json and pnpm-lock.yaml to workspace +COPY . /vben5 + +RUN pnpm install --frozen-lockfile +# 如果你的项目中使用了 antd,需要执行下面的命令 +RUN pnpm build:antd + +# 如果你的项目中使用了 element-ui,需要执行下面的命令 +#RUN pnpm build:ele + +# 如果你的项目中使用了 naive,需要执行下面的命令 +#RUN pnpm build:naive + +RUN echo "Builder Success 🎉" + +FROM nginx:stable-alpine AS production + +RUN echo "types { application/javascript js mjs; }" > /etc/nginx/conf.d/mjs.conf + +# 如果你的项目中使用了 antd,需要执行下面的命令 +COPY --from=builder /vben5/apps/web-antd/dist /usr/share/nginx/html + +# 如果你的项目中使用了 element-ui,需要执行下面的命令 +#COPY --from=builder /vben5/apps/web-ele/dist /usr/share/nginx/html + +# 如果你的项目中使用了 naive,需要执行下面的命令 +#COPY --from=builder /vben5/apps/web-naive/dist /usr/share/nginx/html + +COPY --from=builder /vben5/_nginx/nginx.conf /etc/nginx/nginx.conf + +EXPOSE 8080 + +# start nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/_nginx/nginx.conf b/_nginx/nginx.conf new file mode 100644 index 0000000..8e6ab10 --- /dev/null +++ b/_nginx/nginx.conf @@ -0,0 +1,75 @@ + +#user nobody; +worker_processes 1; + +#error_log logs/error.log; +#error_log logs/error.log notice; +#error_log logs/error.log info; + +#pid logs/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include mime.types; + default_type application/octet-stream; + + types { + application/javascript js mjs; + text/css css; + text/html html; + } + + sendfile on; + # tcp_nopush on; + + #keepalive_timeout 0; + # keepalive_timeout 65; + + # gzip on; + # gzip_buffers 32 16k; + # gzip_comp_level 6; + # gzip_min_length 1k; + # gzip_static on; + # gzip_types text/plain + # text/css + # application/javascript + # application/json + # application/x-javascript + # text/xml + # application/xml + # application/xml+rss + # text/javascript; #设置压缩的文件类型 + # gzip_vary on; + + server { + listen 8080; + server_name localhost; + + location / { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + index index.html; + # Enable CORS + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + } + + error_page 500 502 503 504 /50x.html; + + location = /50x.html { + root /usr/share/nginx/html; + } + } +} diff --git a/apps/web-antd/.env b/apps/web-antd/.env new file mode 100644 index 0000000..1005666 --- /dev/null +++ b/apps/web-antd/.env @@ -0,0 +1,8 @@ +# 应用标题 +VITE_APP_TITLE=采集端综合管理 + +# 应用命名空间,用于缓存、store等功能的前缀,确保隔离 +VITE_APP_NAMESPACE=abp-vnext-pro-vben5-antd + +# 对store进行加密的密钥,在将store持久化到localStorage时会使用该密钥进行加密 +VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key diff --git a/apps/web-antd/.env.analyze b/apps/web-antd/.env.analyze new file mode 100644 index 0000000..ffafa8d --- /dev/null +++ b/apps/web-antd/.env.analyze @@ -0,0 +1,7 @@ +# public path +VITE_BASE=/ + +# Basic interface address SPA +VITE_GLOB_API_URL=/api + +VITE_VISUALIZER=true diff --git a/apps/web-antd/.env.development b/apps/web-antd/.env.development new file mode 100644 index 0000000..650c1ed --- /dev/null +++ b/apps/web-antd/.env.development @@ -0,0 +1,37 @@ +# 端口号 +VITE_PORT=4200 + +VITE_BASE=/ + +# 接口地址 +VITE_GLOB_API_URL=/api + +# 是否开启 Nitro Mock服务,true 为开启,false 为关闭 +VITE_NITRO_MOCK=true + +# vue-router 的模式 +VITE_ROUTER_HISTORY=history + + +# 是否打开 devtools,true 为打开,false 为关闭 +VITE_DEVTOOLS=false + +# 是否注入全局loading +VITE_INJECT_APP_LOADING=true + +# 是否打开刷新浏览器检查用户角色信息 +VITE_REFRESH_ROLE = true + +# # # 后端接口地址 +# VITE_APP_API_ADDRESS=http://182.43.18.151:44317 + +# # websocket地址 +# VITE_WEBSOCKET_URL=http://182.43.18.151:44317/signalr/notification + +# 后端接口地址 +VITE_APP_API_ADDRESS=http://localhost:44315 + +# websocket地址 +VITE_WEBSOCKET_URL=http://localhost:44315/signalr/notification + + diff --git a/apps/web-antd/.env.production b/apps/web-antd/.env.production new file mode 100644 index 0000000..dc56f3d --- /dev/null +++ b/apps/web-antd/.env.production @@ -0,0 +1,28 @@ +VITE_BASE=/ + +# 接口地址 +VITE_GLOB_API_URL=https://mock-napi.vben.pro/api + +# 是否开启压缩,可以设置为 none, brotli, gzip +VITE_COMPRESS=none + +# 是否开启 PWA +VITE_PWA=false + +# vue-router 的模式 +VITE_ROUTER_HISTORY=history + +# 是否注入全局loading +VITE_INJECT_APP_LOADING=true + +# 打包后是否生成dist.zip +VITE_ARCHIVER=true + +# 是否打开刷新浏览器检查用户角色信息 +VITE_REFRESH_ROLE = true + +# 后端接口地址 +VITE_APP_API_ADDRESS=http://182.43.18.151:44317 + +# websocket地址 +VITE_WEBSOCKET_URL=http://182.43.18.151:44317/signalr/notification diff --git a/apps/web-antd/index.html b/apps/web-antd/index.html new file mode 100644 index 0000000..480eb84 --- /dev/null +++ b/apps/web-antd/index.html @@ -0,0 +1,35 @@ + + + + + + + + + + + + <%= VITE_APP_TITLE %> + + + + +
+ + + diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json new file mode 100644 index 0000000..8efbd69 --- /dev/null +++ b/apps/web-antd/package.json @@ -0,0 +1,62 @@ +{ + "name": "@vben/web-antd", + "version": "5.5.6", + "homepage": "https://vben.pro", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "apps/web-antd" + }, + "license": "MIT", + "author": { + "name": "vben", + "email": "ann.vben@gmail.com", + "url": "https://github.com/anncwb" + }, + "type": "module", + "scripts": { + "nswag": "openapi-ts -f ./src/api-client-config/config.ts", + "build": "pnpm vite build --mode production", + "build:analyze": "pnpm vite build --mode analyze", + "dev": "pnpm vite --mode development", + "preview": "vite preview", + "typecheck": "vue-tsc --noEmit --skipLibCheck" + }, + "imports": { + "#/*": "./src/*" + }, + "dependencies": { + "@iconify/json": "^2.2.282", + "@microsoft/signalr": "^8.0.7", + "@vben/access": "workspace:*", + "@vben/common-ui": "workspace:*", + "@vben/constants": "workspace:*", + "@vben/hooks": "workspace:*", + "@vben/icons": "workspace:*", + "@vben/layouts": "workspace:*", + "@vben/locales": "workspace:*", + "@vben/plugins": "workspace:*", + "@vben/preferences": "workspace:*", + "@vben/request": "workspace:*", + "@vben/stores": "workspace:*", + "@vben/styles": "workspace:*", + "@vben/types": "workspace:*", + "@vben/utils": "workspace:*", + "@vueuse/core": "catalog:", + "ant-design-vue": "catalog:", + "axios": "^1.7.7", + "clipboard": "^2.0.11", + "codemirror-editor-vue3": "^2.8.0", + "dayjs": "catalog:", + "pinia": "catalog:", + "vue": "catalog:", + "vue-request": "^2.0.4", + "vue-router": "catalog:", + "vue3-json-viewer": "^2.2.2" + }, + "devDependencies": { + "@hey-api/client-axios": "^0.2.10", + "@hey-api/openapi-ts": "^0.55.3" + } +} diff --git a/apps/web-antd/postcss.config.mjs b/apps/web-antd/postcss.config.mjs new file mode 100644 index 0000000..3d80704 --- /dev/null +++ b/apps/web-antd/postcss.config.mjs @@ -0,0 +1 @@ +export { default } from '@vben/tailwind-config/postcss'; diff --git a/apps/web-antd/public/avatar-v1.webp b/apps/web-antd/public/avatar-v1.webp new file mode 100644 index 0000000000000000000000000000000000000000..9f6ba9a81d4947e51ca8556c7e81deb91be09548 GIT binary patch literal 21586 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 VuBib#;$QA)22EKE^flN3001Z`%FF-& literal 0 HcmV?d00001 diff --git a/apps/web-antd/public/favicon.ico b/apps/web-antd/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fcf9818e2cf855039b272bdbfbb202d3ff3fa159 GIT binary patch literal 5430 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 import('ant-design-vue/es/auto-complete'), +); +const Button = defineAsyncComponent(() => import('ant-design-vue/es/button')); +const Checkbox = defineAsyncComponent( + () => import('ant-design-vue/es/checkbox'), +); +const CheckboxGroup = defineAsyncComponent(() => + import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup), +); +const DatePicker = defineAsyncComponent( + () => import('ant-design-vue/es/date-picker'), +); +const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider')); +const Input = defineAsyncComponent(() => import('ant-design-vue/es/input')); +const InputNumber = defineAsyncComponent( + () => import('ant-design-vue/es/input-number'), +); +const InputPassword = defineAsyncComponent(() => + import('ant-design-vue/es/input').then((res) => res.InputPassword), +); +const Mentions = defineAsyncComponent( + () => import('ant-design-vue/es/mentions'), +); +const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio')); +const RadioGroup = defineAsyncComponent(() => + import('ant-design-vue/es/radio').then((res) => res.RadioGroup), +); +const RangePicker = defineAsyncComponent(() => + import('ant-design-vue/es/date-picker').then((res) => res.RangePicker), +); +const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate')); +const Select = defineAsyncComponent(() => import('ant-design-vue/es/select')); +const Space = defineAsyncComponent(() => import('ant-design-vue/es/space')); +const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch')); +const Textarea = defineAsyncComponent(() => + import('ant-design-vue/es/input').then((res) => res.Textarea), +); +const TimePicker = defineAsyncComponent( + () => import('ant-design-vue/es/time-picker'), +); +const TreeSelect = defineAsyncComponent( + () => import('ant-design-vue/es/tree-select'), +); +const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload')); + +const withDefaultPlaceholder = ( + component: T, + type: 'input' | 'select', + componentProps: Recordable = {}, +) => { + return defineComponent({ + name: component.name, + inheritAttrs: false, + setup: (props: any, { attrs, expose, slots }) => { + const placeholder = + props?.placeholder || + attrs?.placeholder || + $t(`ui.placeholder.${type}`); + // 透传组件暴露的方法 + const innerRef = ref(); + const publicApi: Recordable = {}; + expose(publicApi); + const instance = getCurrentInstance(); + instance?.proxy?.$nextTick(() => { + for (const key in innerRef.value) { + if (typeof innerRef.value[key] === 'function') { + publicApi[key] = innerRef.value[key]; + } + } + }); + return () => + h( + component, + { ...componentProps, placeholder, ...props, ...attrs, ref: innerRef }, + slots, + ); + }, + }); +}; + +// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 +export type ComponentType = + | 'ApiSelect' + | 'ApiTreeSelect' + | 'AutoComplete' + | 'Checkbox' + | 'CheckboxGroup' + | 'DatePicker' + | 'DefaultButton' + | 'Divider' + | 'IconPicker' + | 'Input' + | 'InputNumber' + | 'InputPassword' + | 'Mentions' + | 'PrimaryButton' + | 'Radio' + | 'RadioGroup' + | 'RangePicker' + | 'Rate' + | 'Select' + | 'Space' + | 'Switch' + | 'Textarea' + | 'TimePicker' + | 'TreeSelect' + | 'Upload' + | BaseFormComponentType; + +async function initComponentAdapter() { + const components: Partial> = { + // 如果你的组件体积比较大,可以使用异步加载 + // Button: () => + // import('xxx').then((res) => res.Button), + ApiSelect: withDefaultPlaceholder( + { + ...ApiComponent, + name: 'ApiSelect', + }, + 'select', + { + component: Select, + loadingSlot: 'suffixIcon', + visibleEvent: 'onDropdownVisibleChange', + modelPropName: 'value', + }, + ), + ApiTreeSelect: withDefaultPlaceholder( + { + ...ApiComponent, + name: 'ApiTreeSelect', + }, + 'select', + { + component: TreeSelect, + fieldNames: { label: 'label', value: 'value', children: 'children' }, + loadingSlot: 'suffixIcon', + modelPropName: 'value', + optionsPropName: 'treeData', + visibleEvent: 'onVisibleChange', + }, + ), + AutoComplete, + Checkbox, + CheckboxGroup, + DatePicker, + // 自定义默认按钮 + DefaultButton: (props, { attrs, slots }) => { + return h(Button, { ...props, attrs, type: 'default' }, slots); + }, + Divider, + IconPicker: withDefaultPlaceholder(IconPicker, 'select', { + iconSlot: 'addonAfter', + inputComponent: Input, + modelValueProp: 'value', + }), + 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); + }, + Radio, + RadioGroup, + RangePicker, + Rate, + Select: withDefaultPlaceholder(Select, 'select'), + Space, + Switch, + Textarea: withDefaultPlaceholder(Textarea, 'input'), + TimePicker, + TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'), + Upload, + }; + + // 将组件注册到全局共享状态中 + globalShareState.setComponents(components); + + // 定义全局共享状态中的消息提示 + globalShareState.defineMessage({ + // 复制成功消息提示 + copyPreferencesSuccess: (title, content) => { + notification.success({ + description: content, + message: title, + placement: 'bottomRight', + }); + }, + }); +} + +export { initComponentAdapter }; diff --git a/apps/web-antd/src/adapter/form.ts b/apps/web-antd/src/adapter/form.ts new file mode 100644 index 0000000..65ff793 --- /dev/null +++ b/apps/web-antd/src/adapter/form.ts @@ -0,0 +1,47 @@ +import type { + VbenFormSchema as FormSchema, + VbenFormProps, +} from '@vben/common-ui'; + +import type { ComponentType } from './component'; + +import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui'; +import { $t } from '@vben/locales'; + +setupVbenForm({ + config: { + // ant design vue组件库默认都是 v-model:value + baseModelPropName: 'value', + + // 一些组件是 v-model:checked 或者 v-model:fileList + modelPropNameMap: { + Checkbox: 'checked', + Radio: 'checked', + Switch: 'checked', + Upload: 'fileList', + }, + }, + defineRules: { + // 输入项目必填国际化适配 + required: (value, _params, ctx) => { + if (value === undefined || value === null || value.length === 0) { + return $t('ui.formRules.required', [ctx.label]); + } + return true; + }, + // 选择项目必填国际化适配 + selectRequired: (value, _params, ctx) => { + if (value === undefined || value === null) { + return $t('ui.formRules.selectRequired', [ctx.label]); + } + return true; + }, + }, +}); + +const useVbenForm = useForm; + +export { useVbenForm, z }; + +export type VbenFormSchema = FormSchema; +export type { VbenFormProps }; diff --git a/apps/web-antd/src/adapter/vxe-table.ts b/apps/web-antd/src/adapter/vxe-table.ts new file mode 100644 index 0000000..90081e2 --- /dev/null +++ b/apps/web-antd/src/adapter/vxe-table.ts @@ -0,0 +1,72 @@ +import { h } from 'vue'; + +import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table'; + +import { Button, Image } from 'ant-design-vue'; + +import { useVbenForm } from './form'; + +setupVbenVxeTable({ + configVxeTable: (vxeUI) => { + vxeUI.setConfig({ + grid: { + align: 'center', + border: true, + columnConfig: { + resizable: true, + }, + minHeight: 180, + formConfig: { + // 全局禁用vxe-table的表单配置,使用formOptions + enabled: false, + }, + sortConfig: { + remote: true, + }, + proxyConfig: { + sort: true, // 启用排序请求代理 + autoLoad: true, + response: { + result: 'items', + total: 'totalCount', + list: 'items', + }, + showActiveMsg: true, + showResponseMsg: false, + }, + round: true, + showOverflow: true, + stripe: true, // 斑马线 + size: 'small', // medium / small / mini + }, + }); + + // 表格配置项可以用 cellRender: { name: 'CellImage' }, + vxeUI.renderer.add('CellImage', { + renderTableDefault(_renderOpts, params) { + const { column, row } = params; + return h(Image, { src: row[column.field] }); + }, + }); + + // 表格配置项可以用 cellRender: { name: 'CellLink' }, + vxeUI.renderer.add('CellLink', { + renderTableDefault(renderOpts) { + const { props } = renderOpts; + return h( + Button, + { size: 'small', type: 'link' }, + { default: () => props?.text }, + ); + }, + }); + + // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 + // vxeUI.formats.add + }, + useVbenForm, +}); + +export { useVbenVxeGrid }; + +export type * from '@vben/plugins/vxe-table'; diff --git a/apps/web-antd/src/api-client-config/config.ts b/apps/web-antd/src/api-client-config/config.ts new file mode 100644 index 0000000..d562e98 --- /dev/null +++ b/apps/web-antd/src/api-client-config/config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from '@hey-api/openapi-ts'; + +export default defineConfig({ + client: '@hey-api/client-axios', + input: 'http://localhost:44315/swagger/AbpPro/swagger.json', + output: 'src/api-client', +}); diff --git a/apps/web-antd/src/api-client-config/index.ts b/apps/web-antd/src/api-client-config/index.ts new file mode 100644 index 0000000..97d6367 --- /dev/null +++ b/apps/web-antd/src/api-client-config/index.ts @@ -0,0 +1,143 @@ +import { useAccessStore, useUserStore } from '@vben/stores'; + +import { message as Message } from 'ant-design-vue'; + +import { postApiAppAccountRefreshToken } from '#/api-client'; +import { $t } from '#/locales'; +import { antdLocale } from '#/locales/index'; +import { useAuthStore } from '#/store'; + +import { client } from '../api-client/services.gen'; + +client.setConfig({ + baseURL: import.meta.env.DEV + ? '/proxy/' + : import.meta.env.VITE_APP_API_ADDRESS, + timeout: 1000 * 60, + responseType: 'json', + throwOnError: true, +}); +// 是否正在刷新token +let isRefreshing = false; +// 刷新token队列 +let refreshTokenQueue: ((token: string) => void)[] = []; +client.instance.interceptors.request.use((request) => { + // 全局拦截请求发送前提交的参数 + const userStore = useUserStore(); + const accessStore = useAccessStore(); + const token = accessStore.getAccessToken(); + // 设置请求头 + if (request.headers) { + request.headers.__tenant = userStore.tenant?.tenantId; + // todo vben5 没有提供统一获取当前语言的方式 + request.headers['accept-language'] = antdLocale.value.locale; + } + + // 如果token过期,则跳转到登录页面 + if ( + request.url !== undefined && + request.url.includes('/api/app/account/login') + ) { + return request; + } + + // 设置请求头 + if (request.headers) { + request.headers.Authorization = `Bearer ${token}`; + } + + return request; +}); + +client.instance.interceptors.response.use( + (response) => { + return Promise.resolve(response); + }, + async (error) => { + let message = error.message; + if (message === 'Network Error') { + message = $t('common.mesage500'); + } else if (message.includes('timeout')) { + message = $t('common.timeOut'); + } else + switch (error.status) { + case 400: { + message = error.response.data.error?.validationErrors[0].message; + break; + } + case 401: { + message = $t('common.mesage401'); + const { config } = error; + const originalRequest = config; + if (isRefreshing) { + return new Promise((resolve) => { + refreshTokenQueue.push((token) => { + originalRequest.headers.Authorization = `Bearer ${token}`; + resolve(client.request(originalRequest)); + }); + }); + } else { + isRefreshing = true; + try { + const newToken = await refreshTokenAsync(); + // 处理队列中的请求 + refreshTokenQueue.forEach((callback) => callback(newToken)); + // 清空队列 + refreshTokenQueue = []; + return client.request(originalRequest); + } catch (refreshError) { + // 如果刷新 token 失败,处理错误(如强制登出或跳转登录页面) + message = $t('common.mesage401'); + refreshTokenQueue = []; + const authStore = useAuthStore(); + authStore.logout(); + console.error(refreshError); + } finally { + isRefreshing = false; + } + } + break; + } + case 403: { + message = $t('common.mesage403'); + break; + } + case 500: { + message = error.response.data.error?.message; + break; + } + default: { + if (message.includes('Request failed with status code')) { + message = $t('common.mesage500'); + } + } + } + Message.error(message); + throw error; + }, +); + +async function refreshTokenAsync(): Promise { + try { + const userStore = useUserStore(); + const accessStore = useAccessStore(); + const refreshToken = accessStore.getRefreshToken(); + if (!refreshToken) return ''; + const res = await postApiAppAccountRefreshToken({ + body: { + userId: userStore.userInfo?.id, + refreshToken, + }, + }); + if (res?.data?.success) { + accessStore.setAccessToken(res.data.token as string); + accessStore.setRefreshToken(res.data.refreshToken as string); + return res.data.token as string; + } else { + throw new Error('get refreshToken error'); + } + } catch { + throw new Error($t('common.mesage401')); + } +} +export default client; diff --git a/apps/web-antd/src/api-client/index.ts b/apps/web-antd/src/api-client/index.ts new file mode 100644 index 0000000..002afc3 --- /dev/null +++ b/apps/web-antd/src/api-client/index.ts @@ -0,0 +1,4 @@ +// This file is auto-generated by @hey-api/openapi-ts +export * from './schemas.gen'; +export * from './services.gen'; +export * from './types.gen'; diff --git a/apps/web-antd/src/api-client/schemas.gen.ts b/apps/web-antd/src/api-client/schemas.gen.ts new file mode 100644 index 0000000..6bdde7c --- /dev/null +++ b/apps/web-antd/src/api-client/schemas.gen.ts @@ -0,0 +1,8221 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export const AbpLoginResultSchema = { + type: 'object', + properties: { + result: { + $ref: '#/components/schemas/LoginResultType', + }, + description: { + type: 'string', + nullable: true, + readOnly: true, + }, + }, + additionalProperties: false, +} as const; + +export const AbpProApplicationConfigurationDtoSchema = { + type: 'object', + properties: { + oidcConfiguration: { + $ref: '#/components/schemas/ApplicationOidcConfigurationDto', + }, + multiTenancy: { + $ref: '#/components/schemas/MultiTenancyInfoDto', + }, + }, + additionalProperties: false, +} as const; + +export const ActionApiDescriptionModelSchema = { + type: 'object', + properties: { + uniqueName: { + type: 'string', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + httpMethod: { + type: 'string', + nullable: true, + }, + url: { + type: 'string', + nullable: true, + }, + supportedVersions: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + parametersOnMethod: { + type: 'array', + items: { + $ref: '#/components/schemas/MethodParameterApiDescriptionModel', + }, + nullable: true, + }, + parameters: { + type: 'array', + items: { + $ref: '#/components/schemas/ParameterApiDescriptionModel', + }, + nullable: true, + }, + returnValue: { + $ref: '#/components/schemas/ReturnValueApiDescriptionModel', + }, + allowAnonymous: { + type: 'boolean', + nullable: true, + }, + implementFrom: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const AddOrUpdateConnectionStringInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: 'id', + format: 'uuid', + }, + name: { + type: 'string', + description: '连接字符串名称', + nullable: true, + }, + value: { + type: 'string', + description: '连接字符串地址', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const AddRoleToOrganizationUnitInputSchema = { + type: 'object', + properties: { + roleId: { + type: 'array', + items: { + type: 'string', + format: 'uuid', + }, + nullable: true, + }, + organizationUnitId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const AddUserToOrganizationUnitInputSchema = { + type: 'object', + properties: { + userId: { + type: 'array', + items: { + type: 'string', + format: 'uuid', + }, + nullable: true, + }, + organizationUnitId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const AggregateRouteConfigSchema = { + type: 'object', + properties: { + routeKey: { + type: 'string', + nullable: true, + }, + parameter: { + type: 'string', + nullable: true, + }, + jsonPath: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationApiDescriptionModelSchema = { + type: 'object', + properties: { + modules: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/ModuleApiDescriptionModel', + }, + nullable: true, + }, + types: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/TypeApiDescriptionModel', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationAuthConfigurationDtoSchema = { + type: 'object', + properties: { + grantedPolicies: { + type: 'object', + additionalProperties: { + type: 'boolean', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationConfigurationDtoSchema = { + type: 'object', + properties: { + localization: { + $ref: '#/components/schemas/ApplicationLocalizationConfigurationDto', + }, + auth: { + $ref: '#/components/schemas/ApplicationAuthConfigurationDto', + }, + setting: { + $ref: '#/components/schemas/ApplicationSettingConfigurationDto', + }, + currentUser: { + $ref: '#/components/schemas/CurrentUserDto', + }, + features: { + $ref: '#/components/schemas/ApplicationFeatureConfigurationDto', + }, + globalFeatures: { + $ref: '#/components/schemas/ApplicationGlobalFeatureConfigurationDto', + }, + multiTenancy: { + $ref: '#/components/schemas/MultiTenancyInfoDto', + }, + currentTenant: { + $ref: '#/components/schemas/CurrentTenantDto', + }, + timing: { + $ref: '#/components/schemas/TimingDto', + }, + clock: { + $ref: '#/components/schemas/ClockDto', + }, + objectExtensions: { + $ref: '#/components/schemas/ObjectExtensionsDto', + }, + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationFeatureConfigurationDtoSchema = { + type: 'object', + properties: { + values: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationGlobalFeatureConfigurationDtoSchema = { + type: 'object', + properties: { + enabledFeatures: { + uniqueItems: true, + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationLocalizationConfigurationDtoSchema = { + type: 'object', + properties: { + values: { + type: 'object', + additionalProperties: { + type: 'object', + additionalProperties: { + type: 'string', + }, + }, + nullable: true, + }, + resources: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/ApplicationLocalizationResourceDto', + }, + nullable: true, + }, + languages: { + type: 'array', + items: { + $ref: '#/components/schemas/LanguageInfo', + }, + nullable: true, + }, + currentCulture: { + $ref: '#/components/schemas/CurrentCultureDto', + }, + defaultResourceName: { + type: 'string', + nullable: true, + }, + languagesMap: { + type: 'object', + additionalProperties: { + type: 'array', + items: { + $ref: '#/components/schemas/NameValue', + }, + }, + nullable: true, + }, + languageFilesMap: { + type: 'object', + additionalProperties: { + type: 'array', + items: { + $ref: '#/components/schemas/NameValue', + }, + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationLocalizationDtoSchema = { + type: 'object', + properties: { + resources: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/ApplicationLocalizationResourceDto', + }, + nullable: true, + }, + currentCulture: { + $ref: '#/components/schemas/CurrentCultureDto', + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationLocalizationResourceDtoSchema = { + type: 'object', + properties: { + texts: { + type: 'object', + additionalProperties: { + type: 'string', + }, + nullable: true, + }, + baseResources: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationOidcConfigurationDtoSchema = { + type: 'object', + properties: { + enabled: { + type: 'boolean', + description: '是否启用', + }, + oidcConfiguration: { + type: 'array', + items: { + $ref: '#/components/schemas/OidcConfiguration', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ApplicationSettingConfigurationDtoSchema = { + type: 'object', + properties: { + values: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ChangePasswordInputSchema = { + required: ['newPassword'], + type: 'object', + properties: { + currentPassword: { + maxLength: 128, + minLength: 0, + type: 'string', + nullable: true, + }, + newPassword: { + maxLength: 128, + minLength: 0, + type: 'string', + }, + }, + additionalProperties: false, +} as const; + +export const ClockDtoSchema = { + type: 'object', + properties: { + kind: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ControlTypeSchema = { + enum: [10, 20, 30, 40], + type: 'integer', + description: '控制策略', + format: 'int32', + 'x-enumNames': ['Aggregate', 'Entity', 'Enum', 'Global'], + 'x-enum-varnames': ['Aggregate', 'Entity', 'Enum', 'Global'], +} as const; + +export const ControllerApiDescriptionModelSchema = { + type: 'object', + properties: { + controllerName: { + type: 'string', + nullable: true, + }, + controllerGroupName: { + type: 'string', + nullable: true, + }, + isRemoteService: { + type: 'boolean', + }, + isIntegrationService: { + type: 'boolean', + }, + apiVersion: { + type: 'string', + nullable: true, + }, + type: { + type: 'string', + nullable: true, + }, + interfaces: { + type: 'array', + items: { + $ref: '#/components/schemas/ControllerInterfaceApiDescriptionModel', + }, + nullable: true, + }, + actions: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/ActionApiDescriptionModel', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ControllerInterfaceApiDescriptionModelSchema = { + type: 'object', + properties: { + type: { + type: 'string', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + methods: { + type: 'array', + items: { + $ref: '#/components/schemas/InterfaceMethodApiDescriptionModel', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const CopyTemplateInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + name: { + type: 'string', + description: '名称', + nullable: true, + }, + remark: { + type: 'string', + description: '备注', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const CreateAggregateInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + projectId: { + type: 'string', + format: 'uuid', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + }, + additionalProperties: false, +} as const; + +export const CreateDataDictinaryDetailInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + type: 'string', + nullable: true, + }, + displayText: { + type: 'string', + nullable: true, + }, + description: { + type: 'string', + nullable: true, + }, + order: { + type: 'integer', + format: 'int32', + }, + }, + additionalProperties: false, +} as const; + +export const CreateDataDictinaryInputSchema = { + type: 'object', + properties: { + code: { + type: 'string', + nullable: true, + }, + displayText: { + type: 'string', + nullable: true, + }, + description: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const CreateEntityModelInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + relationalType: { + $ref: '#/components/schemas/RelationalType', + }, + }, + additionalProperties: false, +} as const; + +export const CreateEntityModelPropertyInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + id: { + type: 'string', + description: '实体模型Id', + format: 'uuid', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + isRequired: { + type: 'boolean', + description: '必填', + }, + maxLength: { + type: 'integer', + description: '字符串最大长度', + format: 'int32', + nullable: true, + }, + minLength: { + type: 'integer', + description: '字符串最小长度', + format: 'int32', + nullable: true, + }, + decimalPrecision: { + type: 'integer', + description: '当类型为decimal时的小数位数 (18,4) 中的18', + format: 'int32', + nullable: true, + }, + decimalScale: { + type: 'integer', + description: '当类型为decimal时的字段长度 (18,4) 中的4', + format: 'int32', + nullable: true, + }, + enumTypeId: { + type: 'string', + description: '枚举类型Id', + format: 'uuid', + nullable: true, + }, + dataTypeId: { + type: 'string', + description: '数据类型Id', + format: 'uuid', + nullable: true, + }, + allowSearch: { + type: 'boolean', + description: '允许作为查询条件', + }, + allowAdd: { + type: 'boolean', + description: '允许添加', + }, + allowEdit: { + type: 'boolean', + description: '允许编辑', + }, + }, + additionalProperties: false, +} as const; + +export const CreateEnumTypeInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + entityModelId: { + type: 'string', + description: '实体模型Id', + format: 'uuid', + }, + projectId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const CreateEnumTypePropertyInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + enumTypeId: { + type: 'string', + description: 'Id', + format: 'uuid', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + value: { + type: 'integer', + description: '枚举值', + format: 'int32', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + }, + additionalProperties: false, +} as const; + +export const CreateLanguageInputSchema = { + type: 'object', + properties: { + cultureName: { + type: 'string', + description: '语言名称', + nullable: true, + }, + uiCultureName: { + type: 'string', + description: 'Ui语言名称', + nullable: true, + }, + displayName: { + type: 'string', + description: '显示名称', + nullable: true, + }, + flagIcon: { + type: 'string', + description: '图标', + nullable: true, + }, + isEnabled: { + type: 'boolean', + description: '是否启用', + }, + }, + additionalProperties: false, + description: '创建语言', +} as const; + +export const CreateLanguageTextInputSchema = { + type: 'object', + properties: { + resourceName: { + type: 'string', + description: '资源名称', + nullable: true, + }, + cultureName: { + type: 'string', + description: '语言名称', + nullable: true, + }, + name: { + type: 'string', + description: '名称', + nullable: true, + }, + value: { + type: 'string', + description: '值', + nullable: true, + }, + }, + additionalProperties: false, + description: '创建语言文本', +} as const; + +export const CreateMenuInputSchema = { + required: ['hideInMenu', 'keepAlive', 'name', 'order', 'path', 'title'], + type: 'object', + properties: { + parentId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + name: { + minLength: 1, + type: 'string', + description: '唯一编码', + }, + title: { + minLength: 1, + type: 'string', + description: '标题', + }, + displayTitle: { + type: 'string', + description: '标题', + nullable: true, + }, + icon: { + type: 'string', + description: '图标', + nullable: true, + }, + keepAlive: { + type: 'boolean', + description: '是否缓存', + }, + hideInMenu: { + type: 'boolean', + description: '是否显示', + }, + order: { + type: 'integer', + description: '排序', + format: 'int32', + }, + path: { + minLength: 1, + type: 'string', + description: '路由地址', + }, + menuType: { + $ref: '#/components/schemas/MenuType', + }, + openType: { + $ref: '#/components/schemas/OpenType', + }, + url: { + type: 'string', + description: '内外链地址', + nullable: true, + }, + component: { + type: 'string', + description: '组件地址', + nullable: true, + }, + enabled: { + type: 'boolean', + description: '是否启用', + }, + policy: { + type: 'string', + description: '权限', + nullable: true, + }, + }, + additionalProperties: false, + description: '创建菜单', +} as const; + +export const CreateOrganizationUnitInputSchema = { + type: 'object', + properties: { + displayName: { + type: 'string', + nullable: true, + }, + parentId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const CreateProjectInputSchema = { + type: 'object', + properties: { + owner: { + type: 'string', + description: '负责人', + nullable: true, + }, + companyName: { + type: 'string', + description: '公司名称', + nullable: true, + }, + projectName: { + type: 'string', + description: '项目名称', + nullable: true, + }, + remark: { + type: 'string', + description: '备注', + nullable: true, + }, + supportTenant: { + type: 'boolean', + description: '是否支持多租户', + }, + }, + additionalProperties: false, +} as const; + +export const CreateTemplateDetailInputSchema = { + type: 'object', + properties: { + templateId: { + type: 'string', + description: '模板id', + format: 'uuid', + }, + parentId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + templateType: { + $ref: '#/components/schemas/TemplateType', + }, + controlType: { + $ref: '#/components/schemas/ControlType', + }, + name: { + type: 'string', + description: '模板类型', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + content: { + type: 'string', + description: '模板内容', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const CreateTemplateInputSchema = { + type: 'object', + properties: { + name: { + type: 'string', + description: '名称', + nullable: true, + }, + remark: { + type: 'string', + description: '备注', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const CreateTextTemplateInputSchema = { + required: ['code', 'content', 'cultureName', 'name'], + type: 'object', + properties: { + name: { + minLength: 1, + type: 'string', + description: '名称', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + content: { + minLength: 1, + type: 'string', + description: '内容', + }, + cultureName: { + minLength: 1, + type: 'string', + description: '语言', + }, + }, + additionalProperties: false, + description: '创建模板', +} as const; + +export const CurrentCultureDtoSchema = { + type: 'object', + properties: { + displayName: { + type: 'string', + nullable: true, + }, + englishName: { + type: 'string', + nullable: true, + }, + threeLetterIsoLanguageName: { + type: 'string', + nullable: true, + }, + twoLetterIsoLanguageName: { + type: 'string', + nullable: true, + }, + isRightToLeft: { + type: 'boolean', + }, + cultureName: { + type: 'string', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + nativeName: { + type: 'string', + nullable: true, + }, + dateTimeFormat: { + $ref: '#/components/schemas/DateTimeFormatDto', + }, + }, + additionalProperties: false, +} as const; + +export const CurrentTenantDtoSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + isAvailable: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const CurrentUserDtoSchema = { + type: 'object', + properties: { + isAuthenticated: { + type: 'boolean', + }, + id: { + type: 'string', + format: 'uuid', + nullable: true, + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + impersonatorUserId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + impersonatorTenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + impersonatorUserName: { + type: 'string', + nullable: true, + }, + impersonatorTenantName: { + type: 'string', + nullable: true, + }, + userName: { + type: 'string', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + surName: { + type: 'string', + nullable: true, + }, + email: { + type: 'string', + nullable: true, + }, + emailVerified: { + type: 'boolean', + }, + phoneNumber: { + type: 'string', + nullable: true, + }, + phoneNumberVerified: { + type: 'boolean', + }, + roles: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + sessionId: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const DataTypeDtoSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + type: 'string', + description: '编码', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + isEnum: { + type: 'boolean', + description: '是否是枚举', + }, + }, + additionalProperties: false, +} as const; + +export const DateTimeFormatDtoSchema = { + type: 'object', + properties: { + calendarAlgorithmType: { + type: 'string', + nullable: true, + }, + dateTimeFormatLong: { + type: 'string', + nullable: true, + }, + shortDatePattern: { + type: 'string', + nullable: true, + }, + fullDateTimePattern: { + type: 'string', + nullable: true, + }, + dateSeparator: { + type: 'string', + nullable: true, + }, + shortTimePattern: { + type: 'string', + nullable: true, + }, + longTimePattern: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const DeleteAggregateInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteConnectionStringInputSchema = { + type: 'object', + properties: { + name: { + type: 'string', + description: '连接字符串名称', + nullable: true, + }, + tenantId: { + type: 'string', + description: '租户id', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteDataDictionaryDetailInputSchema = { + type: 'object', + properties: { + dataDictionaryId: { + type: 'string', + format: 'uuid', + }, + dataDictionayDetailId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteEntityModelInputSchema = { + type: 'object', + properties: { + aggregateId: { + type: 'string', + format: 'uuid', + }, + id: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteEntityModelPropertyInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + propertyId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteEnumTypeInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Id', + format: 'uuid', + }, + entityModelId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteEnumTypePropertyInputSchema = { + type: 'object', + properties: { + enumTypeId: { + type: 'string', + description: 'Id', + format: 'uuid', + }, + id: { + type: 'string', + description: 'Id', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteFeatureInputSchema = { + type: 'object', + properties: { + providerName: { + type: 'string', + nullable: true, + }, + providerKey: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const DeleteFileObjectInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '文件Id', + format: 'uuid', + }, + }, + additionalProperties: false, + description: '删除文件', +} as const; + +export const DeleteLanguageInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '语言Id', + format: 'uuid', + }, + }, + additionalProperties: false, + description: '删除语言', +} as const; + +export const DeleteMenuInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '菜单Id', + format: 'uuid', + }, + }, + additionalProperties: false, + description: '删除菜单', +} as const; + +export const DeleteMessageInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + receiverUserId: { + type: 'string', + description: '接受者Id', + format: 'uuid', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const DeleteProjectInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteTemplateDetailInputSchema = { + type: 'object', + properties: { + templateId: { + type: 'string', + format: 'uuid', + }, + templateDetailId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteTemplateInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const DeleteTextTemplateInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '模板Id', + format: 'uuid', + }, + }, + additionalProperties: false, + description: '删除模板', +} as const; + +export const DisabledTwoFactorInputSchema = { + required: ['code'], + type: 'object', + properties: { + code: { + minLength: 1, + type: 'string', + description: '验证码', + }, + }, + additionalProperties: false, +} as const; + +export const DownCodeInputSchema = { + type: 'object', + properties: { + templateId: { + type: 'string', + format: 'uuid', + }, + projectId: { + type: 'string', + format: 'uuid', + }, + entityId: { + type: 'array', + items: { + type: 'string', + format: 'uuid', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const DownloadFileObjectInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '文件Id', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const EnabledTwoFactorInputSchema = { + required: ['code', 'secret'], + type: 'object', + properties: { + code: { + minLength: 1, + type: 'string', + description: '验证码', + }, + secret: { + minLength: 1, + type: 'string', + description: '密钥', + }, + }, + additionalProperties: false, +} as const; + +export const EntityChangeTypeSchema = { + enum: [0, 1, 2], + type: 'integer', + format: 'int32', + 'x-enumNames': ['Created', 'Updated', 'Deleted'], + 'x-enum-varnames': ['Created', 'Updated', 'Deleted'], +} as const; + +export const EntityExtensionDtoSchema = { + type: 'object', + properties: { + properties: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/ExtensionPropertyDto', + }, + nullable: true, + }, + configuration: { + type: 'object', + additionalProperties: {}, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const EntityOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + type: 'string', + description: '编码', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + codeCamelCase: { + type: 'string', + description: '首字母小写', + nullable: true, + readOnly: true, + }, + codePluralized: { + type: 'string', + description: '复数形式', + nullable: true, + readOnly: true, + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionEnumDtoSchema = { + type: 'object', + properties: { + fields: { + type: 'array', + items: { + $ref: '#/components/schemas/ExtensionEnumFieldDto', + }, + nullable: true, + }, + localizationResource: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionEnumFieldDtoSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + value: { + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyApiCreateDtoSchema = { + type: 'object', + properties: { + isAvailable: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyApiDtoSchema = { + type: 'object', + properties: { + onGet: { + $ref: '#/components/schemas/ExtensionPropertyApiGetDto', + }, + onCreate: { + $ref: '#/components/schemas/ExtensionPropertyApiCreateDto', + }, + onUpdate: { + $ref: '#/components/schemas/ExtensionPropertyApiUpdateDto', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyApiGetDtoSchema = { + type: 'object', + properties: { + isAvailable: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyApiUpdateDtoSchema = { + type: 'object', + properties: { + isAvailable: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyAttributeDtoSchema = { + type: 'object', + properties: { + typeSimple: { + type: 'string', + nullable: true, + }, + config: { + type: 'object', + additionalProperties: {}, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyDtoSchema = { + type: 'object', + properties: { + type: { + type: 'string', + nullable: true, + }, + typeSimple: { + type: 'string', + nullable: true, + }, + displayName: { + $ref: '#/components/schemas/LocalizableStringDto', + }, + api: { + $ref: '#/components/schemas/ExtensionPropertyApiDto', + }, + ui: { + $ref: '#/components/schemas/ExtensionPropertyUiDto', + }, + policy: { + $ref: '#/components/schemas/ExtensionPropertyPolicyDto', + }, + attributes: { + type: 'array', + items: { + $ref: '#/components/schemas/ExtensionPropertyAttributeDto', + }, + nullable: true, + }, + configuration: { + type: 'object', + additionalProperties: {}, + nullable: true, + }, + defaultValue: { + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyFeaturePolicyDtoSchema = { + type: 'object', + properties: { + features: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + requiresAll: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyGlobalFeaturePolicyDtoSchema = { + type: 'object', + properties: { + features: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + requiresAll: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyPermissionPolicyDtoSchema = { + type: 'object', + properties: { + permissionNames: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + requiresAll: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyPolicyDtoSchema = { + type: 'object', + properties: { + globalFeatures: { + $ref: '#/components/schemas/ExtensionPropertyGlobalFeaturePolicyDto', + }, + features: { + $ref: '#/components/schemas/ExtensionPropertyFeaturePolicyDto', + }, + permissions: { + $ref: '#/components/schemas/ExtensionPropertyPermissionPolicyDto', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyUiDtoSchema = { + type: 'object', + properties: { + onTable: { + $ref: '#/components/schemas/ExtensionPropertyUiTableDto', + }, + onCreateForm: { + $ref: '#/components/schemas/ExtensionPropertyUiFormDto', + }, + onEditForm: { + $ref: '#/components/schemas/ExtensionPropertyUiFormDto', + }, + lookup: { + $ref: '#/components/schemas/ExtensionPropertyUiLookupDto', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyUiFormDtoSchema = { + type: 'object', + properties: { + isVisible: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyUiLookupDtoSchema = { + type: 'object', + properties: { + url: { + type: 'string', + nullable: true, + }, + resultListPropertyName: { + type: 'string', + nullable: true, + }, + displayPropertyName: { + type: 'string', + nullable: true, + }, + valuePropertyName: { + type: 'string', + nullable: true, + }, + filterParamName: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ExtensionPropertyUiTableDtoSchema = { + type: 'object', + properties: { + isVisible: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const FeatureDtoSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + displayName: { + type: 'string', + nullable: true, + }, + value: { + type: 'string', + nullable: true, + }, + provider: { + $ref: '#/components/schemas/FeatureProviderDto', + }, + description: { + type: 'string', + nullable: true, + }, + valueType: { + $ref: '#/components/schemas/IStringValueType', + }, + depth: { + type: 'integer', + format: 'int32', + }, + parentName: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FeatureGroupDtoSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + displayName: { + type: 'string', + nullable: true, + }, + features: { + type: 'array', + items: { + $ref: '#/components/schemas/FeatureDto', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FeatureProviderDtoSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + key: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FileAggregateRouteSchema = { + type: 'object', + properties: { + routeKeys: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + routeKeysConfig: { + type: 'array', + items: { + $ref: '#/components/schemas/AggregateRouteConfig', + }, + nullable: true, + }, + upstreamPathTemplate: { + type: 'string', + nullable: true, + }, + upstreamHost: { + type: 'string', + nullable: true, + }, + routeIsCaseSensitive: { + type: 'boolean', + }, + aggregator: { + type: 'string', + nullable: true, + }, + upstreamHttpMethod: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + readOnly: true, + }, + priority: { + type: 'integer', + format: 'int32', + }, + }, + additionalProperties: false, +} as const; + +export const FileAuthenticationOptionsSchema = { + type: 'object', + properties: { + authenticationProviderKey: { + type: 'string', + nullable: true, + }, + allowedScopes: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FileCacheOptionsSchema = { + type: 'object', + properties: { + ttlSeconds: { + type: 'integer', + format: 'int32', + }, + region: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FileConfigurationSchema = { + type: 'object', + properties: { + routes: { + type: 'array', + items: { + $ref: '#/components/schemas/FileRoute', + }, + nullable: true, + }, + dynamicRoutes: { + type: 'array', + items: { + $ref: '#/components/schemas/FileDynamicRoute', + }, + nullable: true, + }, + aggregates: { + type: 'array', + items: { + $ref: '#/components/schemas/FileAggregateRoute', + }, + nullable: true, + }, + globalConfiguration: { + $ref: '#/components/schemas/FileGlobalConfiguration', + }, + }, + additionalProperties: false, +} as const; + +export const FileDynamicRouteSchema = { + type: 'object', + properties: { + serviceName: { + type: 'string', + nullable: true, + }, + rateLimitRule: { + $ref: '#/components/schemas/FileRateLimitRule', + }, + downstreamHttpVersion: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FileGlobalConfigurationSchema = { + type: 'object', + properties: { + requestIdKey: { + type: 'string', + nullable: true, + }, + serviceDiscoveryProvider: { + $ref: '#/components/schemas/FileServiceDiscoveryProvider', + }, + rateLimitOptions: { + $ref: '#/components/schemas/FileRateLimitOptions', + }, + qoSOptions: { + $ref: '#/components/schemas/FileQoSOptions', + }, + baseUrl: { + type: 'string', + nullable: true, + }, + loadBalancerOptions: { + $ref: '#/components/schemas/FileLoadBalancerOptions', + }, + downstreamScheme: { + type: 'string', + nullable: true, + }, + httpHandlerOptions: { + $ref: '#/components/schemas/FileHttpHandlerOptions', + }, + downstreamHttpVersion: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FileHostAndPortSchema = { + type: 'object', + properties: { + host: { + type: 'string', + nullable: true, + }, + port: { + type: 'integer', + format: 'int32', + }, + }, + additionalProperties: false, +} as const; + +export const FileHttpHandlerOptionsSchema = { + type: 'object', + properties: { + allowAutoRedirect: { + type: 'boolean', + }, + useCookieContainer: { + type: 'boolean', + }, + useTracing: { + type: 'boolean', + }, + useProxy: { + type: 'boolean', + }, + maxConnectionsPerServer: { + type: 'integer', + format: 'int32', + }, + }, + additionalProperties: false, +} as const; + +export const FileLoadBalancerOptionsSchema = { + type: 'object', + properties: { + type: { + type: 'string', + nullable: true, + }, + key: { + type: 'string', + nullable: true, + }, + expiry: { + type: 'integer', + format: 'int32', + }, + }, + additionalProperties: false, +} as const; + +export const FileQoSOptionsSchema = { + type: 'object', + properties: { + exceptionsAllowedBeforeBreaking: { + type: 'integer', + format: 'int32', + }, + durationOfBreak: { + type: 'integer', + format: 'int32', + }, + timeoutValue: { + type: 'integer', + format: 'int32', + }, + }, + additionalProperties: false, +} as const; + +export const FileRateLimitOptionsSchema = { + type: 'object', + properties: { + clientIdHeader: { + type: 'string', + nullable: true, + }, + quotaExceededMessage: { + type: 'string', + nullable: true, + }, + rateLimitCounterPrefix: { + type: 'string', + nullable: true, + }, + disableRateLimitHeaders: { + type: 'boolean', + }, + httpStatusCode: { + type: 'integer', + format: 'int32', + }, + }, + additionalProperties: false, +} as const; + +export const FileRateLimitRuleSchema = { + type: 'object', + properties: { + clientWhitelist: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + enableRateLimiting: { + type: 'boolean', + }, + period: { + type: 'string', + nullable: true, + }, + periodTimespan: { + type: 'number', + format: 'double', + }, + limit: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const FileRouteSchema = { + type: 'object', + properties: { + downstreamPathTemplate: { + type: 'string', + nullable: true, + }, + upstreamPathTemplate: { + type: 'string', + nullable: true, + }, + upstreamHttpMethod: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + downstreamHttpMethod: { + type: 'string', + nullable: true, + }, + addHeadersToRequest: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + upstreamHeaderTransform: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + downstreamHeaderTransform: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + addClaimsToRequest: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + routeClaimsRequirement: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + addQueriesToRequest: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + changeDownstreamPathTemplate: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + requestIdKey: { + type: 'string', + nullable: true, + }, + fileCacheOptions: { + $ref: '#/components/schemas/FileCacheOptions', + }, + routeIsCaseSensitive: { + type: 'boolean', + }, + serviceName: { + type: 'string', + nullable: true, + }, + serviceNamespace: { + type: 'string', + nullable: true, + }, + downstreamScheme: { + type: 'string', + nullable: true, + }, + qoSOptions: { + $ref: '#/components/schemas/FileQoSOptions', + }, + loadBalancerOptions: { + $ref: '#/components/schemas/FileLoadBalancerOptions', + }, + rateLimitOptions: { + $ref: '#/components/schemas/FileRateLimitRule', + }, + authenticationOptions: { + $ref: '#/components/schemas/FileAuthenticationOptions', + }, + httpHandlerOptions: { + $ref: '#/components/schemas/FileHttpHandlerOptions', + }, + downstreamHostAndPorts: { + type: 'array', + items: { + $ref: '#/components/schemas/FileHostAndPort', + }, + nullable: true, + }, + upstreamHost: { + type: 'string', + nullable: true, + }, + key: { + type: 'string', + nullable: true, + }, + delegatingHandlers: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + priority: { + type: 'integer', + format: 'int32', + }, + timeout: { + type: 'integer', + format: 'int32', + }, + dangerousAcceptAnyServerCertificateValidator: { + type: 'boolean', + }, + securityOptions: { + $ref: '#/components/schemas/FileSecurityOptions', + }, + downstreamHttpVersion: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FileSecurityOptionsSchema = { + type: 'object', + properties: { + ipAllowedList: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + ipBlockedList: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FileServiceDiscoveryProviderSchema = { + type: 'object', + properties: { + scheme: { + type: 'string', + nullable: true, + }, + host: { + type: 'string', + nullable: true, + }, + port: { + type: 'integer', + format: 'int32', + }, + type: { + type: 'string', + nullable: true, + }, + token: { + type: 'string', + nullable: true, + }, + configurationKey: { + type: 'string', + nullable: true, + }, + pollingInterval: { + type: 'integer', + format: 'int32', + }, + namespace: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FindByUserNameInputSchema = { + type: 'object', + properties: { + userName: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FindTenantByNameInputSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const FindTenantResultDtoSchema = { + type: 'object', + properties: { + success: { + type: 'boolean', + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + normalizedName: { + type: 'string', + nullable: true, + }, + isActive: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const GetDataTypeInputSchema = { + type: 'object', + properties: { + entityModelId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const GetDataTypeOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + type: 'string', + description: '枚举编码', + nullable: true, + }, + description: { + type: 'string', + description: '枚举描述', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetEntityModelInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const GetEntityModelOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + type: 'string', + description: '编码', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + relationalType: { + $ref: '#/components/schemas/RelationalType', + }, + entityModelProperties: { + type: 'array', + items: { + $ref: '#/components/schemas/GetEntityModelPropertyOutput', + }, + description: '实体模型属性集合', + nullable: true, + }, + entityModelOutputs: { + type: 'array', + items: { + $ref: '#/components/schemas/GetEntityModelOutput', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetEntityModelPropertyOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + type: 'string', + description: '名称', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + isRequired: { + type: 'boolean', + description: '必填', + }, + maxLength: { + type: 'integer', + description: '字符串最大长度', + format: 'int32', + nullable: true, + }, + minLength: { + type: 'integer', + description: '字符串最小长度', + format: 'int32', + nullable: true, + }, + decimalPrecision: { + type: 'integer', + description: '当类型为decimal时的小数位数 (18,4) 中的18', + format: 'int32', + nullable: true, + }, + decimalScale: { + type: 'integer', + description: '当类型为decimal时的字段长度 (18,4) 中的4', + format: 'int32', + nullable: true, + }, + enumTypeId: { + type: 'string', + description: '枚举类型Id', + format: 'uuid', + nullable: true, + }, + isEnum: { + type: 'boolean', + }, + enumTypeOutput: { + $ref: '#/components/schemas/GetEnumTypeOutput', + }, + dataTypeId: { + type: 'string', + description: '数据类型Id', + format: 'uuid', + nullable: true, + }, + dataTypeOutput: { + $ref: '#/components/schemas/GetDataTypeOutput', + }, + entityModelId: { + type: 'string', + description: '实体模型Id', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const GetEntityModelTreeInputSchema = { + type: 'object', + properties: { + projectId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const GetEntityModelTreeOutputSchema = { + type: 'object', + properties: { + key: { + type: 'string', + description: '模板id', + format: 'uuid', + }, + icon: { + type: 'string', + description: '图标', + nullable: true, + }, + code: { + type: 'string', + description: '描述', + nullable: true, + }, + title: { + type: 'string', + description: '描述', + nullable: true, + }, + parentId: { + type: 'string', + description: '父类Id', + format: 'uuid', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + relationalType: { + $ref: '#/components/schemas/RelationalType', + }, + children: { + type: 'array', + items: { + $ref: '#/components/schemas/GetEntityModelTreeOutput', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetEnumTypeOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + type: 'string', + description: '枚举编码', + nullable: true, + }, + description: { + type: 'string', + description: '枚举描述', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetFeatureListResultDtoSchema = { + type: 'object', + properties: { + groups: { + type: 'array', + items: { + $ref: '#/components/schemas/FeatureGroupDto', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetFeatureListResultInputSchema = { + type: 'object', + properties: { + providerName: { + type: 'string', + nullable: true, + }, + providerKey: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetMenuTreeMetaOutputSchema = { + type: 'object', + properties: { + title: { + type: 'string', + nullable: true, + }, + displayTitle: { + type: 'string', + nullable: true, + }, + icon: { + type: 'string', + description: '图标', + nullable: true, + }, + order: { + type: 'integer', + description: '排序', + format: 'int32', + }, + keepAlive: { + type: 'boolean', + description: '是否缓存', + }, + hideInMenu: { + type: 'boolean', + description: '是否显示', + }, + link: { + type: 'string', + description: '外链地址', + nullable: true, + }, + iframeSrc: { + type: 'string', + description: '内链地址', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetMenuTreeOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + parentId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + name: { + type: 'string', + description: '名称', + nullable: true, + }, + path: { + type: 'string', + nullable: true, + }, + component: { + type: 'string', + nullable: true, + }, + enabled: { + type: 'boolean', + }, + meta: { + $ref: '#/components/schemas/GetMenuTreeMetaOutput', + }, + children: { + type: 'array', + items: { + $ref: '#/components/schemas/GetMenuTreeOutput', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetOrganizationUnitRoleInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + organizationUnitId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const GetOrganizationUnitRoleOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + name: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetOrganizationUnitRoleOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/GetOrganizationUnitRoleOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const GetOrganizationUnitUserInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + organizationUnitId: { + type: 'string', + format: 'uuid', + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetOrganizationUnitUserOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + userName: { + type: 'string', + nullable: true, + }, + email: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetOrganizationUnitUserOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/GetOrganizationUnitUserOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const GetPermissionInputSchema = { + type: 'object', + properties: { + providerName: { + type: 'string', + nullable: true, + }, + providerKey: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetProjectAndEntityInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const GetProjectAndEntityOutputSchema = { + type: 'object', + properties: { + project: { + $ref: '#/components/schemas/ProjectOutput', + }, + entities: { + type: 'array', + items: { + $ref: '#/components/schemas/EntityOutput', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetQRCodeOutputSchema = { + type: 'object', + properties: { + qrCode: { + type: 'string', + description: 'base64 二维码', + format: 'byte', + nullable: true, + }, + secret: { + type: 'string', + description: '密钥', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetTemplateTreeOutputSchema = { + type: 'object', + properties: { + key: { + type: 'string', + description: '模板id', + format: 'uuid', + }, + templateType: { + $ref: '#/components/schemas/TemplateType', + }, + controlType: { + $ref: '#/components/schemas/ControlType', + }, + icon: { + type: 'string', + description: '图标', + nullable: true, + }, + name: { + type: 'string', + description: '模板名称', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + title: { + type: 'string', + description: '描述', + nullable: true, + }, + content: { + type: 'string', + description: '模板内容', + nullable: true, + }, + children: { + type: 'array', + items: { + $ref: '#/components/schemas/GetTemplateTreeOutput', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetTemplteTreeInputSchema = { + type: 'object', + properties: { + templateId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const GetUnAddRoleInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + organizationUnitId: { + type: 'string', + format: 'uuid', + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetUnAddRoleOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + name: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetUnAddRoleOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/GetUnAddRoleOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const GetUnAddUserInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + organizationUnitId: { + type: 'string', + format: 'uuid', + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetUnAddUserOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + userName: { + type: 'string', + nullable: true, + }, + email: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const GetUnAddUserOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/GetUnAddUserOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const HttpStatusCodeSchema = { + enum: [ + 100, 101, 102, 103, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 400, 401, 402, 403, 404, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 421, 422, 423, 424, + 426, 428, 429, 431, 451, 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, + 511, + ], + type: 'integer', + format: 'int32', + 'x-enumNames': [ + 'Continue', + 'SwitchingProtocols', + 'Processing', + 'EarlyHints', + 'OK', + 'Created', + 'Accepted', + 'NonAuthoritativeInformation', + 'NoContent', + 'ResetContent', + 'PartialContent', + 'MultiStatus', + 'AlreadyReported', + 'IMUsed', + 'MultipleChoices', + 'Ambiguous', + 'MovedPermanently', + 'Moved', + 'Found', + 'Redirect', + 'SeeOther', + 'RedirectMethod', + 'NotModified', + 'UseProxy', + 'Unused', + 'TemporaryRedirect', + 'RedirectKeepVerb', + 'PermanentRedirect', + 'BadRequest', + 'Unauthorized', + 'PaymentRequired', + 'Forbidden', + 'NotFound', + 'MethodNotAllowed', + 'NotAcceptable', + 'ProxyAuthenticationRequired', + 'RequestTimeout', + 'Conflict', + 'Gone', + 'LengthRequired', + 'PreconditionFailed', + 'RequestEntityTooLarge', + 'RequestUriTooLong', + 'UnsupportedMediaType', + 'RequestedRangeNotSatisfiable', + 'ExpectationFailed', + 'MisdirectedRequest', + 'UnprocessableEntity', + 'UnprocessableContent', + 'Locked', + 'FailedDependency', + 'UpgradeRequired', + 'PreconditionRequired', + 'TooManyRequests', + 'RequestHeaderFieldsTooLarge', + 'UnavailableForLegalReasons', + 'InternalServerError', + 'NotImplemented', + 'BadGateway', + 'ServiceUnavailable', + 'GatewayTimeout', + 'HttpVersionNotSupported', + 'VariantAlsoNegotiates', + 'InsufficientStorage', + 'LoopDetected', + 'NotExtended', + 'NetworkAuthenticationRequired', + ], + 'x-enum-varnames': [ + 'Continue', + 'SwitchingProtocols', + 'Processing', + 'EarlyHints', + 'OK', + 'Created', + 'Accepted', + 'NonAuthoritativeInformation', + 'NoContent', + 'ResetContent', + 'PartialContent', + 'MultiStatus', + 'AlreadyReported', + 'IMUsed', + 'MultipleChoices', + 'Ambiguous', + 'MovedPermanently', + 'Moved', + 'Found', + 'Redirect', + 'SeeOther', + 'RedirectMethod', + 'NotModified', + 'UseProxy', + 'Unused', + 'TemporaryRedirect', + 'RedirectKeepVerb', + 'PermanentRedirect', + 'BadRequest', + 'Unauthorized', + 'PaymentRequired', + 'Forbidden', + 'NotFound', + 'MethodNotAllowed', + 'NotAcceptable', + 'ProxyAuthenticationRequired', + 'RequestTimeout', + 'Conflict', + 'Gone', + 'LengthRequired', + 'PreconditionFailed', + 'RequestEntityTooLarge', + 'RequestUriTooLong', + 'UnsupportedMediaType', + 'RequestedRangeNotSatisfiable', + 'ExpectationFailed', + 'MisdirectedRequest', + 'UnprocessableEntity', + 'UnprocessableContent', + 'Locked', + 'FailedDependency', + 'UpgradeRequired', + 'PreconditionRequired', + 'TooManyRequests', + 'RequestHeaderFieldsTooLarge', + 'UnavailableForLegalReasons', + 'InternalServerError', + 'NotImplemented', + 'BadGateway', + 'ServiceUnavailable', + 'GatewayTimeout', + 'HttpVersionNotSupported', + 'VariantAlsoNegotiates', + 'InsufficientStorage', + 'LoopDetected', + 'NotExtended', + 'NetworkAuthenticationRequired', + ], +} as const; + +export const IStringValueTypeSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + readOnly: true, + }, + properties: { + type: 'object', + additionalProperties: { + nullable: true, + }, + nullable: true, + readOnly: true, + }, + validator: { + $ref: '#/components/schemas/IValueValidator', + }, + }, + additionalProperties: false, +} as const; + +export const IValueValidatorSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + readOnly: true, + }, + properties: { + type: 'object', + additionalProperties: { + nullable: true, + }, + nullable: true, + readOnly: true, + }, + }, + additionalProperties: false, +} as const; + +export const IanaTimeZoneSchema = { + type: 'object', + properties: { + timeZoneName: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const IdInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const IdentityRoleCreateDtoSchema = { + required: ['name'], + type: 'object', + properties: { + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + readOnly: true, + }, + name: { + maxLength: 256, + minLength: 0, + type: 'string', + }, + isDefault: { + type: 'boolean', + }, + isPublic: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const IdentityRoleDtoSchema = { + type: 'object', + properties: { + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + readOnly: true, + }, + id: { + type: 'string', + format: 'uuid', + }, + name: { + type: 'string', + nullable: true, + }, + isDefault: { + type: 'boolean', + }, + isStatic: { + type: 'boolean', + }, + isPublic: { + type: 'boolean', + }, + concurrencyStamp: { + type: 'string', + nullable: true, + }, + creationTime: { + type: 'string', + format: 'date-time', + }, + }, + additionalProperties: false, +} as const; + +export const IdentityRoleDtoListResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/IdentityRoleDto', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const IdentityRoleDtoPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/IdentityRoleDto', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const IdentityRoleUpdateDtoSchema = { + required: ['name'], + type: 'object', + properties: { + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + readOnly: true, + }, + name: { + maxLength: 256, + minLength: 0, + type: 'string', + }, + isDefault: { + type: 'boolean', + }, + isPublic: { + type: 'boolean', + }, + concurrencyStamp: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const IdentityUserCreateDtoSchema = { + required: ['email', 'password', 'userName'], + type: 'object', + properties: { + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + readOnly: true, + }, + userName: { + maxLength: 256, + minLength: 0, + type: 'string', + }, + name: { + maxLength: 64, + minLength: 0, + type: 'string', + nullable: true, + }, + surname: { + maxLength: 64, + minLength: 0, + type: 'string', + nullable: true, + }, + email: { + maxLength: 256, + minLength: 0, + type: 'string', + format: 'email', + }, + phoneNumber: { + maxLength: 16, + minLength: 0, + type: 'string', + nullable: true, + }, + isActive: { + type: 'boolean', + }, + lockoutEnabled: { + type: 'boolean', + }, + roleNames: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + password: { + maxLength: 128, + minLength: 0, + type: 'string', + }, + }, + additionalProperties: false, +} as const; + +export const IdentityUserDtoSchema = { + type: 'object', + properties: { + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + readOnly: true, + }, + id: { + type: 'string', + format: 'uuid', + }, + creationTime: { + type: 'string', + format: 'date-time', + }, + creatorId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + lastModificationTime: { + type: 'string', + format: 'date-time', + nullable: true, + }, + lastModifierId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + isDeleted: { + type: 'boolean', + }, + deleterId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + deletionTime: { + type: 'string', + format: 'date-time', + nullable: true, + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + userName: { + type: 'string', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + surname: { + type: 'string', + nullable: true, + }, + email: { + type: 'string', + nullable: true, + }, + emailConfirmed: { + type: 'boolean', + }, + phoneNumber: { + type: 'string', + nullable: true, + }, + phoneNumberConfirmed: { + type: 'boolean', + }, + isActive: { + type: 'boolean', + }, + lockoutEnabled: { + type: 'boolean', + }, + accessFailedCount: { + type: 'integer', + format: 'int32', + }, + lockoutEnd: { + type: 'string', + format: 'date-time', + nullable: true, + }, + concurrencyStamp: { + type: 'string', + nullable: true, + }, + entityVersion: { + type: 'integer', + format: 'int32', + }, + lastPasswordChangeTime: { + type: 'string', + format: 'date-time', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const IdentityUserUpdateDtoSchema = { + required: ['email', 'userName'], + type: 'object', + properties: { + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + readOnly: true, + }, + userName: { + maxLength: 256, + minLength: 0, + type: 'string', + }, + name: { + maxLength: 64, + minLength: 0, + type: 'string', + nullable: true, + }, + surname: { + maxLength: 64, + minLength: 0, + type: 'string', + nullable: true, + }, + email: { + maxLength: 256, + minLength: 0, + type: 'string', + format: 'email', + }, + phoneNumber: { + maxLength: 16, + minLength: 0, + type: 'string', + nullable: true, + }, + isActive: { + type: 'boolean', + }, + lockoutEnabled: { + type: 'boolean', + }, + roleNames: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + password: { + maxLength: 128, + minLength: 0, + type: 'string', + nullable: true, + }, + concurrencyStamp: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const InterfaceMethodApiDescriptionModelSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + parametersOnMethod: { + type: 'array', + items: { + $ref: '#/components/schemas/MethodParameterApiDescriptionModel', + }, + nullable: true, + }, + returnValue: { + $ref: '#/components/schemas/ReturnValueApiDescriptionModel', + }, + }, + additionalProperties: false, +} as const; + +export const LanguageInfoSchema = { + type: 'object', + properties: { + cultureName: { + type: 'string', + nullable: true, + }, + uiCultureName: { + type: 'string', + nullable: true, + }, + displayName: { + type: 'string', + nullable: true, + }, + twoLetterISOLanguageName: { + type: 'string', + nullable: true, + readOnly: true, + }, + }, + additionalProperties: false, +} as const; + +export const LocalizableStringDtoSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + resource: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const LockUserInputSchema = { + type: 'object', + properties: { + userId: { + type: 'string', + format: 'uuid', + }, + locked: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const Login2FAInputSchema = { + type: 'object', + properties: { + name: { + type: 'string', + description: '用户名或者邮箱', + nullable: true, + }, + password: { + type: 'string', + description: '密码', + nullable: true, + }, + code: { + type: 'string', + description: '双因素验证码', + nullable: true, + }, + }, + additionalProperties: false, + description: '登录', +} as const; + +export const LoginInputSchema = { + type: 'object', + properties: { + name: { + type: 'string', + description: '用户名或者邮箱', + nullable: true, + }, + password: { + type: 'string', + description: '密码', + nullable: true, + }, + }, + additionalProperties: false, + description: '登录', +} as const; + +export const LoginOidcInputSchema = { + required: ['code', 'state'], + type: 'object', + properties: { + code: { + minLength: 1, + type: 'string', + description: 'code', + }, + state: { + minLength: 1, + type: 'string', + description: 'Provider', + }, + }, + additionalProperties: false, + description: '登录', +} as const; + +export const LoginOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + name: { + type: 'string', + nullable: true, + }, + userName: { + type: 'string', + nullable: true, + }, + token: { + type: 'string', + nullable: true, + }, + refreshToken: { + type: 'string', + nullable: true, + }, + roles: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const LoginResultTypeSchema = { + enum: [1, 2, 3, 4, 5], + type: 'integer', + format: 'int32', + 'x-enumNames': [ + 'Success', + 'InvalidUserNameOrPassword', + 'NotAllowed', + 'LockedOut', + 'RequiresTwoFactor', + ], + 'x-enum-varnames': [ + 'Success', + 'InvalidUserNameOrPassword', + 'NotAllowed', + 'LockedOut', + 'RequiresTwoFactor', + ], +} as const; + +export const MenuTypeSchema = { + enum: [10, 20], + type: 'integer', + description: '菜单类型', + format: 'int32', + 'x-enumNames': ['Folder', 'Menu'], + 'x-enum-varnames': ['Folder', 'Menu'], +} as const; + +export const MessageLevelSchema = { + enum: [10, 20, 30], + type: 'integer', + description: '消息等级', + format: 'int32', + 'x-enumNames': ['Warning', 'Information', 'Error'], + 'x-enum-varnames': ['Warning', 'Information', 'Error'], +} as const; + +export const MessageTypeSchema = { + enum: [10, 20], + type: 'integer', + description: '消息类型', + format: 'int32', + 'x-enumNames': ['BroadCast', 'Common'], + 'x-enum-varnames': ['BroadCast', 'Common'], +} as const; + +export const MethodParameterApiDescriptionModelSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + typeAsString: { + type: 'string', + nullable: true, + }, + type: { + type: 'string', + nullable: true, + }, + typeSimple: { + type: 'string', + nullable: true, + }, + isOptional: { + type: 'boolean', + }, + defaultValue: { + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ModuleApiDescriptionModelSchema = { + type: 'object', + properties: { + rootPath: { + type: 'string', + nullable: true, + }, + remoteServiceName: { + type: 'string', + nullable: true, + }, + controllers: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/ControllerApiDescriptionModel', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ModuleExtensionDtoSchema = { + type: 'object', + properties: { + entities: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/EntityExtensionDto', + }, + nullable: true, + }, + configuration: { + type: 'object', + additionalProperties: {}, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const MultiTenancyInfoDtoSchema = { + type: 'object', + properties: { + isEnabled: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const MyProfileOutputSchema = { + type: 'object', + properties: { + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + userName: { + type: 'string', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + surname: { + type: 'string', + nullable: true, + }, + email: { + type: 'string', + nullable: true, + }, + phoneNumber: { + type: 'string', + nullable: true, + }, + isActive: { + type: 'boolean', + }, + twoFactorEnabled: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const NameValueSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + value: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const NeedChangePasswordOutputSchema = { + type: 'object', + properties: { + needChangePassword: { + type: 'boolean', + }, + message: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ObjectExtensionsDtoSchema = { + type: 'object', + properties: { + modules: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/ModuleExtensionDto', + }, + nullable: true, + }, + enums: { + type: 'object', + additionalProperties: { + $ref: '#/components/schemas/ExtensionEnumDto', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const OidcConfigurationSchema = { + type: 'object', + properties: { + enabled: { + type: 'boolean', + description: '是否启用', + }, + type: { + type: 'string', + description: '类型', + nullable: true, + }, + clientId: { + type: 'string', + description: 'client_id', + nullable: true, + }, + clientName: { + type: 'string', + description: '应用名称', + nullable: true, + }, + icon: { + type: 'string', + description: '应用图标', + nullable: true, + }, + authUri: { + type: 'string', + description: '认证地址', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const OpenTypeSchema = { + enum: [10, 20, 30, 40], + type: 'integer', + description: '打开类型', + format: 'int32', + 'x-enumNames': ['Default', 'Component', 'InternalLink', 'ExternalLink'], + 'x-enum-varnames': ['Default', 'Component', 'InternalLink', 'ExternalLink'], +} as const; + +export const PageEntityModelInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + id: { + type: 'string', + format: 'uuid', + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PageEntityModelPropertyOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + nullable: true, + }, + entityModelId: { + type: 'string', + description: '实体模型Id', + format: 'uuid', + }, + code: { + type: 'string', + description: '名称', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + isRequired: { + type: 'boolean', + description: '必填', + }, + maxLength: { + type: 'integer', + description: '字符串最大长度', + format: 'int32', + nullable: true, + }, + minLength: { + type: 'integer', + description: '字符串最小长度', + format: 'int32', + nullable: true, + }, + decimalPrecision: { + type: 'integer', + description: '当类型为decimal时的小数位数 (18,4) 中的18', + format: 'int32', + nullable: true, + }, + decimalScale: { + type: 'integer', + description: '当类型为decimal时的字段长度 (18,4) 中的4', + format: 'int32', + nullable: true, + }, + dataTypeId: { + type: 'string', + format: 'uuid', + }, + isEnum: { + type: 'boolean', + }, + dataTypeCode: { + type: 'string', + nullable: true, + }, + dataTypeDescription: { + type: 'string', + nullable: true, + }, + allowSearch: { + type: 'boolean', + description: '允许作为查询条件', + }, + allowAdd: { + type: 'boolean', + description: '允许添加', + }, + allowEdit: { + type: 'boolean', + description: '允许编辑', + }, + }, + additionalProperties: false, +} as const; + +export const PageEntityModelPropertyOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageEntityModelPropertyOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PageEnumTypeInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + id: { + type: 'string', + format: 'uuid', + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PageEnumTypeOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + nullable: true, + }, + entityModelId: { + type: 'string', + description: '实体模型Id', + format: 'uuid', + }, + code: { + type: 'string', + description: '名称', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + creationTime: { + type: 'string', + format: 'date-time', + }, + }, + additionalProperties: false, +} as const; + +export const PageEnumTypeOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageEnumTypeOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PageEnumTypePropertyInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + id: { + type: 'string', + format: 'uuid', + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PageEnumTypePropertyOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + nullable: true, + }, + code: { + type: 'string', + description: '名称', + nullable: true, + }, + value: { + type: 'integer', + description: '名称', + format: 'int32', + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + creationTime: { + type: 'string', + format: 'date-time', + }, + }, + additionalProperties: false, +} as const; + +export const PageEnumTypePropertyOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageEnumTypePropertyOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PageFileObjectInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + startCreationTime: { + type: 'string', + description: '开始创建时间', + format: 'date-time', + nullable: true, + }, + endCreationTime: { + type: 'string', + description: '结束创建时间', + format: 'date-time', + nullable: true, + }, + fileName: { + type: 'string', + description: '文件名称', + nullable: true, + }, + }, + additionalProperties: false, + description: '分页查询文件', +} as const; + +export const PageFileObjectOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '文件Id', + format: 'uuid', + }, + fileSize: { + type: 'integer', + description: '文件大小', + format: 'int64', + }, + beautifySize: { + type: 'string', + nullable: true, + readOnly: true, + }, + contentType: { + type: 'string', + description: '文件名称', + nullable: true, + }, + fileName: { + type: 'string', + description: '文件名称', + nullable: true, + }, + creationTime: { + type: 'string', + description: '创建时间', + format: 'date-time', + }, + }, + additionalProperties: false, + description: '分页查询文件', +} as const; + +export const PageFileObjectOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageFileObjectOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PageIdentityUserOutputSchema = { + type: 'object', + properties: { + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + readOnly: true, + }, + id: { + type: 'string', + format: 'uuid', + }, + creationTime: { + type: 'string', + format: 'date-time', + }, + creatorId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + lastModificationTime: { + type: 'string', + format: 'date-time', + nullable: true, + }, + lastModifierId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + isDeleted: { + type: 'boolean', + }, + deleterId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + deletionTime: { + type: 'string', + format: 'date-time', + nullable: true, + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + userName: { + type: 'string', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + surname: { + type: 'string', + nullable: true, + }, + email: { + type: 'string', + nullable: true, + }, + emailConfirmed: { + type: 'boolean', + }, + phoneNumber: { + type: 'string', + nullable: true, + }, + phoneNumberConfirmed: { + type: 'boolean', + }, + isActive: { + type: 'boolean', + }, + lockoutEnabled: { + type: 'boolean', + }, + accessFailedCount: { + type: 'integer', + format: 'int32', + }, + lockoutEnd: { + type: 'string', + format: 'date-time', + nullable: true, + }, + concurrencyStamp: { + type: 'string', + nullable: true, + }, + entityVersion: { + type: 'integer', + format: 'int32', + }, + lastPasswordChangeTime: { + type: 'string', + format: 'date-time', + nullable: true, + }, + twoFactorEnabled: { + type: 'boolean', + description: '是否开启双因素验证码', + }, + }, + additionalProperties: false, +} as const; + +export const PageIdentityUserOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageIdentityUserOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PageLanguageInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, + description: '创建语言', +} as const; + +export const PageLanguageOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '语言Id', + format: 'uuid', + }, + cultureName: { + type: 'string', + description: '语言名称', + nullable: true, + }, + uiCultureName: { + type: 'string', + description: 'Ui语言名称', + nullable: true, + }, + displayName: { + type: 'string', + description: '显示名称', + nullable: true, + }, + flagIcon: { + type: 'string', + description: '图标', + nullable: true, + }, + isEnabled: { + type: 'boolean', + description: '是否启用', + }, + creationTime: { + type: 'string', + description: '创建时间', + format: 'date-time', + }, + isDefault: { + type: 'boolean', + description: '是否是默认语言', + }, + }, + additionalProperties: false, + description: '创建语言', +} as const; + +export const PageLanguageOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageLanguageOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PageLanguageTextInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + cultureName: { + type: 'string', + description: '语言', + nullable: true, + }, + resourceName: { + type: 'string', + description: '资源', + nullable: true, + }, + filter: { + type: 'string', + description: '查询条件 name or value', + nullable: true, + }, + }, + additionalProperties: false, + description: '创建语言文本', +} as const; + +export const PageLanguageTextOutputSchema = { + type: 'object', + properties: { + resourceName: { + type: 'string', + description: '资源名称', + nullable: true, + }, + name: { + type: 'string', + description: '名称', + nullable: true, + }, + value: { + type: 'string', + description: '值', + nullable: true, + }, + }, + additionalProperties: false, + description: '创建语言文本', +} as const; + +export const PageLanguageTextOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageLanguageTextOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PageMenuInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + startCreationTime: { + type: 'string', + description: '开始创建时间', + format: 'date-time', + nullable: true, + }, + endCreationTime: { + type: 'string', + description: '结束创建时间', + format: 'date-time', + nullable: true, + }, + }, + additionalProperties: false, + description: '分页查询菜单', +} as const; + +export const PageMenuOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '菜单Id', + format: 'uuid', + }, + parentId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + name: { + type: 'string', + description: '唯一编码', + nullable: true, + }, + localizationTitle: { + type: 'string', + description: '标题', + nullable: true, + }, + displayTitle: { + type: 'string', + description: '标题', + nullable: true, + }, + title: { + type: 'string', + description: '标题', + nullable: true, + }, + icon: { + type: 'string', + description: '图标', + nullable: true, + }, + keepAlive: { + type: 'boolean', + description: '是否缓存', + }, + hideInMenu: { + type: 'boolean', + description: '是否显示', + }, + order: { + type: 'integer', + description: '排序', + format: 'int32', + }, + path: { + type: 'string', + description: '路由/接口地址', + nullable: true, + }, + menuType: { + $ref: '#/components/schemas/MenuType', + }, + menuTypeDescription: { + type: 'string', + nullable: true, + readOnly: true, + }, + openType: { + $ref: '#/components/schemas/OpenType', + }, + openTypeDescription: { + type: 'string', + nullable: true, + readOnly: true, + }, + url: { + type: 'string', + description: '内外链地址', + nullable: true, + }, + component: { + type: 'string', + description: '组件地址', + nullable: true, + }, + creationTime: { + type: 'string', + description: '创建时间', + format: 'date-time', + }, + enabled: { + type: 'boolean', + description: '是否启用', + }, + policy: { + type: 'string', + description: '权限', + nullable: true, + }, + }, + additionalProperties: false, + description: '分页查询菜单', +} as const; + +export const PageMenuOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageMenuOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PageProjectInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PageTemplateInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PageTenantConnectionStringInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '租户id', + format: 'uuid', + }, + name: { + type: 'string', + description: '连接字符串名称', + nullable: true, + }, + value: { + type: 'string', + description: '连接字符串地址', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PageTenantConnectionStringOutputSchema = { + type: 'object', + properties: { + tenantId: { + type: 'string', + description: '租户id', + format: 'uuid', + }, + name: { + type: 'string', + description: '连接字符串名称', + nullable: true, + }, + value: { + type: 'string', + description: '连接字符串地址', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PageTenantConnectionStringOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageTenantConnectionStringOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PageTextTemplateInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + name: { + type: 'string', + description: '名称', + nullable: true, + }, + code: { + type: 'string', + description: '编码', + nullable: true, + }, + content: { + type: 'string', + description: '内容', + nullable: true, + }, + startCreationTime: { + type: 'string', + description: '开始创建时间', + format: 'date-time', + nullable: true, + }, + endCreationTime: { + type: 'string', + description: '结束创建时间', + format: 'date-time', + nullable: true, + }, + }, + additionalProperties: false, + description: '分页查询模板', +} as const; + +export const PageTextTemplateOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '模板Id', + format: 'uuid', + }, + name: { + type: 'string', + description: '名称', + nullable: true, + }, + code: { + type: 'string', + description: '编码', + nullable: true, + }, + content: { + type: 'string', + description: '内容', + nullable: true, + }, + cultureName: { + type: 'string', + description: '语言', + nullable: true, + }, + creationTime: { + type: 'string', + description: '创建时间', + format: 'date-time', + }, + }, + additionalProperties: false, + description: '分页查询模板', +} as const; + +export const PageTextTemplateOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PageTextTemplateOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PagingAuditLogActionOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + auditLogId: { + type: 'string', + format: 'uuid', + }, + serviceName: { + type: 'string', + nullable: true, + }, + methodName: { + type: 'string', + nullable: true, + }, + parameters: { + type: 'string', + nullable: true, + }, + executionTime: { + type: 'string', + nullable: true, + }, + executionDuration: { + type: 'integer', + format: 'int32', + }, + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingAuditLogInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: '排序', + nullable: true, + }, + startTime: { + type: 'string', + description: '开始时间', + format: 'date-time', + nullable: true, + }, + endTime: { + type: 'string', + description: '结束时间', + format: 'date-time', + nullable: true, + }, + httpMethod: { + type: 'string', + description: '请求方法', + nullable: true, + }, + url: { + type: 'string', + description: '请求地址', + nullable: true, + }, + userId: { + type: 'string', + description: '用户Id', + format: 'uuid', + nullable: true, + }, + userName: { + type: 'string', + description: '用户名', + nullable: true, + }, + applicationName: { + type: 'string', + description: '应用程序名称', + nullable: true, + }, + correlationId: { + type: 'string', + description: 'RequestId', + nullable: true, + }, + maxExecutionDuration: { + type: 'integer', + description: '最大执行时间', + format: 'int32', + nullable: true, + }, + minExecutionDuration: { + type: 'integer', + description: '最小执行时间', + format: 'int32', + nullable: true, + }, + hasException: { + type: 'boolean', + description: '是否有异常', + nullable: true, + }, + httpStatusCode: { + $ref: '#/components/schemas/HttpStatusCode', + }, + clientIpAddress: { + type: 'string', + description: '客户端IP', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingAuditLogOutputSchema = { + type: 'object', + properties: { + applicationName: { + type: 'string', + nullable: true, + }, + userId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + userName: { + type: 'string', + nullable: true, + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + tenantName: { + type: 'string', + nullable: true, + }, + impersonatorUserId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + impersonatorTenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + executionTime: { + type: 'string', + nullable: true, + }, + executionDuration: { + type: 'integer', + format: 'int32', + }, + clientIpAddress: { + type: 'string', + nullable: true, + }, + clientName: { + type: 'string', + nullable: true, + }, + clientId: { + type: 'string', + nullable: true, + }, + correlationId: { + type: 'string', + nullable: true, + }, + browserInfo: { + type: 'string', + nullable: true, + }, + httpMethod: { + type: 'string', + nullable: true, + }, + url: { + type: 'string', + nullable: true, + }, + exceptions: { + type: 'string', + nullable: true, + }, + comments: { + type: 'string', + nullable: true, + }, + httpStatusCode: { + type: 'integer', + format: 'int32', + nullable: true, + }, + entityChanges: { + type: 'array', + items: { + $ref: '#/components/schemas/PagingEntityChangeOutput', + }, + nullable: true, + }, + actions: { + type: 'array', + items: { + $ref: '#/components/schemas/PagingAuditLogActionOutput', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingAuditLogOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PagingAuditLogOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PagingDataDictionaryDetailInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + dataDictionaryId: { + type: 'string', + format: 'uuid', + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingDataDictionaryDetailOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + dataDictionaryId: { + type: 'string', + description: '所属字典Id', + format: 'uuid', + }, + code: { + type: 'string', + description: '字典明细编码', + nullable: true, + }, + order: { + type: 'integer', + description: '展现列表时排序用', + format: 'int32', + }, + displayText: { + type: 'string', + description: '英文显示名', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + isEnabled: { + type: 'boolean', + description: '启/停用(默认启用)', + }, + }, + additionalProperties: false, +} as const; + +export const PagingDataDictionaryDetailOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PagingDataDictionaryDetailOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PagingDataDictionaryInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingDataDictionaryOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + type: 'string', + description: '字典编码', + nullable: true, + }, + displayText: { + type: 'string', + description: '显示名', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingDataDictionaryOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PagingDataDictionaryOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PagingEntityChangeOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + auditLogId: { + type: 'string', + format: 'uuid', + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + changeTime: { + type: 'string', + nullable: true, + }, + changeType: { + $ref: '#/components/schemas/EntityChangeType', + }, + changeTypeDescription: { + type: 'string', + nullable: true, + }, + entityTenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + entityId: { + type: 'string', + nullable: true, + }, + entityTypeFullName: { + type: 'string', + nullable: true, + }, + propertyChanges: { + type: 'array', + items: { + $ref: '#/components/schemas/PagingEntityPropertyChangeOutput', + }, + nullable: true, + }, + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingEntityPropertyChangeOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + entityChangeId: { + type: 'string', + format: 'uuid', + }, + newValue: { + type: 'string', + nullable: true, + }, + originalValue: { + type: 'string', + nullable: true, + }, + propertyName: { + type: 'string', + nullable: true, + }, + propertyTypeFullName: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingIdentitySecurityLogInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: '排序', + nullable: true, + }, + startTime: { + type: 'string', + description: '开始时间', + format: 'date-time', + nullable: true, + }, + endTime: { + type: 'string', + description: '结束时间', + format: 'date-time', + nullable: true, + }, + identity: { + type: 'string', + nullable: true, + }, + action: { + type: 'string', + description: '请求地址', + nullable: true, + }, + userId: { + type: 'string', + description: '用户Id', + format: 'uuid', + nullable: true, + }, + userName: { + type: 'string', + description: '用户名', + nullable: true, + }, + applicationName: { + type: 'string', + description: '应用程序名称', + nullable: true, + }, + correlationId: { + type: 'string', + description: 'RequestId', + nullable: true, + }, + clientId: { + type: 'string', + description: 'ClientId', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingIdentitySecurityLogOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + applicationName: { + type: 'string', + nullable: true, + }, + identity: { + type: 'string', + nullable: true, + }, + action: { + type: 'string', + nullable: true, + }, + userId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + userName: { + type: 'string', + nullable: true, + }, + tenantName: { + type: 'string', + nullable: true, + }, + clientId: { + type: 'string', + nullable: true, + }, + correlationId: { + type: 'string', + nullable: true, + }, + clientIpAddress: { + type: 'string', + nullable: true, + }, + browserInfo: { + type: 'string', + nullable: true, + }, + creationTime: { + type: 'string', + format: 'date-time', + }, + }, + additionalProperties: false, +} as const; + +export const PagingIdentitySecurityLogOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PagingIdentitySecurityLogOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PagingNotificationInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + title: { + type: 'string', + description: '标题', + nullable: true, + }, + content: { + type: 'string', + description: '内容', + nullable: true, + }, + senderUserId: { + type: 'string', + description: '发送者Id', + format: 'uuid', + nullable: true, + }, + senderUserName: { + type: 'string', + description: '发送者名称', + nullable: true, + }, + receiverUserId: { + type: 'string', + description: '接受者Id', + format: 'uuid', + nullable: true, + }, + receiverUserName: { + type: 'string', + description: '接受者名称', + nullable: true, + }, + read: { + type: 'boolean', + description: '是否已读', + nullable: true, + }, + startReadTime: { + type: 'string', + description: '已读开始时间', + format: 'date-time', + nullable: true, + }, + endReadTime: { + type: 'string', + description: '已读结束时间', + format: 'date-time', + nullable: true, + }, + messageType: { + $ref: '#/components/schemas/MessageType', + }, + messageLevel: { + $ref: '#/components/schemas/MessageLevel', + }, + }, + additionalProperties: false, +} as const; + +export const PagingNotificationOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + tenantId: { + type: 'string', + description: '租户id', + format: 'uuid', + nullable: true, + }, + title: { + type: 'string', + description: '消息标题', + nullable: true, + }, + content: { + type: 'string', + description: '消息内容', + nullable: true, + }, + messageType: { + $ref: '#/components/schemas/MessageType', + }, + messageTypeName: { + type: 'string', + nullable: true, + readOnly: true, + }, + messageLevel: { + $ref: '#/components/schemas/MessageLevel', + }, + messageLevelName: { + type: 'string', + nullable: true, + readOnly: true, + }, + senderUserId: { + type: 'string', + description: '发送人', + format: 'uuid', + }, + senderUserName: { + type: 'string', + description: '发送人用户名', + nullable: true, + }, + receiveUserId: { + type: 'string', + description: `订阅人 +消息类型是广播消息时,订阅人为空`, + format: 'uuid', + nullable: true, + }, + receiveUserName: { + type: 'string', + description: `接收人用户名 +消息类型是广播消息时,订接收人用户名为空`, + nullable: true, + }, + read: { + type: 'boolean', + description: '是否已读', + }, + readTime: { + type: 'string', + description: '已读时间', + format: 'date-time', + nullable: true, + }, + creationTime: { + type: 'string', + format: 'date-time', + }, + }, + additionalProperties: false, +} as const; + +export const PagingNotificationOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PagingNotificationOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PagingNotificationSubscriptionInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + notificationId: { + type: 'string', + format: 'uuid', + }, + receiverUserId: { + type: 'string', + description: '接受者Id', + format: 'uuid', + nullable: true, + }, + receiverUserName: { + type: 'string', + description: '接受者名称', + nullable: true, + }, + read: { + type: 'boolean', + description: '是否已读', + nullable: true, + }, + startReadTime: { + type: 'string', + description: '已读开始时间', + format: 'date-time', + nullable: true, + }, + endReadTime: { + type: 'string', + description: '已读结束时间', + format: 'date-time', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingNotificationSubscriptionOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + tenantId: { + type: 'string', + description: '租户id', + format: 'uuid', + nullable: true, + }, + notificationId: { + type: 'string', + description: '消息Id', + format: 'uuid', + }, + receiveUserId: { + type: 'string', + description: '接收人id', + format: 'uuid', + }, + receiveUserName: { + type: 'string', + description: '接收人用户名', + nullable: true, + }, + read: { + type: 'boolean', + description: '是否已读', + }, + readTime: { + type: 'string', + description: '已读时间', + format: 'date-time', + }, + title: { + type: 'string', + description: '消息标题', + nullable: true, + }, + content: { + type: 'string', + description: '消息内容', + nullable: true, + }, + messageType: { + $ref: '#/components/schemas/MessageType', + }, + messageTypeName: { + type: 'string', + nullable: true, + readOnly: true, + }, + messageLevel: { + $ref: '#/components/schemas/MessageLevel', + }, + messageLevelName: { + type: 'string', + nullable: true, + readOnly: true, + }, + senderUserId: { + type: 'string', + description: '发送人', + format: 'uuid', + }, + senderUserName: { + type: 'string', + description: '发送人用户名', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingNotificationSubscriptionOutputPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/PagingNotificationSubscriptionOutput', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const PagingRoleListInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingTenantInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + filter: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PagingUserListInputSchema = { + type: 'object', + properties: { + pageIndex: { + type: 'integer', + description: '当前页面.默认从1开始', + format: 'int32', + }, + pageSize: { + type: 'integer', + description: '每页多少条.每页显示多少记录', + format: 'int32', + }, + skipCount: { + type: 'integer', + description: '跳过多少条', + format: 'int32', + readOnly: true, + }, + sorting: { + type: 'string', + description: `排序 + + name desc +`, + nullable: true, + }, + filter: { + type: 'string', + description: '关键字', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ParameterApiDescriptionModelSchema = { + type: 'object', + properties: { + nameOnMethod: { + type: 'string', + nullable: true, + }, + name: { + type: 'string', + nullable: true, + }, + jsonName: { + type: 'string', + nullable: true, + }, + type: { + type: 'string', + nullable: true, + }, + typeSimple: { + type: 'string', + nullable: true, + }, + isOptional: { + type: 'boolean', + }, + defaultValue: { + nullable: true, + }, + constraintTypes: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + bindingSourceId: { + type: 'string', + nullable: true, + }, + descriptorName: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PermissionOutputSchema = { + type: 'object', + properties: { + grants: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + allGrants: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + permissions: { + type: 'array', + items: { + $ref: '#/components/schemas/PermissionTreeDto', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PermissionTreeDtoSchema = { + type: 'object', + properties: { + title: { + type: 'string', + nullable: true, + }, + key: { + type: 'string', + nullable: true, + }, + children: { + type: 'array', + items: { + $ref: '#/components/schemas/PermissionTreeDto', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PreViewCodeInputSchema = { + type: 'object', + properties: { + templateId: { + type: 'string', + format: 'uuid', + }, + projectId: { + type: 'string', + format: 'uuid', + }, + entityId: { + type: 'array', + items: { + type: 'string', + format: 'uuid', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const ProjectDtoSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + creationTime: { + type: 'string', + format: 'date-time', + }, + creatorId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + lastModificationTime: { + type: 'string', + format: 'date-time', + nullable: true, + }, + lastModifierId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + owner: { + type: 'string', + description: '负责人', + nullable: true, + }, + nameSpace: { + type: 'string', + description: '名称空间', + nullable: true, + }, + companyName: { + type: 'string', + description: '公司名称', + nullable: true, + }, + projectName: { + type: 'string', + description: '项目名称', + nullable: true, + }, + remark: { + type: 'string', + description: '备注', + nullable: true, + }, + supportTenant: { + type: 'boolean', + description: '是否支持多租户', + }, + }, + additionalProperties: false, +} as const; + +export const ProjectDtoPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/ProjectDto', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const ProjectOutputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + companyName: { + type: 'string', + description: '公司名称', + nullable: true, + }, + projectName: { + type: 'string', + description: '项目名称', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const PropertyApiDescriptionModelSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + jsonName: { + type: 'string', + nullable: true, + }, + type: { + type: 'string', + nullable: true, + }, + typeSimple: { + type: 'string', + nullable: true, + }, + isRequired: { + type: 'boolean', + }, + minLength: { + type: 'integer', + format: 'int32', + nullable: true, + }, + maxLength: { + type: 'integer', + format: 'int32', + nullable: true, + }, + minimum: { + type: 'string', + nullable: true, + }, + maximum: { + type: 'string', + nullable: true, + }, + regex: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const RefreshTokenInputSchema = { + required: ['refreshToken'], + type: 'object', + properties: { + userId: { + type: 'string', + format: 'uuid', + }, + refreshToken: { + minLength: 1, + type: 'string', + }, + }, + additionalProperties: false, +} as const; + +export const RefreshTokenOutputSchema = { + type: 'object', + properties: { + success: { + type: 'boolean', + }, + message: { + type: 'string', + nullable: true, + }, + token: { + type: 'string', + nullable: true, + }, + refreshToken: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const RelationalTypeSchema = { + enum: [10, 20], + type: 'integer', + format: 'int32', + 'x-enumNames': ['OnoToOne', 'OneToMany'], + 'x-enum-varnames': ['OnoToOne', 'OneToMany'], +} as const; + +export const RemoteServiceErrorInfoSchema = { + type: 'object', + properties: { + code: { + type: 'string', + nullable: true, + }, + message: { + type: 'string', + nullable: true, + }, + details: { + type: 'string', + nullable: true, + }, + data: { + type: 'object', + additionalProperties: {}, + nullable: true, + }, + validationErrors: { + type: 'array', + items: { + $ref: '#/components/schemas/RemoteServiceValidationErrorInfo', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const RemoteServiceErrorResponseSchema = { + type: 'object', + properties: { + error: { + $ref: '#/components/schemas/RemoteServiceErrorInfo', + }, + }, + additionalProperties: false, +} as const; + +export const RemoteServiceValidationErrorInfoSchema = { + type: 'object', + properties: { + message: { + type: 'string', + nullable: true, + }, + members: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const RemoteStreamContentSchema = { + type: 'object', + properties: { + fileName: { + type: 'string', + nullable: true, + }, + contentType: { + type: 'string', + nullable: true, + }, + contentLength: { + type: 'integer', + format: 'int64', + nullable: true, + readOnly: true, + }, + }, + additionalProperties: false, +} as const; + +export const RemoveRoleToOrganizationUnitInputSchema = { + type: 'object', + properties: { + roleId: { + type: 'string', + format: 'uuid', + }, + organizationUnitId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const RemoveUserToOrganizationUnitInputSchema = { + type: 'object', + properties: { + userId: { + type: 'string', + format: 'uuid', + }, + organizationUnitId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const ResetPasswordInputSchema = { + required: ['password'], + type: 'object', + properties: { + userId: { + type: 'string', + format: 'uuid', + }, + password: { + maxLength: 128, + minLength: 0, + type: 'string', + }, + }, + additionalProperties: false, +} as const; + +export const ResetTwoFactorInputSchema = { + type: 'object', + properties: { + userId: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const ReturnValueApiDescriptionModelSchema = { + type: 'object', + properties: { + type: { + type: 'string', + nullable: true, + }, + typeSimple: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const SendBroadCastMessageInputSchema = { + type: 'object', + properties: { + title: { + type: 'string', + description: '消息标题', + nullable: true, + }, + content: { + type: 'string', + description: '消息内容', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const SendCommonMessageInputSchema = { + type: 'object', + properties: { + title: { + type: 'string', + description: '消息标题', + nullable: true, + }, + content: { + type: 'string', + description: '消息内容', + nullable: true, + }, + receiveUserId: { + type: 'string', + description: '发送人', + format: 'uuid', + }, + receiveUserName: { + type: 'string', + description: '发送人名称', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const SetBatchReadInputSchema = { + type: 'object', + properties: { + ids: { + type: 'array', + items: { + type: 'string', + format: 'uuid', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const SetDataDictinaryDetailInputSchema = { + required: ['isEnabled'], + type: 'object', + properties: { + dataDictionaryId: { + type: 'string', + format: 'uuid', + }, + dataDictionayDetailId: { + type: 'string', + format: 'uuid', + }, + isEnabled: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const SetReadInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const SettingItemOutputSchema = { + type: 'object', + properties: { + name: { + type: 'string', + description: '名称', + nullable: true, + }, + displayName: { + type: 'string', + description: '显示名称', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + value: { + type: 'string', + description: '值', + nullable: true, + }, + type: { + type: 'string', + description: '前端控件类型', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const SettingOutputSchema = { + type: 'object', + properties: { + group: { + type: 'string', + description: '分组', + nullable: true, + }, + groupDisplayName: { + type: 'string', + description: '分组显示名称', + nullable: true, + }, + settingItemOutput: { + type: 'array', + items: { + $ref: '#/components/schemas/SettingItemOutput', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const StringInt32KeyValuePairSchema = { + type: 'object', + properties: { + key: { + type: 'string', + nullable: true, + }, + value: { + type: 'integer', + format: 'int32', + }, + }, + additionalProperties: false, +} as const; + +export const StringStringFromSelectorSchema = { + type: 'object', + properties: { + value: { + type: 'string', + nullable: true, + readOnly: true, + }, + label: { + type: 'string', + nullable: true, + readOnly: true, + }, + }, + additionalProperties: false, +} as const; + +export const TemplateDetailDtoSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + templateId: { + type: 'string', + description: '模板id', + format: 'uuid', + }, + templateType: { + $ref: '#/components/schemas/TemplateType', + }, + controlType: { + $ref: '#/components/schemas/ControlType', + }, + parentId: { + type: 'string', + description: '父级id', + format: 'uuid', + nullable: true, + }, + name: { + type: 'string', + description: '模板名称', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + content: { + type: 'string', + description: '模板内容', + nullable: true, + }, + }, + additionalProperties: false, + description: '模板明细', +} as const; + +export const TemplateDtoSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + creationTime: { + type: 'string', + format: 'date-time', + }, + creatorId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + lastModificationTime: { + type: 'string', + format: 'date-time', + nullable: true, + }, + lastModifierId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + tenantId: { + type: 'string', + format: 'uuid', + nullable: true, + }, + name: { + type: 'string', + description: '名称', + nullable: true, + }, + remark: { + type: 'string', + description: '备注', + nullable: true, + }, + templateDetails: { + type: 'array', + items: { + $ref: '#/components/schemas/TemplateDetailDto', + }, + description: '关联属性1:N 模板明细集合', + nullable: true, + }, + }, + additionalProperties: false, + description: '模板', +} as const; + +export const TemplateDtoPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/TemplateDto', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const TemplateTreeDtoSchema = { + type: 'object', + properties: { + key: { + type: 'string', + description: '模板id', + format: 'uuid', + }, + templateType: { + $ref: '#/components/schemas/TemplateType', + }, + controlType: { + $ref: '#/components/schemas/ControlType', + }, + icon: { + type: 'string', + description: '图标', + nullable: true, + }, + isFolder: { + type: 'boolean', + description: '是否是文件夹', + }, + name: { + type: 'string', + description: '模板名称', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + title: { + type: 'string', + description: '描述', + nullable: true, + }, + content: { + type: 'string', + description: '模板内容', + nullable: true, + }, + children: { + type: 'array', + items: { + $ref: '#/components/schemas/TemplateTreeDto', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const TemplateTypeSchema = { + enum: [10, 20], + type: 'integer', + format: 'int32', + 'x-enumNames': ['Folder', 'File'], + 'x-enum-varnames': ['Folder', 'File'], +} as const; + +export const TenantCreateDtoSchema = { + required: ['adminEmailAddress', 'adminPassword', 'name'], + type: 'object', + properties: { + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + readOnly: true, + }, + name: { + maxLength: 64, + minLength: 0, + type: 'string', + }, + adminEmailAddress: { + maxLength: 256, + minLength: 1, + type: 'string', + format: 'email', + }, + adminPassword: { + maxLength: 128, + minLength: 1, + type: 'string', + }, + }, + additionalProperties: false, +} as const; + +export const TenantDtoSchema = { + type: 'object', + properties: { + extraProperties: { + type: 'object', + additionalProperties: {}, + nullable: true, + readOnly: true, + }, + id: { + type: 'string', + format: 'uuid', + }, + name: { + type: 'string', + nullable: true, + }, + concurrencyStamp: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const TenantDtoPagedResultDtoSchema = { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/TenantDto', + }, + nullable: true, + }, + totalCount: { + type: 'integer', + format: 'int64', + }, + }, + additionalProperties: false, +} as const; + +export const TimeZoneSchema = { + type: 'object', + properties: { + iana: { + $ref: '#/components/schemas/IanaTimeZone', + }, + windows: { + $ref: '#/components/schemas/WindowsTimeZone', + }, + }, + additionalProperties: false, +} as const; + +export const TimingDtoSchema = { + type: 'object', + properties: { + timeZone: { + $ref: '#/components/schemas/TimeZone', + }, + }, + additionalProperties: false, +} as const; + +export const TreeOutputSchema = { + type: 'object', + properties: { + title: { + type: 'string', + nullable: true, + }, + key: { + type: 'string', + format: 'uuid', + }, + children: { + type: 'array', + items: { + $ref: '#/components/schemas/TreeOutput', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const TypeApiDescriptionModelSchema = { + type: 'object', + properties: { + baseType: { + type: 'string', + nullable: true, + }, + isEnum: { + type: 'boolean', + }, + enumNames: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + enumValues: { + type: 'array', + items: {}, + nullable: true, + }, + genericArguments: { + type: 'array', + items: { + type: 'string', + }, + nullable: true, + }, + properties: { + type: 'array', + items: { + $ref: '#/components/schemas/PropertyApiDescriptionModel', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateAggregateInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateDataDictinaryInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + type: 'string', + nullable: true, + }, + displayText: { + type: 'string', + nullable: true, + }, + description: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateDetailInputSchema = { + type: 'object', + properties: { + dataDictionaryId: { + type: 'string', + format: 'uuid', + }, + id: { + type: 'string', + format: 'uuid', + }, + displayText: { + type: 'string', + nullable: true, + }, + description: { + type: 'string', + nullable: true, + }, + order: { + type: 'integer', + format: 'int32', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateEntityModelInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + relationalType: { + $ref: '#/components/schemas/RelationalType', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateEntityModelPropertyInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + propertyId: { + type: 'string', + format: 'uuid', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + isRequired: { + type: 'boolean', + description: '必填', + }, + maxLength: { + type: 'integer', + description: '字符串最大长度', + format: 'int32', + nullable: true, + }, + minLength: { + type: 'integer', + description: '字符串最小长度', + format: 'int32', + nullable: true, + }, + decimalPrecision: { + type: 'integer', + description: '当类型为decimal时的小数位数 (18,4) 中的18', + format: 'int32', + nullable: true, + }, + decimalScale: { + type: 'integer', + description: '当类型为decimal时的字段长度 (18,4) 中的4', + format: 'int32', + nullable: true, + }, + enumTypeId: { + type: 'string', + description: '枚举类型Id', + format: 'uuid', + nullable: true, + }, + dataTypeId: { + type: 'string', + description: '数据类型Id', + format: 'uuid', + nullable: true, + }, + entityModelId: { + type: 'string', + description: '实体模型Id', + format: 'uuid', + }, + allowSearch: { + type: 'boolean', + description: '允许作为查询条件', + }, + allowAdd: { + type: 'boolean', + description: '允许添加', + }, + allowEdit: { + type: 'boolean', + description: '允许编辑', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateEnumTypeInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateEnumTypePropertyInputSchema = { + required: ['code', 'description'], + type: 'object', + properties: { + enumTypeId: { + type: 'string', + description: 'Id', + format: 'uuid', + }, + id: { + type: 'string', + description: 'Id', + format: 'uuid', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + value: { + type: 'integer', + description: '枚举值', + format: 'int32', + }, + description: { + minLength: 1, + type: 'string', + description: '描述', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateFeatureDtoSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + value: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateFeatureInputSchema = { + type: 'object', + properties: { + providerName: { + type: 'string', + nullable: true, + }, + providerKey: { + type: 'string', + nullable: true, + }, + updateFeaturesDto: { + $ref: '#/components/schemas/UpdateFeaturesDto', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateFeaturesDtoSchema = { + type: 'object', + properties: { + features: { + type: 'array', + items: { + $ref: '#/components/schemas/UpdateFeatureDto', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateLanguageInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + description: '语言Id', + format: 'uuid', + }, + cultureName: { + type: 'string', + description: '语言名称', + nullable: true, + }, + uiCultureName: { + type: 'string', + description: 'Ui语言名称', + nullable: true, + }, + displayName: { + type: 'string', + description: '显示名称', + nullable: true, + }, + flagIcon: { + type: 'string', + description: '图标', + nullable: true, + }, + isEnabled: { + type: 'boolean', + description: '是否启用', + }, + }, + additionalProperties: false, + description: '删除语言', +} as const; + +export const UpdateLanguageTextInputSchema = { + required: ['cultureName', 'name', 'resourceName', 'value'], + type: 'object', + properties: { + resourceName: { + minLength: 1, + type: 'string', + description: '资源名称', + }, + cultureName: { + minLength: 1, + type: 'string', + description: '语言名称', + }, + name: { + minLength: 1, + type: 'string', + description: '名称', + }, + value: { + minLength: 1, + type: 'string', + description: '值', + }, + }, + additionalProperties: false, + description: '删除语言文本', +} as const; + +export const UpdateMenuInputSchema = { + required: ['hideInMenu', 'keepAlive', 'name', 'order', 'path', 'title'], + type: 'object', + properties: { + id: { + type: 'string', + description: '菜单Id', + format: 'uuid', + }, + name: { + minLength: 1, + type: 'string', + description: '唯一编码', + }, + title: { + minLength: 1, + type: 'string', + description: '标题', + }, + icon: { + type: 'string', + description: '图标', + nullable: true, + }, + keepAlive: { + type: 'boolean', + description: '是否缓存', + }, + hideInMenu: { + type: 'boolean', + description: '是否显示', + }, + order: { + type: 'integer', + description: '排序', + format: 'int32', + }, + path: { + minLength: 1, + type: 'string', + description: '路由地址', + }, + menuType: { + $ref: '#/components/schemas/MenuType', + }, + openType: { + $ref: '#/components/schemas/OpenType', + }, + url: { + type: 'string', + description: '内外链地址', + nullable: true, + }, + component: { + type: 'string', + description: '组件地址', + nullable: true, + }, + enabled: { + type: 'boolean', + }, + policy: { + type: 'string', + description: '权限', + nullable: true, + }, + }, + additionalProperties: false, + description: '更新菜单', +} as const; + +export const UpdateOrganizationUnitInputSchema = { + type: 'object', + properties: { + displayName: { + type: 'string', + nullable: true, + }, + id: { + type: 'string', + format: 'uuid', + }, + }, + additionalProperties: false, +} as const; + +export const UpdatePermissionDtoSchema = { + type: 'object', + properties: { + name: { + type: 'string', + nullable: true, + }, + isGranted: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const UpdatePermissionsDtoSchema = { + type: 'object', + properties: { + permissions: { + type: 'array', + items: { + $ref: '#/components/schemas/UpdatePermissionDto', + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateProjectInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + owner: { + type: 'string', + description: '负责人', + nullable: true, + }, + companyName: { + type: 'string', + description: '公司名称', + nullable: true, + }, + projectName: { + type: 'string', + description: '项目名称', + nullable: true, + }, + remark: { + type: 'string', + description: '备注', + nullable: true, + }, + supportTenant: { + type: 'boolean', + description: '是否支持多租户', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateRoleInputSchema = { + type: 'object', + properties: { + roleId: { + type: 'string', + format: 'uuid', + }, + roleInfo: { + $ref: '#/components/schemas/IdentityRoleUpdateDto', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateRolePermissionsInputSchema = { + type: 'object', + properties: { + providerName: { + type: 'string', + nullable: true, + }, + providerKey: { + type: 'string', + nullable: true, + }, + updatePermissionsDto: { + $ref: '#/components/schemas/UpdatePermissionsDto', + }, + }, + additionalProperties: false, +} as const; + +export const UpdateSettingInputSchema = { + type: 'object', + properties: { + values: { + type: 'object', + additionalProperties: { + type: 'string', + nullable: true, + }, + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateTemplateDetailContentInputSchema = { + type: 'object', + properties: { + templateId: { + type: 'string', + description: '模板id', + format: 'uuid', + }, + templateDetailId: { + type: 'string', + format: 'uuid', + }, + content: { + type: 'string', + description: '模板内容', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateTemplateDetailInputSchema = { + type: 'object', + properties: { + templateId: { + type: 'string', + description: '模板id', + format: 'uuid', + }, + templateDetailId: { + type: 'string', + format: 'uuid', + }, + controlType: { + $ref: '#/components/schemas/ControlType', + }, + name: { + type: 'string', + description: '模板类型', + nullable: true, + }, + description: { + type: 'string', + description: '描述', + nullable: true, + }, + content: { + type: 'string', + description: '模板内容', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateTemplateInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + name: { + type: 'string', + description: '名称', + nullable: true, + }, + remark: { + type: 'string', + description: '备注', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateTenantInputSchema = { + type: 'object', + properties: { + id: { + type: 'string', + format: 'uuid', + }, + name: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; + +export const UpdateTextTemplateInputSchema = { + required: ['code', 'content', 'cultureName', 'name'], + type: 'object', + properties: { + id: { + type: 'string', + description: '模板Id', + format: 'uuid', + }, + name: { + minLength: 1, + type: 'string', + description: '名称', + }, + code: { + minLength: 1, + type: 'string', + description: '编码', + }, + content: { + minLength: 1, + type: 'string', + description: '内容', + }, + cultureName: { + minLength: 1, + type: 'string', + description: '语言', + }, + }, + additionalProperties: false, + description: '更新模板', +} as const; + +export const UpdateUserInputSchema = { + type: 'object', + properties: { + userId: { + type: 'string', + format: 'uuid', + }, + userInfo: { + $ref: '#/components/schemas/IdentityUserUpdateDto', + }, + }, + additionalProperties: false, +} as const; + +export const UserLoginInfoSchema = { + required: ['password', 'userNameOrEmailAddress'], + type: 'object', + properties: { + userNameOrEmailAddress: { + maxLength: 255, + minLength: 0, + type: 'string', + }, + password: { + maxLength: 32, + minLength: 0, + type: 'string', + format: 'password', + }, + rememberMe: { + type: 'boolean', + }, + }, + additionalProperties: false, +} as const; + +export const WindowsTimeZoneSchema = { + type: 'object', + properties: { + timeZoneId: { + type: 'string', + nullable: true, + }, + }, + additionalProperties: false, +} as const; diff --git a/apps/web-antd/src/api-client/services.gen.ts b/apps/web-antd/src/api-client/services.gen.ts new file mode 100644 index 0000000..a53f248 --- /dev/null +++ b/apps/web-antd/src/api-client/services.gen.ts @@ -0,0 +1,2947 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Options } from '@hey-api/client-axios'; + +import type { + GetApiAbpApiDefinitionData, + GetApiAbpApiDefinitionError, + GetApiAbpApiDefinitionResponse, + GetApiAbpApplicationConfigurationData, + GetApiAbpApplicationConfigurationError, + GetApiAbpApplicationConfigurationResponse, + GetApiAbpApplicationLocalizationData, + GetApiAbpApplicationLocalizationError, + GetApiAbpApplicationLocalizationResponse, + GetApiAppAbpProBasicApplicationConfigurationError, + GetApiAppAbpProBasicApplicationConfigurationResponse, + PostApiAppAccountLogin2FaData, + PostApiAppAccountLogin2FaError, + PostApiAppAccountLogin2FaResponse, + PostApiAppAccountLoginData, + PostApiAppAccountLoginError, + PostApiAppAccountLoginOidcData, + PostApiAppAccountLoginOidcError, + PostApiAppAccountLoginOidcResponse, + PostApiAppAccountLoginResponse, + PostApiAppAccountRefreshTokenData, + PostApiAppAccountRefreshTokenError, + PostApiAppAccountRefreshTokenResponse, + PostAuditLogsPageData, + PostAuditLogsPageError, + PostAuditLogsPageResponse, + PostDataDictionaryCreateData, + PostDataDictionaryCreateDetailData, + PostDataDictionaryCreateDetailError, + PostDataDictionaryCreateDetailResponse, + PostDataDictionaryCreateError, + PostDataDictionaryCreateResponse, + PostDataDictionaryDeleteData, + PostDataDictionaryDeleteDataDictionaryTypeData, + PostDataDictionaryDeleteDataDictionaryTypeError, + PostDataDictionaryDeleteDataDictionaryTypeResponse, + PostDataDictionaryDeleteError, + PostDataDictionaryDeleteResponse, + PostDataDictionaryPageData, + PostDataDictionaryPageDetailData, + PostDataDictionaryPageDetailError, + PostDataDictionaryPageDetailResponse, + PostDataDictionaryPageError, + PostDataDictionaryPageResponse, + PostDataDictionaryStatusData, + PostDataDictionaryStatusError, + PostDataDictionaryStatusResponse, + PostDataDictionaryUpdateData, + PostDataDictionaryUpdateDetailData, + PostDataDictionaryUpdateDetailError, + PostDataDictionaryUpdateDetailResponse, + PostDataDictionaryUpdateError, + PostDataDictionaryUpdateResponse, + PostDataTypesListData, + PostDataTypesListError, + PostDataTypesListResponse, + PostEntityModelsCreateAggregateData, + PostEntityModelsCreateAggregateError, + PostEntityModelsCreateAggregateResponse, + PostEntityModelsCreateEntityModelData, + PostEntityModelsCreateEntityModelError, + PostEntityModelsCreateEntityModelPropertyData, + PostEntityModelsCreateEntityModelPropertyError, + PostEntityModelsCreateEntityModelPropertyResponse, + PostEntityModelsCreateEntityModelResponse, + PostEntityModelsDeleteAggregateData, + PostEntityModelsDeleteAggregateError, + PostEntityModelsDeleteAggregateResponse, + PostEntityModelsDeleteEntityModelData, + PostEntityModelsDeleteEntityModelError, + PostEntityModelsDeleteEntityModelPropertyData, + PostEntityModelsDeleteEntityModelPropertyError, + PostEntityModelsDeleteEntityModelPropertyResponse, + PostEntityModelsDeleteEntityModelResponse, + PostEntityModelsGetData, + PostEntityModelsGetError, + PostEntityModelsGetResponse, + PostEntityModelsPagePropertyData, + PostEntityModelsPagePropertyError, + PostEntityModelsPagePropertyResponse, + PostEntityModelsTreeData, + PostEntityModelsTreeError, + PostEntityModelsTreeResponse, + PostEntityModelsUpdateAggregateData, + PostEntityModelsUpdateAggregateError, + PostEntityModelsUpdateAggregateResponse, + PostEntityModelsUpdateEntityModelData, + PostEntityModelsUpdateEntityModelError, + PostEntityModelsUpdateEntityModelPropertyData, + PostEntityModelsUpdateEntityModelPropertyError, + PostEntityModelsUpdateEntityModelPropertyResponse, + PostEntityModelsUpdateEntityModelResponse, + PostEnumTypesCreateEnumTypeData, + PostEnumTypesCreateEnumTypeError, + PostEnumTypesCreateEnumTypePropertyData, + PostEnumTypesCreateEnumTypePropertyError, + PostEnumTypesCreateEnumTypePropertyResponse, + PostEnumTypesCreateEnumTypeResponse, + PostEnumTypesDeleteEnumTypeData, + PostEnumTypesDeleteEnumTypeError, + PostEnumTypesDeleteEnumTypePropertyData, + PostEnumTypesDeleteEnumTypePropertyError, + PostEnumTypesDeleteEnumTypePropertyResponse, + PostEnumTypesDeleteEnumTypeResponse, + PostEnumTypesPageData, + PostEnumTypesPageError, + PostEnumTypesPagePropertyData, + PostEnumTypesPagePropertyError, + PostEnumTypesPagePropertyResponse, + PostEnumTypesPageResponse, + PostEnumTypesUpdateEnumTypeData, + PostEnumTypesUpdateEnumTypeError, + PostEnumTypesUpdateEnumTypePropertyData, + PostEnumTypesUpdateEnumTypePropertyError, + PostEnumTypesUpdateEnumTypePropertyResponse, + PostEnumTypesUpdateEnumTypeResponse, + PostFeaturesDeleteData, + PostFeaturesDeleteError, + PostFeaturesDeleteResponse, + PostFeaturesListData, + PostFeaturesListError, + PostFeaturesListResponse, + PostFeaturesUpdateData, + PostFeaturesUpdateError, + PostFeaturesUpdateResponse, + PostFilesDeleteData, + PostFilesDeleteError, + PostFilesDeleteResponse, + PostFilesDownloadData, + PostFilesDownloadError, + PostFilesDownloadResponse, + PostFilesPageData, + PostFilesPageError, + PostFilesPageResponse, + PostFilesUploadData, + PostFilesUploadError, + PostFilesUploadResponse, + PostGeneratorDownData, + PostGeneratorDownError, + PostGeneratorDownResponse, + PostGeneratorPreViewCodeData, + PostGeneratorPreViewCodeError, + PostGeneratorPreViewCodeResponse, + PostIdentitySecurityLogsPageData, + PostIdentitySecurityLogsPageError, + PostIdentitySecurityLogsPageResponse, + PostLanguagesAllError, + PostLanguagesAllResponse, + PostLanguagesCreateData, + PostLanguagesCreateError, + PostLanguagesCreateResponse, + PostLanguagesDeleteData, + PostLanguagesDeleteError, + PostLanguagesDeleteResponse, + PostLanguagesPageData, + PostLanguagesPageError, + PostLanguagesPageResponse, + PostLanguagesSetDefaultData, + PostLanguagesSetDefaultError, + PostLanguagesSetDefaultResponse, + PostLanguagesUpdateData, + PostLanguagesUpdateError, + PostLanguagesUpdateResponse, + PostLanguageTextsAllResourceError, + PostLanguageTextsAllResourceResponse, + PostLanguageTextsCreateData, + PostLanguageTextsCreateError, + PostLanguageTextsCreateResponse, + PostLanguageTextsPageData, + PostLanguageTextsPageError, + PostLanguageTextsPageResponse, + PostLanguageTextsUpdateData, + PostLanguageTextsUpdateError, + PostLanguageTextsUpdateResponse, + PostMenusCreateData, + PostMenusCreateError, + PostMenusCreateResponse, + PostMenusDeleteData, + PostMenusDeleteError, + PostMenusDeleteResponse, + PostMenusPageData, + PostMenusPageError, + PostMenusPageResponse, + PostMenusTreeError, + PostMenusTreeResponse, + PostMenusUpdateData, + PostMenusUpdateError, + PostMenusUpdateResponse, + PostMenusUserMenuError, + PostMenusUserMenuResponse, + PostNotificationBatchReadData, + PostNotificationBatchReadError, + PostNotificationBatchReadResponse, + PostNotificationDeleteData, + PostNotificationDeleteError, + PostNotificationDeleteResponse, + PostNotificationNotificationPageData, + PostNotificationNotificationPageError, + PostNotificationNotificationPageResponse, + PostNotificationNotificationSubscriptionPageData, + PostNotificationNotificationSubscriptionPageError, + PostNotificationNotificationSubscriptionPageResponse, + PostNotificationReadData, + PostNotificationReadError, + PostNotificationReadResponse, + PostNotificationSendBroadCastErrorMessageData, + PostNotificationSendBroadCastErrorMessageError, + PostNotificationSendBroadCastErrorMessageResponse, + PostNotificationSendBroadCastInformationMessageData, + PostNotificationSendBroadCastInformationMessageError, + PostNotificationSendBroadCastInformationMessageResponse, + PostNotificationSendBroadCastWarningMessageData, + PostNotificationSendBroadCastWarningMessageError, + PostNotificationSendBroadCastWarningMessageResponse, + PostNotificationSendCommonErrorMessageData, + PostNotificationSendCommonErrorMessageError, + PostNotificationSendCommonErrorMessageResponse, + PostNotificationSendCommonInformationMessageData, + PostNotificationSendCommonInformationMessageError, + PostNotificationSendCommonInformationMessageResponse, + PostNotificationSendCommonWarningMessageData, + PostNotificationSendCommonWarningMessageError, + PostNotificationSendCommonWarningMessageResponse, + PostOrganizationUnitsAddRoleToOrganizationUnitAsyncData, + PostOrganizationUnitsAddRoleToOrganizationUnitAsyncError, + PostOrganizationUnitsAddRoleToOrganizationUnitAsyncResponse, + PostOrganizationUnitsAddUserToOrganizationUnitData, + PostOrganizationUnitsAddUserToOrganizationUnitError, + PostOrganizationUnitsAddUserToOrganizationUnitResponse, + PostOrganizationUnitsCreateData, + PostOrganizationUnitsCreateError, + PostOrganizationUnitsCreateResponse, + PostOrganizationUnitsDeleteData, + PostOrganizationUnitsDeleteError, + PostOrganizationUnitsDeleteResponse, + PostOrganizationUnitsGetRolesData, + PostOrganizationUnitsGetRolesError, + PostOrganizationUnitsGetRolesResponse, + PostOrganizationUnitsGetUnAddRolesData, + PostOrganizationUnitsGetUnAddRolesError, + PostOrganizationUnitsGetUnAddRolesResponse, + PostOrganizationUnitsGetUnAddUsersData, + PostOrganizationUnitsGetUnAddUsersError, + PostOrganizationUnitsGetUnAddUsersResponse, + PostOrganizationUnitsGetUsersData, + PostOrganizationUnitsGetUsersError, + PostOrganizationUnitsGetUsersResponse, + PostOrganizationUnitsRemoveRoleFromOrganizationUnitAsyncData, + PostOrganizationUnitsRemoveRoleFromOrganizationUnitAsyncError, + PostOrganizationUnitsRemoveRoleFromOrganizationUnitAsyncResponse, + PostOrganizationUnitsRemoveUserFromOrganizationUnitData, + PostOrganizationUnitsRemoveUserFromOrganizationUnitError, + PostOrganizationUnitsRemoveUserFromOrganizationUnitResponse, + PostOrganizationUnitsTreeError, + PostOrganizationUnitsTreeResponse, + PostOrganizationUnitsUpdateData, + PostOrganizationUnitsUpdateError, + PostOrganizationUnitsUpdateResponse, + PostPermissionsTreeData, + PostPermissionsTreeError, + PostPermissionsTreeResponse, + PostPermissionsUpdateData, + PostPermissionsUpdateError, + PostPermissionsUpdateResponse, + PostProjectsAllError, + PostProjectsAllResponse, + PostProjectsCreateData, + PostProjectsCreateError, + PostProjectsCreateResponse, + PostProjectsDeleteData, + PostProjectsDeleteError, + PostProjectsDeleteResponse, + PostProjectsGetProjectAndEntityData, + PostProjectsGetProjectAndEntityError, + PostProjectsGetProjectAndEntityResponse, + PostProjectsPageData, + PostProjectsPageError, + PostProjectsPageResponse, + PostProjectsUpdateData, + PostProjectsUpdateError, + PostProjectsUpdateResponse, + PostRolesAllError, + PostRolesAllResponse, + PostRolesCreateData, + PostRolesCreateError, + PostRolesCreateResponse, + PostRolesDeleteData, + PostRolesDeleteError, + PostRolesDeleteResponse, + PostRolesPageData, + PostRolesPageError, + PostRolesPageResponse, + PostRolesUpdateData, + PostRolesUpdateError, + PostRolesUpdateResponse, + PostSettingsAllError, + PostSettingsAllResponse, + PostSettingsUpdateData, + PostSettingsUpdateError, + PostSettingsUpdateResponse, + PostTemplatesAllError, + PostTemplatesAllResponse, + PostTemplatesControlTypeError, + PostTemplatesControlTypeResponse, + PostTemplatesCopyData, + PostTemplatesCopyError, + PostTemplatesCopyResponse, + PostTemplatesCreateData, + PostTemplatesCreateDetailData, + PostTemplatesCreateDetailError, + PostTemplatesCreateDetailResponse, + PostTemplatesCreateError, + PostTemplatesCreateResponse, + PostTemplatesDeleteData, + PostTemplatesDeleteDetailData, + PostTemplatesDeleteDetailError, + PostTemplatesDeleteDetailResponse, + PostTemplatesDeleteError, + PostTemplatesDeleteResponse, + PostTemplatesListError, + PostTemplatesListResponse, + PostTemplatesPageData, + PostTemplatesPageError, + PostTemplatesPageResponse, + PostTemplatesTemplateTypeError, + PostTemplatesTemplateTypeResponse, + PostTemplatesTreeData, + PostTemplatesTreeError, + PostTemplatesTreeResponse, + PostTemplatesUpdateData, + PostTemplatesUpdateDetailContentData, + PostTemplatesUpdateDetailContentError, + PostTemplatesUpdateDetailContentResponse, + PostTemplatesUpdateDetailData, + PostTemplatesUpdateDetailError, + PostTemplatesUpdateDetailResponse, + PostTemplatesUpdateError, + PostTemplatesUpdateResponse, + PostTenantsAddOrUpdateConnectionStringData, + PostTenantsAddOrUpdateConnectionStringError, + PostTenantsAddOrUpdateConnectionStringResponse, + PostTenantsCreateData, + PostTenantsCreateError, + PostTenantsCreateResponse, + PostTenantsDeleteConnectionStringData, + PostTenantsDeleteConnectionStringError, + PostTenantsDeleteConnectionStringResponse, + PostTenantsDeleteData, + PostTenantsDeleteError, + PostTenantsDeleteResponse, + PostTenantsFindData, + PostTenantsFindError, + PostTenantsFindResponse, + PostTenantsPageConnectionStringData, + PostTenantsPageConnectionStringError, + PostTenantsPageConnectionStringResponse, + PostTenantsPageData, + PostTenantsPageError, + PostTenantsPageResponse, + PostTenantsUpdateData, + PostTenantsUpdateError, + PostTenantsUpdateResponse, + PostTextTemplatesCreateData, + PostTextTemplatesCreateError, + PostTextTemplatesCreateResponse, + PostTextTemplatesDeleteData, + PostTextTemplatesDeleteError, + PostTextTemplatesDeleteResponse, + PostTextTemplatesExportData, + PostTextTemplatesExportError, + PostTextTemplatesExportResponse, + PostTextTemplatesPageData, + PostTextTemplatesPageError, + PostTextTemplatesPageResponse, + PostTextTemplatesUpdateData, + PostTextTemplatesUpdateError, + PostTextTemplatesUpdateResponse, + PostUsersCanUseTwoFactorError, + PostUsersCanUseTwoFactorResponse, + PostUsersChangePasswordData, + PostUsersChangePasswordError, + PostUsersChangePasswordResponse, + PostUsersCreateData, + PostUsersCreateError, + PostUsersCreateResponse, + PostUsersDeleteData, + PostUsersDeleteError, + PostUsersDeleteResponse, + PostUsersDisabledTwoFactorData, + PostUsersDisabledTwoFactorError, + PostUsersDisabledTwoFactorResponse, + PostUsersEnabledTwoFactorData, + PostUsersEnabledTwoFactorError, + PostUsersEnabledTwoFactorResponse, + PostUsersExportData, + PostUsersExportError, + PostUsersExportResponse, + PostUsersFindByUserNameData, + PostUsersFindByUserNameError, + PostUsersFindByUserNameResponse, + PostUsersGetQrCodeError, + PostUsersGetQrCodeResponse, + PostUsersListData, + PostUsersListError, + PostUsersListResponse, + PostUsersLockData, + PostUsersLockError, + PostUsersLockResponse, + PostUsersMyProfileError, + PostUsersMyProfileResponse, + PostUsersNeedChangePasswordError, + PostUsersNeedChangePasswordResponse, + PostUsersPageData, + PostUsersPageError, + PostUsersPageResponse, + PostUsersResetPasswordData, + PostUsersResetPasswordError, + PostUsersResetPasswordResponse, + PostUsersResetTwoFactorData, + PostUsersResetTwoFactorError, + PostUsersResetTwoFactorResponse, + PostUsersRoleData, + PostUsersRoleError, + PostUsersRoleResponse, + PostUsersUpdateData, + PostUsersUpdateError, + PostUsersUpdateResponse, +} from './types.gen'; + +import { + createClient, + createConfig, + formDataBodySerializer, +} from '@hey-api/client-axios'; + +export const client = createClient(createConfig()); + +export const getApiAbpApiDefinition = ( + options?: Options, +) => { + return (options?.client ?? client).get< + GetApiAbpApiDefinitionResponse, + GetApiAbpApiDefinitionError, + ThrowOnError + >({ + ...options, + url: '/api/abp/api-definition', + }); +}; + +export const getApiAbpApplicationConfiguration = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).get< + GetApiAbpApplicationConfigurationResponse, + GetApiAbpApplicationConfigurationError, + ThrowOnError + >({ + ...options, + url: '/api/abp/application-configuration', + }); +}; + +export const getApiAbpApplicationLocalization = < + ThrowOnError extends boolean = false, +>( + options: Options, +) => { + return (options?.client ?? client).get< + GetApiAbpApplicationLocalizationResponse, + GetApiAbpApplicationLocalizationError, + ThrowOnError + >({ + ...options, + url: '/api/abp/application-localization', + }); +}; + +export const getApiAppAbpProBasicApplicationConfiguration = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).get< + GetApiAppAbpProBasicApplicationConfigurationResponse, + GetApiAppAbpProBasicApplicationConfigurationError, + ThrowOnError + >({ + ...options, + url: '/api/app/abp-pro-basic-application-configuration', + }); +}; + +/** + * 登录 + */ +export const postApiAppAccountLogin = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostApiAppAccountLoginResponse, + PostApiAppAccountLoginError, + ThrowOnError + >({ + ...options, + url: '/api/app/account/login', + }); +}; + +/** + * 2FA登录 + */ +export const postApiAppAccountLogin2Fa = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostApiAppAccountLogin2FaResponse, + PostApiAppAccountLogin2FaError, + ThrowOnError + >({ + ...options, + url: '/api/app/account/login2FA', + }); +}; + +/** + * 第三方扩展登录 + */ +export const postApiAppAccountLoginOidc = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostApiAppAccountLoginOidcResponse, + PostApiAppAccountLoginOidcError, + ThrowOnError + >({ + ...options, + url: '/api/app/account/login-oidc', + }); +}; + +/** + * 刷新token + */ +export const postApiAppAccountRefreshToken = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostApiAppAccountRefreshTokenResponse, + PostApiAppAccountRefreshTokenError, + ThrowOnError + >({ + ...options, + url: '/api/app/account/refresh-token', + }); +}; + +/** + * 分页获取审计日志信息 + */ +export const postAuditLogsPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostAuditLogsPageResponse, + PostAuditLogsPageError, + ThrowOnError + >({ + ...options, + url: '/AuditLogs/page', + }); +}; + +/** + * 分页字典类型 + */ +export const postDataDictionaryPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostDataDictionaryPageResponse, + PostDataDictionaryPageError, + ThrowOnError + >({ + ...options, + url: '/DataDictionary/page', + }); +}; + +/** + * 分页字典明细 + */ +export const postDataDictionaryPageDetail = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostDataDictionaryPageDetailResponse, + PostDataDictionaryPageDetailError, + ThrowOnError + >({ + ...options, + url: '/DataDictionary/pageDetail', + }); +}; + +/** + * 创建字典类型 + */ +export const postDataDictionaryCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostDataDictionaryCreateResponse, + PostDataDictionaryCreateError, + ThrowOnError + >({ + ...options, + url: '/DataDictionary/create', + }); +}; + +/** + * 创建字典明细 + */ +export const postDataDictionaryCreateDetail = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostDataDictionaryCreateDetailResponse, + PostDataDictionaryCreateDetailError, + ThrowOnError + >({ + ...options, + url: '/DataDictionary/createDetail', + }); +}; + +/** + * 设置字典明细状态 + */ +export const postDataDictionaryStatus = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostDataDictionaryStatusResponse, + PostDataDictionaryStatusError, + ThrowOnError + >({ + ...options, + url: '/DataDictionary/status', + }); +}; + +/** + * 更新字典明细 + */ +export const postDataDictionaryUpdateDetail = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostDataDictionaryUpdateDetailResponse, + PostDataDictionaryUpdateDetailError, + ThrowOnError + >({ + ...options, + url: '/DataDictionary/updateDetail', + }); +}; + +/** + * 删除字典明细 + */ +export const postDataDictionaryDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostDataDictionaryDeleteResponse, + PostDataDictionaryDeleteError, + ThrowOnError + >({ + ...options, + url: '/DataDictionary/delete', + }); +}; + +/** + * 删除字典类型 + */ +export const postDataDictionaryDeleteDataDictionaryType = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostDataDictionaryDeleteDataDictionaryTypeData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostDataDictionaryDeleteDataDictionaryTypeResponse, + PostDataDictionaryDeleteDataDictionaryTypeError, + ThrowOnError + >({ + ...options, + url: '/DataDictionary/deleteDataDictionaryType', + }); +}; + +/** + * 修改字典类型 + */ +export const postDataDictionaryUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostDataDictionaryUpdateResponse, + PostDataDictionaryUpdateError, + ThrowOnError + >({ + ...options, + url: '/DataDictionary/update', + }); +}; + +/** + * 获取类型 + */ +export const postDataTypesList = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostDataTypesListResponse, + PostDataTypesListError, + ThrowOnError + >({ + ...options, + url: '/DataTypes/List', + }); +}; + +/** + * 分页获取实体属性 + */ +export const postEntityModelsPageProperty = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEntityModelsPagePropertyResponse, + PostEntityModelsPagePropertyError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/PageProperty', + }); +}; + +/** + * 新增聚合根 + */ +export const postEntityModelsCreateAggregate = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEntityModelsCreateAggregateResponse, + PostEntityModelsCreateAggregateError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/CreateAggregate', + }); +}; + +/** + * 更新聚合根 + */ +export const postEntityModelsUpdateAggregate = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEntityModelsUpdateAggregateResponse, + PostEntityModelsUpdateAggregateError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/UpdateAggregate', + }); +}; + +/** + * 删除聚合根 + */ +export const postEntityModelsDeleteAggregate = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEntityModelsDeleteAggregateResponse, + PostEntityModelsDeleteAggregateError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/DeleteAggregate', + }); +}; + +/** + * 新增实体 + */ +export const postEntityModelsCreateEntityModel = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEntityModelsCreateEntityModelResponse, + PostEntityModelsCreateEntityModelError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/CreateEntityModel', + }); +}; + +/** + * 更新实体 + */ +export const postEntityModelsUpdateEntityModel = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEntityModelsUpdateEntityModelResponse, + PostEntityModelsUpdateEntityModelError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/UpdateEntityModel', + }); +}; + +/** + * 删除实体 + */ +export const postEntityModelsDeleteEntityModel = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEntityModelsDeleteEntityModelResponse, + PostEntityModelsDeleteEntityModelError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/DeleteEntityModel', + }); +}; + +/** + * 新增实体属性 + */ +export const postEntityModelsCreateEntityModelProperty = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostEntityModelsCreateEntityModelPropertyData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostEntityModelsCreateEntityModelPropertyResponse, + PostEntityModelsCreateEntityModelPropertyError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/CreateEntityModelProperty', + }); +}; + +/** + * 更新实体属性 + */ +export const postEntityModelsUpdateEntityModelProperty = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostEntityModelsUpdateEntityModelPropertyData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostEntityModelsUpdateEntityModelPropertyResponse, + PostEntityModelsUpdateEntityModelPropertyError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/UpdateEntityModelProperty', + }); +}; + +/** + * 删除实体属性 + */ +export const postEntityModelsDeleteEntityModelProperty = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostEntityModelsDeleteEntityModelPropertyData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostEntityModelsDeleteEntityModelPropertyResponse, + PostEntityModelsDeleteEntityModelPropertyError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/DeleteEntityModelProperty', + }); +}; + +/** + * 获取实体树 + */ +export const postEntityModelsTree = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEntityModelsTreeResponse, + PostEntityModelsTreeError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/Tree', + }); +}; + +/** + * 获取模型数据 + */ +export const postEntityModelsGet = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEntityModelsGetResponse, + PostEntityModelsGetError, + ThrowOnError + >({ + ...options, + url: '/EntityModels/Get', + }); +}; + +/** + * 分页获取枚举 + */ +export const postEnumTypesPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEnumTypesPageResponse, + PostEnumTypesPageError, + ThrowOnError + >({ + ...options, + url: '/EnumTypes/Page', + }); +}; + +/** + * 分页获取枚举属性 + */ +export const postEnumTypesPageProperty = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEnumTypesPagePropertyResponse, + PostEnumTypesPagePropertyError, + ThrowOnError + >({ + ...options, + url: '/EnumTypes/PageProperty', + }); +}; + +/** + * 创建枚举 + */ +export const postEnumTypesCreateEnumType = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEnumTypesCreateEnumTypeResponse, + PostEnumTypesCreateEnumTypeError, + ThrowOnError + >({ + ...options, + url: '/EnumTypes/CreateEnumType', + }); +}; + +/** + * 更新枚举 + */ +export const postEnumTypesUpdateEnumType = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEnumTypesUpdateEnumTypeResponse, + PostEnumTypesUpdateEnumTypeError, + ThrowOnError + >({ + ...options, + url: '/EnumTypes/UpdateEnumType', + }); +}; + +/** + * 删除枚举 + */ +export const postEnumTypesDeleteEnumType = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEnumTypesDeleteEnumTypeResponse, + PostEnumTypesDeleteEnumTypeError, + ThrowOnError + >({ + ...options, + url: '/EnumTypes/DeleteEnumType', + }); +}; + +/** + * 创建枚举属性 + */ +export const postEnumTypesCreateEnumTypeProperty = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEnumTypesCreateEnumTypePropertyResponse, + PostEnumTypesCreateEnumTypePropertyError, + ThrowOnError + >({ + ...options, + url: '/EnumTypes/CreateEnumTypeProperty', + }); +}; + +/** + * 更新枚举属性 + */ +export const postEnumTypesUpdateEnumTypeProperty = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEnumTypesUpdateEnumTypePropertyResponse, + PostEnumTypesUpdateEnumTypePropertyError, + ThrowOnError + >({ + ...options, + url: '/EnumTypes/UpdateEnumTypeProperty', + }); +}; + +/** + * 删除枚举属性 + */ +export const postEnumTypesDeleteEnumTypeProperty = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostEnumTypesDeleteEnumTypePropertyResponse, + PostEnumTypesDeleteEnumTypePropertyError, + ThrowOnError + >({ + ...options, + url: '/EnumTypes/DeleteEnumTypeProperty', + }); +}; + +/** + * 获取Features + */ +export const postFeaturesList = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostFeaturesListResponse, + PostFeaturesListError, + ThrowOnError + >({ + ...options, + url: '/Features/list', + }); +}; + +/** + * 更新Features + */ +export const postFeaturesUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostFeaturesUpdateResponse, + PostFeaturesUpdateError, + ThrowOnError + >({ + ...options, + url: '/Features/update', + }); +}; + +/** + * 删除Features + */ +export const postFeaturesDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostFeaturesDeleteResponse, + PostFeaturesDeleteError, + ThrowOnError + >({ + ...options, + url: '/Features/delete', + }); +}; + +/** + * 分页查询文件 + */ +export const postFilesPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostFilesPageResponse, + PostFilesPageError, + ThrowOnError + >({ + ...options, + url: '/Files/Page', + }); +}; + +/** + * 上传文件 + */ +export const postFilesUpload = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostFilesUploadResponse, + PostFilesUploadError, + ThrowOnError + >({ + ...options, + ...formDataBodySerializer, + headers: { + 'Content-Type': null, + ...options?.headers, + }, + url: '/Files/Upload', + }); +}; + +/** + * 删除文件 + */ +export const postFilesDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostFilesDeleteResponse, + PostFilesDeleteError, + ThrowOnError + >({ + ...options, + url: '/Files/Delete', + }); +}; + +/** + * 下载文件 + */ +export const postFilesDownload = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostFilesDownloadResponse, + PostFilesDownloadError, + ThrowOnError + >({ + ...options, + url: '/Files/Download', + }); +}; + +/** + * 预览 + */ +export const postGeneratorPreViewCode = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostGeneratorPreViewCodeResponse, + PostGeneratorPreViewCodeError, + ThrowOnError + >({ + ...options, + url: '/Generator/PreViewCode', + }); +}; + +/** + * 下载 + */ +export const postGeneratorDown = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostGeneratorDownResponse, + PostGeneratorDownError, + ThrowOnError + >({ + ...options, + url: '/Generator/Down', + }); +}; + +/** + * 分页获取登录日志信息 + */ +export const postIdentitySecurityLogsPage = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostIdentitySecurityLogsPageResponse, + PostIdentitySecurityLogsPageError, + ThrowOnError + >({ + ...options, + url: '/IdentitySecurityLogs/page', + }); +}; + +/** + * 获取所有语言 + */ +export const postLanguagesAll = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguagesAllResponse, + PostLanguagesAllError, + ThrowOnError + >({ + ...options, + url: '/Languages/All', + }); +}; + +/** + * 分页查询语言 + */ +export const postLanguagesPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguagesPageResponse, + PostLanguagesPageError, + ThrowOnError + >({ + ...options, + url: '/Languages/Page', + }); +}; + +/** + * 创建语言 + */ +export const postLanguagesCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguagesCreateResponse, + PostLanguagesCreateError, + ThrowOnError + >({ + ...options, + url: '/Languages/Create', + }); +}; + +/** + * 编辑语言 + */ +export const postLanguagesUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguagesUpdateResponse, + PostLanguagesUpdateError, + ThrowOnError + >({ + ...options, + url: '/Languages/Update', + }); +}; + +/** + * 删除语言 + */ +export const postLanguagesDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguagesDeleteResponse, + PostLanguagesDeleteError, + ThrowOnError + >({ + ...options, + url: '/Languages/Delete', + }); +}; + +/** + * 设置默认语言 + */ +export const postLanguagesSetDefault = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguagesSetDefaultResponse, + PostLanguagesSetDefaultError, + ThrowOnError + >({ + ...options, + url: '/Languages/SetDefault', + }); +}; + +/** + * 获取所有资源 + */ +export const postLanguageTextsAllResource = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguageTextsAllResourceResponse, + PostLanguageTextsAllResourceError, + ThrowOnError + >({ + ...options, + url: '/LanguageTexts/AllResource', + }); +}; + +/** + * 分页查询语言文本 + */ +export const postLanguageTextsPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguageTextsPageResponse, + PostLanguageTextsPageError, + ThrowOnError + >({ + ...options, + url: '/LanguageTexts/Page', + }); +}; + +/** + * 创建语言文本 + */ +export const postLanguageTextsCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguageTextsCreateResponse, + PostLanguageTextsCreateError, + ThrowOnError + >({ + ...options, + url: '/LanguageTexts/Create', + }); +}; + +/** + * 编辑语言文本 + */ +export const postLanguageTextsUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostLanguageTextsUpdateResponse, + PostLanguageTextsUpdateError, + ThrowOnError + >({ + ...options, + url: '/LanguageTexts/Update', + }); +}; + +/** + * 获取用户菜单 + */ +export const postMenusUserMenu = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostMenusUserMenuResponse, + PostMenusUserMenuError, + ThrowOnError + >({ + ...options, + url: '/Menus/UserMenu', + }); +}; + +/** + * 分页查询菜单 + */ +export const postMenusPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostMenusPageResponse, + PostMenusPageError, + ThrowOnError + >({ + ...options, + url: '/Menus/Page', + }); +}; + +/** + * 创建菜单 + */ +export const postMenusCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostMenusCreateResponse, + PostMenusCreateError, + ThrowOnError + >({ + ...options, + url: '/Menus/Create', + }); +}; + +/** + * 编辑菜单 + */ +export const postMenusUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostMenusUpdateResponse, + PostMenusUpdateError, + ThrowOnError + >({ + ...options, + url: '/Menus/Update', + }); +}; + +/** + * 删除菜单 + */ +export const postMenusDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostMenusDeleteResponse, + PostMenusDeleteError, + ThrowOnError + >({ + ...options, + url: '/Menus/Delete', + }); +}; + +/** + * 获取菜单树 + */ +export const postMenusTree = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostMenusTreeResponse, + PostMenusTreeError, + ThrowOnError + >({ + ...options, + url: '/Menus/Tree', + }); +}; + +/** + * 分页获取文本消息 + */ +export const postNotificationNotificationPage = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostNotificationNotificationPageResponse, + PostNotificationNotificationPageError, + ThrowOnError + >({ + ...options, + url: '/Notification/NotificationPage', + }); +}; + +/** + * 分页获取广播消息已读人数 + */ +export const postNotificationNotificationSubscriptionPage = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostNotificationNotificationSubscriptionPageData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostNotificationNotificationSubscriptionPageResponse, + PostNotificationNotificationSubscriptionPageError, + ThrowOnError + >({ + ...options, + url: '/Notification/NotificationSubscriptionPage', + }); +}; + +/** + * 删除消息 + */ +export const postNotificationDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostNotificationDeleteResponse, + PostNotificationDeleteError, + ThrowOnError + >({ + ...options, + url: '/Notification/Delete', + }); +}; + +/** + * 发送警告文本消息 + */ +export const postNotificationSendCommonWarningMessage = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostNotificationSendCommonWarningMessageResponse, + PostNotificationSendCommonWarningMessageError, + ThrowOnError + >({ + ...options, + url: '/Notification/SendCommonWarningMessage', + }); +}; + +/** + * 发送普通文本消息 + */ +export const postNotificationSendCommonInformationMessage = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostNotificationSendCommonInformationMessageData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostNotificationSendCommonInformationMessageResponse, + PostNotificationSendCommonInformationMessageError, + ThrowOnError + >({ + ...options, + url: '/Notification/SendCommonInformationMessage', + }); +}; + +/** + * 发送错误文本消息 + */ +export const postNotificationSendCommonErrorMessage = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostNotificationSendCommonErrorMessageResponse, + PostNotificationSendCommonErrorMessageError, + ThrowOnError + >({ + ...options, + url: '/Notification/SendCommonErrorMessage', + }); +}; + +/** + * 发送警告广播消息 + */ +export const postNotificationSendBroadCastWarningMessage = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostNotificationSendBroadCastWarningMessageData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostNotificationSendBroadCastWarningMessageResponse, + PostNotificationSendBroadCastWarningMessageError, + ThrowOnError + >({ + ...options, + url: '/Notification/SendBroadCastWarningMessage', + }); +}; + +/** + * 发送正常广播消息 + */ +export const postNotificationSendBroadCastInformationMessage = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostNotificationSendBroadCastInformationMessageData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostNotificationSendBroadCastInformationMessageResponse, + PostNotificationSendBroadCastInformationMessageError, + ThrowOnError + >({ + ...options, + url: '/Notification/SendBroadCastInformationMessage', + }); +}; + +/** + * 发送错误广播消息 + */ +export const postNotificationSendBroadCastErrorMessage = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostNotificationSendBroadCastErrorMessageData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostNotificationSendBroadCastErrorMessageResponse, + PostNotificationSendBroadCastErrorMessageError, + ThrowOnError + >({ + ...options, + url: '/Notification/SendBroadCastErrorMessage', + }); +}; + +/** + * 消息设置为已读 + */ +export const postNotificationRead = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostNotificationReadResponse, + PostNotificationReadError, + ThrowOnError + >({ + ...options, + url: '/Notification/Read', + }); +}; + +/** + * 消息批量设置为已读 + */ +export const postNotificationBatchRead = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostNotificationBatchReadResponse, + PostNotificationBatchReadError, + ThrowOnError + >({ + ...options, + url: '/Notification/BatchRead', + }); +}; + +/** + * 获取组织机构树 + */ +export const postOrganizationUnitsTree = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsTreeResponse, + PostOrganizationUnitsTreeError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/tree', + }); +}; + +/** + * 创建组织机构 + */ +export const postOrganizationUnitsCreate = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsCreateResponse, + PostOrganizationUnitsCreateError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/create', + }); +}; + +/** + * 删除组织机构 + */ +export const postOrganizationUnitsDelete = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsDeleteResponse, + PostOrganizationUnitsDeleteError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/delete', + }); +}; + +/** + * 编辑组织机构 + */ +export const postOrganizationUnitsUpdate = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsUpdateResponse, + PostOrganizationUnitsUpdateError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/update', + }); +}; + +/** + * 向组织机构添加角色 + */ +export const postOrganizationUnitsAddRoleToOrganizationUnitAsync = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostOrganizationUnitsAddRoleToOrganizationUnitAsyncData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsAddRoleToOrganizationUnitAsyncResponse, + PostOrganizationUnitsAddRoleToOrganizationUnitAsyncError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/addRoleToOrganizationUnitAsync', + }); +}; + +/** + * 向组织机构删除角色 + */ +export const postOrganizationUnitsRemoveRoleFromOrganizationUnitAsync = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostOrganizationUnitsRemoveRoleFromOrganizationUnitAsyncData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsRemoveRoleFromOrganizationUnitAsyncResponse, + PostOrganizationUnitsRemoveRoleFromOrganizationUnitAsyncError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/removeRoleFromOrganizationUnitAsync', + }); +}; + +/** + * 向组织机构添加用户 + */ +export const postOrganizationUnitsAddUserToOrganizationUnit = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostOrganizationUnitsAddUserToOrganizationUnitData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsAddUserToOrganizationUnitResponse, + PostOrganizationUnitsAddUserToOrganizationUnitError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/addUserToOrganizationUnit', + }); +}; + +/** + * 向组织机构删除用户 + */ +export const postOrganizationUnitsRemoveUserFromOrganizationUnit = < + ThrowOnError extends boolean = false, +>( + options?: Options< + PostOrganizationUnitsRemoveUserFromOrganizationUnitData, + ThrowOnError + >, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsRemoveUserFromOrganizationUnitResponse, + PostOrganizationUnitsRemoveUserFromOrganizationUnitError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/removeUserFromOrganizationUnit', + }); +}; + +/** + * 分页获取组织机构下用户 + */ +export const postOrganizationUnitsGetUsers = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsGetUsersResponse, + PostOrganizationUnitsGetUsersError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/getUsers', + }); +}; + +/** + * 分页获取组织机构下角色 + */ +export const postOrganizationUnitsGetRoles = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsGetRolesResponse, + PostOrganizationUnitsGetRolesError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/getRoles', + }); +}; + +/** + * 获取不在组织机构的用户 + */ +export const postOrganizationUnitsGetUnAddUsers = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsGetUnAddUsersResponse, + PostOrganizationUnitsGetUnAddUsersError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/getUnAddUsers', + }); +}; + +/** + * 获取不在组织机构的角色 + */ +export const postOrganizationUnitsGetUnAddRoles = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostOrganizationUnitsGetUnAddRolesResponse, + PostOrganizationUnitsGetUnAddRolesError, + ThrowOnError + >({ + ...options, + url: '/OrganizationUnits/getUnAddRoles', + }); +}; + +/** + * 获取角色权限 + */ +export const postPermissionsTree = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostPermissionsTreeResponse, + PostPermissionsTreeError, + ThrowOnError + >({ + ...options, + url: '/Permissions/tree', + }); +}; + +/** + * 更新角色 + */ +export const postPermissionsUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostPermissionsUpdateResponse, + PostPermissionsUpdateError, + ThrowOnError + >({ + ...options, + url: '/Permissions/update', + }); +}; + +/** + * 获取所有项目 + */ +export const postProjectsAll = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostProjectsAllResponse, + PostProjectsAllError, + ThrowOnError + >({ + ...options, + url: '/Projects/All', + }); +}; + +/** + * 分页获取项目 + */ +export const postProjectsPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostProjectsPageResponse, + PostProjectsPageError, + ThrowOnError + >({ + ...options, + url: '/Projects/Page', + }); +}; + +/** + * 创建项目 + */ +export const postProjectsCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostProjectsCreateResponse, + PostProjectsCreateError, + ThrowOnError + >({ + ...options, + url: '/Projects/Create', + }); +}; + +/** + * 更新项目 + */ +export const postProjectsUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostProjectsUpdateResponse, + PostProjectsUpdateError, + ThrowOnError + >({ + ...options, + url: '/Projects/Update', + }); +}; + +/** + * 删除项目 + */ +export const postProjectsDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostProjectsDeleteResponse, + PostProjectsDeleteError, + ThrowOnError + >({ + ...options, + url: '/Projects/Delete', + }); +}; + +/** + * 获取项目和实体信息 + */ +export const postProjectsGetProjectAndEntity = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostProjectsGetProjectAndEntityResponse, + PostProjectsGetProjectAndEntityError, + ThrowOnError + >({ + ...options, + url: '/Projects/GetProjectAndEntity', + }); +}; + +/** + * 获取所有角色 + */ +export const postRolesAll = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostRolesAllResponse, + PostRolesAllError, + ThrowOnError + >({ + ...options, + url: '/Roles/all', + }); +}; + +/** + * 分页获取角色 + */ +export const postRolesPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostRolesPageResponse, + PostRolesPageError, + ThrowOnError + >({ + ...options, + url: '/Roles/page', + }); +}; + +/** + * 创建角色 + */ +export const postRolesCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostRolesCreateResponse, + PostRolesCreateError, + ThrowOnError + >({ + ...options, + url: '/Roles/create', + }); +}; + +/** + * 更新角色 + */ +export const postRolesUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostRolesUpdateResponse, + PostRolesUpdateError, + ThrowOnError + >({ + ...options, + url: '/Roles/update', + }); +}; + +/** + * 删除角色 + */ +export const postRolesDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostRolesDeleteResponse, + PostRolesDeleteError, + ThrowOnError + >({ + ...options, + url: '/Roles/delete', + }); +}; + +/** + * 获取所有Setting + */ +export const postSettingsAll = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostSettingsAllResponse, + PostSettingsAllError, + ThrowOnError + >({ + ...options, + url: '/Settings/all', + }); +}; + +/** + * 更新Setting + */ +export const postSettingsUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostSettingsUpdateResponse, + PostSettingsUpdateError, + ThrowOnError + >({ + ...options, + url: '/Settings/update', + }); +}; + +/** + * 获取所有模板组 + */ +export const postTemplatesAll = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesAllResponse, + PostTemplatesAllError, + ThrowOnError + >({ + ...options, + url: '/Templates/All', + }); +}; + +/** + * 分页获取模板组 + */ +export const postTemplatesPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesPageResponse, + PostTemplatesPageError, + ThrowOnError + >({ + ...options, + url: '/Templates/Page', + }); +}; + +/** + * 创建模板组 + */ +export const postTemplatesCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesCreateResponse, + PostTemplatesCreateError, + ThrowOnError + >({ + ...options, + url: '/Templates/Create', + }); +}; + +/** + * 更新模板组 + */ +export const postTemplatesUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesUpdateResponse, + PostTemplatesUpdateError, + ThrowOnError + >({ + ...options, + url: '/Templates/Update', + }); +}; + +/** + * 删除模板组 + */ +export const postTemplatesDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesDeleteResponse, + PostTemplatesDeleteError, + ThrowOnError + >({ + ...options, + url: '/Templates/Delete', + }); +}; + +/** + * 创建模板 + */ +export const postTemplatesCreateDetail = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesCreateDetailResponse, + PostTemplatesCreateDetailError, + ThrowOnError + >({ + ...options, + url: '/Templates/CreateDetail', + }); +}; + +/** + * 编辑模板 + */ +export const postTemplatesUpdateDetail = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesUpdateDetailResponse, + PostTemplatesUpdateDetailError, + ThrowOnError + >({ + ...options, + url: '/Templates/UpdateDetail', + }); +}; + +/** + * 编辑模板 + */ +export const postTemplatesUpdateDetailContent = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesUpdateDetailContentResponse, + PostTemplatesUpdateDetailContentError, + ThrowOnError + >({ + ...options, + url: '/Templates/UpdateDetailContent', + }); +}; + +/** + * 删除模板 + */ +export const postTemplatesDeleteDetail = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesDeleteDetailResponse, + PostTemplatesDeleteDetailError, + ThrowOnError + >({ + ...options, + url: '/Templates/DeleteDetail', + }); +}; + +/** + * 获取模板树形结构 + */ +export const postTemplatesTree = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesTreeResponse, + PostTemplatesTreeError, + ThrowOnError + >({ + ...options, + url: '/Templates/Tree', + }); +}; + +/** + * 获取所有模板 + */ +export const postTemplatesList = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesListResponse, + PostTemplatesListError, + ThrowOnError + >({ + ...options, + url: '/Templates/List', + }); +}; + +/** + * 获取模板策略 + */ +export const postTemplatesControlType = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesControlTypeResponse, + PostTemplatesControlTypeError, + ThrowOnError + >({ + ...options, + url: '/Templates/ControlType', + }); +}; + +/** + * 获取模板类型 + */ +export const postTemplatesTemplateType = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesTemplateTypeResponse, + PostTemplatesTemplateTypeError, + ThrowOnError + >({ + ...options, + url: '/Templates/TemplateType', + }); +}; + +/** + * 复制模板 + */ +export const postTemplatesCopy = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTemplatesCopyResponse, + PostTemplatesCopyError, + ThrowOnError + >({ + ...options, + url: '/Templates/Copy', + }); +}; + +/** + * 通过名称获取租户信息 + */ +export const postTenantsFind = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTenantsFindResponse, + PostTenantsFindError, + ThrowOnError + >({ + ...options, + url: '/Tenants/find', + }); +}; + +/** + * 分页获取租户信息 + */ +export const postTenantsPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTenantsPageResponse, + PostTenantsPageError, + ThrowOnError + >({ + ...options, + url: '/Tenants/page', + }); +}; + +/** + * 创建租户 + */ +export const postTenantsCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTenantsCreateResponse, + PostTenantsCreateError, + ThrowOnError + >({ + ...options, + url: '/Tenants/create', + }); +}; + +/** + * 更新租户 + */ +export const postTenantsUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTenantsUpdateResponse, + PostTenantsUpdateError, + ThrowOnError + >({ + ...options, + url: '/Tenants/update', + }); +}; + +/** + * 删除租户 + */ +export const postTenantsDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTenantsDeleteResponse, + PostTenantsDeleteError, + ThrowOnError + >({ + ...options, + url: '/Tenants/delete', + }); +}; + +/** + * 分页租户连接字符串 + */ +export const postTenantsPageConnectionString = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTenantsPageConnectionStringResponse, + PostTenantsPageConnectionStringError, + ThrowOnError + >({ + ...options, + url: '/Tenants/pageConnectionString', + }); +}; + +/** + * 新增或者更新租户所有连接字符串 + */ +export const postTenantsAddOrUpdateConnectionString = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTenantsAddOrUpdateConnectionStringResponse, + PostTenantsAddOrUpdateConnectionStringError, + ThrowOnError + >({ + ...options, + url: '/Tenants/addOrUpdateConnectionString', + }); +}; + +/** + * 删除租户连接字符串 + */ +export const postTenantsDeleteConnectionString = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTenantsDeleteConnectionStringResponse, + PostTenantsDeleteConnectionStringError, + ThrowOnError + >({ + ...options, + url: '/Tenants/deleteConnectionString', + }); +}; + +/** + * 分页查询模板 + */ +export const postTextTemplatesPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTextTemplatesPageResponse, + PostTextTemplatesPageError, + ThrowOnError + >({ + ...options, + url: '/TextTemplates/Page', + }); +}; + +/** + * 创建模板 + */ +export const postTextTemplatesCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTextTemplatesCreateResponse, + PostTextTemplatesCreateError, + ThrowOnError + >({ + ...options, + url: '/TextTemplates/Create', + }); +}; + +/** + * 编辑模板 + */ +export const postTextTemplatesUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTextTemplatesUpdateResponse, + PostTextTemplatesUpdateError, + ThrowOnError + >({ + ...options, + url: '/TextTemplates/Update', + }); +}; + +/** + * 删除模板 + */ +export const postTextTemplatesDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTextTemplatesDeleteResponse, + PostTextTemplatesDeleteError, + ThrowOnError + >({ + ...options, + url: '/TextTemplates/Delete', + }); +}; + +/** + * 导出模板列表 + */ +export const postTextTemplatesExport = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostTextTemplatesExportResponse, + PostTextTemplatesExportError, + ThrowOnError + >({ + ...options, + url: '/TextTemplates/Export', + }); +}; + +/** + * 分页获取用户信息 + */ +export const postUsersPage = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersPageResponse, + PostUsersPageError, + ThrowOnError + >({ + ...options, + url: '/Users/page', + }); +}; + +/** + * 分页获取用户信息 + */ +export const postUsersList = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersListResponse, + PostUsersListError, + ThrowOnError + >({ + ...options, + url: '/Users/list', + }); +}; + +/** + * 导出用户列表 + */ +export const postUsersExport = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersExportResponse, + PostUsersExportError, + ThrowOnError + >({ + ...options, + url: '/Users/export', + }); +}; + +/** + * 创建用户 + */ +export const postUsersCreate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersCreateResponse, + PostUsersCreateError, + ThrowOnError + >({ + ...options, + url: '/Users/create', + }); +}; + +/** + * 编辑用户 + */ +export const postUsersUpdate = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersUpdateResponse, + PostUsersUpdateError, + ThrowOnError + >({ + ...options, + url: '/Users/update', + }); +}; + +/** + * 删除用户 + */ +export const postUsersDelete = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersDeleteResponse, + PostUsersDeleteError, + ThrowOnError + >({ + ...options, + url: '/Users/delete', + }); +}; + +/** + * 获取用户角色信息 + */ +export const postUsersRole = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersRoleResponse, + PostUsersRoleError, + ThrowOnError + >({ + ...options, + url: '/Users/role', + }); +}; + +/** + * 修改当前用户密码 + */ +export const postUsersChangePassword = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersChangePasswordResponse, + PostUsersChangePasswordError, + ThrowOnError + >({ + ...options, + url: '/Users/changePassword', + }); +}; + +/** + * 重置密码 + */ +export const postUsersResetPassword = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersResetPasswordResponse, + PostUsersResetPasswordError, + ThrowOnError + >({ + ...options, + url: '/Users/resetPassword', + }); +}; + +/** + * 锁定用户 + */ +export const postUsersLock = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersLockResponse, + PostUsersLockError, + ThrowOnError + >({ + ...options, + url: '/Users/lock', + }); +}; + +/** + * 通过用户名查找用户 + */ +export const postUsersFindByUserName = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersFindByUserNameResponse, + PostUsersFindByUserNameError, + ThrowOnError + >({ + ...options, + url: '/Users/findByUserName', + }); +}; + +/** + * 获取个人信息 + */ +export const postUsersMyProfile = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersMyProfileResponse, + PostUsersMyProfileError, + ThrowOnError + >({ + ...options, + url: '/Users/myProfile', + }); +}; + +/** + * 是否启用双因素验证 + */ +export const postUsersCanUseTwoFactor = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersCanUseTwoFactorResponse, + PostUsersCanUseTwoFactorError, + ThrowOnError + >({ + ...options, + url: '/Users/canUseTwoFactor', + }); +}; + +/** + * 获取双因素二维码 + */ +export const postUsersGetQrCode = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersGetQrCodeResponse, + PostUsersGetQrCodeError, + ThrowOnError + >({ + ...options, + url: '/Users/getQRCode', + }); +}; + +/** + * 开启双因素验证 + */ +export const postUsersEnabledTwoFactor = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersEnabledTwoFactorResponse, + PostUsersEnabledTwoFactorError, + ThrowOnError + >({ + ...options, + url: '/Users/enabledTwoFactor', + }); +}; + +/** + * 关闭双因素验证 + */ +export const postUsersDisabledTwoFactor = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersDisabledTwoFactorResponse, + PostUsersDisabledTwoFactorError, + ThrowOnError + >({ + ...options, + url: '/Users/disabledTwoFactor', + }); +}; + +/** + * 重置双因素验证 + */ +export const postUsersResetTwoFactor = ( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersResetTwoFactorResponse, + PostUsersResetTwoFactorError, + ThrowOnError + >({ + ...options, + url: '/Users/resetTwoFactor', + }); +}; + +/** + * 是否需要修改密码 + */ +export const postUsersNeedChangePassword = < + ThrowOnError extends boolean = false, +>( + options?: Options, +) => { + return (options?.client ?? client).post< + PostUsersNeedChangePasswordResponse, + PostUsersNeedChangePasswordError, + ThrowOnError + >({ + ...options, + url: '/Users/needChangePassword', + }); +}; diff --git a/apps/web-antd/src/api-client/types.gen.ts b/apps/web-antd/src/api-client/types.gen.ts new file mode 100644 index 0000000..2398064 --- /dev/null +++ b/apps/web-antd/src/api-client/types.gen.ts @@ -0,0 +1,5004 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type AbpLoginResult = { + readonly description?: null | string; + result?: LoginResultType; +}; + +export type AbpProApplicationConfigurationDto = { + multiTenancy?: MultiTenancyInfoDto; + oidcConfiguration?: ApplicationOidcConfigurationDto; +}; + +export type ActionApiDescriptionModel = { + allowAnonymous?: boolean | null; + httpMethod?: null | string; + implementFrom?: null | string; + name?: null | string; + parameters?: Array | null; + parametersOnMethod?: Array | null; + returnValue?: ReturnValueApiDescriptionModel; + supportedVersions?: Array | null; + uniqueName?: null | string; + url?: null | string; +}; + +export type AddOrUpdateConnectionStringInput = { + /** + * id + */ + id?: string; + /** + * 连接字符串名称 + */ + name?: null | string; + /** + * 连接字符串地址 + */ + value?: null | string; +}; + +export type AddRoleToOrganizationUnitInput = { + organizationUnitId?: string; + roleId?: Array | null; +}; + +export type AddUserToOrganizationUnitInput = { + organizationUnitId?: string; + userId?: Array | null; +}; + +export type AggregateRouteConfig = { + jsonPath?: null | string; + parameter?: null | string; + routeKey?: null | string; +}; + +export type ApplicationApiDescriptionModel = { + modules?: null | { + [key: string]: ModuleApiDescriptionModel; + }; + types?: null | { + [key: string]: TypeApiDescriptionModel; + }; +}; + +export type ApplicationAuthConfigurationDto = { + grantedPolicies?: null | { + [key: string]: boolean; + }; +}; + +export type ApplicationConfigurationDto = { + auth?: ApplicationAuthConfigurationDto; + clock?: ClockDto; + currentTenant?: CurrentTenantDto; + currentUser?: CurrentUserDto; + extraProperties?: null | { + [key: string]: unknown; + }; + features?: ApplicationFeatureConfigurationDto; + globalFeatures?: ApplicationGlobalFeatureConfigurationDto; + localization?: ApplicationLocalizationConfigurationDto; + multiTenancy?: MultiTenancyInfoDto; + objectExtensions?: ObjectExtensionsDto; + setting?: ApplicationSettingConfigurationDto; + timing?: TimingDto; +}; + +export type ApplicationFeatureConfigurationDto = { + values?: null | { + [key: string]: null | string; + }; +}; + +export type ApplicationGlobalFeatureConfigurationDto = { + enabledFeatures?: Array | null; +}; + +export type ApplicationLocalizationConfigurationDto = { + currentCulture?: CurrentCultureDto; + defaultResourceName?: null | string; + languageFilesMap?: null | { + [key: string]: Array; + }; + languages?: Array | null; + languagesMap?: null | { + [key: string]: Array; + }; + resources?: null | { + [key: string]: ApplicationLocalizationResourceDto; + }; + values?: null | { + [key: string]: { + [key: string]: string; + }; + }; +}; + +export type ApplicationLocalizationDto = { + currentCulture?: CurrentCultureDto; + resources?: null | { + [key: string]: ApplicationLocalizationResourceDto; + }; +}; + +export type ApplicationLocalizationResourceDto = { + baseResources?: Array | null; + texts?: null | { + [key: string]: string; + }; +}; + +export type ApplicationOidcConfigurationDto = { + /** + * 是否启用 + */ + enabled?: boolean; + oidcConfiguration?: Array | null; +}; + +export type ApplicationSettingConfigurationDto = { + values?: null | { + [key: string]: null | string; + }; +}; + +export type ChangePasswordInput = { + currentPassword?: null | string; + newPassword: string; +}; + +export type ClockDto = { + kind?: null | string; +}; + +export type ControllerApiDescriptionModel = { + actions?: null | { + [key: string]: ActionApiDescriptionModel; + }; + apiVersion?: null | string; + controllerGroupName?: null | string; + controllerName?: null | string; + interfaces?: Array | null; + isIntegrationService?: boolean; + isRemoteService?: boolean; + type?: null | string; +}; + +export type ControllerInterfaceApiDescriptionModel = { + methods?: Array | null; + name?: null | string; + type?: null | string; +}; + +/** + * 控制策略 + */ +export type ControlType = 10 | 20 | 30 | 40; + +export type CopyTemplateInput = { + id?: string; + /** + * 名称 + */ + name?: null | string; + /** + * 备注 + */ + remark?: null | string; +}; + +export type CreateAggregateInput = { + /** + * 编码 + */ + code: string; + /** + * 描述 + */ + description: string; + projectId?: string; +}; + +export type CreateDataDictinaryDetailInput = { + code?: null | string; + description?: null | string; + displayText?: null | string; + id?: string; + order?: number; +}; + +export type CreateDataDictinaryInput = { + code?: null | string; + description?: null | string; + displayText?: null | string; +}; + +export type CreateEntityModelInput = { + /** + * 编码 + */ + code: string; + /** + * 描述 + */ + description: string; + id?: string; + relationalType?: RelationalType; +}; + +export type CreateEntityModelPropertyInput = { + /** + * 允许添加 + */ + allowAdd?: boolean; + /** + * 允许编辑 + */ + allowEdit?: boolean; + /** + * 允许作为查询条件 + */ + allowSearch?: boolean; + /** + * 编码 + */ + code: string; + /** + * 数据类型Id + */ + dataTypeId?: null | string; + /** + * 当类型为decimal时的小数位数 (18,4) 中的18 + */ + decimalPrecision?: null | number; + /** + * 当类型为decimal时的字段长度 (18,4) 中的4 + */ + decimalScale?: null | number; + /** + * 描述 + */ + description: string; + /** + * 枚举类型Id + */ + enumTypeId?: null | string; + /** + * 实体模型Id + */ + id?: string; + /** + * 必填 + */ + isRequired?: boolean; + /** + * 字符串最大长度 + */ + maxLength?: null | number; + /** + * 字符串最小长度 + */ + minLength?: null | number; +}; + +export type CreateEnumTypeInput = { + /** + * 编码 + */ + code: string; + /** + * 描述 + */ + description: string; + /** + * 实体模型Id + */ + entityModelId?: string; + projectId?: string; +}; + +export type CreateEnumTypePropertyInput = { + /** + * 编码 + */ + code: string; + /** + * 描述 + */ + description: string; + /** + * Id + */ + enumTypeId?: string; + /** + * 枚举值 + */ + value?: number; +}; + +/** + * 创建语言 + */ +export type CreateLanguageInput = { + /** + * 语言名称 + */ + cultureName?: null | string; + /** + * 显示名称 + */ + displayName?: null | string; + /** + * 图标 + */ + flagIcon?: null | string; + /** + * 是否启用 + */ + isEnabled?: boolean; + /** + * Ui语言名称 + */ + uiCultureName?: null | string; +}; + +/** + * 创建语言文本 + */ +export type CreateLanguageTextInput = { + /** + * 语言名称 + */ + cultureName?: null | string; + /** + * 名称 + */ + name?: null | string; + /** + * 资源名称 + */ + resourceName?: null | string; + /** + * 值 + */ + value?: null | string; +}; + +/** + * 创建菜单 + */ +export type CreateMenuInput = { + /** + * 组件地址 + */ + component?: null | string; + /** + * 标题 + */ + displayTitle?: null | string; + /** + * 是否启用 + */ + enabled?: boolean; + /** + * 是否显示 + */ + hideInMenu: boolean; + /** + * 图标 + */ + icon?: null | string; + /** + * 是否缓存 + */ + keepAlive: boolean; + menuType?: MenuType; + /** + * 唯一编码 + */ + name: string; + openType?: OpenType; + /** + * 排序 + */ + order: number; + parentId?: null | string; + /** + * 路由地址 + */ + path: string; + /** + * 权限 + */ + policy?: null | string; + /** + * 标题 + */ + title: string; + /** + * 内外链地址 + */ + url?: null | string; +}; + +export type CreateOrganizationUnitInput = { + displayName?: null | string; + parentId?: null | string; +}; + +export type CreateProjectInput = { + /** + * 公司名称 + */ + companyName?: null | string; + /** + * 负责人 + */ + owner?: null | string; + /** + * 项目名称 + */ + projectName?: null | string; + /** + * 备注 + */ + remark?: null | string; + /** + * 是否支持多租户 + */ + supportTenant?: boolean; +}; + +export type CreateTemplateDetailInput = { + /** + * 模板内容 + */ + content?: null | string; + controlType?: ControlType; + /** + * 描述 + */ + description?: null | string; + /** + * 模板类型 + */ + name?: null | string; + parentId?: null | string; + /** + * 模板id + */ + templateId?: string; + templateType?: TemplateType; +}; + +export type CreateTemplateInput = { + /** + * 名称 + */ + name?: null | string; + /** + * 备注 + */ + remark?: null | string; +}; + +/** + * 创建模板 + */ +export type CreateTextTemplateInput = { + /** + * 编码 + */ + code: string; + /** + * 内容 + */ + content: string; + /** + * 语言 + */ + cultureName: string; + /** + * 名称 + */ + name: string; +}; + +export type CurrentCultureDto = { + cultureName?: null | string; + dateTimeFormat?: DateTimeFormatDto; + displayName?: null | string; + englishName?: null | string; + isRightToLeft?: boolean; + name?: null | string; + nativeName?: null | string; + threeLetterIsoLanguageName?: null | string; + twoLetterIsoLanguageName?: null | string; +}; + +export type CurrentTenantDto = { + id?: null | string; + isAvailable?: boolean; + name?: null | string; +}; + +export type CurrentUserDto = { + email?: null | string; + emailVerified?: boolean; + id?: null | string; + impersonatorTenantId?: null | string; + impersonatorTenantName?: null | string; + impersonatorUserId?: null | string; + impersonatorUserName?: null | string; + isAuthenticated?: boolean; + name?: null | string; + phoneNumber?: null | string; + phoneNumberVerified?: boolean; + roles?: Array | null; + sessionId?: null | string; + surName?: null | string; + tenantId?: null | string; + userName?: null | string; +}; + +export type DataTypeDto = { + /** + * 编码 + */ + code?: null | string; + /** + * 描述 + */ + description?: null | string; + id?: string; + /** + * 是否是枚举 + */ + isEnum?: boolean; +}; + +export type DateTimeFormatDto = { + calendarAlgorithmType?: null | string; + dateSeparator?: null | string; + dateTimeFormatLong?: null | string; + fullDateTimePattern?: null | string; + longTimePattern?: null | string; + shortDatePattern?: null | string; + shortTimePattern?: null | string; +}; + +export type DeleteAggregateInput = { + id?: string; +}; + +export type DeleteConnectionStringInput = { + /** + * 连接字符串名称 + */ + name?: null | string; + /** + * 租户id + */ + tenantId?: string; +}; + +export type DeleteDataDictionaryDetailInput = { + dataDictionaryId?: string; + dataDictionayDetailId?: string; +}; + +export type DeleteEntityModelInput = { + aggregateId?: string; + id?: string; +}; + +export type DeleteEntityModelPropertyInput = { + id?: string; + propertyId?: string; +}; + +export type DeleteEnumTypeInput = { + entityModelId?: string; + /** + * Id + */ + id?: string; +}; + +export type DeleteEnumTypePropertyInput = { + /** + * Id + */ + enumTypeId?: string; + /** + * Id + */ + id?: string; +}; + +export type DeleteFeatureInput = { + providerKey?: null | string; + providerName?: null | string; +}; + +/** + * 删除文件 + */ +export type DeleteFileObjectInput = { + /** + * 文件Id + */ + id?: string; +}; + +/** + * 删除语言 + */ +export type DeleteLanguageInput = { + /** + * 语言Id + */ + id?: string; +}; + +/** + * 删除菜单 + */ +export type DeleteMenuInput = { + /** + * 菜单Id + */ + id?: string; +}; + +export type DeleteMessageInput = { + id?: string; + /** + * 接受者Id + */ + receiverUserId?: null | string; +}; + +export type DeleteProjectInput = { + id?: string; +}; + +export type DeleteTemplateDetailInput = { + templateDetailId?: string; + templateId?: string; +}; + +export type DeleteTemplateInput = { + id?: string; +}; + +/** + * 删除模板 + */ +export type DeleteTextTemplateInput = { + /** + * 模板Id + */ + id?: string; +}; + +export type DisabledTwoFactorInput = { + /** + * 验证码 + */ + code: string; +}; + +export type DownCodeInput = { + entityId?: Array | null; + projectId?: string; + templateId?: string; +}; + +export type DownloadFileObjectInput = { + /** + * 文件Id + */ + id?: string; +}; + +export type EnabledTwoFactorInput = { + /** + * 验证码 + */ + code: string; + /** + * 密钥 + */ + secret: string; +}; + +export type EntityChangeType = 0 | 1 | 2; + +export type EntityExtensionDto = { + configuration?: null | { + [key: string]: unknown; + }; + properties?: null | { + [key: string]: ExtensionPropertyDto; + }; +}; + +export type EntityOutput = { + /** + * 编码 + */ + code?: null | string; + /** + * 首字母小写 + */ + readonly codeCamelCase?: null | string; + /** + * 复数形式 + */ + readonly codePluralized?: null | string; + /** + * 描述 + */ + description?: null | string; + id?: string; +}; + +export type ExtensionEnumDto = { + fields?: Array | null; + localizationResource?: null | string; +}; + +export type ExtensionEnumFieldDto = { + name?: null | string; + value?: unknown; +}; + +export type ExtensionPropertyApiCreateDto = { + isAvailable?: boolean; +}; + +export type ExtensionPropertyApiDto = { + onCreate?: ExtensionPropertyApiCreateDto; + onGet?: ExtensionPropertyApiGetDto; + onUpdate?: ExtensionPropertyApiUpdateDto; +}; + +export type ExtensionPropertyApiGetDto = { + isAvailable?: boolean; +}; + +export type ExtensionPropertyApiUpdateDto = { + isAvailable?: boolean; +}; + +export type ExtensionPropertyAttributeDto = { + config?: null | { + [key: string]: unknown; + }; + typeSimple?: null | string; +}; + +export type ExtensionPropertyDto = { + api?: ExtensionPropertyApiDto; + attributes?: Array | null; + configuration?: null | { + [key: string]: unknown; + }; + defaultValue?: unknown; + displayName?: LocalizableStringDto; + policy?: ExtensionPropertyPolicyDto; + type?: null | string; + typeSimple?: null | string; + ui?: ExtensionPropertyUiDto; +}; + +export type ExtensionPropertyFeaturePolicyDto = { + features?: Array | null; + requiresAll?: boolean; +}; + +export type ExtensionPropertyGlobalFeaturePolicyDto = { + features?: Array | null; + requiresAll?: boolean; +}; + +export type ExtensionPropertyPermissionPolicyDto = { + permissionNames?: Array | null; + requiresAll?: boolean; +}; + +export type ExtensionPropertyPolicyDto = { + features?: ExtensionPropertyFeaturePolicyDto; + globalFeatures?: ExtensionPropertyGlobalFeaturePolicyDto; + permissions?: ExtensionPropertyPermissionPolicyDto; +}; + +export type ExtensionPropertyUiDto = { + lookup?: ExtensionPropertyUiLookupDto; + onCreateForm?: ExtensionPropertyUiFormDto; + onEditForm?: ExtensionPropertyUiFormDto; + onTable?: ExtensionPropertyUiTableDto; +}; + +export type ExtensionPropertyUiFormDto = { + isVisible?: boolean; +}; + +export type ExtensionPropertyUiLookupDto = { + displayPropertyName?: null | string; + filterParamName?: null | string; + resultListPropertyName?: null | string; + url?: null | string; + valuePropertyName?: null | string; +}; + +export type ExtensionPropertyUiTableDto = { + isVisible?: boolean; +}; + +export type FeatureDto = { + depth?: number; + description?: null | string; + displayName?: null | string; + name?: null | string; + parentName?: null | string; + provider?: FeatureProviderDto; + value?: null | string; + valueType?: IStringValueType; +}; + +export type FeatureGroupDto = { + displayName?: null | string; + features?: Array | null; + name?: null | string; +}; + +export type FeatureProviderDto = { + key?: null | string; + name?: null | string; +}; + +export type FileAggregateRoute = { + aggregator?: null | string; + priority?: number; + routeIsCaseSensitive?: boolean; + routeKeys?: Array | null; + routeKeysConfig?: Array | null; + upstreamHost?: null | string; + readonly upstreamHttpMethod?: Array | null; + upstreamPathTemplate?: null | string; +}; + +export type FileAuthenticationOptions = { + allowedScopes?: Array | null; + authenticationProviderKey?: null | string; +}; + +export type FileCacheOptions = { + region?: null | string; + ttlSeconds?: number; +}; + +export type FileConfiguration = { + aggregates?: Array | null; + dynamicRoutes?: Array | null; + globalConfiguration?: FileGlobalConfiguration; + routes?: Array | null; +}; + +export type FileDynamicRoute = { + downstreamHttpVersion?: null | string; + rateLimitRule?: FileRateLimitRule; + serviceName?: null | string; +}; + +export type FileGlobalConfiguration = { + baseUrl?: null | string; + downstreamHttpVersion?: null | string; + downstreamScheme?: null | string; + httpHandlerOptions?: FileHttpHandlerOptions; + loadBalancerOptions?: FileLoadBalancerOptions; + qoSOptions?: FileQoSOptions; + rateLimitOptions?: FileRateLimitOptions; + requestIdKey?: null | string; + serviceDiscoveryProvider?: FileServiceDiscoveryProvider; +}; + +export type FileHostAndPort = { + host?: null | string; + port?: number; +}; + +export type FileHttpHandlerOptions = { + allowAutoRedirect?: boolean; + maxConnectionsPerServer?: number; + useCookieContainer?: boolean; + useProxy?: boolean; + useTracing?: boolean; +}; + +export type FileLoadBalancerOptions = { + expiry?: number; + key?: null | string; + type?: null | string; +}; + +export type FileQoSOptions = { + durationOfBreak?: number; + exceptionsAllowedBeforeBreaking?: number; + timeoutValue?: number; +}; + +export type FileRateLimitOptions = { + clientIdHeader?: null | string; + disableRateLimitHeaders?: boolean; + httpStatusCode?: number; + quotaExceededMessage?: null | string; + rateLimitCounterPrefix?: null | string; +}; + +export type FileRateLimitRule = { + clientWhitelist?: Array | null; + enableRateLimiting?: boolean; + limit?: number; + period?: null | string; + periodTimespan?: number; +}; + +export type FileRoute = { + addClaimsToRequest?: null | { + [key: string]: null | string; + }; + addHeadersToRequest?: null | { + [key: string]: null | string; + }; + addQueriesToRequest?: null | { + [key: string]: null | string; + }; + authenticationOptions?: FileAuthenticationOptions; + changeDownstreamPathTemplate?: null | { + [key: string]: null | string; + }; + dangerousAcceptAnyServerCertificateValidator?: boolean; + delegatingHandlers?: Array | null; + downstreamHeaderTransform?: null | { + [key: string]: null | string; + }; + downstreamHostAndPorts?: Array | null; + downstreamHttpMethod?: null | string; + downstreamHttpVersion?: null | string; + downstreamPathTemplate?: null | string; + downstreamScheme?: null | string; + fileCacheOptions?: FileCacheOptions; + httpHandlerOptions?: FileHttpHandlerOptions; + key?: null | string; + loadBalancerOptions?: FileLoadBalancerOptions; + priority?: number; + qoSOptions?: FileQoSOptions; + rateLimitOptions?: FileRateLimitRule; + requestIdKey?: null | string; + routeClaimsRequirement?: null | { + [key: string]: null | string; + }; + routeIsCaseSensitive?: boolean; + securityOptions?: FileSecurityOptions; + serviceName?: null | string; + serviceNamespace?: null | string; + timeout?: number; + upstreamHeaderTransform?: null | { + [key: string]: null | string; + }; + upstreamHost?: null | string; + upstreamHttpMethod?: Array | null; + upstreamPathTemplate?: null | string; +}; + +export type FileSecurityOptions = { + ipAllowedList?: Array | null; + ipBlockedList?: Array | null; +}; + +export type FileServiceDiscoveryProvider = { + configurationKey?: null | string; + host?: null | string; + namespace?: null | string; + pollingInterval?: number; + port?: number; + scheme?: null | string; + token?: null | string; + type?: null | string; +}; + +export type FindByUserNameInput = { + userName?: null | string; +}; + +export type FindTenantByNameInput = { + name?: null | string; +}; + +export type FindTenantResultDto = { + isActive?: boolean; + name?: null | string; + normalizedName?: null | string; + success?: boolean; + tenantId?: null | string; +}; + +export type GetDataTypeInput = { + entityModelId?: string; +}; + +export type GetDataTypeOutput = { + /** + * 枚举编码 + */ + code?: null | string; + /** + * 枚举描述 + */ + description?: null | string; + id?: string; +}; + +export type GetEntityModelInput = { + id?: string; +}; + +export type GetEntityModelOutput = { + /** + * 编码 + */ + code?: null | string; + /** + * 描述 + */ + description?: null | string; + entityModelOutputs?: Array | null; + /** + * 实体模型属性集合 + */ + entityModelProperties?: Array | null; + id?: string; + relationalType?: RelationalType; +}; + +export type GetEntityModelPropertyOutput = { + /** + * 名称 + */ + code?: null | string; + /** + * 数据类型Id + */ + dataTypeId?: null | string; + dataTypeOutput?: GetDataTypeOutput; + /** + * 当类型为decimal时的小数位数 (18,4) 中的18 + */ + decimalPrecision?: null | number; + /** + * 当类型为decimal时的字段长度 (18,4) 中的4 + */ + decimalScale?: null | number; + /** + * 描述 + */ + description?: null | string; + /** + * 实体模型Id + */ + entityModelId?: string; + /** + * 枚举类型Id + */ + enumTypeId?: null | string; + enumTypeOutput?: GetEnumTypeOutput; + id?: string; + isEnum?: boolean; + /** + * 必填 + */ + isRequired?: boolean; + /** + * 字符串最大长度 + */ + maxLength?: null | number; + /** + * 字符串最小长度 + */ + minLength?: null | number; +}; + +export type GetEntityModelTreeInput = { + projectId?: string; +}; + +export type GetEntityModelTreeOutput = { + children?: Array | null; + /** + * 描述 + */ + code?: null | string; + /** + * 描述 + */ + description?: null | string; + /** + * 图标 + */ + icon?: null | string; + /** + * 模板id + */ + key?: string; + /** + * 父类Id + */ + parentId?: null | string; + relationalType?: RelationalType; + /** + * 描述 + */ + title?: null | string; +}; + +export type GetEnumTypeOutput = { + /** + * 枚举编码 + */ + code?: null | string; + /** + * 枚举描述 + */ + description?: null | string; + id?: string; +}; + +export type GetFeatureListResultDto = { + groups?: Array | null; +}; + +export type GetFeatureListResultInput = { + providerKey?: null | string; + providerName?: null | string; +}; + +export type GetMenuTreeMetaOutput = { + displayTitle?: null | string; + /** + * 是否显示 + */ + hideInMenu?: boolean; + /** + * 图标 + */ + icon?: null | string; + /** + * 内链地址 + */ + iframeSrc?: null | string; + /** + * 是否缓存 + */ + keepAlive?: boolean; + /** + * 外链地址 + */ + link?: null | string; + /** + * 排序 + */ + order?: number; + title?: null | string; +}; + +export type GetMenuTreeOutput = { + children?: Array | null; + component?: null | string; + enabled?: boolean; + id?: string; + meta?: GetMenuTreeMetaOutput; + /** + * 名称 + */ + name?: null | string; + parentId?: null | string; + path?: null | string; +}; + +export type GetOrganizationUnitRoleInput = { + organizationUnitId?: string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type GetOrganizationUnitRoleOutput = { + id?: string; + name?: null | string; +}; + +export type GetOrganizationUnitRoleOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type GetOrganizationUnitUserInput = { + filter?: null | string; + organizationUnitId?: string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type GetOrganizationUnitUserOutput = { + email?: null | string; + id?: string; + userName?: null | string; +}; + +export type GetOrganizationUnitUserOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type GetPermissionInput = { + providerKey?: null | string; + providerName?: null | string; +}; + +export type GetProjectAndEntityInput = { + id?: string; +}; + +export type GetProjectAndEntityOutput = { + entities?: Array | null; + project?: ProjectOutput; +}; + +export type GetQRCodeOutput = { + /** + * base64 二维码 + */ + qrCode?: null | string; + /** + * 密钥 + */ + secret?: null | string; +}; + +export type GetTemplateTreeOutput = { + children?: Array | null; + /** + * 模板内容 + */ + content?: null | string; + controlType?: ControlType; + /** + * 描述 + */ + description?: null | string; + /** + * 图标 + */ + icon?: null | string; + /** + * 模板id + */ + key?: string; + /** + * 模板名称 + */ + name?: null | string; + templateType?: TemplateType; + /** + * 描述 + */ + title?: null | string; +}; + +export type GetTemplteTreeInput = { + templateId?: string; +}; + +export type GetUnAddRoleInput = { + filter?: null | string; + organizationUnitId?: string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type GetUnAddRoleOutput = { + id?: string; + name?: null | string; +}; + +export type GetUnAddRoleOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type GetUnAddUserInput = { + filter?: null | string; + organizationUnitId?: string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type GetUnAddUserOutput = { + email?: null | string; + id?: string; + userName?: null | string; +}; + +export type GetUnAddUserOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type HttpStatusCode = + | 100 + | 101 + | 102 + | 103 + | 200 + | 201 + | 202 + | 203 + | 204 + | 205 + | 206 + | 207 + | 208 + | 226 + | 300 + | 301 + | 302 + | 303 + | 304 + | 305 + | 306 + | 307 + | 308 + | 400 + | 401 + | 402 + | 403 + | 404 + | 405 + | 406 + | 407 + | 408 + | 409 + | 410 + | 411 + | 412 + | 413 + | 414 + | 415 + | 416 + | 417 + | 421 + | 422 + | 423 + | 424 + | 426 + | 428 + | 429 + | 431 + | 451 + | 500 + | 501 + | 502 + | 503 + | 504 + | 505 + | 506 + | 507 + | 508 + | 510 + | 511; + +export type IanaTimeZone = { + timeZoneName?: null | string; +}; + +export type IdentityRoleCreateDto = { + readonly extraProperties?: null | { + [key: string]: unknown; + }; + isDefault?: boolean; + isPublic?: boolean; + name: string; +}; + +export type IdentityRoleDto = { + concurrencyStamp?: null | string; + creationTime?: string; + readonly extraProperties?: null | { + [key: string]: unknown; + }; + id?: string; + isDefault?: boolean; + isPublic?: boolean; + isStatic?: boolean; + name?: null | string; +}; + +export type IdentityRoleDtoListResultDto = { + items?: Array | null; +}; + +export type IdentityRoleDtoPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type IdentityRoleUpdateDto = { + concurrencyStamp?: null | string; + readonly extraProperties?: null | { + [key: string]: unknown; + }; + isDefault?: boolean; + isPublic?: boolean; + name: string; +}; + +export type IdentityUserCreateDto = { + email: string; + readonly extraProperties?: null | { + [key: string]: unknown; + }; + isActive?: boolean; + lockoutEnabled?: boolean; + name?: null | string; + password: string; + phoneNumber?: null | string; + roleNames?: Array | null; + surname?: null | string; + userName: string; +}; + +export type IdentityUserDto = { + accessFailedCount?: number; + concurrencyStamp?: null | string; + creationTime?: string; + creatorId?: null | string; + deleterId?: null | string; + deletionTime?: null | string; + email?: null | string; + emailConfirmed?: boolean; + entityVersion?: number; + readonly extraProperties?: null | { + [key: string]: unknown; + }; + id?: string; + isActive?: boolean; + isDeleted?: boolean; + lastModificationTime?: null | string; + lastModifierId?: null | string; + lastPasswordChangeTime?: null | string; + lockoutEnabled?: boolean; + lockoutEnd?: null | string; + name?: null | string; + phoneNumber?: null | string; + phoneNumberConfirmed?: boolean; + surname?: null | string; + tenantId?: null | string; + userName?: null | string; +}; + +export type IdentityUserUpdateDto = { + concurrencyStamp?: null | string; + email: string; + readonly extraProperties?: null | { + [key: string]: unknown; + }; + isActive?: boolean; + lockoutEnabled?: boolean; + name?: null | string; + password?: null | string; + phoneNumber?: null | string; + roleNames?: Array | null; + surname?: null | string; + userName: string; +}; + +export type IdInput = { + id?: string; +}; + +export type InterfaceMethodApiDescriptionModel = { + name?: null | string; + parametersOnMethod?: Array | null; + returnValue?: ReturnValueApiDescriptionModel; +}; + +export type IStringValueType = { + readonly name?: null | string; + readonly properties?: null | { + [key: string]: unknown; + }; + validator?: IValueValidator; +}; + +export type IValueValidator = { + readonly name?: null | string; + readonly properties?: null | { + [key: string]: unknown; + }; +}; + +export type LanguageInfo = { + cultureName?: null | string; + displayName?: null | string; + readonly twoLetterISOLanguageName?: null | string; + uiCultureName?: null | string; +}; + +export type LocalizableStringDto = { + name?: null | string; + resource?: null | string; +}; + +export type LockUserInput = { + locked?: boolean; + userId?: string; +}; + +/** + * 登录 + */ +export type Login2FAInput = { + /** + * 双因素验证码 + */ + code?: null | string; + /** + * 用户名或者邮箱 + */ + name?: null | string; + /** + * 密码 + */ + password?: null | string; +}; + +/** + * 登录 + */ +export type LoginInput = { + /** + * 用户名或者邮箱 + */ + name?: null | string; + /** + * 密码 + */ + password?: null | string; +}; + +/** + * 登录 + */ +export type LoginOidcInput = { + /** + * code + */ + code: string; + /** + * Provider + */ + state: string; +}; + +export type LoginOutput = { + id?: string; + name?: null | string; + refreshToken?: null | string; + roles?: Array | null; + token?: null | string; + userName?: null | string; +}; + +export type LoginResultType = 1 | 2 | 3 | 4 | 5; + +/** + * 菜单类型 + */ +export type MenuType = 10 | 20; + +/** + * 消息等级 + */ +export type MessageLevel = 10 | 20 | 30; + +/** + * 消息类型 + */ +export type MessageType = 10 | 20; + +export type MethodParameterApiDescriptionModel = { + defaultValue?: unknown; + isOptional?: boolean; + name?: null | string; + type?: null | string; + typeAsString?: null | string; + typeSimple?: null | string; +}; + +export type ModuleApiDescriptionModel = { + controllers?: null | { + [key: string]: ControllerApiDescriptionModel; + }; + remoteServiceName?: null | string; + rootPath?: null | string; +}; + +export type ModuleExtensionDto = { + configuration?: null | { + [key: string]: unknown; + }; + entities?: null | { + [key: string]: EntityExtensionDto; + }; +}; + +export type MultiTenancyInfoDto = { + isEnabled?: boolean; +}; + +export type MyProfileOutput = { + email?: null | string; + isActive?: boolean; + name?: null | string; + phoneNumber?: null | string; + surname?: null | string; + tenantId?: null | string; + twoFactorEnabled?: boolean; + userName?: null | string; +}; + +export type NameValue = { + name?: null | string; + value?: null | string; +}; + +export type NeedChangePasswordOutput = { + message?: null | string; + needChangePassword?: boolean; +}; + +export type ObjectExtensionsDto = { + enums?: null | { + [key: string]: ExtensionEnumDto; + }; + modules?: null | { + [key: string]: ModuleExtensionDto; + }; +}; + +export type OidcConfiguration = { + /** + * 认证地址 + */ + authUri?: null | string; + /** + * client_id + */ + clientId?: null | string; + /** + * 应用名称 + */ + clientName?: null | string; + /** + * 是否启用 + */ + enabled?: boolean; + /** + * 应用图标 + */ + icon?: null | string; + /** + * 类型 + */ + type?: null | string; +}; + +/** + * 打开类型 + */ +export type OpenType = 10 | 20 | 30 | 40; + +export type PageEntityModelInput = { + filter?: null | string; + id?: string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type PageEntityModelPropertyOutput = { + /** + * 允许添加 + */ + allowAdd?: boolean; + /** + * 允许编辑 + */ + allowEdit?: boolean; + /** + * 允许作为查询条件 + */ + allowSearch?: boolean; + /** + * 名称 + */ + code?: null | string; + dataTypeCode?: null | string; + dataTypeDescription?: null | string; + dataTypeId?: string; + /** + * 当类型为decimal时的小数位数 (18,4) 中的18 + */ + decimalPrecision?: null | number; + /** + * 当类型为decimal时的字段长度 (18,4) 中的4 + */ + decimalScale?: null | number; + /** + * 描述 + */ + description?: null | string; + /** + * 实体模型Id + */ + entityModelId?: string; + id?: null | string; + isEnum?: boolean; + /** + * 必填 + */ + isRequired?: boolean; + /** + * 字符串最大长度 + */ + maxLength?: null | number; + /** + * 字符串最小长度 + */ + minLength?: null | number; +}; + +export type PageEntityModelPropertyOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PageEnumTypeInput = { + filter?: null | string; + id?: string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type PageEnumTypeOutput = { + /** + * 名称 + */ + code?: null | string; + creationTime?: string; + /** + * 描述 + */ + description?: null | string; + /** + * 实体模型Id + */ + entityModelId?: string; + id?: null | string; +}; + +export type PageEnumTypeOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PageEnumTypePropertyInput = { + filter?: null | string; + id?: string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type PageEnumTypePropertyOutput = { + /** + * 名称 + */ + code?: null | string; + creationTime?: string; + /** + * 描述 + */ + description?: null | string; + id?: null | string; + /** + * 名称 + */ + value?: number; +}; + +export type PageEnumTypePropertyOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +/** + * 分页查询文件 + */ +export type PageFileObjectInput = { + /** + * 结束创建时间 + */ + endCreationTime?: null | string; + /** + * 文件名称 + */ + fileName?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; + /** + * 开始创建时间 + */ + startCreationTime?: null | string; +}; + +/** + * 分页查询文件 + */ +export type PageFileObjectOutput = { + readonly beautifySize?: null | string; + /** + * 文件名称 + */ + contentType?: null | string; + /** + * 创建时间 + */ + creationTime?: string; + /** + * 文件名称 + */ + fileName?: null | string; + /** + * 文件大小 + */ + fileSize?: number; + /** + * 文件Id + */ + id?: string; +}; + +export type PageFileObjectOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PageIdentityUserOutput = { + accessFailedCount?: number; + concurrencyStamp?: null | string; + creationTime?: string; + creatorId?: null | string; + deleterId?: null | string; + deletionTime?: null | string; + email?: null | string; + emailConfirmed?: boolean; + entityVersion?: number; + readonly extraProperties?: null | { + [key: string]: unknown; + }; + id?: string; + isActive?: boolean; + isDeleted?: boolean; + lastModificationTime?: null | string; + lastModifierId?: null | string; + lastPasswordChangeTime?: null | string; + lockoutEnabled?: boolean; + lockoutEnd?: null | string; + name?: null | string; + phoneNumber?: null | string; + phoneNumberConfirmed?: boolean; + surname?: null | string; + tenantId?: null | string; + /** + * 是否开启双因素验证码 + */ + twoFactorEnabled?: boolean; + userName?: null | string; +}; + +export type PageIdentityUserOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +/** + * 创建语言 + */ +export type PageLanguageInput = { + filter?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +/** + * 创建语言 + */ +export type PageLanguageOutput = { + /** + * 创建时间 + */ + creationTime?: string; + /** + * 语言名称 + */ + cultureName?: null | string; + /** + * 显示名称 + */ + displayName?: null | string; + /** + * 图标 + */ + flagIcon?: null | string; + /** + * 语言Id + */ + id?: string; + /** + * 是否是默认语言 + */ + isDefault?: boolean; + /** + * 是否启用 + */ + isEnabled?: boolean; + /** + * Ui语言名称 + */ + uiCultureName?: null | string; +}; + +export type PageLanguageOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +/** + * 创建语言文本 + */ +export type PageLanguageTextInput = { + /** + * 语言 + */ + cultureName?: null | string; + /** + * 查询条件 name or value + */ + filter?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 资源 + */ + resourceName?: null | string; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +/** + * 创建语言文本 + */ +export type PageLanguageTextOutput = { + /** + * 名称 + */ + name?: null | string; + /** + * 资源名称 + */ + resourceName?: null | string; + /** + * 值 + */ + value?: null | string; +}; + +export type PageLanguageTextOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +/** + * 分页查询菜单 + */ +export type PageMenuInput = { + /** + * 结束创建时间 + */ + endCreationTime?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; + /** + * 开始创建时间 + */ + startCreationTime?: null | string; +}; + +/** + * 分页查询菜单 + */ +export type PageMenuOutput = { + /** + * 组件地址 + */ + component?: null | string; + /** + * 创建时间 + */ + creationTime?: string; + /** + * 标题 + */ + displayTitle?: null | string; + /** + * 是否启用 + */ + enabled?: boolean; + /** + * 是否显示 + */ + hideInMenu?: boolean; + /** + * 图标 + */ + icon?: null | string; + /** + * 菜单Id + */ + id?: string; + /** + * 是否缓存 + */ + keepAlive?: boolean; + /** + * 标题 + */ + localizationTitle?: null | string; + menuType?: MenuType; + readonly menuTypeDescription?: null | string; + /** + * 唯一编码 + */ + name?: null | string; + openType?: OpenType; + readonly openTypeDescription?: null | string; + /** + * 排序 + */ + order?: number; + parentId?: null | string; + /** + * 路由/接口地址 + */ + path?: null | string; + /** + * 权限 + */ + policy?: null | string; + /** + * 标题 + */ + title?: null | string; + /** + * 内外链地址 + */ + url?: null | string; +}; + +export type PageMenuOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PageProjectInput = { + filter?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type PageTemplateInput = { + filter?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type PageTenantConnectionStringInput = { + /** + * 租户id + */ + id?: string; + /** + * 连接字符串名称 + */ + name?: null | string; + /** + * 连接字符串地址 + */ + value?: null | string; +}; + +export type PageTenantConnectionStringOutput = { + /** + * 连接字符串名称 + */ + name?: null | string; + /** + * 租户id + */ + tenantId?: string; + /** + * 连接字符串地址 + */ + value?: null | string; +}; + +export type PageTenantConnectionStringOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +/** + * 分页查询模板 + */ +export type PageTextTemplateInput = { + /** + * 编码 + */ + code?: null | string; + /** + * 内容 + */ + content?: null | string; + /** + * 结束创建时间 + */ + endCreationTime?: null | string; + /** + * 名称 + */ + name?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; + /** + * 开始创建时间 + */ + startCreationTime?: null | string; +}; + +/** + * 分页查询模板 + */ +export type PageTextTemplateOutput = { + /** + * 编码 + */ + code?: null | string; + /** + * 内容 + */ + content?: null | string; + /** + * 创建时间 + */ + creationTime?: string; + /** + * 语言 + */ + cultureName?: null | string; + /** + * 模板Id + */ + id?: string; + /** + * 名称 + */ + name?: null | string; +}; + +export type PageTextTemplateOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PagingAuditLogActionOutput = { + auditLogId?: string; + executionDuration?: number; + executionTime?: null | string; + extraProperties?: null | { + [key: string]: unknown; + }; + id?: string; + methodName?: null | string; + parameters?: null | string; + serviceName?: null | string; + tenantId?: null | string; +}; + +export type PagingAuditLogInput = { + /** + * 应用程序名称 + */ + applicationName?: null | string; + /** + * 客户端IP + */ + clientIpAddress?: null | string; + /** + * RequestId + */ + correlationId?: null | string; + /** + * 结束时间 + */ + endTime?: null | string; + /** + * 是否有异常 + */ + hasException?: boolean | null; + /** + * 请求方法 + */ + httpMethod?: null | string; + httpStatusCode?: HttpStatusCode; + /** + * 最大执行时间 + */ + maxExecutionDuration?: null | number; + /** + * 最小执行时间 + */ + minExecutionDuration?: null | number; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + */ + sorting?: null | string; + /** + * 开始时间 + */ + startTime?: null | string; + /** + * 请求地址 + */ + url?: null | string; + /** + * 用户Id + */ + userId?: null | string; + /** + * 用户名 + */ + userName?: null | string; +}; + +export type PagingAuditLogOutput = { + actions?: Array | null; + applicationName?: null | string; + browserInfo?: null | string; + clientId?: null | string; + clientIpAddress?: null | string; + clientName?: null | string; + comments?: null | string; + correlationId?: null | string; + entityChanges?: Array | null; + exceptions?: null | string; + executionDuration?: number; + executionTime?: null | string; + httpMethod?: null | string; + httpStatusCode?: null | number; + impersonatorTenantId?: null | string; + impersonatorUserId?: null | string; + tenantId?: null | string; + tenantName?: null | string; + url?: null | string; + userId?: null | string; + userName?: null | string; +}; + +export type PagingAuditLogOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PagingDataDictionaryDetailInput = { + dataDictionaryId?: string; + filter?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type PagingDataDictionaryDetailOutput = { + /** + * 字典明细编码 + */ + code?: null | string; + /** + * 所属字典Id + */ + dataDictionaryId?: string; + /** + * 描述 + */ + description?: null | string; + /** + * 英文显示名 + */ + displayText?: null | string; + id?: string; + /** + * 启/停用(默认启用) + */ + isEnabled?: boolean; + /** + * 展现列表时排序用 + */ + order?: number; +}; + +export type PagingDataDictionaryDetailOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PagingDataDictionaryInput = { + filter?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type PagingDataDictionaryOutput = { + /** + * 字典编码 + */ + code?: null | string; + /** + * 描述 + */ + description?: null | string; + /** + * 显示名 + */ + displayText?: null | string; + id?: string; +}; + +export type PagingDataDictionaryOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PagingEntityChangeOutput = { + auditLogId?: string; + changeTime?: null | string; + changeType?: EntityChangeType; + changeTypeDescription?: null | string; + entityId?: null | string; + entityTenantId?: null | string; + entityTypeFullName?: null | string; + extraProperties?: null | { + [key: string]: unknown; + }; + id?: string; + propertyChanges?: Array | null; + tenantId?: null | string; +}; + +export type PagingEntityPropertyChangeOutput = { + entityChangeId?: string; + id?: string; + newValue?: null | string; + originalValue?: null | string; + propertyName?: null | string; + propertyTypeFullName?: null | string; + tenantId?: null | string; +}; + +export type PagingIdentitySecurityLogInput = { + /** + * 请求地址 + */ + action?: null | string; + /** + * 应用程序名称 + */ + applicationName?: null | string; + /** + * ClientId + */ + clientId?: null | string; + /** + * RequestId + */ + correlationId?: null | string; + /** + * 结束时间 + */ + endTime?: null | string; + identity?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + */ + sorting?: null | string; + /** + * 开始时间 + */ + startTime?: null | string; + /** + * 用户Id + */ + userId?: null | string; + /** + * 用户名 + */ + userName?: null | string; +}; + +export type PagingIdentitySecurityLogOutput = { + action?: null | string; + applicationName?: null | string; + browserInfo?: null | string; + clientId?: null | string; + clientIpAddress?: null | string; + correlationId?: null | string; + creationTime?: string; + id?: string; + identity?: null | string; + tenantId?: null | string; + tenantName?: null | string; + userId?: null | string; + userName?: null | string; +}; + +export type PagingIdentitySecurityLogOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PagingNotificationInput = { + /** + * 内容 + */ + content?: null | string; + /** + * 已读结束时间 + */ + endReadTime?: null | string; + messageLevel?: MessageLevel; + messageType?: MessageType; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 是否已读 + */ + read?: boolean | null; + /** + * 接受者Id + */ + receiverUserId?: null | string; + /** + * 接受者名称 + */ + receiverUserName?: null | string; + /** + * 发送者Id + */ + senderUserId?: null | string; + /** + * 发送者名称 + */ + senderUserName?: null | string; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; + /** + * 已读开始时间 + */ + startReadTime?: null | string; + /** + * 标题 + */ + title?: null | string; +}; + +export type PagingNotificationOutput = { + /** + * 消息内容 + */ + content?: null | string; + creationTime?: string; + id?: string; + messageLevel?: MessageLevel; + readonly messageLevelName?: null | string; + messageType?: MessageType; + readonly messageTypeName?: null | string; + /** + * 是否已读 + */ + read?: boolean; + /** + * 已读时间 + */ + readTime?: null | string; + /** + * 订阅人 + * 消息类型是广播消息时,订阅人为空 + */ + receiveUserId?: null | string; + /** + * 接收人用户名 + * 消息类型是广播消息时,订接收人用户名为空 + */ + receiveUserName?: null | string; + /** + * 发送人 + */ + senderUserId?: string; + /** + * 发送人用户名 + */ + senderUserName?: null | string; + /** + * 租户id + */ + tenantId?: null | string; + /** + * 消息标题 + */ + title?: null | string; +}; + +export type PagingNotificationOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PagingNotificationSubscriptionInput = { + /** + * 已读结束时间 + */ + endReadTime?: null | string; + notificationId?: string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 是否已读 + */ + read?: boolean | null; + /** + * 接受者Id + */ + receiverUserId?: null | string; + /** + * 接受者名称 + */ + receiverUserName?: null | string; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; + /** + * 已读开始时间 + */ + startReadTime?: null | string; +}; + +export type PagingNotificationSubscriptionOutput = { + /** + * 消息内容 + */ + content?: null | string; + id?: string; + messageLevel?: MessageLevel; + readonly messageLevelName?: null | string; + messageType?: MessageType; + readonly messageTypeName?: null | string; + /** + * 消息Id + */ + notificationId?: string; + /** + * 是否已读 + */ + read?: boolean; + /** + * 已读时间 + */ + readTime?: string; + /** + * 接收人id + */ + receiveUserId?: string; + /** + * 接收人用户名 + */ + receiveUserName?: null | string; + /** + * 发送人 + */ + senderUserId?: string; + /** + * 发送人用户名 + */ + senderUserName?: null | string; + /** + * 租户id + */ + tenantId?: null | string; + /** + * 消息标题 + */ + title?: null | string; +}; + +export type PagingNotificationSubscriptionOutputPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type PagingRoleListInput = { + filter?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type PagingTenantInput = { + filter?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type PagingUserListInput = { + /** + * 关键字 + */ + filter?: null | string; + /** + * 当前页面.默认从1开始 + */ + pageIndex?: number; + /** + * 每页多少条.每页显示多少记录 + */ + pageSize?: number; + /** + * 跳过多少条 + */ + readonly skipCount?: number; + /** + * 排序 + * + * name desc + * + */ + sorting?: null | string; +}; + +export type ParameterApiDescriptionModel = { + bindingSourceId?: null | string; + constraintTypes?: Array | null; + defaultValue?: unknown; + descriptorName?: null | string; + isOptional?: boolean; + jsonName?: null | string; + name?: null | string; + nameOnMethod?: null | string; + type?: null | string; + typeSimple?: null | string; +}; + +export type PermissionOutput = { + allGrants?: Array | null; + grants?: Array | null; + permissions?: Array | null; +}; + +export type PermissionTreeDto = { + children?: Array | null; + key?: null | string; + title?: null | string; +}; + +export type PreViewCodeInput = { + entityId?: Array | null; + projectId?: string; + templateId?: string; +}; + +export type ProjectDto = { + /** + * 公司名称 + */ + companyName?: null | string; + creationTime?: string; + creatorId?: null | string; + id?: string; + lastModificationTime?: null | string; + lastModifierId?: null | string; + /** + * 名称空间 + */ + nameSpace?: null | string; + /** + * 负责人 + */ + owner?: null | string; + /** + * 项目名称 + */ + projectName?: null | string; + /** + * 备注 + */ + remark?: null | string; + /** + * 是否支持多租户 + */ + supportTenant?: boolean; + tenantId?: null | string; +}; + +export type ProjectDtoPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type ProjectOutput = { + /** + * 公司名称 + */ + companyName?: null | string; + id?: string; + /** + * 项目名称 + */ + projectName?: null | string; +}; + +export type PropertyApiDescriptionModel = { + isRequired?: boolean; + jsonName?: null | string; + maximum?: null | string; + maxLength?: null | number; + minimum?: null | string; + minLength?: null | number; + name?: null | string; + regex?: null | string; + type?: null | string; + typeSimple?: null | string; +}; + +export type RefreshTokenInput = { + refreshToken: string; + userId?: string; +}; + +export type RefreshTokenOutput = { + message?: null | string; + refreshToken?: null | string; + success?: boolean; + token?: null | string; +}; + +export type RelationalType = 10 | 20; + +export type RemoteServiceErrorInfo = { + code?: null | string; + data?: null | { + [key: string]: unknown; + }; + details?: null | string; + message?: null | string; + validationErrors?: Array | null; +}; + +export type RemoteServiceErrorResponse = { + error?: RemoteServiceErrorInfo; +}; + +export type RemoteServiceValidationErrorInfo = { + members?: Array | null; + message?: null | string; +}; + +export type RemoteStreamContent = { + readonly contentLength?: null | number; + contentType?: null | string; + fileName?: null | string; +}; + +export type RemoveRoleToOrganizationUnitInput = { + organizationUnitId?: string; + roleId?: string; +}; + +export type RemoveUserToOrganizationUnitInput = { + organizationUnitId?: string; + userId?: string; +}; + +export type ResetPasswordInput = { + password: string; + userId?: string; +}; + +export type ResetTwoFactorInput = { + userId?: string; +}; + +export type ReturnValueApiDescriptionModel = { + type?: null | string; + typeSimple?: null | string; +}; + +export type SendBroadCastMessageInput = { + /** + * 消息内容 + */ + content?: null | string; + /** + * 消息标题 + */ + title?: null | string; +}; + +export type SendCommonMessageInput = { + /** + * 消息内容 + */ + content?: null | string; + /** + * 发送人 + */ + receiveUserId?: string; + /** + * 发送人名称 + */ + receiveUserName?: null | string; + /** + * 消息标题 + */ + title?: null | string; +}; + +export type SetBatchReadInput = { + ids?: Array | null; +}; + +export type SetDataDictinaryDetailInput = { + dataDictionaryId?: string; + dataDictionayDetailId?: string; + isEnabled: boolean; +}; + +export type SetReadInput = { + id?: string; +}; + +export type SettingItemOutput = { + /** + * 描述 + */ + description?: null | string; + /** + * 显示名称 + */ + displayName?: null | string; + /** + * 名称 + */ + name?: null | string; + /** + * 前端控件类型 + */ + type?: null | string; + /** + * 值 + */ + value?: null | string; +}; + +export type SettingOutput = { + /** + * 分组 + */ + group?: null | string; + /** + * 分组显示名称 + */ + groupDisplayName?: null | string; + settingItemOutput?: Array | null; +}; + +export type StringInt32KeyValuePair = { + key?: null | string; + value?: number; +}; + +export type StringStringFromSelector = { + readonly label?: null | string; + readonly value?: null | string; +}; + +/** + * 模板明细 + */ +export type TemplateDetailDto = { + /** + * 模板内容 + */ + content?: null | string; + controlType?: ControlType; + /** + * 描述 + */ + description?: null | string; + id?: string; + /** + * 模板名称 + */ + name?: null | string; + /** + * 父级id + */ + parentId?: null | string; + /** + * 模板id + */ + templateId?: string; + templateType?: TemplateType; +}; + +/** + * 模板 + */ +export type TemplateDto = { + creationTime?: string; + creatorId?: null | string; + id?: string; + lastModificationTime?: null | string; + lastModifierId?: null | string; + /** + * 名称 + */ + name?: null | string; + /** + * 备注 + */ + remark?: null | string; + /** + * 关联属性1:N 模板明细集合 + */ + templateDetails?: Array | null; + tenantId?: null | string; +}; + +export type TemplateDtoPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type TemplateTreeDto = { + children?: Array | null; + /** + * 模板内容 + */ + content?: null | string; + controlType?: ControlType; + /** + * 描述 + */ + description?: null | string; + /** + * 图标 + */ + icon?: null | string; + /** + * 是否是文件夹 + */ + isFolder?: boolean; + /** + * 模板id + */ + key?: string; + /** + * 模板名称 + */ + name?: null | string; + templateType?: TemplateType; + /** + * 描述 + */ + title?: null | string; +}; + +export type TemplateType = 10 | 20; + +export type TenantCreateDto = { + adminEmailAddress: string; + adminPassword: string; + readonly extraProperties?: null | { + [key: string]: unknown; + }; + name: string; +}; + +export type TenantDto = { + concurrencyStamp?: null | string; + readonly extraProperties?: null | { + [key: string]: unknown; + }; + id?: string; + name?: null | string; +}; + +export type TenantDtoPagedResultDto = { + items?: Array | null; + totalCount?: number; +}; + +export type TimeZone = { + iana?: IanaTimeZone; + windows?: WindowsTimeZone; +}; + +export type TimingDto = { + timeZone?: TimeZone; +}; + +export type TreeOutput = { + children?: Array | null; + key?: string; + title?: null | string; +}; + +export type TypeApiDescriptionModel = { + baseType?: null | string; + enumNames?: Array | null; + enumValues?: Array | null; + genericArguments?: Array | null; + isEnum?: boolean; + properties?: Array | null; +}; + +export type UpdateAggregateInput = { + /** + * 编码 + */ + code: string; + /** + * 描述 + */ + description: string; + id?: string; +}; + +export type UpdateDataDictinaryInput = { + code?: null | string; + description?: null | string; + displayText?: null | string; + id?: string; +}; + +export type UpdateDetailInput = { + dataDictionaryId?: string; + description?: null | string; + displayText?: null | string; + id?: string; + order?: number; +}; + +export type UpdateEntityModelInput = { + /** + * 编码 + */ + code: string; + /** + * 描述 + */ + description: string; + id?: string; + relationalType?: RelationalType; +}; + +export type UpdateEntityModelPropertyInput = { + /** + * 允许添加 + */ + allowAdd?: boolean; + /** + * 允许编辑 + */ + allowEdit?: boolean; + /** + * 允许作为查询条件 + */ + allowSearch?: boolean; + /** + * 编码 + */ + code: string; + /** + * 数据类型Id + */ + dataTypeId?: null | string; + /** + * 当类型为decimal时的小数位数 (18,4) 中的18 + */ + decimalPrecision?: null | number; + /** + * 当类型为decimal时的字段长度 (18,4) 中的4 + */ + decimalScale?: null | number; + /** + * 描述 + */ + description: string; + /** + * 实体模型Id + */ + entityModelId?: string; + /** + * 枚举类型Id + */ + enumTypeId?: null | string; + id?: string; + /** + * 必填 + */ + isRequired?: boolean; + /** + * 字符串最大长度 + */ + maxLength?: null | number; + /** + * 字符串最小长度 + */ + minLength?: null | number; + propertyId?: string; +}; + +export type UpdateEnumTypeInput = { + /** + * 编码 + */ + code: string; + /** + * 描述 + */ + description: string; + id?: string; +}; + +export type UpdateEnumTypePropertyInput = { + /** + * 编码 + */ + code: string; + /** + * 描述 + */ + description: string; + /** + * Id + */ + enumTypeId?: string; + /** + * Id + */ + id?: string; + /** + * 枚举值 + */ + value?: number; +}; + +export type UpdateFeatureDto = { + name?: null | string; + value?: null | string; +}; + +export type UpdateFeatureInput = { + providerKey?: null | string; + providerName?: null | string; + updateFeaturesDto?: UpdateFeaturesDto; +}; + +export type UpdateFeaturesDto = { + features?: Array | null; +}; + +/** + * 删除语言 + */ +export type UpdateLanguageInput = { + /** + * 语言名称 + */ + cultureName?: null | string; + /** + * 显示名称 + */ + displayName?: null | string; + /** + * 图标 + */ + flagIcon?: null | string; + /** + * 语言Id + */ + id?: string; + /** + * 是否启用 + */ + isEnabled?: boolean; + /** + * Ui语言名称 + */ + uiCultureName?: null | string; +}; + +/** + * 删除语言文本 + */ +export type UpdateLanguageTextInput = { + /** + * 语言名称 + */ + cultureName: string; + /** + * 名称 + */ + name: string; + /** + * 资源名称 + */ + resourceName: string; + /** + * 值 + */ + value: string; +}; + +/** + * 更新菜单 + */ +export type UpdateMenuInput = { + /** + * 组件地址 + */ + component?: null | string; + enabled?: boolean; + /** + * 是否显示 + */ + hideInMenu: boolean; + /** + * 图标 + */ + icon?: null | string; + /** + * 菜单Id + */ + id?: string; + /** + * 是否缓存 + */ + keepAlive: boolean; + menuType?: MenuType; + /** + * 唯一编码 + */ + name: string; + openType?: OpenType; + /** + * 排序 + */ + order: number; + /** + * 路由地址 + */ + path: string; + /** + * 权限 + */ + policy?: null | string; + /** + * 标题 + */ + title: string; + /** + * 内外链地址 + */ + url?: null | string; +}; + +export type UpdateOrganizationUnitInput = { + displayName?: null | string; + id?: string; +}; + +export type UpdatePermissionDto = { + isGranted?: boolean; + name?: null | string; +}; + +export type UpdatePermissionsDto = { + permissions?: Array | null; +}; + +export type UpdateProjectInput = { + /** + * 公司名称 + */ + companyName?: null | string; + id?: string; + /** + * 负责人 + */ + owner?: null | string; + /** + * 项目名称 + */ + projectName?: null | string; + /** + * 备注 + */ + remark?: null | string; + /** + * 是否支持多租户 + */ + supportTenant?: boolean; +}; + +export type UpdateRoleInput = { + roleId?: string; + roleInfo?: IdentityRoleUpdateDto; +}; + +export type UpdateRolePermissionsInput = { + providerKey?: null | string; + providerName?: null | string; + updatePermissionsDto?: UpdatePermissionsDto; +}; + +export type UpdateSettingInput = { + values?: null | { + [key: string]: null | string; + }; +}; + +export type UpdateTemplateDetailContentInput = { + /** + * 模板内容 + */ + content?: null | string; + templateDetailId?: string; + /** + * 模板id + */ + templateId?: string; +}; + +export type UpdateTemplateDetailInput = { + /** + * 模板内容 + */ + content?: null | string; + controlType?: ControlType; + /** + * 描述 + */ + description?: null | string; + /** + * 模板类型 + */ + name?: null | string; + templateDetailId?: string; + /** + * 模板id + */ + templateId?: string; +}; + +export type UpdateTemplateInput = { + id?: string; + /** + * 名称 + */ + name?: null | string; + /** + * 备注 + */ + remark?: null | string; +}; + +export type UpdateTenantInput = { + id?: string; + name?: null | string; +}; + +/** + * 更新模板 + */ +export type UpdateTextTemplateInput = { + /** + * 编码 + */ + code: string; + /** + * 内容 + */ + content: string; + /** + * 语言 + */ + cultureName: string; + /** + * 模板Id + */ + id?: string; + /** + * 名称 + */ + name: string; +}; + +export type UpdateUserInput = { + userId?: string; + userInfo?: IdentityUserUpdateDto; +}; + +export type UserLoginInfo = { + password: string; + rememberMe?: boolean; + userNameOrEmailAddress: string; +}; + +export type WindowsTimeZone = { + timeZoneId?: null | string; +}; + +export type GetApiAbpApiDefinitionData = { + query?: { + IncludeTypes?: boolean; + }; +}; + +export type GetApiAbpApiDefinitionResponse = ApplicationApiDescriptionModel; + +export type GetApiAbpApiDefinitionError = RemoteServiceErrorResponse; + +export type GetApiAbpApplicationConfigurationData = { + query?: { + IncludeLocalizationResources?: boolean; + }; +}; + +export type GetApiAbpApplicationConfigurationResponse = + ApplicationConfigurationDto; + +export type GetApiAbpApplicationConfigurationError = RemoteServiceErrorResponse; + +export type GetApiAbpApplicationLocalizationData = { + query: { + CultureName: string; + OnlyDynamics?: boolean; + }; +}; + +export type GetApiAbpApplicationLocalizationResponse = + ApplicationLocalizationDto; + +export type GetApiAbpApplicationLocalizationError = RemoteServiceErrorResponse; + +export type GetApiAppAbpProBasicApplicationConfigurationResponse = + AbpProApplicationConfigurationDto; + +export type GetApiAppAbpProBasicApplicationConfigurationError = + RemoteServiceErrorResponse; + +export type PostApiAppAccountLoginData = { + body?: LoginInput; +}; + +export type PostApiAppAccountLoginResponse = LoginOutput; + +export type PostApiAppAccountLoginError = RemoteServiceErrorResponse; + +export type PostApiAppAccountLogin2FaData = { + body?: Login2FAInput; +}; + +export type PostApiAppAccountLogin2FaResponse = LoginOutput; + +export type PostApiAppAccountLogin2FaError = RemoteServiceErrorResponse; + +export type PostApiAppAccountLoginOidcData = { + body?: LoginOidcInput; +}; + +export type PostApiAppAccountLoginOidcResponse = LoginOutput; + +export type PostApiAppAccountLoginOidcError = RemoteServiceErrorResponse; + +export type PostApiAppAccountRefreshTokenData = { + body?: RefreshTokenInput; +}; + +export type PostApiAppAccountRefreshTokenResponse = RefreshTokenOutput; + +export type PostApiAppAccountRefreshTokenError = RemoteServiceErrorResponse; + +export type PostAuditLogsPageData = { + body?: PagingAuditLogInput; +}; + +export type PostAuditLogsPageResponse = PagingAuditLogOutputPagedResultDto; + +export type PostAuditLogsPageError = RemoteServiceErrorResponse; + +export type PostDataDictionaryPageData = { + body?: PagingDataDictionaryInput; +}; + +export type PostDataDictionaryPageResponse = + PagingDataDictionaryOutputPagedResultDto; + +export type PostDataDictionaryPageError = RemoteServiceErrorResponse; + +export type PostDataDictionaryPageDetailData = { + body?: PagingDataDictionaryDetailInput; +}; + +export type PostDataDictionaryPageDetailResponse = + PagingDataDictionaryDetailOutputPagedResultDto; + +export type PostDataDictionaryPageDetailError = RemoteServiceErrorResponse; + +export type PostDataDictionaryCreateData = { + body?: CreateDataDictinaryInput; +}; + +export type PostDataDictionaryCreateResponse = unknown; + +export type PostDataDictionaryCreateError = RemoteServiceErrorResponse; + +export type PostDataDictionaryCreateDetailData = { + body?: CreateDataDictinaryDetailInput; +}; + +export type PostDataDictionaryCreateDetailResponse = unknown; + +export type PostDataDictionaryCreateDetailError = RemoteServiceErrorResponse; + +export type PostDataDictionaryStatusData = { + body?: SetDataDictinaryDetailInput; +}; + +export type PostDataDictionaryStatusResponse = unknown; + +export type PostDataDictionaryStatusError = RemoteServiceErrorResponse; + +export type PostDataDictionaryUpdateDetailData = { + body?: UpdateDetailInput; +}; + +export type PostDataDictionaryUpdateDetailResponse = unknown; + +export type PostDataDictionaryUpdateDetailError = RemoteServiceErrorResponse; + +export type PostDataDictionaryDeleteData = { + body?: DeleteDataDictionaryDetailInput; +}; + +export type PostDataDictionaryDeleteResponse = unknown; + +export type PostDataDictionaryDeleteError = RemoteServiceErrorResponse; + +export type PostDataDictionaryDeleteDataDictionaryTypeData = { + body?: IdInput; +}; + +export type PostDataDictionaryDeleteDataDictionaryTypeResponse = unknown; + +export type PostDataDictionaryDeleteDataDictionaryTypeError = + RemoteServiceErrorResponse; + +export type PostDataDictionaryUpdateData = { + body?: UpdateDataDictinaryInput; +}; + +export type PostDataDictionaryUpdateResponse = unknown; + +export type PostDataDictionaryUpdateError = RemoteServiceErrorResponse; + +export type PostDataTypesListData = { + body?: GetDataTypeInput; +}; + +export type PostDataTypesListResponse = Array; + +export type PostDataTypesListError = RemoteServiceErrorResponse; + +export type PostEntityModelsPagePropertyData = { + body?: PageEntityModelInput; +}; + +export type PostEntityModelsPagePropertyResponse = + PageEntityModelPropertyOutputPagedResultDto; + +export type PostEntityModelsPagePropertyError = RemoteServiceErrorResponse; + +export type PostEntityModelsCreateAggregateData = { + body?: CreateAggregateInput; +}; + +export type PostEntityModelsCreateAggregateResponse = unknown; + +export type PostEntityModelsCreateAggregateError = RemoteServiceErrorResponse; + +export type PostEntityModelsUpdateAggregateData = { + body?: UpdateAggregateInput; +}; + +export type PostEntityModelsUpdateAggregateResponse = unknown; + +export type PostEntityModelsUpdateAggregateError = RemoteServiceErrorResponse; + +export type PostEntityModelsDeleteAggregateData = { + body?: DeleteAggregateInput; +}; + +export type PostEntityModelsDeleteAggregateResponse = unknown; + +export type PostEntityModelsDeleteAggregateError = RemoteServiceErrorResponse; + +export type PostEntityModelsCreateEntityModelData = { + body?: CreateEntityModelInput; +}; + +export type PostEntityModelsCreateEntityModelResponse = unknown; + +export type PostEntityModelsCreateEntityModelError = RemoteServiceErrorResponse; + +export type PostEntityModelsUpdateEntityModelData = { + body?: UpdateEntityModelInput; +}; + +export type PostEntityModelsUpdateEntityModelResponse = unknown; + +export type PostEntityModelsUpdateEntityModelError = RemoteServiceErrorResponse; + +export type PostEntityModelsDeleteEntityModelData = { + body?: DeleteEntityModelInput; +}; + +export type PostEntityModelsDeleteEntityModelResponse = unknown; + +export type PostEntityModelsDeleteEntityModelError = RemoteServiceErrorResponse; + +export type PostEntityModelsCreateEntityModelPropertyData = { + body?: CreateEntityModelPropertyInput; +}; + +export type PostEntityModelsCreateEntityModelPropertyResponse = unknown; + +export type PostEntityModelsCreateEntityModelPropertyError = + RemoteServiceErrorResponse; + +export type PostEntityModelsUpdateEntityModelPropertyData = { + body?: UpdateEntityModelPropertyInput; +}; + +export type PostEntityModelsUpdateEntityModelPropertyResponse = unknown; + +export type PostEntityModelsUpdateEntityModelPropertyError = + RemoteServiceErrorResponse; + +export type PostEntityModelsDeleteEntityModelPropertyData = { + body?: DeleteEntityModelPropertyInput; +}; + +export type PostEntityModelsDeleteEntityModelPropertyResponse = unknown; + +export type PostEntityModelsDeleteEntityModelPropertyError = + RemoteServiceErrorResponse; + +export type PostEntityModelsTreeData = { + body?: GetEntityModelTreeInput; +}; + +export type PostEntityModelsTreeResponse = Array; + +export type PostEntityModelsTreeError = RemoteServiceErrorResponse; + +export type PostEntityModelsGetData = { + body?: GetEntityModelInput; +}; + +export type PostEntityModelsGetResponse = Array; + +export type PostEntityModelsGetError = RemoteServiceErrorResponse; + +export type PostEnumTypesPageData = { + body?: PageEnumTypeInput; +}; + +export type PostEnumTypesPageResponse = PageEnumTypeOutputPagedResultDto; + +export type PostEnumTypesPageError = RemoteServiceErrorResponse; + +export type PostEnumTypesPagePropertyData = { + body?: PageEnumTypePropertyInput; +}; + +export type PostEnumTypesPagePropertyResponse = + PageEnumTypePropertyOutputPagedResultDto; + +export type PostEnumTypesPagePropertyError = RemoteServiceErrorResponse; + +export type PostEnumTypesCreateEnumTypeData = { + body?: CreateEnumTypeInput; +}; + +export type PostEnumTypesCreateEnumTypeResponse = unknown; + +export type PostEnumTypesCreateEnumTypeError = RemoteServiceErrorResponse; + +export type PostEnumTypesUpdateEnumTypeData = { + body?: UpdateEnumTypeInput; +}; + +export type PostEnumTypesUpdateEnumTypeResponse = unknown; + +export type PostEnumTypesUpdateEnumTypeError = RemoteServiceErrorResponse; + +export type PostEnumTypesDeleteEnumTypeData = { + body?: DeleteEnumTypeInput; +}; + +export type PostEnumTypesDeleteEnumTypeResponse = unknown; + +export type PostEnumTypesDeleteEnumTypeError = RemoteServiceErrorResponse; + +export type PostEnumTypesCreateEnumTypePropertyData = { + body?: CreateEnumTypePropertyInput; +}; + +export type PostEnumTypesCreateEnumTypePropertyResponse = unknown; + +export type PostEnumTypesCreateEnumTypePropertyError = + RemoteServiceErrorResponse; + +export type PostEnumTypesUpdateEnumTypePropertyData = { + body?: UpdateEnumTypePropertyInput; +}; + +export type PostEnumTypesUpdateEnumTypePropertyResponse = unknown; + +export type PostEnumTypesUpdateEnumTypePropertyError = + RemoteServiceErrorResponse; + +export type PostEnumTypesDeleteEnumTypePropertyData = { + body?: DeleteEnumTypePropertyInput; +}; + +export type PostEnumTypesDeleteEnumTypePropertyResponse = unknown; + +export type PostEnumTypesDeleteEnumTypePropertyError = + RemoteServiceErrorResponse; + +export type PostFeaturesListData = { + body?: GetFeatureListResultInput; +}; + +export type PostFeaturesListResponse = GetFeatureListResultDto; + +export type PostFeaturesListError = RemoteServiceErrorResponse; + +export type PostFeaturesUpdateData = { + body?: UpdateFeatureInput; +}; + +export type PostFeaturesUpdateResponse = unknown; + +export type PostFeaturesUpdateError = RemoteServiceErrorResponse; + +export type PostFeaturesDeleteData = { + body?: DeleteFeatureInput; +}; + +export type PostFeaturesDeleteResponse = unknown; + +export type PostFeaturesDeleteError = RemoteServiceErrorResponse; + +export type PostFilesPageData = { + body?: PageFileObjectInput; +}; + +export type PostFilesPageResponse = PageFileObjectOutputPagedResultDto; + +export type PostFilesPageError = RemoteServiceErrorResponse; + +export type PostFilesUploadData = { + body?: { + files?: Array; + }; +}; + +export type PostFilesUploadResponse = unknown; + +export type PostFilesUploadError = RemoteServiceErrorResponse; + +export type PostFilesDeleteData = { + body?: DeleteFileObjectInput; +}; + +export type PostFilesDeleteResponse = unknown; + +export type PostFilesDeleteError = RemoteServiceErrorResponse; + +export type PostFilesDownloadData = { + body?: DownloadFileObjectInput; +}; + +export type PostFilesDownloadResponse = RemoteStreamContent; + +export type PostFilesDownloadError = RemoteServiceErrorResponse; + +export type PostGeneratorPreViewCodeData = { + body?: PreViewCodeInput; +}; + +export type PostGeneratorPreViewCodeResponse = Array; + +export type PostGeneratorPreViewCodeError = RemoteServiceErrorResponse; + +export type PostGeneratorDownData = { + body?: DownCodeInput; +}; + +export type PostGeneratorDownResponse = Blob | File; + +export type PostGeneratorDownError = RemoteServiceErrorResponse; + +export type PostIdentitySecurityLogsPageData = { + body?: PagingIdentitySecurityLogInput; +}; + +export type PostIdentitySecurityLogsPageResponse = + PagingIdentitySecurityLogOutputPagedResultDto; + +export type PostIdentitySecurityLogsPageError = RemoteServiceErrorResponse; + +export type PostLanguagesAllResponse = Array; + +export type PostLanguagesAllError = RemoteServiceErrorResponse; + +export type PostLanguagesPageData = { + body?: PageLanguageInput; +}; + +export type PostLanguagesPageResponse = PageLanguageOutputPagedResultDto; + +export type PostLanguagesPageError = RemoteServiceErrorResponse; + +export type PostLanguagesCreateData = { + body?: CreateLanguageInput; +}; + +export type PostLanguagesCreateResponse = unknown; + +export type PostLanguagesCreateError = RemoteServiceErrorResponse; + +export type PostLanguagesUpdateData = { + body?: UpdateLanguageInput; +}; + +export type PostLanguagesUpdateResponse = unknown; + +export type PostLanguagesUpdateError = RemoteServiceErrorResponse; + +export type PostLanguagesDeleteData = { + body?: DeleteLanguageInput; +}; + +export type PostLanguagesDeleteResponse = unknown; + +export type PostLanguagesDeleteError = RemoteServiceErrorResponse; + +export type PostLanguagesSetDefaultData = { + body?: IdInput; +}; + +export type PostLanguagesSetDefaultResponse = unknown; + +export type PostLanguagesSetDefaultError = RemoteServiceErrorResponse; + +export type PostLanguageTextsAllResourceResponse = + Array; + +export type PostLanguageTextsAllResourceError = RemoteServiceErrorResponse; + +export type PostLanguageTextsPageData = { + body?: PageLanguageTextInput; +}; + +export type PostLanguageTextsPageResponse = + PageLanguageTextOutputPagedResultDto; + +export type PostLanguageTextsPageError = RemoteServiceErrorResponse; + +export type PostLanguageTextsCreateData = { + body?: CreateLanguageTextInput; +}; + +export type PostLanguageTextsCreateResponse = unknown; + +export type PostLanguageTextsCreateError = RemoteServiceErrorResponse; + +export type PostLanguageTextsUpdateData = { + body?: UpdateLanguageTextInput; +}; + +export type PostLanguageTextsUpdateResponse = unknown; + +export type PostLanguageTextsUpdateError = RemoteServiceErrorResponse; + +export type PostMenusUserMenuResponse = Array; + +export type PostMenusUserMenuError = RemoteServiceErrorResponse; + +export type PostMenusPageData = { + body?: PageMenuInput; +}; + +export type PostMenusPageResponse = PageMenuOutputPagedResultDto; + +export type PostMenusPageError = RemoteServiceErrorResponse; + +export type PostMenusCreateData = { + body?: CreateMenuInput; +}; + +export type PostMenusCreateResponse = unknown; + +export type PostMenusCreateError = RemoteServiceErrorResponse; + +export type PostMenusUpdateData = { + body?: UpdateMenuInput; +}; + +export type PostMenusUpdateResponse = unknown; + +export type PostMenusUpdateError = RemoteServiceErrorResponse; + +export type PostMenusDeleteData = { + body?: DeleteMenuInput; +}; + +export type PostMenusDeleteResponse = unknown; + +export type PostMenusDeleteError = RemoteServiceErrorResponse; + +export type PostMenusTreeResponse = Array; + +export type PostMenusTreeError = RemoteServiceErrorResponse; + +export type PostNotificationNotificationPageData = { + body?: PagingNotificationInput; +}; + +export type PostNotificationNotificationPageResponse = + PagingNotificationOutputPagedResultDto; + +export type PostNotificationNotificationPageError = RemoteServiceErrorResponse; + +export type PostNotificationNotificationSubscriptionPageData = { + body?: PagingNotificationSubscriptionInput; +}; + +export type PostNotificationNotificationSubscriptionPageResponse = + PagingNotificationSubscriptionOutputPagedResultDto; + +export type PostNotificationNotificationSubscriptionPageError = + RemoteServiceErrorResponse; + +export type PostNotificationDeleteData = { + body?: DeleteMessageInput; +}; + +export type PostNotificationDeleteResponse = unknown; + +export type PostNotificationDeleteError = RemoteServiceErrorResponse; + +export type PostNotificationSendCommonWarningMessageData = { + body?: SendCommonMessageInput; +}; + +export type PostNotificationSendCommonWarningMessageResponse = unknown; + +export type PostNotificationSendCommonWarningMessageError = + RemoteServiceErrorResponse; + +export type PostNotificationSendCommonInformationMessageData = { + body?: SendCommonMessageInput; +}; + +export type PostNotificationSendCommonInformationMessageResponse = unknown; + +export type PostNotificationSendCommonInformationMessageError = + RemoteServiceErrorResponse; + +export type PostNotificationSendCommonErrorMessageData = { + body?: SendCommonMessageInput; +}; + +export type PostNotificationSendCommonErrorMessageResponse = unknown; + +export type PostNotificationSendCommonErrorMessageError = + RemoteServiceErrorResponse; + +export type PostNotificationSendBroadCastWarningMessageData = { + body?: SendBroadCastMessageInput; +}; + +export type PostNotificationSendBroadCastWarningMessageResponse = unknown; + +export type PostNotificationSendBroadCastWarningMessageError = + RemoteServiceErrorResponse; + +export type PostNotificationSendBroadCastInformationMessageData = { + body?: SendBroadCastMessageInput; +}; + +export type PostNotificationSendBroadCastInformationMessageResponse = unknown; + +export type PostNotificationSendBroadCastInformationMessageError = + RemoteServiceErrorResponse; + +export type PostNotificationSendBroadCastErrorMessageData = { + body?: SendBroadCastMessageInput; +}; + +export type PostNotificationSendBroadCastErrorMessageResponse = unknown; + +export type PostNotificationSendBroadCastErrorMessageError = + RemoteServiceErrorResponse; + +export type PostNotificationReadData = { + body?: SetReadInput; +}; + +export type PostNotificationReadResponse = unknown; + +export type PostNotificationReadError = RemoteServiceErrorResponse; + +export type PostNotificationBatchReadData = { + body?: SetBatchReadInput; +}; + +export type PostNotificationBatchReadResponse = unknown; + +export type PostNotificationBatchReadError = RemoteServiceErrorResponse; + +export type PostOrganizationUnitsTreeResponse = Array; + +export type PostOrganizationUnitsTreeError = RemoteServiceErrorResponse; + +export type PostOrganizationUnitsCreateData = { + body?: CreateOrganizationUnitInput; +}; + +export type PostOrganizationUnitsCreateResponse = unknown; + +export type PostOrganizationUnitsCreateError = RemoteServiceErrorResponse; + +export type PostOrganizationUnitsDeleteData = { + body?: IdInput; +}; + +export type PostOrganizationUnitsDeleteResponse = unknown; + +export type PostOrganizationUnitsDeleteError = RemoteServiceErrorResponse; + +export type PostOrganizationUnitsUpdateData = { + body?: UpdateOrganizationUnitInput; +}; + +export type PostOrganizationUnitsUpdateResponse = unknown; + +export type PostOrganizationUnitsUpdateError = RemoteServiceErrorResponse; + +export type PostOrganizationUnitsAddRoleToOrganizationUnitAsyncData = { + body?: AddRoleToOrganizationUnitInput; +}; + +export type PostOrganizationUnitsAddRoleToOrganizationUnitAsyncResponse = + unknown; + +export type PostOrganizationUnitsAddRoleToOrganizationUnitAsyncError = + RemoteServiceErrorResponse; + +export type PostOrganizationUnitsRemoveRoleFromOrganizationUnitAsyncData = { + body?: RemoveRoleToOrganizationUnitInput; +}; + +export type PostOrganizationUnitsRemoveRoleFromOrganizationUnitAsyncResponse = + unknown; + +export type PostOrganizationUnitsRemoveRoleFromOrganizationUnitAsyncError = + RemoteServiceErrorResponse; + +export type PostOrganizationUnitsAddUserToOrganizationUnitData = { + body?: AddUserToOrganizationUnitInput; +}; + +export type PostOrganizationUnitsAddUserToOrganizationUnitResponse = unknown; + +export type PostOrganizationUnitsAddUserToOrganizationUnitError = + RemoteServiceErrorResponse; + +export type PostOrganizationUnitsRemoveUserFromOrganizationUnitData = { + body?: RemoveUserToOrganizationUnitInput; +}; + +export type PostOrganizationUnitsRemoveUserFromOrganizationUnitResponse = + unknown; + +export type PostOrganizationUnitsRemoveUserFromOrganizationUnitError = + RemoteServiceErrorResponse; + +export type PostOrganizationUnitsGetUsersData = { + body?: GetOrganizationUnitUserInput; +}; + +export type PostOrganizationUnitsGetUsersResponse = + GetOrganizationUnitUserOutputPagedResultDto; + +export type PostOrganizationUnitsGetUsersError = RemoteServiceErrorResponse; + +export type PostOrganizationUnitsGetRolesData = { + body?: GetOrganizationUnitRoleInput; +}; + +export type PostOrganizationUnitsGetRolesResponse = + GetOrganizationUnitRoleOutputPagedResultDto; + +export type PostOrganizationUnitsGetRolesError = RemoteServiceErrorResponse; + +export type PostOrganizationUnitsGetUnAddUsersData = { + body?: GetUnAddUserInput; +}; + +export type PostOrganizationUnitsGetUnAddUsersResponse = + GetUnAddUserOutputPagedResultDto; + +export type PostOrganizationUnitsGetUnAddUsersError = + RemoteServiceErrorResponse; + +export type PostOrganizationUnitsGetUnAddRolesData = { + body?: GetUnAddRoleInput; +}; + +export type PostOrganizationUnitsGetUnAddRolesResponse = + GetUnAddRoleOutputPagedResultDto; + +export type PostOrganizationUnitsGetUnAddRolesError = + RemoteServiceErrorResponse; + +export type PostPermissionsTreeData = { + body?: GetPermissionInput; +}; + +export type PostPermissionsTreeResponse = PermissionOutput; + +export type PostPermissionsTreeError = RemoteServiceErrorResponse; + +export type PostPermissionsUpdateData = { + body?: UpdateRolePermissionsInput; +}; + +export type PostPermissionsUpdateResponse = unknown; + +export type PostPermissionsUpdateError = RemoteServiceErrorResponse; + +export type PostProjectsAllResponse = Array; + +export type PostProjectsAllError = RemoteServiceErrorResponse; + +export type PostProjectsPageData = { + body?: PageProjectInput; +}; + +export type PostProjectsPageResponse = ProjectDtoPagedResultDto; + +export type PostProjectsPageError = RemoteServiceErrorResponse; + +export type PostProjectsCreateData = { + body?: CreateProjectInput; +}; + +export type PostProjectsCreateResponse = unknown; + +export type PostProjectsCreateError = RemoteServiceErrorResponse; + +export type PostProjectsUpdateData = { + body?: UpdateProjectInput; +}; + +export type PostProjectsUpdateResponse = unknown; + +export type PostProjectsUpdateError = RemoteServiceErrorResponse; + +export type PostProjectsDeleteData = { + body?: DeleteProjectInput; +}; + +export type PostProjectsDeleteResponse = unknown; + +export type PostProjectsDeleteError = RemoteServiceErrorResponse; + +export type PostProjectsGetProjectAndEntityData = { + body?: GetProjectAndEntityInput; +}; + +export type PostProjectsGetProjectAndEntityResponse = GetProjectAndEntityOutput; + +export type PostProjectsGetProjectAndEntityError = RemoteServiceErrorResponse; + +export type PostRolesAllResponse = IdentityRoleDtoListResultDto; + +export type PostRolesAllError = RemoteServiceErrorResponse; + +export type PostRolesPageData = { + body?: PagingRoleListInput; +}; + +export type PostRolesPageResponse = IdentityRoleDtoPagedResultDto; + +export type PostRolesPageError = RemoteServiceErrorResponse; + +export type PostRolesCreateData = { + body?: IdentityRoleCreateDto; +}; + +export type PostRolesCreateResponse = IdentityRoleDto; + +export type PostRolesCreateError = RemoteServiceErrorResponse; + +export type PostRolesUpdateData = { + body?: UpdateRoleInput; +}; + +export type PostRolesUpdateResponse = IdentityRoleDto; + +export type PostRolesUpdateError = RemoteServiceErrorResponse; + +export type PostRolesDeleteData = { + body?: IdInput; +}; + +export type PostRolesDeleteResponse = unknown; + +export type PostRolesDeleteError = RemoteServiceErrorResponse; + +export type PostSettingsAllResponse = Array; + +export type PostSettingsAllError = RemoteServiceErrorResponse; + +export type PostSettingsUpdateData = { + body?: UpdateSettingInput; +}; + +export type PostSettingsUpdateResponse = unknown; + +export type PostSettingsUpdateError = RemoteServiceErrorResponse; + +export type PostTemplatesAllResponse = Array; + +export type PostTemplatesAllError = RemoteServiceErrorResponse; + +export type PostTemplatesPageData = { + body?: PageTemplateInput; +}; + +export type PostTemplatesPageResponse = TemplateDtoPagedResultDto; + +export type PostTemplatesPageError = RemoteServiceErrorResponse; + +export type PostTemplatesCreateData = { + body?: CreateTemplateInput; +}; + +export type PostTemplatesCreateResponse = unknown; + +export type PostTemplatesCreateError = RemoteServiceErrorResponse; + +export type PostTemplatesUpdateData = { + body?: UpdateTemplateInput; +}; + +export type PostTemplatesUpdateResponse = unknown; + +export type PostTemplatesUpdateError = RemoteServiceErrorResponse; + +export type PostTemplatesDeleteData = { + body?: DeleteTemplateInput; +}; + +export type PostTemplatesDeleteResponse = unknown; + +export type PostTemplatesDeleteError = RemoteServiceErrorResponse; + +export type PostTemplatesCreateDetailData = { + body?: CreateTemplateDetailInput; +}; + +export type PostTemplatesCreateDetailResponse = unknown; + +export type PostTemplatesCreateDetailError = RemoteServiceErrorResponse; + +export type PostTemplatesUpdateDetailData = { + body?: UpdateTemplateDetailInput; +}; + +export type PostTemplatesUpdateDetailResponse = unknown; + +export type PostTemplatesUpdateDetailError = RemoteServiceErrorResponse; + +export type PostTemplatesUpdateDetailContentData = { + body?: UpdateTemplateDetailContentInput; +}; + +export type PostTemplatesUpdateDetailContentResponse = unknown; + +export type PostTemplatesUpdateDetailContentError = RemoteServiceErrorResponse; + +export type PostTemplatesDeleteDetailData = { + body?: DeleteTemplateDetailInput; +}; + +export type PostTemplatesDeleteDetailResponse = unknown; + +export type PostTemplatesDeleteDetailError = RemoteServiceErrorResponse; + +export type PostTemplatesTreeData = { + body?: GetTemplteTreeInput; +}; + +export type PostTemplatesTreeResponse = Array; + +export type PostTemplatesTreeError = RemoteServiceErrorResponse; + +export type PostTemplatesListResponse = Array; + +export type PostTemplatesListError = RemoteServiceErrorResponse; + +export type PostTemplatesControlTypeResponse = Array; + +export type PostTemplatesControlTypeError = RemoteServiceErrorResponse; + +export type PostTemplatesTemplateTypeResponse = Array; + +export type PostTemplatesTemplateTypeError = RemoteServiceErrorResponse; + +export type PostTemplatesCopyData = { + body?: CopyTemplateInput; +}; + +export type PostTemplatesCopyResponse = unknown; + +export type PostTemplatesCopyError = RemoteServiceErrorResponse; + +export type PostTenantsFindData = { + body?: FindTenantByNameInput; +}; + +export type PostTenantsFindResponse = FindTenantResultDto; + +export type PostTenantsFindError = RemoteServiceErrorResponse; + +export type PostTenantsPageData = { + body?: PagingTenantInput; +}; + +export type PostTenantsPageResponse = TenantDtoPagedResultDto; + +export type PostTenantsPageError = RemoteServiceErrorResponse; + +export type PostTenantsCreateData = { + body?: TenantCreateDto; +}; + +export type PostTenantsCreateResponse = TenantDto; + +export type PostTenantsCreateError = RemoteServiceErrorResponse; + +export type PostTenantsUpdateData = { + body?: UpdateTenantInput; +}; + +export type PostTenantsUpdateResponse = TenantDto; + +export type PostTenantsUpdateError = RemoteServiceErrorResponse; + +export type PostTenantsDeleteData = { + body?: IdInput; +}; + +export type PostTenantsDeleteResponse = unknown; + +export type PostTenantsDeleteError = RemoteServiceErrorResponse; + +export type PostTenantsPageConnectionStringData = { + body?: PageTenantConnectionStringInput; +}; + +export type PostTenantsPageConnectionStringResponse = + PageTenantConnectionStringOutputPagedResultDto; + +export type PostTenantsPageConnectionStringError = RemoteServiceErrorResponse; + +export type PostTenantsAddOrUpdateConnectionStringData = { + body?: AddOrUpdateConnectionStringInput; +}; + +export type PostTenantsAddOrUpdateConnectionStringResponse = unknown; + +export type PostTenantsAddOrUpdateConnectionStringError = + RemoteServiceErrorResponse; + +export type PostTenantsDeleteConnectionStringData = { + body?: DeleteConnectionStringInput; +}; + +export type PostTenantsDeleteConnectionStringResponse = unknown; + +export type PostTenantsDeleteConnectionStringError = RemoteServiceErrorResponse; + +export type PostTextTemplatesPageData = { + body?: PageTextTemplateInput; +}; + +export type PostTextTemplatesPageResponse = + PageTextTemplateOutputPagedResultDto; + +export type PostTextTemplatesPageError = RemoteServiceErrorResponse; + +export type PostTextTemplatesCreateData = { + body?: CreateTextTemplateInput; +}; + +export type PostTextTemplatesCreateResponse = unknown; + +export type PostTextTemplatesCreateError = RemoteServiceErrorResponse; + +export type PostTextTemplatesUpdateData = { + body?: UpdateTextTemplateInput; +}; + +export type PostTextTemplatesUpdateResponse = unknown; + +export type PostTextTemplatesUpdateError = RemoteServiceErrorResponse; + +export type PostTextTemplatesDeleteData = { + body?: DeleteTextTemplateInput; +}; + +export type PostTextTemplatesDeleteResponse = unknown; + +export type PostTextTemplatesDeleteError = RemoteServiceErrorResponse; + +export type PostTextTemplatesExportData = { + body?: PageTextTemplateInput; +}; + +export type PostTextTemplatesExportResponse = Blob | File; + +export type PostTextTemplatesExportError = RemoteServiceErrorResponse; + +export type PostUsersPageData = { + body?: PagingUserListInput; +}; + +export type PostUsersPageResponse = PageIdentityUserOutputPagedResultDto; + +export type PostUsersPageError = RemoteServiceErrorResponse; + +export type PostUsersListData = { + body?: PagingUserListInput; +}; + +export type PostUsersListResponse = Array; + +export type PostUsersListError = RemoteServiceErrorResponse; + +export type PostUsersExportData = { + body?: PagingUserListInput; +}; + +export type PostUsersExportResponse = Blob | File; + +export type PostUsersExportError = RemoteServiceErrorResponse; + +export type PostUsersCreateData = { + body?: IdentityUserCreateDto; +}; + +export type PostUsersCreateResponse = IdentityUserDto; + +export type PostUsersCreateError = RemoteServiceErrorResponse; + +export type PostUsersUpdateData = { + body?: UpdateUserInput; +}; + +export type PostUsersUpdateResponse = IdentityUserDto; + +export type PostUsersUpdateError = RemoteServiceErrorResponse; + +export type PostUsersDeleteData = { + body?: IdInput; +}; + +export type PostUsersDeleteResponse = unknown; + +export type PostUsersDeleteError = RemoteServiceErrorResponse; + +export type PostUsersRoleData = { + body?: IdInput; +}; + +export type PostUsersRoleResponse = IdentityRoleDtoListResultDto; + +export type PostUsersRoleError = RemoteServiceErrorResponse; + +export type PostUsersChangePasswordData = { + body?: ChangePasswordInput; +}; + +export type PostUsersChangePasswordResponse = boolean; + +export type PostUsersChangePasswordError = RemoteServiceErrorResponse; + +export type PostUsersResetPasswordData = { + body?: ResetPasswordInput; +}; + +export type PostUsersResetPasswordResponse = boolean; + +export type PostUsersResetPasswordError = RemoteServiceErrorResponse; + +export type PostUsersLockData = { + body?: LockUserInput; +}; + +export type PostUsersLockResponse = unknown; + +export type PostUsersLockError = RemoteServiceErrorResponse; + +export type PostUsersFindByUserNameData = { + body?: FindByUserNameInput; +}; + +export type PostUsersFindByUserNameResponse = IdentityUserDto; + +export type PostUsersFindByUserNameError = RemoteServiceErrorResponse; + +export type PostUsersMyProfileResponse = MyProfileOutput; + +export type PostUsersMyProfileError = RemoteServiceErrorResponse; + +export type PostUsersCanUseTwoFactorResponse = boolean; + +export type PostUsersCanUseTwoFactorError = RemoteServiceErrorResponse; + +export type PostUsersGetQrCodeResponse = GetQRCodeOutput; + +export type PostUsersGetQrCodeError = RemoteServiceErrorResponse; + +export type PostUsersEnabledTwoFactorData = { + body?: EnabledTwoFactorInput; +}; + +export type PostUsersEnabledTwoFactorResponse = unknown; + +export type PostUsersEnabledTwoFactorError = RemoteServiceErrorResponse; + +export type PostUsersDisabledTwoFactorData = { + body?: DisabledTwoFactorInput; +}; + +export type PostUsersDisabledTwoFactorResponse = unknown; + +export type PostUsersDisabledTwoFactorError = RemoteServiceErrorResponse; + +export type PostUsersResetTwoFactorData = { + body?: ResetTwoFactorInput; +}; + +export type PostUsersResetTwoFactorResponse = unknown; + +export type PostUsersResetTwoFactorError = RemoteServiceErrorResponse; + +export type PostUsersNeedChangePasswordResponse = NeedChangePasswordOutput; + +export type PostUsersNeedChangePasswordError = RemoteServiceErrorResponse; diff --git a/apps/web-antd/src/api/core/auth.ts b/apps/web-antd/src/api/core/auth.ts new file mode 100644 index 0000000..71d9f99 --- /dev/null +++ b/apps/web-antd/src/api/core/auth.ts @@ -0,0 +1,51 @@ +import { baseRequestClient, requestClient } from '#/api/request'; + +export namespace AuthApi { + /** 登录接口参数 */ + export interface LoginParams { + password?: string; + username?: string; + } + + /** 登录接口返回值 */ + export interface LoginResult { + accessToken: string; + } + + export interface RefreshTokenResult { + data: string; + status: number; + } +} + +/** + * 登录 + */ +export async function loginApi(data: AuthApi.LoginParams) { + return requestClient.post('/auth/login', data); +} + +/** + * 刷新accessToken + */ +export async function refreshTokenApi() { + return baseRequestClient.post('/auth/refresh', { + withCredentials: true, + }); +} + +/** + * 退出登录 + */ +export async function logoutApi() { + return baseRequestClient.post('/auth/logout', { + withCredentials: true, + }); +} + +/** + * 获取用户权限码 + */ +export async function getAccessCodesApi() { + return requestClient.get('/auth/codes'); +} diff --git a/apps/web-antd/src/api/core/index.ts b/apps/web-antd/src/api/core/index.ts new file mode 100644 index 0000000..28a5aef --- /dev/null +++ b/apps/web-antd/src/api/core/index.ts @@ -0,0 +1,3 @@ +export * from './auth'; +export * from './menu'; +export * from './user'; diff --git a/apps/web-antd/src/api/core/menu.ts b/apps/web-antd/src/api/core/menu.ts new file mode 100644 index 0000000..e8ca4df --- /dev/null +++ b/apps/web-antd/src/api/core/menu.ts @@ -0,0 +1,39 @@ +/** + * 获取用户所有菜单 + */ +export async function getAllMenusApi() { + const dashboardMenus = [ + { + meta: { + order: -1, + title: 'page.dashboard.title', + }, + name: 'Dashboard', + path: '/dashboard', + redirect: '/analytics', + children: [ + { + name: 'Analytics', + path: '/analytics', + component: '/dashboard/analytics/index', + meta: { + affixTab: true, + title: 'page.dashboard.analytics', + authority: ['FileManagement.File1'], + }, + }, + { + name: 'Workspace', + path: '/workspace', + component: '/dashboard/workspace/index', + meta: { + title: 'page.dashboard.workspace', + }, + }, + ], + }, + ]; + debugger; + return dashboardMenus; + // return requestClient.get('/menu/all'); +} diff --git a/apps/web-antd/src/api/core/user.ts b/apps/web-antd/src/api/core/user.ts new file mode 100644 index 0000000..7e28ea8 --- /dev/null +++ b/apps/web-antd/src/api/core/user.ts @@ -0,0 +1,10 @@ +import type { UserInfo } from '@vben/types'; + +import { requestClient } from '#/api/request'; + +/** + * 获取用户信息 + */ +export async function getUserInfoApi() { + return requestClient.get('/user/info'); +} diff --git a/apps/web-antd/src/api/index.ts b/apps/web-antd/src/api/index.ts new file mode 100644 index 0000000..4b0e041 --- /dev/null +++ b/apps/web-antd/src/api/index.ts @@ -0,0 +1 @@ +export * from './core'; diff --git a/apps/web-antd/src/api/request.ts b/apps/web-antd/src/api/request.ts new file mode 100644 index 0000000..288dddd --- /dev/null +++ b/apps/web-antd/src/api/request.ts @@ -0,0 +1,113 @@ +/** + * 该文件可自行根据业务逻辑进行调整 + */ +import type { RequestClientOptions } from '@vben/request'; + +import { useAppConfig } from '@vben/hooks'; +import { preferences } from '@vben/preferences'; +import { + authenticateResponseInterceptor, + defaultResponseInterceptor, + errorMessageResponseInterceptor, + RequestClient, +} from '@vben/request'; +import { useAccessStore } from '@vben/stores'; + +import { message } from 'ant-design-vue'; + +import { useAuthStore } from '#/store'; + +import { refreshTokenApi } from './core'; + +const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD); + +function createRequestClient(baseURL: string, options?: RequestClientOptions) { + const client = new RequestClient({ + ...options, + baseURL, + }); + + /** + * 重新认证逻辑 + */ + async function doReAuthenticate() { + console.warn('Access token or refresh token is invalid or expired. '); + const accessStore = useAccessStore(); + const authStore = useAuthStore(); + accessStore.setAccessToken(null); + if ( + preferences.app.loginExpiredMode === 'modal' && + accessStore.isAccessChecked + ) { + accessStore.setLoginExpired(true); + } else { + await authStore.logout(); + } + } + + /** + * 刷新token逻辑 + */ + async function doRefreshToken() { + const accessStore = useAccessStore(); + const resp = await refreshTokenApi(); + const newToken = resp.data; + accessStore.setAccessToken(newToken); + return newToken; + } + + function formatToken(token: null | string) { + return token ? `Bearer ${token}` : null; + } + + // 请求头处理 + client.addRequestInterceptor({ + fulfilled: async (config) => { + const accessStore = useAccessStore(); + + config.headers.Authorization = formatToken(accessStore.accessToken); + config.headers['Accept-Language'] = preferences.app.locale; + return config; + }, + }); + + // 处理返回的响应数据格式 + client.addResponseInterceptor( + defaultResponseInterceptor({ + codeField: 'code', + dataField: 'data', + successCode: 0, + }), + ); + + // token过期的处理 + client.addResponseInterceptor( + authenticateResponseInterceptor({ + client, + doReAuthenticate, + doRefreshToken, + enableRefreshToken: preferences.app.enableRefreshToken, + formatToken, + }), + ); + + // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里 + client.addResponseInterceptor( + errorMessageResponseInterceptor((msg: string, error) => { + // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg + // 当前mock接口返回的错误字段是 error 或者 message + const responseData = error?.response?.data ?? {}; + const errorMessage = responseData?.error ?? responseData?.message ?? ''; + // 如果没有错误信息,则会根据状态码进行提示 + message.error(errorMessage || msg); + }), + ); + + return client; +} + +export const requestClient = createRequestClient(apiURL, { + responseReturn: 'data', +}); + +export const baseRequestClient = new RequestClient({ baseURL: apiURL }); diff --git a/apps/web-antd/src/app.vue b/apps/web-antd/src/app.vue new file mode 100644 index 0000000..bbaccce --- /dev/null +++ b/apps/web-antd/src/app.vue @@ -0,0 +1,39 @@ + + + diff --git a/apps/web-antd/src/bootstrap.ts b/apps/web-antd/src/bootstrap.ts new file mode 100644 index 0000000..7f9bde9 --- /dev/null +++ b/apps/web-antd/src/bootstrap.ts @@ -0,0 +1,81 @@ +import { createApp, watchEffect } from 'vue'; + +import { registerAccessDirective } from '@vben/access'; +import { registerLoadingDirective } from '@vben/common-ui/es/loading'; +import { preferences } from '@vben/preferences'; +import { initStores } from '@vben/stores'; +import '@vben/styles'; +import '@vben/styles/antd'; + +import { useTitle } from '@vueuse/core'; +// https://github.com/rennzhang/codemirror-editor-vue3 +import { InstallCodeMirror } from 'codemirror-editor-vue3'; +import JsonViewer from 'vue3-json-viewer'; + +import { $t, setupI18n } from '#/locales'; + +import { initComponentAdapter } from './adapter/component'; +import App from './app.vue'; +import { router } from './router'; + +// 加载本地图标 +// import '#/hooks/useLoadIcon'; +import 'vue3-json-viewer/dist/index.css'; + +async function bootstrap(namespace: string) { + // 初始化组件适配器 + await initComponentAdapter(); + + // // 设置弹窗的默认配置 + // setDefaultModalProps({ + // fullscreenButton: false, + // }); + // // 设置抽屉的默认配置 + // setDefaultDrawerProps({ + // zIndex: 1020, + // }); + + const app = createApp(App); + + // 注册v-loading指令 + registerLoadingDirective(app, { + loading: 'loading', // 在这里可以自定义指令名称,也可以明确提供false表示不注册这个指令 + spinning: 'spinning', + }); + + // 国际化 i18n 配置 + await setupI18n(app); + + // 配置 pinia-tore + await initStores(app, { namespace }); + + // 安装权限指令 + registerAccessDirective(app); + + // 初始化 tippy + const { initTippy } = await import('@vben/common-ui/es/tippy'); + initTippy(app); + + // 配置路由及路由守卫 + app.use(router); + // 配置 json-viewer + app.use(JsonViewer); + + // 配置Motion插件 + const { MotionPlugin } = await import('@vben/plugins/motion'); + app.use(MotionPlugin); + + // 动态更新标题 + watchEffect(() => { + if (preferences.app.dynamicTitle) { + const routeTitle = router.currentRoute.value.meta?.title; + const pageTitle = + (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name; + useTitle(pageTitle); + } + }); + app.use(InstallCodeMirror); + app.mount('#app'); +} + +export { bootstrap }; diff --git a/apps/web-antd/src/components/Loading/index.ts b/apps/web-antd/src/components/Loading/index.ts new file mode 100644 index 0000000..18bb3e9 --- /dev/null +++ b/apps/web-antd/src/components/Loading/index.ts @@ -0,0 +1,4 @@ +export { createLoading } from './src/createLoading'; +export { default as Loading } from './src/Loading.vue'; + +export { useLoading } from './src/useLoading'; diff --git a/apps/web-antd/src/components/Loading/src/Loading.vue b/apps/web-antd/src/components/Loading/src/Loading.vue new file mode 100644 index 0000000..c3ad8c6 --- /dev/null +++ b/apps/web-antd/src/components/Loading/src/Loading.vue @@ -0,0 +1,78 @@ + + + diff --git a/apps/web-antd/src/components/Loading/src/createLoading.ts b/apps/web-antd/src/components/Loading/src/createLoading.ts new file mode 100644 index 0000000..1e07b03 --- /dev/null +++ b/apps/web-antd/src/components/Loading/src/createLoading.ts @@ -0,0 +1,84 @@ +import type { LoadingProps } from './typing'; + +import { createVNode, defineComponent, h, reactive, render } from 'vue'; + +import Loading from './Loading.vue'; + +// 创建一个加载组件的函数 +export function createLoading( + props?: Partial, + target?: HTMLElement, + wait = false, +) { + let vm: any = null; + const data = reactive({ + tip: '', + loading: true, + ...props, + }); + + // 定义加载组件的包装 + const LoadingWrap = defineComponent({ + render() { + return h(Loading, { ...data }); + }, + }); + + vm = createVNode(LoadingWrap); + + let container: any = null; + // 根据wait参数决定何时渲染Loading组件 + if (wait) { + setTimeout(() => { + render(vm, (container = document.createElement('div'))); + }, 0); + } else { + render(vm, (container = document.createElement('div'))); + } + + // 关闭加载组件的函数 + function close() { + if (vm?.el && vm.el.parentNode) { + vm.el.remove(); + } + } + + // 打开加载组件并将其附加到目标元素上的函数 + function open(target: HTMLElement = document.body) { + if (!vm || !vm.el) { + return; + } + target.append(vm.el as HTMLElement); + } + + // 销毁加载组件的函数 + function destroy() { + container && render(null, container); + container = vm = null; + } + + // 如果提供了目标元素,则打开加载组件 + if (target) { + open(target); + } + + // 返回加载组件的实例及控制方法 + return { + vm, + close, + open, + destroy, + setTip: (tip: string) => { + data.tip = tip; + }, + setLoading: (loading: boolean) => { + data.loading = loading; + }, + get loading() { + return data.loading; + }, + get $el() { + return vm?.el as HTMLElement; + }, + }; +} diff --git a/apps/web-antd/src/components/Loading/src/typing.ts b/apps/web-antd/src/components/Loading/src/typing.ts new file mode 100644 index 0000000..8805acd --- /dev/null +++ b/apps/web-antd/src/components/Loading/src/typing.ts @@ -0,0 +1,14 @@ +export enum SizeEnum { + DEFAULT = 'default', + LARGE = 'large', + SMALL = 'small', +} + +export interface LoadingProps { + tip: string; + size: SizeEnum; + absolute: boolean; + loading: boolean; + background: string; + theme: 'dark' | 'light'; +} diff --git a/apps/web-antd/src/components/Loading/src/useLoading.ts b/apps/web-antd/src/components/Loading/src/useLoading.ts new file mode 100644 index 0000000..8f5cc51 --- /dev/null +++ b/apps/web-antd/src/components/Loading/src/useLoading.ts @@ -0,0 +1,62 @@ +import type { Ref } from 'vue'; + +import type { LoadingProps } from './typing'; + +import { unref } from 'vue'; + +import { tryOnUnmounted } from '@vueuse/core'; + +import { createLoading } from './createLoading'; + +export interface UseLoadingOptions { + target?: any; + props?: Partial; +} + +interface Fn { + (): void; +} + +export function useLoading( + props: Partial, +): [Fn, Fn, (arg0: string) => void]; +export function useLoading( + opt: Partial, +): [Fn, Fn, (arg0: string) => void]; + +export function useLoading( + opt: Partial | Partial, +): [Fn, Fn, (arg0: string) => void] { + let props: Partial; + let target: HTMLElement | Ref = document.body; + + if (Reflect.has(opt, 'target') || Reflect.has(opt, 'props')) { + const options = opt as Partial; + props = options.props || {}; + target = options.target || document.body; + } else { + props = opt as Partial; + } + + const instance = createLoading(props, undefined, false); + + const open = (): void => { + const t = unref(target as Ref); + if (!t) return; + instance.open(t); + }; + + const close = (): void => { + instance.close(); + }; + + const setTip = (tip: string) => { + instance.setTip(tip); + }; + + tryOnUnmounted(() => { + instance.destroy(); + }); + + return [open, close, setTip]; +} diff --git a/apps/web-antd/src/components/icon/icon.vue b/apps/web-antd/src/components/icon/icon.vue new file mode 100644 index 0000000..e5c0c31 --- /dev/null +++ b/apps/web-antd/src/components/icon/icon.vue @@ -0,0 +1,51 @@ + + + + diff --git a/apps/web-antd/src/components/icon/index.ts b/apps/web-antd/src/components/icon/index.ts new file mode 100644 index 0000000..fc98972 --- /dev/null +++ b/apps/web-antd/src/components/icon/index.ts @@ -0,0 +1 @@ +export { default as Icon } from './icon.vue'; diff --git a/apps/web-antd/src/components/table-action/index.ts b/apps/web-antd/src/components/table-action/index.ts new file mode 100644 index 0000000..00b7e6b --- /dev/null +++ b/apps/web-antd/src/components/table-action/index.ts @@ -0,0 +1,2 @@ +export { default as TableAction } from './table-action.vue'; +export type * from './types.d.ts'; diff --git a/apps/web-antd/src/components/table-action/table-action.vue b/apps/web-antd/src/components/table-action/table-action.vue new file mode 100644 index 0000000..139ba45 --- /dev/null +++ b/apps/web-antd/src/components/table-action/table-action.vue @@ -0,0 +1,227 @@ + + + + diff --git a/apps/web-antd/src/components/table-action/types.d.ts b/apps/web-antd/src/components/table-action/types.d.ts new file mode 100644 index 0000000..29e7d4d --- /dev/null +++ b/apps/web-antd/src/components/table-action/types.d.ts @@ -0,0 +1,26 @@ +import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'; +import { TooltipProps } from 'ant-design-vue/es/tooltip/Tooltip'; + +export interface PopConfirm { + title: string; + okText?: string; + cancelText?: string; + confirm: Fn; + cancel?: Fn; + icon?: string; + disabled?: boolean; +} +export interface ActionItem extends ButtonProps { + onClick?: Fn; + label?: string; + color?: 'error' | 'success' | 'warning'; + icon?: string; + popConfirm?: PopConfirm; + disabled?: boolean; + divider?: boolean; + // 权限编码控制是否显示 + auth?: string[]; + // 业务控制是否显示 + ifShow?: ((action: ActionItem) => boolean) | boolean; + tooltip?: string | TooltipProps; +} diff --git a/apps/web-antd/src/hooks/useLoadIcon.ts b/apps/web-antd/src/hooks/useLoadIcon.ts new file mode 100644 index 0000000..90119d2 --- /dev/null +++ b/apps/web-antd/src/hooks/useLoadIcon.ts @@ -0,0 +1,23 @@ +import { addCollection } from '@vben/icons'; + +import AntDesignIcons from '@iconify/json/json/ant-design.json'; +import CarbonIcons from '@iconify/json/json/carbon.json'; +import EpIcons from '@iconify/json/json/ep.json'; +import IcIcons from '@iconify/json/json/ic.json'; +import LogosIcons from '@iconify/json/json/logos.json'; +import LucideIcons from '@iconify/json/json/lucide.json'; +import MdiIcons from '@iconify/json/json/mdi.json'; +import OuiIcons from '@iconify/json/json/oui.json'; +import PhosphorIcons from '@iconify/json/json/ph.json'; +import UnIcons from '@iconify/json/json/uil.json'; + +addCollection(AntDesignIcons); +addCollection(LucideIcons); +addCollection(CarbonIcons); +addCollection(IcIcons as any); +addCollection(LogosIcons as any); +addCollection(PhosphorIcons as any); +addCollection(UnIcons); +addCollection(OuiIcons); +addCollection(MdiIcons); +addCollection(EpIcons); diff --git a/apps/web-antd/src/hooks/useSignalR.ts b/apps/web-antd/src/hooks/useSignalR.ts new file mode 100644 index 0000000..be1f038 --- /dev/null +++ b/apps/web-antd/src/hooks/useSignalR.ts @@ -0,0 +1,127 @@ +import { useEventbus } from '@vben/hooks'; +import { useUserStore } from '@vben/stores'; + +import * as signalR from '@microsoft/signalr'; +import { notification } from 'ant-design-vue'; + +const eventbus = useEventbus(); +let connection: signalR.HubConnection; +export function useSignalR() { + /** + * 开始连接SignalR + */ + async function startConnect() { + try { + const userStore = useUserStore(); + if (userStore.checkUserLoginExpire()) { + console.debug('未检测到用户信息,登录之后才会链接SignalR.'); + return; + } + connectionsignalR(); + await connection.start(); + } catch (error) { + console.error(error); + setTimeout(() => startConnect(), 5000); + } + } + + /** + * 关闭SignalR连接 + */ + function closeConnect(): void { + connection?.stop(); + } + + async function connectionsignalR() { + const userStore = useUserStore(); + const token = userStore.userInfo?.token; + connection = new signalR.HubConnectionBuilder() + .withUrl(import.meta.env.VITE_WEBSOCKET_URL, { + accessTokenFactory: () => token, + skipNegotiation: true, + transport: signalR.HttpTransportType.WebSockets, + }) + .withAutomaticReconnect({ + nextRetryDelayInMilliseconds: (retryContext) => { + // 重连规则:重连次数<300:间隔1s;重试次数<3000:间隔3s;重试次数>3000:间隔30s + const count = retryContext.previousRetryCount / 300; + if (count < 1) { + // 重试次数<300,间隔1s + return 1000; + } else if (count < 10) { + // 重试次数>300:间隔5s + return 1000 * 5; + } // 重试次数>3000:间隔30s + else { + return 1000 * 30; + } + }, + }) + .configureLogging(signalR.LogLevel.Debug) + .build(); + + // 接收普通文本消息 + connection.on('ReceiveTextMessageAsync', ReceiveTextMessageHandlerAsync); + // 接收广播消息 + connection.on( + 'ReceiveBroadCastMessageAsync', + ReceiveBroadCastMessageHandlerAsync, + ); + } + + /** + * 接收文本消息 + * @param message 消息体 + */ + function ReceiveTextMessageHandlerAsync(message: any) { + // 发布事件 + eventbus.publish('ReceiveTextMessageHandlerAsync', message); + if (message.messageLevel === 10) { + notification.warn({ + description: message.content, + message: message.title, + }); + } + if (message.messageLevel === 20) { + notification.info({ + message: message.title, + description: message.content, + }); + } + if (message.messageLevel === 30) { + notification.error({ + message: message.title, + description: message.content, + }); + } + } + + /** + * 接收广播消息 + * @param message 消息体 + */ + function ReceiveBroadCastMessageHandlerAsync(message: any) { + // 发布事件 + eventbus.publish('ReceiveTextMessageHandlerAsync', message); + if (message.messageLevel === 10) { + notification.warn({ + message: message.title, + description: message.content, + }); + } + if (message.messageLevel === 20) { + notification.info({ + message: message.title, + description: message.content, + }); + } + if (message.messageLevel === 30) { + notification.error({ + message: message.title, + description: message.content, + }); + } + } + + return { startConnect, closeConnect }; +} diff --git a/apps/web-antd/src/layouts/NotifyItem.vue b/apps/web-antd/src/layouts/NotifyItem.vue new file mode 100644 index 0000000..7101ad2 --- /dev/null +++ b/apps/web-antd/src/layouts/NotifyItem.vue @@ -0,0 +1,207 @@ + + + + + diff --git a/apps/web-antd/src/layouts/auth.vue b/apps/web-antd/src/layouts/auth.vue new file mode 100644 index 0000000..18d415b --- /dev/null +++ b/apps/web-antd/src/layouts/auth.vue @@ -0,0 +1,23 @@ + + + diff --git a/apps/web-antd/src/layouts/basic.vue b/apps/web-antd/src/layouts/basic.vue new file mode 100644 index 0000000..ae1237d --- /dev/null +++ b/apps/web-antd/src/layouts/basic.vue @@ -0,0 +1,281 @@ + + + diff --git a/apps/web-antd/src/layouts/change-password.vue b/apps/web-antd/src/layouts/change-password.vue new file mode 100644 index 0000000..db48135 --- /dev/null +++ b/apps/web-antd/src/layouts/change-password.vue @@ -0,0 +1,108 @@ + + + diff --git a/apps/web-antd/src/layouts/index.ts b/apps/web-antd/src/layouts/index.ts new file mode 100644 index 0000000..a432078 --- /dev/null +++ b/apps/web-antd/src/layouts/index.ts @@ -0,0 +1,6 @@ +const BasicLayout = () => import('./basic.vue'); +const AuthPageLayout = () => import('./auth.vue'); + +const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView); + +export { AuthPageLayout, BasicLayout, IFrameView }; diff --git a/apps/web-antd/src/layouts/my-profile.vue b/apps/web-antd/src/layouts/my-profile.vue new file mode 100644 index 0000000..e94cf35 --- /dev/null +++ b/apps/web-antd/src/layouts/my-profile.vue @@ -0,0 +1,403 @@ + + + diff --git a/apps/web-antd/src/locales/README.md b/apps/web-antd/src/locales/README.md new file mode 100644 index 0000000..7b45103 --- /dev/null +++ b/apps/web-antd/src/locales/README.md @@ -0,0 +1,3 @@ +# locale + +每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。 diff --git a/apps/web-antd/src/locales/index.ts b/apps/web-antd/src/locales/index.ts new file mode 100644 index 0000000..7f32bd1 --- /dev/null +++ b/apps/web-antd/src/locales/index.ts @@ -0,0 +1,102 @@ +import type { Locale } from 'ant-design-vue/es/locale'; + +import type { App } from 'vue'; + +import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales'; + +import { ref } from 'vue'; + +import { + $t, + setupI18n as coreSetup, + loadLocalesMapFromDir, +} from '@vben/locales'; +import { preferences } from '@vben/preferences'; + +import antdEnLocale from 'ant-design-vue/es/locale/en_US'; +import antdDefaultLocale from 'ant-design-vue/es/locale/zh_CN'; +import dayjs from 'dayjs'; + +const antdLocale = ref(antdDefaultLocale); + +const modules = import.meta.glob('./langs/**/*.json'); + +const localesMap = loadLocalesMapFromDir( + /\.\/langs\/([^/]+)\/(.*)\.json$/, + modules, +); +/** + * 加载应用特有的语言包 + * 这里也可以改造为从服务端获取翻译数据 + * @param lang + */ +async function loadMessages(lang: SupportedLanguagesType) { + const [appLocaleMessages] = await Promise.all([ + localesMap[lang]?.(), + loadThirdPartyMessage(lang), + ]); + return appLocaleMessages?.default; +} + +/** + * 加载第三方组件库的语言包 + * @param lang + */ +async function loadThirdPartyMessage(lang: SupportedLanguagesType) { + await Promise.all([loadAntdLocale(lang), loadDayjsLocale(lang)]); +} + +/** + * 加载dayjs的语言包 + * @param lang + */ +async function loadDayjsLocale(lang: SupportedLanguagesType) { + let locale; + switch (lang) { + case 'en-US': { + locale = await import('dayjs/locale/en'); + break; + } + case 'zh-CN': { + locale = await import('dayjs/locale/zh-cn'); + break; + } + // 默认使用英语 + default: { + locale = await import('dayjs/locale/en'); + } + } + if (locale) { + dayjs.locale(locale); + } else { + console.error(`Failed to load dayjs locale for ${lang}`); + } +} + +/** + * 加载antd的语言包 + * @param lang + */ +async function loadAntdLocale(lang: SupportedLanguagesType) { + switch (lang) { + case 'en-US': { + antdLocale.value = antdEnLocale; + break; + } + case 'zh-CN': { + antdLocale.value = antdDefaultLocale; + break; + } + } +} + +async function setupI18n(app: App, options: LocaleSetupOptions = {}) { + await coreSetup(app, { + defaultLocale: preferences.app.locale, + loadMessages, + missingWarn: !import.meta.env.PROD, + ...options, + }); +} + +export { $t, antdLocale, setupI18n }; diff --git a/apps/web-antd/src/locales/langs/en-US/abp.json b/apps/web-antd/src/locales/langs/en-US/abp.json new file mode 100644 index 0000000..cab0e93 --- /dev/null +++ b/apps/web-antd/src/locales/langs/en-US/abp.json @@ -0,0 +1,163 @@ +{ + "login": { + "selectTenant": "Please select Tenant and ignore the non-tenant mode", + "inputCode": "Please enter the two-factor authentication code. If two-factor authentication has not been enabled for your account, please ignore this message.", + "oidcTip": "Login......" + }, + "menu": { + "system": "SystemManagement", + "user": "UserManagement", + "role": "RoleManagement", + "tenant": "TenantManagement", + "tenantList": "TenantList", + "language": "LanguageManagement", + "auditLog": "AuditLog", + "loginLog": "LoginLog", + "feature": "FeatureManagement", + "setting": "SettingsManagement", + "organizationUnit": "OrganizationUnitManagement", + "languageText": "LanguageTextManagement", + "dataDictionary": "DataDictionaryManagement", + "notification": "NotificationManagement", + "message": "MessageManagement", + "code": "CodeManagement", + "code-project": "ProjectList", + "code-template": "TemplateList", + "code-genarate": "CodeGenarate", + "code-entity": "Entity", + "code-template-detail": "TemplateDetail", + "code-Preview": "Preview", + "file": "FileManagement", + "menu": "MenuManagement" + }, + "user": { + "user": "User", + "userName": "UserName", + "name": "Name", + "surname": "Surname", + "email": "Email", + "phone": "Phone", + "password": "Password", + "currentPassword": "CurrentPassword", + "newPassword": "NewPassword", + "confirmNewPassword": "ConfirmNewPassword", + "changePassword": "ChangePassword", + "resetPassword": "ResetPassword", + "status": "Status", + "comfirmPassword": "ComfirmPassword", + "comfirmDeleteUser": "Are you sure you want to delete the user", + "newPasswordAndConfirmPasswordNotMatch": "New password and confirm password not match", + "newPasswordAndCurrentPasswordNotAlike": "The old and new passwords cannot be the same", + "myProfile": "MyProfile", + "myAccount": "MyAccount", + "twoFactor": "TwoFactor", + "verifyAuthenticator": "Verify the Authenticator", + "twoFactorDesc": "Your two-factor authentication app will generate a code. Please enter the code and confirm it.", + "code": "TwoFactor Code", + "twoFactorEnabled": "Two-factor authentication for your account has been successfully enabled. You will be required to enter the code generated by the application when logging in.", + "twoFactorDisabled": "Two-factor authentication for your account has been turned off. You will no longer be required to enter the code generated by the application when logging in.", + "twoFactorEnabledDesc": "Two-factor authentication has been enabled for your account. If you need to turn it off, please enter the two-factor authentication code and then disable it.", + "resetTwoFactor": "ResetTwoFactor" + }, + "role": { + "role": "Role", + "roleName": "RoleName", + "isDefault": "IsDefault", + "permissions": "Permissions" + }, + "log": { + "loginTime": "LoginTime", + "userName": "UserName", + "tenant": "Tenant", + "executionTime": "ExecutionTime", + "responseTime": "ResponseTime(ms)", + "clientIp": "ClientIp", + "exception": "Exception", + "applicationName": "ApplicationName", + "loginMode": "LoginMode", + "loginUrl": "LoginUrl", + "detail": "Detail" + }, + "message": { + "title": "Title", + "content": "Content", + "type": "Type", + "level": "Level", + "sender": "Sender", + "receiver": "Receiver", + "isRead": "IsRead", + "sendMessage": "SendMessage", + "sendNotification": "SendNotification", + "setRead": "SetRead", + "confirmRead": "Are you sure you want to set the message as read?", + "read": "Read", + "unread": "UnRead" + }, + "language": { + "language": "LanguageName", + "showLanguage": "ShowLanguageName", + "icon": "Icon", + "resourceName": "ResourceName", + "value": "Value", + "name": "Name" + }, + "dataDictionary": { + "codeName": "Code|Name", + "code": "Code", + "name": "Name", + "order": "Order", + "status": "Status", + "description": "Description", + "type": "Type" + }, + "organizationunit": { + "organizationunit": "Organizationunit", + "add": "Add", + "member": "Member", + "role": "Role", + "userName": "UserName", + "email": "Email", + "name": "Name", + "selectNode": "Select a node to operate on" + }, + "tenant": { + "tenant": "Tenant", + "notExist": "Tenant Does not exist", + "name": "Tenant Name", + "adminEmail": "Admin Email", + "adminPassword": "Admin Password", + "mangeConnectionString": "MangeConnectionString", + "addorEdit": "AddorEdit", + "featureManagement": "FeatureManagement", + "connectionStringName": "ConnectionStringName", + "connectionString": "ConnectionString" + }, + "file": { + "file": "File", + "name": "FileName", + "size": "Size", + "contentType": "ContentType" + }, + "dynamicMenu": { + "name": "RouteName", + "title": "Title", + "displayTitle": "DisplayTitle", + "path": "Path", + "component": "Component", + "policy": "Policy", + "menuType": "MenuType", + "enabled": "Enabled", + "hideInMenu": "HideInMenu", + "keepAlive": "keepAlive", + "order": "Order", + "openType": "OpenType", + "parentId": "Parent", + "icon": "Icon", + "url": "Url", + "menu": "Menu", + "folder": "Folder", + "componentType": "Component", + "internalLink": "InternalLink", + "externalLink": "ExternalLink" + } +} diff --git a/apps/web-antd/src/locales/langs/en-US/code.json b/apps/web-antd/src/locales/langs/en-US/code.json new file mode 100644 index 0000000..4dab556 --- /dev/null +++ b/apps/web-antd/src/locales/langs/en-US/code.json @@ -0,0 +1,37 @@ +{ + "companyName": "CompanyName", + "projectName": "ProjectName", + "projectEnglishName": "ProjectEnglishName", + "namespace": "Namespace", + "remark": "Remark", + "templateName": "TemplateName", + "model": "Model", + "property": "Property", + "enum": "Enum", + "isRequired": "IsRequired", + "maxLength": "MaxLength", + "minLength": "MinLength", + "decimalPrecision18": "Accuracy (18,6) of 18", + "decimalPrecision6": "Accuracy (18,6) of 6", + "pleaseSelectEntity": "Please select entity", + "pleaseSelectEnum": "Please select enum", + "detail": "Detail", + "copy": "Copy", + "addFolder": "AddFolder", + "addFile": "AddFile", + "desc": "Description", + "name": "Name", + "templateType": "TemplateType", + "supportTenant": "Support Multi-Tenant", + "project": "Project", + "template": "Template", + "preview": "Preview", + "download": "Download", + "description": "Please select the target and project to generate", + "autoGenerate": "Auto Generate Code", + "code": "Code", + "type": "Type", + "value": "Value", + "relational": "Relational", + "dataType": "DataType" +} diff --git a/apps/web-antd/src/locales/langs/en-US/common.json b/apps/web-antd/src/locales/langs/en-US/common.json new file mode 100644 index 0000000..85b3a51 --- /dev/null +++ b/apps/web-antd/src/locales/langs/en-US/common.json @@ -0,0 +1,41 @@ +{ + "add": "Add", + "edit": "Edit", + "delete": "Delete", + "search": "Search", + "export": "Export", + "save": "save", + "seq": "Seq", + "isEnable": "IsEnable", + "enabled": "Enabled", + "disabled": "Disabled", + "action": "Action", + "createTime": "CreationTime", + "pleaseInput": "Please input", + "addSuccess": "Add Success", + "editSuccess": "Edit Success", + "deleteSuccess": "Delete Success", + "yes": "yes", + "no": "no", + "confirmDelete": "Confirm to delete", + "askConfirmDelete": "Confirm to delete?", + "warning": "warning", + "info": "info", + "error": "error", + "success": "Success", + "keyword": "Keyword", + "mesage403": "You don't have permission to access this page or function!", + "mesage401": "You are not logged in or the login has timed out. Please log in again!", + "mesage500": "Internal server error!", + "mesage404": "The page you are trying to access does not exist!", + "mesage400": "Request error!", + "mesage405": "Incorrect request method!", + "timeOut": "Request timed out!", + "expandAll": "EexpandAll", + "collapseAll": "CollapseAll", + "description": "description", + "comfirm": "Comfirm", + "valid": "Valid", + "upload": "Upload", + "download": "Download" +} diff --git a/apps/web-antd/src/locales/langs/en-US/demos.json b/apps/web-antd/src/locales/langs/en-US/demos.json new file mode 100644 index 0000000..0715643 --- /dev/null +++ b/apps/web-antd/src/locales/langs/en-US/demos.json @@ -0,0 +1,12 @@ +{ + "title": "Demos", + "antd": "Ant Design Vue", + "vben": { + "title": "Project", + "about": "About", + "document": "Document", + "antdv": "Ant Design Vue Version", + "naive-ui": "Naive UI Version", + "element-plus": "Element Plus Version" + } +} diff --git a/apps/web-antd/src/locales/langs/en-US/page.json b/apps/web-antd/src/locales/langs/en-US/page.json new file mode 100644 index 0000000..7975ddf --- /dev/null +++ b/apps/web-antd/src/locales/langs/en-US/page.json @@ -0,0 +1,15 @@ +{ + "auth": { + "login": "Login", + "register": "Register", + "codeLogin": "Code Login", + "qrcodeLogin": "Qr Code Login", + "forgetPassword": "Forget Password", + "thirdPartyLogin": "Third Party Login" + }, + "dashboard": { + "title": "Dashboard", + "analytics": "Analytics", + "workspace": "Workspace" + } +} diff --git a/apps/web-antd/src/locales/langs/en-US/textTemplate.json b/apps/web-antd/src/locales/langs/en-US/textTemplate.json new file mode 100644 index 0000000..1fd5d89 --- /dev/null +++ b/apps/web-antd/src/locales/langs/en-US/textTemplate.json @@ -0,0 +1,8 @@ +{ + "templateManagement": "TemplateManagement", + "templateList": "TemplateList", + "name": "Name", + "code": "Code", + "content": "Content", + "cultureName": "Language" +} diff --git a/apps/web-antd/src/locales/langs/zh-CN/abp.json b/apps/web-antd/src/locales/langs/zh-CN/abp.json new file mode 100644 index 0000000..ee05d2f --- /dev/null +++ b/apps/web-antd/src/locales/langs/zh-CN/abp.json @@ -0,0 +1,163 @@ +{ + "login": { + "selectTenant": "请选择租户,非租户模式请忽略", + "inputCode": "请输入双因素验证码,如果账户没有开启双因素验证请忽略", + "oidcTip": "登陆中......" + }, + "menu": { + "system": "系统管理", + "user": "用户管理", + "role": "角色管理", + "tenant": "租户管理", + "tenantList": "租户列表", + "language": "语言管理", + "auditLog": "审计日志", + "loginLog": "登录日志", + "feature": "功能管理", + "setting": "设置管理", + "organizationUnit": "组织机构管理", + "languageText": "语言文本管理", + "dataDictionary": "数据字典管理", + "notification": "通告管理", + "message": "消息管理", + "code": "代码管理", + "code-project": "项目列表", + "code-template": "模板列表", + "code-genarate": "代码生成", + "code-entity": "实体", + "code-template-detail": "模板详情", + "code-Preview": "预览", + "file": "文件管理", + "menu": "菜单管理" + }, + "user": { + "user": "用户", + "userName": "用户名", + "name": "名称", + "surname": "姓氏", + "email": "邮箱", + "phone": "手机号", + "password": "密码", + "currentPassword": "当前密码", + "newPassword": "新密码", + "confirmNewPassword": "确认新密码", + "changePassword": "修改密码", + "resetPassword": "重置密码", + "status": "状态", + "comfirmPassword": "确认密码", + "comfirmDeleteUser": "确认删除用户", + "newPasswordAndConfirmPasswordNotMatch": "新密码与确认密码不匹配", + "newPasswordAndCurrentPasswordNotAlike": "新旧密码不能一样", + "myProfile": "个人信息", + "myAccount": "我的账户", + "twoFactor": "双因素验证", + "verifyAuthenticator": "验证身份验证器", + "twoFactorDesc": "您的双因素身份验证应用程序将生成一个代码,请输入该代码并确认.", + "code": "双因素验证码", + "twoFactorEnabled": "您的账户已经成功开启双因素验证,登录时要求输入应用程序生成的代码.", + "twoFactorDisabled": "您的账户已经关闭双因素验证,登录时不在要求输入应用程序生成的代码.", + "twoFactorEnabledDesc": "您的账户已经开启双因素验证,如果需要关闭,请输入双因素验证码,然后在禁用.如果忘记验证码,请联系管理员.", + "resetTwoFactor": "重置双因素验证" + }, + "role": { + "role": "角色", + "roleName": "角色名称", + "isDefault": "是否默认", + "permissions": "授权" + }, + "log": { + "loginTime": "登录时间", + "userName": "用户名", + "tenant": "租户", + "executionTime": "执行时间", + "responseTime": "响应时间(毫秒)", + "clientIp": "客户端Ip", + "exception": "异常", + "applicationName": "应用名称", + "loginMode": "登录方式", + "loginUrl": "登录地址", + "detail": "详情" + }, + "message": { + "title": "标题", + "content": "内容", + "type": "类型", + "level": "级别", + "sender": "发送人", + "receiver": "接收人", + "isRead": "是否已读", + "sendMessage": "发送消息", + "sendNotification": "发送通告", + "setRead": "设置已读", + "confirmRead": "确认设置已读?", + "read": "已读", + "unread": "未读" + }, + "language": { + "language": "语言名称", + "showLanguage": "显示名称", + "icon": "图标", + "resourceName": "资源名称", + "value": "值", + "name": "名称" + }, + "dataDictionary": { + "codeName": "编码|名称", + "code": "编码", + "name": "名称", + "order": "排序", + "status": "状态", + "description": "描述", + "type": "字典类型" + }, + "organizationunit": { + "organizationunit": "组织机构", + "add": "新增根机构", + "member": "成员", + "role": "角色", + "userName": "用户名", + "email": "邮箱", + "name": "名称", + "selectNode": "请先选择一个节点再进行操作" + }, + "tenant": { + "tenant": "租户", + "notExist": "租户不存在", + "name": "租户名称", + "adminEmail": "管理员邮箱", + "adminPassword": "管理员密码", + "mangeConnectionString": "管理链接字符串", + "addorEdit": "新增或编辑", + "featureManagement": "功能管理", + "connectionStringName": "连接名称", + "connectionString": "连接字符串" + }, + "file": { + "file": "文件", + "name": "文件名称", + "size": "文件大小", + "contentType": "文件类型" + }, + "dynamicMenu": { + "name": "路由名称", + "title": "标题", + "displayTitle": "标题(多语言)", + "path": "路由地址", + "component": "组件地址", + "policy": "授权策略", + "menuType": "菜单类型", + "enabled": "是否启用", + "hideInMenu": "是否隐藏", + "keepAlive": "是否缓存", + "order": "排序", + "openType": "打开类型", + "parentId": "所属上级", + "icon": "图标", + "url": "内外链地址", + "menu": "菜单", + "folder": "目录", + "componentType": "组件", + "internalLink": "内链", + "externalLink": "外链" + } +} diff --git a/apps/web-antd/src/locales/langs/zh-CN/code.json b/apps/web-antd/src/locales/langs/zh-CN/code.json new file mode 100644 index 0000000..1032454 --- /dev/null +++ b/apps/web-antd/src/locales/langs/zh-CN/code.json @@ -0,0 +1,37 @@ +{ + "companyName": "公司名称", + "projectName": "项目名称", + "projectEnglishName": "项目英文名称", + "namespace": "命名空间", + "remark": "备注", + "templateName": "模板名称", + "model": "模型", + "property": "属性", + "enum": "枚举", + "isRequired": "是否必填", + "maxLength": "最大长度", + "minLength": "最小长度", + "decimalPrecision18": "精度(18,6)中的18", + "decimalPrecision6": "精度(18,6)中的6", + "pleaseSelectEntity": "请选择实体", + "pleaseSelectEnum": "请选择枚举", + "detail": "详情", + "copy": "复制", + "addFolder": "新增文件夹", + "addFile": "新增文件", + "desc": "描述", + "name": "名称", + "templateType": "模板类型", + "supportTenant": "支持多租户", + "project": "项目", + "template": "模板", + "preview": "预览", + "download": "下载", + "description": "请选择要生成的目标和项目", + "autoGenerate": "自动生成代码", + "code": "编码", + "type": "类型", + "value": "值", + "relational": "关系", + "dataType": "数据类型" +} diff --git a/apps/web-antd/src/locales/langs/zh-CN/common.json b/apps/web-antd/src/locales/langs/zh-CN/common.json new file mode 100644 index 0000000..3204c62 --- /dev/null +++ b/apps/web-antd/src/locales/langs/zh-CN/common.json @@ -0,0 +1,41 @@ +{ + "add": "新增", + "edit": "编辑", + "delete": "删除", + "search": "搜索", + "save": "保存", + "export": "导出", + "isEnable": "是否启用", + "enabled": "启用", + "disabled": "禁用", + "seq": "序号", + "action": "操作", + "createTime": "创建时间", + "pleaseInput": "请输入", + "addSuccess": "新增成功!", + "editSuccess": "编辑成功!", + "deleteSuccess": "删除成功!", + "yes": "是", + "no": "否", + "confirmDelete": "确认删除", + "askConfirmDelete": "确认删除吗?", + "warning": "警告", + "info": "正常", + "error": "错误", + "success": "成功", + "keyword": "关键字", + "mesage403": "您没有权限访问此页面或功能!", + "mesage401": "未登录或登录已超时,请重新登录!", + "mesage500": "服务器内部错误!", + "mesage404": "您访问的页面不存在!", + "mesage400": "请求错误!", + "mesage405": "请求方法错误!", + "timeOut": "请求超时!", + "expandAll": "展开全部", + "collapseAll": "折叠全部", + "description": "描述", + "comfirm": "确认", + "valid": "验证", + "upload": "上传", + "download": "下载" +} diff --git a/apps/web-antd/src/locales/langs/zh-CN/demos.json b/apps/web-antd/src/locales/langs/zh-CN/demos.json new file mode 100644 index 0000000..93ee722 --- /dev/null +++ b/apps/web-antd/src/locales/langs/zh-CN/demos.json @@ -0,0 +1,12 @@ +{ + "title": "演示", + "antd": "Ant Design Vue", + "vben": { + "title": "项目", + "about": "关于", + "document": "文档", + "antdv": "Ant Design Vue 版本", + "naive-ui": "Naive UI 版本", + "element-plus": "Element Plus 版本" + } +} diff --git a/apps/web-antd/src/locales/langs/zh-CN/page.json b/apps/web-antd/src/locales/langs/zh-CN/page.json new file mode 100644 index 0000000..39a4f45 --- /dev/null +++ b/apps/web-antd/src/locales/langs/zh-CN/page.json @@ -0,0 +1,15 @@ +{ + "auth": { + "login": "登录", + "register": "注册", + "codeLogin": "验证码登录", + "qrcodeLogin": "二维码登录", + "forgetPassword": "忘记密码", + "thirdPartyLogin": "第三方登录" + }, + "dashboard": { + "title": "概览", + "analytics": "分析页", + "workspace": "工作台" + } +} diff --git a/apps/web-antd/src/locales/langs/zh-CN/textTemplate.json b/apps/web-antd/src/locales/langs/zh-CN/textTemplate.json new file mode 100644 index 0000000..75343e8 --- /dev/null +++ b/apps/web-antd/src/locales/langs/zh-CN/textTemplate.json @@ -0,0 +1,8 @@ +{ + "templateManagement": "模板管理", + "templateList": "模板列表", + "name": "名称", + "code": "编码", + "content": "内容", + "cultureName": "语言" +} diff --git a/apps/web-antd/src/main.ts b/apps/web-antd/src/main.ts new file mode 100644 index 0000000..d2004e9 --- /dev/null +++ b/apps/web-antd/src/main.ts @@ -0,0 +1,34 @@ +import { initPreferences } from '@vben/preferences'; +import { unmountGlobalLoading } from '@vben/utils'; + +// eslint-disable-next-line unused-imports/no-unused-imports +import client from '#/api-client-config/index'; + +import { overridesPreferences } from './preferences'; + +/** + * 应用初始化完成之后再进行页面加载渲染 + */ +async function initApplication() { + // name用于指定项目唯一标识 + // 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据 + const env = import.meta.env.PROD ? 'prod' : 'dev'; + const appVersion = import.meta.env.VITE_APP_VERSION; + const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`; + + // app偏好设置初始化 + await initPreferences({ + namespace, + overrides: overridesPreferences, + }); + + // 启动应用并挂载 + // vue应用主要逻辑及视图 + const { bootstrap } = await import('./bootstrap'); + await bootstrap(namespace); + + // 移除并销毁loading + unmountGlobalLoading(); +} + +initApplication(); diff --git a/apps/web-antd/src/preferences.ts b/apps/web-antd/src/preferences.ts new file mode 100644 index 0000000..58c4e9c --- /dev/null +++ b/apps/web-antd/src/preferences.ts @@ -0,0 +1,28 @@ +import { defineOverridesPreferences } from '@vben/preferences'; + +/** + * @description 项目配置文件 + * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 + * !!! 更改配置后请清空缓存,否则可能不生效 + */ +export const overridesPreferences = defineOverridesPreferences({ + // overrides + app: { + name: import.meta.env.VITE_APP_TITLE, + // 是否开启检查更新 + enableCheckUpdates: false, + // 检查更新的时间间隔,单位为分钟 + checkUpdatesInterval: 1, + // accessMode: 'backend', // 默认值frontend|backend 默认值frontend可不填写 + defaultAvatar: '/public/avatar-v1.webp', // 默认头像 + }, + theme: { + mode: 'light', + }, + copyright: { + companyName: 'Abp Vben5 Antd', + }, + logo: { + source: '/logo-v1.webp', // 网站图标 + }, +}); diff --git a/apps/web-antd/src/router/access.ts b/apps/web-antd/src/router/access.ts new file mode 100644 index 0000000..2a3a4ad --- /dev/null +++ b/apps/web-antd/src/router/access.ts @@ -0,0 +1,43 @@ +import type { + ComponentRecordType, + GenerateMenuAndRoutesOptions, +} from '@vben/types'; + +import { generateAccessible } from '@vben/access'; +import { preferences } from '@vben/preferences'; + +// import { message } from 'ant-design-vue'; +import { postMenusUserMenu } from '#/api-client/index'; +import { BasicLayout, IFrameView } from '#/layouts'; +// import { $t } from '#/locales'; + +const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue'); + +async function generateAccess(options: GenerateMenuAndRoutesOptions) { + const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue'); + + const layoutMap: ComponentRecordType = { + BasicLayout, + IFrameView, + }; + + return await generateAccessible(preferences.app.accessMode, { + ...options, + fetchMenuListAsync: async () => { + // message.loading({ + // content: `${$t('common.loadingMenu')}...`, + // duration: 1.5, + // }); + const resp = await postMenusUserMenu(); + + return resp.data as any; + }, + // 可以指定没有权限跳转403页面 + forbiddenComponent, + // 如果 route.meta.menuVisibleWithForbidden = true + layoutMap, + pageMap, + }); +} + +export { generateAccess }; diff --git a/apps/web-antd/src/router/guard.ts b/apps/web-antd/src/router/guard.ts new file mode 100644 index 0000000..0df1316 --- /dev/null +++ b/apps/web-antd/src/router/guard.ts @@ -0,0 +1,138 @@ +import type { Router } from 'vue-router'; + +import { LOGIN_PATH } from '@vben/constants'; +import { preferences } from '@vben/preferences'; +import { useAccessStore, useUserStore } from '@vben/stores'; +import { startProgress, stopProgress } from '@vben/utils'; + +import { accessRoutes, coreRouteNames } from '#/router/routes'; +import { useAuthStore } from '#/store'; + +import { generateAccess } from './access'; + +/** + * 通用守卫配置 + * @param router + */ +function setupCommonGuard(router: Router) { + // 记录已经加载的页面 + const loadedPaths = new Set(); + + router.beforeEach(async (to) => { + to.meta.loaded = loadedPaths.has(to.path); + + // 页面加载进度条 + if (!to.meta.loaded && preferences.transition.progress) { + startProgress(); + } + return true; + }); + + router.afterEach((to) => { + // 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行 + + loadedPaths.add(to.path); + + // 关闭页面加载进度条 + if (preferences.transition.progress) { + stopProgress(); + } + }); +} + +/** + * 权限访问守卫配置 + * @param router + */ +function setupAccessGuard(router: Router) { + router.beforeEach(async (to, from) => { + const accessStore = useAccessStore(); + const userStore = useUserStore(); + const authStore = useAuthStore(); + + // 基本路由,这些路由不需要进入权限拦截 + if (coreRouteNames.includes(to.name as string)) { + if (to.path === LOGIN_PATH && accessStore.accessToken) { + return decodeURIComponent( + (to.query?.redirect as string) || + userStore.userInfo?.homePath || + preferences.app.defaultHomePath, + ); + } + return true; + } + + // accessToken 检查 + if (!accessStore.accessToken) { + // 明确声明忽略权限访问权限,则可以访问 + if (to.meta.ignoreAccess) { + return true; + } + + // 没有访问权限,跳转登录页面 + if (to.fullPath !== LOGIN_PATH) { + return { + path: LOGIN_PATH, + // 如不需要,直接删除 query + query: + to.fullPath === preferences.app.defaultHomePath + ? {} + : { redirect: encodeURIComponent(to.fullPath) }, + // 携带当前跳转的页面,登录后重新跳转该页面 + replace: true, + }; + } + return to; + } + + // 是否已经生成过动态路由 + if (accessStore.isAccessChecked) { + return true; + } + // 生成路由表 + // 当前登录用户拥有的角色标识列表 + // const userInfo = userStore.userInfo || (await authStore.fetchUserInfo()); + // const userRoles = userInfo.roles ?? []; + const refreshCount = userStore?.applicationInfo?.refreshCount ?? -1; + if (import.meta.env.VITE_REFRESH_ROLE && refreshCount > 0) { + await authStore.getApplicationConfiguration(); + } + + const userRoles = accessStore.accessCodes ?? []; + + // 生成菜单和路由 + const { accessibleMenus, accessibleRoutes } = await generateAccess({ + roles: userRoles, + router, + // 则会在菜单中显示,但是访问会被重定向到403 + routes: accessRoutes, + }); + + // 保存菜单信息和路由信息 + accessStore.setAccessMenus(accessibleMenus); + accessStore.setAccessRoutes(accessibleRoutes); + accessStore.setIsAccessChecked(true); + const redirectPath = (from.query.redirect ?? + (to.path === preferences.app.defaultHomePath + ? userStore.userInfo?.homePath || preferences.app.defaultHomePath + : to.fullPath)) as string; + + return { + ...router.resolve(decodeURIComponent(redirectPath)), + replace: true, + }; + }); +} + +/** + * 项目守卫配置 + * @param router + */ +function createRouterGuard(router: Router) { + /** 通用 */ + setupCommonGuard(router); + /** 权限访问 */ + setupAccessGuard(router); +} + +export { createRouterGuard }; diff --git a/apps/web-antd/src/router/index.ts b/apps/web-antd/src/router/index.ts new file mode 100644 index 0000000..4840230 --- /dev/null +++ b/apps/web-antd/src/router/index.ts @@ -0,0 +1,37 @@ +import { + createRouter, + createWebHashHistory, + createWebHistory, +} from 'vue-router'; + +import { resetStaticRoutes } from '@vben/utils'; + +import { createRouterGuard } from './guard'; +import { routes } from './routes'; + +/** + * @zh_CN 创建vue-router实例 + */ +const router = createRouter({ + history: + import.meta.env.VITE_ROUTER_HISTORY === 'hash' + ? createWebHashHistory(import.meta.env.VITE_BASE) + : createWebHistory(import.meta.env.VITE_BASE), + // 应该添加到路由的初始路由列表。 + routes, + scrollBehavior: (to, _from, savedPosition) => { + if (savedPosition) { + return savedPosition; + } + return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 }; + }, + // 是否应该禁止尾部斜杠。 + // strict: true, +}); + +const resetRoutes = () => resetStaticRoutes(router, routes); + +// 创建路由守卫 +createRouterGuard(router); + +export { resetRoutes, router }; diff --git a/apps/web-antd/src/router/routes/core.ts b/apps/web-antd/src/router/routes/core.ts new file mode 100644 index 0000000..b88b2d7 --- /dev/null +++ b/apps/web-antd/src/router/routes/core.ts @@ -0,0 +1,105 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { LOGIN_PATH } from '@vben/constants'; +import { preferences } from '@vben/preferences'; + +import { $t } from '#/locales'; + +const BasicLayout = () => import('#/layouts/basic.vue'); +const AuthPageLayout = () => import('#/layouts/auth.vue'); +/** 全局404页面 */ +const fallbackNotFoundRoute: RouteRecordRaw = { + component: () => import('#/views/_core/fallback/not-found.vue'), + meta: { + hideInBreadcrumb: true, + hideInMenu: true, + hideInTab: true, + title: '404', + }, + name: 'FallbackNotFound', + path: '/:path(.*)*', +}; + +/** 基本路由,这些路由是必须存在的 */ +const coreRoutes: RouteRecordRaw[] = [ + /** + * 根路由 + * 使用基础布局,作为所有页面的父级容器,子级就不必配置BasicLayout。 + * 此路由必须存在,且不应修改 + */ + { + component: BasicLayout, + meta: { + hideInBreadcrumb: true, + title: 'Root', + }, + name: 'Root', + path: '/', + redirect: preferences.app.defaultHomePath, + children: [], + }, + { + component: AuthPageLayout, + meta: { + hideInTab: true, + title: 'Authentication', + }, + name: 'Authentication', + path: '/auth', + redirect: LOGIN_PATH, + children: [ + { + name: 'Login', + path: 'login', + component: () => import('#/views/_core/authentication/login.vue'), + meta: { + title: $t('page.auth.login'), + }, + }, + { + name: 'CodeLogin', + path: 'code-login', + component: () => import('#/views/_core/authentication/code-login.vue'), + meta: { + title: $t('page.auth.codeLogin'), + }, + }, + { + name: 'OidcLogin', + path: 'oidc-login', + component: () => import('#/views/_core/authentication/oidc-login.vue'), + meta: { + title: $t('page.auth.thirdPartyLogin'), + }, + }, + { + name: 'QrCodeLogin', + path: 'qrcode-login', + component: () => + import('#/views/_core/authentication/qrcode-login.vue'), + meta: { + title: $t('page.auth.qrcodeLogin'), + }, + }, + { + name: 'ForgetPassword', + path: 'forget-password', + component: () => + import('#/views/_core/authentication/forget-password.vue'), + meta: { + title: $t('page.auth.forgetPassword'), + }, + }, + { + name: 'Register', + path: 'register', + component: () => import('#/views/_core/authentication/register.vue'), + meta: { + title: $t('page.auth.register'), + }, + }, + ], + }, +]; + +export { coreRoutes, fallbackNotFoundRoute }; diff --git a/apps/web-antd/src/router/routes/index.ts b/apps/web-antd/src/router/routes/index.ts new file mode 100644 index 0000000..e6fb144 --- /dev/null +++ b/apps/web-antd/src/router/routes/index.ts @@ -0,0 +1,37 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { mergeRouteModules, traverseTreeValues } from '@vben/utils'; + +import { coreRoutes, fallbackNotFoundRoute } from './core'; + +const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', { + eager: true, +}); + +// 有需要可以自行打开注释,并创建文件夹 +// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true }); +// const staticRouteFiles = import.meta.glob('./static/**/*.ts', { eager: true }); + +/** 动态路由 */ +const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles); + +/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */ +// const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles); +// const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles); +const staticRoutes: RouteRecordRaw[] = []; +const externalRoutes: RouteRecordRaw[] = []; + +/** 路由列表,由基本路由、外部路由和404兜底路由组成 + * 无需走权限验证(会一直显示在菜单中) */ +const routes: RouteRecordRaw[] = [ + ...coreRoutes, + ...externalRoutes, + fallbackNotFoundRoute, +]; + +/** 基本路由列表,这些路由不需要进入权限拦截 */ +const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name); + +/** 有权限校验的路由列表,包含动态路由和静态路由 */ +const accessRoutes = [...dynamicRoutes, ...staticRoutes]; +export { accessRoutes, coreRouteNames, routes }; diff --git a/apps/web-antd/src/router/routes/modules/code.ts b/apps/web-antd/src/router/routes/modules/code.ts new file mode 100644 index 0000000..0b932d0 --- /dev/null +++ b/apps/web-antd/src/router/routes/modules/code.ts @@ -0,0 +1,82 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { BasicLayout } from '#/layouts'; +import { $t } from '#/locales'; + +const routes: RouteRecordRaw[] = [ + { + component: BasicLayout, + meta: { + icon: 'ant-design:format-painter-filled', + order: 3, + title: $t('abp.menu.code'), + authority: ['AbpCodeManagement'], + }, + name: 'code', + path: '/code', + children: [ + { + name: 'project', + path: 'project', + component: () => import('#/views/code/project/index.vue'), + meta: { + icon: 'ant-design:profile-outlined', + title: $t('abp.menu.code-project'), + authority: ['AbpCodeManagement.Project'], + }, + }, + { + name: 'template', + path: 'template', + component: () => import('#/views/code/template/index.vue'), + meta: { + icon: 'ant-design:file-markdown-filled', + title: $t('abp.menu.code-template'), + authority: ['AbpCodeManagement.Template'], + }, + }, + { + name: 'generate', + path: 'generate', + component: () => import('#/views/code/generate/index.vue'), + meta: { + icon: 'ant-design:copyright-circle-filled', + title: $t('abp.menu.code-genarate'), + authority: ['AbpCodeManagement.Generator'], + }, + }, + { + name: 'EntityModel', + path: 'entityModel', + component: () => import('#/views/code/project/entityModel/index.vue'), + meta: { + icon: 'ant-design:file-markdown-filled', + title: $t('abp.menu.code-entity'), + hideInMenu: true, + }, + }, + { + name: 'TemplateDetail', + path: 'templateDetail', + component: () => import('#/views/code/template/TemplateDetail.vue'), + meta: { + icon: 'ant-design:file-markdown-filled', + title: $t('abp.menu.code-template-detail'), + hideInMenu: true, + }, + }, + { + name: 'preview', + path: 'Preview', + component: () => import('#/views/code/generate/preview.vue'), + meta: { + icon: 'ant-design:file-markdown-filled', + title: $t('abp.menu.code-Preview'), + hideInMenu: true, + }, + }, + ], + }, +]; + +export default routes; diff --git a/apps/web-antd/src/router/routes/modules/dashboard.ts b/apps/web-antd/src/router/routes/modules/dashboard.ts new file mode 100644 index 0000000..5254dc6 --- /dev/null +++ b/apps/web-antd/src/router/routes/modules/dashboard.ts @@ -0,0 +1,38 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { $t } from '#/locales'; + +const routes: RouteRecordRaw[] = [ + { + meta: { + icon: 'lucide:layout-dashboard', + order: -1, + title: $t('page.dashboard.title'), + }, + name: 'Dashboard', + path: '/dashboard', + children: [ + { + name: 'Analytics', + path: '/analytics', + component: () => import('#/views/dashboard/analytics/index.vue'), + meta: { + affixTab: true, + icon: 'lucide:area-chart', + title: $t('page.dashboard.analytics'), + }, + }, + { + name: 'Workspace', + path: '/workspace', + component: () => import('#/views/dashboard/workspace/index.vue'), + meta: { + icon: 'carbon:workspace', + title: $t('page.dashboard.workspace'), + }, + }, + ], + }, +]; + +export default routes; diff --git a/apps/web-antd/src/router/routes/modules/demos.ts b/apps/web-antd/src/router/routes/modules/demos.ts new file mode 100644 index 0000000..e0011f5 --- /dev/null +++ b/apps/web-antd/src/router/routes/modules/demos.ts @@ -0,0 +1,41 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { SvgAntdvLogoIcon } from '@vben/icons'; + +import { BasicLayout } from '#/layouts'; +import { $t } from '#/locales'; + +const routes: RouteRecordRaw[] = [ + { + component: BasicLayout, + meta: { + icon: 'ic:baseline-view-in-ar', + keepAlive: true, + order: 1000, + title: $t('demos.title'), + }, + name: 'Demos', + path: '/demos', + children: [ + { + meta: { + title: $t('demos.antd'), + icon: SvgAntdvLogoIcon, + }, + name: 'AntDesignDemos', + path: '/demos/ant-design', + component: () => import('#/views/demos/antd/index.vue'), + }, + // { + // meta: { + // title: '列表页示例', + // }, + // name: 'ListPageDemos', + // path: '/demos/list-page', + // component: () => import('#/views/demos/listPage/index.vue'), + // }, + ], + }, +]; + +export default routes; diff --git a/apps/web-antd/src/router/routes/modules/file.ts b/apps/web-antd/src/router/routes/modules/file.ts new file mode 100644 index 0000000..308456c --- /dev/null +++ b/apps/web-antd/src/router/routes/modules/file.ts @@ -0,0 +1,32 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { BasicLayout } from '#/layouts'; +import { $t } from '#/locales'; + +const routes: RouteRecordRaw[] = [ + { + component: BasicLayout, + meta: { + icon: 'ant-design:folder-open-outlined', + order: 3, + title: $t('abp.menu.file'), + authority: ['FileManagement'], + }, + name: 'file', + path: '/file', + children: [ + { + name: 'abpFile', + path: 'page', + component: () => import('#/views/system/abpfiles/index.vue'), + meta: { + icon: 'ant-design:file-text-twotone', + title: $t('abp.menu.file'), + authority: ['FileManagement.File'], + }, + }, + ], + }, +]; + +export default routes; diff --git a/apps/web-antd/src/router/routes/modules/system.ts b/apps/web-antd/src/router/routes/modules/system.ts new file mode 100644 index 0000000..d9229d4 --- /dev/null +++ b/apps/web-antd/src/router/routes/modules/system.ts @@ -0,0 +1,154 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { BasicLayout } from '#/layouts'; +import { $t } from '#/locales'; + +const routes: RouteRecordRaw[] = [ + { + component: BasicLayout, + meta: { + icon: 'lucide:layout-dashboard', + order: 1, + title: $t('abp.menu.system'), + authority: ['AbpIdentity'], + }, + name: 'system', + path: '/system', + children: [ + { + name: 'abpUser', + path: 'user', + component: () => import('#/views/system/abpuser/index.vue'), + meta: { + // affixTab: true, + icon: 'ph:user', + title: $t('abp.menu.user'), + authority: ['AbpIdentity.Users'], + }, + }, + { + name: 'abpRole', + path: 'role', + component: () => import('#/views/system/abprole/index.vue'), + meta: { + icon: 'oui:app-users-roles', + title: $t('abp.menu.role'), + authority: ['AbpIdentity.Roles'], + }, + }, + { + name: 'OrganizationUnit', + path: 'organizationUnit', + component: () => import('#/views/system/abporganizationunit/index.vue'), + meta: { + title: $t('abp.menu.organizationUnit'), + authority: ['AbpIdentity.OrganizationUnitManagement'], + icon: 'ant-design:team-outlined', + }, + }, + { + name: 'abpSetting', + path: 'setting', + component: () => import('#/views/system/abpsetting/index.vue'), + meta: { + icon: 'uil:setting', + title: $t('abp.menu.setting'), + authority: ['AbpIdentity.Setting'], + }, + }, + { + name: 'abpfeature', + path: 'Feature', + component: () => import('#/views/system/abpfeature/index.vue'), + meta: { + icon: 'ant-design:tool-outlined', + title: $t('abp.menu.feature'), + authority: ['AbpIdentity.FeatureManagement'], + }, + }, + { + name: 'AbpAuditLog', + path: 'auditlog', + component: () => import('#/views/system/abplog/audit.vue'), + meta: { + title: $t('abp.menu.auditLog'), + authority: ['AbpIdentity.AuditLog'], + icon: 'ant-design:snippets-twotone', + }, + }, + { + name: 'AbpLoginLog', + path: 'loginlog', + component: () => import('#/views/system/abplog/login.vue'), + meta: { + title: $t('abp.menu.loginLog'), + authority: ['AbpIdentity.IdentitySecurityLogs'], + icon: 'ant-design:file-protect-outlined', + }, + }, + { + name: 'AbpLanguage', + path: 'language', + component: () => import('#/views/system/abplanguage/language.vue'), + meta: { + title: $t('abp.menu.language'), + authority: ['AbpIdentity.Languages'], + icon: 'ant-design:read-outlined', + }, + }, + { + name: 'AbpLanguageText', + path: 'languagetext', + component: () => import('#/views/system/abplanguage/languagetext.vue'), + meta: { + title: $t('abp.menu.languageText'), + authority: ['AbpIdentity.LanguageTexts'], + icon: 'ant-design:font-size-outlined', + }, + }, + { + name: 'DataDictionary', + path: 'dataDictionary', + component: () => import('#/views/system/abpdatadictionary/index.vue'), + meta: { + title: $t('abp.menu.dataDictionary'), + authority: ['AbpIdentity.DataDictionaryManagement'], + icon: 'ant-design:table-outlined', + }, + }, + { + name: 'AbpNotification', + path: 'notification', + component: () => + import('#/views/system/abpnotification/notification.vue'), + meta: { + title: $t('abp.menu.notification'), + authority: ['AbpIdentity.NotificationSubscriptionManagement'], + icon: 'ant-design:comment-outlined', + }, + }, + { + name: 'AbpMessage', + path: 'message', + component: () => import('#/views/system/abpnotification/message.vue'), + meta: { + title: $t('abp.menu.message'), + authority: ['AbpIdentity.NotificationManagement'], + icon: 'ant-design:customer-service-twotone', + }, + }, + { + path: 'menu', + name: 'AbpMenu', + component: () => import('#/views/system/abpmenu/index.vue'), + meta: { + icon: 'ant-design:bars-outlined', + title: $t('abp.menu.menu'), + authority: ['AbpIdentity.DynamicMenuManagement'], + }, + }, + ], + }, +]; + +export default routes; diff --git a/apps/web-antd/src/router/routes/modules/tenant.ts b/apps/web-antd/src/router/routes/modules/tenant.ts new file mode 100644 index 0000000..1555f18 --- /dev/null +++ b/apps/web-antd/src/router/routes/modules/tenant.ts @@ -0,0 +1,32 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { BasicLayout } from '#/layouts'; +import { $t } from '#/locales'; + +const routes: RouteRecordRaw[] = [ + { + component: BasicLayout, + meta: { + icon: 'ant-design:switcher-filled', + order: 2, + title: $t('abp.menu.tenant'), + authority: ['AbpTenantManagement'], + }, + name: 'tenant', + path: '/tenant', + children: [ + { + name: 'abpTenant', + path: 'page', + component: () => import('#/views/system/abptenant/index.vue'), + meta: { + icon: 'ph:user', + title: $t('abp.menu.tenantList'), + authority: ['AbpTenantManagement.Tenants'], + }, + }, + ], + }, +]; + +export default routes; diff --git a/apps/web-antd/src/router/routes/modules/textTemplate.ts b/apps/web-antd/src/router/routes/modules/textTemplate.ts new file mode 100644 index 0000000..bad0b65 --- /dev/null +++ b/apps/web-antd/src/router/routes/modules/textTemplate.ts @@ -0,0 +1,32 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { BasicLayout } from '#/layouts'; +import { $t } from '#/locales'; + +const routes: RouteRecordRaw[] = [ + { + component: BasicLayout, + meta: { + icon: 'ant-design:tool-outlined', + // order: 998, + title: $t('textTemplate.templateManagement'), + authority: ['AbpTemplateManagement'], + }, + name: 'TextTemplate', + path: '/TextTemplate', + children: [ + { + path: 'page', + name: 'TextTemplatePage', + component: () => import('#/views/textTemplate/index.vue'), + meta: { + icon: 'ant-design:file-markdown-filled', + title: $t('textTemplate.templateList'), + authority: ['AbpTemplateManagement.Template'], + }, + }, + ], + }, +]; + +export default routes; diff --git a/apps/web-antd/src/router/routes/modules/vben.ts b/apps/web-antd/src/router/routes/modules/vben.ts new file mode 100644 index 0000000..453afe5 --- /dev/null +++ b/apps/web-antd/src/router/routes/modules/vben.ts @@ -0,0 +1,94 @@ +import type { RouteRecordRaw } from 'vue-router'; + +import { SvgAntdvLogoIcon } from '@vben/icons'; + +import { BasicLayout, IFrameView } from '#/layouts'; +import { $t } from '#/locales'; + +const routes: RouteRecordRaw[] = [ + { + component: BasicLayout, + meta: { + badgeType: 'dot', + icon: 'ph:file-doc-light', + order: 9999, + title: $t('demos.vben.title'), + }, + name: 'VbenProject', + path: '/vben-admin', + children: [ + // { + // name: 'VbenAbout', + // path: '/vben-admin/about', + // component: () => import('#/views/_core/about/index.vue'), + // meta: { + // icon: 'lucide:copyright', + // title: $t('demos.vben.about'), + // }, + // }, + { + name: 'VbenDocument', + path: '/vben-admin/document', + component: IFrameView, + meta: { + icon: 'lucide:book-open-text', + link: 'https://doc.cncore.club/', + title: 'ABPPro文档', + }, + }, + { + name: 'VbenDocument', + path: '/vben-admin/document', + component: IFrameView, + meta: { + icon: 'lucide:book-open-text', + link: 'http://doc.china.cncore.club:81/', + title: 'ABPPro国内文档', + }, + }, + { + name: 'VbenDocument', + path: '/vben-admin/document', + component: IFrameView, + meta: { + icon: 'lucide:book-open-text', + link: 'https://abp.io/docs/latest/', + title: 'ABP官方文档', + }, + }, + { + name: 'VbenGithub', + path: '/vben-admin/github', + component: IFrameView, + meta: { + icon: 'mdi:github', + link: 'https://github.com/WangJunZzz/abp-vnext-pro', + title: 'Github', + }, + }, + { + name: 'VbenGithub', + path: '/vben-admin/github', + component: IFrameView, + meta: { + icon: 'ant-design:google-circle-filled', + link: 'https://gitee.com/WangJunZzz/abp-vnext-pro', + title: 'Gitee', + }, + }, + { + name: 'VbenGithub', + path: '/vben-admin/github', + component: IFrameView, + meta: { + icon: SvgAntdvLogoIcon, + // link: 'https://www.antdv.com/components/overview-cn/', + iframeSrc: 'https://doc.cncore.club/', + title: 'Ant Design Vue', + }, + }, + ], + }, +]; + +export default routes; diff --git a/apps/web-antd/src/store/auth.ts b/apps/web-antd/src/store/auth.ts new file mode 100644 index 0000000..1d8ae1a --- /dev/null +++ b/apps/web-antd/src/store/auth.ts @@ -0,0 +1,158 @@ +import type { Recordable, UserInfo } from '@vben/types'; + +import type { + ApplicationAuthConfigurationDto, + ApplicationConfigurationDto, +} from '#/api-client'; + +import { ref } from 'vue'; +import { useRouter } from 'vue-router'; + +import { LOGIN_PATH } from '@vben/constants'; +import { preferences } from '@vben/preferences'; +import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores'; + +import { message as Message, notification } from 'ant-design-vue'; +import { defineStore } from 'pinia'; + +import { + getApiAbpApplicationConfiguration, + postApiAppAccountLogin2Fa, + postTenantsFind, +} from '#/api-client'; +import { useSignalR } from '#/hooks/useSignalR'; +import { $t } from '#/locales'; + +export const useAuthStore = defineStore('auth', () => { + const accessStore = useAccessStore(); + const userStore = useUserStore(); + const router = useRouter(); + + const loginLoading = ref(false); + + /** + * 异步处理登录操作 + * Asynchronously handle the login process + * @param params 登录表单数据 + */ + async function authLogin( + params: Recordable, + onSuccess?: () => Promise | void, + ) { + // 异步处理用户登录操作并获取 accessToken + let userInfo: null | UserInfo = null; + + try { + loginLoading.value = true; + // 判断是否租户登录 + if (params.tenant) { + const tenantResult = await postTenantsFind({ + body: { + name: params.tenant, + }, + }); + if (tenantResult.data?.success) { + userStore.setTenantInfo(tenantResult.data as any); + } else { + Message.error(`${params.tenant}$t('abp.tenant.notExist')`); + userStore.setTenantInfo(null); + delete params.tenant; + return; + } + } + + const { data = {} } = await postApiAppAccountLogin2Fa({ + body: { + ...params, + }, + }); + // 如果成功获取到 accessToken + if (data.token) { + accessStore.setAccessToken(data.token); + accessStore.setRefreshToken(data.refreshToken); + userInfo = data as any; + userStore.setUserInfo(userInfo as any); + await getApplicationConfiguration(); + if (accessStore.loginExpired) { + accessStore.setLoginExpired(false); + } else { + onSuccess + ? await onSuccess?.() + : await router.push( + userInfo?.homePath || preferences.app.defaultHomePath, + ); + } + + if (userInfo?.userName) { + notification.success({ + description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.userName}`, + duration: 3, + message: $t('authentication.loginSuccess'), + }); + } + } + } catch { + userStore.setTenantInfo(null); + userStore.setUserInfo(null); + } finally { + loginLoading.value = false; + } + + return { + userInfo, + }; + } + + async function logout(redirect: boolean = true) { + try { + // await logoutApi(); + const { closeConnect } = useSignalR(); + closeConnect(); + } catch { + // 不做任何处理 + } + resetAllStores(); + accessStore.setLoginExpired(false); + + // 回登录页带上当前路由地址 + await router.replace({ + path: LOGIN_PATH, + query: redirect + ? { + redirect: encodeURIComponent(router.currentRoute.value.fullPath), + } + : {}, + }); + } + + async function fetchUserInfo() { + const userInfo: null | UserInfo = null; + // userInfo = await getUserInfoApi(); + // userStore.setUserInfo(userInfo); + return userInfo; + } + + function $reset() { + loginLoading.value = false; + } + + async function getApplicationConfiguration() { + const { data: authData } = await getApiAbpApplicationConfiguration({ + query: { IncludeLocalizationResources: false }, + }); + const { auth } = authData as ApplicationConfigurationDto; + const accessCodes = Object.keys( + (auth as ApplicationAuthConfigurationDto) + .grantedPolicies as unknown as Record, + ); + accessStore.setAccessCodes(accessCodes); + } + return { + $reset, + authLogin, + fetchUserInfo, + loginLoading, + logout, + getApplicationConfiguration, + }; +}); diff --git a/apps/web-antd/src/store/index.ts b/apps/web-antd/src/store/index.ts new file mode 100644 index 0000000..269586e --- /dev/null +++ b/apps/web-antd/src/store/index.ts @@ -0,0 +1 @@ +export * from './auth'; diff --git a/apps/web-antd/src/views/_core/README.md b/apps/web-antd/src/views/_core/README.md new file mode 100644 index 0000000..8248afe --- /dev/null +++ b/apps/web-antd/src/views/_core/README.md @@ -0,0 +1,3 @@ +# \_core + +此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。 diff --git a/apps/web-antd/src/views/_core/about/index.vue b/apps/web-antd/src/views/_core/about/index.vue new file mode 100644 index 0000000..0ee5243 --- /dev/null +++ b/apps/web-antd/src/views/_core/about/index.vue @@ -0,0 +1,9 @@ + + + diff --git a/apps/web-antd/src/views/_core/authentication/code-login.vue b/apps/web-antd/src/views/_core/authentication/code-login.vue new file mode 100644 index 0000000..acfd1fd --- /dev/null +++ b/apps/web-antd/src/views/_core/authentication/code-login.vue @@ -0,0 +1,69 @@ + + + diff --git a/apps/web-antd/src/views/_core/authentication/forget-password.vue b/apps/web-antd/src/views/_core/authentication/forget-password.vue new file mode 100644 index 0000000..fef0d42 --- /dev/null +++ b/apps/web-antd/src/views/_core/authentication/forget-password.vue @@ -0,0 +1,43 @@ + + + diff --git a/apps/web-antd/src/views/_core/authentication/login.vue b/apps/web-antd/src/views/_core/authentication/login.vue new file mode 100644 index 0000000..3747959 --- /dev/null +++ b/apps/web-antd/src/views/_core/authentication/login.vue @@ -0,0 +1,84 @@ + + + diff --git a/apps/web-antd/src/views/_core/authentication/oidc-login.vue b/apps/web-antd/src/views/_core/authentication/oidc-login.vue new file mode 100644 index 0000000..2680eb7 --- /dev/null +++ b/apps/web-antd/src/views/_core/authentication/oidc-login.vue @@ -0,0 +1,55 @@ + + + diff --git a/apps/web-antd/src/views/_core/authentication/qrcode-login.vue b/apps/web-antd/src/views/_core/authentication/qrcode-login.vue new file mode 100644 index 0000000..23f5f2d --- /dev/null +++ b/apps/web-antd/src/views/_core/authentication/qrcode-login.vue @@ -0,0 +1,10 @@ + + + diff --git a/apps/web-antd/src/views/_core/authentication/register.vue b/apps/web-antd/src/views/_core/authentication/register.vue new file mode 100644 index 0000000..b1a5de7 --- /dev/null +++ b/apps/web-antd/src/views/_core/authentication/register.vue @@ -0,0 +1,96 @@ + + + diff --git a/apps/web-antd/src/views/_core/fallback/coming-soon.vue b/apps/web-antd/src/views/_core/fallback/coming-soon.vue new file mode 100644 index 0000000..f394930 --- /dev/null +++ b/apps/web-antd/src/views/_core/fallback/coming-soon.vue @@ -0,0 +1,7 @@ + + + diff --git a/apps/web-antd/src/views/_core/fallback/forbidden.vue b/apps/web-antd/src/views/_core/fallback/forbidden.vue new file mode 100644 index 0000000..8ea65fe --- /dev/null +++ b/apps/web-antd/src/views/_core/fallback/forbidden.vue @@ -0,0 +1,9 @@ + + + diff --git a/apps/web-antd/src/views/_core/fallback/internal-error.vue b/apps/web-antd/src/views/_core/fallback/internal-error.vue new file mode 100644 index 0000000..819a47d --- /dev/null +++ b/apps/web-antd/src/views/_core/fallback/internal-error.vue @@ -0,0 +1,9 @@ + + + diff --git a/apps/web-antd/src/views/_core/fallback/not-found.vue b/apps/web-antd/src/views/_core/fallback/not-found.vue new file mode 100644 index 0000000..4d178e9 --- /dev/null +++ b/apps/web-antd/src/views/_core/fallback/not-found.vue @@ -0,0 +1,9 @@ + + + diff --git a/apps/web-antd/src/views/_core/fallback/offline.vue b/apps/web-antd/src/views/_core/fallback/offline.vue new file mode 100644 index 0000000..5de4a88 --- /dev/null +++ b/apps/web-antd/src/views/_core/fallback/offline.vue @@ -0,0 +1,9 @@ + + + diff --git a/apps/web-antd/src/views/code/generate/index.vue b/apps/web-antd/src/views/code/generate/index.vue new file mode 100644 index 0000000..7b73fa9 --- /dev/null +++ b/apps/web-antd/src/views/code/generate/index.vue @@ -0,0 +1,137 @@ + + + diff --git a/apps/web-antd/src/views/code/generate/preview.vue b/apps/web-antd/src/views/code/generate/preview.vue new file mode 100644 index 0000000..ea05eae --- /dev/null +++ b/apps/web-antd/src/views/code/generate/preview.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/apps/web-antd/src/views/code/project/AddModal.vue b/apps/web-antd/src/views/code/project/AddModal.vue new file mode 100644 index 0000000..e4c6219 --- /dev/null +++ b/apps/web-antd/src/views/code/project/AddModal.vue @@ -0,0 +1,54 @@ + + diff --git a/apps/web-antd/src/views/code/project/EditModal.vue b/apps/web-antd/src/views/code/project/EditModal.vue new file mode 100644 index 0000000..be525fa --- /dev/null +++ b/apps/web-antd/src/views/code/project/EditModal.vue @@ -0,0 +1,63 @@ + + diff --git a/apps/web-antd/src/views/code/project/entityModel/AddAggregateRootModal.vue b/apps/web-antd/src/views/code/project/entityModel/AddAggregateRootModal.vue new file mode 100644 index 0000000..b07afb5 --- /dev/null +++ b/apps/web-antd/src/views/code/project/entityModel/AddAggregateRootModal.vue @@ -0,0 +1,74 @@ + + diff --git a/apps/web-antd/src/views/code/project/entityModel/AddEditEntityModal.vue b/apps/web-antd/src/views/code/project/entityModel/AddEditEntityModal.vue new file mode 100644 index 0000000..9c1f516 --- /dev/null +++ b/apps/web-antd/src/views/code/project/entityModel/AddEditEntityModal.vue @@ -0,0 +1,153 @@ + + + diff --git a/apps/web-antd/src/views/code/project/entityModel/AddEditEntityPropertyModal.vue b/apps/web-antd/src/views/code/project/entityModel/AddEditEntityPropertyModal.vue new file mode 100644 index 0000000..ea74d55 --- /dev/null +++ b/apps/web-antd/src/views/code/project/entityModel/AddEditEntityPropertyModal.vue @@ -0,0 +1,190 @@ + + diff --git a/apps/web-antd/src/views/code/project/entityModel/AddEditEnumModal.vue b/apps/web-antd/src/views/code/project/entityModel/AddEditEnumModal.vue new file mode 100644 index 0000000..54f197a --- /dev/null +++ b/apps/web-antd/src/views/code/project/entityModel/AddEditEnumModal.vue @@ -0,0 +1,96 @@ + + + diff --git a/apps/web-antd/src/views/code/project/entityModel/AddEditEnumPropertyModal.vue b/apps/web-antd/src/views/code/project/entityModel/AddEditEnumPropertyModal.vue new file mode 100644 index 0000000..4d9958c --- /dev/null +++ b/apps/web-antd/src/views/code/project/entityModel/AddEditEnumPropertyModal.vue @@ -0,0 +1,121 @@ + + + diff --git a/apps/web-antd/src/views/code/project/entityModel/index.vue b/apps/web-antd/src/views/code/project/entityModel/index.vue new file mode 100644 index 0000000..eb67379 --- /dev/null +++ b/apps/web-antd/src/views/code/project/entityModel/index.vue @@ -0,0 +1,806 @@ + + + + + diff --git a/apps/web-antd/src/views/code/project/index.vue b/apps/web-antd/src/views/code/project/index.vue new file mode 100644 index 0000000..42095f3 --- /dev/null +++ b/apps/web-antd/src/views/code/project/index.vue @@ -0,0 +1,173 @@ + + + + diff --git a/apps/web-antd/src/views/code/project/schema.ts b/apps/web-antd/src/views/code/project/schema.ts new file mode 100644 index 0000000..a4094a6 --- /dev/null +++ b/apps/web-antd/src/views/code/project/schema.ts @@ -0,0 +1,169 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import { z } from '@vben/common-ui'; + +import dayjs from 'dayjs'; + +import { $t } from '#/locales'; + +export const querySchema = computed(() => [ + { + component: 'Input', + fieldName: 'filter', + label: $t('code.projectName'), + }, +]); + +export const tableSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { field: 'companyName', title: $t('code.companyName'), minWidth: '150' }, + { + field: 'projectName', + title: $t('code.projectName'), + minWidth: '150', + }, + + { field: 'nameSpace', title: $t('code.namespace'), minWidth: '150' }, + { + field: 'supportTenant', + title: $t('code.supportTenant'), + minWidth: '150', + slots: { default: 'supportTenant' }, + }, + { field: 'remark', title: $t('code.remark'), minWidth: '150' }, + { + field: 'creationTime', + title: $t('common.createTime'), + minWidth: '150', + formatter: ({ cellValue }) => { + return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss'); + }, + }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '250', + slots: { default: 'action' }, + }, +]); + +export const addFormSchema = computed(() => [ + { + component: 'Input', + componentProps: {}, + fieldName: 'companyName', + label: $t('code.companyName'), + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('code.companyName'), + }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'projectName', + label: $t('code.projectName'), + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('code.projectEnglishName'), + }), + }, + // { + // component: 'Input', + // componentProps: {}, + // fieldName: 'nameSpace', + // label: $t('code.namespace'), + // rules: z + // .string() + // .min(1, { message: $t('common.pleaseInput') + $t('code.namespace') }), + // }, + { + component: 'RadioGroup', + componentProps: { + options: [ + { + label: $t('common.yes'), + value: true, + }, + { + label: $t('common.no'), + value: false, + }, + ], + }, + defaultValue: 0, + fieldName: 'supportTenant', + label: $t('code.supportTenant'), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'remark', + label: $t('code.remark'), + }, +]); + +export const editFormSchema = computed(() => [ + { + component: 'Input', + componentProps: {}, + fieldName: 'id', + label: 'id', + dependencies: { + show: () => false, + triggerFields: ['id'], + }, + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'companyName', + label: $t('code.companyName'), + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('code.companyName'), + }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'projectName', + label: $t('code.projectName'), + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('code.projectEnglishName'), + }), + }, + // { + // component: 'Input', + // componentProps: {}, + // fieldName: 'nameSpace', + // label: $t('code.namespace'), + // rules: z + // .string() + // .min(1, { message: $t('common.pleaseInput') + $t('code.namespace') }), + // }, + { + component: 'RadioGroup', + componentProps: { + options: [ + { + label: $t('common.yes'), + value: true, + }, + { + label: $t('common.no'), + value: false, + }, + ], + }, + defaultValue: 0, + fieldName: 'supportTenant', + label: $t('code.supportTenant'), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'remark', + label: $t('code.remark'), + }, +]); diff --git a/apps/web-antd/src/views/code/template/AddEditTemplateModal.vue b/apps/web-antd/src/views/code/template/AddEditTemplateModal.vue new file mode 100644 index 0000000..edaf58e --- /dev/null +++ b/apps/web-antd/src/views/code/template/AddEditTemplateModal.vue @@ -0,0 +1,128 @@ + + diff --git a/apps/web-antd/src/views/code/template/AddModal.vue b/apps/web-antd/src/views/code/template/AddModal.vue new file mode 100644 index 0000000..fb4dd07 --- /dev/null +++ b/apps/web-antd/src/views/code/template/AddModal.vue @@ -0,0 +1,52 @@ + + diff --git a/apps/web-antd/src/views/code/template/CopyModal.vue b/apps/web-antd/src/views/code/template/CopyModal.vue new file mode 100644 index 0000000..9ae6f8d --- /dev/null +++ b/apps/web-antd/src/views/code/template/CopyModal.vue @@ -0,0 +1,74 @@ + + diff --git a/apps/web-antd/src/views/code/template/EditModal.vue b/apps/web-antd/src/views/code/template/EditModal.vue new file mode 100644 index 0000000..f508337 --- /dev/null +++ b/apps/web-antd/src/views/code/template/EditModal.vue @@ -0,0 +1,63 @@ + + diff --git a/apps/web-antd/src/views/code/template/TemplateDetail.vue b/apps/web-antd/src/views/code/template/TemplateDetail.vue new file mode 100644 index 0000000..95a028b --- /dev/null +++ b/apps/web-antd/src/views/code/template/TemplateDetail.vue @@ -0,0 +1,432 @@ + + + + + diff --git a/apps/web-antd/src/views/code/template/index.vue b/apps/web-antd/src/views/code/template/index.vue new file mode 100644 index 0000000..9cb2296 --- /dev/null +++ b/apps/web-antd/src/views/code/template/index.vue @@ -0,0 +1,212 @@ + + + + diff --git a/apps/web-antd/src/views/code/template/schema.ts b/apps/web-antd/src/views/code/template/schema.ts new file mode 100644 index 0000000..63e64d3 --- /dev/null +++ b/apps/web-antd/src/views/code/template/schema.ts @@ -0,0 +1,80 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import { z } from '@vben/common-ui'; + +import { $t } from '#/locales'; + +export const querySchema = computed(() => [ + { + component: 'Input', + fieldName: 'filter', + label: $t('code.templateName'), + }, +]); + +export const tableSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { title: $t('code.templateName'), field: 'name', minWidth: '150' }, + { title: $t('code.remark'), field: 'remark', minWidth: '150' }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '300', + slots: { default: 'action' }, + }, +]); + +export const addFormSchema = computed(() => [ + { + fieldName: 'name', + label: $t('code.templateName'), + component: 'Input', + componentProps: {}, + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('code.templateName'), + }), + }, + { + fieldName: 'remark', + label: $t('code.remark'), + component: 'Input', + componentProps: {}, + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('code.remark'), + }), + }, +]); + +export const editFormSchema = computed(() => [ + { + component: 'Input', + componentProps: {}, + fieldName: 'id', + label: 'id', + dependencies: { + show: () => false, + triggerFields: ['id'], + }, + }, + { + fieldName: 'name', + label: $t('code.templateName'), + component: 'Input', + componentProps: {}, + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('code.templateName'), + }), + }, + { + fieldName: 'remark', + label: $t('code.remark'), + component: 'Input', + componentProps: {}, + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('code.remark'), + }), + }, +]); diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue new file mode 100644 index 0000000..f1f0b23 --- /dev/null +++ b/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue @@ -0,0 +1,98 @@ + + + diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-visits-data.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-visits-data.vue new file mode 100644 index 0000000..190fb41 --- /dev/null +++ b/apps/web-antd/src/views/dashboard/analytics/analytics-visits-data.vue @@ -0,0 +1,82 @@ + + + diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-visits-sales.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-visits-sales.vue new file mode 100644 index 0000000..02f5091 --- /dev/null +++ b/apps/web-antd/src/views/dashboard/analytics/analytics-visits-sales.vue @@ -0,0 +1,46 @@ + + + diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-visits-source.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-visits-source.vue new file mode 100644 index 0000000..0915c7a --- /dev/null +++ b/apps/web-antd/src/views/dashboard/analytics/analytics-visits-source.vue @@ -0,0 +1,65 @@ + + + diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue new file mode 100644 index 0000000..7e0f101 --- /dev/null +++ b/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue @@ -0,0 +1,55 @@ + + + diff --git a/apps/web-antd/src/views/dashboard/analytics/index.vue b/apps/web-antd/src/views/dashboard/analytics/index.vue new file mode 100644 index 0000000..5e3d6d2 --- /dev/null +++ b/apps/web-antd/src/views/dashboard/analytics/index.vue @@ -0,0 +1,90 @@ + + + diff --git a/apps/web-antd/src/views/dashboard/workspace/index.vue b/apps/web-antd/src/views/dashboard/workspace/index.vue new file mode 100644 index 0000000..b95d613 --- /dev/null +++ b/apps/web-antd/src/views/dashboard/workspace/index.vue @@ -0,0 +1,266 @@ + + + diff --git a/apps/web-antd/src/views/demos/antd/index.vue b/apps/web-antd/src/views/demos/antd/index.vue new file mode 100644 index 0000000..b3b05cc --- /dev/null +++ b/apps/web-antd/src/views/demos/antd/index.vue @@ -0,0 +1,66 @@ + + + diff --git a/apps/web-antd/src/views/demos/listPage/AddEditModal.vue b/apps/web-antd/src/views/demos/listPage/AddEditModal.vue new file mode 100644 index 0000000..21e2f8f --- /dev/null +++ b/apps/web-antd/src/views/demos/listPage/AddEditModal.vue @@ -0,0 +1,106 @@ + + diff --git a/apps/web-antd/src/views/demos/listPage/index.vue b/apps/web-antd/src/views/demos/listPage/index.vue new file mode 100644 index 0000000..097f94a --- /dev/null +++ b/apps/web-antd/src/views/demos/listPage/index.vue @@ -0,0 +1,188 @@ + + + diff --git a/apps/web-antd/src/views/demos/listPage/mock.ts b/apps/web-antd/src/views/demos/listPage/mock.ts new file mode 100644 index 0000000..75f3b2e --- /dev/null +++ b/apps/web-antd/src/views/demos/listPage/mock.ts @@ -0,0 +1,22 @@ +import dayjs from 'dayjs'; + +export const getExampleTableApi = (params: any) => { + const list: any[] = []; + for (let i = 0; i < 20; i++) { + list.push({ + id: i, + category: `category${i}`, + productName: `productName${i}`, + price: 20 + (i + 1) * 2, + releaseDate: dayjs().subtract(i, 'day').format('YYYY-MM-DD'), + color: `color${i}`, + }); + } + + return new Promise((resolve) => { + resolve({ + totalCount: 30, + items: list, + }); + }); +}; diff --git a/apps/web-antd/src/views/system/abpdatadictionary/DataDictionaryDetailModal.vue b/apps/web-antd/src/views/system/abpdatadictionary/DataDictionaryDetailModal.vue new file mode 100644 index 0000000..1c9b055 --- /dev/null +++ b/apps/web-antd/src/views/system/abpdatadictionary/DataDictionaryDetailModal.vue @@ -0,0 +1,125 @@ + + diff --git a/apps/web-antd/src/views/system/abpdatadictionary/DataDictionaryModal.vue b/apps/web-antd/src/views/system/abpdatadictionary/DataDictionaryModal.vue new file mode 100644 index 0000000..5bc54f2 --- /dev/null +++ b/apps/web-antd/src/views/system/abpdatadictionary/DataDictionaryModal.vue @@ -0,0 +1,100 @@ + + diff --git a/apps/web-antd/src/views/system/abpdatadictionary/index.vue b/apps/web-antd/src/views/system/abpdatadictionary/index.vue new file mode 100644 index 0000000..053b7a0 --- /dev/null +++ b/apps/web-antd/src/views/system/abpdatadictionary/index.vue @@ -0,0 +1,358 @@ + + + + + diff --git a/apps/web-antd/src/views/system/abpfeature/index.vue b/apps/web-antd/src/views/system/abpfeature/index.vue new file mode 100644 index 0000000..feb74ba --- /dev/null +++ b/apps/web-antd/src/views/system/abpfeature/index.vue @@ -0,0 +1,134 @@ + + + diff --git a/apps/web-antd/src/views/system/abpfiles/AddModal.vue b/apps/web-antd/src/views/system/abpfiles/AddModal.vue new file mode 100644 index 0000000..ec0d58f --- /dev/null +++ b/apps/web-antd/src/views/system/abpfiles/AddModal.vue @@ -0,0 +1,39 @@ + + diff --git a/apps/web-antd/src/views/system/abpfiles/index.vue b/apps/web-antd/src/views/system/abpfiles/index.vue new file mode 100644 index 0000000..4a38edf --- /dev/null +++ b/apps/web-antd/src/views/system/abpfiles/index.vue @@ -0,0 +1,150 @@ + + + + diff --git a/apps/web-antd/src/views/system/abpfiles/schema.ts b/apps/web-antd/src/views/system/abpfiles/schema.ts new file mode 100644 index 0000000..8590eea --- /dev/null +++ b/apps/web-antd/src/views/system/abpfiles/schema.ts @@ -0,0 +1,98 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import { useUserStore } from '@vben/stores'; + +import dayjs from 'dayjs'; + +import { postFilesDelete } from '#/api-client/index'; +import { $t } from '#/locales'; + +const userStore = useUserStore(); +export const querySchema = computed(() => [ + { + component: 'RangePicker', + fieldName: 'time', + label: $t('common.createTime'), + componentProps: { + 'value-format': 'YYYY-MM-DD', + }, + defaultValue: [ + // 最近7天 + dayjs().subtract(7, 'day').format('YYYY-MM-DD'), + dayjs().subtract(-1, 'day').format('YYYY-MM-DD'), + ], + }, + { + component: 'Input', + fieldName: 'fileName', + label: $t('abp.file.name'), + }, +]); + +export const tableSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { + title: $t('abp.file.name'), + minWidth: '150', + field: 'fileName', + }, + { + title: $t('abp.file.size'), + minWidth: '150', + field: 'beautifySize', + }, + { + title: $t('abp.file.contentType'), + minWidth: '150', + field: 'contentType', + }, + { + field: 'creationTime', + title: $t('common.createTime'), + minWidth: '150', + formatter: ({ cellValue }) => { + return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss'); + }, + }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '150', + slots: { default: 'action' }, + }, +]); + +export const addFormSchema = computed(() => [ + { + component: 'Upload', + fieldName: 'files', + label: $t('abp.file.file'), + componentProps: () => { + return { + listType: 'picture-card', + autoUpload: true, + multiple: true, + name: 'files', + action: `${import.meta.env.VITE_APP_API_ADDRESS}/Files/Upload?access_token=${ + userStore.userInfo?.token + }`, + onPreview: () => {}, + onRemove: async (file: any) => { + await postFilesDelete({ + body: { + id: file.response[0].id, + }, + }); + }, + }; + }, + renderComponentContent: () => { + return { + default: () => 'Upload', + }; + }, + }, +]); diff --git a/apps/web-antd/src/views/system/abplanguage/AddLanguageTextModal.vue b/apps/web-antd/src/views/system/abplanguage/AddLanguageTextModal.vue new file mode 100644 index 0000000..5e1c5f6 --- /dev/null +++ b/apps/web-antd/src/views/system/abplanguage/AddLanguageTextModal.vue @@ -0,0 +1,74 @@ + + diff --git a/apps/web-antd/src/views/system/abplanguage/EditLanguageTextModal.vue b/apps/web-antd/src/views/system/abplanguage/EditLanguageTextModal.vue new file mode 100644 index 0000000..047a55c --- /dev/null +++ b/apps/web-antd/src/views/system/abplanguage/EditLanguageTextModal.vue @@ -0,0 +1,63 @@ + + diff --git a/apps/web-antd/src/views/system/abplanguage/language.vue b/apps/web-antd/src/views/system/abplanguage/language.vue new file mode 100644 index 0000000..8ed66bf --- /dev/null +++ b/apps/web-antd/src/views/system/abplanguage/language.vue @@ -0,0 +1,72 @@ + + + + diff --git a/apps/web-antd/src/views/system/abplanguage/languagetext.vue b/apps/web-antd/src/views/system/abplanguage/languagetext.vue new file mode 100644 index 0000000..a61d0ce --- /dev/null +++ b/apps/web-antd/src/views/system/abplanguage/languagetext.vue @@ -0,0 +1,147 @@ + + + + diff --git a/apps/web-antd/src/views/system/abplanguage/schema.ts b/apps/web-antd/src/views/system/abplanguage/schema.ts new file mode 100644 index 0000000..749f0b6 --- /dev/null +++ b/apps/web-antd/src/views/system/abplanguage/schema.ts @@ -0,0 +1,175 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import { $t } from '@vben/locales'; + +export const languageQuerySchema = computed(() => [ + { + component: 'Input', + fieldName: 'filter', + label: $t('common.keyword'), + }, +]); + +export const languageTableSchema: any = computed( + (): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { + field: 'cultureName', + title: $t('abp.language.language'), + minWidth: '150', + }, + { + field: 'displayName', + title: $t('abp.language.showLanguage'), + minWidth: '150', + }, + // { field: 'flagIcon', title: '图标', minWidth: '150' }, + { + field: 'isEnabled', + title: $t('common.isEnable'), + minWidth: '150', + slots: { default: 'isEnabled' }, + }, + ], +); + +export const languageTextQuerySchema = computed(() => [ + { + component: 'VbenSelect', + fieldName: 'cultureName', + label: $t('abp.language.language'), + defaultValue: 'zh-Hans', + componentProps: { + options: [ + { + label: '简体中文', + value: 'zh-Hans', + }, + { + label: 'en', + value: 'en', + }, + ], + }, + }, + { + component: 'VbenSelect', + fieldName: 'resourceName', + label: $t('abp.language.resourceName'), + componentProps: { + options: [], + }, + }, + { + component: 'Input', + fieldName: 'filter', + label: $t('common.keyword'), + }, +]); + +export const languageTextTableSchema: any = computed( + (): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { field: 'name', title: $t('abp.language.name'), minWidth: '150' }, + { field: 'value', title: $t('abp.language.value'), minWidth: '150' }, + { + field: 'resourceName', + title: $t('abp.language.resourceName'), + minWidth: '150', + }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '150', + slots: { default: 'action' }, + }, + ], +); + +export const addFormSchema = computed(() => [ + { + component: 'VbenSelect', + fieldName: 'cultureName', + label: $t('abp.language.language'), + defaultValue: 'zh-Hans', + componentProps: { + options: [ + { + label: '简体中文', + value: 'zh-Hans', + }, + { + label: 'en', + value: 'en', + }, + ], + }, + }, + { + component: 'VbenSelect', + fieldName: 'resourceName', + label: $t('abp.language.resourceName'), + componentProps: { + options: [], + }, + }, + { + fieldName: 'name', + label: $t('abp.language.name'), + component: 'Input', + componentProps: {}, + }, + { + fieldName: 'value', + label: $t('abp.language.value'), + component: 'Input', + componentProps: {}, + }, +]); + +export const editFormSchema = computed(() => [ + { + component: 'VbenSelect', + fieldName: 'cultureName', + label: $t('abp.language.language'), + defaultValue: 'zh-Hans', + componentProps: { + disabled: true, + options: [ + { + label: '简体中文', + value: 'zh-Hans', + }, + { + label: 'en', + value: 'en', + }, + ], + }, + }, + { + component: 'Input', + fieldName: 'resourceName', + label: $t('abp.language.resourceName'), + componentProps: { + disabled: true, + }, + }, + { + fieldName: 'name', + label: $t('abp.language.name'), + component: 'Input', + componentProps: { + disabled: true, + }, + }, + { + fieldName: 'value', + label: $t('abp.language.value'), + component: 'Input', + componentProps: {}, + }, +]); diff --git a/apps/web-antd/src/views/system/abplog/audit.vue b/apps/web-antd/src/views/system/abplog/audit.vue new file mode 100644 index 0000000..f0d482a --- /dev/null +++ b/apps/web-antd/src/views/system/abplog/audit.vue @@ -0,0 +1,96 @@ + + + + diff --git a/apps/web-antd/src/views/system/abplog/login.vue b/apps/web-antd/src/views/system/abplog/login.vue new file mode 100644 index 0000000..9e43a48 --- /dev/null +++ b/apps/web-antd/src/views/system/abplog/login.vue @@ -0,0 +1,62 @@ + + + diff --git a/apps/web-antd/src/views/system/abplog/schema.ts b/apps/web-antd/src/views/system/abplog/schema.ts new file mode 100644 index 0000000..bd23d3f --- /dev/null +++ b/apps/web-antd/src/views/system/abplog/schema.ts @@ -0,0 +1,120 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import dayjs from 'dayjs'; + +import { $t } from '#/locales'; + +export const logQuerySchema = computed(() => [ + { + component: 'RangePicker', + fieldName: 'time', + label: $t('abp.log.loginTime'), + componentProps: { + 'value-format': 'YYYY-MM-DD', + }, + defaultValue: [ + dayjs().subtract(0, 'day').format('YYYY-MM-DD'), + dayjs().format('YYYY-MM-DD'), + ], + }, + { + component: 'Input', + fieldName: 'userName', + label: $t('abp.log.userName'), + }, + { + component: 'Input', + fieldName: 'correlationId', + label: 'CorrelationId', + }, +]); + +export const logTableSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { + field: 'applicationName', + title: $t('abp.log.applicationName'), + minWidth: '150', + }, + { field: 'identity', title: $t('abp.log.loginMode'), minWidth: '150' }, + { field: 'action', title: $t('abp.log.loginUrl'), minWidth: '150' }, + { field: 'userName', title: $t('abp.log.userName'), minWidth: '150' }, + { field: 'correlationId', title: 'CorrelationId', minWidth: '150' }, + { field: 'clientIpAddress', title: $t('abp.log.clientIp'), minWidth: '150' }, + { + field: 'creationTime', + title: $t('common.createTime'), + minWidth: '150', + formatter: ({ cellValue }) => { + return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss'); + }, + }, +]); + +export const auditLogQuerySchema = computed(() => [ + { + component: 'RangePicker', + fieldName: 'time', + label: $t('abp.log.executionTime'), + componentProps: { + 'value-format': 'YYYY-MM-DD', + }, + defaultValue: [ + dayjs().subtract(0, 'day').format('YYYY-MM-DD'), + dayjs().format('YYYY-MM-DD'), + ], + }, + { + component: 'Input', + fieldName: 'userName', + label: $t('abp.log.userName'), + }, + { + component: 'Input', + fieldName: 'correlationId', + label: 'CorrelationId', + }, + { + component: 'Input', + fieldName: 'url', + label: 'Url', + }, +]); + +export const auditLogTableSchema: any = computed( + (): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { field: 'url', title: 'Url', minWidth: '150' }, + { field: 'tenantName', title: $t('abp.log.tenant'), minWidth: '150' }, + { field: 'userName', title: $t('abp.log.userName'), minWidth: '150' }, + { + field: 'executionTime', + title: $t('abp.log.executionTime'), + minWidth: '150', + formatter: ({ cellValue }) => { + return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss'); + }, + }, + { + field: 'executionDuration', + title: $t('abp.log.responseTime'), + minWidth: '150', + }, + { + field: 'clientIpAddress', + title: $t('abp.log.clientIp'), + minWidth: '150', + }, + { field: 'correlationId', title: 'CorrelationId', minWidth: '150' }, + { field: 'exceptions', title: $t('abp.log.exception'), minWidth: '150' }, + { + field: 'action', + fixed: 'right', + slots: { default: 'action' }, + title: '操作', + width: 120, + }, + ], +); diff --git a/apps/web-antd/src/views/system/abpmenu/AddModal.vue b/apps/web-antd/src/views/system/abpmenu/AddModal.vue new file mode 100644 index 0000000..f1b1adf --- /dev/null +++ b/apps/web-antd/src/views/system/abpmenu/AddModal.vue @@ -0,0 +1,54 @@ + + diff --git a/apps/web-antd/src/views/system/abpmenu/EditModal.vue b/apps/web-antd/src/views/system/abpmenu/EditModal.vue new file mode 100644 index 0000000..37d6481 --- /dev/null +++ b/apps/web-antd/src/views/system/abpmenu/EditModal.vue @@ -0,0 +1,80 @@ + + diff --git a/apps/web-antd/src/views/system/abpmenu/index.vue b/apps/web-antd/src/views/system/abpmenu/index.vue new file mode 100644 index 0000000..5253322 --- /dev/null +++ b/apps/web-antd/src/views/system/abpmenu/index.vue @@ -0,0 +1,180 @@ + + + + diff --git a/apps/web-antd/src/views/system/abpmenu/schema.ts b/apps/web-antd/src/views/system/abpmenu/schema.ts new file mode 100644 index 0000000..dceadc8 --- /dev/null +++ b/apps/web-antd/src/views/system/abpmenu/schema.ts @@ -0,0 +1,483 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed, h } from 'vue'; + +import dayjs from 'dayjs'; + +import { postMenusTree } from '#/api-client/index'; +import { Icon } from '#/components/icon'; +import { $t } from '#/locales'; + +async function getMenusTree() { + const response = await postMenusTree(); + return response.data; +} +export const querySchema = computed(() => [ + { + component: 'RangePicker', + fieldName: 'time', + label: $t('common.createTime'), + componentProps: { + 'value-format': 'YYYY-MM-DD', + }, + defaultValue: [ + // 最近7天 + dayjs().subtract(7, 'day').format('YYYY-MM-DD'), + dayjs().subtract(-1, 'day').format('YYYY-MM-DD'), + ], + }, +]); + +export const tableSchema: any = computed((): VxeGridProps['columns'] => [ + { + field: 'title', + title: '菜单名称', + treeNode: true, + align: 'left', + slots: { + default: ({ row }) => { + return row.icon + ? h('span', {}, [ + h(Icon, { + icon: row.icon, + }), + h( + 'span', + { + style: { + paddingLeft: '6px', + }, + }, + row.localizationTitle, + ), + ]) + : h('span', {}, row.localizationTitle); + }, + }, + }, + { + field: 'name', + title: $t('abp.dynamicMenu.name'), + }, + + { field: 'path', title: $t('abp.dynamicMenu.path') }, + { field: 'component', title: $t('abp.dynamicMenu.component') }, + { + field: 'policy', + title: $t('abp.dynamicMenu.policy'), + }, + { + field: 'menuType', + title: $t('abp.dynamicMenu.menuType'), + width: '100', + slots: { default: 'menuType' }, + }, + { + field: 'enabled', + title: $t('abp.dynamicMenu.enabled'), + width: '100', + slots: { default: 'enabled' }, + }, + { + field: 'hideInMenu', + title: $t('abp.dynamicMenu.hideInMenu'), + slots: { default: 'hideInMenu' }, + width: '100', + }, + { + field: 'keepAlive', + title: $t('abp.dynamicMenu.keepAlive'), + slots: { default: 'keepAlive' }, + width: '100', + }, + + { + field: 'order', + title: $t('abp.dynamicMenu.order'), + minWidth: '75', + width: '75', + }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '200', + slots: { default: 'action' }, + }, +]); + +export const addFormSchema = computed(() => [ + { + fieldName: 'menuType', + label: $t('abp.dynamicMenu.menuType'), + rules: 'required', + component: 'Select', + componentProps: { + options: [ + { label: $t('abp.dynamicMenu.folder'), value: 10 }, + { label: $t('abp.dynamicMenu.menu'), value: 20 }, + ], + }, + }, + { + fieldName: 'openType', + label: $t('abp.dynamicMenu.openType'), + rules: 'required', + component: 'Select', + componentProps: { + options: [ + { label: $t('abp.dynamicMenu.componentType'), value: 20 }, + { label: $t('abp.dynamicMenu.internalLink'), value: 30 }, + { label: $t('abp.dynamicMenu.externalLink'), value: 40 }, + ], + }, + dependencies: { + triggerFields: ['menuType'], + disabled: (values) => { + // 打开方式只有菜单==2才需配置 + values.component = values.menuType === 10 ? '' : ''; + values.openType = 20; + return values.menuType !== 20; + }, + }, + }, + { + fieldName: 'parentId', + label: $t('abp.dynamicMenu.parentId'), + component: 'ApiTreeSelect', + componentProps: { + childrenField: 'children', + allowClear: true, + api: getMenusTree, + labelField: 'meta.title', + valueField: 'id', + }, + }, + { + fieldName: 'name', + label: $t('abp.dynamicMenu.name'), + rules: 'required', + help: 'route.name', + component: 'Input', + }, + { + fieldName: 'path', + label: $t('abp.dynamicMenu.path'), + rules: 'required', + component: 'Input', + help: 'route.path', + }, + { + fieldName: 'policy', + label: $t('abp.dynamicMenu.policy'), + help: 'route.policy', + component: 'Input', + dependencies: { + triggerFields: ['menuType'], + disabled: (values) => { + if (values.menuType === 10) { + values.policy = ''; + return true; + } + }, + }, + }, + { + fieldName: 'title', + label: $t('abp.dynamicMenu.title'), + help: 'route.title', + rules: 'required', + component: 'Input', + }, + { + fieldName: 'displayTitle', + label: $t('abp.dynamicMenu.displayTitle'), + help: 'route.displayTitle', + component: 'Input', + }, + + { + fieldName: 'component', + label: $t('abp.dynamicMenu.component'), + help: 'route.component', + component: 'Input', + dependencies: { + triggerFields: ['openType', 'menuType'], + disabled: (values) => { + if ( + values.openType === 30 || + values.openType === 40 || + values.menuType === 10 + ) { + values.component = values.menuType === 10 ? '' : 'IFrameView'; + + return true; + } else { + values.component = ''; + } + }, + }, + }, + { + fieldName: 'icon', + label: $t('abp.dynamicMenu.icon'), + component: 'IconPicker', + }, + + { + fieldName: 'url', + label: $t('abp.dynamicMenu.url'), + component: 'Input', + dependencies: { + triggerFields: ['openType'], + disabled: (values) => { + if (values.openType === 20) { + return true; + } + }, + }, + }, + { + fieldName: 'keepAlive', + label: $t('abp.dynamicMenu.keepAlive'), + defaultValue: false, + help: 'meta.keepAlive', + component: 'RadioGroup', + componentProps: { + options: [ + { + label: $t('common.yes'), + value: true, + }, + { + label: $t('common.no'), + value: false, + }, + ], + }, + }, + { + fieldName: 'hideInMenu', + label: $t('abp.dynamicMenu.hideInMenu'), + help: 'meta.hideInMenu', + defaultValue: false, + component: 'RadioGroup', + componentProps: { + options: [ + { + label: $t('common.yes'), + value: true, + }, + { + label: $t('common.no'), + value: false, + }, + ], + }, + }, + { + fieldName: 'enabled', + label: $t('abp.dynamicMenu.enabled'), + defaultValue: true, + component: 'RadioGroup', + componentProps: { + options: [ + { + label: $t('common.yes'), + value: true, + }, + { + label: $t('common.no'), + value: false, + }, + ], + }, + }, + { + fieldName: 'order', + label: $t('abp.dynamicMenu.order'), + defaultValue: 1, + component: 'InputNumber', + }, +]); +export const editFormSchema = computed(() => [ + { + component: 'Input', + componentProps: {}, + fieldName: 'id', + label: 'id', + dependencies: { + show: () => false, + triggerFields: ['id'], + }, + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'parentId', + label: 'parentId', + dependencies: { + show: () => false, + triggerFields: ['parentId'], + }, + }, + { + fieldName: 'menuType', + label: $t('abp.dynamicMenu.menuType'), + rules: 'required', + component: 'Select', + componentProps: { + options: [ + { label: $t('abp.dynamicMenu.folder'), value: 10 }, + { label: $t('abp.dynamicMenu.menu'), value: 20 }, + ], + }, + }, + { + fieldName: 'openType', + label: $t('abp.dynamicMenu.openType'), + rules: 'required', + component: 'Select', + componentProps: { + options: [ + { label: $t('abp.dynamicMenu.componentType'), value: 20 }, + { label: $t('abp.dynamicMenu.internalLink'), value: 30 }, + { label: $t('abp.dynamicMenu.externalLink'), value: 40 }, + ], + }, + }, + { + fieldName: 'parentId', + label: $t('abp.dynamicMenu.parentId'), + component: 'ApiTreeSelect', + componentProps: { + childrenField: 'children', + allowClear: true, + api: getMenusTree, + labelField: 'meta.title', + valueField: 'id', + }, + }, + { + fieldName: 'name', + label: $t('abp.dynamicMenu.name'), + rules: 'required', + help: 'route.name', + component: 'Input', + }, + { + fieldName: 'path', + label: $t('abp.dynamicMenu.path'), + rules: 'required', + component: 'Input', + help: 'route.path', + }, + { + fieldName: 'policy', + label: $t('abp.dynamicMenu.policy'), + help: 'route.policy', + component: 'Input', + dependencies: { + triggerFields: ['menuType'], + disabled: (values) => { + if (values.menuType === 10) { + values.policy = ''; + return true; + } + }, + }, + }, + { + fieldName: 'title', + label: $t('abp.dynamicMenu.title'), + help: 'route.title', + rules: 'required', + component: 'Input', + }, + { + fieldName: 'displayTitle', + label: $t('abp.dynamicMenu.displayTitle'), + help: 'route.displayTitle', + component: 'Input', + }, + + { + fieldName: 'component', + label: $t('abp.dynamicMenu.component'), + help: 'route.component', + component: 'Input', + }, + { + fieldName: 'icon', + label: $t('abp.dynamicMenu.icon'), + component: 'IconPicker', + }, + + { + fieldName: 'url', + label: $t('abp.dynamicMenu.url'), + component: 'Input', + }, + { + fieldName: 'keepAlive', + label: $t('abp.dynamicMenu.keepAlive'), + defaultValue: false, + help: 'meta.keepAlive', + component: 'RadioGroup', + componentProps: { + options: [ + { + label: $t('common.yes'), + value: true, + }, + { + label: $t('common.no'), + value: false, + }, + ], + }, + }, + { + fieldName: 'hideInMenu', + label: $t('abp.dynamicMenu.hideInMenu'), + help: 'meta.hideInMenu', + defaultValue: true, + component: 'RadioGroup', + componentProps: { + options: [ + { + label: $t('common.yes'), + value: true, + }, + { + label: $t('common.no'), + value: false, + }, + ], + }, + }, + { + fieldName: 'enabled', + label: $t('abp.dynamicMenu.enabled'), + defaultValue: true, + component: 'RadioGroup', + componentProps: { + options: [ + { + label: $t('common.yes'), + value: true, + }, + { + label: $t('common.no'), + value: false, + }, + ], + }, + }, + { + fieldName: 'order', + label: $t('abp.dynamicMenu.order'), + defaultValue: 1, + component: 'InputNumber', + }, +]); diff --git a/apps/web-antd/src/views/system/abpnotification/message.vue b/apps/web-antd/src/views/system/abpnotification/message.vue new file mode 100644 index 0000000..55707d5 --- /dev/null +++ b/apps/web-antd/src/views/system/abpnotification/message.vue @@ -0,0 +1,292 @@ + + + + + diff --git a/apps/web-antd/src/views/system/abpnotification/notification.vue b/apps/web-antd/src/views/system/abpnotification/notification.vue new file mode 100644 index 0000000..87ffee5 --- /dev/null +++ b/apps/web-antd/src/views/system/abpnotification/notification.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/apps/web-antd/src/views/system/abpnotification/schema.ts b/apps/web-antd/src/views/system/abpnotification/schema.ts new file mode 100644 index 0000000..b00a770 --- /dev/null +++ b/apps/web-antd/src/views/system/abpnotification/schema.ts @@ -0,0 +1,288 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import { z } from '@vben/common-ui'; + +import dayjs from 'dayjs'; + +import { $t } from '#/locales'; + +export const querySchema = computed(() => [ + { + component: 'Input', + fieldName: 'messageType', + label: 'messageType', + defaultValue: 10, + dependencies: { + show: () => false, + triggerFields: ['messageType'], + }, + }, + { + component: 'Input', + fieldName: 'title', + label: $t('abp.message.title'), + }, + { + component: 'Input', + fieldName: 'content', + label: $t('abp.message.content'), + }, + { + component: 'Select', + fieldName: 'messageLevel', + label: $t('abp.message.level'), + width: 120, + componentProps: { + options: [ + { + label: $t('common.warning'), + value: 10, + }, + { + label: $t('common.info'), + value: 20, + }, + { + label: $t('common.error'), + value: 30, + }, + ], + }, + }, +]); +export const tableSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { field: 'title', title: $t('abp.message.title'), minWidth: '150' }, + { field: 'content', title: $t('abp.message.content'), minWidth: '150' }, + { + field: 'messageLevelName', + title: $t('abp.message.level'), + minWidth: '150', + slots: { default: 'messageLevel' }, + }, + { field: 'senderUserName', title: $t('abp.message.sender'), minWidth: '150' }, + { + field: 'creationTime', + title: $t('common.createTime'), + width: '150', + formatter: ({ cellValue }) => { + return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss'); + }, + }, +]); + +export const addFormSchema = computed(() => [ + { + component: 'Input', + componentProps: {}, + fieldName: 'title', + label: $t('abp.message.title'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.message.title') }), + }, + { + component: 'Textarea', + componentProps: {}, + fieldName: 'content', + label: $t('abp.message.content'), + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('abp.message.content'), + }), + }, + { + component: 'Select', + fieldName: 'messageLevel', + label: $t('abp.message.level'), + required: true, + defaultValue: 20, + componentProps: { + options: [ + { + label: $t('common.warning'), + value: 10, + }, + { + label: $t('common.info'), + value: 20, + }, + { + label: $t('common.error'), + value: 30, + }, + ], + }, + }, +]); + +export const addMessageFormSchema = computed(() => [ + { + component: 'Input', + componentProps: {}, + fieldName: 'userName', + label: $t('abp.message.receiver'), + required: true, + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'title', + label: $t('abp.message.title'), + required: true, + }, + { + component: 'Textarea', + componentProps: {}, + fieldName: 'content', + label: $t('abp.message.content'), + required: true, + }, + { + component: 'Select', + fieldName: 'messageLevel', + label: $t('abp.message.level'), + required: true, + defaultValue: 20, + componentProps: { + options: [ + { + label: $t('common.warning'), + value: 10, + }, + { + label: $t('common.info'), + value: 20, + }, + { + label: $t('common.error'), + value: 30, + }, + ], + }, + }, +]); + +export const tableMessageSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { field: 'title', title: $t('abp.message.title'), minWidth: '150' }, + { field: 'content', title: $t('abp.message.content'), minWidth: '150' }, + // { field: 'messageTypeName', title: '类型', minWidth: '150' }, + { + field: 'messageLevelName', + title: $t('abp.message.level'), + minWidth: '150', + slots: { default: 'messageLevel' }, + }, + { + field: 'senderUserName', + title: $t('abp.message.sender'), + minWidth: '150', + }, + { + field: 'receiveUserName', + title: $t('abp.message.receiver'), + minWidth: '150', + }, + { + field: 'read', + title: $t('abp.message.isRead'), + minWidth: '150', + slots: { default: 'read' }, + }, + { + field: 'creationTime', + title: $t('common.createTime'), + minWidth: '150', + formatter: ({ cellValue }) => { + return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss'); + }, + }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '150', + slots: { default: 'action' }, + }, +]); +export const queryMessageSchema = computed(() => [ + { + component: 'Input', + fieldName: 'messageType', + label: 'messageType', + defaultValue: 20, + dependencies: { + show: () => false, + triggerFields: ['messageType'], + }, + }, + { + component: 'Input', + fieldName: 'title', + label: $t('abp.message.title'), + }, + { + component: 'Input', + fieldName: 'content', + label: $t('abp.message.content'), + }, + { + component: 'Select', + fieldName: 'messageLevel', + label: $t('abp.message.level'), + width: 120, + componentProps: { + options: [ + { + label: $t('common.warning'), + value: 10, + }, + { + label: $t('common.info'), + value: 20, + }, + { + label: $t('common.error'), + value: 30, + }, + ], + }, + }, + // { + // component: 'Select', + // fieldName: 'messageType', + // label: '类型', + // width: 120, + // componentProps: { + // options: [ + // { + // label: '广播消息', + // value: 10, + // }, + // { + // label: '普通文本消息', + // value: 20, + // }, + // ], + // }, + // }, + { + component: 'Select', + fieldName: 'read', + label: $t('abp.message.isRead'), + componentProps: { + options: [ + { + label: $t('common.yes'), + value: true, + }, + { + label: $t('common.no'), + value: false, + }, + ], + }, + }, +]); diff --git a/apps/web-antd/src/views/system/abporganizationunit/ContextMenu.vue b/apps/web-antd/src/views/system/abporganizationunit/ContextMenu.vue new file mode 100644 index 0000000..e9b2c26 --- /dev/null +++ b/apps/web-antd/src/views/system/abporganizationunit/ContextMenu.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/apps/web-antd/src/views/system/abporganizationunit/OrgTreeAddModal.vue b/apps/web-antd/src/views/system/abporganizationunit/OrgTreeAddModal.vue new file mode 100644 index 0000000..44ee456 --- /dev/null +++ b/apps/web-antd/src/views/system/abporganizationunit/OrgTreeAddModal.vue @@ -0,0 +1,83 @@ + + diff --git a/apps/web-antd/src/views/system/abporganizationunit/OrgTreeEditModal.vue b/apps/web-antd/src/views/system/abporganizationunit/OrgTreeEditModal.vue new file mode 100644 index 0000000..a5d78ec --- /dev/null +++ b/apps/web-antd/src/views/system/abporganizationunit/OrgTreeEditModal.vue @@ -0,0 +1,72 @@ + + diff --git a/apps/web-antd/src/views/system/abporganizationunit/index.vue b/apps/web-antd/src/views/system/abporganizationunit/index.vue new file mode 100644 index 0000000..1cfa71c --- /dev/null +++ b/apps/web-antd/src/views/system/abporganizationunit/index.vue @@ -0,0 +1,705 @@ + + + + + diff --git a/apps/web-antd/src/views/system/abprole/index.vue b/apps/web-antd/src/views/system/abprole/index.vue new file mode 100644 index 0000000..f55ffca --- /dev/null +++ b/apps/web-antd/src/views/system/abprole/index.vue @@ -0,0 +1,346 @@ + + + + diff --git a/apps/web-antd/src/views/system/abprole/schema.ts b/apps/web-antd/src/views/system/abprole/schema.ts new file mode 100644 index 0000000..b788c53 --- /dev/null +++ b/apps/web-antd/src/views/system/abprole/schema.ts @@ -0,0 +1,71 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import { z } from '@vben/common-ui'; + +import { $t } from '#/locales'; + +export const querySchema = computed(() => [ + { + component: 'Input', + fieldName: 'filter', + label: $t('abp.role.roleName'), + }, +]); + +export const tableSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { + field: 'name', + title: $t('abp.role.roleName'), + minWidth: '150', + sortable: true, + }, + { + field: 'isDefault', + title: $t('abp.role.isDefault'), + minWidth: '75', + slots: { default: 'isDefault' }, + }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '200', + slots: { default: 'action' }, + }, +]); + +export const addRoleFormSchema = computed(() => [ + { + component: 'Input', + componentProps: { + placeholder: $t('common.pleaseInput') + $t('abp.role.roleName'), + }, + fieldName: 'name', + label: $t('abp.role.roleName'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.role.roleName') }), + }, + { + component: 'RadioGroup', + componentProps: { + options: [ + { + label: $t('common.yes'), + value: 1, + }, + { + label: $t('common.no'), + value: 0, + }, + ], + }, + defaultValue: 0, + fieldName: 'isDefault', + label: $t('abp.role.isDefault'), + rules: 'required', + }, +]); diff --git a/apps/web-antd/src/views/system/abpsetting/index.vue b/apps/web-antd/src/views/system/abpsetting/index.vue new file mode 100644 index 0000000..5ec38b8 --- /dev/null +++ b/apps/web-antd/src/views/system/abpsetting/index.vue @@ -0,0 +1,138 @@ + + + diff --git a/apps/web-antd/src/views/system/abptenant/AddEditModal.vue b/apps/web-antd/src/views/system/abptenant/AddEditModal.vue new file mode 100644 index 0000000..d5fe9b3 --- /dev/null +++ b/apps/web-antd/src/views/system/abptenant/AddEditModal.vue @@ -0,0 +1,63 @@ + + diff --git a/apps/web-antd/src/views/system/abptenant/ConnectionStringModal.vue b/apps/web-antd/src/views/system/abptenant/ConnectionStringModal.vue new file mode 100644 index 0000000..ec4b048 --- /dev/null +++ b/apps/web-antd/src/views/system/abptenant/ConnectionStringModal.vue @@ -0,0 +1,136 @@ + + diff --git a/apps/web-antd/src/views/system/abptenant/FeatureManageModal.vue b/apps/web-antd/src/views/system/abptenant/FeatureManageModal.vue new file mode 100644 index 0000000..c4d1423 --- /dev/null +++ b/apps/web-antd/src/views/system/abptenant/FeatureManageModal.vue @@ -0,0 +1,132 @@ + + diff --git a/apps/web-antd/src/views/system/abptenant/index.vue b/apps/web-antd/src/views/system/abptenant/index.vue new file mode 100644 index 0000000..d8ab0fd --- /dev/null +++ b/apps/web-antd/src/views/system/abptenant/index.vue @@ -0,0 +1,245 @@ + + + + + diff --git a/apps/web-antd/src/views/system/abptenant/schema.ts b/apps/web-antd/src/views/system/abptenant/schema.ts new file mode 100644 index 0000000..995ac44 --- /dev/null +++ b/apps/web-antd/src/views/system/abptenant/schema.ts @@ -0,0 +1,78 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import { z } from '@vben/common-ui'; + +import { $t } from '#/locales'; + +export const querySchema = computed(() => [ + { + component: 'Input', + fieldName: 'filter', + label: $t('abp.tenant.name'), + }, +]); + +export const tableSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { field: 'name', title: $t('abp.tenant.name'), minWidth: '150' }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '500', + slots: { default: 'action' }, + }, +]); + +export const addTenantFormSchema = computed(() => [ + { + component: 'Input', + componentProps: {}, + fieldName: 'name', + label: $t('abp.tenant.name'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.tenant.name') }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'adminEmailAddress', + label: $t('abp.tenant.adminEmail'), + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('abp.tenant.adminEmail'), + }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'adminPassword', + label: $t('abp.tenant.adminPassword'), + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('abp.tenant.adminPassword'), + }), + }, +]); + +export const editTenantFormSchemaEdit = computed(() => [ + { + component: 'Input', + fieldName: 'id', + label: 'id', + dependencies: { + show: () => false, + triggerFields: ['id'], + }, + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'name', + label: $t('abp.tenant.name'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.tenant.name') }), + }, +]); diff --git a/apps/web-antd/src/views/system/abpuser/index.vue b/apps/web-antd/src/views/system/abpuser/index.vue new file mode 100644 index 0000000..7291bec --- /dev/null +++ b/apps/web-antd/src/views/system/abpuser/index.vue @@ -0,0 +1,428 @@ + + + + + diff --git a/apps/web-antd/src/views/system/abpuser/schema.ts b/apps/web-antd/src/views/system/abpuser/schema.ts new file mode 100644 index 0000000..853358b --- /dev/null +++ b/apps/web-antd/src/views/system/abpuser/schema.ts @@ -0,0 +1,170 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import { z } from '@vben/common-ui'; + +import dayjs from 'dayjs'; + +import { $t } from '#/locales'; + +export const querySchema = computed(() => [ + { + component: 'Input', + fieldName: 'filter', + label: $t('abp.user.userName'), + }, +]); + +export const tableSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { field: 'userName', title: $t('abp.user.userName'), minWidth: '150' }, + { field: 'name', title: $t('abp.user.name'), minWidth: '150' }, + { field: 'email', title: $t('abp.user.email'), minWidth: '150' }, + { + field: 'isActive', + title: $t('abp.user.status'), + minWidth: '150', + slots: { default: 'isActive' }, + }, + { + field: 'twoFactorEnabled', + title: $t('abp.user.twoFactor'), + minWidth: '150', + slots: { default: 'twoFactorEnabled' }, + }, + { field: 'phoneNumber', title: $t('abp.user.phone'), minWidth: '150' }, + { + field: 'creationTime', + title: $t('common.createTime'), + minWidth: '150', + formatter: ({ cellValue }) => { + return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss'); + }, + }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '150', + slots: { default: 'action' }, + }, +]); + +export const addUserFormSchema: any = computed(() => [ + { + component: 'Input', + componentProps: {}, + fieldName: 'userName', + label: $t('abp.user.userName'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.user.userName') }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'name', + label: $t('abp.user.name'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.user.name') }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'email', + label: $t('abp.user.email'), + rules: z.string().email($t('common.pleaseInput') + $t('abp.user.email')), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'phoneNumber', + label: $t('abp.user.phone'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.user.phone') }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'password', + label: $t('abp.user.password'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.user.password') }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'confirmPassword', + label: $t('abp.user.comfirmPassword'), + rules: z.string().min(1, { + message: $t('common.pleaseInput') + $t('abp.user.comfirmPassword'), + }), + }, +]); + +export const editUserFormSchemaEdit: any = computed(() => [ + { + component: 'Input', + fieldName: 'isActive', + label: 'isActive', + dependencies: { + show: () => false, + triggerFields: ['isActive'], + }, + }, + { + component: 'Input', + componentProps: {}, + disabled: true, + fieldName: 'userName', + label: $t('abp.user.userName'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.user.userName') }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'name', + label: $t('abp.user.name'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.user.name') }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'email', + label: $t('abp.user.email'), + rules: z.string().email($t('common.pleaseInput') + $t('abp.user.email')), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'phoneNumber', + label: $t('abp.user.phone'), + rules: z + .string() + .min(1, { message: $t('common.pleaseInput') + $t('abp.user.phone') }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'password', + label: $t('abp.user.password'), + // rules: z.string().min(1, { message: $t('common.pleaseInput') + $t('abp.user.password') }), + }, + { + component: 'Input', + componentProps: {}, + fieldName: 'confirmPassword', + label: $t('abp.user.comfirmPassword'), + // rules: z + // .string() + // .min(1, { message: $t('common.pleaseInput') + $t('abp.user.comfirmPassword') }), + }, +]); diff --git a/apps/web-antd/src/views/textTemplate/AddModal.vue b/apps/web-antd/src/views/textTemplate/AddModal.vue new file mode 100644 index 0000000..b00d24a --- /dev/null +++ b/apps/web-antd/src/views/textTemplate/AddModal.vue @@ -0,0 +1,58 @@ + + diff --git a/apps/web-antd/src/views/textTemplate/EditModal.vue b/apps/web-antd/src/views/textTemplate/EditModal.vue new file mode 100644 index 0000000..5239521 --- /dev/null +++ b/apps/web-antd/src/views/textTemplate/EditModal.vue @@ -0,0 +1,67 @@ + + diff --git a/apps/web-antd/src/views/textTemplate/index.vue b/apps/web-antd/src/views/textTemplate/index.vue new file mode 100644 index 0000000..a4b9cb5 --- /dev/null +++ b/apps/web-antd/src/views/textTemplate/index.vue @@ -0,0 +1,176 @@ + + + + diff --git a/apps/web-antd/src/views/textTemplate/schema.ts b/apps/web-antd/src/views/textTemplate/schema.ts new file mode 100644 index 0000000..c344329 --- /dev/null +++ b/apps/web-antd/src/views/textTemplate/schema.ts @@ -0,0 +1,155 @@ +import type { VxeGridProps } from '#/adapter/vxe-table'; + +import { computed } from 'vue'; + +import { $t } from '#/locales'; + +export const querySchema = computed(() => [ + // { + // component: 'RangePicker', + // fieldName: 'time', + // label: $t('common.createTime'), + // componentProps: { + // 'value-format': 'YYYY-MM-DD', + // }, + // defaultValue: [ + // // 最近7天 + // dayjs().subtract(7, 'day').format('YYYY-MM-DD'), + // dayjs().subtract(-1, 'day').format('YYYY-MM-DD'), + // ], + // }, + { + component: 'Input', + fieldName: 'name', + label: $t('textTemplate.name'), + }, + { + component: 'Input', + fieldName: 'code', + label: $t('textTemplate.code'), + }, + { + component: 'Input', + fieldName: 'content', + label: $t('textTemplate.content'), + }, +]); + +export const tableSchema: any = computed((): VxeGridProps['columns'] => [ + { title: $t('common.seq'), type: 'seq', width: 50 }, + { + title: $t('textTemplate.name'), + minWidth: '150', + field: 'name', + }, + { + title: $t('textTemplate.code'), + minWidth: '150', + field: 'code', + }, + { + title: $t('textTemplate.content'), + minWidth: '150', + field: 'content', + }, + { + title: $t('textTemplate.cultureName'), + minWidth: '150', + field: 'cultureName', + }, + { + title: $t('common.action'), + field: 'action', + fixed: 'right', + width: '150', + slots: { default: 'action' }, + }, +]); + +export const addFormSchema = computed(() => [ + { + fieldName: 'name', + label: $t('textTemplate.name'), + rules: 'required', + component: 'Input', + }, + { + fieldName: 'code', + label: $t('textTemplate.code'), + rules: 'required', + component: 'Input', + }, + { + fieldName: 'content', + label: $t('textTemplate.content'), + rules: 'required', + component: 'Textarea', + }, + { + fieldName: 'cultureName', + label: $t('textTemplate.cultureName'), + rules: 'required', + component: 'Select', + componentProps: { + options: [ + { + label: 'en', + value: 'en', + }, + { + label: '简体中文', + value: 'zh-Hans', + }, + ], + }, + }, +]); + +export const editFormSchema = computed(() => [ + { + component: 'Input', + componentProps: {}, + fieldName: 'id', + label: 'id', + dependencies: { + show: () => false, + triggerFields: ['id'], + }, + }, + { + fieldName: 'name', + label: $t('textTemplate.name'), + rules: 'required', + component: 'Input', + }, + { + fieldName: 'code', + label: $t('textTemplate.code'), + rules: 'required', + component: 'Input', + }, + { + fieldName: 'content', + label: $t('textTemplate.content'), + rules: 'required', + component: 'Textarea', + }, + { + fieldName: 'cultureName', + label: $t('textTemplate.cultureName'), + rules: 'required', + component: 'Select', + componentProps: { + options: [ + { + label: 'en', + value: 'en', + }, + { + label: '简体中文', + value: 'zh-Hans', + }, + ], + }, + }, +]); diff --git a/apps/web-antd/tailwind.config.mjs b/apps/web-antd/tailwind.config.mjs new file mode 100644 index 0000000..f17f556 --- /dev/null +++ b/apps/web-antd/tailwind.config.mjs @@ -0,0 +1 @@ +export { default } from '@vben/tailwind-config'; diff --git a/apps/web-antd/tsconfig.json b/apps/web-antd/tsconfig.json new file mode 100644 index 0000000..02c287f --- /dev/null +++ b/apps/web-antd/tsconfig.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/web-app.json", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "#/*": ["./src/*"] + } + }, + "references": [{ "path": "./tsconfig.node.json" }], + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] +} diff --git a/apps/web-antd/tsconfig.node.json b/apps/web-antd/tsconfig.node.json new file mode 100644 index 0000000..c2f0d86 --- /dev/null +++ b/apps/web-antd/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/node.json", + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "noEmit": false + }, + "include": ["vite.config.mts"] +} diff --git a/apps/web-antd/vite.config.mts b/apps/web-antd/vite.config.mts new file mode 100644 index 0000000..7b9fe83 --- /dev/null +++ b/apps/web-antd/vite.config.mts @@ -0,0 +1,32 @@ +import { defineConfig } from '@vben/vite-config'; + +import { loadEnv } from 'vite'; + +export default defineConfig(async (config) => { + const { command, mode } = config as { command: string; mode: string }; + const env = loadEnv(mode, process.cwd()); + console.log(env, '-----------env', command); + return { + application: {}, + vite: { + server: { + proxy: { + '/proxy': { + changeOrigin: true, + rewrite: (path) => path.replace(/^\/proxy/, ''), + // mock代理目标地址 + target: env.VITE_APP_API_ADDRESS, + ws: true, + }, + // '/api': { + // changeOrigin: true, + // rewrite: (path) => path.replace(/^\/api/, ''), + // // mock代理目标地址 + // target: 'http://localhost:5320/api', + // ws: true, + // }, + }, + }, + }, + }; +}); diff --git a/cspell.json b/cspell.json new file mode 100644 index 0000000..89545b4 --- /dev/null +++ b/cspell.json @@ -0,0 +1,68 @@ +{ + "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", + "version": "0.2", + "language": "en,en-US", + "allowCompoundWords": true, + "words": [ + "acmr", + "antd", + "antdv", + "astro", + "brotli", + "clsx", + "defu", + "demi", + "echarts", + "ependencies", + "esno", + "etag", + "execa", + "iconify", + "iconoir", + "intlify", + "lockb", + "lucide", + "minh", + "minw", + "mkdist", + "mockjs", + "naiveui", + "nocheck", + "noopener", + "noreferrer", + "nprogress", + "nuxt", + "pinia", + "prefixs", + "publint", + "qrcode", + "shadcn", + "sonner", + "sortablejs", + "styl", + "taze", + "ui-kit", + "uicons", + "unplugin", + "unref", + "vben", + "vbenjs", + "vite", + "vitejs", + "vitepress", + "vnode", + "vueuse", + "yxxx" + ], + "ignorePaths": [ + "**/node_modules/**", + "**/dist/**", + "**/*-dist/**", + "**/icons/**", + "pnpm-lock.yaml", + "**/*.log", + "**/*.test.ts", + "**/*.spec.ts", + "**/__tests__/**" + ] +} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..b29b567 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,5 @@ +// @ts-check + +import { defineConfig } from '@vben/eslint-config'; + +export default defineConfig(); diff --git a/internal/lint-configs/commitlint-config/index.mjs b/internal/lint-configs/commitlint-config/index.mjs new file mode 100644 index 0000000..3d85439 --- /dev/null +++ b/internal/lint-configs/commitlint-config/index.mjs @@ -0,0 +1,153 @@ +import { execSync } from 'node:child_process'; + +import { getPackagesSync } from '@vben/node-utils'; + +const { packages } = getPackagesSync(); + +const allowedScopes = [ + ...packages.map((pkg) => pkg.packageJson.name), + 'project', + 'style', + 'lint', + 'ci', + 'dev', + 'deploy', + 'other', +]; + +// precomputed scope +const scopeComplete = execSync('git status --porcelain || true') + .toString() + .trim() + .split('\n') + .find((r) => ~r.indexOf('M src')) + ?.replace(/(\/)/g, '%%') + ?.match(/src%%((\w|-)*)/)?.[1] + ?.replace(/s$/, ''); + +/** + * @type {import('cz-git').UserConfig} + */ +const userConfig = { + extends: ['@commitlint/config-conventional'], + plugins: ['commitlint-plugin-function-rules'], + prompt: { + /** @use `pnpm commit :f` */ + alias: { + b: 'build: bump dependencies', + c: 'chore: update config', + f: 'docs: fix typos', + r: 'docs: update README', + s: 'style: update code format', + }, + allowCustomIssuePrefixs: false, + // scopes: [...scopes, 'mock'], + allowEmptyIssuePrefixs: false, + customScopesAlign: scopeComplete ? 'bottom' : 'top', + defaultScope: scopeComplete, + // English + typesAppend: [ + { name: 'workflow: workflow improvements', value: 'workflow' }, + { name: 'types: type definition file changes', value: 'types' }, + ], + + // 中英文对照版 + // messages: { + // type: '选择你要提交的类型 :', + // scope: '选择一个提交范围 (可选):', + // customScope: '请输入自定义的提交范围 :', + // subject: '填写简短精炼的变更描述 :\n', + // body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n', + // breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n', + // footerPrefixsSelect: '选择关联issue前缀 (可选):', + // customFooterPrefixs: '输入自定义issue前缀 :', + // footer: '列举关联issue (可选) 例如: #31, #I3244 :\n', + // confirmCommit: '是否提交或修改commit ?', + // }, + // types: [ + // { value: 'feat', name: 'feat: 新增功能' }, + // { value: 'fix', name: 'fix: 修复缺陷' }, + // { value: 'docs', name: 'docs: 文档变更' }, + // { value: 'style', name: 'style: 代码格式' }, + // { value: 'refactor', name: 'refactor: 代码重构' }, + // { value: 'perf', name: 'perf: 性能优化' }, + // { value: 'test', name: 'test: 添加疏漏测试或已有测试改动' }, + // { value: 'build', name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)' }, + // { value: 'ci', name: 'ci: 修改 CI 配置、脚本' }, + // { value: 'revert', name: 'revert: 回滚 commit' }, + // { value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)' }, + // { value: 'wip', name: 'wip: 正在开发中' }, + // { value: 'workflow', name: 'workflow: 工作流程改进' }, + // { value: 'types', name: 'types: 类型定义文件修改' }, + // ], + // emptyScopesAlias: 'empty: 不填写', + // customScopesAlias: 'custom: 自定义', + }, + rules: { + /** + * type[scope]: [function] description + * + * ^^^^^^^^^^^^^^ empty line. + * - Something here + */ + 'body-leading-blank': [2, 'always'], + /** + * type[scope]: [function] description + * + * - something here + * + * ^^^^^^^^^^^^^^ + */ + 'footer-leading-blank': [1, 'always'], + /** + * type[scope]: [function] description + * ^^^^^ + */ + 'function-rules/scope-enum': [ + 2, // level: error + 'always', + (parsed) => { + if (!parsed.scope || allowedScopes.includes(parsed.scope)) { + return [true]; + } + + return [false, `scope must be one of ${allowedScopes.join(', ')}`]; + }, + ], + /** + * type[scope]: [function] description [No more than 108 characters] + * ^^^^^ + */ + 'header-max-length': [2, 'always', 108], + + 'scope-enum': [0], + 'subject-case': [0], + 'subject-empty': [2, 'never'], + 'type-empty': [2, 'never'], + /** + * type[scope]: [function] description + * ^^^^ + */ + 'type-enum': [ + 2, + 'always', + [ + 'feat', + 'fix', + 'perf', + 'style', + 'docs', + 'test', + 'refactor', + 'build', + 'ci', + 'chore', + 'revert', + 'types', + 'release', + ], + ], + }, +}; + +export default userConfig; diff --git a/internal/lint-configs/commitlint-config/package.json b/internal/lint-configs/commitlint-config/package.json new file mode 100644 index 0000000..c17cde2 --- /dev/null +++ b/internal/lint-configs/commitlint-config/package.json @@ -0,0 +1,33 @@ +{ + "name": "@vben/commitlint-config", + "version": "5.5.6", + "private": true, + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "internal/lint-configs/commitlint-config" + }, + "license": "MIT", + "type": "module", + "files": [ + "dist" + ], + "main": "./index.mjs", + "module": "./index.mjs", + "exports": { + ".": { + "import": "./index.mjs", + "default": "./index.mjs" + } + }, + "dependencies": { + "@commitlint/cli": "catalog:", + "@commitlint/config-conventional": "catalog:", + "@vben/node-utils": "workspace:*", + "commitlint-plugin-function-rules": "catalog:", + "cz-git": "catalog:", + "czg": "catalog:" + } +} diff --git a/internal/lint-configs/eslint-config/build.config.ts b/internal/lint-configs/eslint-config/build.config.ts new file mode 100644 index 0000000..97e572c --- /dev/null +++ b/internal/lint-configs/eslint-config/build.config.ts @@ -0,0 +1,7 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + clean: true, + declaration: true, + entries: ['src/index'], +}); diff --git a/internal/lint-configs/eslint-config/package.json b/internal/lint-configs/eslint-config/package.json new file mode 100644 index 0000000..12556ec --- /dev/null +++ b/internal/lint-configs/eslint-config/package.json @@ -0,0 +1,56 @@ +{ + "name": "@vben/eslint-config", + "version": "5.0.0", + "private": true, + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "internal/lint-configs/eslint-config" + }, + "license": "MIT", + "type": "module", + "scripts": { + "stub": "pnpm unbuild --stub" + }, + "files": [ + "dist" + ], + "main": "./dist/index.mjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs" + } + }, + "dependencies": { + "eslint-config-turbo": "catalog:", + "eslint-plugin-command": "catalog:", + "eslint-plugin-import-x": "catalog:" + }, + "devDependencies": { + "@eslint/js": "catalog:", + "@types/eslint": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "eslint": "catalog:", + "eslint-plugin-eslint-comments": "catalog:", + "eslint-plugin-jsdoc": "catalog:", + "eslint-plugin-jsonc": "catalog:", + "eslint-plugin-n": "catalog:", + "eslint-plugin-no-only-tests": "catalog:", + "eslint-plugin-perfectionist": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-regexp": "catalog:", + "eslint-plugin-unicorn": "catalog:", + "eslint-plugin-unused-imports": "catalog:", + "eslint-plugin-vitest": "catalog:", + "eslint-plugin-vue": "catalog:", + "globals": "catalog:", + "jsonc-eslint-parser": "catalog:", + "vue-eslint-parser": "catalog:" + } +} diff --git a/internal/lint-configs/eslint-config/src/configs/command.ts b/internal/lint-configs/eslint-config/src/configs/command.ts new file mode 100644 index 0000000..67651b2 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/command.ts @@ -0,0 +1,10 @@ +import createCommand from 'eslint-plugin-command/config'; + +export async function command() { + return [ + { + // @ts-expect-error - no types + ...createCommand(), + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/comments.ts b/internal/lint-configs/eslint-config/src/configs/comments.ts new file mode 100644 index 0000000..77ccd5d --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/comments.ts @@ -0,0 +1,24 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function comments(): Promise { + const [pluginComments] = await Promise.all([ + // @ts-expect-error - no types + interopDefault(import('eslint-plugin-eslint-comments')), + ] as const); + + return [ + { + plugins: { + 'eslint-comments': pluginComments, + }, + rules: { + 'eslint-comments/no-aggregating-enable': 'error', + 'eslint-comments/no-duplicate-disable': 'error', + 'eslint-comments/no-unlimited-disable': 'error', + 'eslint-comments/no-unused-enable': 'error', + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/disableds.ts b/internal/lint-configs/eslint-config/src/configs/disableds.ts new file mode 100644 index 0000000..152b84c --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/disableds.ts @@ -0,0 +1,28 @@ +import type { Linter } from 'eslint'; + +export async function disableds(): Promise { + return [ + { + files: ['**/__tests__/**/*.?([cm])[jt]s?(x)'], + name: 'disables/test', + rules: { + '@typescript-eslint/ban-ts-comment': 'off', + 'no-console': 'off', + }, + }, + { + files: ['**/*.d.ts'], + name: 'disables/dts', + rules: { + '@typescript-eslint/triple-slash-reference': 'off', + }, + }, + { + files: ['**/*.js', '**/*.mjs', '**/*.cjs'], + name: 'disables/js', + rules: { + '@typescript-eslint/explicit-module-boundary-types': 'off', + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/ignores.ts b/internal/lint-configs/eslint-config/src/configs/ignores.ts new file mode 100644 index 0000000..136c956 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/ignores.ts @@ -0,0 +1,52 @@ +import type { Linter } from 'eslint'; + +export async function ignores(): Promise { + return [ + { + ignores: [ + '**/node_modules', + '**/dist', + '**/dist-*', + '**/*-dist', + '**/.husky', + '**/.nitro', + '**/.output', + '**/Dockerfile', + '**/package-lock.json', + '**/yarn.lock', + '**/pnpm-lock.yaml', + '**/bun.lockb', + '**/output', + '**/coverage', + '**/temp', + '**/.temp', + '**/tmp', + '**/.tmp', + '**/.history', + '**/.turbo', + '**/.nuxt', + '**/.next', + '**/.vercel', + '**/.changeset', + '**/.idea', + '**/.cache', + '**/.output', + '**/.vite-inspect', + + '**/CHANGELOG*.md', + '**/*.min.*', + '**/LICENSE*', + '**/__snapshots__', + '**/*.snap', + '**/fixtures/**', + '**/.vitepress/cache/**', + '**/auto-import?(s).d.ts', + '**/components.d.ts', + '**/vite.config.mts.*', + '**/*.sh', + '**/*.ttf', + '**/*.woff', + ], + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/import.ts b/internal/lint-configs/eslint-config/src/configs/import.ts new file mode 100644 index 0000000..ce6cf65 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/import.ts @@ -0,0 +1,25 @@ +import type { Linter } from 'eslint'; + +import * as pluginImport from 'eslint-plugin-import-x'; + +export async function importPluginConfig(): Promise { + return [ + { + plugins: { + // @ts-expect-error - This is a dynamic import + import: pluginImport, + }, + rules: { + 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], + 'import/first': 'error', + 'import/newline-after-import': 'error', + 'import/no-duplicates': 'error', + 'import/no-mutable-exports': 'error', + 'import/no-named-default': 'error', + 'import/no-self-import': 'error', + 'import/no-unresolved': 'off', + 'import/no-webpack-loader-syntax': 'error', + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/index.ts b/internal/lint-configs/eslint-config/src/configs/index.ts new file mode 100644 index 0000000..c0284ef --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/index.ts @@ -0,0 +1,17 @@ +export * from './command'; +export * from './comments'; +export * from './disableds'; +export * from './ignores'; +export * from './import'; +export * from './javascript'; +export * from './jsdoc'; +export * from './jsonc'; +export * from './node'; +export * from './perfectionist'; +export * from './prettier'; +export * from './regexp'; +export * from './test'; +export * from './turbo'; +export * from './typescript'; +export * from './unicorn'; +export * from './vue'; diff --git a/internal/lint-configs/eslint-config/src/configs/javascript.ts b/internal/lint-configs/eslint-config/src/configs/javascript.ts new file mode 100644 index 0000000..44cf5b6 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/javascript.ts @@ -0,0 +1,241 @@ +import type { Linter } from 'eslint'; + +import js from '@eslint/js'; +import pluginUnusedImports from 'eslint-plugin-unused-imports'; +import globals from 'globals'; + +export async function javascript(): Promise { + return [ + { + languageOptions: { + ecmaVersion: 'latest', + globals: { + ...globals.browser, + ...globals.es2021, + ...globals.node, + document: 'readonly', + navigator: 'readonly', + window: 'readonly', + }, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 'latest', + sourceType: 'module', + }, + sourceType: 'module', + }, + linterOptions: { + reportUnusedDisableDirectives: true, + }, + plugins: { + 'unused-imports': pluginUnusedImports, + }, + rules: { + ...js.configs.recommended.rules, + 'accessor-pairs': [ + 'error', + { enforceForClassMembers: true, setWithoutGet: true }, + ], + 'array-callback-return': 'error', + 'block-scoped-var': 'error', + 'constructor-super': 'error', + 'default-case-last': 'error', + 'dot-notation': ['error', { allowKeywords: true }], + eqeqeq: ['error', 'always'], + 'keyword-spacing': 'off', + + 'new-cap': [ + 'error', + { capIsNew: false, newIsCap: true, properties: true }, + ], + 'no-alert': 'error', + 'no-array-constructor': 'error', + 'no-async-promise-executor': 'error', + 'no-caller': 'error', + 'no-case-declarations': 'error', + 'no-class-assign': 'error', + 'no-compare-neg-zero': 'error', + 'no-cond-assign': ['error', 'always'], + 'no-console': ['error', { allow: ['warn', 'error'] }], + 'no-const-assign': 'error', + 'no-control-regex': 'error', + 'no-debugger': 'error', + 'no-delete-var': 'error', + 'no-dupe-args': 'error', + 'no-dupe-class-members': 'error', + 'no-dupe-keys': 'error', + 'no-duplicate-case': 'error', + 'no-empty': ['error', { allowEmptyCatch: true }], + 'no-empty-character-class': 'error', + 'no-empty-function': 'off', + 'no-empty-pattern': 'error', + 'no-eval': 'error', + 'no-ex-assign': 'error', + 'no-extend-native': 'error', + 'no-extra-bind': 'error', + 'no-extra-boolean-cast': 'error', + 'no-fallthrough': 'error', + 'no-func-assign': 'error', + 'no-global-assign': 'error', + 'no-implied-eval': 'error', + 'no-import-assign': 'error', + 'no-invalid-regexp': 'error', + 'no-irregular-whitespace': 'error', + 'no-iterator': 'error', + 'no-labels': ['error', { allowLoop: false, allowSwitch: false }], + 'no-lone-blocks': 'error', + 'no-loss-of-precision': 'error', + 'no-misleading-character-class': 'error', + 'no-multi-str': 'error', + 'no-new': 'error', + 'no-new-func': 'error', + 'no-new-object': 'error', + 'no-new-symbol': 'error', + 'no-new-wrappers': 'error', + 'no-obj-calls': 'error', + 'no-octal': 'error', + 'no-octal-escape': 'error', + 'no-proto': 'error', + 'no-prototype-builtins': 'error', + 'no-redeclare': ['error', { builtinGlobals: false }], + 'no-regex-spaces': 'error', + 'no-restricted-globals': [ + 'error', + { message: 'Use `globalThis` instead.', name: 'global' }, + { message: 'Use `globalThis` instead.', name: 'self' }, + ], + 'no-restricted-properties': [ + 'error', + { + message: + 'Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.', + property: '__proto__', + }, + { + message: 'Use `Object.defineProperty` instead.', + property: '__defineGetter__', + }, + { + message: 'Use `Object.defineProperty` instead.', + property: '__defineSetter__', + }, + { + message: 'Use `Object.getOwnPropertyDescriptor` instead.', + property: '__lookupGetter__', + }, + { + message: 'Use `Object.getOwnPropertyDescriptor` instead.', + property: '__lookupSetter__', + }, + ], + 'no-restricted-syntax': [ + 'error', + 'DebuggerStatement', + 'LabeledStatement', + 'WithStatement', + 'TSEnumDeclaration[const=true]', + 'TSExportAssignment', + ], + 'no-self-assign': ['error', { props: true }], + 'no-self-compare': 'error', + 'no-sequences': 'error', + 'no-shadow-restricted-names': 'error', + 'no-sparse-arrays': 'error', + 'no-template-curly-in-string': 'error', + 'no-this-before-super': 'error', + 'no-throw-literal': 'error', + 'no-undef': 'off', + 'no-undef-init': 'error', + 'no-unexpected-multiline': 'error', + 'no-unmodified-loop-condition': 'error', + 'no-unneeded-ternary': ['error', { defaultAssignment: false }], + 'no-unreachable': 'error', + 'no-unreachable-loop': 'error', + 'no-unsafe-finally': 'error', + 'no-unsafe-negation': 'error', + 'no-unused-expressions': [ + 'error', + { + allowShortCircuit: true, + allowTaggedTemplates: true, + allowTernary: true, + }, + ], + 'no-unused-vars': [ + 'error', + { + args: 'none', + caughtErrors: 'none', + ignoreRestSiblings: true, + vars: 'all', + }, + ], + 'no-use-before-define': [ + 'error', + { classes: false, functions: false, variables: false }, + ], + 'no-useless-backreference': 'error', + 'no-useless-call': 'error', + 'no-useless-catch': 'error', + 'no-useless-computed-key': 'error', + 'no-useless-constructor': 'error', + 'no-useless-rename': 'error', + 'no-useless-return': 'error', + 'no-var': 'error', + 'no-with': 'error', + 'object-shorthand': [ + 'error', + 'always', + { avoidQuotes: true, ignoreConstructors: false }, + ], + 'one-var': ['error', { initialized: 'never' }], + 'prefer-arrow-callback': [ + 'error', + { + allowNamedFunctions: false, + allowUnboundThis: true, + }, + ], + 'prefer-const': [ + 'error', + { + destructuring: 'all', + ignoreReadBeforeAssign: true, + }, + ], + 'prefer-exponentiation-operator': 'error', + + 'prefer-promise-reject-errors': 'error', + 'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }], + 'prefer-rest-params': 'error', + 'prefer-spread': 'error', + 'prefer-template': 'error', + 'space-before-function-paren': 'off', + 'spaced-comment': 'error', + 'symbol-description': 'error', + 'unicode-bom': ['error', 'never'], + + 'unused-imports/no-unused-imports': 'error', + 'unused-imports/no-unused-vars': [ + 'error', + { + args: 'after-used', + argsIgnorePattern: '^_', + vars: 'all', + varsIgnorePattern: '^_', + }, + ], + 'use-isnan': [ + 'error', + { enforceForIndexOf: true, enforceForSwitchCase: true }, + ], + 'valid-typeof': ['error', { requireStringLiterals: true }], + + 'vars-on-top': 'error', + yoda: ['error', 'never'], + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/jsdoc.ts b/internal/lint-configs/eslint-config/src/configs/jsdoc.ts new file mode 100644 index 0000000..1368197 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/jsdoc.ts @@ -0,0 +1,34 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function jsdoc(): Promise { + const [pluginJsdoc] = await Promise.all([ + interopDefault(import('eslint-plugin-jsdoc')), + ] as const); + + return [ + { + plugins: { + jsdoc: pluginJsdoc, + }, + rules: { + 'jsdoc/check-access': 'warn', + 'jsdoc/check-param-names': 'warn', + 'jsdoc/check-property-names': 'warn', + 'jsdoc/check-types': 'warn', + 'jsdoc/empty-tags': 'warn', + 'jsdoc/implements-on-classes': 'warn', + 'jsdoc/no-defaults': 'warn', + 'jsdoc/no-multi-asterisks': 'warn', + 'jsdoc/require-param-name': 'warn', + 'jsdoc/require-property': 'warn', + 'jsdoc/require-property-description': 'warn', + 'jsdoc/require-property-name': 'warn', + 'jsdoc/require-returns-check': 'warn', + 'jsdoc/require-returns-description': 'warn', + 'jsdoc/require-yields-check': 'warn', + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/jsonc.ts b/internal/lint-configs/eslint-config/src/configs/jsonc.ts new file mode 100644 index 0000000..4072e4c --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/jsonc.ts @@ -0,0 +1,258 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function jsonc(): Promise { + const [pluginJsonc, parserJsonc] = await Promise.all([ + interopDefault(import('eslint-plugin-jsonc')), + interopDefault(import('jsonc-eslint-parser')), + ] as const); + + return [ + { + files: ['**/*.json', '**/*.json5', '**/*.jsonc', '*.code-workspace'], + languageOptions: { + parser: parserJsonc as any, + }, + plugins: { + jsonc: pluginJsonc as any, + }, + rules: { + 'jsonc/no-bigint-literals': 'error', + 'jsonc/no-binary-expression': 'error', + 'jsonc/no-binary-numeric-literals': 'error', + 'jsonc/no-dupe-keys': 'error', + 'jsonc/no-escape-sequence-in-identifier': 'error', + 'jsonc/no-floating-decimal': 'error', + 'jsonc/no-hexadecimal-numeric-literals': 'error', + 'jsonc/no-infinity': 'error', + 'jsonc/no-multi-str': 'error', + 'jsonc/no-nan': 'error', + 'jsonc/no-number-props': 'error', + 'jsonc/no-numeric-separators': 'error', + 'jsonc/no-octal': 'error', + 'jsonc/no-octal-escape': 'error', + 'jsonc/no-octal-numeric-literals': 'error', + 'jsonc/no-parenthesized': 'error', + 'jsonc/no-plus-sign': 'error', + 'jsonc/no-regexp-literals': 'error', + 'jsonc/no-sparse-arrays': 'error', + 'jsonc/no-template-literals': 'error', + 'jsonc/no-undefined-value': 'error', + 'jsonc/no-unicode-codepoint-escapes': 'error', + 'jsonc/no-useless-escape': 'error', + 'jsonc/space-unary-ops': 'error', + 'jsonc/valid-json-number': 'error', + 'jsonc/vue-custom-block/no-parsing-error': 'error', + }, + }, + sortTsconfig(), + sortPackageJson(), + ]; +} + +function sortPackageJson(): Linter.Config { + return { + files: ['**/package.json'], + rules: { + 'jsonc/sort-array-values': [ + 'error', + { + order: { type: 'asc' }, + pathPattern: '^files$|^pnpm.neverBuiltDependencies$', + }, + ], + 'jsonc/sort-keys': [ + 'error', + { + order: [ + 'name', + 'version', + 'description', + 'private', + 'keywords', + 'homepage', + 'bugs', + 'repository', + 'license', + 'author', + 'contributors', + 'categories', + 'funding', + 'type', + 'scripts', + 'files', + 'sideEffects', + 'bin', + 'main', + 'module', + 'unpkg', + 'jsdelivr', + 'types', + 'typesVersions', + 'imports', + 'exports', + 'publishConfig', + 'icon', + 'activationEvents', + 'contributes', + 'peerDependencies', + 'peerDependenciesMeta', + 'dependencies', + 'optionalDependencies', + 'devDependencies', + 'engines', + 'packageManager', + 'pnpm', + 'overrides', + 'resolutions', + 'husky', + 'simple-git-hooks', + 'lint-staged', + 'eslintConfig', + ], + pathPattern: '^$', + }, + { + order: { type: 'asc' }, + pathPattern: '^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$', + }, + { + order: { type: 'asc' }, + pathPattern: '^(?:resolutions|overrides|pnpm.overrides)$', + }, + { + order: ['types', 'import', 'require', 'default'], + pathPattern: '^exports.*$', + }, + ], + }, + }; +} + +function sortTsconfig(): Linter.Config { + return { + files: [ + '**/tsconfig.json', + '**/tsconfig.*.json', + 'internal/tsconfig/*.json', + ], + rules: { + 'jsonc/sort-keys': [ + 'error', + { + order: [ + 'extends', + 'compilerOptions', + 'references', + 'files', + 'include', + 'exclude', + ], + pathPattern: '^$', + }, + { + order: [ + /* Projects */ + 'incremental', + 'composite', + 'tsBuildInfoFile', + 'disableSourceOfProjectReferenceRedirect', + 'disableSolutionSearching', + 'disableReferencedProjectLoad', + /* Language and Environment */ + 'target', + 'jsx', + 'jsxFactory', + 'jsxFragmentFactory', + 'jsxImportSource', + 'lib', + 'moduleDetection', + 'noLib', + 'reactNamespace', + 'useDefineForClassFields', + 'emitDecoratorMetadata', + 'experimentalDecorators', + /* Modules */ + 'baseUrl', + 'rootDir', + 'rootDirs', + 'customConditions', + 'module', + 'moduleResolution', + 'moduleSuffixes', + 'noResolve', + 'paths', + 'resolveJsonModule', + 'resolvePackageJsonExports', + 'resolvePackageJsonImports', + 'typeRoots', + 'types', + 'allowArbitraryExtensions', + 'allowImportingTsExtensions', + 'allowUmdGlobalAccess', + /* JavaScript Support */ + 'allowJs', + 'checkJs', + 'maxNodeModuleJsDepth', + /* Type Checking */ + 'strict', + 'strictBindCallApply', + 'strictFunctionTypes', + 'strictNullChecks', + 'strictPropertyInitialization', + 'allowUnreachableCode', + 'allowUnusedLabels', + 'alwaysStrict', + 'exactOptionalPropertyTypes', + 'noFallthroughCasesInSwitch', + 'noImplicitAny', + 'noImplicitOverride', + 'noImplicitReturns', + 'noImplicitThis', + 'noPropertyAccessFromIndexSignature', + 'noUncheckedIndexedAccess', + 'noUnusedLocals', + 'noUnusedParameters', + 'useUnknownInCatchVariables', + /* Emit */ + 'declaration', + 'declarationDir', + 'declarationMap', + 'downlevelIteration', + 'emitBOM', + 'emitDeclarationOnly', + 'importHelpers', + 'importsNotUsedAsValues', + 'inlineSourceMap', + 'inlineSources', + 'mapRoot', + 'newLine', + 'noEmit', + 'noEmitHelpers', + 'noEmitOnError', + 'outDir', + 'outFile', + 'preserveConstEnums', + 'preserveValueImports', + 'removeComments', + 'sourceMap', + 'sourceRoot', + 'stripInternal', + /* Interop Constraints */ + 'allowSyntheticDefaultImports', + 'esModuleInterop', + 'forceConsistentCasingInFileNames', + 'isolatedModules', + 'preserveSymlinks', + 'verbatimModuleSyntax', + /* Completeness */ + 'skipDefaultLibCheck', + 'skipLibCheck', + ], + pathPattern: '^compilerOptions$', + }, + ], + }, + }; +} diff --git a/internal/lint-configs/eslint-config/src/configs/node.ts b/internal/lint-configs/eslint-config/src/configs/node.ts new file mode 100644 index 0000000..fa960d8 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/node.ts @@ -0,0 +1,57 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function node(): Promise { + const pluginNode = await interopDefault(import('eslint-plugin-n')); + + return [ + { + plugins: { + n: pluginNode, + }, + rules: { + 'n/handle-callback-err': ['error', '^(err|error)$'], + 'n/no-deprecated-api': 'error', + 'n/no-exports-assign': 'error', + 'n/no-extraneous-import': [ + 'error', + { + allowModules: [ + 'unbuild', + '@vben/vite-config', + 'vitest', + 'vite', + '@vue/test-utils', + '@vben/tailwind-config', + '@playwright/test', + ], + }, + ], + 'n/no-new-require': 'error', + 'n/no-path-concat': 'error', + // 'n/no-unpublished-import': 'off', + 'n/no-unsupported-features/es-syntax': [ + 'error', + { + ignores: [], + version: '>=18.0.0', + }, + ], + 'n/prefer-global/buffer': ['error', 'never'], + // 'n/no-missing-import': 'off', + 'n/prefer-global/process': ['error', 'never'], + 'n/process-exit-as-throw': 'error', + }, + }, + { + files: [ + 'scripts/**/*.?([cm])[jt]s?(x)', + 'internal/**/*.?([cm])[jt]s?(x)', + ], + rules: { + 'n/prefer-global/process': 'off', + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/perfectionist.ts b/internal/lint-configs/eslint-config/src/configs/perfectionist.ts new file mode 100644 index 0000000..136bfa3 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/perfectionist.ts @@ -0,0 +1,89 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function perfectionist(): Promise { + const perfectionistPlugin = await interopDefault( + // @ts-expect-error - no types + import('eslint-plugin-perfectionist'), + ); + + return [ + perfectionistPlugin.configs['recommended-natural'], + { + rules: { + 'perfectionist/sort-exports': [ + 'error', + { + order: 'asc', + type: 'natural', + }, + ], + 'perfectionist/sort-imports': [ + 'error', + { + customGroups: { + type: { + 'vben-core-type': ['^@vben-core/.+'], + 'vben-type': ['^@vben/.+'], + 'vue-type': ['^vue$', '^vue-.+', '^@vue/.+'], + }, + value: { + vben: ['^@vben/.+'], + 'vben-core': ['^@vben-core/.+'], + vue: ['^vue$', '^vue-.+', '^@vue/.+'], + }, + }, + environment: 'node', + groups: [ + ['external-type', 'builtin-type', 'type'], + 'vue-type', + 'vben-type', + 'vben-core-type', + ['parent-type', 'sibling-type', 'index-type'], + ['internal-type'], + 'builtin', + 'vue', + 'vben', + 'vben-core', + 'external', + 'internal', + ['parent', 'sibling', 'index'], + 'side-effect', + 'side-effect-style', + 'style', + 'object', + 'unknown', + ], + internalPattern: ['^#/.+'], + newlinesBetween: 'always', + order: 'asc', + type: 'natural', + }, + ], + 'perfectionist/sort-modules': 'off', + 'perfectionist/sort-named-exports': [ + 'error', + { + order: 'asc', + type: 'natural', + }, + ], + 'perfectionist/sort-objects': [ + 'off', + { + customGroups: { + items: 'items', + list: 'list', + children: 'children', + }, + groups: ['unknown', 'items', 'list', 'children'], + ignorePattern: ['children'], + order: 'asc', + type: 'natural', + }, + ], + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/prettier.ts b/internal/lint-configs/eslint-config/src/configs/prettier.ts new file mode 100644 index 0000000..3cd7af4 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/prettier.ts @@ -0,0 +1,19 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function prettier(): Promise { + const [pluginPrettier] = await Promise.all([ + interopDefault(import('eslint-plugin-prettier')), + ] as const); + return [ + { + plugins: { + prettier: pluginPrettier, + }, + rules: { + 'prettier/prettier': 'error', + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/regexp.ts b/internal/lint-configs/eslint-config/src/configs/regexp.ts new file mode 100644 index 0000000..c0f4c9f --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/regexp.ts @@ -0,0 +1,20 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function regexp(): Promise { + const [pluginRegexp] = await Promise.all([ + interopDefault(import('eslint-plugin-regexp')), + ] as const); + + return [ + { + plugins: { + regexp: pluginRegexp, + }, + rules: { + ...pluginRegexp.configs.recommended.rules, + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/test.ts b/internal/lint-configs/eslint-config/src/configs/test.ts new file mode 100644 index 0000000..ddfde2b --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/test.ts @@ -0,0 +1,45 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function test(): Promise { + const [pluginTest, pluginNoOnlyTests] = await Promise.all([ + interopDefault(import('eslint-plugin-vitest')), + // @ts-expect-error - no types + interopDefault(import('eslint-plugin-no-only-tests')), + ] as const); + + return [ + { + files: [ + `**/__tests__/**/*.?([cm])[jt]s?(x)`, + `**/*.spec.?([cm])[jt]s?(x)`, + `**/*.test.?([cm])[jt]s?(x)`, + `**/*.bench.?([cm])[jt]s?(x)`, + `**/*.benchmark.?([cm])[jt]s?(x)`, + ], + plugins: { + test: { + ...pluginTest, + rules: { + ...pluginTest.rules, + ...pluginNoOnlyTests.rules, + }, + }, + }, + rules: { + 'no-console': 'off', + 'node/prefer-global/process': 'off', + 'test/consistent-test-it': [ + 'error', + { fn: 'it', withinDescribe: 'it' }, + ], + 'test/no-identical-title': 'error', + 'test/no-import-node-test': 'error', + 'test/no-only-tests': 'error', + 'test/prefer-hooks-in-order': 'error', + 'test/prefer-lowercase-title': 'error', + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/turbo.ts b/internal/lint-configs/eslint-config/src/configs/turbo.ts new file mode 100644 index 0000000..9f6bf75 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/turbo.ts @@ -0,0 +1,18 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function turbo(): Promise { + const [pluginTurbo] = await Promise.all([ + // @ts-expect-error - no types + interopDefault(import('eslint-config-turbo')), + ] as const); + + return [ + { + plugins: { + turbo: pluginTurbo, + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/typescript.ts b/internal/lint-configs/eslint-config/src/configs/typescript.ts new file mode 100644 index 0000000..cff9aa4 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/typescript.ts @@ -0,0 +1,72 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function typescript(): Promise { + const [pluginTs, parserTs] = await Promise.all([ + interopDefault(import('@typescript-eslint/eslint-plugin')), + // @ts-expect-error missing types + interopDefault(import('@typescript-eslint/parser')), + ] as const); + + return [ + { + files: ['**/*.?([cm])[jt]s?(x)'], + languageOptions: { + parser: parserTs, + parserOptions: { + createDefaultProgram: false, + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 'latest', + extraFileExtensions: ['.vue'], + jsxPragma: 'React', + project: './tsconfig.*.json', + sourceType: 'module', + }, + }, + plugins: { + '@typescript-eslint': pluginTs, + }, + rules: { + ...pluginTs.configs['eslint-recommended'].overrides?.[0].rules, + ...pluginTs.configs.strict.rules, + '@typescript-eslint/ban-ts-comment': [ + 'error', + { + 'ts-check': false, + 'ts-expect-error': 'allow-with-description', + 'ts-ignore': 'allow-with-description', + 'ts-nocheck': 'allow-with-description', + }, + ], + + // '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'], + '@typescript-eslint/consistent-type-definitions': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-empty-function': [ + 'error', + { + allow: ['arrowFunctions', 'functions', 'methods'], + }, + ], + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-namespace': 'off', + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-unused-expressions': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + }, + ], + '@typescript-eslint/no-use-before-define': 'off', + '@typescript-eslint/no-var-requires': 'error', + 'unused-imports/no-unused-vars': 'off', + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/unicorn.ts b/internal/lint-configs/eslint-config/src/configs/unicorn.ts new file mode 100644 index 0000000..21b1902 --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/unicorn.ts @@ -0,0 +1,45 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function unicorn(): Promise { + const [pluginUnicorn] = await Promise.all([ + interopDefault(import('eslint-plugin-unicorn')), + ] as const); + + return [ + { + plugins: { + unicorn: pluginUnicorn, + }, + rules: { + ...pluginUnicorn.configs.recommended.rules, + + 'unicorn/better-regex': 'off', + 'unicorn/consistent-destructuring': 'off', + 'unicorn/consistent-function-scoping': 'off', + 'unicorn/expiring-todo-comments': 'off', + 'unicorn/filename-case': 'off', + 'unicorn/import-style': 'off', + 'unicorn/no-array-for-each': 'off', + 'unicorn/no-null': 'off', + 'unicorn/no-useless-undefined': 'off', + 'unicorn/prefer-at': 'off', + 'unicorn/prefer-dom-node-text-content': 'off', + 'unicorn/prefer-export-from': ['error', { ignoreUsedVariables: true }], + 'unicorn/prefer-global-this': 'off', + 'unicorn/prefer-top-level-await': 'off', + 'unicorn/prevent-abbreviations': 'off', + }, + }, + { + files: [ + 'scripts/**/*.?([cm])[jt]s?(x)', + 'internal/**/*.?([cm])[jt]s?(x)', + ], + rules: { + 'unicorn/no-process-exit': 'off', + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/configs/vue.ts b/internal/lint-configs/eslint-config/src/configs/vue.ts new file mode 100644 index 0000000..a64c55a --- /dev/null +++ b/internal/lint-configs/eslint-config/src/configs/vue.ts @@ -0,0 +1,153 @@ +import type { Linter } from 'eslint'; + +import { interopDefault } from '../util'; + +export async function vue(): Promise { + const [pluginVue, parserVue, parserTs] = await Promise.all([ + interopDefault(import('eslint-plugin-vue')), + interopDefault(import('vue-eslint-parser')), + // @ts-expect-error missing types + interopDefault(import('@typescript-eslint/parser')), + ] as const); + + const flatEssential = pluginVue.configs?.['flat/essential'] || []; + const flatStronglyRecommended = + pluginVue.configs?.['flat/strongly-recommended'] || []; + const flatRecommended = pluginVue.configs?.['flat/recommended'] || []; + + return [ + ...flatEssential, + ...flatStronglyRecommended, + ...flatRecommended, + { + files: ['**/*.vue'], + languageOptions: { + // globals: { + // computed: 'readonly', + // defineEmits: 'readonly', + // defineExpose: 'readonly', + // defineProps: 'readonly', + // onMounted: 'readonly', + // onUnmounted: 'readonly', + // reactive: 'readonly', + // ref: 'readonly', + // shallowReactive: 'readonly', + // shallowRef: 'readonly', + // toRef: 'readonly', + // toRefs: 'readonly', + // watch: 'readonly', + // watchEffect: 'readonly', + // }, + parser: parserVue, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + extraFileExtensions: ['.vue'], + parser: parserTs, + sourceType: 'module', + }, + }, + plugins: { + vue: pluginVue, + }, + processor: pluginVue.processors?.['.vue'], + rules: { + ...pluginVue.configs?.base?.rules, + + 'vue/attribute-hyphenation': [ + 'error', + 'always', + { + ignore: [], + }, + ], + 'vue/attributes-order': 'off', + 'vue/block-order': [ + 'error', + { + order: ['script', 'template', 'style'], + }, + ], + 'vue/component-name-in-template-casing': ['error', 'PascalCase'], + 'vue/component-options-name-casing': ['error', 'PascalCase'], + 'vue/custom-event-name-casing': ['error', 'camelCase'], + 'vue/define-macros-order': [ + 'error', + { + order: [ + 'defineOptions', + 'defineProps', + 'defineEmits', + 'defineSlots', + ], + }, + ], + 'vue/dot-location': ['error', 'property'], + 'vue/dot-notation': ['error', { allowKeywords: true }], + 'vue/eqeqeq': ['error', 'smart'], + 'vue/html-closing-bracket-newline': 'error', + 'vue/html-indent': 'off', + // 'vue/html-indent': ['error', 2], + 'vue/html-quotes': ['error', 'double'], + 'vue/html-self-closing': [ + 'error', + { + html: { + component: 'always', + normal: 'never', + void: 'always', + }, + math: 'always', + svg: 'always', + }, + ], + 'vue/max-attributes-per-line': 'off', + 'vue/multi-word-component-names': 'off', + 'vue/multiline-html-element-content-newline': 'error', + 'vue/no-empty-pattern': 'error', + 'vue/no-extra-parens': ['error', 'functions'], + 'vue/no-irregular-whitespace': 'error', + 'vue/no-loss-of-precision': 'error', + 'vue/no-reserved-component-names': 'off', + 'vue/no-restricted-syntax': [ + 'error', + 'DebuggerStatement', + 'LabeledStatement', + 'WithStatement', + ], + 'vue/no-restricted-v-bind': ['error', '/^v-/'], + 'vue/no-sparse-arrays': 'error', + 'vue/no-unused-refs': 'error', + 'vue/no-useless-v-bind': 'error', + 'vue/object-shorthand': [ + 'error', + 'always', + { + avoidQuotes: true, + ignoreConstructors: false, + }, + ], + 'vue/one-component-per-file': 'error', + 'vue/prefer-import-from-vue': 'error', + 'vue/prefer-separate-static-class': 'error', + 'vue/prefer-template': 'error', + 'vue/prop-name-casing': ['error', 'camelCase'], + 'vue/require-default-prop': 'error', + 'vue/require-explicit-emits': 'error', + 'vue/require-prop-types': 'off', + 'vue/singleline-html-element-content-newline': 'off', + 'vue/space-infix-ops': 'error', + 'vue/space-unary-ops': ['error', { nonwords: false, words: true }], + 'vue/v-on-event-hyphenation': [ + 'error', + 'always', + { + autofix: true, + ignore: [], + }, + ], + }, + }, + ]; +} diff --git a/internal/lint-configs/eslint-config/src/custom-config.ts b/internal/lint-configs/eslint-config/src/custom-config.ts new file mode 100644 index 0000000..27c3e2f --- /dev/null +++ b/internal/lint-configs/eslint-config/src/custom-config.ts @@ -0,0 +1,168 @@ +import type { Linter } from 'eslint'; + +const restrictedImportIgnores = [ + '**/vite.config.mts', + '**/tailwind.config.mjs', + '**/postcss.config.mjs', +]; + +const customConfig: Linter.Config[] = [ + // shadcn-ui 内部组件是自动生成的,不做太多限制 + { + files: ['packages/@core/ui-kit/shadcn-ui/**/**'], + rules: { + 'vue/require-default-prop': 'off', + }, + }, + { + files: [ + 'apps/**/**', + 'packages/effects/**/**', + 'packages/utils/**/**', + 'packages/types/**/**', + 'packages/locales/**/**', + ], + ignores: restrictedImportIgnores, + rules: { + 'perfectionist/sort-interfaces': 'off', + 'perfectionist/sort-objects': 'off', + }, + }, + { + files: ['**/**.vue'], + ignores: restrictedImportIgnores, + rules: { + 'perfectionist/sort-objects': 'off', + }, + }, + { + // apps内部的一些基础规则 + files: ['apps/**/**'], + ignores: restrictedImportIgnores, + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['#/api/*'], + message: + 'The #/api package cannot be imported, please use the @core package itself', + }, + { + group: ['#/layouts/*'], + message: + 'The #/layouts package cannot be imported, please use the @core package itself', + }, + { + group: ['#/locales/*'], + message: + 'The #/locales package cannot be imported, please use the @core package itself', + }, + { + group: ['#/stores/*'], + message: + 'The #/stores package cannot be imported, please use the @core package itself', + }, + ], + }, + ], + 'perfectionist/sort-interfaces': 'off', + }, + }, + { + // @core内部组件,不能引入@vben/* 里面的包 + files: ['packages/@core/**/**'], + ignores: restrictedImportIgnores, + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['@vben/*'], + message: + 'The @core package cannot import the @vben package, please use the @core package itself', + }, + ], + }, + ], + }, + }, + { + // @core/shared内部组件,不能引入@vben/* 或者 @vben-core/* 里面的包 + files: ['packages/@core/base/**/**'], + ignores: restrictedImportIgnores, + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['@vben/*', '@vben-core/*'], + message: + 'The @vben-core/shared package cannot import the @vben package, please use the @core/shared package itself', + }, + ], + }, + ], + }, + }, + + { + // 不能引入@vben/*里面的包 + files: [ + 'packages/types/**/**', + 'packages/utils/**/**', + 'packages/icons/**/**', + 'packages/constants/**/**', + 'packages/styles/**/**', + 'packages/stores/**/**', + 'packages/preferences/**/**', + 'packages/locales/**/**', + ], + ignores: restrictedImportIgnores, + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['@vben/*'], + message: + 'The @vben package cannot be imported, please use the @core package itself', + }, + ], + }, + ], + }, + }, + // 后端模拟代码,不需要太多规则 + { + files: ['apps/backend-mock/**/**', 'docs/**/**'], + rules: { + '@typescript-eslint/no-extraneous-class': 'off', + 'n/no-extraneous-import': 'off', + 'n/prefer-global/buffer': 'off', + 'n/prefer-global/process': 'off', + 'no-console': 'off', + 'unicorn/prefer-module': 'off', + }, + }, + { + files: ['**/**/playwright.config.ts'], + rules: { + 'n/prefer-global/buffer': 'off', + 'n/prefer-global/process': 'off', + 'no-console': 'off', + }, + }, + { + files: ['internal/**/**', 'scripts/**/**'], + rules: { + 'no-console': 'off', + }, + }, +]; + +export { customConfig }; diff --git a/internal/lint-configs/eslint-config/src/index.ts b/internal/lint-configs/eslint-config/src/index.ts new file mode 100644 index 0000000..c9f08bd --- /dev/null +++ b/internal/lint-configs/eslint-config/src/index.ts @@ -0,0 +1,60 @@ +import type { Linter } from 'eslint'; + +import { + command, + comments, + disableds, + ignores, + importPluginConfig, + javascript, + jsdoc, + jsonc, + node, + perfectionist, + prettier, + regexp, + test, + turbo, + typescript, + unicorn, + vue, +} from './configs'; +import { customConfig } from './custom-config'; + +type FlatConfig = Linter.Config; + +type FlatConfigPromise = + | FlatConfig + | FlatConfig[] + | Promise + | Promise; + +async function defineConfig(config: FlatConfig[] = []) { + const configs: FlatConfigPromise[] = [ + vue(), + javascript(), + ignores(), + prettier(), + typescript(), + jsonc(), + disableds(), + importPluginConfig(), + node(), + perfectionist(), + comments(), + jsdoc(), + unicorn(), + test(), + regexp(), + command(), + turbo(), + ...customConfig, + ...config, + ]; + + const resolved = await Promise.all(configs); + + return resolved.flat(); +} + +export { defineConfig }; diff --git a/internal/lint-configs/eslint-config/src/util.ts b/internal/lint-configs/eslint-config/src/util.ts new file mode 100644 index 0000000..d1a10ad --- /dev/null +++ b/internal/lint-configs/eslint-config/src/util.ts @@ -0,0 +1,8 @@ +export type Awaitable = Promise | T; + +export async function interopDefault( + m: Awaitable, +): Promise { + const resolved = await m; + return (resolved as any).default || resolved; +} diff --git a/internal/lint-configs/eslint-config/tsconfig.json b/internal/lint-configs/eslint-config/tsconfig.json new file mode 100644 index 0000000..b2ec3b6 --- /dev/null +++ b/internal/lint-configs/eslint-config/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/node.json", + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/internal/lint-configs/prettier-config/index.mjs b/internal/lint-configs/prettier-config/index.mjs new file mode 100644 index 0000000..f6a20c8 --- /dev/null +++ b/internal/lint-configs/prettier-config/index.mjs @@ -0,0 +1,18 @@ +export default { + endOfLine: 'auto', + overrides: [ + { + files: ['*.json5'], + options: { + quoteProps: 'preserve', + singleQuote: false, + }, + }, + ], + plugins: ['prettier-plugin-tailwindcss'], + printWidth: 80, + proseWrap: 'never', + semi: true, + singleQuote: true, + trailingComma: 'all', +}; diff --git a/internal/lint-configs/prettier-config/package.json b/internal/lint-configs/prettier-config/package.json new file mode 100644 index 0000000..65e8b8f --- /dev/null +++ b/internal/lint-configs/prettier-config/package.json @@ -0,0 +1,28 @@ +{ + "name": "@vben/prettier-config", + "version": "5.0.0", + "private": true, + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "internal/lint-configs/prettier-config" + }, + "license": "MIT", + "type": "module", + "files": [ + "dist" + ], + "main": "./index.mjs", + "module": "./index.mjs", + "exports": { + ".": { + "default": "./index.mjs" + } + }, + "dependencies": { + "prettier": "catalog:", + "prettier-plugin-tailwindcss": "catalog:" + } +} diff --git a/internal/lint-configs/stylelint-config/index.mjs b/internal/lint-configs/stylelint-config/index.mjs new file mode 100644 index 0000000..08ac823 --- /dev/null +++ b/internal/lint-configs/stylelint-config/index.mjs @@ -0,0 +1,141 @@ +export default { + extends: ['stylelint-config-standard', 'stylelint-config-recess-order'], + ignoreFiles: [ + '**/*.js', + '**/*.jsx', + '**/*.tsx', + '**/*.ts', + '**/*.json', + '**/*.md', + ], + overrides: [ + { + customSyntax: 'postcss-html', + files: ['*.(html|vue)', '**/*.(html|vue)'], + rules: { + 'selector-pseudo-class-no-unknown': [ + true, + { + ignorePseudoClasses: ['global', 'deep'], + }, + ], + 'selector-pseudo-element-no-unknown': [ + true, + { + ignorePseudoElements: ['v-deep', 'v-global', 'v-slotted'], + }, + ], + }, + }, + { + customSyntax: 'postcss-scss', + extends: [ + 'stylelint-config-recommended-scss', + 'stylelint-config-recommended-vue/scss', + ], + files: ['*.scss', '**/*.scss'], + }, + ], + plugins: [ + 'stylelint-order', + '@stylistic/stylelint-plugin', + 'stylelint-prettier', + 'stylelint-scss', + ], + rules: { + 'at-rule-no-deprecated': null, + 'at-rule-no-unknown': [ + true, + { + ignoreAtRules: [ + 'extends', + 'ignores', + 'include', + 'mixin', + 'if', + 'else', + 'media', + 'for', + 'at-root', + 'tailwind', + 'apply', + 'variants', + 'responsive', + 'screen', + 'function', + 'each', + 'use', + 'forward', + 'return', + ], + }, + ], + 'font-family-no-missing-generic-family-keyword': null, + 'function-no-unknown': null, + 'import-notation': null, + 'media-feature-range-notation': null, + 'named-grid-areas-no-invalid': null, + 'no-descending-specificity': null, + 'no-empty-source': null, + 'order/order': [ + [ + 'dollar-variables', + 'custom-properties', + 'at-rules', + 'declarations', + { + name: 'supports', + type: 'at-rule', + }, + { + name: 'media', + type: 'at-rule', + }, + { + name: 'include', + type: 'at-rule', + }, + 'rules', + ], + { severity: 'error' }, + ], + 'prettier/prettier': true, + 'rule-empty-line-before': [ + 'always', + { + ignore: ['after-comment', 'first-nested'], + }, + ], + 'scss/at-rule-no-unknown': [ + true, + { + ignoreAtRules: [ + 'extends', + 'ignores', + 'include', + 'mixin', + 'if', + 'else', + 'media', + 'for', + 'at-root', + 'tailwind', + 'apply', + 'variants', + 'responsive', + 'screen', + 'function', + 'each', + 'use', + 'forward', + 'return', + ], + }, + ], + 'scss/operator-no-newline-after': null, + 'selector-class-pattern': + '^(?:(?:o|c|u|t|s|is|has|_|js|qa)-)?[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*(?:__[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:--[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:[.+])?$', + + 'selector-not-notation': null, + }, +}; diff --git a/internal/lint-configs/stylelint-config/package.json b/internal/lint-configs/stylelint-config/package.json new file mode 100644 index 0000000..ee55c70 --- /dev/null +++ b/internal/lint-configs/stylelint-config/package.json @@ -0,0 +1,43 @@ +{ + "name": "@vben/stylelint-config", + "version": "5.5.6", + "private": true, + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "internal/lint-configs/stylelint-config" + }, + "license": "MIT", + "type": "module", + "files": [ + "dist" + ], + "main": "./index.mjs", + "module": "./index.mjs", + "exports": { + ".": { + "import": "./index.mjs", + "default": "./index.mjs" + } + }, + "dependencies": { + "@stylistic/stylelint-plugin": "catalog:", + "stylelint-config-recess-order": "catalog:", + "stylelint-scss": "catalog:" + }, + "devDependencies": { + "postcss": "catalog:", + "postcss-html": "catalog:", + "postcss-scss": "catalog:", + "prettier": "catalog:", + "stylelint": "catalog:", + "stylelint-config-recommended": "catalog:", + "stylelint-config-recommended-scss": "catalog:", + "stylelint-config-recommended-vue": "catalog:", + "stylelint-config-standard": "catalog:", + "stylelint-order": "catalog:", + "stylelint-prettier": "catalog:" + } +} diff --git a/internal/node-utils/build.config.ts b/internal/node-utils/build.config.ts new file mode 100644 index 0000000..97e572c --- /dev/null +++ b/internal/node-utils/build.config.ts @@ -0,0 +1,7 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + clean: true, + declaration: true, + entries: ['src/index'], +}); diff --git a/internal/node-utils/package.json b/internal/node-utils/package.json new file mode 100644 index 0000000..782c0b3 --- /dev/null +++ b/internal/node-utils/package.json @@ -0,0 +1,43 @@ +{ + "name": "@vben/node-utils", + "version": "5.5.6", + "private": true, + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "internal/node-utils" + }, + "license": "MIT", + "type": "module", + "scripts": { + "stub": "pnpm unbuild --stub" + }, + "files": [ + "dist" + ], + "main": "./dist/index.mjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./dist/index.mjs", + "default": "./dist/index.mjs" + } + }, + "dependencies": { + "@changesets/git": "catalog:", + "@manypkg/get-packages": "catalog:", + "chalk": "catalog:", + "consola": "catalog:", + "dayjs": "catalog:", + "execa": "catalog:", + "find-up": "catalog:", + "ora": "catalog:", + "pkg-types": "catalog:", + "prettier": "catalog:", + "rimraf": "catalog:" + } +} diff --git a/internal/node-utils/src/__tests__/hash.test.ts b/internal/node-utils/src/__tests__/hash.test.ts new file mode 100644 index 0000000..3851306 --- /dev/null +++ b/internal/node-utils/src/__tests__/hash.test.ts @@ -0,0 +1,52 @@ +import { createHash } from 'node:crypto'; + +import { describe, expect, it } from 'vitest'; + +import { generatorContentHash } from '../hash'; + +describe('generatorContentHash', () => { + it('should generate an MD5 hash for the content', () => { + const content = 'example content'; + const expectedHash = createHash('md5') + .update(content, 'utf8') + .digest('hex'); + const actualHash = generatorContentHash(content); + expect(actualHash).toBe(expectedHash); + }); + + it('should generate an MD5 hash with specified length', () => { + const content = 'example content'; + const hashLength = 10; + const generatedHash = generatorContentHash(content, hashLength); + expect(generatedHash).toHaveLength(hashLength); + }); + + it('should correctly generate the hash with specified length', () => { + const content = 'example content'; + const hashLength = 8; + const expectedHash = createHash('md5') + .update(content, 'utf8') + .digest('hex') + .slice(0, hashLength); + const generatedHash = generatorContentHash(content, hashLength); + expect(generatedHash).toBe(expectedHash); + }); + + it('should return full hash if hash length parameter is not provided', () => { + const content = 'example content'; + const expectedHash = createHash('md5') + .update(content, 'utf8') + .digest('hex'); + const actualHash = generatorContentHash(content); + expect(actualHash).toBe(expectedHash); + }); + + it('should handle empty content', () => { + const content = ''; + const expectedHash = createHash('md5') + .update(content, 'utf8') + .digest('hex'); + const actualHash = generatorContentHash(content); + expect(actualHash).toBe(expectedHash); + }); +}); diff --git a/internal/node-utils/src/__tests__/path.test.ts b/internal/node-utils/src/__tests__/path.test.ts new file mode 100644 index 0000000..3bab5a1 --- /dev/null +++ b/internal/node-utils/src/__tests__/path.test.ts @@ -0,0 +1,67 @@ +// pathUtils.test.ts + +import { describe, expect, it } from 'vitest'; + +import { toPosixPath } from '../path'; + +describe('toPosixPath', () => { + // 测试 Windows 风格路径到 POSIX 风格路径的转换 + it('converts Windows-style paths to POSIX paths', () => { + const windowsPath = String.raw`C:\Users\Example\file.txt`; + const expectedPosixPath = 'C:/Users/Example/file.txt'; + expect(toPosixPath(windowsPath)).toBe(expectedPosixPath); + }); + + // 确认 POSIX 风格路径不会被改变 + it('leaves POSIX-style paths unchanged', () => { + const posixPath = '/home/user/file.txt'; + expect(toPosixPath(posixPath)).toBe(posixPath); + }); + + // 测试带有多个分隔符的路径 + it('converts paths with mixed separators', () => { + const mixedPath = String.raw`C:/Users\Example\file.txt`; + const expectedPosixPath = 'C:/Users/Example/file.txt'; + expect(toPosixPath(mixedPath)).toBe(expectedPosixPath); + }); + + // 测试空字符串 + it('handles empty strings', () => { + const emptyPath = ''; + expect(toPosixPath(emptyPath)).toBe(''); + }); + + // 测试仅包含分隔符的路径 + it('handles path with only separators', () => { + const separatorsPath = '\\\\\\'; + const expectedPosixPath = '///'; + expect(toPosixPath(separatorsPath)).toBe(expectedPosixPath); + }); + + // 测试不包含任何分隔符的路径 + it('handles path without separators', () => { + const noSeparatorPath = 'file.txt'; + expect(toPosixPath(noSeparatorPath)).toBe('file.txt'); + }); + + // 测试以分隔符结尾的路径 + it('handles path ending with a separator', () => { + const endingSeparatorPath = 'C:\\Users\\Example\\'; + const expectedPosixPath = 'C:/Users/Example/'; + expect(toPosixPath(endingSeparatorPath)).toBe(expectedPosixPath); + }); + + // 测试以分隔符开头的路径 + it('handles path starting with a separator', () => { + const startingSeparatorPath = String.raw`\Users\Example`; + const expectedPosixPath = '/Users/Example'; + expect(toPosixPath(startingSeparatorPath)).toBe(expectedPosixPath); + }); + + // 测试包含非法字符的路径 + it('handles path with invalid characters', () => { + const invalidCharsPath = String.raw`C:\Us*?ers\Ex|file.txt`; + const expectedPosixPath = 'C:/Us*?ers/Ex|file.txt'; + expect(toPosixPath(invalidCharsPath)).toBe(expectedPosixPath); + }); +}); diff --git a/internal/node-utils/src/constants.ts b/internal/node-utils/src/constants.ts new file mode 100644 index 0000000..71d8a6c --- /dev/null +++ b/internal/node-utils/src/constants.ts @@ -0,0 +1,6 @@ +enum UNICODE { + FAILURE = '\u2716', // ✖ + SUCCESS = '\u2714', // ✔ +} + +export { UNICODE }; diff --git a/internal/node-utils/src/date.ts b/internal/node-utils/src/date.ts new file mode 100644 index 0000000..d36572d --- /dev/null +++ b/internal/node-utils/src/date.ts @@ -0,0 +1,12 @@ +import dayjs from 'dayjs'; +import timezone from 'dayjs/plugin/timezone'; +import utc from 'dayjs/plugin/utc'; + +dayjs.extend(utc); +dayjs.extend(timezone); + +dayjs.tz.setDefault('Asia/Shanghai'); + +const dateUtil = dayjs; + +export { dateUtil }; diff --git a/internal/node-utils/src/fs.ts b/internal/node-utils/src/fs.ts new file mode 100644 index 0000000..8eec357 --- /dev/null +++ b/internal/node-utils/src/fs.ts @@ -0,0 +1,39 @@ +import { promises as fs } from 'node:fs'; +import { dirname } from 'node:path'; + +export async function outputJSON( + filePath: string, + data: any, + spaces: number = 2, +) { + try { + const dir = dirname(filePath); + await fs.mkdir(dir, { recursive: true }); + const jsonData = JSON.stringify(data, null, spaces); + await fs.writeFile(filePath, jsonData, 'utf8'); + } catch (error) { + console.error('Error writing JSON file:', error); + throw error; + } +} + +export async function ensureFile(filePath: string) { + try { + const dir = dirname(filePath); + await fs.mkdir(dir, { recursive: true }); + await fs.writeFile(filePath, '', { flag: 'a' }); + } catch (error) { + console.error('Error ensuring file:', error); + throw error; + } +} + +export async function readJSON(filePath: string) { + try { + const data = await fs.readFile(filePath, 'utf8'); + return JSON.parse(data); + } catch (error) { + console.error('Error reading JSON file:', error); + throw error; + } +} diff --git a/internal/node-utils/src/git.ts b/internal/node-utils/src/git.ts new file mode 100644 index 0000000..88f159c --- /dev/null +++ b/internal/node-utils/src/git.ts @@ -0,0 +1,34 @@ +import path from 'node:path'; + +import { execa } from 'execa'; + +export * from '@changesets/git'; + +/** + * 获取暂存区文件 + */ +async function getStagedFiles(): Promise { + try { + const { stdout } = await execa('git', [ + '-c', + 'submodule.recurse=false', + 'diff', + '--staged', + '--diff-filter=ACMR', + '--name-only', + '--ignore-submodules', + '-z', + ]); + + let changedList = stdout ? stdout.replace(/\0$/, '').split('\0') : []; + changedList = changedList.map((item) => path.resolve(process.cwd(), item)); + const changedSet = new Set(changedList); + changedSet.delete(''); + return [...changedSet]; + } catch (error) { + console.error('Failed to get staged files:', error); + return []; + } +} + +export { getStagedFiles }; diff --git a/internal/node-utils/src/hash.ts b/internal/node-utils/src/hash.ts new file mode 100644 index 0000000..81f6b05 --- /dev/null +++ b/internal/node-utils/src/hash.ts @@ -0,0 +1,18 @@ +import { createHash } from 'node:crypto'; + +/** + * 生产基于内容的 hash,可自定义长度 + * @param content + * @param hashLSize + */ +function generatorContentHash(content: string, hashLSize?: number) { + const hash = createHash('md5').update(content, 'utf8').digest('hex'); + + if (hashLSize) { + return hash.slice(0, hashLSize); + } + + return hash; +} + +export { generatorContentHash }; diff --git a/internal/node-utils/src/index.ts b/internal/node-utils/src/index.ts new file mode 100644 index 0000000..963cb87 --- /dev/null +++ b/internal/node-utils/src/index.ts @@ -0,0 +1,19 @@ +export * from './constants'; +export * from './date'; +export * from './fs'; +export * from './git'; +export { getStagedFiles, add as gitAdd } from './git'; +export { generatorContentHash } from './hash'; +export * from './monorepo'; +export { toPosixPath } from './path'; +export { prettierFormat } from './prettier'; +export * from './spinner'; +export type { Package } from '@manypkg/get-packages'; +export { default as colors } from 'chalk'; +export { consola } from 'consola'; +export * from 'execa'; + +export { default as fs } from 'node:fs/promises'; + +export { type PackageJson, readPackageJSON } from 'pkg-types'; +export { rimraf } from 'rimraf'; diff --git a/internal/node-utils/src/monorepo.ts b/internal/node-utils/src/monorepo.ts new file mode 100644 index 0000000..b6373e7 --- /dev/null +++ b/internal/node-utils/src/monorepo.ts @@ -0,0 +1,46 @@ +import { dirname } from 'node:path'; + +import { + getPackages as getPackagesFunc, + getPackagesSync as getPackagesSyncFunc, +} from '@manypkg/get-packages'; +import { findUpSync } from 'find-up'; + +/** + * 查找大仓的根目录 + * @param cwd + */ +function findMonorepoRoot(cwd: string = process.cwd()) { + const lockFile = findUpSync('pnpm-lock.yaml', { + cwd, + type: 'file', + }); + return dirname(lockFile || ''); +} + +/** + * 获取大仓的所有包 + */ +function getPackagesSync() { + const root = findMonorepoRoot(); + return getPackagesSyncFunc(root); +} + +/** + * 获取大仓的所有包 + */ +async function getPackages() { + const root = findMonorepoRoot(); + + return await getPackagesFunc(root); +} + +/** + * 获取大仓指定的包 + */ +async function getPackage(pkgName: string) { + const { packages } = await getPackages(); + return packages.find((pkg) => pkg.packageJson.name === pkgName); +} + +export { findMonorepoRoot, getPackage, getPackages, getPackagesSync }; diff --git a/internal/node-utils/src/path.ts b/internal/node-utils/src/path.ts new file mode 100644 index 0000000..e625fd2 --- /dev/null +++ b/internal/node-utils/src/path.ts @@ -0,0 +1,11 @@ +import { posix } from 'node:path'; + +/** + * 将给定的文件路径转换为 POSIX 风格。 + * @param {string} pathname - 原始文件路径。 + */ +function toPosixPath(pathname: string) { + return pathname.split(`\\`).join(posix.sep); +} + +export { toPosixPath }; diff --git a/internal/node-utils/src/prettier.ts b/internal/node-utils/src/prettier.ts new file mode 100644 index 0000000..1e1525d --- /dev/null +++ b/internal/node-utils/src/prettier.ts @@ -0,0 +1,21 @@ +import fs from 'node:fs/promises'; + +import { format, getFileInfo, resolveConfig } from 'prettier'; + +async function prettierFormat(filepath: string) { + const prettierOptions = await resolveConfig(filepath, {}); + + const fileInfo = await getFileInfo(filepath); + + const input = await fs.readFile(filepath, 'utf8'); + const output = await format(input, { + ...prettierOptions, + parser: fileInfo.inferredParser as any, + }); + if (output !== input) { + await fs.writeFile(filepath, output, 'utf8'); + } + return output; +} + +export { prettierFormat }; diff --git a/internal/node-utils/src/spinner.ts b/internal/node-utils/src/spinner.ts new file mode 100644 index 0000000..13ad6a4 --- /dev/null +++ b/internal/node-utils/src/spinner.ts @@ -0,0 +1,26 @@ +import type { Ora } from 'ora'; + +import ora from 'ora'; + +interface SpinnerOptions { + failedText?: string; + successText?: string; + title: string; +} +export async function spinner( + { failedText, successText, title }: SpinnerOptions, + callback: () => Promise, +): Promise { + const loading: Ora = ora(title).start(); + + try { + const result = await callback(); + loading.succeed(successText || 'Success!'); + return result; + } catch (error) { + loading.fail(failedText || 'Failed!'); + throw error; + } finally { + loading.stop(); + } +} diff --git a/internal/node-utils/tsconfig.json b/internal/node-utils/tsconfig.json new file mode 100644 index 0000000..b2ec3b6 --- /dev/null +++ b/internal/node-utils/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/node.json", + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/internal/tailwind-config/build.config.ts b/internal/tailwind-config/build.config.ts new file mode 100644 index 0000000..1f3c3c2 --- /dev/null +++ b/internal/tailwind-config/build.config.ts @@ -0,0 +1,10 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + clean: true, + declaration: true, + entries: ['src/index', './src/postcss.config'], + rollup: { + emitCJS: true, + }, +}); diff --git a/internal/tailwind-config/package.json b/internal/tailwind-config/package.json new file mode 100644 index 0000000..c7044ea --- /dev/null +++ b/internal/tailwind-config/package.json @@ -0,0 +1,66 @@ +{ + "name": "@vben/tailwind-config", + "version": "5.5.6", + "private": true, + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "internal/tailwind-config" + }, + "license": "MIT", + "type": "module", + "scripts": { + "stub": "pnpm unbuild" + }, + "files": [ + "dist" + ], + "main": "./dist/index.mjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "typesVersions": { + "*": { + "*": [ + "./dist/*", + "./*" + ] + } + }, + "exports": { + ".": { + "types": "./src/index.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + }, + "./postcss": { + "types": "./src/postcss.config.ts", + "import": "./dist/postcss.config.mjs", + "require": "./dist/postcss.config.cjs", + "default": "./dist/postcss.config.mjs" + }, + "./*": "./*" + }, + "peerDependencies": { + "tailwindcss": "^3.4.3" + }, + "dependencies": { + "@iconify/json": "catalog:", + "@iconify/tailwind": "catalog:", + "@manypkg/get-packages": "catalog:", + "@tailwindcss/nesting": "catalog:", + "@tailwindcss/typography": "catalog:", + "autoprefixer": "catalog:", + "cssnano": "catalog:", + "postcss": "catalog:", + "postcss-antd-fixes": "catalog:", + "postcss-import": "catalog:", + "postcss-preset-env": "catalog:", + "tailwindcss": "catalog:", + "tailwindcss-animate": "catalog:" + }, + "devDependencies": { + "@types/postcss-import": "catalog:" + } +} diff --git a/internal/tailwind-config/src/index.ts b/internal/tailwind-config/src/index.ts new file mode 100644 index 0000000..93332a3 --- /dev/null +++ b/internal/tailwind-config/src/index.ts @@ -0,0 +1,266 @@ +import type { Config } from 'tailwindcss'; + +import path from 'node:path'; + +import { addDynamicIconSelectors } from '@iconify/tailwind'; +import { getPackagesSync } from '@manypkg/get-packages'; +import typographyPlugin from '@tailwindcss/typography'; +import animate from 'tailwindcss-animate'; + +import { enterAnimationPlugin } from './plugins/entry'; + +// import defaultTheme from 'tailwindcss/defaultTheme'; + +const { packages } = getPackagesSync(process.cwd()); + +const tailwindPackages: string[] = []; + +packages.forEach((pkg) => { + // apps目录下和 @vben-core/tailwind-ui 包需要使用到 tailwindcss ui + // if (fs.existsSync(path.join(pkg.dir, 'tailwind.config.mjs'))) { + tailwindPackages.push(pkg.dir); + // } +}); + +const shadcnUiColors = { + accent: { + DEFAULT: 'hsl(var(--accent))', + foreground: 'hsl(var(--accent-foreground))', + hover: 'hsl(var(--accent-hover))', + lighter: 'has(val(--accent-lighter))', + }, + background: { + deep: 'hsl(var(--background-deep))', + DEFAULT: 'hsl(var(--background))', + }, + border: { + DEFAULT: 'hsl(var(--border))', + }, + card: { + DEFAULT: 'hsl(var(--card))', + foreground: 'hsl(var(--card-foreground))', + }, + destructive: { + ...createColorsPalette('destructive'), + DEFAULT: 'hsl(var(--destructive))', + }, + + foreground: { + DEFAULT: 'hsl(var(--foreground))', + }, + + input: { + background: 'hsl(var(--input-background))', + DEFAULT: 'hsl(var(--input))', + }, + muted: { + DEFAULT: 'hsl(var(--muted))', + foreground: 'hsl(var(--muted-foreground))', + }, + popover: { + DEFAULT: 'hsl(var(--popover))', + foreground: 'hsl(var(--popover-foreground))', + }, + primary: { + ...createColorsPalette('primary'), + DEFAULT: 'hsl(var(--primary))', + }, + + ring: 'hsl(var(--ring))', + secondary: { + DEFAULT: 'hsl(var(--secondary))', + desc: 'hsl(var(--secondary-desc))', + foreground: 'hsl(var(--secondary-foreground))', + }, +}; + +const customColors = { + green: { + ...createColorsPalette('green'), + foreground: 'hsl(var(--success-foreground))', + }, + header: { + DEFAULT: 'hsl(var(--header))', + }, + heavy: { + DEFAULT: 'hsl(var(--heavy))', + foreground: 'hsl(var(--heavy-foreground))', + }, + main: { + DEFAULT: 'hsl(var(--main))', + }, + overlay: { + content: 'hsl(var(--overlay-content))', + DEFAULT: 'hsl(var(--overlay))', + }, + red: { + ...createColorsPalette('red'), + foreground: 'hsl(var(--destructive-foreground))', + }, + sidebar: { + deep: 'hsl(var(--sidebar-deep))', + DEFAULT: 'hsl(var(--sidebar))', + }, + success: { + ...createColorsPalette('success'), + DEFAULT: 'hsl(var(--success))', + }, + warning: { + ...createColorsPalette('warning'), + DEFAULT: 'hsl(var(--warning))', + }, + yellow: { + ...createColorsPalette('yellow'), + foreground: 'hsl(var(--warning-foreground))', + }, +}; + +export default { + content: [ + './index.html', + ...tailwindPackages.map((item) => + path.join(item, 'src/**/*.{vue,js,ts,jsx,tsx,svelte,astro,html}'), + ), + ], + darkMode: 'selector', + plugins: [ + animate, + typographyPlugin, + addDynamicIconSelectors(), + enterAnimationPlugin, + ], + prefix: '', + theme: { + container: { + center: true, + padding: '2rem', + screens: { + '2xl': '1400px', + }, + }, + extend: { + animation: { + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out', + 'collapsible-down': 'collapsible-down 0.2s ease-in-out', + 'collapsible-up': 'collapsible-up 0.2s ease-in-out', + float: 'float 5s linear 0ms infinite', + }, + + animationDuration: { + '2000': '2000ms', + '3000': '3000ms', + }, + borderRadius: { + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)', + xl: 'calc(var(--radius) + 4px)', + }, + boxShadow: { + float: `0 6px 16px 0 rgb(0 0 0 / 8%), + 0 3px 6px -4px rgb(0 0 0 / 12%), + 0 9px 28px 8px rgb(0 0 0 / 5%)`, + }, + colors: { + ...customColors, + ...shadcnUiColors, + }, + fontFamily: { + sans: [ + 'var(--font-family)', + // ...defaultTheme.fontFamily.sans + ], + }, + keyframes: { + 'accordion-down': { + from: { height: '0' }, + to: { height: 'var(--radix-accordion-content-height)' }, + }, + 'accordion-up': { + from: { height: 'var(--radix-accordion-content-height)' }, + to: { height: '0' }, + }, + 'collapsible-down': { + from: { height: '0' }, + to: { height: 'var(--radix-collapsible-content-height)' }, + }, + 'collapsible-up': { + from: { height: 'var(--radix-collapsible-content-height)' }, + to: { height: '0' }, + }, + float: { + '0%': { transform: 'translateY(0)' }, + '50%': { transform: 'translateY(-20px)' }, + '100%': { transform: 'translateY(0)' }, + }, + }, + zIndex: { + '100': '100', + '1000': '1000', + }, + }, + }, + safelist: ['dark'], +} as Config; + +function createColorsPalette(name: string) { + // backgroundLightest: '#EFF6FF', // Tailwind CSS 默认的 `blue-50` + // backgroundLighter: '#DBEAFE', // Tailwind CSS 默认的 `blue-100` + // backgroundLight: '#BFDBFE', // Tailwind CSS 默认的 `blue-200` + // borderLight: '#93C5FD', // Tailwind CSS 默认的 `blue-300` + // border: '#60A5FA', // Tailwind CSS 默认的 `blue-400` + // main: '#3B82F6', // Tailwind CSS 默认的 `blue-500` + // hover: '#2563EB', // Tailwind CSS 默认的 `blue-600` + // active: '#1D4ED8', // Tailwind CSS 默认的 `blue-700` + // backgroundDark: '#1E40AF', // Tailwind CSS 默认的 `blue-800` + // backgroundDarker: '#1E3A8A', // Tailwind CSS 默认的 `blue-900` + // backgroundDarkest: '#172554', // Tailwind CSS 默认的 `blue-950` + + // • backgroundLightest (#EFF6FF): 适用于最浅的背景色,可能用于非常轻微的阴影或卡片的背景。 + // • backgroundLighter (#DBEAFE): 适用于略浅的背景色,通常用于次要背景或略浅的区域。 + // • backgroundLight (#BFDBFE): 适用于浅色背景,可能用于输入框或表单区域的背景。 + // • borderLight (#93C5FD): 适用于浅色边框,可能用于输入框或卡片的边框。 + // • border (#60A5FA): 适用于普通边框,可能用于按钮或卡片的边框。 + // • main (#3B82F6): 适用于主要的主题色,通常用于按钮、链接或主要的强调色。 + // • hover (#2563EB): 适用于鼠标悬停状态下的颜色,例如按钮悬停时的背景色或边框色。 + // • active (#1D4ED8): 适用于激活状态下的颜色,例如按钮按下时的背景色或边框色。 + // • backgroundDark (#1E40AF): 适用于深色背景,可能用于主要按钮或深色卡片背景。 + // • backgroundDarker (#1E3A8A): 适用于更深的背景,通常用于头部导航栏或页脚。 + // • backgroundDarkest (#172554): 适用于最深的背景,可能用于非常深色的区域或极端对比色。 + + return { + 50: `hsl(var(--${name}-50))`, + 100: `hsl(var(--${name}-100))`, + 200: `hsl(var(--${name}-200))`, + 300: `hsl(var(--${name}-300))`, + 400: `hsl(var(--${name}-400))`, + 500: `hsl(var(--${name}-500))`, + 600: `hsl(var(--${name}-600))`, + 700: `hsl(var(--${name}-700))`, + // 800: `hsl(var(--${name}-800))`, + // 900: `hsl(var(--${name}-900))`, + // 950: `hsl(var(--${name}-950))`, + // 激活状态下的颜色,适用于按钮按下时的背景色或边框色。 + active: `hsl(var(--${name}-700))`, + // 浅色背景,适用于输入框或表单区域的背景。 + 'background-light': `hsl(var(--${name}-200))`, + // 适用于略浅的背景色,通常用于次要背景或略浅的区域。 + 'background-lighter': `hsl(var(--${name}-100))`, + // 最浅的背景色,适用于非常轻微的阴影或卡片的背景。 + 'background-lightest': `hsl(var(--${name}-50))`, + // 适用于普通边框,可能用于按钮或卡片的边框。 + border: `hsl(var(--${name}-400))`, + // 浅色边框,适用于输入框或卡片的边框。 + 'border-light': `hsl(var(--${name}-300))`, + foreground: `hsl(var(--${name}-foreground))`, + // 鼠标悬停状态下的颜色,适用于按钮悬停时的背景色或边框色。 + hover: `hsl(var(--${name}-600))`, + // 主色文本 + text: `hsl(var(--${name}-500))`, + // 主色文本激活态 + 'text-active': `hsl(var(--${name}-700))`, + // 主色文本悬浮态 + 'text-hover': `hsl(var(--${name}-600))`, + }; +} diff --git a/internal/tailwind-config/src/module.d.ts b/internal/tailwind-config/src/module.d.ts new file mode 100644 index 0000000..a399653 --- /dev/null +++ b/internal/tailwind-config/src/module.d.ts @@ -0,0 +1,3 @@ +declare module '@tailwindcss/nesting' { + export default any; +} diff --git a/internal/tailwind-config/src/plugins/entry.ts b/internal/tailwind-config/src/plugins/entry.ts new file mode 100644 index 0000000..0d8e8ec --- /dev/null +++ b/internal/tailwind-config/src/plugins/entry.ts @@ -0,0 +1,53 @@ +import plugin from 'tailwindcss/plugin.js'; + +const enterAnimationPlugin = plugin(({ addUtilities }) => { + const maxChild = 5; + const utilities: Record = {}; + for (let i = 1; i <= maxChild; i++) { + const baseDelay = 0.1; + const delay = `${baseDelay * i}s`; + + utilities[`.enter-x:nth-child(${i})`] = { + animation: `enter-x-animation 0.3s ease-in-out ${delay} forwards`, + opacity: '0', + transform: `translateX(50px)`, + }; + + utilities[`.enter-y:nth-child(${i})`] = { + animation: `enter-y-animation 0.3s ease-in-out ${delay} forwards`, + opacity: '0', + transform: `translateY(50px)`, + }; + + utilities[`.-enter-x:nth-child(${i})`] = { + animation: `enter-x-animation 0.3s ease-in-out ${delay} forwards`, + opacity: '0', + transform: `translateX(-50px)`, + }; + + utilities[`.-enter-y:nth-child(${i})`] = { + animation: `enter-y-animation 0.3s ease-in-out ${delay} forwards`, + opacity: '0', + transform: `translateY(-50px)`, + }; + } + + // 添加动画关键帧 + addUtilities(utilities); + addUtilities({ + '@keyframes enter-x-animation': { + to: { + opacity: '1', + transform: 'translateX(0)', + }, + }, + '@keyframes enter-y-animation': { + to: { + opacity: '1', + transform: 'translateY(0)', + }, + }, + }); +}); + +export { enterAnimationPlugin }; diff --git a/internal/tailwind-config/src/postcss.config.ts b/internal/tailwind-config/src/postcss.config.ts new file mode 100644 index 0000000..43b30b3 --- /dev/null +++ b/internal/tailwind-config/src/postcss.config.ts @@ -0,0 +1,15 @@ +import config from '.'; + +export default { + plugins: { + ...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}), + // Specifying the config is not necessary in most cases, but it is included + autoprefixer: {}, + // 修复 element-plus 和 ant-design-vue 的样式和tailwindcss冲突问题 + 'postcss-antd-fixes': { prefixes: ['ant', 'el'] }, + 'postcss-import': {}, + 'postcss-preset-env': {}, + tailwindcss: { config }, + 'tailwindcss/nesting': {}, + }, +}; diff --git a/internal/tailwind-config/tsconfig.json b/internal/tailwind-config/tsconfig.json new file mode 100644 index 0000000..dbd3bcc --- /dev/null +++ b/internal/tailwind-config/tsconfig.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/node.json", + "compilerOptions": { + "moduleResolution": "bundler" + }, + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/internal/tsconfig/base.json b/internal/tsconfig/base.json new file mode 100644 index 0000000..1e45a78 --- /dev/null +++ b/internal/tsconfig/base.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Base", + "compilerOptions": { + "composite": false, + "target": "ESNext", + + "moduleDetection": "force", + "experimentalDecorators": true, + + "baseUrl": ".", + "module": "ESNext", + + "moduleResolution": "node", + "resolveJsonModule": true, + + "strict": true, + "strictNullChecks": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitOverride": true, + "noImplicitThis": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + + "inlineSources": false, + "noEmit": true, + "removeComments": true, + "sourceMap": false, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true, + "preserveWatchOutput": true + }, + "exclude": ["**/node_modules/**", "**/dist/**", "**/.turbo/**"] +} diff --git a/internal/tsconfig/library.json b/internal/tsconfig/library.json new file mode 100644 index 0000000..7a976f0 --- /dev/null +++ b/internal/tsconfig/library.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Web Application", + "extends": "./base.json", + "compilerOptions": { + "jsx": "preserve", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "useDefineForClassFields": true, + "moduleResolution": "bundler", + "declaration": true, + "noEmit": false + } +} diff --git a/internal/tsconfig/node.json b/internal/tsconfig/node.json new file mode 100644 index 0000000..31ce8f1 --- /dev/null +++ b/internal/tsconfig/node.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Node Config", + "extends": "./base.json", + "compilerOptions": { + "composite": false, + "lib": ["ESNext"], + "baseUrl": "./", + "types": ["node"], + "noImplicitAny": true + } +} diff --git a/internal/tsconfig/package.json b/internal/tsconfig/package.json new file mode 100644 index 0000000..dd4f632 --- /dev/null +++ b/internal/tsconfig/package.json @@ -0,0 +1,25 @@ +{ + "name": "@vben/tsconfig", + "version": "5.5.6", + "private": true, + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "internal/tsconfig" + }, + "license": "MIT", + "type": "module", + "files": [ + "base.json", + "library.json", + "node.json", + "web-app.json", + "web.json" + ], + "dependencies": { + "@vben/types": "workspace:*", + "vite": "catalog:" + } +} diff --git a/internal/tsconfig/web-app.json b/internal/tsconfig/web-app.json new file mode 100644 index 0000000..00479cb --- /dev/null +++ b/internal/tsconfig/web-app.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Web Application", + "extends": "./web.json", + "compilerOptions": { + "types": ["vite/client", "@vben/types/global"] + } +} diff --git a/internal/tsconfig/web.json b/internal/tsconfig/web.json new file mode 100644 index 0000000..a4b60ce --- /dev/null +++ b/internal/tsconfig/web.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Web Package", + "extends": "./base.json", + "compilerOptions": { + "jsx": "preserve", + "jsxImportSource": "vue", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "useDefineForClassFields": true, + "moduleResolution": "bundler", + "types": ["vite/client"], + "declaration": false + } +} diff --git a/internal/vite-config/build.config.ts b/internal/vite-config/build.config.ts new file mode 100644 index 0000000..97e572c --- /dev/null +++ b/internal/vite-config/build.config.ts @@ -0,0 +1,7 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + clean: true, + declaration: true, + entries: ['src/index'], +}); diff --git a/internal/vite-config/package.json b/internal/vite-config/package.json new file mode 100644 index 0000000..d7ba6a6 --- /dev/null +++ b/internal/vite-config/package.json @@ -0,0 +1,59 @@ +{ + "name": "@vben/vite-config", + "version": "5.5.6", + "private": true, + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "internal/vite-config" + }, + "license": "MIT", + "type": "module", + "scripts": { + "stub": "pnpm unbuild --stub" + }, + "files": [ + "dist" + ], + "main": "./dist/index.mjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./src/index.ts", + "default": "./dist/index.mjs" + } + }, + "dependencies": { + "@intlify/unplugin-vue-i18n": "catalog:", + "@jspm/generator": "catalog:", + "archiver": "catalog:", + "cheerio": "catalog:", + "get-port": "catalog:", + "html-minifier-terser": "catalog:", + "nitropack": "catalog:", + "resolve.exports": "catalog:", + "vite-plugin-pwa": "catalog:", + "vite-plugin-vue-devtools": "catalog:" + }, + "devDependencies": { + "@pnpm/workspace.read-manifest": "catalog:", + "@types/archiver": "catalog:", + "@types/html-minifier-terser": "catalog:", + "@vben/node-utils": "workspace:*", + "@vitejs/plugin-vue": "catalog:", + "@vitejs/plugin-vue-jsx": "catalog:", + "dayjs": "catalog:", + "dotenv": "catalog:", + "rollup": "catalog:", + "rollup-plugin-visualizer": "catalog:", + "sass": "catalog:", + "vite": "catalog:", + "vite-plugin-compression": "catalog:", + "vite-plugin-dts": "catalog:", + "vite-plugin-html": "catalog:", + "vite-plugin-lazy-import": "catalog:" + } +} diff --git a/internal/vite-config/src/config/application.ts b/internal/vite-config/src/config/application.ts new file mode 100644 index 0000000..2b74613 --- /dev/null +++ b/internal/vite-config/src/config/application.ts @@ -0,0 +1,125 @@ +import type { CSSOptions, UserConfig } from 'vite'; + +import type { DefineApplicationOptions } from '../typing'; + +import path, { relative } from 'node:path'; + +import { findMonorepoRoot } from '@vben/node-utils'; + +import { NodePackageImporter } from 'sass'; +import { defineConfig, loadEnv, mergeConfig } from 'vite'; + +import { defaultImportmapOptions, getDefaultPwaOptions } from '../options'; +import { loadApplicationPlugins } from '../plugins'; +import { loadAndConvertEnv } from '../utils/env'; +import { getCommonConfig } from './common'; + +function defineApplicationConfig(userConfigPromise?: DefineApplicationOptions) { + return defineConfig(async (config) => { + const options = await userConfigPromise?.(config); + const { appTitle, base, port, ...envConfig } = await loadAndConvertEnv(); + const { command, mode } = config; + const { application = {}, vite = {} } = options || {}; + const root = process.cwd(); + const isBuild = command === 'build'; + const env = loadEnv(mode, root); + + const plugins = await loadApplicationPlugins({ + archiver: true, + archiverPluginOptions: {}, + compress: false, + compressTypes: ['brotli', 'gzip'], + devtools: true, + env, + extraAppConfig: true, + html: true, + i18n: true, + importmapOptions: defaultImportmapOptions, + injectAppLoading: true, + injectMetadata: true, + isBuild, + license: true, + mode, + nitroMock: !isBuild, + nitroMockOptions: {}, + print: !isBuild, + printInfoMap: { + 'Vben Admin Docs': 'https://doc.cncore.club/', + }, + pwa: true, + pwaOptions: getDefaultPwaOptions(appTitle), + vxeTableLazyImport: true, + ...envConfig, + ...application, + }); + + const { injectGlobalScss = true } = application; + + const applicationConfig: UserConfig = { + base, + build: { + rollupOptions: { + output: { + assetFileNames: '[ext]/[name]-[hash].[ext]', + chunkFileNames: 'js/[name]-[hash].js', + entryFileNames: 'jse/index-[name]-[hash].js', + }, + }, + target: 'es2015', + }, + css: createCssOptions(injectGlobalScss), + esbuild: { + drop: isBuild + ? [ + // 'console', + 'debugger', + ] + : [], + legalComments: 'none', + }, + plugins, + server: { + host: true, + port, + warmup: { + // 预热文件 + clientFiles: [ + './index.html', + './src/bootstrap.ts', + './src/{views,layouts,router,store,api,adapter}/*', + ], + }, + }, + }; + + const mergedCommonConfig = mergeConfig( + await getCommonConfig(), + applicationConfig, + ); + return mergeConfig(mergedCommonConfig, vite); + }); +} + +function createCssOptions(injectGlobalScss = true): CSSOptions { + const root = findMonorepoRoot(); + return { + preprocessorOptions: injectGlobalScss + ? { + scss: { + additionalData: (content: string, filepath: string) => { + const relativePath = relative(root, filepath); + // apps下的包注入全局样式 + if (relativePath.startsWith(`apps${path.sep}`)) { + return `@use "@vben/styles/global" as *;\n${content}`; + } + return content; + }, + api: 'modern', + importers: [new NodePackageImporter()], + }, + } + : {}, + }; +} + +export { defineApplicationConfig }; diff --git a/internal/vite-config/src/config/common.ts b/internal/vite-config/src/config/common.ts new file mode 100644 index 0000000..653f210 --- /dev/null +++ b/internal/vite-config/src/config/common.ts @@ -0,0 +1,13 @@ +import type { UserConfig } from 'vite'; + +async function getCommonConfig(): Promise { + return { + build: { + chunkSizeWarningLimit: 2000, + reportCompressedSize: false, + sourcemap: false, + }, + }; +} + +export { getCommonConfig }; diff --git a/internal/vite-config/src/config/index.ts b/internal/vite-config/src/config/index.ts new file mode 100644 index 0000000..d04a84a --- /dev/null +++ b/internal/vite-config/src/config/index.ts @@ -0,0 +1,37 @@ +import type { DefineConfig } from '../typing'; + +import { existsSync } from 'node:fs'; +import { join } from 'node:path'; + +import { defineApplicationConfig } from './application'; +import { defineLibraryConfig } from './library'; + +export * from './application'; +export * from './library'; + +function defineConfig( + userConfigPromise?: DefineConfig, + type: 'application' | 'auto' | 'library' = 'auto', +) { + let projectType = type; + + // 根据包是否存在 index.html,自动判断类型 + if (projectType === 'auto') { + const htmlPath = join(process.cwd(), 'index.html'); + projectType = existsSync(htmlPath) ? 'application' : 'library'; + } + + switch (projectType) { + case 'application': { + return defineApplicationConfig(userConfigPromise); + } + case 'library': { + return defineLibraryConfig(userConfigPromise); + } + default: { + throw new Error(`Unsupported project type: ${projectType}`); + } + } +} + +export { defineConfig }; diff --git a/internal/vite-config/src/config/library.ts b/internal/vite-config/src/config/library.ts new file mode 100644 index 0000000..08b8135 --- /dev/null +++ b/internal/vite-config/src/config/library.ts @@ -0,0 +1,59 @@ +import type { ConfigEnv, UserConfig } from 'vite'; + +import type { DefineLibraryOptions } from '../typing'; + +import { readPackageJSON } from '@vben/node-utils'; + +import { defineConfig, mergeConfig } from 'vite'; + +import { loadLibraryPlugins } from '../plugins'; +import { getCommonConfig } from './common'; + +function defineLibraryConfig(userConfigPromise?: DefineLibraryOptions) { + return defineConfig(async (config: ConfigEnv) => { + const options = await userConfigPromise?.(config); + const { command, mode } = config; + const { library = {}, vite = {} } = options || {}; + const root = process.cwd(); + const isBuild = command === 'build'; + + const plugins = await loadLibraryPlugins({ + dts: false, + injectMetadata: true, + isBuild, + mode, + ...library, + }); + + const { dependencies = {}, peerDependencies = {} } = + await readPackageJSON(root); + + const externalPackages = [ + ...Object.keys(dependencies), + ...Object.keys(peerDependencies), + ]; + + const packageConfig: UserConfig = { + build: { + lib: { + entry: 'src/index.ts', + fileName: () => 'index.mjs', + formats: ['es'], + }, + rollupOptions: { + external: (id) => { + return externalPackages.some( + (pkg) => id === pkg || id.startsWith(`${pkg}/`), + ); + }, + }, + }, + plugins, + }; + const commonConfig = await getCommonConfig(); + const mergedConmonConfig = mergeConfig(commonConfig, packageConfig); + return mergeConfig(mergedConmonConfig, vite); + }); +} + +export { defineLibraryConfig }; diff --git a/internal/vite-config/src/index.ts b/internal/vite-config/src/index.ts new file mode 100644 index 0000000..352a323 --- /dev/null +++ b/internal/vite-config/src/index.ts @@ -0,0 +1,4 @@ +export * from './config'; +export * from './options'; +export * from './plugins'; +export { loadAndConvertEnv } from './utils/env'; diff --git a/internal/vite-config/src/options.ts b/internal/vite-config/src/options.ts new file mode 100644 index 0000000..f1e2401 --- /dev/null +++ b/internal/vite-config/src/options.ts @@ -0,0 +1,45 @@ +import type { Options as PwaPluginOptions } from 'vite-plugin-pwa'; + +import type { ImportmapPluginOptions } from './typing'; + +const isDevelopment = process.env.NODE_ENV === 'development'; + +const getDefaultPwaOptions = (name: string): Partial => ({ + manifest: { + description: + 'Vben Admin is a modern admin dashboard template based on Vue 3. ', + icons: [ + { + sizes: '192x192', + src: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/pwa-icon-192.png', + type: 'image/png', + }, + { + sizes: '512x512', + src: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/pwa-icon-512.png', + type: 'image/png', + }, + ], + name: `${name}${isDevelopment ? ' dev' : ''}`, + short_name: `${name}${isDevelopment ? ' dev' : ''}`, + }, +}); + +/** + * importmap CDN 暂时不开启,因为有些包不支持,且网络不稳定 + */ +const defaultImportmapOptions: ImportmapPluginOptions = { + // 通过 Importmap CDN 方式引入, + // 目前只有esm.sh源兼容性好一点,jspm.io对于 esm 入口要求高 + defaultProvider: 'esm.sh', + importmap: [ + { name: 'vue' }, + { name: 'pinia' }, + { name: 'vue-router' }, + // { name: 'vue-i18n' }, + { name: 'dayjs' }, + { name: 'vue-demi' }, + ], +}; + +export { defaultImportmapOptions, getDefaultPwaOptions }; diff --git a/internal/vite-config/src/plugins/archiver.ts b/internal/vite-config/src/plugins/archiver.ts new file mode 100644 index 0000000..8eec8a0 --- /dev/null +++ b/internal/vite-config/src/plugins/archiver.ts @@ -0,0 +1,75 @@ +import type { PluginOption } from 'vite'; + +import type { ArchiverPluginOptions } from '../typing'; + +import fs from 'node:fs'; +import fsp from 'node:fs/promises'; +import { join } from 'node:path'; + +import archiver from 'archiver'; + +export const viteArchiverPlugin = ( + options: ArchiverPluginOptions = {}, +): PluginOption => { + return { + apply: 'build', + closeBundle: { + handler() { + const { name = 'dist', outputDir = '.' } = options; + + setTimeout(async () => { + const folderToZip = 'dist'; + + const zipOutputDir = join(process.cwd(), outputDir); + const zipOutputPath = join(zipOutputDir, `${name}.zip`); + try { + await fsp.mkdir(zipOutputDir, { recursive: true }); + } catch { + // ignore + } + + try { + await zipFolder(folderToZip, zipOutputPath); + console.log(`Folder has been zipped to: ${zipOutputPath}`); + } catch (error) { + console.error('Error zipping folder:', error); + } + }, 0); + }, + order: 'post', + }, + enforce: 'post', + name: 'vite:archiver', + }; +}; + +async function zipFolder( + folderPath: string, + outputPath: string, +): Promise { + return new Promise((resolve, reject) => { + const output = fs.createWriteStream(outputPath); + const archive = archiver('zip', { + zlib: { level: 9 }, // 设置压缩级别为 9 以实现最高压缩率 + }); + + output.on('close', () => { + console.log( + `ZIP file created: ${outputPath} (${archive.pointer()} total bytes)`, + ); + resolve(); + }); + + archive.on('error', (err) => { + reject(err); + }); + + archive.pipe(output); + + // 使用 directory 方法以流的方式压缩文件夹,减少内存消耗 + archive.directory(folderPath, false); + + // 流式处理完成 + archive.finalize(); + }); +} diff --git a/internal/vite-config/src/plugins/extra-app-config.ts b/internal/vite-config/src/plugins/extra-app-config.ts new file mode 100644 index 0000000..813819b --- /dev/null +++ b/internal/vite-config/src/plugins/extra-app-config.ts @@ -0,0 +1,92 @@ +import type { PluginOption } from 'vite'; + +import { + colors, + generatorContentHash, + readPackageJSON, +} from '@vben/node-utils'; + +import { loadEnv } from '../utils/env'; + +interface PluginOptions { + isBuild: boolean; + root: string; +} + +const GLOBAL_CONFIG_FILE_NAME = '_app.config.js'; +const VBEN_ADMIN_PRO_APP_CONF = '_VBEN_ADMIN_PRO_APP_CONF_'; + +/** + * 用于将配置文件抽离出来并注入到项目中 + * @returns + */ + +async function viteExtraAppConfigPlugin({ + isBuild, + root, +}: PluginOptions): Promise { + let publicPath: string; + let source: string; + + if (!isBuild) { + return; + } + + const { version = '' } = await readPackageJSON(root); + + return { + async configResolved(config) { + publicPath = ensureTrailingSlash(config.base); + source = await getConfigSource(); + }, + async generateBundle() { + try { + this.emitFile({ + fileName: GLOBAL_CONFIG_FILE_NAME, + source, + type: 'asset', + }); + + console.log(colors.cyan(`✨configuration file is build successfully!`)); + } catch (error) { + console.log( + colors.red( + `configuration file configuration file failed to package:\n${error}`, + ), + ); + } + }, + name: 'vite:extra-app-config', + async transformIndexHtml(html) { + const hash = `v=${version}-${generatorContentHash(source, 8)}`; + + const appConfigSrc = `${publicPath}${GLOBAL_CONFIG_FILE_NAME}?${hash}`; + + return { + html, + tags: [{ attrs: { src: appConfigSrc }, tag: 'script' }], + }; + }, + }; +} + +async function getConfigSource() { + const config = await loadEnv(); + const windowVariable = `window.${VBEN_ADMIN_PRO_APP_CONF}`; + // 确保变量不会被修改 + let source = `${windowVariable}=${JSON.stringify(config)};`; + source += ` + Object.freeze(${windowVariable}); + Object.defineProperty(window, "${VBEN_ADMIN_PRO_APP_CONF}", { + configurable: false, + writable: false, + }); + `.replaceAll(/\s/g, ''); + return source; +} + +function ensureTrailingSlash(path: string) { + return path.endsWith('/') ? path : `${path}/`; +} + +export { viteExtraAppConfigPlugin }; diff --git a/internal/vite-config/src/plugins/importmap.ts b/internal/vite-config/src/plugins/importmap.ts new file mode 100644 index 0000000..0ccda99 --- /dev/null +++ b/internal/vite-config/src/plugins/importmap.ts @@ -0,0 +1,245 @@ +/** + * 参考 https://github.com/jspm/vite-plugin-jspm,调整为需要的功能 + */ +import type { GeneratorOptions } from '@jspm/generator'; +import type { Plugin } from 'vite'; + +import { Generator } from '@jspm/generator'; +import { load } from 'cheerio'; +import { minify } from 'html-minifier-terser'; + +const DEFAULT_PROVIDER = 'jspm.io'; + +type pluginOptions = GeneratorOptions & { + debug?: boolean; + defaultProvider?: 'esm.sh' | 'jsdelivr' | 'jspm.io'; + importmap?: Array<{ name: string; range?: string }>; +}; + +// async function getLatestVersionOfShims() { +// const result = await fetch('https://ga.jspm.io/npm:es-module-shims'); +// const version = result.text(); +// return version; +// } + +async function getShimsUrl(provide: string) { + // const version = await getLatestVersionOfShims(); + const version = '1.10.0'; + + const shimsSubpath = `dist/es-module-shims.js`; + const providerShimsMap: Record = { + 'esm.sh': `https://esm.sh/es-module-shims@${version}/${shimsSubpath}`, + // unpkg: `https://unpkg.com/es-module-shims@${version}/${shimsSubpath}`, + jsdelivr: `https://cdn.jsdelivr.net/npm/es-module-shims@${version}/${shimsSubpath}`, + + // 下面两个CDN不稳定,暂时不用 + 'jspm.io': `https://ga.jspm.io/npm:es-module-shims@${version}/${shimsSubpath}`, + }; + + return providerShimsMap[provide] || providerShimsMap[DEFAULT_PROVIDER]; +} + +let generator: Generator; + +async function viteImportMapPlugin( + pluginOptions?: pluginOptions, +): Promise { + const { importmap } = pluginOptions || {}; + + let isSSR = false; + let isBuild = false; + let installed = false; + let installError: Error | null = null; + + const options: pluginOptions = Object.assign( + {}, + { + debug: false, + defaultProvider: 'jspm.io', + env: ['production', 'browser', 'module'], + importmap: [], + }, + pluginOptions, + ); + + generator = new Generator({ + ...options, + baseUrl: process.cwd(), + }); + + if (options?.debug) { + (async () => { + for await (const { message, type } of generator.logStream()) { + console.log(`${type}: ${message}`); + } + })(); + } + + const imports = options.inputMap?.imports ?? {}; + const scopes = options.inputMap?.scopes ?? {}; + const firstLayerKeys = Object.keys(scopes); + const inputMapScopes: string[] = []; + firstLayerKeys.forEach((key) => { + inputMapScopes.push(...Object.keys(scopes[key] || {})); + }); + const inputMapImports = Object.keys(imports); + + const allDepNames: string[] = [ + ...(importmap?.map((item) => item.name) || []), + ...inputMapImports, + ...inputMapScopes, + ]; + const depNames = new Set(allDepNames); + + const installDeps = importmap?.map((item) => ({ + range: item.range, + target: item.name, + })); + + return [ + { + async config(_, { command, isSsrBuild }) { + isBuild = command === 'build'; + isSSR = !!isSsrBuild; + }, + enforce: 'pre', + name: 'importmap:external', + resolveId(id) { + if (isSSR || !isBuild) { + return null; + } + + if (!depNames.has(id)) { + return null; + } + return { external: true, id }; + }, + }, + { + enforce: 'post', + name: 'importmap:install', + async resolveId() { + if (isSSR || !isBuild || installed) { + return null; + } + try { + installed = true; + await Promise.allSettled( + (installDeps || []).map((dep) => generator.install(dep)), + ); + } catch (error: any) { + installError = error; + installed = false; + } + return null; + }, + }, + { + buildEnd() { + // 未生成importmap时,抛出错误,防止被turbo缓存 + if (!installed && !isSSR) { + installError && console.error(installError); + throw new Error('Importmap installation failed.'); + } + }, + enforce: 'post', + name: 'importmap:html', + transformIndexHtml: { + async handler(html) { + if (isSSR || !isBuild) { + return html; + } + + const importmapJson = generator.getMap(); + + if (!importmapJson) { + return html; + } + + const esModuleShimsSrc = await getShimsUrl( + options.defaultProvider || DEFAULT_PROVIDER, + ); + + const resultHtml = await injectShimsToHtml( + html, + esModuleShimsSrc || '', + ); + html = await minify(resultHtml || html, { + collapseWhitespace: true, + minifyCSS: true, + minifyJS: true, + removeComments: false, + }); + + return { + html, + tags: [ + { + attrs: { + type: 'importmap', + }, + injectTo: 'head-prepend', + tag: 'script', + children: `${JSON.stringify(importmapJson)}`, + }, + ], + }; + }, + order: 'post', + }, + }, + ]; +} + +async function injectShimsToHtml(html: string, esModuleShimUrl: string) { + const $ = load(html); + + const $script = $(`script[type='module']`); + + if (!$script) { + return; + } + + const entry = $script.attr('src'); + + $script.removeAttr('type'); + $script.removeAttr('crossorigin'); + $script.removeAttr('src'); + $script.html(` +if (!HTMLScriptElement.supports || !HTMLScriptElement.supports('importmap')) { + self.importShim = function () { + const promise = new Promise((resolve, reject) => { + document.head.appendChild( + Object.assign(document.createElement('script'), { + src: '${esModuleShimUrl}', + crossorigin: 'anonymous', + async: true, + onload() { + if (!importShim.$proxy) { + resolve(importShim); + } else { + reject(new Error('No globalThis.importShim found:' + esModuleShimUrl)); + } + }, + onerror(error) { + reject(error); + }, + }), + ); + }); + importShim.$proxy = true; + return promise.then((importShim) => importShim(...arguments)); + }; +} + +var modules = ['${entry}']; +typeof importShim === 'function' + ? modules.forEach((moduleName) => importShim(moduleName)) + : modules.forEach((moduleName) => import(moduleName)); + `); + $('body').after($script); + $('head').remove(`script[type='module']`); + return $.html(); +} + +export { viteImportMapPlugin }; diff --git a/internal/vite-config/src/plugins/index.ts b/internal/vite-config/src/plugins/index.ts new file mode 100644 index 0000000..da08db4 --- /dev/null +++ b/internal/vite-config/src/plugins/index.ts @@ -0,0 +1,247 @@ +import type { PluginOption } from 'vite'; + +import type { + ApplicationPluginOptions, + CommonPluginOptions, + ConditionPlugin, + LibraryPluginOptions, +} from '../typing'; + +import viteVueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'; +import viteVue from '@vitejs/plugin-vue'; +import viteVueJsx from '@vitejs/plugin-vue-jsx'; +import { visualizer as viteVisualizerPlugin } from 'rollup-plugin-visualizer'; +import viteCompressPlugin from 'vite-plugin-compression'; +import viteDtsPlugin from 'vite-plugin-dts'; +import { createHtmlPlugin as viteHtmlPlugin } from 'vite-plugin-html'; +import { VitePWA } from 'vite-plugin-pwa'; +import viteVueDevTools from 'vite-plugin-vue-devtools'; + +import { viteArchiverPlugin } from './archiver'; +import { viteExtraAppConfigPlugin } from './extra-app-config'; +import { viteImportMapPlugin } from './importmap'; +import { viteInjectAppLoadingPlugin } from './inject-app-loading'; +import { viteMetadataPlugin } from './inject-metadata'; +import { viteLicensePlugin } from './license'; +import { viteNitroMockPlugin } from './nitro-mock'; +import { vitePrintPlugin } from './print'; +import { viteVxeTableImportsPlugin } from './vxe-table'; + +/** + * 获取条件成立的 vite 插件 + * @param conditionPlugins + */ +async function loadConditionPlugins(conditionPlugins: ConditionPlugin[]) { + const plugins: PluginOption[] = []; + for (const conditionPlugin of conditionPlugins) { + if (conditionPlugin.condition) { + const realPlugins = await conditionPlugin.plugins(); + plugins.push(...realPlugins); + } + } + return plugins.flat(); +} + +/** + * 根据条件获取通用的vite插件 + */ +async function loadCommonPlugins( + options: CommonPluginOptions, +): Promise { + const { devtools, injectMetadata, isBuild, visualizer } = options; + return [ + { + condition: true, + plugins: () => [ + viteVue({ + script: { + defineModel: true, + // propsDestructure: true, + }, + }), + viteVueJsx(), + ], + }, + + { + condition: !isBuild && devtools, + plugins: () => [viteVueDevTools()], + }, + { + condition: injectMetadata, + plugins: async () => [await viteMetadataPlugin()], + }, + { + condition: isBuild && !!visualizer, + plugins: () => [viteVisualizerPlugin({ + filename: './node_modules/.cache/visualizer/stats.html', + gzipSize: true, + open: true, + })], + }, + ]; +} + +/** + * 根据条件获取应用类型的vite插件 + */ +async function loadApplicationPlugins( + options: ApplicationPluginOptions, +): Promise { + // 单独取,否则commonOptions拿不到 + const isBuild = options.isBuild; + const env = options.env; + + const { + archiver, + archiverPluginOptions, + compress, + compressTypes, + extraAppConfig, + html, + i18n, + importmap, + importmapOptions, + injectAppLoading, + license, + nitroMock, + nitroMockOptions, + print, + printInfoMap, + pwa, + pwaOptions, + vxeTableLazyImport, + ...commonOptions + } = options; + + const commonPlugins = await loadCommonPlugins(commonOptions); + + return await loadConditionPlugins([ + ...commonPlugins, + { + condition: i18n, + plugins: async () => { + return [ + viteVueI18nPlugin({ + compositionOnly: true, + fullInstall: true, + runtimeOnly: true, + }), + ]; + }, + }, + { + condition: print, + plugins: async () => { + return [await vitePrintPlugin({ infoMap: printInfoMap })]; + }, + }, + { + condition: vxeTableLazyImport, + plugins: async () => { + return [await viteVxeTableImportsPlugin()]; + }, + }, + { + condition: nitroMock, + plugins: async () => { + return [await viteNitroMockPlugin(nitroMockOptions)]; + }, + }, + + { + condition: injectAppLoading, + plugins: async () => [await viteInjectAppLoadingPlugin(!!isBuild, env)], + }, + { + condition: license, + plugins: async () => [await viteLicensePlugin()], + }, + { + condition: pwa, + plugins: () => + VitePWA({ + injectRegister: false, + workbox: { + globPatterns: [], + }, + ...pwaOptions, + manifest: { + display: 'standalone', + start_url: '/', + theme_color: '#ffffff', + ...pwaOptions?.manifest, + }, + }), + }, + { + condition: isBuild && !!compress, + plugins: () => { + const compressPlugins: PluginOption[] = []; + if (compressTypes?.includes('brotli')) { + compressPlugins.push( + viteCompressPlugin({ deleteOriginFile: false, ext: '.br' }), + ); + } + if (compressTypes?.includes('gzip')) { + compressPlugins.push( + viteCompressPlugin({ deleteOriginFile: false, ext: '.gz' }), + ); + } + return compressPlugins; + }, + }, + { + condition: !!html, + plugins: () => [viteHtmlPlugin({ minify: true })], + }, + { + condition: isBuild && importmap, + plugins: () => { + return [viteImportMapPlugin(importmapOptions)]; + }, + }, + { + condition: isBuild && extraAppConfig, + plugins: async () => [ + await viteExtraAppConfigPlugin({ isBuild: true, root: process.cwd() }), + ], + }, + { + condition: archiver, + plugins: async () => { + return [await viteArchiverPlugin(archiverPluginOptions)]; + }, + }, + ]); +} + +/** + * 根据条件获取库类型的vite插件 + */ +async function loadLibraryPlugins( + options: LibraryPluginOptions, +): Promise { + // 单独取,否则commonOptions拿不到 + const isBuild = options.isBuild; + const { dts, ...commonOptions } = options; + const commonPlugins = await loadCommonPlugins(commonOptions); + return await loadConditionPlugins([ + ...commonPlugins, + { + condition: isBuild && !!dts, + plugins: () => [viteDtsPlugin({ logLevel: 'error' })], + }, + ]); +} + +export { + loadApplicationPlugins, + loadLibraryPlugins, + viteArchiverPlugin, + viteCompressPlugin, + viteDtsPlugin, + viteHtmlPlugin, + viteVisualizerPlugin, + viteVxeTableImportsPlugin, +}; diff --git a/internal/vite-config/src/plugins/inject-app-loading/README.md b/internal/vite-config/src/plugins/inject-app-loading/README.md new file mode 100644 index 0000000..8d2358f --- /dev/null +++ b/internal/vite-config/src/plugins/inject-app-loading/README.md @@ -0,0 +1,3 @@ +# inject-app-loading + +用于在应用加载时显示加载动画的插件,可自行选择加载动画的样式。 diff --git a/internal/vite-config/src/plugins/inject-app-loading/default-loading-antd.html b/internal/vite-config/src/plugins/inject-app-loading/default-loading-antd.html new file mode 100644 index 0000000..20a21fb --- /dev/null +++ b/internal/vite-config/src/plugins/inject-app-loading/default-loading-antd.html @@ -0,0 +1,107 @@ + +
+ +
<%= VITE_APP_TITLE %>
+
diff --git a/internal/vite-config/src/plugins/inject-app-loading/default-loading.html b/internal/vite-config/src/plugins/inject-app-loading/default-loading.html new file mode 100644 index 0000000..2895705 --- /dev/null +++ b/internal/vite-config/src/plugins/inject-app-loading/default-loading.html @@ -0,0 +1,113 @@ + +
+
+
<%= VITE_APP_TITLE %>
+
diff --git a/internal/vite-config/src/plugins/inject-app-loading/index.ts b/internal/vite-config/src/plugins/inject-app-loading/index.ts new file mode 100644 index 0000000..c6a7983 --- /dev/null +++ b/internal/vite-config/src/plugins/inject-app-loading/index.ts @@ -0,0 +1,66 @@ +import type { PluginOption } from 'vite'; + +import fs from 'node:fs'; +import fsp from 'node:fs/promises'; +import { join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { readPackageJSON } from '@vben/node-utils'; + +/** + * 用于生成将loading样式注入到项目中 + * 为多app提供loading样式,无需在每个 app -> index.html单独引入 + */ +async function viteInjectAppLoadingPlugin( + isBuild: boolean, + env: Record = {}, + loadingTemplate = 'loading.html', +): Promise { + const loadingHtml = await getLoadingRawByHtmlTemplate(loadingTemplate); + const { version } = await readPackageJSON(process.cwd()); + const envRaw = isBuild ? 'prod' : 'dev'; + const cacheName = `'${env.VITE_APP_NAMESPACE}-${version}-${envRaw}-preferences-theme'`; + + // 获取缓存的主题 + // 保证黑暗主题下,刷新页面时,loading也是黑暗主题 + const injectScript = ` + +`; + + if (!loadingHtml) { + return; + } + + return { + enforce: 'pre', + name: 'vite:inject-app-loading', + transformIndexHtml: { + handler(html) { + const re = //; + html = html.replace(re, `${injectScript}${loadingHtml}`); + return html; + }, + order: 'pre', + }, + }; +} + +/** + * 用于获取loading的html模板 + */ +async function getLoadingRawByHtmlTemplate(loadingTemplate: string) { + // 支持在app内自定义loading模板,模版参考default-loading.html即可 + let appLoadingPath = join(process.cwd(), loadingTemplate); + + if (!fs.existsSync(appLoadingPath)) { + const __dirname = fileURLToPath(new URL('.', import.meta.url)); + appLoadingPath = join(__dirname, './default-loading.html'); + } + + return await fsp.readFile(appLoadingPath, 'utf8'); +} + +export { viteInjectAppLoadingPlugin }; diff --git a/internal/vite-config/src/plugins/inject-metadata.ts b/internal/vite-config/src/plugins/inject-metadata.ts new file mode 100644 index 0000000..41c4db4 --- /dev/null +++ b/internal/vite-config/src/plugins/inject-metadata.ts @@ -0,0 +1,111 @@ +import type { PluginOption } from 'vite'; + +import { + dateUtil, + findMonorepoRoot, + getPackages, + readPackageJSON, +} from '@vben/node-utils'; + +import { readWorkspaceManifest } from '@pnpm/workspace.read-manifest'; + +function resolvePackageVersion( + pkgsMeta: Record, + name: string, + value: string, + catalog: Record, +) { + if (value.includes('catalog:')) { + return catalog[name]; + } + + if (value.includes('workspace')) { + return pkgsMeta[name]; + } + + return value; +} + +async function resolveMonorepoDependencies() { + const { packages } = await getPackages(); + const manifest = await readWorkspaceManifest(findMonorepoRoot()); + const catalog = manifest?.catalog || {}; + + const resultDevDependencies: Record = {}; + const resultDependencies: Record = {}; + const pkgsMeta: Record = {}; + + for (const { packageJson } of packages) { + pkgsMeta[packageJson.name] = packageJson.version; + } + + for (const { packageJson } of packages) { + const { dependencies = {}, devDependencies = {} } = packageJson; + for (const [key, value] of Object.entries(dependencies)) { + resultDependencies[key] = resolvePackageVersion( + pkgsMeta, + key, + value, + catalog, + ); + } + for (const [key, value] of Object.entries(devDependencies)) { + resultDevDependencies[key] = resolvePackageVersion( + pkgsMeta, + key, + value, + catalog, + ); + } + } + return { + dependencies: resultDependencies, + devDependencies: resultDevDependencies, + }; +} + +/** + * 用于注入项目信息 + */ +async function viteMetadataPlugin( + root = process.cwd(), +): Promise { + const { author, description, homepage, license, version } = + await readPackageJSON(root); + + const buildTime = dateUtil().format('YYYY-MM-DD HH:mm:ss'); + + return { + async config() { + const { dependencies, devDependencies } = + await resolveMonorepoDependencies(); + + const isAuthorObject = typeof author === 'object'; + const authorName = isAuthorObject ? author.name : author; + const authorEmail = isAuthorObject ? author.email : null; + const authorUrl = isAuthorObject ? author.url : null; + + return { + define: { + __VBEN_ADMIN_METADATA__: JSON.stringify({ + authorEmail, + authorName, + authorUrl, + buildTime, + dependencies, + description, + devDependencies, + homepage, + license, + version, + }), + 'import.meta.env.VITE_APP_VERSION': JSON.stringify(version), + }, + }; + }, + enforce: 'post', + name: 'vite:inject-metadata', + }; +} + +export { viteMetadataPlugin }; diff --git a/internal/vite-config/src/plugins/license.ts b/internal/vite-config/src/plugins/license.ts new file mode 100644 index 0000000..81fc4ff --- /dev/null +++ b/internal/vite-config/src/plugins/license.ts @@ -0,0 +1,63 @@ +import type { + NormalizedOutputOptions, + OutputBundle, + OutputChunk, +} from 'rollup'; +import type { PluginOption } from 'vite'; + +import { EOL } from 'node:os'; + +import { dateUtil, readPackageJSON } from '@vben/node-utils'; + +/** + * 用于注入版权信息 + * @returns + */ + +async function viteLicensePlugin( + root = process.cwd(), +): Promise { + const { + description = '', + homepage = '', + version = '', + } = await readPackageJSON(root); + + return { + apply: 'build', + enforce: 'post', + generateBundle: { + handler: (_options: NormalizedOutputOptions, bundle: OutputBundle) => { + const date = dateUtil().format('YYYY-MM-DD '); + const copyrightText = `/*! + * Vben Admin + * Version: ${version} + * Author: vben + * Copyright (C) 2024 Vben + * License: MIT License + * Description: ${description} + * Date Created: ${date} + * Homepage: ${homepage} + * Contact: ann.vben@gmail.com +*/ + `.trim(); + + for (const [, fileContent] of Object.entries(bundle)) { + if (fileContent.type === 'chunk' && fileContent.isEntry) { + const chunkContent = fileContent as OutputChunk; + // 插入版权信息 + const content = chunkContent.code; + const updatedContent = `${copyrightText}${EOL}${content}`; + + // 更新bundle + (fileContent as OutputChunk).code = updatedContent; + } + } + }, + order: 'post', + }, + name: 'vite:license', + }; +} + +export { viteLicensePlugin }; diff --git a/internal/vite-config/src/plugins/nitro-mock.ts b/internal/vite-config/src/plugins/nitro-mock.ts new file mode 100644 index 0000000..60d7327 --- /dev/null +++ b/internal/vite-config/src/plugins/nitro-mock.ts @@ -0,0 +1,98 @@ +import type { PluginOption } from 'vite'; + +import type { NitroMockPluginOptions } from '../typing'; + +import { colors, consola, getPackage } from '@vben/node-utils'; + +import getPort from 'get-port'; +import { build, createDevServer, createNitro, prepare } from 'nitropack'; + +const hmrKeyRe = /^runtimeConfig\.|routeRules\./; + +export const viteNitroMockPlugin = ({ + mockServerPackage = '@vben/backend-mock', + port = 5320, + verbose = true, +}: NitroMockPluginOptions = {}): PluginOption => { + return { + async configureServer(server) { + const availablePort = await getPort({ port }); + if (availablePort !== port) { + return; + } + + const pkg = await getPackage(mockServerPackage); + if (!pkg) { + consola.log( + `Package ${mockServerPackage} not found. Skip mock server.`, + ); + return; + } + + runNitroServer(pkg.dir, port, verbose); + + const _printUrls = server.printUrls; + server.printUrls = () => { + _printUrls(); + + consola.log( + ` ${colors.green('➜')} ${colors.bold('Nitro Mock Server')}: ${colors.cyan(`http://localhost:${port}/api`)}`, + ); + }; + }, + enforce: 'pre', + name: 'vite:mock-server', + }; +}; + +async function runNitroServer(rootDir: string, port: number, verbose: boolean) { + let nitro: any; + const reload = async () => { + if (nitro) { + consola.info('Restarting dev server...'); + if ('unwatch' in nitro.options._c12) { + await nitro.options._c12.unwatch(); + } + await nitro.close(); + } + nitro = await createNitro( + { + dev: true, + preset: 'nitro-dev', + rootDir, + }, + { + c12: { + async onUpdate({ getDiff, newConfig }) { + const diff = getDiff(); + if (diff.length === 0) { + return; + } + verbose && + consola.info( + `Nitro config updated:\n${diff + .map((entry) => ` ${entry.toString()}`) + .join('\n')}`, + ); + await (diff.every((e) => hmrKeyRe.test(e.key)) + ? nitro.updateConfig(newConfig.config) + : reload()); + }, + }, + watch: true, + }, + ); + nitro.hooks.hookOnce('restart', reload); + + const server = createDevServer(nitro); + await server.listen(port, { showURL: false }); + await prepare(nitro); + await build(nitro); + + if (verbose) { + console.log(''); + consola.success(colors.bold(colors.green('Nitro Mock Server started.'))); + } + }; + return await reload(); +} diff --git a/internal/vite-config/src/plugins/print.ts b/internal/vite-config/src/plugins/print.ts new file mode 100644 index 0000000..0146b8a --- /dev/null +++ b/internal/vite-config/src/plugins/print.ts @@ -0,0 +1,28 @@ +import type { PluginOption } from 'vite'; + +import type { PrintPluginOptions } from '../typing'; + +import { colors } from '@vben/node-utils'; + +export const vitePrintPlugin = ( + options: PrintPluginOptions = {}, +): PluginOption => { + const { infoMap = {} } = options; + + return { + configureServer(server) { + const _printUrls = server.printUrls; + server.printUrls = () => { + _printUrls(); + + for (const [key, value] of Object.entries(infoMap)) { + console.log( + ` ${colors.green('➜')} ${colors.bold(key)}: ${colors.cyan(value)}`, + ); + } + }; + }, + enforce: 'pre', + name: 'vite:print-info', + }; +}; diff --git a/internal/vite-config/src/plugins/vxe-table.ts b/internal/vite-config/src/plugins/vxe-table.ts new file mode 100644 index 0000000..3c107a7 --- /dev/null +++ b/internal/vite-config/src/plugins/vxe-table.ts @@ -0,0 +1,20 @@ +import type { PluginOption } from 'vite'; + +import { lazyImport, VxeResolver } from 'vite-plugin-lazy-import'; + +async function viteVxeTableImportsPlugin(): Promise { + return [ + lazyImport({ + resolvers: [ + VxeResolver({ + libraryName: 'vxe-table', + }), + VxeResolver({ + libraryName: 'vxe-pc-ui', + }), + ], + }), + ]; +} + +export { viteVxeTableImportsPlugin }; diff --git a/internal/vite-config/src/typing.ts b/internal/vite-config/src/typing.ts new file mode 100644 index 0000000..f730bdb --- /dev/null +++ b/internal/vite-config/src/typing.ts @@ -0,0 +1,343 @@ +import type { PluginVisualizerOptions } from 'rollup-plugin-visualizer'; +import type { ConfigEnv, PluginOption, UserConfig } from 'vite'; +import type { PluginOptions } from 'vite-plugin-dts'; +import type { Options as PwaPluginOptions } from 'vite-plugin-pwa'; + +/** + * ImportMap 配置接口 + * @description 用于配置模块导入映射,支持自定义导入路径和范围 + * @example + * ```typescript + * { + * imports: { + * 'vue': 'https://unpkg.com/vue@3.2.47/dist/vue.esm-browser.js' + * }, + * scopes: { + * 'https://site.com/': { + * 'vue': 'https://unpkg.com/vue@3.2.47/dist/vue.esm-browser.js' + * } + * } + * } + * ``` + */ +interface IImportMap { + /** 模块导入映射 */ + imports?: Record; + /** 作用域特定的导入映射 */ + scopes?: { + [scope: string]: Record; + }; +} + +/** + * 打印插件配置选项 + * @description 用于配置控制台打印信息 + */ +interface PrintPluginOptions { + /** + * 打印的数据映射 + * @description 键值对形式的数据,将在控制台打印 + * @example + * ```typescript + * { + * 'App Version': '1.0.0', + * 'Build Time': '2024-01-01' + * } + * ``` + */ + infoMap?: Record; +} + +/** + * Nitro Mock 插件配置选项 + * @description 用于配置 Nitro Mock 服务器的行为 + */ +interface NitroMockPluginOptions { + /** + * Mock 服务器包名 + * @default '@vbenjs/nitro-mock' + */ + mockServerPackage?: string; + + /** + * Mock 服务端口 + * @default 3000 + */ + port?: number; + + /** + * 是否打印 Mock 日志 + * @default false + */ + verbose?: boolean; +} + +/** + * 归档插件配置选项 + * @description 用于配置构建产物的压缩归档 + */ +interface ArchiverPluginOptions { + /** + * 输出文件名 + * @default 'dist' + */ + name?: string; + /** + * 输出目录 + * @default '.' + */ + outputDir?: string; +} + +/** + * ImportMap 插件配置 + * @description 用于配置模块的 CDN 导入 + */ +interface ImportmapPluginOptions { + /** + * CDN 供应商 + * @default 'jspm.io' + * @description 支持 esm.sh 和 jspm.io 两种 CDN 供应商 + */ + defaultProvider?: 'esm.sh' | 'jspm.io'; + /** + * ImportMap 配置数组 + * @description 配置需要从 CDN 导入的包 + * @example + * ```typescript + * [ + * { name: 'vue' }, + * { name: 'pinia', range: '^2.0.0' } + * ] + * ``` + */ + importmap?: Array<{ name: string; range?: string }>; + /** + * 手动配置 ImportMap + * @description 自定义 ImportMap 配置 + */ + inputMap?: IImportMap; +} + +/** + * 条件插件配置 + * @description 用于根据条件动态加载插件 + */ +interface ConditionPlugin { + /** + * 判断条件 + * @description 当条件为 true 时加载插件 + */ + condition?: boolean; + /** + * 插件对象 + * @description 返回插件数组或 Promise + */ + plugins: () => PluginOption[] | PromiseLike; +} + +/** + * 通用插件配置选项 + * @description 所有插件共用的基础配置 + */ +interface CommonPluginOptions { + /** + * 是否开启开发工具 + * @default false + */ + devtools?: boolean; + /** + * 环境变量 + * @description 自定义环境变量 + */ + env?: Record; + /** + * 是否注入元数据 + * @default true + */ + injectMetadata?: boolean; + /** + * 是否为构建模式 + * @default false + */ + isBuild?: boolean; + /** + * 构建模式 + * @default 'development' + */ + mode?: string; + /** + * 是否开启依赖分析 + * @default false + * @description 使用 rollup-plugin-visualizer 分析依赖 + */ + visualizer?: boolean | PluginVisualizerOptions; +} + +/** + * 应用插件配置选项 + * @description 用于配置应用构建时的插件选项 + */ +interface ApplicationPluginOptions extends CommonPluginOptions { + /** + * 是否开启压缩归档 + * @default false + * @description 开启后会在打包目录生成 zip 文件 + */ + archiver?: boolean; + /** + * 压缩归档插件配置 + * @description 配置压缩归档的行为 + */ + archiverPluginOptions?: ArchiverPluginOptions; + /** + * 是否开启压缩 + * @default false + * @description 支持 gzip 和 brotli 压缩 + */ + compress?: boolean; + /** + * 压缩类型 + * @default ['gzip'] + * @description 可选的压缩类型 + */ + compressTypes?: ('brotli' | 'gzip')[]; + /** + * 是否抽离配置文件 + * @default false + * @description 在构建时抽离配置文件 + */ + extraAppConfig?: boolean; + /** + * 是否开启 HTML 插件 + * @default true + */ + html?: boolean; + /** + * 是否开启国际化 + * @default false + */ + i18n?: boolean; + /** + * 是否开启 ImportMap CDN + * @default false + */ + importmap?: boolean; + /** + * ImportMap 插件配置 + */ + importmapOptions?: ImportmapPluginOptions; + /** + * 是否注入应用加载动画 + * @default true + */ + injectAppLoading?: boolean; + /** + * 是否注入全局 SCSS + * @default true + */ + injectGlobalScss?: boolean; + /** + * 是否注入版权信息 + * @default true + */ + license?: boolean; + /** + * 是否开启 Nitro Mock + * @default false + */ + nitroMock?: boolean; + /** + * Nitro Mock 插件配置 + */ + nitroMockOptions?: NitroMockPluginOptions; + /** + * 是否开启控制台打印 + * @default false + */ + print?: boolean; + /** + * 打印插件配置 + */ + printInfoMap?: PrintPluginOptions['infoMap']; + /** + * 是否开启 PWA + * @default false + */ + pwa?: boolean; + /** + * PWA 插件配置 + */ + pwaOptions?: Partial; + /** + * 是否开启 VXE Table 懒加载 + * @default false + */ + vxeTableLazyImport?: boolean; +} + +/** + * 库插件配置选项 + * @description 用于配置库构建时的插件选项 + */ +interface LibraryPluginOptions extends CommonPluginOptions { + /** + * 是否开启 DTS 输出 + * @default true + * @description 生成 TypeScript 类型声明文件 + */ + dts?: boolean | PluginOptions; +} + +/** + * 应用配置选项类型 + */ +type ApplicationOptions = ApplicationPluginOptions; + +/** + * 库配置选项类型 + */ +type LibraryOptions = LibraryPluginOptions; + +/** + * 应用配置定义函数类型 + * @description 用于定义应用构建配置 + */ +type DefineApplicationOptions = (config?: ConfigEnv) => Promise<{ + /** 应用插件配置 */ + application?: ApplicationOptions; + /** Vite 配置 */ + vite?: UserConfig; +}>; + +/** + * 库配置定义函数类型 + * @description 用于定义库构建配置 + */ +type DefineLibraryOptions = (config?: ConfigEnv) => Promise<{ + /** 库插件配置 */ + library?: LibraryOptions; + /** Vite 配置 */ + vite?: UserConfig; +}>; + +/** + * 配置定义类型 + * @description 应用或库的配置定义 + */ +type DefineConfig = DefineApplicationOptions | DefineLibraryOptions; + +export type { + ApplicationPluginOptions, + ArchiverPluginOptions, + CommonPluginOptions, + ConditionPlugin, + DefineApplicationOptions, + DefineConfig, + DefineLibraryOptions, + IImportMap, + ImportmapPluginOptions, + LibraryPluginOptions, + NitroMockPluginOptions, + PrintPluginOptions, +}; diff --git a/internal/vite-config/src/utils/env.ts b/internal/vite-config/src/utils/env.ts new file mode 100644 index 0000000..f342216 --- /dev/null +++ b/internal/vite-config/src/utils/env.ts @@ -0,0 +1,110 @@ +import type { ApplicationPluginOptions } from '../typing'; + +import { existsSync } from 'node:fs'; +import { join } from 'node:path'; + +import { fs } from '@vben/node-utils'; + +import dotenv from 'dotenv'; + +const getBoolean = (value: string | undefined) => value === 'true'; + +const getString = (value: string | undefined, fallback: string) => + value ?? fallback; + +const getNumber = (value: string | undefined, fallback: number) => + Number(value) || fallback; + +/** + * 获取当前环境下生效的配置文件名 + */ +function getConfFiles() { + const script = process.env.npm_lifecycle_script as string; + const reg = /--mode ([\d_a-z]+)/; + const result = reg.exec(script); + let mode = 'production'; + if (result) { + mode = result[1] as string; + } + return ['.env', '.env.local', `.env.${mode}`, `.env.${mode}.local`]; +} + +/** + * Get the environment variables starting with the specified prefix + * @param match prefix + * @param confFiles ext + */ +async function loadEnv>( + match = 'VITE_GLOB_', + confFiles = getConfFiles(), +) { + let envConfig = {}; + + for (const confFile of confFiles) { + try { + const confFilePath = join(process.cwd(), confFile); + if (existsSync(confFilePath)) { + const envPath = await fs.readFile(confFilePath, { + encoding: 'utf8', + }); + const env = dotenv.parse(envPath); + envConfig = { ...envConfig, ...env }; + } + } catch (error) { + console.error(`Error while parsing ${confFile}`, error); + } + } + const reg = new RegExp(`^(${match})`); + Object.keys(envConfig).forEach((key) => { + if (!reg.test(key)) { + Reflect.deleteProperty(envConfig, key); + } + }); + return envConfig as T; +} + +async function loadAndConvertEnv( + match = 'VITE_', + confFiles = getConfFiles(), +): Promise< + Partial & { + appTitle: string; + base: string; + port: number; + } +> { + const envConfig = await loadEnv(match, confFiles); + + const { + VITE_APP_TITLE, + VITE_ARCHIVER, + VITE_BASE, + VITE_COMPRESS, + VITE_DEVTOOLS, + VITE_INJECT_APP_LOADING, + VITE_NITRO_MOCK, + VITE_PORT, + VITE_PWA, + VITE_VISUALIZER, + } = envConfig; + + const compressTypes = (VITE_COMPRESS ?? '') + .split(',') + .filter((item) => item === 'brotli' || item === 'gzip'); + + return { + appTitle: getString(VITE_APP_TITLE, 'Vben Admin'), + archiver: getBoolean(VITE_ARCHIVER), + base: getString(VITE_BASE, '/'), + compress: compressTypes.length > 0, + compressTypes, + devtools: getBoolean(VITE_DEVTOOLS), + injectAppLoading: getBoolean(VITE_INJECT_APP_LOADING), + nitroMock: getBoolean(VITE_NITRO_MOCK), + port: getNumber(VITE_PORT, 5173), + pwa: getBoolean(VITE_PWA), + visualizer: getBoolean(VITE_VISUALIZER), + }; +} + +export { loadAndConvertEnv, loadEnv }; diff --git a/internal/vite-config/tsconfig.json b/internal/vite-config/tsconfig.json new file mode 100644 index 0000000..b2ec3b6 --- /dev/null +++ b/internal/vite-config/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/node.json", + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000..7280174 --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,76 @@ +# EXAMPLE USAGE: +# +# Refer for explanation to following link: +# https://lefthook.dev/configuration/ +# +# pre-push: +# jobs: +# - name: packages audit +# tags: +# - frontend +# - security +# run: yarn audit +# +# - name: gems audit +# tags: +# - backend +# - security +# run: bundle audit +# +# pre-commit: +# parallel: true +# jobs: +# - run: yarn eslint {staged_files} +# glob: "*.{js,ts,jsx,tsx}" +# +# - name: rubocop +# glob: "*.rb" +# exclude: +# - config/application.rb +# - config/routes.rb +# run: bundle exec rubocop --force-exclusion {all_files} +# +# - name: govet +# files: git ls-files -m +# glob: "*.go" +# run: go vet {files} +# +# - script: "hello.js" +# runner: node +# +# - script: "hello.go" +# runner: go run + +pre-commit: + parallel: true + commands: + code-workspace: + run: pnpm vsh code-workspace --auto-commit + lint-md: + run: pnpm prettier --cache --ignore-unknown --write {staged_files} + glob: '*.md' + lint-vue: + run: pnpm prettier --write {staged_files} && pnpm eslint --cache --fix {staged_files} && pnpm stylelint --fix --allow-empty-input {staged_files} + glob: '*.vue' + lint-js: + run: pnpm prettier --cache --ignore-unknown --write {staged_files} && pnpm eslint --cache --fix {staged_files} + glob: '*.{js,jsx,ts,tsx}' + lint-style: + run: pnpm prettier --cache --ignore-unknown --write {staged_files} && pnpm stylelint --fix --allow-empty-input {staged_files} + glob: '*.{scss,less,styl,html,vue,css}' + lint-package: + run: pnpm prettier --cache --write {staged_files} + glob: 'package.json' + lint-json: + run: pnpm prettier --cache --write --parser json {staged_files} + glob: '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}' + +post-merge: + commands: + install: + run: pnpm install + +commit-msg: + commands: + commitlint: + run: pnpm exec commitlint --edit $1 diff --git a/package.json b/package.json new file mode 100644 index 0000000..1592c44 --- /dev/null +++ b/package.json @@ -0,0 +1,117 @@ +{ + "name": "vben-admin-monorepo", + "version": "5.5.6", + "private": true, + "keywords": [ + "monorepo", + "turbo", + "vben", + "vben admin", + "vben pro", + "vue", + "vue admin", + "vue vben admin", + "vue vben admin pro", + "vue3" + ], + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": "vbenjs/vue-vben-admin.git", + "license": "MIT", + "author": { + "name": "vben", + "email": "ann.vben@gmail.com", + "url": "https://github.com/anncwb" + }, + "type": "module", + "scripts": { + "build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 turbo build", + "build:analyze": "turbo build:analyze", + "build:antd": "pnpm run build --filter=@vben/web-antd", + "build:docker": "./scripts/deploy/build-local-docker-image.sh", + "build:docs": "pnpm run build --filter=@vben/docs", + "build:play": "pnpm run build --filter=@vben/playground", + "changeset": "pnpm exec changeset", + "check": "pnpm run check:circular && pnpm run check:dep && pnpm run check:type && pnpm check:cspell", + "check:circular": "vsh check-circular", + "check:cspell": "cspell lint **/*.ts **/README.md .changeset/*.md --no-progress", + "check:dep": "vsh check-dep", + "check:type": "turbo run typecheck", + "clean": "node ./scripts/clean.mjs", + "commit": "czg", + "dev": "turbo-run dev", + "dev:antd": "pnpm -F @vben/web-antd run dev", + "dev:docs": "pnpm -F @vben/docs run dev", + "dev:play": "pnpm -F @vben/playground run dev", + "format": "vsh lint --format", + "lint": "vsh lint", + "postinstall": "pnpm -r run stub --if-present", + "preinstall": "npx only-allow pnpm", + "preview": "turbo-run preview", + "publint": "vsh publint", + "reinstall": "pnpm clean --del-lock && pnpm install", + "test:unit": "vitest run --dom", + "test:e2e": "turbo run test:e2e", + "update:deps": "npx taze -r -w", + "version": "pnpm exec changeset version && pnpm install --no-frozen-lockfile", + "catalog": "pnpx codemod pnpm/catalog" + }, + "devDependencies": { + "@changesets/changelog-github": "catalog:", + "@changesets/cli": "catalog:", + "@playwright/test": "catalog:", + "@types/node": "catalog:", + "@vben/commitlint-config": "workspace:*", + "@vben/eslint-config": "workspace:*", + "@vben/prettier-config": "workspace:*", + "@vben/stylelint-config": "workspace:*", + "@vben/tailwind-config": "workspace:*", + "@vben/tsconfig": "workspace:*", + "@vben/turbo-run": "workspace:*", + "@vben/vite-config": "workspace:*", + "@vben/vsh": "workspace:*", + "@vitejs/plugin-vue": "catalog:", + "@vitejs/plugin-vue-jsx": "catalog:", + "@vue/test-utils": "catalog:", + "autoprefixer": "catalog:", + "cross-env": "catalog:", + "cspell": "catalog:", + "happy-dom": "catalog:", + "is-ci": "catalog:", + "lefthook": "catalog:", + "playwright": "catalog:", + "rimraf": "catalog:", + "tailwindcss": "catalog:", + "turbo": "catalog:", + "typescript": "catalog:", + "unbuild": "catalog:", + "vite": "catalog:", + "vitest": "catalog:", + "vue": "catalog:", + "vue-tsc": "catalog:" + }, + "engines": { + "node": ">=20.10.0", + "pnpm": ">=9.12.0" + }, + "packageManager": "pnpm@10.10.0", + "pnpm": { + "peerDependencyRules": { + "allowedVersions": { + "eslint": "*" + } + }, + "overrides": { + "@ast-grep/napi": "catalog:", + "@ctrl/tinycolor": "catalog:", + "clsx": "catalog:", + "esbuild": "0.25.3", + "pinia": "catalog:", + "vue": "catalog:" + }, + "neverBuiltDependencies": [ + "canvas", + "node-gyp" + ] + } +} diff --git a/packages/@core/README.md b/packages/@core/README.md new file mode 100644 index 0000000..8eb201d --- /dev/null +++ b/packages/@core/README.md @@ -0,0 +1,3 @@ +# @vben-core + +系统一些比较基础的SDK和UI组件库,该目录后续完善后,可能会迁移出去或者发布到npm,请勿将任何业务逻辑和业务包放在该目录。 diff --git a/packages/@core/base/README.md b/packages/@core/base/README.md new file mode 100644 index 0000000..cc745b4 --- /dev/null +++ b/packages/@core/base/README.md @@ -0,0 +1,5 @@ +# base + +基础共享包,请勿引入 workspace 依赖 + +- diff --git a/packages/@core/base/design/package.json b/packages/@core/base/design/package.json new file mode 100644 index 0000000..4bdfbe3 --- /dev/null +++ b/packages/@core/base/design/package.json @@ -0,0 +1,41 @@ +{ + "name": "@vben-core/design", + "version": "5.5.6", + "homepage": "https://github.com/vbenjs/vue-vben-admin", + "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", + "directory": "packages/@vben-core/base/design" + }, + "license": "MIT", + "type": "module", + "scripts": { + "build": "pnpm vite build", + "prepublishOnly": "npm run build" + }, + "files": [ + "dist", + "src" + ], + "main": "./dist/index.mjs", + "module": "./dist/index.mjs", + "exports": { + "./bem": { + "development": "./src/scss-bem/bem.scss", + "default": "./dist/bem.scss" + }, + ".": { + "types": "./src/index.ts", + "development": "./src/index.ts", + "default": "./dist/design.css" + } + }, + "publishConfig": { + "exports": { + ".": { + "default": "./dist/index.mjs" + } + } + } +} diff --git a/packages/@core/base/design/src/css/global.css b/packages/@core/base/design/src/css/global.css new file mode 100644 index 0000000..d199909 --- /dev/null +++ b/packages/@core/base/design/src/css/global.css @@ -0,0 +1,160 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + *, + ::after, + ::before { + @apply border-border; + + box-sizing: border-box; + border-style: solid; + border-width: 0; + } + + html { + @apply text-foreground bg-background font-sans text-[100%]; + + font-variation-settings: normal; + line-height: 1.15; + text-size-adjust: 100%; + font-synthesis-weight: none; + scroll-behavior: smooth; + text-rendering: optimizelegibility; + -webkit-tap-highlight-color: transparent; + + /* -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; */ + } + + #app, + body, + html { + @apply size-full; + + /* scrollbar-gutter: stable; */ + } + + body { + min-height: 100vh; + + /* pointer-events: auto !important; */ + + /* overflow: overlay; */ + + /* -webkit-font-smoothing: antialiased; */ + + /* -moz-osx-font-smoothing: grayscale; */ + } + + a, + a:active, + a:hover, + a:link, + a:visited { + @apply no-underline; + } + + ::view-transition-new(root), + ::view-transition-old(root) { + @apply animate-none mix-blend-normal; + } + + ::view-transition-old(root) { + @apply z-[1]; + } + + ::view-transition-new(root) { + @apply z-[2147483646]; + } + + html.dark::view-transition-old(root) { + @apply z-[2147483646]; + } + + html.dark::view-transition-new(root) { + @apply z-[1]; + } + + input::placeholder, + textarea::placeholder { + @apply opacity-100; + } + + /* input:-webkit-autofill { + @apply border-none; + + box-shadow: 0 0 0 1000px transparent inset; + } */ + + input[type='number']::-webkit-inner-spin-button, + input[type='number']::-webkit-outer-spin-button { + @apply m-0 appearance-none; + } + + /* 只有非mac下才进行调整,mac下使用默认滚动条 */ + html:not([data-platform='macOs']) { + ::-webkit-scrollbar { + @apply h-[10px] w-[10px]; + } + + ::-webkit-scrollbar-thumb { + @apply bg-border rounded-sm border-none; + } + + ::-webkit-scrollbar-track { + @apply rounded-sm border-none bg-transparent shadow-none; + } + + ::-webkit-scrollbar-button { + @apply hidden; + } + } +} + +@layer components { + .flex-center { + @apply flex items-center justify-center; + } + + .flex-col-center { + @apply flex flex-col items-center justify-center; + } + + .outline-box { + @apply outline-border relative cursor-pointer rounded-md p-1 outline outline-1; + } + + .outline-box::after { + @apply absolute left-1/2 top-1/2 z-20 h-0 w-[1px] rounded-sm opacity-0 outline outline-2 outline-transparent transition-all duration-300 content-[""]; + } + + .outline-box.outline-box-active { + @apply outline-primary outline outline-2; + } + + .outline-box.outline-box-active::after { + display: none; + } + + .outline-box:not(.outline-box-active):hover::after { + @apply outline-primary left-0 top-0 h-full w-full p-1 opacity-100; + } + + .vben-link { + @apply text-primary hover:text-primary-hover active:text-primary-active cursor-pointer; + } + + .card-box { + @apply bg-card text-card-foreground border-border rounded-xl border; + } +} + +html.invert-mode { + @apply invert; +} + +html.grayscale-mode { + @apply grayscale; +} diff --git a/packages/@core/base/design/src/css/nprogress.css b/packages/@core/base/design/src/css/nprogress.css new file mode 100644 index 0000000..3503dab --- /dev/null +++ b/packages/@core/base/design/src/css/nprogress.css @@ -0,0 +1,59 @@ +/* Make clicks pass-through */ +#nprogress { + @apply pointer-events-none; +} + +#nprogress .bar { + @apply bg-primary fixed left-0 top-0 z-[1031] h-[2px] w-full; +} + +/* Fancy blur effect */ +#nprogress .peg { + @apply absolute right-0 block h-full w-[100px]; + + box-shadow: + 0 0 10px hsl(var(--primary)), + 0 0 5px hsl(var(--primary)); + opacity: 1; + transform: rotate(3deg) translate(0, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + @apply fixed right-4 top-4 z-[1031] block; +} + +#nprogress .spinner-icon { + @apply border-t-primary border-l-primary size-4 rounded-full border-[2px] border-solid border-transparent; + + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + @apply relative overflow-hidden; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + @apply absolute; +} + +@keyframes nprogress-spinner { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +@keyframes nprogress-spinner { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} diff --git a/packages/@core/base/design/src/css/transition.css b/packages/@core/base/design/src/css/transition.css new file mode 100644 index 0000000..c1cb0e4 --- /dev/null +++ b/packages/@core/base/design/src/css/transition.css @@ -0,0 +1,236 @@ +.slide-up-enter-active, +.slide-up-leave-active { + transition: 0.25s cubic-bezier(0.25, 0.8, 0.5, 1); +} + +.slide-up-move { + transition: transform 0.3s; +} + +.slide-up-enter-from, +.slide-up-leave-to { + opacity: 0; + transform: translateY(-15px); +} + +.slide-down-enter-active, +.slide-down-leave-active { + transition: 0.25s cubic-bezier(0.25, 0.8, 0.5, 1); +} + +.slide-down-move { + transition: transform 0.3s; +} + +.slide-down-enter-from, +.slide-down-leave-to { + opacity: 0; + transform: translateY(15px); +} + +.slide-left-enter-active, +.slide-left-leave-active { + transition: 0.25s cubic-bezier(0.25, 0.8, 0.5, 1); +} + +.slide-left-move { + transition: transform 0.3s; +} + +.slide-left-enter-from, +.slide-left-leave-to { + opacity: 0; + transform: translate(-15px); +} + +.slide-right-enter-active, +.slide-right-leave-active { + transition: 0.25s cubic-bezier(0.25, 0.8, 0.5, 1); +} + +.slide-right-move { + transition: transform 0.3s; +} + +.slide-right-enter-from, +.slide-right-leave-to { + opacity: 0; + transform: translate(15px); +} + +.fade-transition-enter-active, +.fade-transition-leave-active { + transition: opacity 0.2s ease-in-out; +} + +.fade-transition-enter-from, +.fade-transition-leave-to { + opacity: 0; +} + +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.2s ease-in-out; +} + +.fade-enter-from, +.fade-leave-to { + opacity: 0; +} + +.fade-slide-leave-active, +.fade-slide-enter-active { + transition: all 0.3s; +} + +.fade-slide-enter-from { + opacity: 0; + transform: translate(-30px); +} + +.fade-slide-leave-to { + opacity: 0; + transform: translate(30px); +} + +.fade-down-enter-active, +.fade-down-leave-active { + transition: + opacity 0.25s, + transform 0.3s; +} + +.fade-down-enter-from { + opacity: 0; + transform: translateY(-10%); +} + +.fade-down-leave-to { + opacity: 0; + transform: translateY(10%); +} + +.fade-scale-leave-active, +.fade-scale-enter-active { + transition: all 0.28s; +} + +.fade-scale-enter-from { + opacity: 0; + transform: scale(1.2); +} + +.fade-scale-leave-to { + opacity: 0; + transform: scale(0.8); +} + +.fade-up-enter-active, +.fade-up-leave-active { + transition: + opacity 0.2s, + transform 0.25s; +} + +.fade-up-enter-from { + opacity: 0; + transform: translateY(10%); +} + +.fade-up-leave-to { + opacity: 0; + transform: translateY(-10%); +} + +@keyframes fade-slide { + 0% { + opacity: 0; + transform: translate(-30px); + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + transform: translate(30px); + } +} + +@keyframes fade { + 0% { + opacity: 0; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@keyframes fade-up { + 0% { + opacity: 0; + transform: translateY(10%); + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + transform: translateY(-10%); + } +} + +@keyframes fade-down { + 0% { + opacity: 0; + transform: translateY(-10%); + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + transform: translateY(10%); + } +} + +.fade-slow { + animation: fade 3s infinite; +} + +.fade-slide-slow { + animation: fade-slide 3s infinite; +} + +.fade-up-slow { + animation: fade-up 3s infinite; +} + +.fade-down-slow { + animation: fade-down 3s infinite; +} + +.collapse-transition { + transition: + 0.2s height ease-in-out, + 0.2s padding-top ease-in-out, + 0.2s padding-bottom ease-in-out; +} + +.collapse-transition-leave-active, +.collapse-transition-enter-active { + transition: + 0.2s max-height ease-in-out, + 0.2s padding-top ease-in-out, + 0.2s margin-top ease-in-out; +} diff --git a/packages/@core/base/design/src/css/ui.css b/packages/@core/base/design/src/css/ui.css new file mode 100644 index 0000000..f7119c8 --- /dev/null +++ b/packages/@core/base/design/src/css/ui.css @@ -0,0 +1,87 @@ +.side-content { + animation-duration: 0.2s; + animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); +} + +.side-content[data-side='top'] { + animation-name: slide-up; +} + +.side-content[data-side='bottom'] { + animation-name: slide-down; +} + +.side-content[data-side='left'] { + animation-name: slide-left; +} + +.side-content[data-side='right'] { + animation-name: slide-right; +} + +.breadcrumb-transition-enter-active { + transition: + transform 0.4s cubic-bezier(0.76, 0, 0.24, 1), + opacity 0.4s cubic-bezier(0.76, 0, 0.24, 1); +} + +.breadcrumb-transition-leave-active { + display: none; +} + +.breadcrumb-transition-enter-from { + opacity: 0; + transform: translateX(30px) skewX(-30deg); +} + +@keyframes slide-down { + from { + opacity: 0; + transform: translateY(-10px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slide-left { + from { + opacity: 0; + transform: translateX(-10px); + } + + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes slide-right { + from { + opacity: 0; + transform: translateX(-10px); + } + + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes slide-up { + from { + opacity: 0; + transform: translateY(10px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +.z-popup { + z-index: var(--popup-z-index); +} diff --git a/packages/@core/base/design/src/design-tokens/dark.css b/packages/@core/base/design/src/design-tokens/dark.css new file mode 100644 index 0000000..3881041 --- /dev/null +++ b/packages/@core/base/design/src/design-tokens/dark.css @@ -0,0 +1,446 @@ +.dark, +.dark[data-theme='custom'], +.dark[data-theme='default'] { + /* Default background color of ...etc */ + --background: 222.34deg 10.43% 12.27%; + + /* 主体区域背景色 */ + --background-deep: 220deg 13.06% 9%; + --foreground: 0 0% 95%; + + /* Background color for */ + --card: 222.34deg 10.43% 12.27%; + + /* --card: 222.2 84% 4.9%; */ + --card-foreground: 210 40% 98%; + + /* Background color for popovers such as , , */ + + /* --popover: 222.82deg 8.43% 12.27%; */ + + /* 弹出层的背景色与主题区域背景色太过接近 */ + --popover: 0 0% 14.2%; + --popover-foreground: 210 40% 98%; + + /* Muted backgrounds such as , and */ + + /* --muted: 220deg 6.82% 17.25%; */ + + /* --muted-foreground: 215 20.2% 65.1%; */ + + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + + /* 主题颜色 */ + + /* --primary: 245 82% 67%; */ + --primary-foreground: 0 0% 98%; + + /* Used for destructive actions such as