From a393fe6dd3a3cf6abffd2bf16d2f0130750dddbd Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud Date: Wed, 9 Sep 2026 12:08:07 +0800 Subject: [PATCH] feat: nodes --- ui/src/api/API_README.md | 1 + .../admin/system/resource-authorization.ts | 21 +++-- .../admin/workspace/resource-authorization.ts | 33 ++++---- ui/src/components/COMPONENT_README.md | 12 ++- .../business/folder-tree/VirtualizedTree.vue | 19 +++-- .../components/business/folder-tree/index.vue | 14 ++++ .../PermissionConfigDialog.vue | 21 +++-- .../resource-authorization-drawer/index.vue | 45 ++++------- .../components/global/mk-tag-group/index.vue | 7 ++ ui/src/styles/app.scss | 17 +--- ui/src/views/VIEW_README.md | 37 +++++++-- .../chat/user-groups/GroupsListView.vue | 6 ++ .../views/system/chat/users/UserListView.vue | 77 +++++-------------- .../BatchSetUserGroupButton.vue | 19 +++++ .../BatchSetUserGroupDialog.vue | 4 +- .../users/import-users/ImportUsersButton.vue | 21 +++++ .../ImportUsersDialog.vue | 28 ++++++- .../quota-settings/QuotaSettingsButton.vue | 23 ++++++ .../QuotaSettingsDialog.vue | 14 +++- .../users/user-password/UserPwdButton.vue | 24 ++++++ .../UserPwdDialog.vue | 27 ++++++- .../system/identity/groups/GroupsListView.vue | 6 ++ .../ResourceAuthorizationView.vue | 2 +- .../UserGroupAuthorizationList.vue | 2 +- .../user-group}/UserGroupMembersDrawer.vue | 0 .../system/identity/roles/RoleListView.vue | 2 + .../system/identity/users/UserListView.vue | 53 ++++--------- .../BatchSetUserRoleButton.vue | 19 +++++ .../BatchSetUserRoleDialog.vue | 26 ++++++- .../users/import-users/ImportUsersButton.vue | 21 +++++ .../ImportUsersDialog.vue | 14 +++- .../users/user-password/UserPwdButton.vue | 24 ++++++ .../UserPwdDialog.vue | 27 ++++++- .../identity/workspaces/WorkspaceListView.vue | 5 ++ .../operate-logs/OperateLogListView.vue | 17 +--- .../clean-strategy/CleanStrategyButton.vue | 19 +++++ .../CleanStrategyDialog.vue | 0 .../dialog/OperateLogDetailDialog.vue | 2 +- ui/vite.config.ts | 2 +- 39 files changed, 486 insertions(+), 225 deletions(-) create mode 100644 ui/src/views/system/chat/users/batch-set-user-group/BatchSetUserGroupButton.vue rename ui/src/views/system/chat/users/{dialog => batch-set-user-group}/BatchSetUserGroupDialog.vue (96%) create mode 100644 ui/src/views/system/chat/users/import-users/ImportUsersButton.vue rename ui/src/views/system/chat/users/{dialog => import-users}/ImportUsersDialog.vue (88%) create mode 100644 ui/src/views/system/chat/users/quota-settings/QuotaSettingsButton.vue rename ui/src/views/system/chat/users/{dialog => quota-settings}/QuotaSettingsDialog.vue (93%) create mode 100644 ui/src/views/system/chat/users/user-password/UserPwdButton.vue rename ui/src/views/system/chat/users/{dialog => user-password}/UserPwdDialog.vue (80%) rename ui/src/views/system/identity/resource-authorization/components/{ => user-group}/UserGroupAuthorizationList.vue (94%) rename ui/src/views/system/identity/resource-authorization/{ => components/user-group}/UserGroupMembersDrawer.vue (100%) create mode 100644 ui/src/views/system/identity/users/batch-set-user-role/BatchSetUserRoleButton.vue rename ui/src/views/system/identity/users/{dialog => batch-set-user-role}/BatchSetUserRoleDialog.vue (88%) create mode 100644 ui/src/views/system/identity/users/import-users/ImportUsersButton.vue rename ui/src/views/system/identity/users/{dialog => import-users}/ImportUsersDialog.vue (96%) create mode 100644 ui/src/views/system/identity/users/user-password/UserPwdButton.vue rename ui/src/views/system/identity/users/{dialog => user-password}/UserPwdDialog.vue (82%) create mode 100644 ui/src/views/system/operate-logs/clean-strategy/CleanStrategyButton.vue rename ui/src/views/system/operate-logs/{dialog => clean-strategy}/CleanStrategyDialog.vue (100%) diff --git a/ui/src/api/API_README.md b/ui/src/api/API_README.md index 0c5d24a7cda..35a936d98a3 100644 --- a/ui/src/api/API_README.md +++ b/ui/src/api/API_README.md @@ -180,6 +180,7 @@ API 枚举与类型统一在 `src/api` 范围内管理,相关规则由本文 `resource_user_permission/resource//resource/`;与 System 用户视角的 `user_resource_permission` 区分。分页使用 `ParamsPage`,直接返回 `ResponsePage`;提交 `ResourceUserPermissionPayload[]`。 +查询和更新接口内部调用 `getWorkspaceId()` 获取路由工作空间,调用方不传工作空间 ID。 `ResourceAuthorizationTargetType` 包含资源类型和三个 `_FOLDER` 类型,文件夹类型用于后端 鉴权。包含子资源时传 `include_children: true` 及经过管理权限筛选的 `folder_ids`, 普通资源或仅当前文件夹不传子文件夹 ID。loading、刷新及成功提示由抽屉负责。 diff --git a/ui/src/api/admin/system/resource-authorization.ts b/ui/src/api/admin/system/resource-authorization.ts index 79888e939cb..97388fba8d4 100644 --- a/ui/src/api/admin/system/resource-authorization.ts +++ b/ui/src/api/admin/system/resource-authorization.ts @@ -1,19 +1,26 @@ import { get, put } from '../core/request' import type { Dict, ResourceAuthorizationType, ResourcePermissionItem, ResourcePermissionPayload } from '@/api/types' -/** 系统管理资源授权 */ +/** 系统管理用户资源授权 */ const prefix = (workspaceId: string) => `/workspace/${workspaceId}/user_resource_permission` -const groupPrefix = (workspaceId: string) => `/workspace/${workspaceId}/user_group_resource_permission` + /** 获取指定空间、指定用户、指定资源类型的权限列表。 */ const getUserResourcePermissions = (workspaceId: string, userId: string, resource: ResourceAuthorizationType, query?: Dict) => { return get(`${prefix(workspaceId)}/user/${userId}/resource/${resource}`, query) } /** 更新指定空间、指定用户、指定资源类型的权限列表。 */ -const putUserResourcePermissions = (workspaceId: string, userId: string, resource: ResourceAuthorizationType, permissions: ResourcePermissionPayload[]) => { +const putUserResourcePermissions = ( + workspaceId: string, + userId: string, + resource: ResourceAuthorizationType, + permissions: ResourcePermissionPayload[], +) => { return put(`${prefix(workspaceId)}/user/${userId}/resource/${resource}`, permissions) } +/** 系统管理用户组资源授权 */ +const groupPrefix = (workspaceId: string) => `/workspace/${workspaceId}/user_group_resource_permission` /** 获取指定空间、指定用户组、指定资源类型的权限列表。 */ const getUserGroupResourcePermissions = (workspaceId: string, userId: string, resource: ResourceAuthorizationType, query?: Dict) => { @@ -21,12 +28,16 @@ const getUserGroupResourcePermissions = (workspaceId: string, userId: string, re } /** 更新指定空间、指定用户组、指定资源类型的权限列表。 */ -const putUserGroupResourcePermissions = (workspaceId: string, userId: string, resource: ResourceAuthorizationType, permissions: ResourcePermissionPayload[]) => { +const putUserGroupResourcePermissions = ( + workspaceId: string, + userId: string, + resource: ResourceAuthorizationType, + permissions: ResourcePermissionPayload[], +) => { return put( `${groupPrefix(workspaceId)}/user_group/${userId}/resource/${resource}`, permissions, ) } - export default { getUserResourcePermissions, putUserResourcePermissions, getUserGroupResourcePermissions, putUserGroupResourcePermissions } diff --git a/ui/src/api/admin/workspace/resource-authorization.ts b/ui/src/api/admin/workspace/resource-authorization.ts index f32a37d4fae..68974b724e6 100644 --- a/ui/src/api/admin/workspace/resource-authorization.ts +++ b/ui/src/api/admin/workspace/resource-authorization.ts @@ -1,29 +1,26 @@ import { get, put } from '../core/request' import type { ParamsPage, ResponsePage } from '../core/types' import type { Dict, ResourceAuthorizationTargetType, ResourceUserPermission, ResourceUserPermissionPayload } from '@/api/types' +import { getWorkspaceId } from '@/utils/resource-context' -const prefix = (workspaceId: string, targetId: string, resource: ResourceAuthorizationTargetType) => - `/workspace/${workspaceId}/resource_user_permission/resource/${targetId}/resource/${resource}` - +const getPrefix = () => { + const workspaceId = getWorkspaceId() + return `/workspace/${workspaceId}` +} /** 获取指定资源或文件夹的用户权限分页列表。 */ -const getResourceAuthorization = ( - workspaceId: string, - targetId: string, - resource: ResourceAuthorizationTargetType, - page: ParamsPage, - query?: Dict, -) => { - return get>(`${prefix(workspaceId, targetId, resource)}/${page.currentPage}/${page.pageSize}`, query) +const getResourceAuthorization = (targetId: string, resource: ResourceAuthorizationTargetType, page: ParamsPage, query?: Dict) => { + return get>( + `${getPrefix()}/resource_user_permission/resource/${targetId}/resource/${resource}/${page.currentPage}/${page.pageSize}`, + query, + ) } /** 更新资源的用户权限,可同时应用到有管理权限的子文件夹及资源。 */ -const putResourceAuthorization = ( - workspaceId: string, - targetId: string, - resource: ResourceAuthorizationTargetType, - permissions: ResourceUserPermissionPayload[], -) => { - return put(prefix(workspaceId, targetId, resource), permissions) +const putResourceAuthorization = (targetId: string, resource: ResourceAuthorizationTargetType, permissions: ResourceUserPermissionPayload[]) => { + return put( + `${getPrefix()}/resource_user_permission/resource/${targetId}/resource/${resource}`, + permissions, + ) } export default { getResourceAuthorization, putResourceAuthorization } diff --git a/ui/src/components/COMPONENT_README.md b/ui/src/components/COMPONENT_README.md index 08e792e7b3f..98ac0a12588 100644 --- a/ui/src/components/COMPONENT_README.md +++ b/ui/src/components/COMPONENT_README.md @@ -1186,6 +1186,10 @@ Workspace 的文件夹虚拟树业务组件。组件根据当前资源上下文 新 ID 写入路由,但会清除已有的 `folderId`,避免刷新页面后恢复到旧文件夹。隐藏“全部”入口的 移动目录树继续以调用方传入的 `v-model` 为准。 +可编辑文件夹的菜单提供“资源授权”,根据对应资源模块的 `folderAuth(folder.id)` 控制入口。 +点击后复用 `ResourceAuthorizationDrawer`,传入 Workspace 资源授权 API、当前 `source` 和 +原始完整文件夹子树;搜索过滤不缩减子资源授权范围。只读选择场景不挂载授权抽屉。 + ```vue