diff --git a/apps/vben5/apps/app-antd/package.json b/apps/vben5/apps/app-antd/package.json index b4b1336ef..1e1a592ef 100644 --- a/apps/vben5/apps/app-antd/package.json +++ b/apps/vben5/apps/app-antd/package.json @@ -29,6 +29,8 @@ "@abp/account": "workspace:*", "@abp/auditing": "workspace:*", "@abp/core": "workspace:*", + "@abp/data-protection": "workspace:*", + "@abp/demo": "workspace:*", "@abp/features": "workspace:*", "@abp/identity": "workspace:*", "@abp/localization": "workspace:*", diff --git a/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json b/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json index 920c5e943..0844acf85 100644 --- a/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json +++ b/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json @@ -51,6 +51,10 @@ "resources": "Resources", "languages": "Languages", "texts": "Texts" + }, + "dataProtection": { + "title": "Data Protection", + "entityTypeInfos": "Entity Type Infos" } }, "openiddict": { @@ -98,5 +102,9 @@ "title": "Saas", "editions": "Editions", "tenants": "Tenants" + }, + "demo": { + "title": "Demo", + "books": "Books" } } diff --git a/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json b/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json index 23c6b717a..d1da0fbd7 100644 --- a/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json +++ b/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json @@ -51,6 +51,10 @@ "resources": "资源管理", "languages": "语言管理", "texts": "文档管理" + }, + "dataProtection": { + "title": "数据权限", + "entityTypeInfos": "实体列表" } }, "openiddict": { @@ -98,5 +102,9 @@ "title": "Saas", "editions": "版本管理", "tenants": "租户管理" + }, + "demo": { + "title": "演示", + "books": "书籍列表" } } diff --git a/apps/vben5/apps/app-antd/src/router/routes/modules/abp.ts b/apps/vben5/apps/app-antd/src/router/routes/modules/abp.ts index cd842c657..e31424022 100644 --- a/apps/vben5/apps/app-antd/src/router/routes/modules/abp.ts +++ b/apps/vben5/apps/app-antd/src/router/routes/modules/abp.ts @@ -214,6 +214,27 @@ const routes: RouteRecordRaw[] = [ }, ], }, + { + meta: { + title: $t('abp.manage.dataProtection.title'), + icon: 'icon-park-outline:protect', + }, + name: 'DataProtectionManagement', + path: '/manage/data-protection', + children: [ + { + meta: { + title: $t('abp.manage.dataProtection.entityTypeInfos'), + icon: 'iconamoon:type', + keepAlive: true, + }, + name: 'EntityTypeInfos', + path: '/manage/data-protection/entity-type-infos', + component: () => + import('#/views/data-protection/entity-type-infos/index.vue'), + }, + ], + }, { meta: { title: $t('abp.manage.identity.auditLogs'), @@ -401,6 +422,25 @@ const routes: RouteRecordRaw[] = [ }, ], }, + { + name: 'AbpDemo', + path: '/abp/demos', + meta: { + title: $t('abp.demo.title'), + icon: 'carbon:demo', + }, + children: [ + { + meta: { + title: $t('abp.demo.books'), + icon: 'mingcute:book-line', + }, + name: 'DemoBooks', + path: '/abp/demos/books', + component: () => import('#/views/demos/books/index.vue'), + }, + ], + }, ], }, ]; diff --git a/apps/vben5/apps/app-antd/src/views/data-protection/entity-type-infos/index.vue b/apps/vben5/apps/app-antd/src/views/data-protection/entity-type-infos/index.vue new file mode 100644 index 000000000..e62aa8ce9 --- /dev/null +++ b/apps/vben5/apps/app-antd/src/views/data-protection/entity-type-infos/index.vue @@ -0,0 +1,15 @@ + + + diff --git a/apps/vben5/apps/app-antd/src/views/demos/books/index.vue b/apps/vben5/apps/app-antd/src/views/demos/books/index.vue new file mode 100644 index 000000000..9cce8d620 --- /dev/null +++ b/apps/vben5/apps/app-antd/src/views/demos/books/index.vue @@ -0,0 +1,15 @@ + + + diff --git a/apps/vben5/packages/@abp/core/src/types/dto.ts b/apps/vben5/packages/@abp/core/src/types/dto.ts index 7adcb9e67..f400dd184 100644 --- a/apps/vben5/packages/@abp/core/src/types/dto.ts +++ b/apps/vben5/packages/@abp/core/src/types/dto.ts @@ -53,6 +53,7 @@ interface ExtensibleObject { } /** 实体数据传输对象 */ interface EntityDto { + [key: string]: any; /** 实体标识 */ id: TPrimaryKey; } diff --git a/apps/vben5/packages/@abp/data-protection/package.json b/apps/vben5/packages/@abp/data-protection/package.json new file mode 100644 index 000000000..4c4c957e9 --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/package.json @@ -0,0 +1,36 @@ +{ + "name": "@abp/data-protection", + "version": "9.0.4", + "homepage": "https://github.com/colinin/abp-next-admin", + "bugs": "https://github.com/colinin/abp-next-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/colinin/abp-next-admin.git", + "directory": "packages/@abp/data-protection" + }, + "license": "MIT", + "type": "module", + "sideEffects": [ + "**/*.css" + ], + "exports": { + ".": { + "types": "./src/index.ts", + "default": "./src/index.ts" + } + }, + "dependencies": { + "@abp/core": "workspace:*", + "@abp/request": "workspace:*", + "@abp/ui": "workspace:*", + "@ant-design/icons-vue": "catalog:", + "@vben/common-ui": "workspace:*", + "@vben/hooks": "workspace:*", + "@vben/icons": "workspace:*", + "@vben/layouts": "workspace:*", + "@vben/locales": "workspace:*", + "ant-design-vue": "catalog:", + "dayjs": "catalog:", + "vue": "catalog:*" + } +} diff --git a/apps/vben5/packages/@abp/data-protection/src/api/index.ts b/apps/vben5/packages/@abp/data-protection/src/api/index.ts new file mode 100644 index 000000000..39db68d49 --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/api/index.ts @@ -0,0 +1,3 @@ +export { useEntityTypeInfosApi } from './useEntityTypeInfosApi'; +export { useRoleEntityRulesApi } from './useRoleEntityRulesApi'; +export { useSubjectStrategysApi } from './useSubjectStrategysApi'; diff --git a/apps/vben5/packages/@abp/data-protection/src/api/useEntityTypeInfosApi.ts b/apps/vben5/packages/@abp/data-protection/src/api/useEntityTypeInfosApi.ts new file mode 100644 index 000000000..af63d226b --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/api/useEntityTypeInfosApi.ts @@ -0,0 +1,33 @@ +import type { PagedResultDto } from '@abp/core'; + +import type { + EntityTypeInfoDto, + GetEntityTypeInfoListInput, +} from '../types/entityTypeInfos'; + +import { useRequest } from '@abp/request'; + +export function useEntityTypeInfosApi() { + const { cancel, request } = useRequest(); + + function getApi(id: string): Promise { + return request(`/api/data-protection-management/entity-type-infos/${id}`, { + method: 'GET', + }); + } + + function getPagedListApi( + input?: GetEntityTypeInfoListInput, + ): Promise> { + return request(`/api/data-protection-management/entity-type-infos`, { + method: 'GET', + params: input, + }); + } + + return { + cancel, + getApi, + getPagedListApi, + }; +} diff --git a/apps/vben5/packages/@abp/data-protection/src/api/useRoleEntityRulesApi.ts b/apps/vben5/packages/@abp/data-protection/src/api/useRoleEntityRulesApi.ts new file mode 100644 index 000000000..42966247b --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/api/useRoleEntityRulesApi.ts @@ -0,0 +1,44 @@ +import type { + RoleEntityRuleCreateDto, + RoleEntityRuleDto, + RoleEntityRuleGetInput, +} from '../types/roleEntityRules'; + +import { useRequest } from '@abp/request'; + +export function useRoleEntityRulesApi() { + const { cancel, request } = useRequest(); + + function getApi(input: RoleEntityRuleGetInput): Promise { + return request('/api/data-protection-management/entity-rule/roles', { + method: 'GET', + params: input, + }); + } + + function createApi( + input: RoleEntityRuleCreateDto, + ): Promise { + return request('/api/data-protection-management/entity-rule/roles', { + data: input, + method: 'POST', + }); + } + + function updateApi( + id: string, + input: RoleEntityRuleCreateDto, + ): Promise { + return request(`/api/data-protection-management/entity-rule/roles/${id}`, { + data: input, + method: 'PUT', + }); + } + + return { + cancel, + createApi, + getApi, + updateApi, + }; +} diff --git a/apps/vben5/packages/@abp/data-protection/src/api/useSubjectStrategysApi.ts b/apps/vben5/packages/@abp/data-protection/src/api/useSubjectStrategysApi.ts new file mode 100644 index 000000000..78603b26a --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/api/useSubjectStrategysApi.ts @@ -0,0 +1,49 @@ +import type { + SubjectStrategyDto, + SubjectStrategyGetInput, + SubjectStrategySetInput, +} from '../types'; + +import { useRequest } from '@abp/request'; + +export function useSubjectStrategysApi() { + const { cancel, request } = useRequest(); + + /** + * 获取主体数据权限策略 + * @param input 参数 + * @returns 数据权限策略配置 + */ + function getApi( + input: SubjectStrategyGetInput, + ): Promise { + return request( + '/api/data-protection-management/subject-strategys', + { + method: 'GET', + params: input, + }, + ); + } + + /** + * 设置主体数据权限策略 + * @param input 参数 + * @returns 数据权限策略配置 + */ + function setApi(input: SubjectStrategySetInput): Promise { + return request( + '/api/data-protection-management/subject-strategys', + { + data: input, + method: 'PUT', + }, + ); + } + + return { + cancel, + getApi, + setApi, + }; +} diff --git a/apps/vben5/packages/@abp/data-protection/src/components/entity-rules/EntityRuleModal.vue b/apps/vben5/packages/@abp/data-protection/src/components/entity-rules/EntityRuleModal.vue new file mode 100644 index 000000000..b2caa29d6 --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/components/entity-rules/EntityRuleModal.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/apps/vben5/packages/@abp/data-protection/src/components/entity-type-infos/EntityTypeInfoTable.vue b/apps/vben5/packages/@abp/data-protection/src/components/entity-type-infos/EntityTypeInfoTable.vue new file mode 100644 index 000000000..bec7e4482 --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/components/entity-type-infos/EntityTypeInfoTable.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/apps/vben5/packages/@abp/data-protection/src/components/index.ts b/apps/vben5/packages/@abp/data-protection/src/components/index.ts new file mode 100644 index 000000000..e4716b1d9 --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/components/index.ts @@ -0,0 +1,2 @@ +export { default as EntityRuleModal } from './entity-rules/EntityRuleModal.vue'; +export { default as EntityTypeInfoTable } from './entity-type-infos/EntityTypeInfoTable.vue'; diff --git a/apps/vben5/packages/@abp/data-protection/src/index.ts b/apps/vben5/packages/@abp/data-protection/src/index.ts new file mode 100644 index 000000000..314dad0cd --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/index.ts @@ -0,0 +1,3 @@ +export * from './api'; +export * from './components'; +export * from './types'; diff --git a/apps/vben5/packages/@abp/data-protection/src/types/entityRules.ts b/apps/vben5/packages/@abp/data-protection/src/types/entityRules.ts new file mode 100644 index 000000000..e3ab09d8b --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/types/entityRules.ts @@ -0,0 +1,101 @@ +import type { AuditedEntityDto } from '@abp/core'; + +enum DataAccessOperation { + /** 删除 */ + Delete = 2, + /** 查询 */ + Read = 0, + /** 更新 */ + Write = 1, +} + +enum DataAccessFilterOperate { + /** 包含 */ + Contains = 9, + /** 右包含 */ + EndsWith = 8, + /** 等于 */ + Equal = 1, + /** 大于 */ + Greater = 5, + /** 大于或等于 */ + GreaterOrEqual = 6, + /** 小于 */ + Less = 3, + /** 小于或等于 */ + LessOrEqual = 4, + /** 不包含 */ + NotContains = 10, + /** 不等于 */ + NotEqual = 2, + /** 左包含 */ + StartsWith = 7, +} + +enum DataAccessFilterLogic { + /** 且 */ + And = 0, + /** 或 */ + Or = 1, +} + +interface DataAccessFilterRule { + [key: string]: any; + field: string; + isLeft: boolean; + javaScriptType: string; + operate: DataAccessFilterOperate; + typeFullName: string; + value: string; +} + +interface DataAccessFilterGroup { + groups: DataAccessFilterGroup[]; + logic: DataAccessFilterLogic; + rules: DataAccessFilterRule[]; +} + +interface EntityRuleDtoBase extends AuditedEntityDto { + accessedProperties: string[]; + entityTypeFullName: string; + entityTypeId: string; + filterGroup: DataAccessFilterGroup; + isEnabled: boolean; + operation: DataAccessOperation; + tenantId?: string; +} + +interface EntityEnumInfoModel { + key: string; + value: any; +} + +interface EntityPropertyInfoModel { + displayName: string; + enums: EntityEnumInfoModel[]; + javaScriptName: string; + javaScriptType: string; + name: string; + operates: DataAccessFilterOperate[]; + typeFullName: string; +} + +interface EntityTypeInfoModel { + displayName: string; + name: string; + properties: EntityPropertyInfoModel[]; +} + +interface EntityTypeInfoGetModel { + operation: DataAccessOperation; +} + +export { DataAccessFilterLogic, DataAccessFilterOperate, DataAccessOperation }; + +export type { + DataAccessFilterGroup, + DataAccessFilterRule, + EntityRuleDtoBase, + EntityTypeInfoGetModel, + EntityTypeInfoModel, +}; diff --git a/apps/vben5/packages/@abp/data-protection/src/types/entityTypeInfos.ts b/apps/vben5/packages/@abp/data-protection/src/types/entityTypeInfos.ts new file mode 100644 index 000000000..93e57c1fd --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/types/entityTypeInfos.ts @@ -0,0 +1,38 @@ +import type { + AuditedEntityDto, + EntityDto, + PagedAndSortedResultRequestDto, +} from '@abp/core'; + +interface EntityEnumInfoDto extends EntityDto { + displayName: string; + name: string; + value: string; +} + +interface EntityPropertyInfoDto extends EntityDto { + displayName: string; + enums: EntityEnumInfoDto[]; + javaScriptType: string; + name: string; + typeFullName: string; +} + +interface EntityTypeInfoDto extends AuditedEntityDto { + displayName: string; + isAuditEnabled: boolean; + name: string; + properties: EntityPropertyInfoDto[]; + typeFullName: string; +} + +interface GetEntityTypeInfoListInput extends PagedAndSortedResultRequestDto { + filter?: string; + isAuditEnabled?: boolean; +} + +export type { + EntityPropertyInfoDto, + EntityTypeInfoDto, + GetEntityTypeInfoListInput, +}; diff --git a/apps/vben5/packages/@abp/data-protection/src/types/index.ts b/apps/vben5/packages/@abp/data-protection/src/types/index.ts new file mode 100644 index 000000000..4595b0af4 --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/types/index.ts @@ -0,0 +1,4 @@ +export * from './entityRules'; +export * from './entityTypeInfos'; +export * from './roleEntityRules'; +export * from './strategys'; diff --git a/apps/vben5/packages/@abp/data-protection/src/types/roleEntityRules.ts b/apps/vben5/packages/@abp/data-protection/src/types/roleEntityRules.ts new file mode 100644 index 000000000..1e67d58fe --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/types/roleEntityRules.ts @@ -0,0 +1,38 @@ +import type { + DataAccessFilterGroup, + DataAccessOperation, + EntityRuleDtoBase, +} from './entityRules'; + +interface RoleEntityRuleGetInput { + entityTypeId: string; + operation: DataAccessOperation; + roleName: string; +} + +interface EntityRuleCreateOrUpdateDto { + accessedProperties?: string[]; + filterGroup: DataAccessFilterGroup; + isEnabled: boolean; + operation: DataAccessOperation; +} + +interface RoleEntityRuleCreateDto extends EntityRuleCreateOrUpdateDto { + entityTypeId: string; + roleId: string; + roleName: string; +} + +type RoleEntityRuleUpdateDto = EntityRuleCreateOrUpdateDto; + +interface RoleEntityRuleDto extends EntityRuleDtoBase { + roleId: string; + roleName: string; +} + +export type { + RoleEntityRuleCreateDto, + RoleEntityRuleDto, + RoleEntityRuleGetInput, + RoleEntityRuleUpdateDto, +}; diff --git a/apps/vben5/packages/@abp/data-protection/src/types/strategys.ts b/apps/vben5/packages/@abp/data-protection/src/types/strategys.ts new file mode 100644 index 000000000..3736fc7a0 --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/src/types/strategys.ts @@ -0,0 +1,42 @@ +/** 数据访问策略 */ +enum DataAccessStrategy { + /** 可以访问所有数据 */ + All = 0, + /** 仅当前用户组织机构及下级机构 */ + CurrentAndSubOrganizationUnits = 5, + /** 仅当前用户组织机构 */ + CurrentOrganizationUnits = 4, + /** 仅当前用户角色 */ + CurrentRoles = 3, + /** 仅当前用户 */ + CurrentUser = 2, + /** 自定义规则 */ + Custom = 1, +} + +interface SubjectStrategyGetInput { + subjectId: string; + subjectName: string; +} + +interface SubjectStrategySetInput { + isEnabled: boolean; + strategy: DataAccessStrategy; + subjectId: string; + subjectName: string; +} + +interface SubjectStrategyDto { + isEnabled: boolean; + strategy: DataAccessStrategy; + subjectId: string; + subjectName: string; +} + +export { DataAccessStrategy }; + +export type { + SubjectStrategyDto, + SubjectStrategyGetInput, + SubjectStrategySetInput, +}; diff --git a/apps/vben5/packages/@abp/data-protection/tsconfig.json b/apps/vben5/packages/@abp/data-protection/tsconfig.json new file mode 100644 index 000000000..ce1a891fb --- /dev/null +++ b/apps/vben5/packages/@abp/data-protection/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/web.json", + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/apps/vben5/packages/@abp/demo/package.json b/apps/vben5/packages/@abp/demo/package.json new file mode 100644 index 000000000..a87ba8513 --- /dev/null +++ b/apps/vben5/packages/@abp/demo/package.json @@ -0,0 +1,37 @@ +{ + "name": "@abp/demo", + "version": "9.0.4", + "homepage": "https://github.com/colinin/abp-next-admin", + "bugs": "https://github.com/colinin/abp-next-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/colinin/abp-next-admin.git", + "directory": "packages/@abp/demo" + }, + "license": "MIT", + "type": "module", + "sideEffects": [ + "**/*.css" + ], + "exports": { + ".": { + "types": "./src/index.ts", + "default": "./src/index.ts" + } + }, + "dependencies": { + "@abp/core": "workspace:*", + "@abp/data-protection": "workspace:*", + "@abp/request": "workspace:*", + "@abp/ui": "workspace:*", + "@ant-design/icons-vue": "catalog:", + "@vben/access": "workspace:*", + "@vben/common-ui": "workspace:*", + "@vben/hooks": "workspace:*", + "@vben/icons": "workspace:*", + "@vben/locales": "workspace:*", + "ant-design-vue": "catalog:", + "dayjs": "catalog:", + "vue": "catalog:*" + } +} diff --git a/apps/vben5/packages/@abp/demo/src/api/index.ts b/apps/vben5/packages/@abp/demo/src/api/index.ts new file mode 100644 index 000000000..b0f3cc483 --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/api/index.ts @@ -0,0 +1,2 @@ +export { useAuthorsApi } from './useAuthorsApi'; +export { useBooksApi } from './useBooksApi'; diff --git a/apps/vben5/packages/@abp/demo/src/api/useAuthorsApi.ts b/apps/vben5/packages/@abp/demo/src/api/useAuthorsApi.ts new file mode 100644 index 000000000..257b800ef --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/api/useAuthorsApi.ts @@ -0,0 +1,23 @@ +import type { PagedResultDto } from '@abp/core'; + +import type { AuthorDto, GetAuthorPagedListInput } from '../types/authors'; + +import { useRequest } from '@abp/request'; + +export function useAuthorsApi() { + const { cancel, request } = useRequest(); + + function getPagedListApi( + input?: GetAuthorPagedListInput, + ): Promise> { + return request>('/api/demo/authors', { + method: 'GET', + params: input, + }); + } + + return { + cancel, + getPagedListApi, + }; +} diff --git a/apps/vben5/packages/@abp/demo/src/api/useBooksApi.ts b/apps/vben5/packages/@abp/demo/src/api/useBooksApi.ts new file mode 100644 index 000000000..ac416d388 --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/api/useBooksApi.ts @@ -0,0 +1,71 @@ +import type { PagedResultDto } from '@abp/core'; +import type { + EntityTypeInfoGetModel, + EntityTypeInfoModel, +} from '@abp/data-protection'; + +import type { + BookDto, + CreateUpdateBookDto, + GetBookPagedListInput, +} from '../types/books'; + +import { useRequest } from '@abp/request'; + +export function useBooksApi() { + const { cancel, request } = useRequest(); + + function createApi(input: CreateUpdateBookDto): Promise { + return request(`/api/demo/books`, { + data: input, + method: 'POST', + }); + } + + function deleteApi(id: string): Promise { + return request(`/api/demo/books/${id}`, { + method: 'DELETE', + }); + } + + function getApi(id: string): Promise { + return request(`/api/demo/books/${id}`, { + method: 'GET', + }); + } + + function getPagedListApi( + input?: GetBookPagedListInput, + ): Promise> { + return request>('/api/demo/books', { + method: 'GET', + params: input, + }); + } + + function getEntityInfoApi( + input: EntityTypeInfoGetModel, + ): Promise { + return request('/api/demo/books/entity', { + method: 'GET', + params: input, + }); + } + + function updateApi(id: string, input: CreateUpdateBookDto): Promise { + return request(`/api/demo/books/${id}`, { + data: input, + method: 'PUT', + }); + } + + return { + cancel, + createApi, + deleteApi, + getApi, + getEntityInfoApi, + getPagedListApi, + updateApi, + }; +} diff --git a/apps/vben5/packages/@abp/demo/src/components/books/BookModal.vue b/apps/vben5/packages/@abp/demo/src/components/books/BookModal.vue new file mode 100644 index 000000000..652a5a056 --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/components/books/BookModal.vue @@ -0,0 +1,212 @@ + + + + + diff --git a/apps/vben5/packages/@abp/demo/src/components/books/BookTable.vue b/apps/vben5/packages/@abp/demo/src/components/books/BookTable.vue new file mode 100644 index 000000000..109675b16 --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/components/books/BookTable.vue @@ -0,0 +1,204 @@ + + + + + diff --git a/apps/vben5/packages/@abp/demo/src/components/index.ts b/apps/vben5/packages/@abp/demo/src/components/index.ts new file mode 100644 index 000000000..924370120 --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/components/index.ts @@ -0,0 +1 @@ +export { default as BookTable } from './books/BookTable.vue'; diff --git a/apps/vben5/packages/@abp/demo/src/constants/permissions.ts b/apps/vben5/packages/@abp/demo/src/constants/permissions.ts new file mode 100644 index 000000000..aa2af4a74 --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/constants/permissions.ts @@ -0,0 +1,8 @@ +export const BookPermissions = { + /** 新增 */ + Create: 'Demo.Books.Create', + /** 删除 */ + Delete: 'Demo.Books.Delete', + /** 更新 */ + Update: 'Demo.Books.Edit', +}; diff --git a/apps/vben5/packages/@abp/demo/src/index.ts b/apps/vben5/packages/@abp/demo/src/index.ts new file mode 100644 index 000000000..314dad0cd --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/index.ts @@ -0,0 +1,3 @@ +export * from './api'; +export * from './components'; +export * from './types'; diff --git a/apps/vben5/packages/@abp/demo/src/types/authors.ts b/apps/vben5/packages/@abp/demo/src/types/authors.ts new file mode 100644 index 000000000..515d6d0e1 --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/types/authors.ts @@ -0,0 +1,13 @@ +import type { EntityDto, PagedAndSortedResultRequestDto } from '@abp/core'; + +interface AuthorDto extends EntityDto { + birthDate: string; + name: string; + shortBio?: string; +} + +interface GetAuthorPagedListInput extends PagedAndSortedResultRequestDto { + filter?: string; +} + +export type { AuthorDto, GetAuthorPagedListInput }; diff --git a/apps/vben5/packages/@abp/demo/src/types/books.ts b/apps/vben5/packages/@abp/demo/src/types/books.ts new file mode 100644 index 000000000..0ce367e9a --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/types/books.ts @@ -0,0 +1,41 @@ +import type { + AuditedEntityDto, + PagedAndSortedResultRequestDto, +} from '@abp/core'; + +enum BookType { + Undefined, + Adventure, + Biography, + Dystopia, + Fantastic, + Horror, + Science, + ScienceFiction, + Poetry, +} + +interface BookDto extends AuditedEntityDto { + authorId: string; + authorName: string; + name: string; + price?: number; + publishDate: string; + type: BookType; +} + +interface CreateUpdateBookDto { + authorId: string; + name: string; + price: number; + publishDate: string; + type: BookType; +} + +interface GetBookPagedListInput extends PagedAndSortedResultRequestDto { + filter?: string; +} + +export { BookType }; + +export type { BookDto, CreateUpdateBookDto, GetBookPagedListInput }; diff --git a/apps/vben5/packages/@abp/demo/src/types/index.ts b/apps/vben5/packages/@abp/demo/src/types/index.ts new file mode 100644 index 000000000..5c6465c67 --- /dev/null +++ b/apps/vben5/packages/@abp/demo/src/types/index.ts @@ -0,0 +1 @@ +export * from './authors'; diff --git a/apps/vben5/packages/@abp/demo/tsconfig.json b/apps/vben5/packages/@abp/demo/tsconfig.json new file mode 100644 index 000000000..ce1a891fb --- /dev/null +++ b/apps/vben5/packages/@abp/demo/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/web.json", + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/apps/vben5/packages/@abp/identity/package.json b/apps/vben5/packages/@abp/identity/package.json index b01823c08..c047d3c47 100644 --- a/apps/vben5/packages/@abp/identity/package.json +++ b/apps/vben5/packages/@abp/identity/package.json @@ -22,6 +22,7 @@ "dependencies": { "@abp/auditing": "workspace:*", "@abp/core": "workspace:*", + "@abp/data-protection": "workspace:*", "@abp/permissions": "workspace:*", "@abp/request": "workspace:*", "@abp/ui": "workspace:*", diff --git a/apps/vben5/packages/@abp/identity/src/api/useOrganizationUnitsApi.ts b/apps/vben5/packages/@abp/identity/src/api/useOrganizationUnitsApi.ts index bc8fa2011..af8fd4480 100644 --- a/apps/vben5/packages/@abp/identity/src/api/useOrganizationUnitsApi.ts +++ b/apps/vben5/packages/@abp/identity/src/api/useOrganizationUnitsApi.ts @@ -234,7 +234,7 @@ export function useOrganizationUnitsApi() { ): Promise { return request(`/api/identity/organization-units/${id}/roles`, { data: input, - method: 'GET', + method: 'POST', }); } diff --git a/apps/vben5/packages/@abp/identity/src/components/roles/RoleRuleDrawer.vue b/apps/vben5/packages/@abp/identity/src/components/roles/RoleRuleDrawer.vue new file mode 100644 index 000000000..8a0e2ecb4 --- /dev/null +++ b/apps/vben5/packages/@abp/identity/src/components/roles/RoleRuleDrawer.vue @@ -0,0 +1,528 @@ + + + + + diff --git a/apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue b/apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue index 2ea506927..dca4c445d 100644 --- a/apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue +++ b/apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue @@ -39,6 +39,7 @@ const AuditLogIcon = createIconifyIcon('fluent-mdl2:compliance-audit'); const RoleModal = defineAsyncComponent(() => import('./RoleModal.vue')); const ClaimModal = defineAsyncComponent(() => import('./RoleClaimModal.vue')); +const RuleModal = defineAsyncComponent(() => import('./RoleRuleDrawer.vue')); const abpStore = useAbpStore(); const { publish } = useEventBus(); @@ -52,6 +53,9 @@ const [RolePermissionModal, permissionModalApi] = useVbenModal({ const [RoleClaimModal, claimModalApi] = useVbenModal({ connectedComponent: ClaimModal, }); +const [RoleRuleDrawer, roleRuleDrawerApi] = useVbenDrawer({ + connectedComponent: RuleModal, +}); const [RoleChangeDrawer, roleChangeDrawerApi] = useVbenDrawer({ connectedComponent: EntityChangeDrawer, }); @@ -169,6 +173,11 @@ const handleMenuClick = async (row: IdentityRoleDto, info: MenuInfo) => { roleChangeDrawerApi.open(); break; } + case 'entity-rules': { + roleRuleDrawerApi.setData(row); + roleRuleDrawerApi.open(); + break; + } case 'permissions': { const roles = abpStore.application?.currentUser.roles ?? []; permissionModalApi.setData({ @@ -272,6 +281,9 @@ function onPermissionChange(_name: string, key: string) { > {{ $t('AbpAuditLogging.EntitiesChanged') }} + + {{ '数据权限' }} +