From f230a2a94d9995ec7df16c6570414e854a8b9486 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Sun, 14 Jul 2024 19:24:39 +0000 Subject: [PATCH 01/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: 1 --- packages/ui/certd-client/package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index c54a18a5..28ef05ad 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -107,9 +107,6 @@ "vite": "^5.1.6", "vite-plugin-compression": "^0.5.1", "vite-plugin-html": "^3.2.2", - "vite-plugin-optimize-persist": "^0.1.2", - "vite-plugin-package-config": "^0.1.1", - "vite-plugin-purge-icons": "^0.10.0", "vite-plugin-theme": "^0.8.6", "vite-plugin-windicss": "^1.9.3", "vue-eslint-parser": "^9.4.2", From f97827ec76fd19fc13a59390b7c7af702023e678 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Mon, 15 Jul 2024 19:23:57 +0000 Subject: [PATCH 02/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=203=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build: publish success Merge remote-tracking branch 'origin/main' --- packages/ui/certd-client/CHANGELOG.md | 6 ++++++ packages/ui/certd-client/package.json | 10 +++++----- .../ui/certd-client/src/plugin/fast-crud/index.tsx | 6 +++--- .../src/views/crud/component/uploader/s3/s3-server.ts | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 33bd004a..5a2d23e3 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.21.2](https://github.com/fast-crud/fast-crud/compare/v1.21.1...v1.21.2) (2024-07-15) + +### Performance Improvements + +* 增加示例,FsInDrawer ([777830f](https://github.com/fast-crud/fast-crud/commit/777830f860b6a9752ba24df5a99af5e7c62bdfb2)) + ## [1.21.1](https://github.com/fast-crud/fast-crud/compare/v1.21.0...v1.21.1) (2024-06-23) ### Bug Fixes diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index 28ef05ad..93368886 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.21.1", + "version": "1.21.2", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.21.1", - "@fast-crud/fast-extends": "^1.21.1", - "@fast-crud/ui-antdv4": "^1.21.1", - "@fast-crud/ui-interface": "^1.21.1", + "@fast-crud/fast-crud": "^1.21.2", + "@fast-crud/fast-extends": "^1.21.2", + "@fast-crud/ui-antdv4": "^1.21.2", + "@fast-crud/ui-interface": "^1.21.2", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.1.2", diff --git a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx index 7ee67212..bef56eb2 100644 --- a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx +++ b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx @@ -181,7 +181,7 @@ function install(app: any, options: any = {}) { domain: "https://d2p-demo.oss-cn-shenzhen.aliyuncs.com", bucket: "d2p-demo", region: "oss-cn-shenzhen", - accessKeyId: "", + accessKeyId: "", //不建议客户端使用AccessKey,生产部署请使用getAuthorization来获取授权 accessKeySecret: "", async getAuthorization(context: FsUploaderGetAuthContext): Promise { // 不传accessKeySecret代表使用临时签名模式,此时此参数必传(安全,生产环境推荐) @@ -239,12 +239,12 @@ function install(app: any, options: any = {}) { //minio与s3完全适配 endpoint: "https://play.min.io", credentials: { - //不建议在客户端使用secretAccessKey来上传 + //不建议在客户端使用secretAccessKey来上传, 生产部署请使用getSignedUrl,来获取授权 accessKeyId: "Q3AM3UQ867SPQQA43P2F", //访问登录名 secretAccessKey: "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG" //访问密码 } }, - //预签名配置,向后端获取上传的预签名连接 + //预签名配置,向后端获取上传的预签名连接(生产部署推荐) async getSignedUrl(bucket: string, key: string, options: any, type: FsUploaderS3SignedUrlType = "put") { return await GetSignedUrl(bucket, key, type); }, diff --git a/packages/ui/certd-client/src/views/crud/component/uploader/s3/s3-server.ts b/packages/ui/certd-client/src/views/crud/component/uploader/s3/s3-server.ts index 5e6833fd..0b39fa2b 100644 --- a/packages/ui/certd-client/src/views/crud/component/uploader/s3/s3-server.ts +++ b/packages/ui/certd-client/src/views/crud/component/uploader/s3/s3-server.ts @@ -1,7 +1,7 @@ // @ts-ignore import { S3Client, GetObjectCommand, PutObjectCommand, CreateBucketCommand } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; -import {utils} from "@fast-crud/fast-crud"; +import { utils } from "@fast-crud/fast-crud"; // TODO 模拟server, 你应该将此代码搬到你的server端 let bucketCreated = false; export async function generateSignedUrl(bucket: string, key: string, type: "put" | "get" = "get") { From b2971cf5fba7d11438aca18f0bf59e3dfd17dd5e Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Sun, 28 Jul 2024 19:23:50 +0000 Subject: [PATCH 03/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: --- .../ui/certd-client/src/plugin/permission/util.permission.ts | 3 +++ packages/ui/certd-client/src/store/modules/resource.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/packages/ui/certd-client/src/plugin/permission/util.permission.ts b/packages/ui/certd-client/src/plugin/permission/util.permission.ts index 4efd2b6b..d16ba7bf 100644 --- a/packages/ui/certd-client/src/plugin/permission/util.permission.ts +++ b/packages/ui/certd-client/src/plugin/permission/util.permission.ts @@ -15,6 +15,9 @@ const util = { const permissionStore = usePermissionStore(); const userPermissionList = permissionStore.getPermissions; return userPermissionList.some((permission: any) => { + if (permission === "*") { + return true; + } return need.includes(permission); }); }, diff --git a/packages/ui/certd-client/src/store/modules/resource.ts b/packages/ui/certd-client/src/store/modules/resource.ts index cf7d39e8..965d2f54 100644 --- a/packages/ui/certd-client/src/store/modules/resource.ts +++ b/packages/ui/certd-client/src/store/modules/resource.ts @@ -112,6 +112,9 @@ export const useResourceStore = defineStore({ filterChildrenByPermission(list: any, permissions: any) { const menus = list.filter((item: any) => { if (item?.meta?.permission) { + if (permissions.includes("*")) { + return true; + } return permissions.includes(item.meta.permission); } return true; From f4a11ed328ffe2a8b40689b2a9aeea8d6498df22 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Mon, 29 Jul 2024 19:24:00 +0000 Subject: [PATCH 04/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: --- .../certd-client/src/views/crud/form/independent/index.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ui/certd-client/src/views/crud/form/independent/index.vue b/packages/ui/certd-client/src/views/crud/form/independent/index.vue index 398a38f7..3d47ab6e 100644 --- a/packages/ui/certd-client/src/views/crud/form/independent/index.vue +++ b/packages/ui/certd-client/src/views/crud/form/independent/index.vue @@ -232,11 +232,11 @@ function useCrudOptions() { * 此方式可以层叠打开多个对话框 */ function useFormProvider() { - const { openDialog } = useFormWrapper(); + const { openCrudFormDialog } = useFormWrapper(); async function openFormWrapperNoTag() { - const opts = createFormOptionsFromCrudOptions(); - const wrapperRef = await openDialog(opts); + const { crudOptions } = createCrudOptions({} as any); + const wrapperRef = await openCrudFormDialog({ crudOptions }); utils.logger.log("对话框已打开", wrapperRef); } return { From d0c4dfca97b93cb45a9145f72a21a4b6bbf55961 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Sun, 4 Aug 2024 19:24:18 +0000 Subject: [PATCH 05/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf: 全部支持拖动调整列宽 --- .../certd-client/src/plugin/fast-crud/index.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx index bef56eb2..cfba1653 100644 --- a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx +++ b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx @@ -336,6 +336,22 @@ function install(app: any, options: any = {}) { return columnProps; } }); + + //默认宽度,支持自动拖动调整列宽 + registerMergeColumnPlugin({ + name: "resize-column-plugin", + order: 2, + handle: (columnProps: ColumnCompositionProps) => { + if (!columnProps.column) { + columnProps.column = {}; + } + columnProps.column.resizable = true; + if (!columnProps.column.width) { + columnProps.column.width = 100; + } + return columnProps; + } + }); } export default { From 6e8b0eeca981edbe7de9903337d024dda18c828c Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Tue, 10 Sep 2024 19:24:33 +0000 Subject: [PATCH 06/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: 修复antdv 文件上传 success事件无效的bug --- .../src/plugin/fast-crud/index.tsx | 1 + .../crud/component/uploader/form/crud.tsx | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx index cfba1653..24d05e90 100644 --- a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx +++ b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx @@ -60,6 +60,7 @@ function install(app: any, options: any = {}) { } }, rowHandle: { + fixed: "right", buttons: { view: { type: "link", text: null, icon: "ion:eye-outline" }, copy: { show: true, type: "link", text: null, icon: "ion:copy-outline" }, diff --git a/packages/ui/certd-client/src/views/crud/component/uploader/form/crud.tsx b/packages/ui/certd-client/src/views/crud/component/uploader/form/crud.tsx index b592dc02..f477097b 100644 --- a/packages/ui/certd-client/src/views/crud/component/uploader/form/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/component/uploader/form/crud.tsx @@ -37,6 +37,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti } } }, + table: { + scroll: { x: 2000 } + }, columns: { id: { title: "ID", @@ -141,11 +144,28 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti component: { uploader: { type: "form" + }, + on: { + success(ctx) { + // 上传成功后的回调 + console.log("success", ctx); + ctx.form.avatarSize = ctx.$event.file.size; + } } }, helper: "就是照片墙limit=1的效果" } }, + avatarSize: { + title: "头像文件大小", + type: "number", + form: { + component: { + disabled: true + }, + helper: "左边头像上传成功后,会自动填充文件大小" + } + }, cropper: { title: "裁剪", type: "cropper-uploader", From 5ab2943c3ae4b4805751a0aa07423b8eec7bebf6 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Wed, 11 Sep 2024 19:24:00 +0000 Subject: [PATCH 07/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: 修复search-slot错位的问题 --- packages/ui/certd-client/src/views/crud/slots/layout/crud.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/certd-client/src/views/crud/slots/layout/crud.tsx b/packages/ui/certd-client/src/views/crud/slots/layout/crud.tsx index ee4a9585..1b77f109 100644 --- a/packages/ui/certd-client/src/views/crud/slots/layout/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/slots/layout/crud.tsx @@ -31,7 +31,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti container: { action: { col: { - span: 16 + span: 4 } } }, From 3dec43d8d48e8eee33ffd818fe0c427c16fe105d Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Fri, 20 Sep 2024 19:24:53 +0000 Subject: [PATCH 08/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build: publish success --- packages/ui/certd-client/CHANGELOG.md | 6 ++++++ packages/ui/certd-client/package.json | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 5a2d23e3..256e6813 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.21.3](https://github.com/fast-crud/fast-crud/compare/v1.21.2...v1.21.3) (2024-09-20) + +### Performance Improvements + +* 优化antdv search按钮组错位问题 ([0948650](https://github.com/fast-crud/fast-crud/commit/0948650747d725ffe84e4f357d81a3a9a331109e)) + ## [1.21.2](https://github.com/fast-crud/fast-crud/compare/v1.21.1...v1.21.2) (2024-07-15) ### Performance Improvements diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index 93368886..b13a857c 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.21.2", + "version": "1.21.3", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.21.2", - "@fast-crud/fast-extends": "^1.21.2", - "@fast-crud/ui-antdv4": "^1.21.2", - "@fast-crud/ui-interface": "^1.21.2", + "@fast-crud/fast-crud": "^1.21.3", + "@fast-crud/fast-extends": "^1.21.3", + "@fast-crud/ui-antdv4": "^1.21.3", + "@fast-crud/ui-interface": "^1.21.3", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.1.2", From fe9d443100336810b30d5531c78d8945318bd950 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Wed, 25 Sep 2024 19:23:59 +0000 Subject: [PATCH 09/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf: 优化示例的自动调整列宽 --- .../src/plugin/fast-crud/index.tsx | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx index 24d05e90..e5817613 100644 --- a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx +++ b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx @@ -45,6 +45,9 @@ function install(app: any, options: any = {}) { }, conditionalRender: { match(scope) { + if (scope.key === "__blank__") { + return false; + } //不能用 !scope.value , 否则switch组件设置为关之后就消失了 const { value, key, props } = scope; return !value && key != "_index" && value != false; @@ -134,6 +137,20 @@ function install(app: any, options: any = {}) { column: { order: 1000 } + }, + //最后一列空白,用于自动伸缩列宽 + __blank__: { + title: "", + type: "text", + form: { + show: false + }, + column: { + order: 99999, + width: -1, + columnSetShow: false, + resizable: false + } } } }; @@ -346,10 +363,13 @@ function install(app: any, options: any = {}) { if (!columnProps.column) { columnProps.column = {}; } - columnProps.column.resizable = true; - if (!columnProps.column.width) { - columnProps.column.width = 100; + if (columnProps.column.resizable == null) { + columnProps.column.resizable = true; + if (!columnProps.column.width) { + columnProps.column.width = 200; + } } + return columnProps; } }); From 49fa01f209bee61c6520d1747946aab9c574cace Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Sun, 13 Oct 2024 19:27:22 +0000 Subject: [PATCH 10/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=204=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build: publish success perf: 优化列设置多级表头支持级联勾选 perf: table-select支持destroyOnClose参数,以修复点击取消后,扔保留上一次选中值的bug --- packages/ui/certd-client/CHANGELOG.md | 7 +++++++ packages/ui/certd-client/package.json | 10 +++++----- .../src/layout/components/tabs/index.vue | 6 +++--- .../src/views/crud/component/text/crud.tsx | 14 +++++++++++--- .../src/views/crud/component/text/mock.ts | 1 + .../certd-client/src/views/crud/form/base/crud.tsx | 8 ++++++-- .../certd-client/src/views/crud/form/base/mock.ts | 2 ++ 7 files changed, 35 insertions(+), 13 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 256e6813..0cc21de0 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.21.4](https://github.com/fast-crud/fast-crud/compare/v1.21.3...v1.21.4) (2024-10-13) + +### Performance Improvements + +* 优化列设置多级表头支持级联勾选 ([a196922](https://github.com/fast-crud/fast-crud/commit/a196922630e9ef627dd548bb8d1c13acbe2eee28)) +* table-select支持destroyOnClose参数,以修复点击取消后,扔保留上一次选中值的bug ([5a70cec](https://github.com/fast-crud/fast-crud/commit/5a70cec7e5f45439a518fc2aadc40b29fad5c6f1)) + ## [1.21.3](https://github.com/fast-crud/fast-crud/compare/v1.21.2...v1.21.3) (2024-09-20) ### Performance Improvements diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index b13a857c..eb0a5e7a 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.21.3", + "version": "1.21.4", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.21.3", - "@fast-crud/fast-extends": "^1.21.3", - "@fast-crud/ui-antdv4": "^1.21.3", - "@fast-crud/ui-interface": "^1.21.3", + "@fast-crud/fast-crud": "^1.21.4", + "@fast-crud/fast-extends": "^1.21.4", + "@fast-crud/ui-antdv4": "^1.21.4", + "@fast-crud/ui-interface": "^1.21.4", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.1.2", diff --git a/packages/ui/certd-client/src/layout/components/tabs/index.vue b/packages/ui/certd-client/src/layout/components/tabs/index.vue index 6f289abc..14d8144e 100644 --- a/packages/ui/certd-client/src/layout/components/tabs/index.vue +++ b/packages/ui/certd-client/src/layout/components/tabs/index.vue @@ -2,7 +2,7 @@
- + @@ -16,10 +16,10 @@
- + + - diff --git a/packages/ui/certd-client/src/views/crud/basis/i18n/crud.tsx b/packages/ui/certd-client/src/views/crud/basis/i18n/crud.tsx index 1cc13c44..821c12dd 100644 --- a/packages/ui/certd-client/src/views/crud/basis/i18n/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/basis/i18n/crud.tsx @@ -2,7 +2,7 @@ import * as api from "./api"; import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; import { useI18n } from "vue-i18n"; -export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet { +export default async function ({ crudExpose }: CreateCrudOptionsProps): Promise { const pageRequest = async (query: UserPageQuery): Promise => { return await api.GetList(query); }; diff --git a/packages/ui/certd-client/src/views/crud/basis/i18n/index.vue b/packages/ui/certd-client/src/views/crud/basis/i18n/index.vue index 9a53a5b2..bb06ce37 100644 --- a/packages/ui/certd-client/src/views/crud/basis/i18n/index.vue +++ b/packages/ui/certd-client/src/views/crud/basis/i18n/index.vue @@ -17,16 +17,17 @@ diff --git a/packages/ui/certd-client/src/views/crud/feature/height/crud.tsx b/packages/ui/certd-client/src/views/crud/feature/height/crud.tsx index b2d4c4c0..e8ebf7e7 100644 --- a/packages/ui/certd-client/src/views/crud/feature/height/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/feature/height/crud.tsx @@ -1,7 +1,7 @@ import * as api from "./api"; import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; -export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet { +export default async function ({ crudExpose }: CreateCrudOptionsProps): Promise { const pageRequest = async (query: UserPageQuery): Promise => { return await api.GetList(query); }; diff --git a/packages/ui/certd-client/src/views/crud/feature/height/index.vue b/packages/ui/certd-client/src/views/crud/feature/height/index.vue index 01c59c98..95640403 100644 --- a/packages/ui/certd-client/src/views/crud/feature/height/index.vue +++ b/packages/ui/certd-client/src/views/crud/feature/height/index.vue @@ -6,16 +6,18 @@ diff --git a/packages/ui/certd-client/src/views/crud/advanced/card/mock.ts b/packages/ui/certd-client/src/views/crud/advanced/card/mock.ts new file mode 100644 index 00000000..2c6a29c2 --- /dev/null +++ b/packages/ui/certd-client/src/views/crud/advanced/card/mock.ts @@ -0,0 +1,27 @@ +// @ts-ignore +import mockUtil from "/src/mock/base"; +import _ from "lodash-es"; +const options: any = { + name: "AdvancedCard", + idGenerator: 0 +}; +const list = [ + { + title: "fast-crud怎么样", + content: "很好用" + }, + { + title: "大环境不好呀", + content: "好好学习提升自己吧" + }, + { + title: "Certd是什么", + content: "Certd是一款开源的证书全自动管理系统" + } +]; + +options.list = list; +options.copyTimes = 100; +const mock = mockUtil.buildMock(options); + +export default mock; diff --git a/packages/ui/certd-client/src/views/crud/component/table-select/crud.tsx b/packages/ui/certd-client/src/views/crud/component/table-select/crud.tsx index d52400ce..aafda5fa 100644 --- a/packages/ui/certd-client/src/views/crud/component/table-select/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/component/table-select/crud.tsx @@ -210,7 +210,10 @@ export default async function ({ crudExpose }: CreateCrudOptionsProps): Promise< title: "查看模式", dict: dict({ value: "id", - label: "name" + label: "name", + getNodesByValues: async (values: any[]) => { + return await textTableApi.GetByIds(values); + } }), column: { component: { @@ -219,6 +222,14 @@ export default async function ({ crudExpose }: CreateCrudOptionsProps): Promise< viewMode: true, createCrudOptions: createCrudOptionsText, crudOptionsOverride, + on: { + dialogClose(ctx) { + console.log("dialog close", ctx); + }, + dialogClosed(ctx) { + console.log("dialog closed", ctx); + } + }, slots: { default({ scope, value }) { async function open() { diff --git a/packages/ui/certd-client/src/views/crud/form/new-page/edit.vue b/packages/ui/certd-client/src/views/crud/form/new-page/edit.vue index 257cfda5..83b0b68f 100644 --- a/packages/ui/certd-client/src/views/crud/form/new-page/edit.vue +++ b/packages/ui/certd-client/src/views/crud/form/new-page/edit.vue @@ -25,41 +25,32 @@ export default defineComponent({ name: "FormNewPageEdit", setup(props, ctx) { const { crudRef, crudBinding, crudExpose, context } = useFsRef(); - - // 页面打开后获取列表数据 - onMounted(async () => { - await useFsAsync({ crudBinding, crudRef,crudExpose, context, createCrudOptions }); - await crudExpose.doRefresh(); - }); - const formRef = ref(); const formOptions = ref(); - - const route = useRoute(); - const id: any = route.query.id; - - if (id) { - //编辑表单 - formOptions.value = crudBinding.value.editForm; - } else { - formOptions.value = crudBinding.value.addForm; - } - const doSubmit = formOptions.value.doSubmit; const pageStore = usePageStore(); - - formOptions.value.doSubmit = (context: any) => { - utils.logger.log("submit", context); - doSubmit(context); - //提交成功后,关闭本页面 - message.success("保存成功"); - pageStore.close({ tagName: route.fullPath }); - }; - - const getDetail = async (id: any) => { - return await api.GetObj(id); - }; - + const route = useRoute(); + // 页面打开后获取列表数据 onMounted(async () => { + await useFsAsync({ crudBinding, crudRef, crudExpose, context, createCrudOptions }); + await crudExpose.doRefresh(); + + const id: any = route.query.id; + if (id) { + //编辑表单 + formOptions.value = crudBinding.value.editForm; + } else { + formOptions.value = crudBinding.value.addForm; + } + const doSubmit = formOptions.value.doSubmit; + + formOptions.value.doSubmit = (context: any) => { + utils.logger.log("submit", context); + doSubmit(context); + //提交成功后,关闭本页面 + message.success("保存成功"); + pageStore.close({ tagName: route.fullPath }); + }; + if (id) { //远程获取记录详情 const detail = await getDetail(id); @@ -67,6 +58,10 @@ export default defineComponent({ } }); + const getDetail = async (id: any) => { + return await api.GetObj(id); + }; + return { crudBinding, crudRef, From 43961c1c18b4625a19ad68cf4edb996d46d5760a Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Mon, 2 Dec 2024 19:26:32 +0000 Subject: [PATCH 24/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=203=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf: rowHandle按钮支持render,删除按钮提供popcomfirm风格示例 perf: table-select open支持context参数 --- packages/ui/certd-client/package.json | 2 +- .../src/views/crud/row-handle/tooltip/crud.tsx | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index 14fb5afc..363059b5 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -19,7 +19,7 @@ "circle:check": "pnpm dependency-cruise --validate --output-type err-html -f dependency-report.html src", "afterPubPush": "git add . && git commit -m \"build: publish success\" && git push" }, - "author": "Greper", + "author": "greper", "license": "MIT", "dependencies": { "@ant-design/colors": "^7.0.2", diff --git a/packages/ui/certd-client/src/views/crud/row-handle/tooltip/crud.tsx b/packages/ui/certd-client/src/views/crud/row-handle/tooltip/crud.tsx index 02d989cd..fb6e4e5e 100644 --- a/packages/ui/certd-client/src/views/crud/row-handle/tooltip/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/row-handle/tooltip/crud.tsx @@ -1,5 +1,5 @@ import * as api from "./api"; -import {dict, utils} from "@fast-crud/fast-crud"; +import { dict, utils } from "@fast-crud/fast-crud"; import { ref } from "vue"; import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; export default async function ({ crudExpose }: CreateCrudOptionsProps): Promise { @@ -42,8 +42,16 @@ export default async function ({ crudExpose }: CreateCrudOptionsProps): Promise< } }, remove: { - tooltip: { - title: "删除" + render(scope: any) { + function confirm() { + const { row, index } = scope; + crudExpose.doRemove({ row, index }, { noConfirm: true }); + } + return ( + + 删除 + + ); } }, custom: { From 844c4bf98363b0c69dbb4f2cf0ed3be75afb45a5 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Tue, 3 Dec 2024 19:26:18 +0000 Subject: [PATCH 25/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=203=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build: publish success fix: 修复表单全屏的bug --- packages/ui/certd-client/CHANGELOG.md | 11 +++++++++++ packages/ui/certd-client/package.json | 10 +++++----- .../src/views/crud/basis/compute/crud.tsx | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 9dc87316..ea7e4c0e 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.23.4](https://github.com/fast-crud/fast-crud/compare/v1.23.3...v1.23.4) (2024-12-03) + +### Bug Fixes + +* 修复表单全屏的bug ([a25cff7](https://github.com/fast-crud/fast-crud/commit/a25cff725bef9d0dac063f7bd653844231c57b8d)) + +### Performance Improvements + +* rowHandle按钮支持render,删除按钮提供popcomfirm风格示例 ([b834db9](https://github.com/fast-crud/fast-crud/commit/b834db96e46e6b281d5c3a178a57c71aadf9bfd0)) +* table-select open支持context参数 ([492ee98](https://github.com/fast-crud/fast-crud/commit/492ee9862eee80ffcef81f42178a33484102213a)) + ## [1.23.3](https://github.com/fast-crud/fast-crud/compare/v1.23.2...v1.23.3) (2024-11-26) ### Bug Fixes diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index 363059b5..28bed6b2 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.23.3", + "version": "1.23.4", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.23.3", - "@fast-crud/fast-extends": "^1.23.3", - "@fast-crud/ui-antdv4": "^1.23.3", - "@fast-crud/ui-interface": "^1.23.3", + "@fast-crud/fast-crud": "^1.23.4", + "@fast-crud/fast-extends": "^1.23.4", + "@fast-crud/ui-antdv4": "^1.23.4", + "@fast-crud/ui-interface": "^1.23.4", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.1.2", diff --git a/packages/ui/certd-client/src/views/crud/basis/compute/crud.tsx b/packages/ui/certd-client/src/views/crud/basis/compute/crud.tsx index 1848d260..1cc13744 100644 --- a/packages/ui/certd-client/src/views/crud/basis/compute/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/basis/compute/crud.tsx @@ -148,6 +148,7 @@ export default async function ({ crudExpose, context }: CreateCrudOptionsProps): placeholder: "异步计算远程获取options", options: asyncCompute({ async asyncFn(watchValue: any, context: GetContextFn) { + message.info("asyncCompute 获取options"); const url = "/mock/dicts/OpenStatusEnum?remote"; return await requestForMock({ url }); } From ed6a18dae76bf1a606714b5b6466129172011766 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Tue, 24 Dec 2024 19:23:49 +0000 Subject: [PATCH 26/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: 提示优化 --- .../ui/certd-client/src/views/crud/form/nest/crud.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/ui/certd-client/src/views/crud/form/nest/crud.tsx b/packages/ui/certd-client/src/views/crud/form/nest/crud.tsx index d22cf105..b9d2a538 100644 --- a/packages/ui/certd-client/src/views/crud/form/nest/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/form/nest/crud.tsx @@ -33,6 +33,14 @@ export default async function ({ crudExpose }: CreateCrudOptionsProps): Promise< helper: { // position: "label" // helper的展示位置全局配置 // tooltip:{} + }, + group: { + groups: { + profile: { + header: "profile", + columns: ["profile.name", "profile.age", "profile.status"] + } + } } }, columns: { From c504f33b1f8d475920d69fd0015ea5e48145c070 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Sat, 28 Dec 2024 19:23:55 +0000 Subject: [PATCH 27/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=203=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build: publish success chore: --- packages/ui/certd-client/CHANGELOG.md | 8 ++++++++ packages/ui/certd-client/package.json | 10 +++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index ea7e4c0e..36d63434 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.24.1](https://github.com/fast-crud/fast-crud/compare/v1.24.0...v1.24.1) (2024-12-28) + +**Note:** Version bump only for package @fast-crud/fs-admin-antdv4 + +# [1.24.0](https://github.com/fast-crud/fast-crud/compare/v1.23.4...v1.24.0) (2024-12-28) + +**Note:** Version bump only for package @fast-crud/fs-admin-antdv4 + ## [1.23.4](https://github.com/fast-crud/fast-crud/compare/v1.23.3...v1.23.4) (2024-12-03) ### Bug Fixes diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index 28bed6b2..a21e5878 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.23.4", + "version": "1.24.1", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.23.4", - "@fast-crud/fast-extends": "^1.23.4", - "@fast-crud/ui-antdv4": "^1.23.4", - "@fast-crud/ui-interface": "^1.23.4", + "@fast-crud/fast-crud": "^1.24.1", + "@fast-crud/fast-extends": "^1.24.1", + "@fast-crud/ui-antdv4": "^1.24.1", + "@fast-crud/ui-interface": "^1.24.1", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.1.2", From 7f5e89d489a71af49315d064f0e6ea61d272b591 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Tue, 31 Dec 2024 19:23:58 +0000 Subject: [PATCH 28/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=203=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build: publish success chore: --- packages/ui/certd-client/CHANGELOG.md | 4 ++++ packages/ui/certd-client/package.json | 10 +++++----- .../certd-client/src/views/crud/basis/plugin/crud.tsx | 4 +++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 36d63434..8effae8f 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.24.2](https://github.com/fast-crud/fast-crud/compare/v1.24.1...v1.24.2) (2024-12-31) + +**Note:** Version bump only for package @fast-crud/fs-admin-antdv4 + ## [1.24.1](https://github.com/fast-crud/fast-crud/compare/v1.24.0...v1.24.1) (2024-12-28) **Note:** Version bump only for package @fast-crud/fs-admin-antdv4 diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index a21e5878..0b83df93 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.24.1", + "version": "1.24.2", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.24.1", - "@fast-crud/fast-extends": "^1.24.1", - "@fast-crud/ui-antdv4": "^1.24.1", - "@fast-crud/ui-interface": "^1.24.1", + "@fast-crud/fast-crud": "^1.24.2", + "@fast-crud/fast-extends": "^1.24.2", + "@fast-crud/ui-antdv4": "^1.24.2", + "@fast-crud/ui-interface": "^1.24.2", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.1.2", diff --git a/packages/ui/certd-client/src/views/crud/basis/plugin/crud.tsx b/packages/ui/certd-client/src/views/crud/basis/plugin/crud.tsx index 6728a080..682f1c55 100644 --- a/packages/ui/certd-client/src/views/crud/basis/plugin/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/basis/plugin/crud.tsx @@ -36,7 +36,9 @@ export default async function ({ crudExpose, context }: CreateCrudOptionsProps): props: { multiple: true, crossPage: true, - selectedRowKeys, + selectedRowKeys: () => { + return selectedRowKeys; + }, onSelectedChanged(selected) { utils.logger.info("已选择变化:", selected); } From 42ad04cabd32179bd8c8fa2d3a26f9c7173956ba Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Thu, 9 Jan 2025 19:24:07 +0000 Subject: [PATCH 29/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf: 支持图标选择器 --- .../views/crud/advanced/many-columns/api.ts | 43 ++ .../views/crud/advanced/many-columns/crud.tsx | 679 ++++++++++++++++++ .../crud/advanced/many-columns/index.vue | 31 + .../views/crud/advanced/many-columns/mock.ts | 144 ++++ .../src/views/crud/component/icon/crud.tsx | 5 + 5 files changed, 902 insertions(+) create mode 100644 packages/ui/certd-client/src/views/crud/advanced/many-columns/api.ts create mode 100644 packages/ui/certd-client/src/views/crud/advanced/many-columns/crud.tsx create mode 100644 packages/ui/certd-client/src/views/crud/advanced/many-columns/index.vue create mode 100644 packages/ui/certd-client/src/views/crud/advanced/many-columns/mock.ts diff --git a/packages/ui/certd-client/src/views/crud/advanced/many-columns/api.ts b/packages/ui/certd-client/src/views/crud/advanced/many-columns/api.ts new file mode 100644 index 00000000..dcd30e8b --- /dev/null +++ b/packages/ui/certd-client/src/views/crud/advanced/many-columns/api.ts @@ -0,0 +1,43 @@ +import { requestForMock } from "/src/api/service"; + +const request = requestForMock; +const apiPrefix = "/mock/AdvancedManyColumns"; +export function GetList(query: any) { + return request({ + url: apiPrefix + "/page", + method: "get", + data: query + }); +} + +export function AddObj(obj: any) { + return request({ + url: apiPrefix + "/add", + method: "post", + data: obj + }); +} + +export function UpdateObj(obj: any) { + return request({ + url: apiPrefix + "/update", + method: "post", + data: obj + }); +} + +export function DelObj(id: any) { + return request({ + url: apiPrefix + "/delete", + method: "post", + params: { id } + }); +} + +export function GetObj(id: any) { + return request({ + url: apiPrefix + "/get", + method: "get", + params: { id } + }); +} diff --git a/packages/ui/certd-client/src/views/crud/advanced/many-columns/crud.tsx b/packages/ui/certd-client/src/views/crud/advanced/many-columns/crud.tsx new file mode 100644 index 00000000..3f10b886 --- /dev/null +++ b/packages/ui/certd-client/src/views/crud/advanced/many-columns/crud.tsx @@ -0,0 +1,679 @@ +import * as api from "./api"; +import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; +import { ref } from "vue"; + +export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { + const pageRequest = async (query: UserPageQuery): Promise => { + return await api.GetList(query); + }; + const editRequest = async ({ form, row }: EditReq) => { + if (form.id == null) { + form.id = row.id; + } + return await api.UpdateObj(form); + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; + + const addRequest = async ({ form }: AddReq) => { + return await api.AddObj(form); + }; + const selectedRowKeys = ref([]); + context.selectedRowKeys = selectedRowKeys; + + return { + output: {}, + crudOptions: { + settings: { + plugins: { + //这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并 + rowSelection: { + enabled: true, + order: -2, + before: true, + // handle: (pluginProps,useCrudProps)=>CrudOptions, + props: { + multiple: true, + crossPage: true, + selectionFixed: "left", + selectedRowKeys, + onSelectedChanged(selected) { + console.log("已选择变化:", selected); + } + } + } + } + }, + request: { + pageRequest, + addRequest, + editRequest, + delRequest + }, + table: { + editable: { + //是否启用编辑 + enabled: false, + //模式,free 自由编辑,row:行编辑,cell:单元格编辑 + mode: "cell", //"free" | "row" | "cell"; + /** + * 是否排他式激活,激活一个,关闭其他 + */ + exclusive: true, + /** + * 排他式激活关闭其他编辑时的效果,是取消还是保存 + */ + exclusiveEffect: "cancel", // "cancel" | "save";, + updateCell() { + console.log("updateCell"); + } + } + }, + pagination: { + pageSize: 100 + }, + rowHandle: { + fixed: "right", + width: 300 + }, + columns: { + id: { + title: "ID", + type: "number", + column: { + width: 50 + }, + form: { + show: false + } + }, + text: { + title: "文本", + type: "text", + search: { show: true } + }, + dict1: { + title: "字典1", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict1" + }) + }, + dict2: { + title: "字典2", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict2" + }) + }, + dict3: { + title: "字典3", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict3" + }) + }, + dict4: { + title: "字典4", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict4" + }) + }, + dict5: { + title: "字典5", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict5" + }) + }, + dict6: { + title: "字典6", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict6" + }) + }, + dict7: { + title: "字典7", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict7" + }) + }, + dict8: { + title: "字典8", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict8" + }) + }, + dict9: { + title: "字典9", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict9" + }) + }, + dict10: { + title: "字典10", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict10" + }) + }, + text1: { + title: "文本", + type: "text" + }, + text2: { + title: "文本", + type: "text" + }, + text3: { + title: "文本", + type: "text" + }, + text4: { + title: "文本", + type: "text" + }, + text5: { + title: "文本", + type: "text" + }, + text6: { + title: "文本", + type: "text" + }, + text7: { + title: "文本", + type: "text" + }, + text8: { + title: "文本", + type: "text" + }, + text9: { + title: "文本", + type: "text" + }, + text10: { + title: "文本", + type: "text" + }, + text11: { + title: "文本", + type: "text" + }, + text12: { + title: "文本", + type: "text" + }, + text13: { + title: "文本", + type: "text" + }, + text14: { + title: "文本", + type: "text" + }, + text15: { + title: "文本", + type: "text" + }, + text16: { + title: "文本", + type: "text" + }, + text17: { + title: "文本", + type: "text" + }, + text18: { + title: "文本", + type: "text" + }, + text19: { + title: "文本", + type: "text" + }, + text20: { + title: "文本", + type: "text" + }, + text21: { + title: "文本", + type: "text" + }, + text22: { + title: "文本", + type: "text" + }, + text23: { + title: "文本", + type: "text" + }, + text24: { + title: "文本", + type: "text" + }, + text25: { + title: "文本", + type: "text" + }, + text26: { + title: "文本", + type: "text" + }, + text27: { + title: "文本", + type: "text" + }, + text28: { + title: "文本", + type: "text" + }, + text29: { + title: "文本", + type: "text" + }, + text30: { + title: "文本", + type: "text" + }, + text31: { + title: "文本", + type: "text" + }, + text32: { + title: "文本", + type: "text" + }, + text33: { + title: "文本", + type: "text" + }, + text34: { + title: "文本", + type: "text" + }, + text35: { + title: "文本", + type: "text" + }, + text36: { + title: "文本", + type: "text" + }, + text37: { + title: "文本", + type: "text" + }, + text38: { + title: "文本", + type: "text" + }, + text39: { + title: "文本", + type: "text" + }, + text40: { + title: "文本", + type: "text" + }, + dict11: { + title: "字典1", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict1" + }) + }, + dict12: { + title: "字典2", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict2" + }) + }, + dict13: { + title: "字典3", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict3" + }) + }, + dict14: { + title: "字典4", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict4" + }) + }, + dict15: { + title: "字典5", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict5" + }) + }, + dict16: { + title: "字典6", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict6" + }) + }, + dict17: { + title: "字典7", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict7" + }) + }, + dict18: { + title: "字典8", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict8" + }) + }, + dict19: { + title: "字典9", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict9" + }) + }, + dict110: { + title: "字典10", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict10" + }) + }, + dict21: { + title: "字典1", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict1" + }) + }, + dict22: { + title: "字典2", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict2" + }) + }, + dict23: { + title: "字典3", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict3" + }) + }, + dict24: { + title: "字典4", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict4" + }) + }, + dict25: { + title: "字典5", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict5" + }) + }, + dict26: { + title: "字典6", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict6" + }) + }, + dict27: { + title: "字典7", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict7" + }) + }, + dict28: { + title: "字典8", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict8" + }) + }, + dict29: { + title: "字典9", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict9" + }) + }, + dict210: { + title: "字典10", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict10" + }) + }, + dict31: { + title: "字典1", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict1" + }) + }, + dict32: { + title: "字典2", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict3" + }) + }, + dict33: { + title: "字典3", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict3" + }) + }, + dict34: { + title: "字典4", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict4" + }) + }, + dict35: { + title: "字典5", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict5" + }) + }, + dict36: { + title: "字典6", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict6" + }) + }, + dict37: { + title: "字典7", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict7" + }) + }, + dict38: { + title: "字典8", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict8" + }) + }, + dict39: { + title: "字典9", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict9" + }) + }, + dict310: { + title: "字典10", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict10" + }) + }, + dict41: { + title: "字典1", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict1" + }) + }, + dict42: { + title: "字典2", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict4" + }) + }, + dict43: { + title: "字典3", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict4" + }) + }, + dict44: { + title: "字典4", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict4" + }) + }, + dict45: { + title: "字典5", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict5" + }) + }, + dict46: { + title: "字典6", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict6" + }) + }, + dict47: { + title: "字典7", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict7" + }) + }, + dict48: { + title: "字典8", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict8" + }) + }, + dict49: { + title: "字典9", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict9" + }) + }, + dict410: { + title: "字典10", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict10" + }) + }, + dict51: { + title: "字典1", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict1" + }) + }, + dict52: { + title: "字典2", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict5" + }) + }, + dict53: { + title: "字典3", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict5" + }) + }, + dict54: { + title: "字典4", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict5" + }) + }, + dict55: { + title: "字典5", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict5" + }) + }, + dict56: { + title: "字典6", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict6" + }) + }, + dict57: { + title: "字典7", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict7" + }) + }, + dict58: { + title: "字典8", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict8" + }) + }, + dict59: { + title: "字典9", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict9" + }) + }, + dict510: { + title: "字典10", + type: "dict-select", + dict: dict({ + url: "/mock/dicts/ManyOpenStatusEnum?from=dict10" + }) + } + } + } + }; +} diff --git a/packages/ui/certd-client/src/views/crud/advanced/many-columns/index.vue b/packages/ui/certd-client/src/views/crud/advanced/many-columns/index.vue new file mode 100644 index 00000000..dc28bea5 --- /dev/null +++ b/packages/ui/certd-client/src/views/crud/advanced/many-columns/index.vue @@ -0,0 +1,31 @@ + + + diff --git a/packages/ui/certd-client/src/views/crud/advanced/many-columns/mock.ts b/packages/ui/certd-client/src/views/crud/advanced/many-columns/mock.ts new file mode 100644 index 00000000..cde3052a --- /dev/null +++ b/packages/ui/certd-client/src/views/crud/advanced/many-columns/mock.ts @@ -0,0 +1,144 @@ +// @ts-ignore +import mockUtil from "/src/mock/base"; +const options: any = { + name: "AdvancedManyColumns", + idGenerator: 0, + //此处copy多次,模拟大量数据 + copyTimes: 1000 +}; +const list = [ + { + text: "测试文本", + dict1: "1", + dict2: "1", + dict3: "2", + dict4: "1", + dict5: "2", + dict6: "1", + dict7: "1", + dict8: "1", + text1: "测试文本1", + text2: "测试文本2", + text3: "测试文本3", + text4: "测试文本4", + text5: "测试文本5", + text6: "测试文本6", + text7: "测试文本7", + text8: "测试文本8", + dict9: "2", + dict10: "1", + dict11: "2", + dict12: "1" + }, + { + text: "测试文本", + dict1: "1", + dict2: "1", + dict3: "2", + dict4: "1", + dict5: "2", + dict6: "1", + dict7: "1", + dict8: "1", + text1: "文本1", + text2: "文本2", + text3: "文本3", + text4: "文本4", + text5: "文本5", + text6: "文本6", + text7: "文本7", + text8: "文本8", + text11: "文本1", + text12: "文本2", + text13: "文本3", + text14: "文本4", + text15: "文本5", + text16: "文本6", + text17: "文本7", + text18: "文本8", + text21: "文本1", + text22: "文本2", + text23: "文本3", + text24: "文本4", + text25: "文本5", + text26: "文本6", + text27: "文本7", + text28: "文本8", + dict9: "2", + dict10: "1", + dict11: "2", + dict12: "1" + }, + { + text: "测试文本", + dict1: "1", + dict2: "1", + dict3: "2", + dict4: "1", + dict5: "2", + dict6: "1", + dict7: "1", + dict8: "1", + text1: "测试文本1", + text2: "测试文本2", + text3: "测试文本3", + text4: "测试文本4", + text5: "测试文本5", + text6: "测试文本6", + text7: "测试文本7", + text8: "测试文本8", + dict9: "2", + dict10: "1", + dict11: "2", + dict12: "1" + }, + { + text: "测试文本", + dict1: "1", + dict2: "1", + dict3: "2", + dict4: "1", + dict5: "2", + dict6: "1", + dict7: "1", + dict8: "1", + text1: "测试文本1", + text2: "测试文本2", + text3: "测试文本3", + text4: "测试文本4", + text5: "测试文本5", + text6: "测试文本6", + text7: "测试文本7", + text8: "测试文本8", + dict9: "2", + dict10: "1", + dict11: "2", + dict12: "1" + }, + { + text: "测试文本", + dict1: "1", + dict2: "1", + dict3: "2", + dict4: "1", + dict5: "2", + dict6: "1", + dict7: "1", + dict8: "1", + text1: "测试文本1", + text2: "测试文本2", + text3: "测试文本3", + text4: "测试文本4", + text5: "测试文本5", + text6: "测试文本6", + text7: "测试文本7", + text8: "测试文本8", + dict9: "2", + dict10: "1", + dict11: "2", + dict12: "1" + } +]; +options.list = list; +const mock = mockUtil.buildMock(options); +export default mock; diff --git a/packages/ui/certd-client/src/views/crud/component/icon/crud.tsx b/packages/ui/certd-client/src/views/crud/component/icon/crud.tsx index 9fd33970..a9f28865 100644 --- a/packages/ui/certd-client/src/views/crud/component/icon/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/component/icon/crud.tsx @@ -72,6 +72,11 @@ export default async function ({ crudExpose }: CreateCrudOptionsProps): Promise< style: "font-size:18px" } } + }, + selector: { + title: "图标选择器", + search: { show: true }, + type: "icon" } } } From e70732c9ac1662beff8b5c1d097069b96cf77728 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Sun, 12 Jan 2025 19:23:54 +0000 Subject: [PATCH 30/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build: publish success --- packages/ui/certd-client/CHANGELOG.md | 6 ++++++ packages/ui/certd-client/package.json | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 8effae8f..8c9bbd0e 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.25.0](https://github.com/fast-crud/fast-crud/compare/v1.24.2...v1.25.0) (2025-01-12) + +### Performance Improvements + +* 支持图标选择器 ([7dd8745](https://github.com/fast-crud/fast-crud/commit/7dd874534caa926ba63d6b8100116c032d794d51)) + ## [1.24.2](https://github.com/fast-crud/fast-crud/compare/v1.24.1...v1.24.2) (2024-12-31) **Note:** Version bump only for package @fast-crud/fs-admin-antdv4 diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index 0b83df93..ec3f0752 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.24.2", + "version": "1.25.0", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.24.2", - "@fast-crud/fast-extends": "^1.24.2", - "@fast-crud/ui-antdv4": "^1.24.2", - "@fast-crud/ui-interface": "^1.24.2", + "@fast-crud/fast-crud": "^1.25.0", + "@fast-crud/fast-extends": "^1.25.0", + "@fast-crud/ui-antdv4": "^1.25.0", + "@fast-crud/ui-interface": "^1.25.0", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.1.2", From fe4367c58042924a7145e71d53bd1f5f2085a48f Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Fri, 24 Jan 2025 19:24:01 +0000 Subject: [PATCH 31/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: --- packages/ui/certd-client/src/plugin/fast-crud/index.tsx | 4 +++- .../src/views/crud/component/uploader/form/crud.tsx | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx index e5817613..9bec0786 100644 --- a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx +++ b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx @@ -277,7 +277,9 @@ function install(app: any, options: any = {}) { action: "http://www.docmirror.cn:7070/api/upload/form/upload", name: "file", withCredentials: false, - uploadRequest: async ({ action, file, onProgress }: any) => { + uploadRequest: async (opts: any) => { + console.log("uploadRequest:", opts); + const { action, file, onProgress } = opts; // @ts-ignore const data = new FormData(); data.append("file", file); diff --git a/packages/ui/certd-client/src/views/crud/component/uploader/form/crud.tsx b/packages/ui/certd-client/src/views/crud/component/uploader/form/crud.tsx index 244ee033..84475be4 100644 --- a/packages/ui/certd-client/src/views/crud/component/uploader/form/crud.tsx +++ b/packages/ui/certd-client/src/views/crud/component/uploader/form/crud.tsx @@ -61,6 +61,8 @@ export default async function ({ crudExpose }: CreateCrudOptionsProps): Promise< uploader: { type: "form", keepName: true, + test: 111, + custom: { aaa: 111 }, successHandle(res: any) { //这里我的后台返回res是一个key 字符串 //此方法需要返回的数据结构为 {key:"string",url:"string"...} From 2eebb3388a1565426048c29cfffc41d9d09f4b27 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Wed, 12 Feb 2025 19:24:12 +0000 Subject: [PATCH 32/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: --- packages/ui/certd-client/CHANGELOG.md | 4 ++++ packages/ui/certd-client/package.json | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 8c9bbd0e..769510f1 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.25.1](https://github.com/fast-crud/fast-crud/compare/v1.25.0...v1.25.1) (2025-02-12) + +**Note:** Version bump only for package @fast-crud/fs-admin-antdv4 + # [1.25.0](https://github.com/fast-crud/fast-crud/compare/v1.24.2...v1.25.0) (2025-01-12) ### Performance Improvements diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index ec3f0752..e19c7ad0 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.25.0", + "version": "1.25.1", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.25.0", - "@fast-crud/fast-extends": "^1.25.0", - "@fast-crud/ui-antdv4": "^1.25.0", - "@fast-crud/ui-interface": "^1.25.0", + "@fast-crud/fast-crud": "^1.25.1", + "@fast-crud/fast-extends": "^1.25.1", + "@fast-crud/ui-antdv4": "^1.25.1", + "@fast-crud/ui-interface": "^1.25.1", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.1.2", From 558fc9f30600ab65ec587cbed8b563b4a7e3d529 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Thu, 20 Feb 2025 19:24:20 +0000 Subject: [PATCH 33/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: 修复4.2.x版本antdv导致modal全屏无效的bug --- packages/ui/certd-client/package.json | 2 +- packages/ui/certd-client/src/plugin/fast-crud/index.tsx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index e19c7ad0..ff7bf2b3 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -32,7 +32,7 @@ "@fast-crud/ui-interface": "^1.25.1", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", - "ant-design-vue": "^4.1.2", + "ant-design-vue": "^4.2.6", "axios": "^1.6.8", "axios-mock-adapter": "^1.22.0", "base64-js": "^1.5.1", diff --git a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx index 9bec0786..04e5aff8 100644 --- a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx +++ b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx @@ -277,6 +277,8 @@ function install(app: any, options: any = {}) { action: "http://www.docmirror.cn:7070/api/upload/form/upload", name: "file", withCredentials: false, + test: 22, + custom: { aaa: 22 }, uploadRequest: async (opts: any) => { console.log("uploadRequest:", opts); const { action, file, onProgress } = opts; From d442462952caf8ad9b953620cebfd1ee6a1b0e2c Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Sat, 22 Feb 2025 19:23:46 +0000 Subject: [PATCH 34/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build: publish success --- packages/ui/certd-client/CHANGELOG.md | 6 ++++++ packages/ui/certd-client/package.json | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index 769510f1..af2340b3 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.25.2](https://github.com/fast-crud/fast-crud/compare/v1.25.1...v1.25.2) (2025-02-22) + +### Bug Fixes + +* 修复4.2.x版本antdv导致modal全屏无效的bug ([9a26363](https://github.com/fast-crud/fast-crud/commit/9a26363d44faf6b0eb0809be4a8dd0fd14f2c309)) + ## [1.25.1](https://github.com/fast-crud/fast-crud/compare/v1.25.0...v1.25.1) (2025-02-12) **Note:** Version bump only for package @fast-crud/fs-admin-antdv4 diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index ff7bf2b3..a779e0e3 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.25.1", + "version": "1.25.2", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.25.1", - "@fast-crud/fast-extends": "^1.25.1", - "@fast-crud/ui-antdv4": "^1.25.1", - "@fast-crud/ui-interface": "^1.25.1", + "@fast-crud/fast-crud": "^1.25.2", + "@fast-crud/fast-extends": "^1.25.2", + "@fast-crud/ui-antdv4": "^1.25.2", + "@fast-crud/ui-interface": "^1.25.2", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.2.6", From de26ee93835513bc7c28b2a0c7300478b101111e Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Sun, 23 Feb 2025 19:23:42 +0000 Subject: [PATCH 35/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=202=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build: publish success --- packages/ui/certd-client/CHANGELOG.md | 4 ++++ packages/ui/certd-client/package.json | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/ui/certd-client/CHANGELOG.md b/packages/ui/certd-client/CHANGELOG.md index af2340b3..ad58182b 100644 --- a/packages/ui/certd-client/CHANGELOG.md +++ b/packages/ui/certd-client/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.25.3](https://github.com/fast-crud/fast-crud/compare/v1.25.2...v1.25.3) (2025-02-23) + +**Note:** Version bump only for package @fast-crud/fs-admin-antdv4 + ## [1.25.2](https://github.com/fast-crud/fast-crud/compare/v1.25.1...v1.25.2) (2025-02-22) ### Bug Fixes diff --git a/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index a779e0e3..4a03ba85 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -1,6 +1,6 @@ { "name": "@fast-crud/fs-admin-antdv4", - "version": "1.25.2", + "version": "1.25.3", "private": true, "scripts": { "dev": "vite", @@ -26,10 +26,10 @@ "@ant-design/icons-vue": "^7.0.1", "@aws-sdk/client-s3": "^3.535.0", "@aws-sdk/s3-request-presigner": "^3.535.0", - "@fast-crud/fast-crud": "^1.25.2", - "@fast-crud/fast-extends": "^1.25.2", - "@fast-crud/ui-antdv4": "^1.25.2", - "@fast-crud/ui-interface": "^1.25.2", + "@fast-crud/fast-crud": "^1.25.3", + "@fast-crud/fast-extends": "^1.25.3", + "@fast-crud/ui-antdv4": "^1.25.3", + "@fast-crud/ui-interface": "^1.25.3", "@iconify/vue": "^4.1.1", "@soerenmartius/vue3-clipboard": "^0.1.2", "ant-design-vue": "^4.2.6", From 335d175d57f677e14cdbc7c19558acbccd0527f7 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot Date: Mon, 3 Mar 2025 19:24:51 +0000 Subject: [PATCH 36/38] =?UTF-8?q?=F0=9F=94=B1:=20[client]=20sync=20upgrade?= =?UTF-8?q?=20with=207=20commits=20[trident-sync]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: Merge branch 'vben' # Conflicts: # package.json perf: antdv示例改成使用vben框架 chore: vben chore: vben chore: vben --- packages/ui/certd-client/.env | 1 + .../build/tailwind-config/index.mjs | 254 ++++ .../build/tailwind-config/plugins/entry.mjs | 53 + .../build/tailwind-config/postcss.config.mjs | 15 + packages/ui/certd-client/package.json | 35 +- packages/ui/certd-client/postcss.config.mjs | 15 + packages/ui/certd-client/src/App.vue | 97 +- .../certd-client/src/api/modules/api.user.ts | 1 + .../certd-client/src/layout/layout-basic.vue | 47 + .../src/layout/layout-outside.vue | 2 + packages/ui/certd-client/src/main.ts | 44 +- .../src/plugin/fast-crud/index.tsx | 12 + .../src/plugin/permission/hook.ts | 12 +- .../src/plugin/permission/store.permission.ts | 7 +- packages/ui/certd-client/src/router/access.ts | 35 + packages/ui/certd-client/src/router/guard.ts | 109 ++ packages/ui/certd-client/src/router/index.ts | 127 +- .../ui/certd-client/src/router/resolve.ts | 1 - .../src/router/source/framework.ts | 32 +- .../src/router/source/modules/crud.ts | 3 + .../src/router/source/modules/integration.ts | 5 + .../src/router/source/modules/sys.ts | 4 +- .../src/router/source/modules/ui.ts | 4 + .../ui/certd-client/src/store/modules/page.ts | 436 ------- .../src/store/modules/resource.ts | 130 -- .../src/store/modules/settings.ts | 81 -- .../ui/certd-client/src/store/modules/user.ts | 8 +- .../ui/certd-client/src/style/antdv4.less | 19 + .../ui/certd-client/src/style/common.less | 6 +- .../src/vben/access/access-control.vue | 47 + .../src/vben/access/accessible.ts | 84 ++ .../certd-client/src/vben/access/directive.ts | 42 + .../ui/certd-client/src/vben/access/index.ts | 4 + .../src/vben/access/use-access.ts | 52 + .../api-component/api-component.vue | 200 +++ .../components/api-component/index.ts | 1 + .../captcha/hooks/useCaptchaPoints.ts | 19 + .../common-ui/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/components/captcha/types.ts | 175 +++ .../components/col-page/col-page.vue | 107 ++ .../common-ui/components/col-page/index.ts | 2 + .../common-ui/components/col-page/types.ts | 26 + .../components/count-to/count-to.vue | 123 ++ .../common-ui/components/count-to/index.ts | 2 + .../common-ui/components/count-to/types.ts | 53 + .../ellipsis-text/ellipsis-text.vue | 148 +++ .../components/ellipsis-text/index.ts | 1 + .../components/icon-picker/icon-picker.vue | 304 +++++ .../common-ui/components/icon-picker/icons.ts | 56 + .../common-ui/components/icon-picker/index.ts | 1 + .../src/vben/common-ui/components/index.ts | 27 + .../common-ui/components/json-viewer/index.ts | 3 + .../components/json-viewer/index.vue | 98 ++ .../components/json-viewer/style.scss | 98 ++ .../common-ui/components/json-viewer/types.ts | 44 + .../common-ui/components/loading/directive.ts | 132 ++ .../common-ui/components/loading/index.ts | 3 + .../common-ui/components/loading/loading.vue | 39 + .../common-ui/components/loading/spinner.vue | 28 + .../components/page/__tests__/page.test.ts | 89 ++ .../vben/common-ui/components/page/index.ts | 2 + .../vben/common-ui/components/page/page.vue | 105 ++ .../vben/common-ui/components/page/types.ts | 11 + .../vben/common-ui/components/resize/index.ts | 1 + .../common-ui/components/resize/resize.vue | 1122 +++++++++++++++++ .../common-ui/components/tippy/directive.ts | 100 ++ .../vben/common-ui/components/tippy/index.ts | 67 + .../certd-client/src/vben/common-ui/index.ts | 2 + .../src/vben/common-ui/ui/about/about.ts | 14 + .../src/vben/common-ui/ui/about/about.vue | 183 +++ .../src/vben/common-ui/ui/about/index.ts | 1 + .../ui/authentication/auth-title.vue | 13 + .../ui/authentication/code-login.vue | 117 ++ .../ui/authentication/forget-password.vue | 116 ++ .../vben/common-ui/ui/authentication/index.ts | 7 + .../ui/authentication/login-expired-modal.vue | 79 ++ .../common-ui/ui/authentication/login.vue | 186 +++ .../ui/authentication/qrcode-login.vue | 95 ++ .../common-ui/ui/authentication/register.vue | 121 ++ .../ui/authentication/third-party-login.vue | 37 + .../vben/common-ui/ui/authentication/types.ts | 70 + .../analysis/analysis-chart-card.vue | 24 + .../analysis/analysis-charts-tabs.vue | 40 + .../dashboard/analysis/analysis-overview.vue | 55 + .../common-ui/ui/dashboard/analysis/index.ts | 3 + .../src/vben/common-ui/ui/dashboard/index.ts | 3 + .../src/vben/common-ui/ui/dashboard/typing.ts | 48 + .../common-ui/ui/dashboard/workbench/index.ts | 5 + .../dashboard/workbench/workbench-header.vue | 46 + .../dashboard/workbench/workbench-project.vue | 63 + .../workbench/workbench-quick-nav.vue | 54 + .../ui/dashboard/workbench/workbench-todo.vue | 63 + .../dashboard/workbench/workbench-trends.vue | 64 + .../vben/common-ui/ui/fallback/fallback.ts | 25 + .../vben/common-ui/ui/fallback/fallback.vue | 164 +++ .../common-ui/ui/fallback/icons/icon-403.vue | 151 +++ .../common-ui/ui/fallback/icons/icon-404.vue | 154 +++ .../common-ui/ui/fallback/icons/icon-500.vue | 215 ++++ .../ui/fallback/icons/icon-coming-soon.vue | 262 ++++ .../ui/fallback/icons/icon-offline.vue | 112 ++ .../common-ui/ui/fallback/icons/warning.svg | 1 + .../src/vben/common-ui/ui/fallback/index.ts | 2 + .../src/vben/common-ui/ui/index.ts | 4 + .../__tests__/use-sortable.test.ts | 48 + .../src/vben/composables/index.ts | 8 + .../src/vben/composables/use-is-mobile.ts | 7 + .../src/vben/composables/use-layout-style.ts | 79 ++ .../src/vben/composables/use-namespace.ts | 88 ++ .../vben/composables/use-priority-value.ts | 71 ++ .../src/vben/composables/use-scroll-lock.ts | 46 + .../composables/use-simple-locale/README.md | 3 + .../composables/use-simple-locale/index.ts | 27 + .../composables/use-simple-locale/messages.ts | 22 + .../src/vben/composables/use-sortable.ts | 26 + .../certd-client/src/vben/constants/core.ts | 28 + .../src/vben/constants/globals.ts | 16 + .../certd-client/src/vben/constants/index.ts | 3 + .../certd-client/src/vben/constants/vben.ts | 25 + .../src/vben/design/css/global.css | 160 +++ .../src/vben/design/css/nprogress.css | 59 + .../src/vben/design/css/transition.css | 236 ++++ .../certd-client/src/vben/design/css/ui.css | 87 ++ .../src/vben/design/design-tokens/dark.css | 446 +++++++ .../src/vben/design/design-tokens/default.css | 382 ++++++ .../src/vben/design/design-tokens/index.ts | 4 + .../ui/certd-client/src/vben/design/index.ts | 8 + .../src/vben/design/scss-bem/bem.scss | 34 + .../src/vben/design/scss-bem/constants.scss | 5 + .../vben/form-ui/components/form-actions.vue | 126 ++ .../certd-client/src/vben/form-ui/config.ts | 65 + .../certd-client/src/vben/form-ui/form-api.ts | 361 ++++++ .../src/vben/form-ui/form-render/context.ts | 21 + .../vben/form-ui/form-render/dependencies.ts | 110 ++ .../vben/form-ui/form-render/expandable.ts | 90 ++ .../vben/form-ui/form-render/form-field.vue | 366 ++++++ .../vben/form-ui/form-render/form-label.vue | 31 + .../src/vben/form-ui/form-render/form.vue | 146 +++ .../src/vben/form-ui/form-render/helper.ts | 60 + .../src/vben/form-ui/form-render/index.ts | 3 + .../ui/certd-client/src/vben/form-ui/index.ts | 7 + .../ui/certd-client/src/vben/form-ui/types.ts | 343 +++++ .../src/vben/form-ui/use-form-context.ts | 60 + .../src/vben/form-ui/use-vben-form.ts | 43 + .../src/vben/form-ui/vben-form.vue | 58 + .../src/vben/form-ui/vben-use-form.vue | 96 ++ .../ui/certd-client/src/vben/hooks/index.ts | 9 + .../src/vben/hooks/use-app-config.ts | 15 + .../src/vben/hooks/use-content-maximize.ts | 24 + .../src/vben/hooks/use-design-tokens.ts | 253 ++++ .../src/vben/hooks/use-hover-toggle.ts | 65 + .../src/vben/hooks/use-pagination.ts | 53 + .../src/vben/hooks/use-refresh.ts | 16 + .../certd-client/src/vben/hooks/use-tabs.ts | 113 ++ .../src/vben/hooks/use-watermark.ts | 88 ++ .../src/vben/icons/create-icon.ts | 14 + .../ui/certd-client/src/vben/icons/index.ts | 10 + .../ui/certd-client/src/vben/icons/lucide.ts | 64 + packages/ui/certd-client/src/vben/index.ts | 78 ++ .../src/vben/layout-ui/components/index.ts | 5 + .../layout-ui/components/layout-content.vue | 54 + .../layout-ui/components/layout-footer.vue | 41 + .../layout-ui/components/layout-header.vue | 73 ++ .../layout-ui/components/layout-sidebar.vue | 291 +++++ .../layout-ui/components/layout-tabbar.vue | 27 + .../layout-ui/components/widgets/index.ts | 2 + .../widgets/sidebar-collapse-button.vue | 16 + .../widgets/sidebar-fixed-button.vue | 16 + .../src/vben/layout-ui/hooks/use-layout.ts | 43 + .../certd-client/src/vben/layout-ui/index.ts | 2 + .../src/vben/layout-ui/vben-layout.ts | 160 +++ .../src/vben/layout-ui/vben-layout.vue | 498 ++++++++ .../src/vben/layouts/basic/README.md | 7 + .../layouts/basic/content/content-spinner.vue | 12 + .../vben/layouts/basic/content/content.vue | 92 ++ .../src/vben/layouts/basic/content/index.ts | 2 + .../basic/content/use-content-spinner.ts | 50 + .../layouts/basic/copyright/copyright.vue | 38 + .../src/vben/layouts/basic/copyright/index.ts | 1 + .../src/vben/layouts/basic/footer/footer.vue | 11 + .../src/vben/layouts/basic/footer/index.ts | 1 + .../src/vben/layouts/basic/header/header.vue | 164 +++ .../src/vben/layouts/basic/header/index.ts | 1 + .../src/vben/layouts/basic/index.ts | 1 + .../src/vben/layouts/basic/layout.vue | 253 ++++ .../vben/layouts/basic/menu/extra-menu.vue | 32 + .../src/vben/layouts/basic/menu/index.ts | 5 + .../src/vben/layouts/basic/menu/menu.vue | 44 + .../vben/layouts/basic/menu/mixed-menu.vue | 36 + .../vben/layouts/basic/menu/use-extra-menu.ts | 113 ++ .../vben/layouts/basic/menu/use-mixed-menu.ts | 180 +++ .../vben/layouts/basic/menu/use-navigation.ts | 35 + .../src/vben/layouts/basic/tabbar/index.ts | 2 + .../src/vben/layouts/basic/tabbar/tabbar.vue | 64 + .../vben/layouts/basic/tabbar/use-tabbar.ts | 181 +++ .../layouts/iframe/iframe-router-view.vue | 72 ++ .../src/vben/layouts/iframe/iframe-view.vue | 3 + .../src/vben/layouts/iframe/index.ts | 2 + .../ui/certd-client/src/vben/layouts/index.ts | 3 + .../src/vben/layouts/widgets/breadcrumb.vue | 67 + .../widgets/check-updates/check-updates.vue | 127 ++ .../layouts/widgets/check-updates/index.ts | 1 + .../src/vben/layouts/widgets/color-toggle.vue | 46 + .../widgets/global-search/global-search.vue | 137 ++ .../layouts/widgets/global-search/index.ts | 1 + .../widgets/global-search/search-panel.vue | 243 ++++ .../src/vben/layouts/widgets/index.ts | 11 + .../vben/layouts/widgets/language-toggle.vue | 34 + .../vben/layouts/widgets/layout-toggle.vue | 55 + .../vben/layouts/widgets/lock-screen/index.ts | 2 + .../widgets/lock-screen/lock-screen-modal.vue | 89 ++ .../widgets/lock-screen/lock-screen.vue | 131 ++ .../layouts/widgets/notification/index.ts | 3 + .../widgets/notification/notification.vue | 153 +++ .../layouts/widgets/notification/types.ts | 9 + .../widgets/preferences/blocks/block.vue | 22 + .../preferences/blocks/general/animation.vue | 48 + .../preferences/blocks/general/general.vue | 31 + .../widgets/preferences/blocks/index.ts | 19 + .../widgets/preferences/blocks/input-item.vue | 52 + .../preferences/blocks/layout/breadcrumb.vue | 49 + .../preferences/blocks/layout/content.vue | 50 + .../preferences/blocks/layout/copyright.vue | 42 + .../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 | 65 + .../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 | 150 +++ .../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 | 30 + .../preferences/icons/full-content.vue | 24 + .../preferences/icons/header-mixed-nav.vue | 25 + .../widgets/preferences/icons/header-nav.vue | 30 + .../preferences/icons/header-sidebar-nav.vue | 61 + .../widgets/preferences/icons/index.ts | 12 + .../widgets/preferences/icons/mixed-nav.vue | 63 + .../widgets/preferences/icons/setting.vue | 7 + .../preferences/icons/sidebar-mixed-nav.vue | 22 + .../widgets/preferences/icons/sidebar-nav.vue | 26 + .../vben/layouts/widgets/preferences/index.ts | 3 + .../preferences/preferences-button.vue | 20 + .../preferences/preferences-drawer.vue | 323 +++++ .../widgets/preferences/preferences.vue | 67 + .../preferences/use-open-preferences.ts | 16 + .../layouts/widgets/theme-toggle/index.ts | 1 + .../widgets/theme-toggle/theme-button.vue | 157 +++ .../widgets/theme-toggle/theme-toggle.vue | 59 + .../layouts/widgets/user-dropdown/index.ts | 1 + .../widgets/user-dropdown/user-dropdown.vue | 213 ++++ .../ui/certd-client/src/vben/locales/i18n.ts | 128 ++ .../ui/certd-client/src/vben/locales/index.ts | 12 + .../locales/langs/en-US/authentication.json | 56 + .../src/vben/locales/langs/en-US/common.json | 22 + .../vben/locales/langs/en-US/preferences.json | 186 +++ .../src/vben/locales/langs/en-US/ui.json | 104 ++ .../locales/langs/zh-CN/authentication.json | 56 + .../src/vben/locales/langs/zh-CN/common.json | 22 + .../vben/locales/langs/zh-CN/preferences.json | 186 +++ .../src/vben/locales/langs/zh-CN/ui.json | 104 ++ .../certd-client/src/vben/locales/typing.ts | 23 + .../components/collapse-transition.vue | 96 ++ .../src/vben/menu-ui/components/index.ts | 4 + .../menu-ui/components/menu-badge-dot.vue | 19 + .../vben/menu-ui/components/menu-badge.vue | 52 + .../src/vben/menu-ui/components/menu-item.vue | 89 ++ .../src/vben/menu-ui/components/menu.vue | 807 ++++++++++++ .../menu-ui/components/normal-menu/index.ts | 2 + .../components/normal-menu/normal-menu.ts | 27 + .../components/normal-menu/normal-menu.vue | 144 +++ .../menu-ui/components/sub-menu-content.vue | 77 ++ .../src/vben/menu-ui/components/sub-menu.vue | 208 +++ .../src/vben/menu-ui/hooks/index.ts | 2 + .../vben/menu-ui/hooks/use-menu-context.ts | 55 + .../src/vben/menu-ui/hooks/use-menu.ts | 48 + .../ui/certd-client/src/vben/menu-ui/index.ts | 4 + .../ui/certd-client/src/vben/menu-ui/menu.vue | 38 + .../src/vben/menu-ui/sub-menu.vue | 71 ++ .../ui/certd-client/src/vben/menu-ui/types.ts | 139 ++ .../src/vben/menu-ui/utils/index.ts | 52 + .../drawer/__tests__/drawer-api.test.ts | 117 ++ .../src/vben/popup-ui/drawer/drawer-api.ts | 138 ++ .../src/vben/popup-ui/drawer/drawer.ts | 173 +++ .../src/vben/popup-ui/drawer/drawer.vue | 229 ++++ .../src/vben/popup-ui/drawer/index.ts | 3 + .../src/vben/popup-ui/drawer/use-drawer.ts | 117 ++ .../certd-client/src/vben/popup-ui/index.ts | 2 + .../modal/__tests__/modal-api.test.ts | 117 ++ .../src/vben/popup-ui/modal/index.ts | 3 + .../src/vben/popup-ui/modal/modal-api.ts | 183 +++ .../src/vben/popup-ui/modal/modal.ts | 189 +++ .../src/vben/popup-ui/modal/modal.vue | 319 +++++ .../popup-ui/modal/use-modal-draggable.ts | 117 ++ .../src/vben/popup-ui/modal/use-modal.ts | 147 +++ .../src/vben/preferences/config.ts | 120 ++ .../src/vben/preferences/constants.ts | 88 ++ .../src/vben/preferences/index.ts | 35 + .../src/vben/preferences/preferences.ts | 228 ++++ .../src/vben/preferences/types.ts | 292 +++++ .../vben/preferences/update-css-variables.ts | 116 ++ .../src/vben/preferences/use-preferences.ts | 226 ++++ .../shadcn-ui/components/avatar/avatar.vue | 50 + .../vben/shadcn-ui/components/avatar/index.ts | 1 + .../components/back-top/back-top.vue | 43 + .../shadcn-ui/components/back-top/backtop.ts | 38 + .../shadcn-ui/components/back-top/index.ts | 1 + .../components/back-top/use-backtop.ts | 45 + .../breadcrumb/breadcrumb-background.vue | 109 ++ .../components/breadcrumb/breadcrumb-view.vue | 39 + .../components/breadcrumb/breadcrumb.vue | 98 ++ .../shadcn-ui/components/breadcrumb/index.ts | 3 + .../shadcn-ui/components/breadcrumb/types.ts | 17 + .../components/button/button-group.vue | 98 ++ .../shadcn-ui/components/button/button.ts | 42 + .../shadcn-ui/components/button/button.vue | 42 + .../components/button/check-button-group.vue | 146 +++ .../components/button/icon-button.vue | 68 + .../vben/shadcn-ui/components/button/index.ts | 5 + .../components/checkbox/checkbox.vue | 26 + .../shadcn-ui/components/checkbox/index.ts | 1 + .../components/context-menu/context-menu.vue | 97 ++ .../components/context-menu/index.ts | 3 + .../components/context-menu/interface.ts | 38 + .../count-to-animator/count-to-animator.vue | 128 ++ .../components/count-to-animator/index.ts | 1 + .../dropdown-menu/dropdown-menu.vue | 49 + .../dropdown-menu/dropdown-radio-menu.vue | 52 + .../components/dropdown-menu/index.ts | 4 + .../components/dropdown-menu/interface.ts | 32 + .../expandable-arrow/expandable-arrow.vue | 31 + .../components/expandable-arrow/index.ts | 1 + .../components/full-screen/full-screen.vue | 28 + .../shadcn-ui/components/full-screen/index.ts | 1 + .../components/hover-card/hover-card.vue | 55 + .../shadcn-ui/components/hover-card/index.ts | 2 + .../vben/shadcn-ui/components/icon/icon.vue | 30 + .../vben/shadcn-ui/components/icon/index.ts | 1 + .../src/vben/shadcn-ui/components/index.ts | 23 + .../components/input-password/index.ts | 1 + .../input-password/input-password.vue | 57 + .../input-password/password-strength.vue | 66 + .../vben/shadcn-ui/components/logo/index.ts | 1 + .../vben/shadcn-ui/components/logo/logo.vue | 65 + .../shadcn-ui/components/pin-input/index.ts | 3 + .../shadcn-ui/components/pin-input/input.vue | 120 ++ .../shadcn-ui/components/pin-input/types.ts | 30 + .../shadcn-ui/components/popover/index.ts | 1 + .../shadcn-ui/components/popover/popover.vue | 58 + .../components/render-content/index.ts | 1 + .../render-content/render-content.vue | 40 + .../shadcn-ui/components/scrollbar/index.ts | 1 + .../components/scrollbar/scrollbar.vue | 153 +++ .../shadcn-ui/components/segmented/index.ts | 3 + .../components/segmented/segmented.vue | 59 + .../components/segmented/tabs-indicator.vue | 37 + .../shadcn-ui/components/segmented/types.ts | 6 + .../vben/shadcn-ui/components/select/index.ts | 1 + .../shadcn-ui/components/select/select.vue | 35 + .../shadcn-ui/components/spine-text/index.ts | 1 + .../components/spine-text/spine-text.vue | 49 + .../shadcn-ui/components/spinner/index.ts | 2 + .../shadcn-ui/components/spinner/loading.vue | 140 ++ .../shadcn-ui/components/spinner/spinner.vue | 137 ++ .../components/tooltip/help-tooltip.vue | 31 + .../shadcn-ui/components/tooltip/index.ts | 2 + .../shadcn-ui/components/tooltip/tooltip.vue | 44 + .../certd-client/src/vben/shadcn-ui/index.ts | 3 + .../vben/shadcn-ui/ui/accordion/Accordion.vue | 16 + .../ui/accordion/AccordionContent.vue | 28 + .../shadcn-ui/ui/accordion/AccordionItem.vue | 25 + .../ui/accordion/AccordionTrigger.vue | 39 + .../src/vben/shadcn-ui/ui/accordion/index.ts | 4 + .../src/vben/shadcn-ui/ui/avatar/Avatar.vue | 27 + .../shadcn-ui/ui/avatar/AvatarFallback.vue | 13 + .../vben/shadcn-ui/ui/avatar/AvatarImage.vue | 11 + .../src/vben/shadcn-ui/ui/avatar/avatar.ts | 22 + .../src/vben/shadcn-ui/ui/avatar/index.ts | 4 + .../src/vben/shadcn-ui/ui/badge/Badge.vue | 18 + .../src/vben/shadcn-ui/ui/badge/badge.ts | 25 + .../src/vben/shadcn-ui/ui/badge/index.ts | 3 + .../shadcn-ui/ui/breadcrumb/Breadcrumb.vue | 11 + .../ui/breadcrumb/BreadcrumbEllipsis.vue | 22 + .../ui/breadcrumb/BreadcrumbItem.vue | 17 + .../ui/breadcrumb/BreadcrumbLink.vue | 21 + .../ui/breadcrumb/BreadcrumbList.vue | 20 + .../ui/breadcrumb/BreadcrumbPage.vue | 18 + .../ui/breadcrumb/BreadcrumbSeparator.vue | 21 + .../src/vben/shadcn-ui/ui/breadcrumb/index.ts | 7 + .../src/vben/shadcn-ui/ui/button/Button.vue | 32 + .../src/vben/shadcn-ui/ui/button/button.ts | 34 + .../src/vben/shadcn-ui/ui/button/index.ts | 5 + .../src/vben/shadcn-ui/ui/button/types.ts | 20 + .../src/vben/shadcn-ui/ui/card/Card.vue | 20 + .../vben/shadcn-ui/ui/card/CardContent.vue | 13 + .../shadcn-ui/ui/card/CardDescription.vue | 13 + .../src/vben/shadcn-ui/ui/card/CardFooter.vue | 13 + .../src/vben/shadcn-ui/ui/card/CardHeader.vue | 13 + .../src/vben/shadcn-ui/ui/card/CardTitle.vue | 13 + .../src/vben/shadcn-ui/ui/card/index.ts | 6 + .../vben/shadcn-ui/ui/checkbox/Checkbox.vue | 45 + .../src/vben/shadcn-ui/ui/checkbox/index.ts | 1 + .../shadcn-ui/ui/context-menu/ContextMenu.vue | 18 + .../context-menu/ContextMenuCheckboxItem.vue | 47 + .../ui/context-menu/ContextMenuContent.vue | 43 + .../ui/context-menu/ContextMenuGroup.vue | 13 + .../ui/context-menu/ContextMenuItem.vue | 37 + .../ui/context-menu/ContextMenuLabel.vue | 34 + .../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 + .../ui/context-menu/ContextMenuSub.vue | 16 + .../ui/context-menu/ContextMenuSubContent.vue | 37 + .../ui/context-menu/ContextMenuSubTrigger.vue | 41 + .../ui/context-menu/ContextMenuTrigger.vue | 15 + .../vben/shadcn-ui/ui/context-menu/index.ts | 14 + .../src/vben/shadcn-ui/ui/dialog/Dialog.vue | 16 + .../vben/shadcn-ui/ui/dialog/DialogClose.vue | 13 + .../shadcn-ui/ui/dialog/DialogContent.vue | 123 ++ .../shadcn-ui/ui/dialog/DialogDescription.vue | 28 + .../vben/shadcn-ui/ui/dialog/DialogFooter.vue | 15 + .../vben/shadcn-ui/ui/dialog/DialogHeader.vue | 15 + .../shadcn-ui/ui/dialog/DialogOverlay.vue | 11 + .../ui/dialog/DialogScrollContent.vue | 71 ++ .../vben/shadcn-ui/ui/dialog/DialogTitle.vue | 30 + .../shadcn-ui/ui/dialog/DialogTrigger.vue | 13 + .../src/vben/shadcn-ui/ui/dialog/index.ts | 9 + .../ui/dropdown-menu/DropdownMenu.vue | 18 + .../DropdownMenuCheckboxItem.vue | 47 + .../ui/dropdown-menu/DropdownMenuContent.vue | 48 + .../ui/dropdown-menu/DropdownMenuGroup.vue | 13 + .../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 + .../ui/dropdown-menu/DropdownMenuSub.vue | 16 + .../dropdown-menu/DropdownMenuSubContent.vue | 37 + .../dropdown-menu/DropdownMenuSubTrigger.vue | 35 + .../ui/dropdown-menu/DropdownMenuTrigger.vue | 15 + .../vben/shadcn-ui/ui/dropdown-menu/index.ts | 16 + .../vben/shadcn-ui/ui/form/FormControl.vue | 19 + .../shadcn-ui/ui/form/FormDescription.vue | 20 + .../src/vben/shadcn-ui/ui/form/FormItem.vue | 20 + .../src/vben/shadcn-ui/ui/form/FormLabel.vue | 18 + .../vben/shadcn-ui/ui/form/FormMessage.vue | 18 + .../src/vben/shadcn-ui/ui/form/index.ts | 11 + .../vben/shadcn-ui/ui/form/injectionKeys.ts | 4 + .../vben/shadcn-ui/ui/form/useFormField.ts | 38 + .../shadcn-ui/ui/hover-card/HoverCard.vue | 16 + .../ui/hover-card/HoverCardContent.vue | 40 + .../ui/hover-card/HoverCardTrigger.vue | 13 + .../src/vben/shadcn-ui/ui/hover-card/index.ts | 3 + .../src/vben/shadcn-ui/ui/index.ts | 29 + .../src/vben/shadcn-ui/ui/input/Input.vue | 32 + .../src/vben/shadcn-ui/ui/input/index.ts | 1 + .../src/vben/shadcn-ui/ui/label/Label.vue | 31 + .../src/vben/shadcn-ui/ui/label/index.ts | 1 + .../shadcn-ui/ui/number-field/NumberField.vue | 26 + .../ui/number-field/NumberFieldContent.vue | 20 + .../ui/number-field/NumberFieldDecrement.vue | 37 + .../ui/number-field/NumberFieldIncrement.vue | 37 + .../ui/number-field/NumberFieldInput.vue | 16 + .../vben/shadcn-ui/ui/number-field/index.ts | 5 + .../ui/pagination/PaginationEllipsis.vue | 29 + .../ui/pagination/PaginationFirst.vue | 35 + .../ui/pagination/PaginationLast.vue | 35 + .../ui/pagination/PaginationNext.vue | 35 + .../ui/pagination/PaginationPrev.vue | 35 + .../src/vben/shadcn-ui/ui/pagination/index.ts | 10 + .../vben/shadcn-ui/ui/pin-input/PinInput.vue | 28 + .../shadcn-ui/ui/pin-input/PinInputGroup.vue | 25 + .../shadcn-ui/ui/pin-input/PinInputInput.vue | 30 + .../ui/pin-input/PinInputSeparator.vue | 17 + .../src/vben/shadcn-ui/ui/pin-input/index.ts | 4 + .../src/vben/shadcn-ui/ui/popover/Popover.vue | 16 + .../shadcn-ui/ui/popover/PopoverContent.vue | 46 + .../shadcn-ui/ui/popover/PopoverTrigger.vue | 13 + .../src/vben/shadcn-ui/ui/popover/index.ts | 4 + .../shadcn-ui/ui/radio-group/RadioGroup.vue | 26 + .../ui/radio-group/RadioGroupItem.vue | 40 + .../vben/shadcn-ui/ui/radio-group/index.ts | 2 + .../ui/resizable/ResizableHandle.vue | 50 + .../ui/resizable/ResizablePanelGroup.vue | 37 + .../src/vben/shadcn-ui/ui/resizable/index.ts | 3 + .../shadcn-ui/ui/scroll-area/ScrollArea.vue | 50 + .../shadcn-ui/ui/scroll-area/ScrollBar.vue | 40 + .../vben/shadcn-ui/ui/scroll-area/index.ts | 2 + .../src/vben/shadcn-ui/ui/select/Select.vue | 16 + .../shadcn-ui/ui/select/SelectContent.vue | 67 + .../vben/shadcn-ui/ui/select/SelectGroup.vue | 23 + .../vben/shadcn-ui/ui/select/SelectItem.vue | 47 + .../shadcn-ui/ui/select/SelectItemText.vue | 13 + .../vben/shadcn-ui/ui/select/SelectLabel.vue | 15 + .../ui/select/SelectScrollDownButton.vue | 33 + .../ui/select/SelectScrollUpButton.vue | 33 + .../shadcn-ui/ui/select/SelectSeparator.vue | 24 + .../shadcn-ui/ui/select/SelectTrigger.vue | 37 + .../vben/shadcn-ui/ui/select/SelectValue.vue | 13 + .../src/vben/shadcn-ui/ui/select/index.ts | 11 + .../vben/shadcn-ui/ui/separator/Separator.vue | 44 + .../src/vben/shadcn-ui/ui/separator/index.ts | 1 + .../src/vben/shadcn-ui/ui/sheet/Sheet.vue | 16 + .../vben/shadcn-ui/ui/sheet/SheetClose.vue | 13 + .../vben/shadcn-ui/ui/sheet/SheetContent.vue | 107 ++ .../shadcn-ui/ui/sheet/SheetDescription.vue | 26 + .../vben/shadcn-ui/ui/sheet/SheetFooter.vue | 15 + .../vben/shadcn-ui/ui/sheet/SheetHeader.vue | 11 + .../vben/shadcn-ui/ui/sheet/SheetOverlay.vue | 11 + .../vben/shadcn-ui/ui/sheet/SheetTitle.vue | 26 + .../vben/shadcn-ui/ui/sheet/SheetTrigger.vue | 13 + .../src/vben/shadcn-ui/ui/sheet/index.ts | 10 + .../src/vben/shadcn-ui/ui/sheet/sheet.ts | 24 + .../src/vben/shadcn-ui/ui/switch/Switch.vue | 35 + .../src/vben/shadcn-ui/ui/switch/index.ts | 1 + .../src/vben/shadcn-ui/ui/tabs/Tabs.vue | 16 + .../vben/shadcn-ui/ui/tabs/TabsContent.vue | 31 + .../src/vben/shadcn-ui/ui/tabs/TabsList.vue | 31 + .../vben/shadcn-ui/ui/tabs/TabsTrigger.vue | 33 + .../src/vben/shadcn-ui/ui/tabs/index.ts | 5 + .../vben/shadcn-ui/ui/textarea/Textarea.vue | 32 + .../src/vben/shadcn-ui/ui/textarea/index.ts | 1 + .../shadcn-ui/ui/toggle-group/ToggleGroup.vue | 44 + .../ui/toggle-group/ToggleGroupItem.vue | 48 + .../vben/shadcn-ui/ui/toggle-group/index.ts | 2 + .../src/vben/shadcn-ui/ui/toggle/Toggle.vue | 47 + .../src/vben/shadcn-ui/ui/toggle/index.ts | 2 + .../src/vben/shadcn-ui/ui/toggle/toggle.ts | 27 + .../src/vben/shadcn-ui/ui/tooltip/Tooltip.vue | 16 + .../shadcn-ui/ui/tooltip/TooltipContent.vue | 48 + .../shadcn-ui/ui/tooltip/TooltipProvider.vue | 13 + .../shadcn-ui/ui/tooltip/TooltipTrigger.vue | 13 + .../src/vben/shadcn-ui/ui/tooltip/index.ts | 4 + .../cache/__tests__/storage-manager.test.ts | 130 ++ .../src/vben/shared/cache/index.ts | 1 + .../src/vben/shared/cache/storage-manager.ts | 118 ++ .../src/vben/shared/cache/types.ts | 17 + .../shared/color/__tests__/convert.test.ts | 58 + .../src/vben/shared/color/color.ts | 9 + .../src/vben/shared/color/convert.ts | 62 + .../src/vben/shared/color/generator.ts | 45 + .../src/vben/shared/color/index.ts | 3 + .../src/vben/shared/constants/globals.ts | 16 + .../src/vben/shared/constants/index.ts | 2 + .../src/vben/shared/constants/vben.ts | 26 + .../src/vben/shared/global-state.ts | 45 + .../ui/certd-client/src/vben/shared/store.ts | 1 + .../vben/shared/utils/__tests__/diff.test.ts | 53 + .../vben/shared/utils/__tests__/dom.test.ts | 127 ++ .../shared/utils/__tests__/inference.test.ts | 183 +++ .../shared/utils/__tests__/letter.test.ts | 116 ++ .../utils/__tests__/state-handler.test.ts | 60 + .../vben/shared/utils/__tests__/tree.test.ts | 179 +++ .../shared/utils/__tests__/unique.test.ts | 60 + .../__tests__/update-css-variables.test.ts | 30 + .../vben/shared/utils/__tests__/util.test.ts | 156 +++ .../shared/utils/__tests__/window.test.ts | 33 + .../certd-client/src/vben/shared/utils/cn.ts | 10 + .../src/vben/shared/utils/date.ts | 26 + .../src/vben/shared/utils/diff.ts | 91 ++ .../certd-client/src/vben/shared/utils/dom.ts | 87 ++ .../src/vben/shared/utils/download.ts | 137 ++ .../src/vben/shared/utils/index.ts | 19 + .../src/vben/shared/utils/inference.ts | 147 +++ .../src/vben/shared/utils/letter.ts | 40 + .../src/vben/shared/utils/merge.ts | 10 + .../src/vben/shared/utils/nprogress.ts | 43 + .../src/vben/shared/utils/state-handler.ts | 50 + .../certd-client/src/vben/shared/utils/to.ts | 21 + .../src/vben/shared/utils/tree.ts | 85 ++ .../src/vben/shared/utils/unique.ts | 15 + .../vben/shared/utils/update-css-variables.ts | 31 + .../src/vben/shared/utils/util.ts | 38 + .../src/vben/shared/utils/window.ts | 35 + .../ui/certd-client/src/vben/stores/index.ts | 3 + .../src/vben/stores/modules/access.test.ts | 44 + .../src/vben/stores/modules/access.ts | 102 ++ .../src/vben/stores/modules/index.ts | 4 + .../src/vben/stores/modules/lock.test.ts | 31 + .../src/vben/stores/modules/lock.ts | 33 + .../src/vben/stores/modules/tabbar.test.ts | 291 +++++ .../src/vben/stores/modules/tabbar.ts | 533 ++++++++ .../src/vben/stores/modules/user.test.ts | 37 + .../src/vben/stores/modules/user.ts | 64 + .../ui/certd-client/src/vben/stores/setup.ts | 43 + .../src/vben/styles/antd/index.css | 75 ++ .../src/vben/styles/ele/index.css | 44 + .../src/vben/styles/global/index.scss | 1 + .../ui/certd-client/src/vben/styles/index.ts | 1 + .../src/vben/styles/naive/index.css | 20 + .../src/vben/tabs-ui/components/index.ts | 2 + .../tabs-ui/components/tabs-chrome/tabs.vue | 181 +++ .../src/vben/tabs-ui/components/tabs/tabs.vue | 125 ++ .../vben/tabs-ui/components/widgets/index.ts | 2 + .../tabs-ui/components/widgets/tool-more.vue | 16 + .../components/widgets/tool-screen.vue | 16 + .../ui/certd-client/src/vben/tabs-ui/index.ts | 3 + .../src/vben/tabs-ui/tabs-view.vue | 106 ++ .../ui/certd-client/src/vben/tabs-ui/types.ts | 73 ++ .../src/vben/tabs-ui/use-tabs-drag.ts | 124 ++ .../src/vben/tabs-ui/use-tabs-view-scroll.ts | 202 +++ .../ui/certd-client/src/vben/types/index.ts | 2 + .../ui/certd-client/src/vben/types/user.ts | 20 + .../ui/certd-client/src/vben/typings/app.d.ts | 103 ++ .../certd-client/src/vben/typings/basic.d.ts | 35 + .../certd-client/src/vben/typings/helper.d.ts | 119 ++ .../ui/certd-client/src/vben/typings/index.ts | 6 + .../src/vben/typings/menu-record.ts | 78 ++ .../ui/certd-client/src/vben/typings/tabs.ts | 3 + .../src/vben/typings/vue-router.d.ts | 134 ++ .../__tests__/find-menu-by-path.test.ts | 88 ++ .../helpers/__tests__/generate-menus.test.ts | 236 ++++ .../generate-routes-frontend.test.ts | 105 ++ .../__tests__/merge-route-modules.test.ts | 68 + .../vben/utils/helpers/find-menu-by-path.ts | 32 + .../src/vben/utils/helpers/generate-menus.ts | 65 + .../utils/helpers/generate-routes-backend.ts | 71 ++ .../utils/helpers/generate-routes-frontend.ts | 50 + .../vben/utils/helpers/get-popup-container.ts | 10 + .../src/vben/utils/helpers/index.ts | 8 + .../vben/utils/helpers/merge-route-modules.ts | 26 + .../src/vben/utils/helpers/reset-routes.ts | 31 + .../utils/helpers/unmount-global-loading.ts | 31 + .../ui/certd-client/src/vben/utils/index.ts | 4 + .../views/crud/basis/compute-more/index.vue | 3 +- .../src/views/crud/basis/compute/crud.tsx | 4 +- .../src/views/crud/basis/compute/index.vue | 14 +- .../src/views/crud/basis/i18n/index.vue | 2 +- .../src/views/framework/error/403.vue | 19 + .../src/views/framework/login/index.vue | 8 +- packages/ui/certd-client/tailwind.config.js | 11 - packages/ui/certd-client/tailwind.config.mjs | 1 + 649 files changed, 36984 insertions(+), 826 deletions(-) create mode 100644 packages/ui/certd-client/build/tailwind-config/index.mjs create mode 100644 packages/ui/certd-client/build/tailwind-config/plugins/entry.mjs create mode 100644 packages/ui/certd-client/build/tailwind-config/postcss.config.mjs create mode 100644 packages/ui/certd-client/postcss.config.mjs create mode 100644 packages/ui/certd-client/src/layout/layout-basic.vue create mode 100644 packages/ui/certd-client/src/router/access.ts create mode 100644 packages/ui/certd-client/src/router/guard.ts delete mode 100644 packages/ui/certd-client/src/store/modules/page.ts delete mode 100644 packages/ui/certd-client/src/store/modules/resource.ts delete mode 100644 packages/ui/certd-client/src/store/modules/settings.ts create mode 100644 packages/ui/certd-client/src/vben/access/access-control.vue create mode 100644 packages/ui/certd-client/src/vben/access/accessible.ts create mode 100644 packages/ui/certd-client/src/vben/access/directive.ts create mode 100644 packages/ui/certd-client/src/vben/access/index.ts create mode 100644 packages/ui/certd-client/src/vben/access/use-access.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/api-component/api-component.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/api-component/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/hooks/useCaptchaPoints.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/point-selection-captcha/index.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/point-selection-captcha/point-selection-captcha-card.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/index.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-action.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-bar.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-content.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-rotate-captcha/index.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/captcha/types.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/col-page/col-page.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/col-page/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/col-page/types.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/count-to/count-to.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/count-to/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/count-to/types.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/ellipsis-text/ellipsis-text.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/ellipsis-text/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/icon-picker/icon-picker.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/icon-picker/icons.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/icon-picker/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/json-viewer/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/json-viewer/index.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/json-viewer/style.scss create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/json-viewer/types.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/loading/directive.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/loading/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/loading/loading.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/loading/spinner.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/page/__tests__/page.test.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/page/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/page/page.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/page/types.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/resize/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/resize/resize.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/tippy/directive.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/components/tippy/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/about/about.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/about/about.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/about/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/auth-title.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/code-login.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/forget-password.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/login-expired-modal.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/login.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/qrcode-login.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/register.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/third-party-login.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/authentication/types.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-chart-card.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-charts-tabs.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-overview.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/typing.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-header.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-project.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-quick-nav.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-todo.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-trends.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/fallback/fallback.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/fallback/fallback.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-403.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-404.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-500.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-coming-soon.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-offline.vue create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/warning.svg create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/fallback/index.ts create mode 100644 packages/ui/certd-client/src/vben/common-ui/ui/index.ts create mode 100644 packages/ui/certd-client/src/vben/composables/__tests__/use-sortable.test.ts create mode 100644 packages/ui/certd-client/src/vben/composables/index.ts create mode 100644 packages/ui/certd-client/src/vben/composables/use-is-mobile.ts create mode 100644 packages/ui/certd-client/src/vben/composables/use-layout-style.ts create mode 100644 packages/ui/certd-client/src/vben/composables/use-namespace.ts create mode 100644 packages/ui/certd-client/src/vben/composables/use-priority-value.ts create mode 100644 packages/ui/certd-client/src/vben/composables/use-scroll-lock.ts create mode 100644 packages/ui/certd-client/src/vben/composables/use-simple-locale/README.md create mode 100644 packages/ui/certd-client/src/vben/composables/use-simple-locale/index.ts create mode 100644 packages/ui/certd-client/src/vben/composables/use-simple-locale/messages.ts create mode 100644 packages/ui/certd-client/src/vben/composables/use-sortable.ts create mode 100644 packages/ui/certd-client/src/vben/constants/core.ts create mode 100644 packages/ui/certd-client/src/vben/constants/globals.ts create mode 100644 packages/ui/certd-client/src/vben/constants/index.ts create mode 100644 packages/ui/certd-client/src/vben/constants/vben.ts create mode 100644 packages/ui/certd-client/src/vben/design/css/global.css create mode 100644 packages/ui/certd-client/src/vben/design/css/nprogress.css create mode 100644 packages/ui/certd-client/src/vben/design/css/transition.css create mode 100644 packages/ui/certd-client/src/vben/design/css/ui.css create mode 100644 packages/ui/certd-client/src/vben/design/design-tokens/dark.css create mode 100644 packages/ui/certd-client/src/vben/design/design-tokens/default.css create mode 100644 packages/ui/certd-client/src/vben/design/design-tokens/index.ts create mode 100644 packages/ui/certd-client/src/vben/design/index.ts create mode 100644 packages/ui/certd-client/src/vben/design/scss-bem/bem.scss create mode 100644 packages/ui/certd-client/src/vben/design/scss-bem/constants.scss create mode 100644 packages/ui/certd-client/src/vben/form-ui/components/form-actions.vue create mode 100644 packages/ui/certd-client/src/vben/form-ui/config.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/form-api.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/form-render/context.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/form-render/dependencies.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/form-render/expandable.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/form-render/form-field.vue create mode 100644 packages/ui/certd-client/src/vben/form-ui/form-render/form-label.vue create mode 100644 packages/ui/certd-client/src/vben/form-ui/form-render/form.vue create mode 100644 packages/ui/certd-client/src/vben/form-ui/form-render/helper.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/form-render/index.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/index.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/types.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/use-form-context.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/use-vben-form.ts create mode 100644 packages/ui/certd-client/src/vben/form-ui/vben-form.vue create mode 100644 packages/ui/certd-client/src/vben/form-ui/vben-use-form.vue create mode 100644 packages/ui/certd-client/src/vben/hooks/index.ts create mode 100644 packages/ui/certd-client/src/vben/hooks/use-app-config.ts create mode 100644 packages/ui/certd-client/src/vben/hooks/use-content-maximize.ts create mode 100644 packages/ui/certd-client/src/vben/hooks/use-design-tokens.ts create mode 100644 packages/ui/certd-client/src/vben/hooks/use-hover-toggle.ts create mode 100644 packages/ui/certd-client/src/vben/hooks/use-pagination.ts create mode 100644 packages/ui/certd-client/src/vben/hooks/use-refresh.ts create mode 100644 packages/ui/certd-client/src/vben/hooks/use-tabs.ts create mode 100644 packages/ui/certd-client/src/vben/hooks/use-watermark.ts create mode 100644 packages/ui/certd-client/src/vben/icons/create-icon.ts create mode 100644 packages/ui/certd-client/src/vben/icons/index.ts create mode 100644 packages/ui/certd-client/src/vben/icons/lucide.ts create mode 100644 packages/ui/certd-client/src/vben/index.ts create mode 100644 packages/ui/certd-client/src/vben/layout-ui/components/index.ts create mode 100644 packages/ui/certd-client/src/vben/layout-ui/components/layout-content.vue create mode 100644 packages/ui/certd-client/src/vben/layout-ui/components/layout-footer.vue create mode 100644 packages/ui/certd-client/src/vben/layout-ui/components/layout-header.vue create mode 100644 packages/ui/certd-client/src/vben/layout-ui/components/layout-sidebar.vue create mode 100644 packages/ui/certd-client/src/vben/layout-ui/components/layout-tabbar.vue create mode 100644 packages/ui/certd-client/src/vben/layout-ui/components/widgets/index.ts create mode 100644 packages/ui/certd-client/src/vben/layout-ui/components/widgets/sidebar-collapse-button.vue create mode 100644 packages/ui/certd-client/src/vben/layout-ui/components/widgets/sidebar-fixed-button.vue create mode 100644 packages/ui/certd-client/src/vben/layout-ui/hooks/use-layout.ts create mode 100644 packages/ui/certd-client/src/vben/layout-ui/index.ts create mode 100644 packages/ui/certd-client/src/vben/layout-ui/vben-layout.ts create mode 100644 packages/ui/certd-client/src/vben/layout-ui/vben-layout.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/README.md create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/content/content-spinner.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/content/content.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/content/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/content/use-content-spinner.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/copyright/copyright.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/copyright/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/footer/footer.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/footer/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/header/header.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/header/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/layout.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/menu/extra-menu.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/menu/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/menu/menu.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/menu/mixed-menu.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/menu/use-extra-menu.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/menu/use-mixed-menu.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/menu/use-navigation.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/tabbar/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/tabbar/tabbar.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/basic/tabbar/use-tabbar.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/iframe/iframe-router-view.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/iframe/iframe-view.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/iframe/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/breadcrumb.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/check-updates/check-updates.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/check-updates/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/color-toggle.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/global-search/global-search.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/global-search/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/global-search/search-panel.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/language-toggle.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/layout-toggle.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/lock-screen/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/lock-screen/lock-screen-modal.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/lock-screen/lock-screen.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/notification/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/notification/notification.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/notification/types.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/block.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/general/animation.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/general/general.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/input-item.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/breadcrumb.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/content.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/copyright.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/footer.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/header.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/layout.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/navigation.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/sidebar.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/tabbar.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/layout/widget.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/number-field-item.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/select-item.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/shortcut-keys/global.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/switch-item.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/theme/builtin.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/theme/color-mode.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/theme/radius.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/theme/theme.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/blocks/toggle-item.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/content-compact.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/full-content.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/header-mixed-nav.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/header-nav.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/header-sidebar-nav.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/mixed-nav.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/setting.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/sidebar-mixed-nav.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/icons/sidebar-nav.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/preferences-button.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/preferences-drawer.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/preferences.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/preferences/use-open-preferences.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/theme-toggle/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/theme-toggle/theme-button.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/theme-toggle/theme-toggle.vue create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/user-dropdown/index.ts create mode 100644 packages/ui/certd-client/src/vben/layouts/widgets/user-dropdown/user-dropdown.vue create mode 100644 packages/ui/certd-client/src/vben/locales/i18n.ts create mode 100644 packages/ui/certd-client/src/vben/locales/index.ts create mode 100644 packages/ui/certd-client/src/vben/locales/langs/en-US/authentication.json create mode 100644 packages/ui/certd-client/src/vben/locales/langs/en-US/common.json create mode 100644 packages/ui/certd-client/src/vben/locales/langs/en-US/preferences.json create mode 100644 packages/ui/certd-client/src/vben/locales/langs/en-US/ui.json create mode 100644 packages/ui/certd-client/src/vben/locales/langs/zh-CN/authentication.json create mode 100644 packages/ui/certd-client/src/vben/locales/langs/zh-CN/common.json create mode 100644 packages/ui/certd-client/src/vben/locales/langs/zh-CN/preferences.json create mode 100644 packages/ui/certd-client/src/vben/locales/langs/zh-CN/ui.json create mode 100644 packages/ui/certd-client/src/vben/locales/typing.ts create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/collapse-transition.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/index.ts create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/menu-badge-dot.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/menu-badge.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/menu-item.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/menu.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/normal-menu/index.ts create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/normal-menu/normal-menu.ts create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/normal-menu/normal-menu.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/sub-menu-content.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/components/sub-menu.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/hooks/index.ts create mode 100644 packages/ui/certd-client/src/vben/menu-ui/hooks/use-menu-context.ts create mode 100644 packages/ui/certd-client/src/vben/menu-ui/hooks/use-menu.ts create mode 100644 packages/ui/certd-client/src/vben/menu-ui/index.ts create mode 100644 packages/ui/certd-client/src/vben/menu-ui/menu.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/sub-menu.vue create mode 100644 packages/ui/certd-client/src/vben/menu-ui/types.ts create mode 100644 packages/ui/certd-client/src/vben/menu-ui/utils/index.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/drawer/__tests__/drawer-api.test.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/drawer/drawer-api.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/drawer/drawer.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/drawer/drawer.vue create mode 100644 packages/ui/certd-client/src/vben/popup-ui/drawer/index.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/drawer/use-drawer.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/index.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/modal/__tests__/modal-api.test.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/modal/index.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/modal/modal-api.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/modal/modal.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/modal/modal.vue create mode 100644 packages/ui/certd-client/src/vben/popup-ui/modal/use-modal-draggable.ts create mode 100644 packages/ui/certd-client/src/vben/popup-ui/modal/use-modal.ts create mode 100644 packages/ui/certd-client/src/vben/preferences/config.ts create mode 100644 packages/ui/certd-client/src/vben/preferences/constants.ts create mode 100644 packages/ui/certd-client/src/vben/preferences/index.ts create mode 100644 packages/ui/certd-client/src/vben/preferences/preferences.ts create mode 100644 packages/ui/certd-client/src/vben/preferences/types.ts create mode 100644 packages/ui/certd-client/src/vben/preferences/update-css-variables.ts create mode 100644 packages/ui/certd-client/src/vben/preferences/use-preferences.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/avatar/avatar.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/avatar/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/back-top/back-top.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/back-top/backtop.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/back-top/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/back-top/use-backtop.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/breadcrumb/breadcrumb-background.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/breadcrumb/breadcrumb-view.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/breadcrumb/breadcrumb.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/breadcrumb/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/breadcrumb/types.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/button/button-group.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/button/button.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/button/button.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/button/check-button-group.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/button/icon-button.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/button/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/checkbox/checkbox.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/checkbox/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/context-menu/context-menu.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/context-menu/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/context-menu/interface.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/count-to-animator/count-to-animator.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/count-to-animator/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/dropdown-menu/dropdown-menu.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/dropdown-menu/dropdown-radio-menu.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/dropdown-menu/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/dropdown-menu/interface.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/expandable-arrow/expandable-arrow.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/expandable-arrow/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/full-screen/full-screen.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/full-screen/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/hover-card/hover-card.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/hover-card/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/icon/icon.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/icon/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/input-password/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/input-password/input-password.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/input-password/password-strength.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/logo/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/logo/logo.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/pin-input/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/pin-input/input.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/pin-input/types.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/popover/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/popover/popover.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/render-content/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/render-content/render-content.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/scrollbar/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/scrollbar/scrollbar.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/segmented/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/segmented/segmented.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/segmented/tabs-indicator.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/segmented/types.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/select/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/select/select.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/spine-text/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/spine-text/spine-text.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/spinner/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/spinner/loading.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/spinner/spinner.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/tooltip/help-tooltip.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/tooltip/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/components/tooltip/tooltip.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/accordion/Accordion.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/accordion/AccordionContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/accordion/AccordionItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/accordion/AccordionTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/accordion/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/avatar/Avatar.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/avatar/AvatarFallback.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/avatar/AvatarImage.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/avatar/avatar.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/avatar/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/badge/Badge.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/badge/badge.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/badge/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/breadcrumb/Breadcrumb.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/breadcrumb/BreadcrumbEllipsis.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/breadcrumb/BreadcrumbItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/breadcrumb/BreadcrumbLink.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/breadcrumb/BreadcrumbList.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/breadcrumb/BreadcrumbPage.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/breadcrumb/BreadcrumbSeparator.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/breadcrumb/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/button/Button.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/button/button.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/button/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/button/types.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/card/Card.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/card/CardContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/card/CardDescription.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/card/CardFooter.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/card/CardHeader.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/card/CardTitle.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/card/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/checkbox/Checkbox.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/checkbox/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenu.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuCheckboxItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuGroup.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuLabel.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuPortal.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuRadioGroup.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuRadioItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuSeparator.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuShortcut.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuSub.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuSubContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuSubTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/ContextMenuTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/context-menu/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/Dialog.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/DialogClose.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/DialogContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/DialogDescription.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/DialogFooter.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/DialogHeader.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/DialogOverlay.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/DialogScrollContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/DialogTitle.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/DialogTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dialog/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenu.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuCheckboxItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuGroup.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuLabel.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuRadioGroup.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuRadioItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuSeparator.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuShortcut.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuSub.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuSubContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuSubTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/DropdownMenuTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/dropdown-menu/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/form/FormControl.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/form/FormDescription.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/form/FormItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/form/FormLabel.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/form/FormMessage.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/form/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/form/injectionKeys.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/form/useFormField.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/hover-card/HoverCard.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/hover-card/HoverCardContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/hover-card/HoverCardTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/hover-card/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/input/Input.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/input/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/label/Label.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/label/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/number-field/NumberField.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/number-field/NumberFieldContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/number-field/NumberFieldDecrement.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/number-field/NumberFieldIncrement.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/number-field/NumberFieldInput.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/number-field/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pagination/PaginationEllipsis.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pagination/PaginationFirst.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pagination/PaginationLast.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pagination/PaginationNext.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pagination/PaginationPrev.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pagination/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pin-input/PinInput.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pin-input/PinInputGroup.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pin-input/PinInputInput.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pin-input/PinInputSeparator.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/pin-input/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/popover/Popover.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/popover/PopoverContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/popover/PopoverTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/popover/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/radio-group/RadioGroup.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/radio-group/RadioGroupItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/radio-group/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/resizable/ResizableHandle.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/resizable/ResizablePanelGroup.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/resizable/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/scroll-area/ScrollArea.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/scroll-area/ScrollBar.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/scroll-area/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/Select.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectGroup.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectItemText.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectLabel.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectScrollDownButton.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectScrollUpButton.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectSeparator.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/SelectValue.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/select/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/separator/Separator.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/separator/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/Sheet.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/SheetClose.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/SheetContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/SheetDescription.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/SheetFooter.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/SheetHeader.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/SheetOverlay.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/SheetTitle.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/SheetTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/sheet/sheet.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/switch/Switch.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/switch/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tabs/Tabs.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tabs/TabsContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tabs/TabsList.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tabs/TabsTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tabs/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/textarea/Textarea.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/textarea/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/toggle-group/ToggleGroup.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/toggle-group/ToggleGroupItem.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/toggle-group/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/toggle/Toggle.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/toggle/index.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/toggle/toggle.ts create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tooltip/Tooltip.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tooltip/TooltipContent.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tooltip/TooltipProvider.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tooltip/TooltipTrigger.vue create mode 100644 packages/ui/certd-client/src/vben/shadcn-ui/ui/tooltip/index.ts create mode 100644 packages/ui/certd-client/src/vben/shared/cache/__tests__/storage-manager.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/cache/index.ts create mode 100644 packages/ui/certd-client/src/vben/shared/cache/storage-manager.ts create mode 100644 packages/ui/certd-client/src/vben/shared/cache/types.ts create mode 100644 packages/ui/certd-client/src/vben/shared/color/__tests__/convert.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/color/color.ts create mode 100644 packages/ui/certd-client/src/vben/shared/color/convert.ts create mode 100644 packages/ui/certd-client/src/vben/shared/color/generator.ts create mode 100644 packages/ui/certd-client/src/vben/shared/color/index.ts create mode 100644 packages/ui/certd-client/src/vben/shared/constants/globals.ts create mode 100644 packages/ui/certd-client/src/vben/shared/constants/index.ts create mode 100644 packages/ui/certd-client/src/vben/shared/constants/vben.ts create mode 100644 packages/ui/certd-client/src/vben/shared/global-state.ts create mode 100644 packages/ui/certd-client/src/vben/shared/store.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/diff.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/dom.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/inference.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/letter.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/state-handler.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/tree.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/unique.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/update-css-variables.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/util.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/__tests__/window.test.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/cn.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/date.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/diff.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/dom.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/download.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/index.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/inference.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/letter.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/merge.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/nprogress.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/state-handler.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/to.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/tree.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/unique.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/update-css-variables.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/util.ts create mode 100644 packages/ui/certd-client/src/vben/shared/utils/window.ts create mode 100644 packages/ui/certd-client/src/vben/stores/index.ts create mode 100644 packages/ui/certd-client/src/vben/stores/modules/access.test.ts create mode 100644 packages/ui/certd-client/src/vben/stores/modules/access.ts create mode 100644 packages/ui/certd-client/src/vben/stores/modules/index.ts create mode 100644 packages/ui/certd-client/src/vben/stores/modules/lock.test.ts create mode 100644 packages/ui/certd-client/src/vben/stores/modules/lock.ts create mode 100644 packages/ui/certd-client/src/vben/stores/modules/tabbar.test.ts create mode 100644 packages/ui/certd-client/src/vben/stores/modules/tabbar.ts create mode 100644 packages/ui/certd-client/src/vben/stores/modules/user.test.ts create mode 100644 packages/ui/certd-client/src/vben/stores/modules/user.ts create mode 100644 packages/ui/certd-client/src/vben/stores/setup.ts create mode 100644 packages/ui/certd-client/src/vben/styles/antd/index.css create mode 100644 packages/ui/certd-client/src/vben/styles/ele/index.css create mode 100644 packages/ui/certd-client/src/vben/styles/global/index.scss create mode 100644 packages/ui/certd-client/src/vben/styles/index.ts create mode 100644 packages/ui/certd-client/src/vben/styles/naive/index.css create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/components/index.ts create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/components/tabs-chrome/tabs.vue create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/components/tabs/tabs.vue create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/components/widgets/index.ts create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/components/widgets/tool-more.vue create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/components/widgets/tool-screen.vue create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/index.ts create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/tabs-view.vue create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/types.ts create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/use-tabs-drag.ts create mode 100644 packages/ui/certd-client/src/vben/tabs-ui/use-tabs-view-scroll.ts create mode 100644 packages/ui/certd-client/src/vben/types/index.ts create mode 100644 packages/ui/certd-client/src/vben/types/user.ts create mode 100644 packages/ui/certd-client/src/vben/typings/app.d.ts create mode 100644 packages/ui/certd-client/src/vben/typings/basic.d.ts create mode 100644 packages/ui/certd-client/src/vben/typings/helper.d.ts create mode 100644 packages/ui/certd-client/src/vben/typings/index.ts create mode 100644 packages/ui/certd-client/src/vben/typings/menu-record.ts create mode 100644 packages/ui/certd-client/src/vben/typings/tabs.ts create mode 100644 packages/ui/certd-client/src/vben/typings/vue-router.d.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/__tests__/find-menu-by-path.test.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/__tests__/generate-menus.test.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/__tests__/generate-routes-frontend.test.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/__tests__/merge-route-modules.test.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/find-menu-by-path.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/generate-menus.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/generate-routes-backend.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/generate-routes-frontend.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/get-popup-container.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/index.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/merge-route-modules.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/reset-routes.ts create mode 100644 packages/ui/certd-client/src/vben/utils/helpers/unmount-global-loading.ts create mode 100644 packages/ui/certd-client/src/vben/utils/index.ts create mode 100644 packages/ui/certd-client/src/views/framework/error/403.vue delete mode 100644 packages/ui/certd-client/tailwind.config.js create mode 100644 packages/ui/certd-client/tailwind.config.mjs diff --git a/packages/ui/certd-client/.env b/packages/ui/certd-client/.env index 27e8c04b..e1dc660f 100644 --- a/packages/ui/certd-client/.env +++ b/packages/ui/certd-client/.env @@ -6,3 +6,4 @@ VITE_APP_SLOGAN=面向配置的CRUD开发,快如闪电 VITE_APP_COPYRIGHT=Copyright © 2021 Greper VITE_APP_LOGO_PATH=./images/logo/logo.svg VITE_APP_PROJECT_PATH=https://github.com/fast-crud/fast-crud +VITE_APP_NAMESPACE=fs \ No newline at end of file diff --git a/packages/ui/certd-client/build/tailwind-config/index.mjs b/packages/ui/certd-client/build/tailwind-config/index.mjs new file mode 100644 index 00000000..9742789a --- /dev/null +++ b/packages/ui/certd-client/build/tailwind-config/index.mjs @@ -0,0 +1,254 @@ +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.mjs"; + +// import defaultTheme from 'tailwindcss/defaultTheme'; + +const { packages } = getPackagesSync(process.cwd()); + +const tailwindPackages = []; + +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"] +}; + +function createColorsPalette(name) { + // 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/packages/ui/certd-client/build/tailwind-config/plugins/entry.mjs b/packages/ui/certd-client/build/tailwind-config/plugins/entry.mjs new file mode 100644 index 00000000..8c24529e --- /dev/null +++ b/packages/ui/certd-client/build/tailwind-config/plugins/entry.mjs @@ -0,0 +1,53 @@ +import plugin from "tailwindcss/plugin.js"; + +const enterAnimationPlugin = plugin(({ addUtilities }) => { + const maxChild = 5; + const utilities = {}; + 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/packages/ui/certd-client/build/tailwind-config/postcss.config.mjs b/packages/ui/certd-client/build/tailwind-config/postcss.config.mjs new file mode 100644 index 00000000..914e44b2 --- /dev/null +++ b/packages/ui/certd-client/build/tailwind-config/postcss.config.mjs @@ -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/packages/ui/certd-client/package.json b/packages/ui/certd-client/package.json index 4a03ba85..e6b5aef2 100644 --- a/packages/ui/certd-client/package.json +++ b/packages/ui/certd-client/package.json @@ -30,31 +30,58 @@ "@fast-crud/fast-extends": "^1.25.3", "@fast-crud/ui-antdv4": "^1.25.3", "@fast-crud/ui-interface": "^1.25.3", + "@ctrl/tinycolor": "^4.1.0", + "@iconify/tailwind": "^1.2.0", "@iconify/vue": "^4.1.1", + "@manypkg/get-packages": "^2.2.2", "@soerenmartius/vue3-clipboard": "^0.1.2", + "@tailwindcss/nesting": "0.0.0-insiders.565cd3e", + "@tailwindcss/typography": "^0.5.16", + "@tanstack/vue-store": "^0.7.0", + "@vee-validate/zod": "^4.15.0", + "@vue/shared": "^3.5.13", + "@vueuse/core": "^10.11.0", "ant-design-vue": "^4.2.6", "axios": "^1.6.8", "axios-mock-adapter": "^1.22.0", "base64-js": "^1.5.1", "better-scroll": "^2.5.1", "china-division": "^2.7.0", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "core-js": "^3.36.0", "cos-js-sdk-v5": "^1.7.0", "cropperjs": "^1.6.1", + "cssnano": "^7.0.6", "dayjs": "^1.11.10", + "defu": "^6.1.4", "highlight.js": "^11.9.0", "lodash-es": "^4.17.21", + "lucide-vue-next": "^0.477.0", "mitt": "^3.0.1", "nprogress": "^0.2.0", "object-assign": "^4.1.1", "pinia": "2.1.7", + "pinia-plugin-persistedstate": "^4.2.0", + "postcss-antd-fixes": "^0.2.0", + "postcss-import": "^16.1.0", + "postcss-preset-env": "^10.1.5", "qiniu-js": "^3.4.2", - "sortablejs": "^1.15.2", + "radix-vue": "^1.9.16", + "sortablejs": "^1.15.3", + "tailwind-merge": "^3.0.2", + "tailwindcss-animate": "^1.0.7", + "theme-colors": "^0.1.0", + "vee-validate": "^4.15.0", + "vitest": "^0.34.6", "vue": "^3.4.21", "vue-cropperjs": "^5.0.0", "vue-i18n": "^9.10.2", "vue-router": "^4.3.0", - "vuedraggable": "^2.24.3" + "vuedraggable": "^2.24.3", + "watermark-js-plus": "^1.5.8", + "zod": "^3.24.2", + "zod-defaults": "^0.1.3" }, "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", @@ -72,7 +99,7 @@ "@vue/compiler-sfc": "^3.4.21", "@vue/eslint-config-typescript": "^13.0.0", "@vue/test-utils": "^2.4.5", - "autoprefixer": "^10.4.18", + "autoprefixer": "^10.4.20", "caller-path": "^4.0.0", "chai": "^5.1.0", "dependency-cruiser": "^16.2.3", @@ -98,7 +125,7 @@ "stylelint": "^16.2.1", "stylelint-config-prettier": "^9.0.5", "stylelint-order": "^6.0.4", - "tailwindcss": "^3.4.1", + "tailwindcss": "^3.4.14", "terser": "^5.29.2", "ts-node": "^10.9.2", "tslint": "^6.1.3", diff --git a/packages/ui/certd-client/postcss.config.mjs b/packages/ui/certd-client/postcss.config.mjs new file mode 100644 index 00000000..dc7cfb97 --- /dev/null +++ b/packages/ui/certd-client/postcss.config.mjs @@ -0,0 +1,15 @@ +import config from "./build/tailwind-config/index.mjs"; + +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/packages/ui/certd-client/src/App.vue b/packages/ui/certd-client/src/App.vue index dc7e2ccd..f0425d5d 100644 --- a/packages/ui/certd-client/src/App.vue +++ b/packages/ui/certd-client/src/App.vue @@ -1,60 +1,69 @@ - diff --git a/packages/ui/certd-client/src/api/modules/api.user.ts b/packages/ui/certd-client/src/api/modules/api.user.ts index ea711596..77c31b31 100644 --- a/packages/ui/certd-client/src/api/modules/api.user.ts +++ b/packages/ui/certd-client/src/api/modules/api.user.ts @@ -12,6 +12,7 @@ export interface UserInfoRes { id: string | number; username: string; nickName: string; + avatar?: string; } export interface LoginRes { diff --git a/packages/ui/certd-client/src/layout/layout-basic.vue b/packages/ui/certd-client/src/layout/layout-basic.vue new file mode 100644 index 00000000..82e70de0 --- /dev/null +++ b/packages/ui/certd-client/src/layout/layout-basic.vue @@ -0,0 +1,47 @@ + + + diff --git a/packages/ui/certd-client/src/layout/layout-outside.vue b/packages/ui/certd-client/src/layout/layout-outside.vue index 35b113ea..9061fb14 100644 --- a/packages/ui/certd-client/src/layout/layout-outside.vue +++ b/packages/ui/certd-client/src/layout/layout-outside.vue @@ -60,6 +60,8 @@ export default { background-size: 100%; //padding: 50px 0 84px; position: relative; + display: flex; + flex-direction: column; .user-layout-lang { width: 100%; diff --git a/packages/ui/certd-client/src/main.ts b/packages/ui/certd-client/src/main.ts index 4734a200..b32e1c2c 100644 --- a/packages/ui/certd-client/src/main.ts +++ b/packages/ui/certd-client/src/main.ts @@ -1,22 +1,42 @@ import { createApp } from "vue"; import App from "./App.vue"; -import router from "./router"; import Antd from "ant-design-vue"; import "./style/common.less"; - import i18n from "./i18n"; -import store from "./store"; import components from "./components"; +import router from "./router"; +import store from "./store"; import plugin from "./plugin/"; // 正式项目请删除mock,避免影响性能 import "./mock"; - +import { setupVben } from "./vben"; +import { util } from "/@/utils"; +import { initPreferences } from "/@/vben/preferences"; // @ts-ignore -const app = createApp(App); -app.use(Antd); -app.use(router); -app.use(i18n); -app.use(store); -app.use(components); -app.use(plugin, { i18n }); -app.mount("#app"); +async function bootstrap() { + const app = createApp(App); + app.use(Antd); + await setupVben(app); + app.use(router); + app.use(i18n); + // app.use(store); + app.use(components); + app.use(plugin, { i18n }); + + const envMode = util.env.MODE; + const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${envMode}`; + + // app偏好设置初始化 + await initPreferences({ + namespace, + overrides: { + app: { + name: import.meta.env.VITE_APP_TITLE + } + } + }); + + app.mount("#app"); +} + +bootstrap(); diff --git a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx index 04e5aff8..5f1028ac 100644 --- a/packages/ui/certd-client/src/plugin/fast-crud/index.tsx +++ b/packages/ui/certd-client/src/plugin/fast-crud/index.tsx @@ -10,6 +10,7 @@ import _ from "lodash-es"; import { useCrudPermission } from "../permission"; import { GetSignedUrl } from "/@/views/crud/component/uploader/s3/api"; import { notification } from "ant-design-vue"; +import { usePreferences } from "/@/vben/preferences"; function install(app: any, options: any = {}) { app.use(UiAntdv); @@ -31,7 +32,18 @@ function install(app: any, options: any = {}) { commonOptions(props: UseCrudProps): CrudOptions { utils.logger.debug("commonOptions:", props); const crudBinding = props.crudExpose?.crudBinding; + const { isMobile } = usePreferences(); const opts: CrudOptions = { + settings: { + plugins: { + mobile: { + enabled: true, + props: { + isMobile: isMobile + } + } + } + }, table: { scroll: { x: 960 diff --git a/packages/ui/certd-client/src/plugin/permission/hook.ts b/packages/ui/certd-client/src/plugin/permission/hook.ts index af4b0c76..cdddd54a 100644 --- a/packages/ui/certd-client/src/plugin/permission/hook.ts +++ b/packages/ui/certd-client/src/plugin/permission/hook.ts @@ -6,7 +6,7 @@ import { message } from "ant-design-vue"; import NProgress from "nprogress"; export function registerRouterHook() { // 注册路由beforeEach钩子,在第一次加载路由页面时,加载权限 - router.beforeEach(async (to, from, next) => { + router.beforeEach(async (to, from) => { const permissionStore = usePermissionStore(); if (permissionStore.isInited) { if (to.meta.permission) { @@ -20,15 +20,13 @@ export function registerRouterHook() { return false; } } - next(); - return; + return true; } const userStore = useUserStore(); const token = userStore.getToken; if (!token || token === "undefined") { - next(); - return; + return true; } // 初始化权限列表 @@ -36,10 +34,10 @@ export function registerRouterHook() { console.log("permission is enabled"); await permissionStore.loadFromRemote(); console.log("PM load success"); - next({ ...to, replace: true }); + return { ...to, replace: true }; } catch (e) { console.error("加载动态路由失败", e); - next(); + return false; } }); } diff --git a/packages/ui/certd-client/src/plugin/permission/store.permission.ts b/packages/ui/certd-client/src/plugin/permission/store.permission.ts index a5d4cf25..135f0913 100644 --- a/packages/ui/certd-client/src/plugin/permission/store.permission.ts +++ b/packages/ui/certd-client/src/plugin/permission/store.permission.ts @@ -1,8 +1,9 @@ import { defineStore } from "pinia"; -import { useResourceStore } from "/src/store/modules/resource"; +// import { useResourceStore } from "/src/store/modules/resource"; import { getPermissions } from "./api"; import { mitter } from "/@/utils/util.mitt"; import { env } from "/@/utils/util.env"; +import { useAccessStore } from "/@/vben/stores"; //监听注销事件 mitter.on("app.logout", () => { @@ -69,8 +70,8 @@ export const usePermissionStore = defineStore({ this.init({ permissions }); //过滤没有权限的菜单 - const resourceStore = useResourceStore(); - resourceStore.filterByPermission(permissions); + const accessStore = useAccessStore(); + accessStore.setAccessCodes(permissions); }, async loadFromRemote() { let permissionTree = []; diff --git a/packages/ui/certd-client/src/router/access.ts b/packages/ui/certd-client/src/router/access.ts new file mode 100644 index 00000000..d96657fd --- /dev/null +++ b/packages/ui/certd-client/src/router/access.ts @@ -0,0 +1,35 @@ +import type { ComponentRecordType, GenerateMenuAndRoutesOptions } from "/@/vben/types"; + +import { generateAccessible } from "/@/vben/access"; +import { preferences } from "/@/vben/preferences"; + +import { BasicLayout, IFrameView } from "/@/vben/layouts"; + +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 + } as any; + + return await generateAccessible(preferences.app.accessMode, { + ...options, + // fetchMenuListAsync: async () => { + // message.loading({ + // content: `${$t("common.loadingMenu")}...`, + // duration: 1.5 + // }); + // return await getAllMenusApi(); + // }, + // 可以指定没有权限跳转403页面 + forbiddenComponent, + // 如果 route.meta.menuVisibleWithForbidden = true + layoutMap, + pageMap + }); +} + +export { generateAccess }; diff --git a/packages/ui/certd-client/src/router/guard.ts b/packages/ui/certd-client/src/router/guard.ts new file mode 100644 index 00000000..4220c921 --- /dev/null +++ b/packages/ui/certd-client/src/router/guard.ts @@ -0,0 +1,109 @@ +import type { Router } from "vue-router"; + +import { DEFAULT_HOME_PATH, LOGIN_PATH } from "/@/vben/constants"; +import { preferences } from "/@/vben/preferences"; +import { useAccessStore } from "/@/vben/stores"; +import { generateMenus, startProgress, stopProgress } from "/@/vben/utils"; +import { useUserStore } from "/@/store/modules/user"; +import { frameworkRoutes } from "/@/router/resolve"; + +/** + * 通用守卫配置 + * @param router + */ +export 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 needAuth = to.matched.some((r) => { + return r.meta?.auth || r.meta?.permission; + }); + + const accessStore = useAccessStore(); + if (needAuth) { + if (!accessStore.accessToken) { + // 没有访问权限,跳转登录页面 + if (to.fullPath !== LOGIN_PATH) { + return { + path: LOGIN_PATH, + // 如不需要,直接删除 query + query: to.fullPath === DEFAULT_HOME_PATH ? {} : { redirect: encodeURIComponent(to.fullPath) }, + // 携带当前跳转的页面,登录后重新跳转该页面 + replace: true + }; + } + return true; + } + } + + // 是否已经生成过动态路由 + if (!accessStore.isAccessChecked) { + const accessibleMenus = await generateMenus(frameworkRoutes[0].children, router); + accessStore.setAccessRoutes(frameworkRoutes); + accessStore.setAccessMenus(accessibleMenus); + accessStore.setIsAccessChecked(true); + } + + // 生成菜单和路由 + // const { accessibleMenus, accessibleRoutes } = await generateAccess({ + // roles: [], + // router, + // // 则会在菜单中显示,但是访问会被重定向到403 + // routes: accessRoutes + // }); + // + // // 保存菜单信息和路由信息 + // accessStore.setAccessMenus(accessibleMenus); + // accessStore.setAccessRoutes(accessibleRoutes); + + // const redirectPath = (from.query.redirect ?? (to.path === DEFAULT_HOME_PATH ? DEFAULT_HOME_PATH : to.fullPath)) as string; + // + // return { + // ...router.resolve(decodeURIComponent(redirectPath)), + // replace: true + // }; + return true; + }); +} + +/** + * 项目守卫配置 + * @param router + */ +function createRouterGuard(router: Router) { + /** 通用 */ + setupCommonGuard(router); + /** 权限访问 */ + setupAccessGuard(router); +} + +export { createRouterGuard }; diff --git a/packages/ui/certd-client/src/router/index.ts b/packages/ui/certd-client/src/router/index.ts index 818aa6c9..eec084fe 100644 --- a/packages/ui/certd-client/src/router/index.ts +++ b/packages/ui/certd-client/src/router/index.ts @@ -1,74 +1,73 @@ import { createRouter, createWebHashHistory } from "vue-router"; // 进度条 -import NProgress from "nprogress"; import "nprogress/nprogress.css"; -import { usePageStore } from "../store/modules/page"; -import { site } from "../utils/util.site"; import { routes } from "./resolve"; -import { useResourceStore } from "../store/modules/resource"; -import { useUserStore } from "../store/modules/user"; +import { createRouterGuard } from "/@/router/guard"; + const router = createRouter({ history: createWebHashHistory(), routes }); +// +// /** +// * 路由拦截 +// */ +// router.beforeEach(async (to, from, next) => { +// // 进度条 +// NProgress.start(); +// // 修复三级以上路由页面无法缓存的问题 +// if (to.matched && to.matched.length > 2) { +// to.matched.splice(1, to.matched.length - 2); +// } +// // 验证当前路由所有的匹配中是否需要有登录验证的 +// if ( +// to.matched.some((r) => { +// return r.meta?.auth || r.meta?.permission; +// }) +// ) { +// const userStore = useUserStore(); +// // 这里暂时将cookie里是否存有token作为验证是否登录的条件 +// // 请根据自身业务需要修改 +// const token = userStore.getToken; +// if (token) { +// next(); +// } else { +// // 没有登录的时候跳转到登录界面 +// // 携带上登陆成功之后需要跳转的页面完整路径 +// next({ +// name: "login", +// query: { +// redirect: to.fullPath +// } +// }); +// // https://github.com/d2-projects/d2-admin/issues/138 +// NProgress.done(); +// } +// } else { +// // 不需要身份校验 直接通过 +// next(); +// } +// }); +// +// router.afterEach((to: any) => { +// // 进度条 +// NProgress.done(); +// // 多页控制 打开新的页面 +// const pageStore = usePageStore(); +// // for (const item of to.matched) { +// // pageStore.keepAlivePush(item.name); +// // } +// pageStore.open(to); +// // 更改标题 +// site.title(to.meta.title); +// +// //修改左侧边栏 +// const matched = to.matched; +// if (matched.length > 0) { +// const resourceStore = useResourceStore(); +// resourceStore.setAsideMenuByCurrentRoute(matched); +// } +// }); -/** - * 路由拦截 - */ -router.beforeEach(async (to, from, next) => { - // 进度条 - NProgress.start(); - // 修复三级以上路由页面无法缓存的问题 - if (to.matched && to.matched.length > 2) { - to.matched.splice(1, to.matched.length - 2); - } - // 验证当前路由所有的匹配中是否需要有登录验证的 - if ( - to.matched.some((r) => { - return r.meta?.auth || r.meta?.permission; - }) - ) { - const userStore = useUserStore(); - // 这里暂时将cookie里是否存有token作为验证是否登录的条件 - // 请根据自身业务需要修改 - const token = userStore.getToken; - if (token) { - next(); - } else { - // 没有登录的时候跳转到登录界面 - // 携带上登陆成功之后需要跳转的页面完整路径 - next({ - name: "login", - query: { - redirect: to.fullPath - } - }); - // https://github.com/d2-projects/d2-admin/issues/138 - NProgress.done(); - } - } else { - // 不需要身份校验 直接通过 - next(); - } -}); - -router.afterEach((to: any) => { - // 进度条 - NProgress.done(); - // 多页控制 打开新的页面 - const pageStore = usePageStore(); - // for (const item of to.matched) { - // pageStore.keepAlivePush(item.name); - // } - pageStore.open(to); - // 更改标题 - site.title(to.meta.title); - - //修改左侧边栏 - const matched = to.matched; - if (matched.length > 0) { - const resourceStore = useResourceStore(); - resourceStore.setAsideMenuByCurrentRoute(matched); - } -}); +createRouterGuard(router); export default router; diff --git a/packages/ui/certd-client/src/router/resolve.ts b/packages/ui/certd-client/src/router/resolve.ts index 9d65027d..8c36cc7d 100644 --- a/packages/ui/certd-client/src/router/resolve.ts +++ b/packages/ui/certd-client/src/router/resolve.ts @@ -152,4 +152,3 @@ const routes = [...outsideRoutes, ...frameworkRoutes]; const frameworkMenus = frameworkRet.menus; const headerMenus = headerRet.menus; export { routes, outsideRoutes, frameworkRoutes, frameworkMenus, headerMenus, findMenus, filterMenus }; - diff --git a/packages/ui/certd-client/src/router/source/framework.ts b/packages/ui/certd-client/src/router/source/framework.ts index b404e2f1..ed201a06 100644 --- a/packages/ui/certd-client/src/router/source/framework.ts +++ b/packages/ui/certd-client/src/router/source/framework.ts @@ -1,17 +1,26 @@ -import LayoutFramework from "/src/layout/layout-framework.vue"; -import { crudResources } from "/@/router/source/modules/crud"; -// import { uiResources } from "/@/router/source/modules/ui"; -// import { integrationResources } from "/@/router/source/modules/integration"; -import { sysResources } from "/@/router/source/modules/sys"; +import LayoutBasic from "/@/layout/layout-basic.vue"; + +import type { RouteRecordRaw } from "vue-router"; + +import { mergeRouteModules } from "/@/vben/utils"; + +const dynamicRouteFiles = import.meta.glob("./modules/**/*.ts", { + eager: true +}); + +/** 动态路由 */ +const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles); + export const frameworkResource = [ { title: "框架", - name: "framework", + name: "root", path: "/", redirect: "/index", - component: LayoutFramework, + component: LayoutBasic, meta: { - icon: "ion:accessibility" + icon: "ion:accessibility", + hideInBreadcrumb: true }, children: [ { @@ -22,12 +31,11 @@ export const frameworkResource = [ meta: { fixedAside: true, showOnHeader: false, - icon: "ion:home-outline" + icon: "ion:home-outline", + auth: true } }, - ...crudResources, - // ...integrationResources, - ...sysResources + ...dynamicRoutes ] } ]; diff --git a/packages/ui/certd-client/src/router/source/modules/crud.ts b/packages/ui/certd-client/src/router/source/modules/crud.ts index 07a32b0d..103a7a18 100644 --- a/packages/ui/certd-client/src/router/source/modules/crud.ts +++ b/packages/ui/certd-client/src/router/source/modules/crud.ts @@ -15,6 +15,7 @@ export const crudResources = [ component: "/crud/debug/index.vue", meta: { isMenu: false + // hideInMenu: true } }, { @@ -794,3 +795,5 @@ export const crudResources = [ ] } ]; + +export default crudResources; diff --git a/packages/ui/certd-client/src/router/source/modules/integration.ts b/packages/ui/certd-client/src/router/source/modules/integration.ts index 0b0c8cd8..3cc9ad25 100644 --- a/packages/ui/certd-client/src/router/source/modules/integration.ts +++ b/packages/ui/certd-client/src/router/source/modules/integration.ts @@ -1,3 +1,6 @@ +import type { RouteRecordRaw } from "vue-router"; +import BasicLayout from "/@/vben/layouts/basic/layout.vue"; + export const integrationResources = [ { title: "集成", @@ -20,3 +23,5 @@ export const integrationResources = [ ] } ]; + +// export default integrationResources; diff --git a/packages/ui/certd-client/src/router/source/modules/sys.ts b/packages/ui/certd-client/src/router/source/modules/sys.ts index a2d75127..4556c3ca 100644 --- a/packages/ui/certd-client/src/router/source/modules/sys.ts +++ b/packages/ui/certd-client/src/router/source/modules/sys.ts @@ -1,4 +1,5 @@ import LayoutPass from "/@/layout/layout-pass.vue"; +import BasicLayout from "/@/vben/layouts/basic/layout.vue"; export const sysResources = [ { @@ -6,7 +7,6 @@ export const sysResources = [ name: "sys", path: "/sys", redirect: "/sys/authority", - component: LayoutPass, meta: { icon: "ion:settings-outline", permission: "sys" @@ -59,3 +59,5 @@ export const sysResources = [ ] } ]; + +export default sysResources; diff --git a/packages/ui/certd-client/src/router/source/modules/ui.ts b/packages/ui/certd-client/src/router/source/modules/ui.ts index e8cfc6e4..de28579f 100644 --- a/packages/ui/certd-client/src/router/source/modules/ui.ts +++ b/packages/ui/certd-client/src/router/source/modules/ui.ts @@ -1,3 +1,5 @@ +import BasicLayout from "/@/vben/layouts/basic/layout.vue"; + export const uiResources = [ { title: "UI示例", @@ -28,3 +30,5 @@ export const uiResources = [ ] } ]; + +export default uiResources; diff --git a/packages/ui/certd-client/src/store/modules/page.ts b/packages/ui/certd-client/src/store/modules/page.ts deleted file mode 100644 index 39e06c65..00000000 --- a/packages/ui/certd-client/src/store/modules/page.ts +++ /dev/null @@ -1,436 +0,0 @@ -import { defineStore } from "pinia"; -import { cloneDeep, get, uniq } from "lodash-es"; -import router from "/src/router"; -import { frameworkRoutes } from "/src/router/resolve"; -// @ts-ignore -import { LocalStorage } from "/src/utils/util.storage"; -import { useUserStore } from "/src/store/modules/user"; -const OPENED_CACHE_KEY = "TABS_OPENED"; - -interface PageState { - // 可以在多页 tab 模式下显示的页面 - pool: Array; - // 当前显示的多页面列表 - opened: Array; - // 已经加载多标签页数据 https://github.com/d2-projects/d2-admin/issues/201 - openedLoaded: boolean; - // 当前页面 - current: string; - // 需要缓存的页面 name - keepAlive: Array; - inited: boolean; -} -// 判定是否需要缓存 -const isKeepAlive = (data: any) => get(data, "meta.cache", false); - -export const usePageStore = defineStore({ - id: "app.page", - state: (): PageState => ({ - // 可以在多页 tab 模式下显示的页面 - pool: [], - // 当前显示的多页面列表 - opened: [ - { - name: "index", - fullPath: "/index", - meta: { - title: "首页", - auth: false - } - } - ], - // 已经加载多标签页数据 https://github.com/d2-projects/d2-admin/issues/201 - openedLoaded: false, - // 当前页面 - current: "", - // 需要缓存的页面 name - keepAlive: [], - inited: false - }), - getters: { - getOpened(): any { - // @ts-ignore - return this.opened; - }, - getCurrent(): string { - return this.current; - } - }, - actions: { - /** - * @description 确认已经加载多标签页数据 https://github.com/d2-projects/d2-admin/issues/201 - * @param {Object} context - */ - async isLoaded() { - if (this.openedLoaded) { - return true; - } - return new Promise((resolve) => { - const timer = setInterval(() => { - if (this.openedLoaded) { - resolve(clearInterval(timer)); - } - }, 10); - }); - }, - /** - * @class opened - * @description 从持久化数据载入标签页列表 - * @param {Object} context - */ - async openedLoad() { - // store 赋值 - const value = LocalStorage.get(this.getStorageKey()); - if (value == null) { - return; - } - // 在处理函数中进行数据优化 过滤掉现在已经失效的页签或者已经改变了信息的页签 - // 以 fullPath 字段为准 - // 如果页面过多的话可能需要优化算法 - // valid 有效列表 1, 1, 0, 1 => 有效, 有效, 失效, 有效 - const valid: Array = []; - // 处理数据 - this.opened = value - .map((opened: any) => { - // 忽略首页 - if (opened.fullPath === "/index") { - valid.push(1); - return opened; - } - // 尝试在所有的支持多标签页的页面里找到 name 匹配的页面 - const find = this.pool.find((item) => item.name === opened.name); - // 记录有效或无效信息 - valid.push(find ? 1 : 0); - // 返回合并后的数据 新的覆盖旧的 - // 新的数据中一般不会携带 params 和 query, 所以旧的参数会留存 - return Object.assign({}, opened, find); - }) - .filter((opened: any, index: any) => valid[index] === 1); - // 标记已经加载多标签页数据 https://github.com/d2-projects/d2-admin/issues/201 - this.openedLoaded = true; - // 根据 opened 数据生成缓存设置 - this.keepAliveRefresh(); - }, - - getStorageKey() { - const userStore = useUserStore(); - const userId = userStore.getUserInfo?.id ?? "anonymous"; - return OPENED_CACHE_KEY + ":" + userId; - }, - /** - * 将 opened 属性赋值并持久化 在这之前请先确保已经更新了 state.opened - * @param {Object} context - */ - async opened2db() { - // 设置数据 - - LocalStorage.set(this.getStorageKey(), this.opened); - }, - /** - * @class opened - * @description 更新页面列表上的某一项 - * @param {Object} context - * @param {Object} payload { index, params, query, fullPath } 路由信息 - */ - async openedUpdate({ index, params, query, fullPath }: any) { - // 更新页面列表某一项 - const page = this.opened[index]; - page.params = params || page.params; - page.query = query || page.query; - page.fullPath = fullPath || page.fullPath; - this.opened.splice(index, 1, page); - // 持久化 - await this.opened2db(); - }, - /** - * @class opened - * @description 重排页面列表上的某一项 - * @param {Object} context - * @param {Object} payload { oldIndex, newIndex } 位置信息 - */ - async openedSort({ oldIndex, newIndex }: any) { - // 重排页面列表某一项 - const page = this.opened[oldIndex]; - this.opened.splice(oldIndex, 1); - this.opened.splice(newIndex, 0, page); - // 持久化 - await this.opened2db(); - }, - /** - * @class opened - * @description 新增一个 tag (打开一个页面) - * @param {Object} context - * @param {Object} payload new tag info - */ - async add({ tag, params, query, fullPath }: any) { - // 设置新的 tag 在新打开一个以前没打开过的页面时使用 - const newTag = tag; - newTag.params = params || newTag.params; - newTag.query = query || newTag.query; - newTag.fullPath = fullPath || newTag.fullPath; - // 添加进当前显示的页面数组 - this.opened.push(newTag); - // 如果这个页面需要缓存 将其添加到缓存设置 - if (isKeepAlive(newTag)) { - this.keepAlivePush(tag.name); - } - // 持久化 - await this.opened2db(); - }, - /** - * @class current - * @description 打开一个新的页面 - * @param {Object} context - * @param {Object} payload 从路由钩子的 to 对象上获取 { name, params, query, fullPath, meta } 路由信息 - */ - async open({ name, params, query, fullPath, meta }: any) { - // 已经打开的页面 - const opened = this.opened; - // 判断此页面是否已经打开 并且记录位置 - let pageOpendIndex = 0; - const pageOpend = opened.find((page, index) => { - const same = page.fullPath === fullPath; - pageOpendIndex = same ? index : pageOpendIndex; - return same; - }); - if (pageOpend) { - // 页面以前打开过 - await this.openedUpdate({ - index: pageOpendIndex, - params, - query, - fullPath - }); - } else { - // 页面以前没有打开过 - const page = this.pool.find((t) => t.name === name); - // 如果这里没有找到 page 代表这个路由虽然在框架内 但是不参与标签页显示 - if (page) { - this.add({ - tag: Object.assign({}, page), - params, - query, - fullPath - }); - } - } - // 如果这个页面需要缓存 将其添加到缓存设置 - if (isKeepAlive({ meta })) { - this.keepAlivePush(name); - } - // 设置当前的页面 - this.currentSet(fullPath); - }, - /** - * @class opened - * @description 关闭一个 tag (关闭一个页面) - * @param {Object} context - * @param {Object} payload { tagName: 要关闭的标签名字 } - */ - async close({ tagName }: any) { - // 预定下个新页面 - let newPage = {}; - const isCurrent = this.current === tagName; - // 如果关闭的页面就是当前显示的页面 - if (isCurrent) { - // 去找一个新的页面 - const len = this.opened.length; - for (let i = 0; i < len; i++) { - if (this.opened[i].fullPath === tagName) { - newPage = i < len - 1 ? this.opened[i + 1] : this.opened[i - 1]; - break; - } - } - } - // 找到这个页面在已经打开的数据里是第几个 - const index = this.opened.findIndex((page) => page.fullPath === tagName); - if (index >= 0) { - // 如果这个页面是缓存的页面 将其在缓存设置中删除 - this.keepAliveRemove(this.opened[index].name); - // 更新数据 删除关闭的页面 - this.opened.splice(index, 1); - } - // 持久化 - await this.opened2db(); - // 决定最后停留的页面 - if (isCurrent) { - // @ts-ignore - const { name = "index", params = {}, query = {} } = newPage; - const routerObj = { name, params, query }; - await router.push(routerObj); - } - }, - /** - * @class opened - * @description 关闭当前标签左边的标签 - * @param opts - */ - async closeLeft(opts = {}) { - await this.closeByCondition({ - condition({ i, currentIndex }: any) { - return i >= currentIndex; - }, - ...opts - }); - }, - /** - * @class opened - * @description 关闭当前标签右边的标签 - * @param opts - */ - async closeRight(opts = {}) { - await this.closeByCondition({ - condition({ i, currentIndex }: any) { - return currentIndex >= i; - }, - ...opts - }); - }, - /** - * @class opened - * @description 关闭当前标签右边的标签 - * @param opts - */ - async closeByCondition(opts = {}) { - // @ts-ignore - const { pageSelect, condition } = opts; - const pageAim = pageSelect || this.current; - let currentIndex = 0; - this.opened.forEach((page, index) => { - if (page.fullPath === pageAim) currentIndex = index; - }); - // 删除打开的页面 并在缓存设置中删除 - for (let i = this.opened.length - 1; i >= 0; i--) { - if (this.opened[i].name === "index" || condition({ i, currentIndex })) { - continue; - } - this.keepAliveRemove(this.opened[i].name); - this.opened.splice(i, 1); - } - // 持久化 - await this.opened2db(); - // 设置当前的页面 - this.current = pageAim; - // @ts-ignore - if (router.currentRoute.fullPath !== pageAim) await router.push(pageAim); - }, - /** - * @class opened - * @description 关闭当前激活之外的 tag - * @param opts - */ - async closeOther(opts = {}) { - await this.closeByCondition({ - condition({ i, currentIndex }: any) { - return currentIndex === i; - }, - ...opts - }); - }, - /** - * @class opened - * @description 关闭所有 tag - * @param {Object} context - */ - async closeAll() { - // 删除打开的页面 并在缓存设置中删除 - for (let i = this.opened.length - 1; i >= 0; i--) { - if (this.opened[i].name === "index") { - continue; - } - - this.keepAliveRemove(this.opened[i].name); - this.opened.splice(i, 1); - } - // 持久化 - await this.opened2db(); - // 关闭所有的标签页后需要判断一次现在是不是在首页 - // @ts-ignore - if (router.currentRoute.name !== "index") { - await router.push({ name: "index" }); - } - }, - /** - * @class keepAlive - * @description 从已经打开的页面记录中更新需要缓存的页面记录 - * @param {Object} state state - */ - keepAliveRefresh() { - this.keepAlive = this.opened.filter((item) => isKeepAlive(item)).map((e) => e.name); - console.log("keepalive", this.keepAlive); - }, - /** - * @description 删除一个页面的缓存设置 - * @param {Object} state state - * @param {String} name name - */ - keepAliveRemove(name: string) { - const list = cloneDeep(this.keepAlive); - const index = list.findIndex((item) => item === name); - if (index !== -1) { - list.splice(index, 1); - this.keepAlive = list; - } - }, - /** - * @description 增加一个页面的缓存设置 - * @param {Object} state state - * @param {String} name name - */ - keepAlivePush(name: string) { - const keep = cloneDeep(this.keepAlive); - keep.push(name); - this.keepAlive = uniq(keep); - }, - /** - * @description 清空页面缓存设置 - * @param {Object} state state - */ - keepAliveClean() { - this.keepAlive = []; - }, - /** - * @class current - * @description 设置当前激活的页面 fullPath - * @param {Object} state state - * @param {String} fullPath new fullPath - */ - currentSet(fullPath: string) { - this.current = fullPath; - }, - /** - * @class pool - * @description 保存 pool (候选池) - * @param {Object} state state - * @param {Array} routes routes - */ - async init(routes?: any) { - if (this.inited) { - return; - } - this.inited = true; - if (routes == null) { - //不能用全部的routes,只能是framework内的 - routes = frameworkRoutes; - } - - const pool: any = []; - const push = function (routes: any) { - routes.forEach((route: any) => { - if (route.children && route.children.length > 0) { - push(route.children); - } else { - if (!route.hidden) { - const { meta, name, path } = route; - // @ts-ignore - pool.push({ meta, name, path }); - } - } - }); - }; - push(routes); - this.pool = pool; - await this.openedLoad(); - } - } -}); diff --git a/packages/ui/certd-client/src/store/modules/resource.ts b/packages/ui/certd-client/src/store/modules/resource.ts deleted file mode 100644 index 965d2f54..00000000 --- a/packages/ui/certd-client/src/store/modules/resource.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { defineStore } from "pinia"; -// @ts-ignore -import { frameworkMenus, headerMenus, filterMenus, findMenus } from "/src/router/resolve"; -import _ from "lodash-es"; -import { mitter } from "/src/utils/util.mitt"; -//监听注销事件 -mitter.on("app.logout", () => { - const resourceStore = useResourceStore(); - resourceStore.clear(); -}); - -interface ResourceState { - frameworkMenus: Array; - headerMenus: Array; - asideMenus: Array; - fixedAsideMenus: Array; - inited: boolean; - currentAsidePath: string; -} - -export const useResourceStore = defineStore({ - id: "app.resource", - state: (): ResourceState => ({ - // user info - frameworkMenus: [], - headerMenus: [], - asideMenus: [], - fixedAsideMenus: [], - inited: false, - currentAsidePath: "" - }), - getters: { - getAsideMenus() { - return this.asideMenus; - }, - getHeaderMenus() { - return this.headerMenus; - }, - getFrameworkMenus() { - return this.frameworkMenus; - } - } as any, - actions: { - clear() { - this.inited = false; - }, - /** - * 初始化资源 - */ - init() { - if (this.inited) { - return; - } - this.inited = true; - - const showMenus = _.cloneDeep(frameworkMenus[0].children); - this.frameworkMenus = filterMenus(showMenus, (item: any) => { - return item?.meta?.showOnHeader !== false; - }); - - this.fixedAsideMenus = findMenus(showMenus, (item: any) => { - return item?.meta?.fixedAside === true; - }); - this.headerMenus = headerMenus; - this.setAsideMenu(); - }, - setAsideMenu(topMenu?: any) { - if (this.frameworkMenus.length === 0) { - return; - } - if (topMenu == null) { - topMenu = this.frameworkMenus[0]; - } - const asideMenus = topMenu?.children || []; - this.asideMenus = [...this.fixedAsideMenus, ...asideMenus]; - }, - setAsideMenuByCurrentRoute(matched: any) { - const menuHeader = this.frameworkMenus; - if (matched?.length <= 1) { - return; - } - - function findFromTree(tree: any, find: any) { - const results: Array = []; - for (const item of tree) { - if (find(item)) { - results.push(item); - return results; - } - if (item.children && item.children.length > 0) { - const found: any = findFromTree(item.children, find); - if (found) { - results.push(item); - return results.concat(found); - } - } - } - } - const matchedPath = matched[1].path; - const _side = findFromTree(menuHeader, (menu: any) => menu.path === matchedPath); - if (_side?.length > 0) { - if (this.currentAsidePath === _side[0]) { - return; - } - this.currentAsidePath = _side[0]; - this.setAsideMenu(_side[0]); - } - }, - filterByPermission(permissions: any) { - this.frameworkMenus = this.filterChildrenByPermission(this.frameworkMenus, permissions); - }, - filterChildrenByPermission(list: any, permissions: any) { - const menus = list.filter((item: any) => { - if (item?.meta?.permission) { - if (permissions.includes("*")) { - return true; - } - return permissions.includes(item.meta.permission); - } - return true; - }); - for (const menu of menus) { - if (menu.children && menu.children.length > 0) { - menu.children = this.filterChildrenByPermission(menu.children, permissions); - } - } - return menus; - } - } -}); diff --git a/packages/ui/certd-client/src/store/modules/settings.ts b/packages/ui/certd-client/src/store/modules/settings.ts deleted file mode 100644 index 2f7589db..00000000 --- a/packages/ui/certd-client/src/store/modules/settings.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { defineStore } from "pinia"; -import { theme } from "ant-design-vue"; -import _ from "lodash-es"; -// @ts-ignore -import { LocalStorage } from "/src/utils/util.storage"; -export type ThemeToken = { - token: { - colorPrimary?: string; - }; - algorithm: any; -}; -export type ThemeConfig = { - colorPrimary: string; - mode: string; -}; -export interface SettingState { - themeConfig?: ThemeConfig; - themeToken: ThemeToken; -} - -const defaultThemeConfig = { - colorPrimary: "#1890ff", - mode: "light" -}; -const SETTING_THEME_KEY = "SETTING_THEME"; -export const useSettingStore = defineStore({ - id: "app.setting", - state: (): SettingState => ({ - themeConfig: null, - themeToken: { - token: {}, - algorithm: theme.defaultAlgorithm - } - }), - getters: { - getThemeConfig(): any { - return this.themeConfig || _.merge({}, defaultThemeConfig, LocalStorage.get(SETTING_THEME_KEY) || {}); - } - }, - actions: { - persistThemeConfig() { - LocalStorage.set(SETTING_THEME_KEY, this.getThemeConfig); - }, - async setThemeConfig(themeConfig?: ThemeConfig) { - this.themeConfig = _.merge({}, this.themeConfig, themeConfig); - - this.persistThemeConfig(); - this.setPrimaryColor(this.themeConfig.colorPrimary); - this.setDarkMode(this.themeConfig.mode); - }, - setPrimaryColor(color: any) { - this.themeConfig.colorPrimary = color; - _.set(this.themeToken, "token.colorPrimary", color); - this.persistThemeConfig(); - }, - setDarkMode(mode: string) { - this.themeConfig.mode = mode; - if (mode === "dark") { - this.themeToken.algorithm = theme.darkAlgorithm; - // const defaultSeed = theme.defaultSeed; - // const mapToken = theme.darkAlgorithm(defaultSeed); - // less.modifyVars(mapToken); - // less.modifyVars({ - // "@colorPrimaryBg": "#111a2c", - // colorPrimaryBg: "#111a2c" - // }); - // less.refreshStyles(); - } else { - this.themeToken.algorithm = theme.defaultAlgorithm; - - // const defaultSeed = theme.defaultSeed; - // const mapToken = theme.defaultAlgorithm(defaultSeed); - // less.modifyVars(mapToken); - } - this.persistThemeConfig(); - }, - async init() { - await this.setThemeConfig(this.getThemeConfig); - } - } -}); diff --git a/packages/ui/certd-client/src/store/modules/user.ts b/packages/ui/certd-client/src/store/modules/user.ts index fcd71b87..d9c796f7 100644 --- a/packages/ui/certd-client/src/store/modules/user.ts +++ b/packages/ui/certd-client/src/store/modules/user.ts @@ -11,6 +11,7 @@ import { Modal } from "ant-design-vue"; import { useI18n } from "vue-i18n"; import { mitter } from "/src/utils/util.mitt"; +import { resetAllStores, useAccessStore } from "/@/vben/stores"; interface UserState { userInfo: Nullable; @@ -36,8 +37,10 @@ export const useUserStore = defineStore({ } }, actions: { - setToken(info: string, expire: number) { - this.token = info; + setToken(token: string, expire: number) { + this.token = token; + const accessStore = useAccessStore(); + accessStore.setAccessToken(token); LocalStorage.set(TOKEN_KEY, this.token, expire); }, setUserInfo(info: UserInfoRes) { @@ -79,6 +82,7 @@ export const useUserStore = defineStore({ */ logout(goLogin = true) { this.resetState(); + resetAllStores(); goLogin && router.push("/login"); mitter.emit("app.logout"); }, diff --git a/packages/ui/certd-client/src/style/antdv4.less b/packages/ui/certd-client/src/style/antdv4.less index 6acf779b..7ec2646b 100644 --- a/packages/ui/certd-client/src/style/antdv4.less +++ b/packages/ui/certd-client/src/style/antdv4.less @@ -26,3 +26,22 @@ padding-inline:revert; } + + +//适配手机端 +.ant-tour{ + max-width: 90vw +} + +.fs-page{ + .fs-page-header{ + background-color: hsl(var(--card)); + } + .fs-crud-table{ + background-color: hsl(var(--card)); + } +} + +footer{ + background-color: hsl(var(--card)) !important; +} diff --git a/packages/ui/certd-client/src/style/common.less b/packages/ui/certd-client/src/style/common.less index 17d83ccb..2fb12706 100644 --- a/packages/ui/certd-client/src/style/common.less +++ b/packages/ui/certd-client/src/style/common.less @@ -13,7 +13,7 @@ html, body { } body{ - min-width: 1000px; + //min-width: 1000px; } div#app { height: 100% @@ -46,10 +46,6 @@ h1, h2, h3, h4, h5, h6 { vertical-align: 0 !important; } -.flex{ - display: flex; - align-items: center; -} .ml-5{ diff --git a/packages/ui/certd-client/src/vben/access/access-control.vue b/packages/ui/certd-client/src/vben/access/access-control.vue new file mode 100644 index 00000000..ba3b5573 --- /dev/null +++ b/packages/ui/certd-client/src/vben/access/access-control.vue @@ -0,0 +1,47 @@ + + + + diff --git a/packages/ui/certd-client/src/vben/access/accessible.ts b/packages/ui/certd-client/src/vben/access/accessible.ts new file mode 100644 index 00000000..b9c7cb10 --- /dev/null +++ b/packages/ui/certd-client/src/vben/access/accessible.ts @@ -0,0 +1,84 @@ +import type { AccessModeType, GenerateMenuAndRoutesOptions, RouteRecordRaw } from "/@/vben/types"; + +import { cloneDeep, generateMenus, generateRoutesByBackend, generateRoutesByFrontend, mapTree } from "/@/vben/utils"; + +async function generateAccessible(mode: AccessModeType, options: GenerateMenuAndRoutesOptions) { + const { router } = options; + + options.routes = cloneDeep(options.routes); + // 生成路由 + const accessibleRoutes = await generateRoutes(mode, options); + + const root = router.getRoutes().find((item: any) => item.path === "/"); + + // 动态添加到router实例内 + accessibleRoutes.forEach((route) => { + if (root && !route.meta?.noBasicLayout) { + // 为了兼容之前的版本用法,如果包含子路由,则将component移除,以免出现多层BasicLayout + // 如果你的项目已经跟进了本次修改,移除了所有自定义菜单首级的BasicLayout,可以将这段if代码删除 + if (route.children && route.children.length > 0) { + delete route.component; + } + root.children?.push(route); + } else { + router.addRoute(route); + } + }); + + if (root) { + if (root.name) { + router.removeRoute(root.name); + } + router.addRoute(root); + } + + // 生成菜单 + const accessibleMenus = await generateMenus(accessibleRoutes, options.router); + + return { accessibleMenus, accessibleRoutes }; +} + +/** + * Generate routes + * @param mode + * @param options + */ +async function generateRoutes(mode: AccessModeType, options: GenerateMenuAndRoutesOptions) { + const { forbiddenComponent, roles, routes } = options; + + let resultRoutes: RouteRecordRaw[] = routes; + switch (mode) { + case "backend": { + resultRoutes = await generateRoutesByBackend(options); + break; + } + case "frontend": { + resultRoutes = await generateRoutesByFrontend(routes, roles || [], forbiddenComponent); + break; + } + } + + /** + * 调整路由树,做以下处理: + * 1. 对未添加redirect的路由添加redirect + */ + resultRoutes = mapTree(resultRoutes, (route) => { + // 如果有redirect或者没有子路由,则直接返回 + if (route.redirect || !route.children || route.children.length === 0) { + return route; + } + const firstChild = route.children[0]; + + // 如果子路由不是以/开头,则直接返回,这种情况需要计算全部父级的path才能得出正确的path,这里不做处理 + if (!firstChild?.path || !firstChild.path.startsWith("/")) { + return route; + } + + route.redirect = firstChild.path; + return route; + }); + + return resultRoutes; +} + +export { generateAccessible }; diff --git a/packages/ui/certd-client/src/vben/access/directive.ts b/packages/ui/certd-client/src/vben/access/directive.ts new file mode 100644 index 00000000..35d9d517 --- /dev/null +++ b/packages/ui/certd-client/src/vben/access/directive.ts @@ -0,0 +1,42 @@ +/** + * Global authority directive + * Used for fine-grained control of component permissions + * @Example v-access:role="[ROLE_NAME]" or v-access:role="ROLE_NAME" + * @Example v-access:code="[ROLE_CODE]" or v-access:code="ROLE_CODE" + */ +import type { App, Directive, DirectiveBinding } from 'vue'; + +import { useAccess } from './use-access'; + +function isAccessible( + el: Element, + binding: DirectiveBinding, +) { + const { accessMode, hasAccessByCodes, hasAccessByRoles } = useAccess(); + + const value = binding.value; + + if (!value) return; + const authMethod = + accessMode.value === 'frontend' && binding.arg === 'role' + ? hasAccessByRoles + : hasAccessByCodes; + + const values = Array.isArray(value) ? value : [value]; + + if (!authMethod(values)) { + el?.remove(); + } +} + +const mounted = (el: Element, binding: DirectiveBinding) => { + isAccessible(el, binding); +}; + +const authDirective: Directive = { + mounted, +}; + +export function registerAccessDirective(app: App) { + app.directive('access', authDirective); +} diff --git a/packages/ui/certd-client/src/vben/access/index.ts b/packages/ui/certd-client/src/vben/access/index.ts new file mode 100644 index 00000000..392aa53b --- /dev/null +++ b/packages/ui/certd-client/src/vben/access/index.ts @@ -0,0 +1,4 @@ +export { default as AccessControl } from './access-control.vue'; +export * from './accessible'; +export * from './directive'; +export * from './use-access'; diff --git a/packages/ui/certd-client/src/vben/access/use-access.ts b/packages/ui/certd-client/src/vben/access/use-access.ts new file mode 100644 index 00000000..2dbd6d01 --- /dev/null +++ b/packages/ui/certd-client/src/vben/access/use-access.ts @@ -0,0 +1,52 @@ +import { computed } from "vue"; + +import { preferences, updatePreferences } from "@vben/preferences"; +import { useAccessStore, useUserStore } from "@vben/stores"; + +function useAccess() { + const accessStore = useAccessStore(); + const userStore = useUserStore(); + const accessMode = computed(() => { + return preferences.app.accessMode; + }); + + /** + * 基于角色判断是否有权限 + * @description: Determine whether there is permission,The role is judged by the user's role + * @param roles + */ + function hasAccessByRoles(roles: string[]) { + const userRoleSet = new Set(userStore.userRoles); + const intersection = roles.filter((item) => userRoleSet.has(item)); + return intersection.length > 0; + } + + /** + * 基于权限码判断是否有权限 + * @description: Determine whether there is permission,The permission code is judged by the user's permission code + * @param codes + */ + function hasAccessByCodes(codes: string[]) { + const userCodesSet = new Set(accessStore.accessCodes); + + const intersection = codes.filter((item) => userCodesSet.has(item)); + return intersection.length > 0; + } + + async function toggleAccessMode() { + updatePreferences({ + app: { + accessMode: preferences.app.accessMode === "frontend" ? "backend" : "frontend" + } + }); + } + + return { + accessMode, + hasAccessByCodes, + hasAccessByRoles, + toggleAccessMode + }; +} + +export { useAccess }; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/api-component/api-component.vue b/packages/ui/certd-client/src/vben/common-ui/components/api-component/api-component.vue new file mode 100644 index 00000000..a12500e0 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/api-component/api-component.vue @@ -0,0 +1,200 @@ + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/api-component/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/api-component/index.ts new file mode 100644 index 00000000..9815763c --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/api-component/index.ts @@ -0,0 +1 @@ +export { default as ApiComponent } from './api-component.vue'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/hooks/useCaptchaPoints.ts b/packages/ui/certd-client/src/vben/common-ui/components/captcha/hooks/useCaptchaPoints.ts new file mode 100644 index 00000000..511fb3b7 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/hooks/useCaptchaPoints.ts @@ -0,0 +1,19 @@ +import type { CaptchaPoint } from '../types'; + +import { reactive } from 'vue'; + +export function useCaptchaPoints() { + const points = reactive([]); + function addPoint(point: CaptchaPoint) { + points.push(point); + } + + function clearPoints() { + points.splice(0, points.length); + } + return { + addPoint, + clearPoints, + points, + }; +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/captcha/index.ts new file mode 100644 index 00000000..6ad68c49 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/index.ts @@ -0,0 +1,6 @@ +export { default as PointSelectionCaptcha } from './point-selection-captcha/index.vue'; +export { default as PointSelectionCaptchaCard } from './point-selection-captcha/index.vue'; + +export { default as SliderCaptcha } from './slider-captcha/index.vue'; +export { default as SliderRotateCaptcha } from './slider-rotate-captcha/index.vue'; +export type * from './types'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/point-selection-captcha/index.vue b/packages/ui/certd-client/src/vben/common-ui/components/captcha/point-selection-captcha/index.vue new file mode 100644 index 00000000..3a8d2a38 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/point-selection-captcha/index.vue @@ -0,0 +1,176 @@ + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/point-selection-captcha/point-selection-captcha-card.vue b/packages/ui/certd-client/src/vben/common-ui/components/captcha/point-selection-captcha/point-selection-captcha-card.vue new file mode 100644 index 00000000..9bdf7d9c --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/point-selection-captcha/point-selection-captcha-card.vue @@ -0,0 +1,84 @@ + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/index.vue b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/index.vue new file mode 100644 index 00000000..5757fcb6 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/index.vue @@ -0,0 +1,244 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-action.vue b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-action.vue new file mode 100644 index 00000000..b449c540 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-action.vue @@ -0,0 +1,65 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-bar.vue b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-bar.vue new file mode 100644 index 00000000..0884ccb6 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-bar.vue @@ -0,0 +1,40 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-content.vue b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-content.vue new file mode 100644 index 00000000..905c1696 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-captcha/slider-captcha-content.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-rotate-captcha/index.vue b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-rotate-captcha/index.vue new file mode 100644 index 00000000..06f118ff --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/slider-rotate-captcha/index.vue @@ -0,0 +1,213 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/captcha/types.ts b/packages/ui/certd-client/src/vben/common-ui/components/captcha/types.ts new file mode 100644 index 00000000..481667a9 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/captcha/types.ts @@ -0,0 +1,175 @@ +import type { CSSProperties } from 'vue'; + +import type { ClassType } from '/@/vben/types'; + +export interface CaptchaData { + /** + * x + */ + x: number; + /** + * y + */ + y: number; + /** + * 时间戳 + */ + t: number; +} +export interface CaptchaPoint extends CaptchaData { + /** + * 数据索引 + */ + i: number; +} +export interface PointSelectionCaptchaCardProps { + /** + * 验证码图片 + */ + captchaImage: string; + /** + * 验证码图片高度 + * @default '220px' + */ + height?: number | string; + /** + * 水平内边距 + * @default '12px' + */ + paddingX?: number | string; + /** + * 垂直内边距 + * @default '16px' + */ + paddingY?: number | string; + /** + * 标题 + * @default '请按图依次点击' + */ + title?: string; + /** + * 验证码图片宽度 + * @default '300px' + */ + width?: number | string; +} + +export interface PointSelectionCaptchaProps + extends PointSelectionCaptchaCardProps { + /** + * 是否展示确定按钮 + * @default false + */ + showConfirm?: boolean; + /** + * 提示图片 + * @default '' + */ + hintImage?: string; + /** + * 提示文本 + * @default '' + */ + hintText?: string; +} + +export interface SliderCaptchaProps { + class?: ClassType; + /** + * @description 滑块的样式 + * @default {} + */ + actionStyle?: CSSProperties; + + /** + * @description 滑块条的样式 + * @default {} + */ + barStyle?: CSSProperties; + + /** + * @description 内容的样式 + * @default {} + */ + contentStyle?: CSSProperties; + + /** + * @description 组件的样式 + * @default {} + */ + wrapperStyle?: CSSProperties; + + /** + * @description 是否作为插槽使用,用于联动组件,可参考旋转校验组件 + * @default false + */ + isSlot?: boolean; + + /** + * @description 验证成功的提示 + * @default '验证通过' + */ + successText?: string; + + /** + * @description 提示文字 + * @default '请按住滑块拖动' + */ + text?: string; +} + +export interface SliderRotateCaptchaProps { + /** + * @description 旋转的角度 + * @default 20 + */ + diffDegree?: number; + + /** + * @description 图片的宽度 + * @default 260 + */ + imageSize?: number; + + /** + * @description 图片的样式 + * @default {} + */ + imageWrapperStyle?: CSSProperties; + + /** + * @description 最大旋转角度 + * @default 270 + */ + maxDegree?: number; + + /** + * @description 最小旋转角度 + * @default 90 + */ + minDegree?: number; + + /** + * @description 图片的地址 + */ + src?: string; + /** + * @description 默认提示文本 + */ + defaultTip?: string; +} + +export interface CaptchaVerifyPassingData { + isPassing: boolean; + time: number | string; +} + +export interface SliderCaptchaActionType { + resume: () => void; +} + +export interface SliderRotateVerifyPassingData { + event: MouseEvent | TouchEvent; + moveDistance: number; + moveX: number; +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/col-page/col-page.vue b/packages/ui/certd-client/src/vben/common-ui/components/col-page/col-page.vue new file mode 100644 index 00000000..9d583ebe --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/col-page/col-page.vue @@ -0,0 +1,107 @@ + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/col-page/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/col-page/index.ts new file mode 100644 index 00000000..11b33058 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/col-page/index.ts @@ -0,0 +1,2 @@ +export { default as ColPage } from './col-page.vue'; +export * from './types'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/col-page/types.ts b/packages/ui/certd-client/src/vben/common-ui/components/col-page/types.ts new file mode 100644 index 00000000..491d1e6d --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/col-page/types.ts @@ -0,0 +1,26 @@ +import type { PageProps } from '../page/types'; + +export interface ColPageProps extends PageProps { + /** + * 左侧宽度 + * @default 30 + */ + leftWidth?: number; + leftMinWidth?: number; + leftMaxWidth?: number; + leftCollapsedWidth?: number; + leftCollapsible?: boolean; + /** + * 右侧宽度 + * @default 70 + */ + rightWidth?: number; + rightMinWidth?: number; + rightCollapsedWidth?: number; + rightMaxWidth?: number; + rightCollapsible?: boolean; + + resizable?: boolean; + splitLine?: boolean; + splitHandle?: boolean; +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/count-to/count-to.vue b/packages/ui/certd-client/src/vben/common-ui/components/count-to/count-to.vue new file mode 100644 index 00000000..b40f9f45 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/count-to/count-to.vue @@ -0,0 +1,123 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/count-to/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/count-to/index.ts new file mode 100644 index 00000000..d942796e --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/count-to/index.ts @@ -0,0 +1,2 @@ +export { default as CountTo } from './count-to.vue'; +export * from './types'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/count-to/types.ts b/packages/ui/certd-client/src/vben/common-ui/components/count-to/types.ts new file mode 100644 index 00000000..0b3bd82d --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/count-to/types.ts @@ -0,0 +1,53 @@ +import type { CubicBezierPoints, EasingFunction } from '@vueuse/core'; + +import type { StyleValue } from 'vue'; + +import { TransitionPresets as TransitionPresetsData } from '@vueuse/core'; + +export type TransitionPresets = keyof typeof TransitionPresetsData; + +export const TransitionPresetsKeys = Object.keys( + TransitionPresetsData, +) as TransitionPresets[]; + +export interface CountToProps { + /** 初始值 */ + startVal?: number; + /** 当前值 */ + endVal: number; + /** 是否禁用动画 */ + disabled?: boolean; + /** 延迟动画开始的时间 */ + delay?: number; + /** 持续时间 */ + duration?: number; + /** 小数位数 */ + decimals?: number; + /** 小数点 */ + decimal?: string; + /** 分隔符 */ + separator?: string; + /** 前缀 */ + prefix?: string; + /** 后缀 */ + suffix?: string; + /** 过渡效果 */ + transition?: CubicBezierPoints | EasingFunction | TransitionPresets; + /** 整数部分的类名 */ + mainClass?: string; + /** 小数部分的类名 */ + decimalClass?: string; + /** 前缀部分的类名 */ + prefixClass?: string; + /** 后缀部分的类名 */ + suffixClass?: string; + + /** 整数部分的样式 */ + mainStyle?: StyleValue; + /** 小数部分的样式 */ + decimalStyle?: StyleValue; + /** 前缀部分的样式 */ + prefixStyle?: StyleValue; + /** 后缀部分的样式 */ + suffixStyle?: StyleValue; +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/ellipsis-text/ellipsis-text.vue b/packages/ui/certd-client/src/vben/common-ui/components/ellipsis-text/ellipsis-text.vue new file mode 100644 index 00000000..587da3d7 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/ellipsis-text/ellipsis-text.vue @@ -0,0 +1,148 @@ + + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/ellipsis-text/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/ellipsis-text/index.ts new file mode 100644 index 00000000..67a236c9 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/ellipsis-text/index.ts @@ -0,0 +1 @@ +export { default as EllipsisText } from './ellipsis-text.vue'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/icon-picker/icon-picker.vue b/packages/ui/certd-client/src/vben/common-ui/components/icon-picker/icon-picker.vue new file mode 100644 index 00000000..cfc5152f --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/icon-picker/icon-picker.vue @@ -0,0 +1,304 @@ + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/icon-picker/icons.ts b/packages/ui/certd-client/src/vben/common-ui/components/icon-picker/icons.ts new file mode 100644 index 00000000..0bc18ef5 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/icon-picker/icons.ts @@ -0,0 +1,56 @@ +import type { Recordable } from '/@/vben/types'; + +/** + * 一个缓存对象,在不刷新页面时,无需重复请求远程接口 + */ +export const ICONS_MAP: Recordable = {}; + +interface IconifyResponse { + prefix: string; + total: number; + title: string; + uncategorized?: string[]; + categories?: Recordable; + aliases?: Recordable; +} + +const PENDING_REQUESTS: Recordable> = {}; + +/** + * 通过Iconify接口获取图标集数据。 + * 同一时间多个图标选择器同时请求同一个图标集时,实际上只会发起一次请求(所有请求共享同一份结果)。 + * 请求结果会被缓存,刷新页面前同一个图标集不会再次请求 + * @param prefix 图标集名称 + * @returns 图标集中包含的所有图标名称 + */ +export async function fetchIconsData(prefix: string): Promise { + if (Reflect.has(ICONS_MAP, prefix) && ICONS_MAP[prefix]) { + return ICONS_MAP[prefix]; + } + if (Reflect.has(PENDING_REQUESTS, prefix) && PENDING_REQUESTS[prefix]) { + return PENDING_REQUESTS[prefix]; + } + PENDING_REQUESTS[prefix] = (async () => { + try { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 1000 * 10); + const response: IconifyResponse = await fetch( + `https://api.iconify.design/collection?prefix=${prefix}`, + { signal: controller.signal }, + ).then((res) => res.json()); + clearTimeout(timeoutId); + const list = response.uncategorized || []; + if (response.categories) { + for (const category in response.categories) { + list.push(...(response.categories[category] || [])); + } + } + ICONS_MAP[prefix] = list.map((v) => `${prefix}:${v}`); + } catch (error) { + console.error(`Failed to fetch icons for prefix ${prefix}:`, error); + return [] as string[]; + } + return ICONS_MAP[prefix]; + })(); + return PENDING_REQUESTS[prefix]; +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/icon-picker/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/icon-picker/index.ts new file mode 100644 index 00000000..3dabc86a --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/icon-picker/index.ts @@ -0,0 +1 @@ +export { default as IconPicker } from './icon-picker.vue'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/index.ts new file mode 100644 index 00000000..75024870 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/index.ts @@ -0,0 +1,27 @@ +export * from './api-component'; +export * from './captcha'; +export * from './col-page'; +export * from './count-to'; +export * from './ellipsis-text'; +export * from './icon-picker'; +export * from './json-viewer'; +export * from './loading'; +export * from './page'; +export * from './resize'; +export * from './tippy'; +export * from '/@/vben/form-ui'; +export * from '/@/vben/popup-ui'; + +// 给文档用 +export { + VbenButton, + VbenButtonGroup, + VbenCheckButtonGroup, + VbenCountToAnimator, + VbenInputPassword, + VbenLoading, + VbenPinInput, + VbenSpinner, +} from '/@/vben/shadcn-ui'; + +export { globalShareState } from '/@/vben/shared/global-state'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/index.ts new file mode 100644 index 00000000..1aec78bb --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/index.ts @@ -0,0 +1,3 @@ +export { default as JsonViewer } from './index.vue'; + +export * from './types'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/index.vue b/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/index.vue new file mode 100644 index 00000000..1ef6b833 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/index.vue @@ -0,0 +1,98 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/style.scss b/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/style.scss new file mode 100644 index 00000000..73ce22b9 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/style.scss @@ -0,0 +1,98 @@ +.default-json-theme { + font-family: Consolas, Menlo, Courier, monospace; + font-size: 14px; + color: hsl(var(--foreground)); + white-space: nowrap; + background: hsl(var(--background)); + + &.jv-container.boxed { + border: 1px solid hsl(var(--border)); + } + + .jv-ellipsis { + display: inline-block; + padding: 0 4px 2px; + font-size: 0.9em; + line-height: 0.9; + color: hsl(var(--secondary-foreground)); + vertical-align: 2px; + cursor: pointer; + user-select: none; + background-color: hsl(var(--secondary)); + border-radius: 3px; + } + + .jv-button { + color: hsl(var(--primary)); + } + + .jv-key { + color: hsl(var(--heavy-foreground)); + } + + .jv-item { + &.jv-array { + color: hsl(var(--heavy-foreground)); + } + + &.jv-boolean { + color: hsl(var(--red-400)); + } + + &.jv-function { + color: hsl(var(--destructive-foreground)); + } + + &.jv-number { + color: hsl(var(--info-foreground)); + } + + &.jv-number-float { + color: hsl(var(--info-foreground)); + } + + &.jv-number-integer { + color: hsl(var(--info-foreground)); + } + + &.jv-object { + color: hsl(var(--accent-darker)); + } + + &.jv-undefined { + color: hsl(var(--secondary-foreground)); + } + + &.jv-string { + color: hsl(var(--primary)); + word-break: break-word; + white-space: normal; + } + } + + &.jv-container .jv-code { + padding: 10px; + + &.boxed:not(.open) { + padding-bottom: 20px; + margin-bottom: 10px; + } + + &.open { + padding-bottom: 10px; + } + + .jv-toggle { + &::before { + padding: 0 2px; + border-radius: 2px; + } + + &:hover { + &::before { + background: hsl(var(--accent-foreground)); + } + } + } + } +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/types.ts b/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/types.ts new file mode 100644 index 00000000..8f3a206e --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/json-viewer/types.ts @@ -0,0 +1,44 @@ +export interface JsonViewerProps { + /** 要展示的结构数据 */ + value: any; + /** 展开深度 */ + expandDepth?: number; + /** 是否可复制 */ + copyable?: boolean; + /** 是否排序 */ + sort?: boolean; + /** 显示边框 */ + boxed?: boolean; + /** 主题 */ + theme?: string; + /** 是否展开 */ + expanded?: boolean; + /** 时间格式化函数 */ + timeformat?: (time: Date | number | string) => string; + /** 预览模式 */ + previewMode?: boolean; + /** 显示数组索引 */ + showArrayIndex?: boolean; + /** 显示双引号 */ + showDoubleQuotes?: boolean; +} + +export interface JsonViewerAction { + action: string; + text: string; + trigger: HTMLElement; +} + +export interface JsonViewerValue { + value: any; + path: string; + depth: number; + el: HTMLElement; +} + +export interface JsonViewerToggle { + /** 鼠标事件 */ + event: MouseEvent; + /** 当前展开状态 */ + open: boolean; +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/loading/directive.ts b/packages/ui/certd-client/src/vben/common-ui/components/loading/directive.ts new file mode 100644 index 00000000..0387a881 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/loading/directive.ts @@ -0,0 +1,132 @@ +import type { App, Directive, DirectiveBinding } from 'vue'; + +import { h, render } from 'vue'; + +import { VbenLoading, VbenSpinner } from '/@/vben/shadcn-ui'; +import { isString } from '/@/vben/shared/utils'; + +const LOADING_INSTANCE_KEY = Symbol('loading'); +const SPINNER_INSTANCE_KEY = Symbol('spinner'); + +const CLASS_NAME_RELATIVE = 'spinner-parent--relative'; + +const loadingDirective: Directive = { + mounted(el, binding) { + const instance = h(VbenLoading, getOptions(binding)); + render(instance, el); + + el.classList.add(CLASS_NAME_RELATIVE); + el[LOADING_INSTANCE_KEY] = instance; + }, + unmounted(el) { + const instance = el[LOADING_INSTANCE_KEY]; + el.classList.remove(CLASS_NAME_RELATIVE); + render(null, el); + instance.el.remove(); + + el[LOADING_INSTANCE_KEY] = null; + }, + + updated(el, binding) { + const instance = el[LOADING_INSTANCE_KEY]; + const options = getOptions(binding); + if (options && instance?.component) { + try { + Object.keys(options).forEach((key) => { + instance.component.props[key] = options[key]; + }); + instance.component.update(); + } catch (error) { + console.error( + 'Failed to update loading component in directive:', + error, + ); + } + } + }, +}; + +function getOptions(binding: DirectiveBinding) { + if (binding.value === undefined) { + return { spinning: true }; + } else if (typeof binding.value === 'boolean') { + return { spinning: binding.value }; + } else { + return { ...binding.value }; + } +} + +const spinningDirective: Directive = { + mounted(el, binding) { + const instance = h(VbenSpinner, getOptions(binding)); + render(instance, el); + + el.classList.add(CLASS_NAME_RELATIVE); + el[SPINNER_INSTANCE_KEY] = instance; + }, + unmounted(el) { + const instance = el[SPINNER_INSTANCE_KEY]; + el.classList.remove(CLASS_NAME_RELATIVE); + render(null, el); + instance.el.remove(); + + el[SPINNER_INSTANCE_KEY] = null; + }, + + updated(el, binding) { + const instance = el[SPINNER_INSTANCE_KEY]; + const options = getOptions(binding); + if (options && instance?.component) { + try { + Object.keys(options).forEach((key) => { + instance.component.props[key] = options[key]; + }); + instance.component.update(); + } catch (error) { + console.error( + 'Failed to update spinner component in directive:', + error, + ); + } + } + }, +}; + +type loadingDirectiveParams = { + /** 是否注册loading指令。如果提供一个string,则将指令注册为指定的名称 */ + loading?: boolean | string; + /** 是否注册spinning指令。如果提供一个string,则将指令注册为指定的名称 */ + spinning?: boolean | string; +}; + +/** + * 注册loading指令 + * @param app + * @param params + */ +export function registerLoadingDirective( + app: App, + params?: loadingDirectiveParams, +) { + // 注入一个样式供指令使用,确保容器是相对定位 + const style = document.createElement('style'); + style.id = CLASS_NAME_RELATIVE; + style.innerHTML = ` + .${CLASS_NAME_RELATIVE} { + position: relative !important; + } + `; + document.head.append(style); + if (params?.loading !== false) { + app.directive( + isString(params?.loading) ? params.loading : 'loading', + loadingDirective, + ); + } + if (params?.spinning !== false) { + app.directive( + isString(params?.spinning) ? params.spinning : 'spinning', + spinningDirective, + ); + } +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/loading/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/loading/index.ts new file mode 100644 index 00000000..2fbfb047 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/loading/index.ts @@ -0,0 +1,3 @@ +export * from './directive'; +export { default as Loading } from './loading.vue'; +export { default as Spinner } from './spinner.vue'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/loading/loading.vue b/packages/ui/certd-client/src/vben/common-ui/components/loading/loading.vue new file mode 100644 index 00000000..bfc08261 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/loading/loading.vue @@ -0,0 +1,39 @@ + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/loading/spinner.vue b/packages/ui/certd-client/src/vben/common-ui/components/loading/spinner.vue new file mode 100644 index 00000000..5e6684a2 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/loading/spinner.vue @@ -0,0 +1,28 @@ + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/page/__tests__/page.test.ts b/packages/ui/certd-client/src/vben/common-ui/components/page/__tests__/page.test.ts new file mode 100644 index 00000000..a89061f5 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/page/__tests__/page.test.ts @@ -0,0 +1,89 @@ +import { mount } from '@vue/test-utils'; + +import { describe, expect, it } from 'vitest'; + +import { Page } from '..'; + +describe('page.vue', () => { + it('renders title when passed', () => { + const wrapper = mount(Page, { + props: { + title: 'Test Title', + }, + }); + + expect(wrapper.text()).toContain('Test Title'); + }); + + it('renders description when passed', () => { + const wrapper = mount(Page, { + props: { + description: 'Test Description', + }, + }); + + expect(wrapper.text()).toContain('Test Description'); + }); + + it('renders default slot content', () => { + const wrapper = mount(Page, { + slots: { + default: '

Default Slot Content

', + }, + }); + + expect(wrapper.html()).toContain('

Default Slot Content

'); + }); + + it('renders footer slot when showFooter is true', () => { + const wrapper = mount(Page, { + props: { + showFooter: true, + }, + slots: { + footer: '

Footer Slot Content

', + }, + }); + + expect(wrapper.html()).toContain('

Footer Slot Content

'); + }); + + it('applies the custom contentClass', () => { + const wrapper = mount(Page, { + props: { + contentClass: 'custom-class', + }, + }); + + const contentDiv = wrapper.find('.p-4'); + expect(contentDiv.classes()).toContain('custom-class'); + }); + + it('does not render title slot if title prop is provided', () => { + const wrapper = mount(Page, { + props: { + title: 'Test Title', + }, + slots: { + title: '

Title Slot Content

', + }, + }); + + expect(wrapper.text()).toContain('Title Slot Content'); + expect(wrapper.html()).not.toContain('Test Title'); + }); + + it('does not render description slot if description prop is provided', () => { + const wrapper = mount(Page, { + props: { + description: 'Test Description', + }, + slots: { + description: '

Description Slot Content

', + }, + }); + + expect(wrapper.text()).toContain('Description Slot Content'); + expect(wrapper.html()).not.toContain('Test Description'); + }); +}); diff --git a/packages/ui/certd-client/src/vben/common-ui/components/page/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/page/index.ts new file mode 100644 index 00000000..fd9e02f2 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/page/index.ts @@ -0,0 +1,2 @@ +export { default as Page } from './page.vue'; +export * from './types'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/page/page.vue b/packages/ui/certd-client/src/vben/common-ui/components/page/page.vue new file mode 100644 index 00000000..557336bc --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/page/page.vue @@ -0,0 +1,105 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/page/types.ts b/packages/ui/certd-client/src/vben/common-ui/components/page/types.ts new file mode 100644 index 00000000..5316d08d --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/page/types.ts @@ -0,0 +1,11 @@ +export interface PageProps { + title?: string; + description?: string; + contentClass?: string; + /** + * 根据content可见高度自适应 + */ + autoContentHeight?: boolean; + headerClass?: string; + footerClass?: string; +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/resize/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/resize/index.ts new file mode 100644 index 00000000..f9375221 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/resize/index.ts @@ -0,0 +1 @@ +export { default as VResize } from './resize.vue'; diff --git a/packages/ui/certd-client/src/vben/common-ui/components/resize/resize.vue b/packages/ui/certd-client/src/vben/common-ui/components/resize/resize.vue new file mode 100644 index 00000000..aaf89eaf --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/resize/resize.vue @@ -0,0 +1,1122 @@ + + + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/components/tippy/directive.ts b/packages/ui/certd-client/src/vben/common-ui/components/tippy/directive.ts new file mode 100644 index 00000000..ed277d6a --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/tippy/directive.ts @@ -0,0 +1,100 @@ +import type { ComputedRef, Directive } from 'vue'; + +import { useTippy } from 'vue-tippy'; + +export default function useTippyDirective(isDark: ComputedRef) { + const directive: Directive = { + mounted(el, binding, vnode) { + const opts = + typeof binding.value === 'string' + ? { content: binding.value } + : binding.value || {}; + + const modifiers = Object.keys(binding.modifiers || {}); + const placement = modifiers.find((modifier) => modifier !== 'arrow'); + const withArrow = modifiers.includes('arrow'); + + if (placement) { + opts.placement = opts.placement || placement; + } + + if (withArrow) { + opts.arrow = opts.arrow === undefined ? true : opts.arrow; + } + + if (vnode.props && vnode.props.onTippyShow) { + opts.onShow = function (...args: any[]) { + return vnode.props?.onTippyShow(...args); + }; + } + + if (vnode.props && vnode.props.onTippyShown) { + opts.onShown = function (...args: any[]) { + return vnode.props?.onTippyShown(...args); + }; + } + + if (vnode.props && vnode.props.onTippyHidden) { + opts.onHidden = function (...args: any[]) { + return vnode.props?.onTippyHidden(...args); + }; + } + + if (vnode.props && vnode.props.onTippyHide) { + opts.onHide = function (...args: any[]) { + return vnode.props?.onTippyHide(...args); + }; + } + + if (vnode.props && vnode.props.onTippyMount) { + opts.onMount = function (...args: any[]) { + return vnode.props?.onTippyMount(...args); + }; + } + + if (el.getAttribute('title') && !opts.content) { + opts.content = el.getAttribute('title'); + el.removeAttribute('title'); + } + + if (el.getAttribute('content') && !opts.content) { + opts.content = el.getAttribute('content'); + } + + useTippy(el, opts); + }, + unmounted(el) { + if (el.$tippy) { + el.$tippy.destroy(); + } else if (el._tippy) { + el._tippy.destroy(); + } + }, + + updated(el, binding) { + const opts = + typeof binding.value === 'string' + ? { content: binding.value, theme: isDark.value ? '' : 'light' } + : Object.assign( + { theme: isDark.value ? '' : 'light' }, + binding.value, + ); + + if (el.getAttribute('title') && !opts.content) { + opts.content = el.getAttribute('title'); + el.removeAttribute('title'); + } + + if (el.getAttribute('content') && !opts.content) { + opts.content = el.getAttribute('content'); + } + + if (el.$tippy) { + el.$tippy.setProps(opts || {}); + } else if (el._tippy) { + el._tippy.setProps(opts || {}); + } + }, + }; + return directive; +} diff --git a/packages/ui/certd-client/src/vben/common-ui/components/tippy/index.ts b/packages/ui/certd-client/src/vben/common-ui/components/tippy/index.ts new file mode 100644 index 00000000..59439ce7 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/components/tippy/index.ts @@ -0,0 +1,67 @@ +import type { DefaultProps, Props } from 'tippy.js'; + +import type { App, SetupContext } from 'vue'; + +import { h, watchEffect } from 'vue'; +import { setDefaultProps, Tippy as TippyComponent } from 'vue-tippy'; + +import { usePreferences } from '/@/vben/preferences'; + +import useTippyDirective from './directive'; + +import 'tippy.js/dist/tippy.css'; +import 'tippy.js/dist/backdrop.css'; +import 'tippy.js/themes/light.css'; +import 'tippy.js/animations/scale.css'; +import 'tippy.js/animations/shift-toward.css'; +import 'tippy.js/animations/shift-away.css'; +import 'tippy.js/animations/perspective.css'; + +const { isDark } = usePreferences(); +export type TippyProps = Partial< + Props & { + animation?: + | 'fade' + | 'perspective' + | 'scale' + | 'shift-away' + | 'shift-toward' + | boolean; + theme?: 'auto' | 'dark' | 'light'; + } +>; + +export function initTippy(app: App, options?: DefaultProps) { + setDefaultProps({ + allowHTML: true, + delay: [500, 200], + theme: isDark.value ? '' : 'light', + ...options, + }); + if (!options || !Reflect.has(options, 'theme') || options.theme === 'auto') { + watchEffect(() => { + setDefaultProps({ theme: isDark.value ? '' : 'light' }); + }); + } + + app.directive('tippy', useTippyDirective(isDark)); +} + +export const Tippy = (props: any, { attrs, slots }: SetupContext) => { + let theme: string = (attrs.theme as string) ?? 'auto'; + if (theme === 'auto') { + theme = isDark.value ? '' : 'light'; + } + if (theme === 'dark') { + theme = ''; + } + return h( + TippyComponent, + { + ...props, + ...attrs, + theme, + }, + slots, + ); +}; diff --git a/packages/ui/certd-client/src/vben/common-ui/index.ts b/packages/ui/certd-client/src/vben/common-ui/index.ts new file mode 100644 index 00000000..27bd7186 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/index.ts @@ -0,0 +1,2 @@ +export * from './components'; +export * from './ui'; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/about/about.ts b/packages/ui/certd-client/src/vben/common-ui/ui/about/about.ts new file mode 100644 index 00000000..c4cf9579 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/about/about.ts @@ -0,0 +1,14 @@ +import type { Component } from 'vue'; + +interface AboutProps { + description?: string; + name?: string; + title?: string; +} + +interface DescriptionItem { + content: Component | string; + title: string; +} + +export type { AboutProps, DescriptionItem }; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/about/about.vue b/packages/ui/certd-client/src/vben/common-ui/ui/about/about.vue new file mode 100644 index 00000000..2c1e4976 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/about/about.vue @@ -0,0 +1,183 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/about/index.ts b/packages/ui/certd-client/src/vben/common-ui/ui/about/index.ts new file mode 100644 index 00000000..5860f5b9 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/about/index.ts @@ -0,0 +1 @@ +export { default as About } from './about.vue'; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/auth-title.vue b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/auth-title.vue new file mode 100644 index 00000000..3ed9a6be --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/auth-title.vue @@ -0,0 +1,13 @@ + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/code-login.vue b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/code-login.vue new file mode 100644 index 00000000..e2e8b865 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/code-login.vue @@ -0,0 +1,117 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/forget-password.vue b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/forget-password.vue new file mode 100644 index 00000000..c1554a65 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/forget-password.vue @@ -0,0 +1,116 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/index.ts b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/index.ts new file mode 100644 index 00000000..ac5e1e01 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/index.ts @@ -0,0 +1,7 @@ +export { default as AuthenticationCodeLogin } from './code-login.vue'; +export { default as AuthenticationForgetPassword } from './forget-password.vue'; +export { default as AuthenticationLoginExpiredModal } from './login-expired-modal.vue'; +export { default as AuthenticationLogin } from './login.vue'; +export { default as AuthenticationQrCodeLogin } from './qrcode-login.vue'; +export { default as AuthenticationRegister } from './register.vue'; +export type { AuthenticationProps } from './types'; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/login-expired-modal.vue b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/login-expired-modal.vue new file mode 100644 index 00000000..cbdb7167 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/login-expired-modal.vue @@ -0,0 +1,79 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/login.vue b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/login.vue new file mode 100644 index 00000000..a5f2bb06 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/login.vue @@ -0,0 +1,186 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/qrcode-login.vue b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/qrcode-login.vue new file mode 100644 index 00000000..2b278b99 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/qrcode-login.vue @@ -0,0 +1,95 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/register.vue b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/register.vue new file mode 100644 index 00000000..8ed35613 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/register.vue @@ -0,0 +1,121 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/third-party-login.vue b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/third-party-login.vue new file mode 100644 index 00000000..ff334200 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/third-party-login.vue @@ -0,0 +1,37 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/authentication/types.ts b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/types.ts new file mode 100644 index 00000000..cb297e2e --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/authentication/types.ts @@ -0,0 +1,70 @@ +interface AuthenticationProps { + /** + * @zh_CN 验证码登录路径 + */ + codeLoginPath?: string; + /** + * @zh_CN 忘记密码路径 + */ + forgetPasswordPath?: string; + + /** + * @zh_CN 是否处于加载处理状态 + */ + loading?: boolean; + + /** + * @zh_CN 二维码登录路径 + */ + qrCodeLoginPath?: string; + + /** + * @zh_CN 注册路径 + */ + registerPath?: string; + + /** + * @zh_CN 是否显示验证码登录 + */ + showCodeLogin?: boolean; + /** + * @zh_CN 是否显示忘记密码 + */ + showForgetPassword?: boolean; + + /** + * @zh_CN 是否显示二维码登录 + */ + showQrcodeLogin?: boolean; + + /** + * @zh_CN 是否显示注册按钮 + */ + showRegister?: boolean; + + /** + * @zh_CN 是否显示记住账号 + */ + showRememberMe?: boolean; + + /** + * @zh_CN 是否显示第三方登录 + */ + showThirdPartyLogin?: boolean; + + /** + * @zh_CN 登录框子标题 + */ + subTitle?: string; + + /** + * @zh_CN 登录框标题 + */ + title?: string; + /** + * @zh_CN 提交按钮文本 + */ + submitButtonText?: string; +} + +export type { AuthenticationProps }; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-chart-card.vue b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-chart-card.vue new file mode 100644 index 00000000..b02ed374 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-chart-card.vue @@ -0,0 +1,24 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-charts-tabs.vue b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-charts-tabs.vue new file mode 100644 index 00000000..1ed35fdb --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-charts-tabs.vue @@ -0,0 +1,40 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-overview.vue b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-overview.vue new file mode 100644 index 00000000..dc91b3ef --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/analysis-overview.vue @@ -0,0 +1,55 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/index.ts b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/index.ts new file mode 100644 index 00000000..7c67b872 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/analysis/index.ts @@ -0,0 +1,3 @@ +export { default as AnalysisChartCard } from './analysis-chart-card.vue'; +export { default as AnalysisChartsTabs } from './analysis-charts-tabs.vue'; +export { default as AnalysisOverview } from './analysis-overview.vue'; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/index.ts b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/index.ts new file mode 100644 index 00000000..bc74424b --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/index.ts @@ -0,0 +1,3 @@ +export * from './analysis'; +export type * from './typing'; +export * from './workbench'; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/typing.ts b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/typing.ts new file mode 100644 index 00000000..48fc9c7b --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/typing.ts @@ -0,0 +1,48 @@ +import type { Component } from 'vue'; + +interface AnalysisOverviewItem { + icon: Component | string; + title: string; + totalTitle: string; + totalValue: number; + value: number; +} + +interface WorkbenchProjectItem { + color?: string; + content: string; + date: string; + group: string; + icon: Component | string; + title: string; + url?: string; +} + +interface WorkbenchTrendItem { + avatar: string; + content: string; + date: string; + title: string; +} + +interface WorkbenchTodoItem { + completed: boolean; + content: string; + date: string; + title: string; +} + +interface WorkbenchQuickNavItem { + color?: string; + icon: Component | string; + title: string; + url?: string; +} + +export type { + AnalysisOverviewItem, + WorkbenchProjectItem, + WorkbenchQuickNavItem, + WorkbenchTodoItem, + WorkbenchTrendItem, +}; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/index.ts b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/index.ts new file mode 100644 index 00000000..76b7af17 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/index.ts @@ -0,0 +1,5 @@ +export { default as WorkbenchHeader } from './workbench-header.vue'; +export { default as WorkbenchProject } from './workbench-project.vue'; +export { default as WorkbenchQuickNav } from './workbench-quick-nav.vue'; +export { default as WorkbenchTodo } from './workbench-todo.vue'; +export { default as WorkbenchTrends } from './workbench-trends.vue'; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-header.vue b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-header.vue new file mode 100644 index 00000000..157f23f6 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-header.vue @@ -0,0 +1,46 @@ + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-project.vue b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-project.vue new file mode 100644 index 00000000..680720da --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-project.vue @@ -0,0 +1,63 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-quick-nav.vue b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-quick-nav.vue new file mode 100644 index 00000000..50a12e6e --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-quick-nav.vue @@ -0,0 +1,54 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-todo.vue b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-todo.vue new file mode 100644 index 00000000..2a9cd159 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-todo.vue @@ -0,0 +1,63 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-trends.vue b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-trends.vue new file mode 100644 index 00000000..2ace1e04 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/dashboard/workbench/workbench-trends.vue @@ -0,0 +1,64 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/fallback/fallback.ts b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/fallback.ts new file mode 100644 index 00000000..5f8e1937 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/fallback.ts @@ -0,0 +1,25 @@ +interface FallbackProps { + /** + * 描述 + */ + description?: string; + /** + * @zh_CN 首页路由地址 + * @default / + */ + homePath?: string; + /** + * @zh_CN 默认显示的图片 + * @default pageNotFoundSvg + */ + image?: string; + /** + * @zh_CN 内置类型 + */ + status?: '403' | '404' | '500' | 'coming-soon' | 'offline'; + /** + * @zh_CN 页面提示语 + */ + title?: string; +} +export type { FallbackProps }; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/fallback/fallback.vue b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/fallback.vue new file mode 100644 index 00000000..0686c9b2 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/fallback.vue @@ -0,0 +1,164 @@ + + + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-403.vue b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-403.vue new file mode 100644 index 00000000..e3908673 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-403.vue @@ -0,0 +1,151 @@ + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-404.vue b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-404.vue new file mode 100644 index 00000000..385cf6a5 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-404.vue @@ -0,0 +1,154 @@ + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-500.vue b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-500.vue new file mode 100644 index 00000000..97326b7c --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-500.vue @@ -0,0 +1,215 @@ + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-coming-soon.vue b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-coming-soon.vue new file mode 100644 index 00000000..e511c43c --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-coming-soon.vue @@ -0,0 +1,262 @@ + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-offline.vue b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-offline.vue new file mode 100644 index 00000000..9e50b19b --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/icon-offline.vue @@ -0,0 +1,112 @@ + diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/warning.svg b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/warning.svg new file mode 100644 index 00000000..951a905c --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/icons/warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/fallback/index.ts b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/index.ts new file mode 100644 index 00000000..f56f6651 --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/fallback/index.ts @@ -0,0 +1,2 @@ +export type * from './fallback'; +export { default as Fallback } from './fallback.vue'; diff --git a/packages/ui/certd-client/src/vben/common-ui/ui/index.ts b/packages/ui/certd-client/src/vben/common-ui/ui/index.ts new file mode 100644 index 00000000..fb99fdec --- /dev/null +++ b/packages/ui/certd-client/src/vben/common-ui/ui/index.ts @@ -0,0 +1,4 @@ +export * from './about'; +export * from './authentication'; +export * from './dashboard'; +export * from './fallback'; diff --git a/packages/ui/certd-client/src/vben/composables/__tests__/use-sortable.test.ts b/packages/ui/certd-client/src/vben/composables/__tests__/use-sortable.test.ts new file mode 100644 index 00000000..e7ba1f13 --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/__tests__/use-sortable.test.ts @@ -0,0 +1,48 @@ +import type { SortableOptions } from 'sortablejs'; + +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +import { useSortable } from '../use-sortable'; + +describe('useSortable', () => { + beforeEach(() => { + vi.mock('sortablejs/modular/sortable.complete.esm.js', () => ({ + default: { + create: vi.fn(), + }, + })); + }); + it('should call Sortable.create with the correct options', async () => { + // Create a mock element + const mockElement = document.createElement('div') as HTMLDivElement; + + // Define custom options + const customOptions: SortableOptions = { + group: 'test-group', + sort: false, + }; + + // Use the useSortable function + const { initializeSortable } = useSortable(mockElement, customOptions); + + // Initialize sortable + await initializeSortable(); + + // Import sortablejs to access the mocked create function + const Sortable = await import( + 'sortablejs/modular/sortable.complete.esm.js' + ); + + // Verify that Sortable.create was called with the correct parameters + expect(Sortable.default.create).toHaveBeenCalledTimes(1); + expect(Sortable.default.create).toHaveBeenCalledWith( + mockElement, + expect.objectContaining({ + animation: 300, + delay: 400, + delayOnTouchOnly: true, + ...customOptions, + }), + ); + }); +}); diff --git a/packages/ui/certd-client/src/vben/composables/index.ts b/packages/ui/certd-client/src/vben/composables/index.ts new file mode 100644 index 00000000..e6c28809 --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/index.ts @@ -0,0 +1,8 @@ +export * from "./use-is-mobile"; +export * from "./use-layout-style"; +export * from "./use-namespace"; +export * from "./use-priority-value"; +export * from "./use-scroll-lock"; +export * from "./use-simple-locale"; +export * from "./use-sortable"; +export { useEmitAsProps, useForwardExpose, useForwardProps, useForwardPropsEmits } from "radix-vue"; diff --git a/packages/ui/certd-client/src/vben/composables/use-is-mobile.ts b/packages/ui/certd-client/src/vben/composables/use-is-mobile.ts new file mode 100644 index 00000000..66163dc6 --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/use-is-mobile.ts @@ -0,0 +1,7 @@ +import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"; + +export function useIsMobile() { + const breakpoints = useBreakpoints(breakpointsTailwind); + const isMobile = breakpoints.smaller("md"); + return { isMobile }; +} diff --git a/packages/ui/certd-client/src/vben/composables/use-layout-style.ts b/packages/ui/certd-client/src/vben/composables/use-layout-style.ts new file mode 100644 index 00000000..e5e9e1de --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/use-layout-style.ts @@ -0,0 +1,79 @@ +import type { CSSProperties } from "vue"; + +import type { VisibleDomRect } from "/@/vben/shared/utils"; + +import { computed, onMounted, onUnmounted, ref } from "vue"; + +import { CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT, CSS_VARIABLE_LAYOUT_CONTENT_WIDTH, CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT, CSS_VARIABLE_LAYOUT_HEADER_HEIGHT } from "/@/vben/shared/constants"; +import { getElementVisibleRect } from "/@/vben/shared/utils"; + +import { useCssVar, useDebounceFn } from "@vueuse/core"; + +/** + * @zh_CN content style + */ +export function useLayoutContentStyle() { + let resizeObserver: null | ResizeObserver = null; + const contentElement = ref(null); + const visibleDomRect = ref(null); + const contentHeight = useCssVar(CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT); + const contentWidth = useCssVar(CSS_VARIABLE_LAYOUT_CONTENT_WIDTH); + + const overlayStyle = computed((): CSSProperties => { + const { height, left, top, width } = visibleDomRect.value ?? {}; + return { + height: `${height}px`, + left: `${left}px`, + position: "fixed", + top: `${top}px`, + width: `${width}px`, + zIndex: 150 + }; + }); + + const debouncedCalcHeight = useDebounceFn((_entries: ResizeObserverEntry[]) => { + visibleDomRect.value = getElementVisibleRect(contentElement.value); + contentHeight.value = `${visibleDomRect.value.height}px`; + contentWidth.value = `${visibleDomRect.value.width}px`; + }, 16); + + onMounted(() => { + if (contentElement.value && !resizeObserver) { + resizeObserver = new ResizeObserver(debouncedCalcHeight); + resizeObserver.observe(contentElement.value); + } + }); + + onUnmounted(() => { + resizeObserver?.disconnect(); + resizeObserver = null; + }); + + return { contentElement, overlayStyle, visibleDomRect }; +} + +export function useLayoutHeaderStyle() { + const headerHeight = useCssVar(CSS_VARIABLE_LAYOUT_HEADER_HEIGHT); + + return { + getLayoutHeaderHeight: () => { + return Number.parseInt(`${headerHeight.value}`, 10); + }, + setLayoutHeaderHeight: (height: number) => { + headerHeight.value = `${height}px`; + } + }; +} + +export function useLayoutFooterStyle() { + const footerHeight = useCssVar(CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT); + + return { + getLayoutFooterHeight: () => { + return Number.parseInt(`${footerHeight.value}`, 10); + }, + setLayoutFooterHeight: (height: number) => { + footerHeight.value = `${height}px`; + } + }; +} diff --git a/packages/ui/certd-client/src/vben/composables/use-namespace.ts b/packages/ui/certd-client/src/vben/composables/use-namespace.ts new file mode 100644 index 00000000..55f36711 --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/use-namespace.ts @@ -0,0 +1,88 @@ +import { DEFAULT_NAMESPACE } from "../shared/constants"; + +/** + * @see copy https://github.com/element-plus/element-plus/blob/dev/packages/hooks/use-namespace/index.ts + */ + +const statePrefix = "is-"; + +const _bem = (namespace: string, block: string, blockSuffix: string, element: string, modifier: string) => { + let cls = `${namespace}-${block}`; + if (blockSuffix) { + cls += `-${blockSuffix}`; + } + if (element) { + cls += `__${element}`; + } + if (modifier) { + cls += `--${modifier}`; + } + return cls; +}; + +const is: { + (name: string): string; + // eslint-disable-next-line @typescript-eslint/unified-signatures + (name: string, state: boolean | undefined): string; +} = (name: string, ...args: [] | [boolean | undefined]) => { + const state = args.length > 0 ? args[0] : true; + return name && state ? `${statePrefix}${name}` : ""; +}; + +const useNamespace = (block: string) => { + const namespace = DEFAULT_NAMESPACE; + const b = (blockSuffix = "") => _bem(namespace, block, blockSuffix, "", ""); + const e = (element?: string) => (element ? _bem(namespace, block, "", element, "") : ""); + const m = (modifier?: string) => (modifier ? _bem(namespace, block, "", "", modifier) : ""); + const be = (blockSuffix?: string, element?: string) => (blockSuffix && element ? _bem(namespace, block, blockSuffix, element, "") : ""); + const em = (element?: string, modifier?: string) => (element && modifier ? _bem(namespace, block, "", element, modifier) : ""); + const bm = (blockSuffix?: string, modifier?: string) => (blockSuffix && modifier ? _bem(namespace, block, blockSuffix, "", modifier) : ""); + const bem = (blockSuffix?: string, element?: string, modifier?: string) => (blockSuffix && element && modifier ? _bem(namespace, block, blockSuffix, element, modifier) : ""); + + // for css var + // --el-xxx: value; + const cssVar = (object: Record) => { + const styles: Record = {}; + for (const key in object) { + if (object[key]) { + styles[`--${namespace}-${key}`] = object[key]; + } + } + return styles; + }; + // with block + const cssVarBlock = (object: Record) => { + const styles: Record = {}; + for (const key in object) { + if (object[key]) { + styles[`--${namespace}-${block}-${key}`] = object[key]; + } + } + return styles; + }; + + const cssVarName = (name: string) => `--${namespace}-${name}`; + const cssVarBlockName = (name: string) => `--${namespace}-${block}-${name}`; + + return { + b, + be, + bem, + bm, + // css + cssVar, + cssVarBlock, + cssVarBlockName, + cssVarName, + e, + em, + is, + m, + namespace + }; +}; + +type UseNamespaceReturn = ReturnType; + +export type { UseNamespaceReturn }; +export { useNamespace }; diff --git a/packages/ui/certd-client/src/vben/composables/use-priority-value.ts b/packages/ui/certd-client/src/vben/composables/use-priority-value.ts new file mode 100644 index 00000000..42e5c2ff --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/use-priority-value.ts @@ -0,0 +1,71 @@ +import type { ComputedRef, Ref } from "vue"; + +import { computed, getCurrentInstance, unref, useAttrs, useSlots } from "vue"; + +import { getFirstNonNullOrUndefined, kebabToCamelCase } from "../shared/utils"; + +/** + * 依次从插槽、attrs、props、state 中获取值 + * @param key + * @param props + * @param state + */ +export function usePriorityValue, S extends Record, K extends keyof T = keyof T>(key: K, props: T, state: Readonly>> | undefined) { + const instance = getCurrentInstance(); + const slots = useSlots(); + const attrs = useAttrs() as T; + + const value = computed((): T[K] => { + // props不管有没有传,都会有默认值,会影响这里的顺序, + // 通过判断原始props是否有值来判断是否传入 + const rawProps = (instance?.vnode?.props || {}) as T; + + const standardRawProps = {} as T; + + for (const [key, value] of Object.entries(rawProps)) { + standardRawProps[kebabToCamelCase(key) as K] = value; + } + const propsKey = standardRawProps?.[key] === undefined ? undefined : props[key]; + + // slot可以关闭 + return getFirstNonNullOrUndefined(slots[key as string], attrs[key], propsKey, state?.value?.[key as keyof S]) as T[K]; + }); + + return value; +} + +/** + * 批量获取state中的值(每个值都是ref) + * @param props + * @param state + */ +export function usePriorityValues, S extends Ref> = Readonly, NoInfer>>>(props: T, state: S | undefined) { + const result: { [K in keyof T]: ComputedRef } = {} as never; + + (Object.keys(props) as (keyof T)[]).forEach((key) => { + result[key] = usePriorityValue(key as keyof typeof props, props, state); + }); + + return result; +} + +/** + * 批量获取state中的值(集中在一个computed,用于透传) + * @param props + * @param state + */ +export function useForwardPriorityValues, S extends Ref> = Readonly, NoInfer>>>(props: T, state: S | undefined) { + const computedResult: { [K in keyof T]: ComputedRef } = {} as never; + + (Object.keys(props) as (keyof T)[]).forEach((key) => { + computedResult[key] = usePriorityValue(key as keyof typeof props, props, state); + }); + + return computed(() => { + const unwrapResult: Record = {}; + Object.keys(props).forEach((key) => { + unwrapResult[key] = unref(computedResult[key]); + }); + return unwrapResult as { [K in keyof T]: T[K] }; + }); +} diff --git a/packages/ui/certd-client/src/vben/composables/use-scroll-lock.ts b/packages/ui/certd-client/src/vben/composables/use-scroll-lock.ts new file mode 100644 index 00000000..ad0e9ad8 --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/use-scroll-lock.ts @@ -0,0 +1,46 @@ +import { getScrollbarWidth, needsScrollbar } from "../shared/utils"; + +import { useScrollLock as _useScrollLock, tryOnBeforeUnmount, tryOnMounted } from "@vueuse/core"; + +export const SCROLL_FIXED_CLASS = `_scroll__fixed_`; + +export function useScrollLock() { + const isLocked = _useScrollLock(document.body); + const scrollbarWidth = getScrollbarWidth(); + + tryOnMounted(() => { + if (!needsScrollbar()) { + return; + } + document.body.style.paddingRight = `${scrollbarWidth}px`; + + const layoutFixedNodes = document.querySelectorAll(`.${SCROLL_FIXED_CLASS}`); + const nodes = [...layoutFixedNodes]; + if (nodes.length > 0) { + nodes.forEach((node) => { + node.dataset.transition = node.style.transition; + node.style.transition = "none"; + node.style.paddingRight = `${scrollbarWidth}px`; + }); + } + isLocked.value = true; + }); + + tryOnBeforeUnmount(() => { + if (!needsScrollbar()) { + return; + } + isLocked.value = false; + const layoutFixedNodes = document.querySelectorAll(`.${SCROLL_FIXED_CLASS}`); + const nodes = [...layoutFixedNodes]; + if (nodes.length > 0) { + nodes.forEach((node) => { + node.style.paddingRight = ""; + requestAnimationFrame(() => { + node.style.transition = node.dataset.transition || ""; + }); + }); + } + document.body.style.paddingRight = ""; + }); +} diff --git a/packages/ui/certd-client/src/vben/composables/use-simple-locale/README.md b/packages/ui/certd-client/src/vben/composables/use-simple-locale/README.md new file mode 100644 index 00000000..c0a676d3 --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/use-simple-locale/README.md @@ -0,0 +1,3 @@ +# Simple i18n + +Simple i18 implementation diff --git a/packages/ui/certd-client/src/vben/composables/use-simple-locale/index.ts b/packages/ui/certd-client/src/vben/composables/use-simple-locale/index.ts new file mode 100644 index 00000000..3054ceb2 --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/use-simple-locale/index.ts @@ -0,0 +1,27 @@ +import type { Locale } from "./messages"; + +import { computed, ref } from "vue"; + +import { createSharedComposable } from "@vueuse/core"; + +import { getMessages } from "./messages"; + +export const useSimpleLocale = createSharedComposable(() => { + const currentLocale = ref("zh-CN"); + + const setSimpleLocale = (locale: Locale) => { + currentLocale.value = locale; + }; + + const $t = computed(() => { + const localeMessages = getMessages(currentLocale.value); + return (key: string) => { + return localeMessages[key] || key; + }; + }); + return { + $t, + currentLocale, + setSimpleLocale + }; +}); diff --git a/packages/ui/certd-client/src/vben/composables/use-simple-locale/messages.ts b/packages/ui/certd-client/src/vben/composables/use-simple-locale/messages.ts new file mode 100644 index 00000000..70ebb528 --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/use-simple-locale/messages.ts @@ -0,0 +1,22 @@ +export type Locale = "en-US" | "zh-CN"; + +export const messages: Record> = { + "en-US": { + cancel: "Cancel", + collapse: "Collapse", + confirm: "Confirm", + expand: "Expand", + reset: "Reset", + submit: "Submit" + }, + "zh-CN": { + cancel: "取消", + collapse: "收起", + confirm: "确认", + expand: "展开", + reset: "重置", + submit: "提交" + } +}; + +export const getMessages = (locale: Locale) => messages[locale]; diff --git a/packages/ui/certd-client/src/vben/composables/use-sortable.ts b/packages/ui/certd-client/src/vben/composables/use-sortable.ts new file mode 100644 index 00000000..ae00841a --- /dev/null +++ b/packages/ui/certd-client/src/vben/composables/use-sortable.ts @@ -0,0 +1,26 @@ +import type { SortableOptions } from "sortablejs"; +import type Sortable from "sortablejs"; + +function useSortable(sortableContainer: T, options: SortableOptions = {}) { + const initializeSortable = async () => { + const Sortable = await import( + // @ts-expect-error - This is a dynamic import + "sortablejs/modular/sortable.complete.esm.js" + ); + const sortable = Sortable?.default?.create?.(sortableContainer, { + animation: 300, + delay: 400, + delayOnTouchOnly: true, + ...options + }); + return sortable as Sortable; + }; + + return { + initializeSortable + }; +} + +export { useSortable }; + +export type { Sortable }; diff --git a/packages/ui/certd-client/src/vben/constants/core.ts b/packages/ui/certd-client/src/vben/constants/core.ts new file mode 100644 index 00000000..bc022064 --- /dev/null +++ b/packages/ui/certd-client/src/vben/constants/core.ts @@ -0,0 +1,28 @@ +/** + * @zh_CN 登录页面 url 地址 + */ +export const LOGIN_PATH = "/login"; + +/** + * @zh_CN 默认首页地址 + */ +export const DEFAULT_HOME_PATH = "/"; + +export interface LanguageOption { + label: string; + value: "en-US" | "zh-CN"; +} + +/** + * Supported languages + */ +export const SUPPORT_LANGUAGES: LanguageOption[] = [ + { + label: "简体中文", + value: "zh-CN" + }, + { + label: "English", + value: "en-US" + } +]; diff --git a/packages/ui/certd-client/src/vben/constants/globals.ts b/packages/ui/certd-client/src/vben/constants/globals.ts new file mode 100644 index 00000000..141a0cbf --- /dev/null +++ b/packages/ui/certd-client/src/vben/constants/globals.ts @@ -0,0 +1,16 @@ +/** layout content 组件的高度 */ +export const CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT = `--vben-content-height`; +/** layout content 组件的宽度 */ +export const CSS_VARIABLE_LAYOUT_CONTENT_WIDTH = `--vben-content-width`; +/** layout header 组件的高度 */ +export const CSS_VARIABLE_LAYOUT_HEADER_HEIGHT = `--vben-header-height`; +/** layout footer 组件的高度 */ +export const CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT = `--vben-footer-height`; + +/** 内容区域的组件ID */ +export const ELEMENT_ID_MAIN_CONTENT = `__vben_main_content`; + +/** + * @zh_CN 默认命名空间 + */ +export const DEFAULT_NAMESPACE = "vben"; diff --git a/packages/ui/certd-client/src/vben/constants/index.ts b/packages/ui/certd-client/src/vben/constants/index.ts new file mode 100644 index 00000000..78a9f3c4 --- /dev/null +++ b/packages/ui/certd-client/src/vben/constants/index.ts @@ -0,0 +1,3 @@ +export * from "./globals"; +export * from "./vben"; +export * from "./core"; diff --git a/packages/ui/certd-client/src/vben/constants/vben.ts b/packages/ui/certd-client/src/vben/constants/vben.ts new file mode 100644 index 00000000..96bf8944 --- /dev/null +++ b/packages/ui/certd-client/src/vben/constants/vben.ts @@ -0,0 +1,25 @@ +/** + * @zh_CN GITHUB 仓库地址 + */ +export const VBEN_GITHUB_URL = "https://github.com/vbenjs/vue-vben-admin"; + +/** + * @zh_CN 文档地址 + */ +export const VBEN_DOC_URL = "https://doc.vben.pro"; + +/** + * @zh_CN Vben Logo + */ +export const VBEN_LOGO_URL = "https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp"; + +/** + * @zh_CN Vben Admin 首页地址 + */ +export const VBEN_PREVIEW_URL = "https://www.vben.pro"; + +export const VBEN_ELE_PREVIEW_URL = "https://ele.vben.pro"; + +export const VBEN_NAIVE_PREVIEW_URL = "https://naive.vben.pro"; + +export const VBEN_ANT_PREVIEW_URL = "https://ant.vben.pro"; diff --git a/packages/ui/certd-client/src/vben/design/css/global.css b/packages/ui/certd-client/src/vben/design/css/global.css new file mode 100644 index 00000000..fb613baa --- /dev/null +++ b/packages/ui/certd-client/src/vben/design/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.5; + 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/ui/certd-client/src/vben/design/css/nprogress.css b/packages/ui/certd-client/src/vben/design/css/nprogress.css new file mode 100644 index 00000000..3503dab2 --- /dev/null +++ b/packages/ui/certd-client/src/vben/design/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/ui/certd-client/src/vben/design/css/transition.css b/packages/ui/certd-client/src/vben/design/css/transition.css new file mode 100644 index 00000000..c1cb0e48 --- /dev/null +++ b/packages/ui/certd-client/src/vben/design/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/ui/certd-client/src/vben/design/css/ui.css b/packages/ui/certd-client/src/vben/design/css/ui.css new file mode 100644 index 00000000..f7119c8b --- /dev/null +++ b/packages/ui/certd-client/src/vben/design/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/ui/certd-client/src/vben/design/design-tokens/dark.css b/packages/ui/certd-client/src/vben/design/design-tokens/dark.css new file mode 100644 index 00000000..d34541e9 --- /dev/null +++ b/packages/ui/certd-client/src/vben/design/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