From d8678460ae51d105a3fe7ab6ce69f3783fede4bf Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 13 Mar 2025 17:35:38 +0800 Subject: [PATCH] feat(vben5): Added a simple state check component --- .../app-antd/src/adapter/component/index.ts | 10 +- apps/vben5/packages/@abp/core/package.json | 2 + ...eRequireAuthenticatedSimpleStateChecker.ts | 2 +- .../useRequireFeaturesSimpleStateChecker.ts | 2 +- ...RequireGlobalFeaturesSimpleStateChecker.ts | 18 +- ...useRequirePermissionsSimpleStateChecker.ts | 2 +- .../core/src/hooks/useSimpleStateCheck.ts | 27 +- .../packages/@abp/core/src/utils/array.ts | 1 + .../packages/@abp/core/src/utils/index.ts | 1 + .../packages/@abp/core/src/utils/tree.ts | 34 ++- .../@abp/features/src/components/index.ts | 2 + .../state-check/FeatureStateCheck.vue | 135 +++++++++ .../state-check/GlobalFeatureStateCheck.vue | 65 +++++ .../permissions/PermissionDefinitionModal.vue | 33 ++- .../@abp/permissions/src/components/index.ts | 1 + .../state-check/PermissionStateCheck.vue | 134 +++++++++ apps/vben5/packages/@abp/ui/package.json | 4 + .../packages/@abp/ui/src/components/index.ts | 1 + .../SimpleStateChecking.vue | 265 ++++++++++++++++++ .../SimpleStateCheckingModal.vue | 231 +++++++++++++++ .../components/simple-state-checking/index.ts | 2 + .../simple-state-checking/interface.ts | 6 + apps/vben5/pnpm-workspace.yaml | 2 + 23 files changed, 940 insertions(+), 40 deletions(-) create mode 100644 apps/vben5/packages/@abp/core/src/utils/array.ts create mode 100644 apps/vben5/packages/@abp/features/src/components/state-check/FeatureStateCheck.vue create mode 100644 apps/vben5/packages/@abp/features/src/components/state-check/GlobalFeatureStateCheck.vue create mode 100644 apps/vben5/packages/@abp/permissions/src/components/state-check/PermissionStateCheck.vue create mode 100644 apps/vben5/packages/@abp/ui/src/components/simple-state-checking/SimpleStateChecking.vue create mode 100644 apps/vben5/packages/@abp/ui/src/components/simple-state-checking/SimpleStateCheckingModal.vue create mode 100644 apps/vben5/packages/@abp/ui/src/components/simple-state-checking/index.ts create mode 100644 apps/vben5/packages/@abp/ui/src/components/simple-state-checking/interface.ts diff --git a/apps/vben5/apps/app-antd/src/adapter/component/index.ts b/apps/vben5/apps/app-antd/src/adapter/component/index.ts index 818acdd0d..199e349d2 100644 --- a/apps/vben5/apps/app-antd/src/adapter/component/index.ts +++ b/apps/vben5/apps/app-antd/src/adapter/component/index.ts @@ -3,14 +3,17 @@ * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, */ +import type { Component, SetupContext } from 'vue'; + import type { BaseFormComponentType } from '@vben/common-ui'; -import type { Component, SetupContext } from 'vue'; import { h } from 'vue'; import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; +import { FeatureStateCheck, GlobalFeatureStateCheck } from '@abp/features'; +import { PermissionStateCheck } from '@abp/permissions'; import { AutoComplete, Button, @@ -18,6 +21,7 @@ import { CheckboxGroup, DatePicker, Divider, + Empty, Input, InputNumber, InputPassword, @@ -123,6 +127,7 @@ async function initComponentAdapter() { return h(Button, { ...props, attrs, type: 'default' }, slots); }, Divider, + Empty, IconPicker: (props, { attrs, slots }) => { return h( IconPicker, @@ -150,6 +155,9 @@ async function initComponentAdapter() { TimePicker, TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'), Upload, + FeatureStateCheck, + GlobalFeatureStateCheck, + PermissionStateCheck, }; // 将组件注册到全局共享状态中 diff --git a/apps/vben5/packages/@abp/core/package.json b/apps/vben5/packages/@abp/core/package.json index 2ec3857eb..2374f1ebc 100644 --- a/apps/vben5/packages/@abp/core/package.json +++ b/apps/vben5/packages/@abp/core/package.json @@ -37,12 +37,14 @@ "dependencies": { "@vueuse/core": "catalog:", "dayjs": "catalog:", + "lodash.groupby": "catalog:", "lodash.merge": "catalog:", "pinia": "catalog:", "pinia-plugin-persistedstate": "catalog:", "vue": "catalog:" }, "devDependencies": { + "@types/lodash.groupby": "catalog:", "@types/lodash.merge": "catalog:" } } diff --git a/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireAuthenticatedSimpleStateChecker.ts b/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireAuthenticatedSimpleStateChecker.ts index 83c370e56..add3d46cf 100644 --- a/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireAuthenticatedSimpleStateChecker.ts +++ b/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireAuthenticatedSimpleStateChecker.ts @@ -14,7 +14,7 @@ export interface RequireAuthenticatedStateChecker { export class RequireAuthenticatedSimpleStateChecker< TState extends IHasSimpleStateCheckers, > - implements RequireAuthenticatedStateChecker, ISimpleStateChecker + implements ISimpleStateChecker, RequireAuthenticatedStateChecker { _currentUser?: CurrentUser; name = 'A'; diff --git a/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireFeaturesSimpleStateChecker.ts b/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireFeaturesSimpleStateChecker.ts index 3a155dff3..0de9dda52 100644 --- a/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireFeaturesSimpleStateChecker.ts +++ b/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireFeaturesSimpleStateChecker.ts @@ -16,7 +16,7 @@ export interface RequireFeaturesStateChecker { export class RequireFeaturesSimpleStateChecker< TState extends IHasSimpleStateCheckers, > - implements RequireFeaturesStateChecker, ISimpleStateChecker + implements ISimpleStateChecker, RequireFeaturesStateChecker { _featureChecker: IFeatureChecker; featureNames: string[]; diff --git a/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireGlobalFeaturesSimpleStateChecker.ts b/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireGlobalFeaturesSimpleStateChecker.ts index 700ea5ee6..882d5d89d 100644 --- a/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireGlobalFeaturesSimpleStateChecker.ts +++ b/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequireGlobalFeaturesSimpleStateChecker.ts @@ -8,7 +8,7 @@ import type { import { useGlobalFeatures } from '../useGlobalFeatures'; export interface RequireGlobalFeaturesStateChecker { - featureNames: string[]; + globalFeatureNames: string[]; name: string; requiresAll: boolean; } @@ -16,24 +16,24 @@ export interface RequireGlobalFeaturesStateChecker { export class RequireGlobalFeaturesSimpleStateChecker< TState extends IHasSimpleStateCheckers, > - implements RequireGlobalFeaturesStateChecker, ISimpleStateChecker + implements ISimpleStateChecker, RequireGlobalFeaturesStateChecker { _globalFeatureChecker: IGlobalFeatureChecker; - featureNames: string[]; + globalFeatureNames: string[]; name: string = 'G'; requiresAll: boolean; constructor( globalFeatureChecker: IGlobalFeatureChecker, - featureNames: string[], + globalFeatureNames: string[], requiresAll: boolean = false, ) { this._globalFeatureChecker = globalFeatureChecker; - this.featureNames = featureNames; + this.globalFeatureNames = globalFeatureNames; this.requiresAll = requiresAll; } isEnabled(_context: SimpleStateCheckerContext): boolean { return this._globalFeatureChecker.isEnabled( - this.featureNames, + this.globalFeatureNames, this.requiresAll, ); } @@ -41,7 +41,7 @@ export class RequireGlobalFeaturesSimpleStateChecker< serialize(): string { return JSON.stringify({ A: this.requiresAll, - N: this.featureNames, + N: this.globalFeatureNames, T: this.name, }); } @@ -50,13 +50,13 @@ export class RequireGlobalFeaturesSimpleStateChecker< export function useRequireGlobalFeaturesSimpleStateChecker< TState extends IHasSimpleStateCheckers, >( - featureNames: string[], + globalFeatureNames: string[], requiresAll: boolean = false, ): ISimpleStateChecker { const globalFeatureChecker = useGlobalFeatures(); return new RequireGlobalFeaturesSimpleStateChecker( globalFeatureChecker, - featureNames, + globalFeatureNames, requiresAll, ); } diff --git a/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequirePermissionsSimpleStateChecker.ts b/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequirePermissionsSimpleStateChecker.ts index 5040cbb1b..18b96e326 100644 --- a/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequirePermissionsSimpleStateChecker.ts +++ b/apps/vben5/packages/@abp/core/src/hooks/SimpleStateChecking/useRequirePermissionsSimpleStateChecker.ts @@ -37,7 +37,7 @@ export interface RequirePermissionsStateChecker< export class RequirePermissionsSimpleStateChecker< TState extends IHasSimpleStateCheckers, > - implements RequirePermissionsStateChecker, ISimpleStateChecker + implements ISimpleStateChecker, RequirePermissionsStateChecker { _permissionChecker: IPermissionChecker; model: RequirePermissionsSimpleBatchStateCheckerModel; diff --git a/apps/vben5/packages/@abp/core/src/hooks/useSimpleStateCheck.ts b/apps/vben5/packages/@abp/core/src/hooks/useSimpleStateCheck.ts index 68f811602..f7b681b67 100644 --- a/apps/vben5/packages/@abp/core/src/hooks/useSimpleStateCheck.ts +++ b/apps/vben5/packages/@abp/core/src/hooks/useSimpleStateCheck.ts @@ -11,8 +11,10 @@ import { useRequireFeaturesSimpleStateChecker } from './SimpleStateChecking/useR import { useRequireGlobalFeaturesSimpleStateChecker } from './SimpleStateChecking/useRequireGlobalFeaturesSimpleStateChecker'; import { useRequirePermissionsSimpleStateChecker } from './SimpleStateChecking/useRequirePermissionsSimpleStateChecker'; -class SimpleStateCheckerSerializer implements ISimpleStateCheckerSerializer { - deserialize>( +export function useSimpleStateCheck< + TState extends IHasSimpleStateCheckers, +>(): ISimpleStateCheckerSerializer { + function deserialize>( jsonObject: any, state: TState, ): ISimpleStateChecker | undefined { @@ -72,7 +74,7 @@ class SimpleStateCheckerSerializer implements ISimpleStateCheckerSerializer { } } - deserializeArray>( + function deserializeArray>( value: string, state: TState, ): ISimpleStateChecker[] { @@ -82,22 +84,22 @@ class SimpleStateCheckerSerializer implements ISimpleStateCheckerSerializer { if (Array.isArray(jsonObject)) { if (jsonObject.length === 0) return []; return jsonObject - .map((json) => this.deserialize(json, state)) + .map((json) => deserialize(json, state)) .filter((checker) => !isNullOrUnDef(checker)) .map((checker) => checker); } - const stateChecker = this.deserialize(jsonObject, state); + const stateChecker = deserialize(jsonObject, state); if (!stateChecker) return []; return [stateChecker]; } - serialize>( + function serialize>( checker: ISimpleStateChecker, ): string | undefined { return checker.serialize(); } - serializeArray>( + function serializeArray>( stateCheckers: ISimpleStateChecker[], ): string | undefined { if (stateCheckers.length === 0) return undefined; @@ -124,10 +126,11 @@ class SimpleStateCheckerSerializer implements ISimpleStateCheckerSerializer { ? `[${serializedCheckers}]` : undefined; } -} -export function useSimpleStateCheck< - TState extends IHasSimpleStateCheckers, ->(): ISimpleStateCheckerSerializer { - return new SimpleStateCheckerSerializer(); + return { + deserialize, + deserializeArray, + serialize, + serializeArray, + }; } diff --git a/apps/vben5/packages/@abp/core/src/utils/array.ts b/apps/vben5/packages/@abp/core/src/utils/array.ts new file mode 100644 index 000000000..b766b0680 --- /dev/null +++ b/apps/vben5/packages/@abp/core/src/utils/array.ts @@ -0,0 +1 @@ +export { default as groupBy } from 'lodash.groupby'; diff --git a/apps/vben5/packages/@abp/core/src/utils/index.ts b/apps/vben5/packages/@abp/core/src/utils/index.ts index 1219f2544..4c7bf48a5 100644 --- a/apps/vben5/packages/@abp/core/src/utils/index.ts +++ b/apps/vben5/packages/@abp/core/src/utils/index.ts @@ -1,3 +1,4 @@ +export * from './array'; export * from './date'; export * from './is'; export * from './mitt'; diff --git a/apps/vben5/packages/@abp/core/src/utils/tree.ts b/apps/vben5/packages/@abp/core/src/utils/tree.ts index be64f1c92..7af084394 100644 --- a/apps/vben5/packages/@abp/core/src/utils/tree.ts +++ b/apps/vben5/packages/@abp/core/src/utils/tree.ts @@ -18,20 +18,28 @@ export function listToTree( config: Partial = {}, ): T[] { const conf = getConfig(config) as TreeHelperConfig; - const nodeMap = new Map(); - const result: T[] = []; + const map: { [key: string]: any } = {}; + const roots: any[] = []; const { id, pid, children } = conf; - for (const node of list) { - node[children] = node[children] || []; - nodeMap.set(node[id], node); - } - for (const node of list) { - const parent = nodeMap.get(node[pid]); - (parent ? parent[children] : result).push(node); - if (parent) { - parent.hasChildren = true; + // 将每个元素放入map中,方便通过id查找 + list.forEach((item) => { + map[item[id]] = { ...item, [children]: [] }; + }); + + // 构建树形结构 + list.forEach((item) => { + const parentId = item[pid]; + if (parentId === null || parentId === undefined) { + // 根节点 + roots.push(map[item[id]]); + } else { + // 非根节点,将其添加到父节点的children数组中 + if (map[parentId]) { + map[parentId][children].push(map[item[id]]); + } } - } - return result; + }); + + return roots; } diff --git a/apps/vben5/packages/@abp/features/src/components/index.ts b/apps/vben5/packages/@abp/features/src/components/index.ts index 32ec4e334..2f6f6676e 100644 --- a/apps/vben5/packages/@abp/features/src/components/index.ts +++ b/apps/vben5/packages/@abp/features/src/components/index.ts @@ -1,3 +1,5 @@ export { default as FeatureDefinitionTable } from './definitions/features/FeatureDefinitionTable.vue'; export { default as FeatureGroupDefinitionTable } from './definitions/groups/FeatureGroupDefinitionTable.vue'; export { default as FeatureModal } from './features/FeatureModal.vue'; +export { default as FeatureStateCheck } from './state-check/FeatureStateCheck.vue'; +export { default as GlobalFeatureStateCheck } from './state-check/GlobalFeatureStateCheck.vue'; diff --git a/apps/vben5/packages/@abp/features/src/components/state-check/FeatureStateCheck.vue b/apps/vben5/packages/@abp/features/src/components/state-check/FeatureStateCheck.vue new file mode 100644 index 000000000..8b233215d --- /dev/null +++ b/apps/vben5/packages/@abp/features/src/components/state-check/FeatureStateCheck.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/apps/vben5/packages/@abp/features/src/components/state-check/GlobalFeatureStateCheck.vue b/apps/vben5/packages/@abp/features/src/components/state-check/GlobalFeatureStateCheck.vue new file mode 100644 index 000000000..cba77c7cf --- /dev/null +++ b/apps/vben5/packages/@abp/features/src/components/state-check/GlobalFeatureStateCheck.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/apps/vben5/packages/@abp/permissions/src/components/definitions/permissions/PermissionDefinitionModal.vue b/apps/vben5/packages/@abp/permissions/src/components/definitions/permissions/PermissionDefinitionModal.vue index 84371bfce..df70f913e 100644 --- a/apps/vben5/packages/@abp/permissions/src/components/definitions/permissions/PermissionDefinitionModal.vue +++ b/apps/vben5/packages/@abp/permissions/src/components/definitions/permissions/PermissionDefinitionModal.vue @@ -1,4 +1,5 @@ + + + + diff --git a/apps/vben5/packages/@abp/ui/package.json b/apps/vben5/packages/@abp/ui/package.json index a151de95f..f077d1a35 100644 --- a/apps/vben5/packages/@abp/ui/package.json +++ b/apps/vben5/packages/@abp/ui/package.json @@ -35,8 +35,12 @@ "@vben/utils": "workspace:*", "@vueuse/core": "catalog:", "ant-design-vue": "catalog:", + "lodash.clonedeep": "catalog:", "vue": "catalog:*", "vxe-pc-ui": "catalog:", "vxe-table": "catalog:" + }, + "devDependencies": { + "@types/lodash.clonedeep": "catalog:" } } diff --git a/apps/vben5/packages/@abp/ui/src/components/index.ts b/apps/vben5/packages/@abp/ui/src/components/index.ts index 3e9b28b37..f7ea1fd4b 100644 --- a/apps/vben5/packages/@abp/ui/src/components/index.ts +++ b/apps/vben5/packages/@abp/ui/src/components/index.ts @@ -1,5 +1,6 @@ export { default as LocalizableInput } from './localizable-input/LocalizableInput.vue'; export { default as PropertyTable } from './properties/PropertyTable.vue'; export * from './properties/types'; +export * from './simple-state-checking'; export * from './string-value-type'; export type * from './vxe-table'; diff --git a/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/SimpleStateChecking.vue b/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/SimpleStateChecking.vue new file mode 100644 index 000000000..414959d7e --- /dev/null +++ b/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/SimpleStateChecking.vue @@ -0,0 +1,265 @@ + + + + + diff --git a/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/SimpleStateCheckingModal.vue b/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/SimpleStateCheckingModal.vue new file mode 100644 index 000000000..e8d32e609 --- /dev/null +++ b/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/SimpleStateCheckingModal.vue @@ -0,0 +1,231 @@ + + + + + diff --git a/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/index.ts b/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/index.ts new file mode 100644 index 000000000..d78e7cde8 --- /dev/null +++ b/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/index.ts @@ -0,0 +1,2 @@ +export * from './interface'; +export { default as SimpleStateChecking } from './SimpleStateChecking.vue'; diff --git a/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/interface.ts b/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/interface.ts new file mode 100644 index 000000000..357c55b7a --- /dev/null +++ b/apps/vben5/packages/@abp/ui/src/components/simple-state-checking/interface.ts @@ -0,0 +1,6 @@ +import type { IHasSimpleStateCheckers, ISimpleStateChecker } from '@abp/core'; + +export interface SimplaCheckStateBase + extends IHasSimpleStateCheckers { + stateCheckers: ISimpleStateChecker[]; +} diff --git a/apps/vben5/pnpm-workspace.yaml b/apps/vben5/pnpm-workspace.yaml index ef691de56..790065150 100644 --- a/apps/vben5/pnpm-workspace.yaml +++ b/apps/vben5/pnpm-workspace.yaml @@ -49,6 +49,7 @@ catalog: '@types/lodash.clonedeep': ^4.5.9 '@types/lodash.debounce': ^4.0.9 '@types/lodash.get': ^4.4.9 + '@types/lodash.groupby': ^4.6.9 '@types/lodash.isequal': ^4.5.8 '@types/lodash.isnumber': ^3.0.9 '@types/lodash.merge': ^4.6.9 @@ -124,6 +125,7 @@ catalog: lodash.clonedeep: ^4.5.0 lodash.debounce: ^4.0.8 lodash.get: ^4.4.2 + lodash.groupby: ^4.6.0 lodash.isequal: ^4.5.0 lodash.isnumber: ^3.0.3 lodash.merge: ^4.6.2