From 272b4934db0628dd6381f3a9ae1034a88a2fe535 Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud Date: Mon, 24 Aug 2026 20:36:33 +0800 Subject: [PATCH] feat: resource authorization --- ui/src/api/admin/system/common.ts | 6 +- .../admin/system/resource-authorization.ts | 15 +- ui/src/api/types/common.ts | 2 +- ui/src/components/COMPONENT_README.md | 11 +- .../business/folder-tree/FolderFormDialog.vue | 8 +- .../business/folder-tree/MoveToDialog.vue | 10 +- .../global/mk-complex-search/index.vue | 18 +- ui/src/components/global/mk-table/index.vue | 2 +- ui/src/layout/LayoutHeader.vue | 4 +- .../index.vue | 2 +- ui/src/styles/app.scss | 101 ++++++---- ui/src/styles/element-plus.scss | 34 ++++ .../model/create-model/CreateModelDrawer.vue | 13 +- .../create-model/SelectProviderDrawer.vue | 9 +- .../chat/authentication/EditSCANDrawer.vue | 10 +- .../authentication/components/SCANLogin.vue | 1 - .../dialog/CreateGroupMemberDialog.vue | 9 +- .../dialog/CreateOrUpdateGroupDialog.vue | 9 +- .../system/chat/users/UserFromDrawer.vue | 11 +- .../users/dialog/BatchSetUserGroupDialog.vue | 9 +- .../chat/users/dialog/ImportUsersDialog.vue | 9 +- .../chat/users/dialog/UserPwdDialog.vue | 9 +- .../system/identity/groups/GroupsListView.vue | 158 ++++++++------- .../groups/dialog/CreateGroupMemberDialog.vue | 13 +- .../dialog/CreateOrUpdateGroupDialog.vue | 9 +- .../ResourceAuthorizationView.vue | 182 +++++++----------- .../components/PermissionTable.vue | 157 +++++---------- .../resource-authorization/constants.ts | 30 +-- .../dialog/BatchSetPermissionDialog.vue | 54 ++++++ .../system/identity/roles/AddMemberDrawer.vue | 9 +- .../roles/dialog/CreateOrUpdateRoleDialog.vue | 8 +- .../system/identity/users/UserFromDrawer.vue | 11 +- .../users/dialog/BatchSetUserRoleDialog.vue | 9 +- .../identity/users/dialog/UserPwdDialog.vue | 9 +- .../identity/workspaces/AddMemberDrawer.vue | 9 +- .../identity/workspaces/WorkspaceListView.vue | 2 +- .../dialog/CreateOrUpdateWorkspaceDialog.vue | 9 +- .../authentication/EditSCANDrawer.vue | 10 +- ui/src/views/tool/ToolDebugDrawer.vue | 11 +- .../tool/components/ToolCreateDropdown.vue | 2 +- .../{create-form => form}/ToolFormDrawer.vue | 17 +- .../components/init-field/InitFieldDialog.vue | 11 +- .../components/init-field/InitFieldTable.vue | 0 .../input-field/InputFieldDialog.vue | 11 +- .../input-field/InputFieldTable.vue | 0 .../components/python-code/CodeSetting.vue | 0 .../python-code/GenerateCodeDialog.vue | 0 47 files changed, 468 insertions(+), 565 deletions(-) rename ui/src/layout/{workspace-dropdown => header-workspace-dropdown}/index.vue (96%) create mode 100644 ui/src/views/system/identity/resource-authorization/dialog/BatchSetPermissionDialog.vue rename ui/src/views/tool/{create-form => form}/ToolFormDrawer.vue (96%) rename ui/src/views/tool/{create-form => form}/components/init-field/InitFieldDialog.vue (95%) rename ui/src/views/tool/{create-form => form}/components/init-field/InitFieldTable.vue (100%) rename ui/src/views/tool/{create-form => form}/components/input-field/InputFieldDialog.vue (95%) rename ui/src/views/tool/{create-form => form}/components/input-field/InputFieldTable.vue (100%) rename ui/src/views/tool/{create-form => form}/components/python-code/CodeSetting.vue (100%) rename ui/src/views/tool/{create-form => form}/components/python-code/GenerateCodeDialog.vue (100%) diff --git a/ui/src/api/admin/system/common.ts b/ui/src/api/admin/system/common.ts index b37e83e3c0b..684c8224ae5 100644 --- a/ui/src/api/admin/system/common.ts +++ b/ui/src/api/admin/system/common.ts @@ -1,5 +1,5 @@ import { get } from '../core/request' -import type { RequestParams, SystemUserOption, WorkspaceMemberOption } from '@/api/types' +import type { RequestParams, SystemUserOption, CommonUserOption } from '@/api/types' /** 获取默认密码。 */ const getDefaultPassword = () => { @@ -11,9 +11,9 @@ const getAllUsers = (query?: RequestParams) => { return get('/user/list', query) } -/** 获取指定工作空间的成员选项。 */ +/** 获取指定工作空间的普通用户选项。 */ const getWorkspaceMembers = (workspaceId: string, query?: RequestParams) => { - return get(`/workspace/${workspaceId}/user_member`, query) + return get(`/workspace/${workspaceId}/user_member`, query) } export default { diff --git a/ui/src/api/admin/system/resource-authorization.ts b/ui/src/api/admin/system/resource-authorization.ts index 02a4092c74f..1eed87d6d37 100644 --- a/ui/src/api/admin/system/resource-authorization.ts +++ b/ui/src/api/admin/system/resource-authorization.ts @@ -6,20 +6,23 @@ import type { ResourcePermissionPayload, } from '@/api/types' -const prefix = (workspaceId: string, userId: string, resource: ResourceAuthorizationType) => - `/workspace/${workspaceId}/user_resource_permission/user/${userId}/resource/${resource}` +/** 系统管理资源授权 */ +const prefix = (workspaceId: string) => `/workspace/${workspaceId}/user_resource_permission` -/** 获取工作空间成员对指定类型资源的权限列表。 */ +/** 获取指定空间、指定用户、指定资源类型的权限列表。 */ const getUserResourcePermissions = ( workspaceId: string, userId: string, resource: ResourceAuthorizationType, query?: RequestParams, ) => { - return get(prefix(workspaceId, userId, resource), query) + return get( + `${prefix(workspaceId)}/user/${userId}/resource/${resource}`, + query, + ) } -/** 更新工作空间成员对指定类型资源的权限。 */ +/** 更新指定空间、指定用户、指定资源类型的权限列表。 */ const putUserResourcePermissions = ( workspaceId: string, userId: string, @@ -27,7 +30,7 @@ const putUserResourcePermissions = ( permissions: ResourcePermissionPayload[], ) => { return put( - prefix(workspaceId, userId, resource), + `${prefix(workspaceId)}/user/${userId}/resource/${resource}`, permissions, ) } diff --git a/ui/src/api/types/common.ts b/ui/src/api/types/common.ts index 7c8bf5a8179..7f91335b8f4 100644 --- a/ui/src/api/types/common.ts +++ b/ui/src/api/types/common.ts @@ -23,7 +23,7 @@ export interface ExportError { } } -export interface WorkspaceMemberOption { +export interface CommonUserOption { id: string nick_name: string roles?: string[] diff --git a/ui/src/components/COMPONENT_README.md b/ui/src/components/COMPONENT_README.md index 76a04f370e5..024d2288505 100644 --- a/ui/src/components/COMPONENT_README.md +++ b/ui/src/components/COMPONENT_README.md @@ -220,16 +220,18 @@ Escape 关闭;这些默认行为可以通过同名 Props 覆盖。Element Plus ``` 业务 Dialog 和 Drawer 的状态生命周期保持一致:`open()` 先调用 `resetData()`,再回填编辑数据并 -显示浮层;`close()` 先关闭浮层,再调用 `resetData()`;组件同时监听 `closed` 调用 -`resetData()`,确保点击右上角关闭按钮时也完成清理。`resetData()` 应统一重置表单、提交状态、 -临时选项和表单校验,不把清理逻辑散落在 `open()`、取消按钮或提交成功回调中。 +显示浮层;取消、提交成功或其他关闭操作直接将 `v-model` 绑定的可见状态设为 `false`,不额外定义或 +向父组件暴露 `close()`;组件统一监听 `closed` 调用 `resetData()`,确保所有关闭路径都在关闭动画 +结束后完成清理。`resetData()` 应统一重置表单、提交状态、临时选项和表单校验,不把清理逻辑散落在 +`open()`、取消按钮或提交成功回调中。 ### MkComplexSearch 用于在多个字段之间切换搜索条件。`fields` 中的基础字段使用 `@/api/types` 中的 `OptionItem`;字段包含 `options` 时使用下拉选择,否则使用文本输入。选项字段配置 `remoteMethod` 后自动启用远程搜索,并由该方法异步加载当前字段的选项。输入或选择完成时,`change` 返回 -`{ [field]: value }`;切换字段或清空条件时返回 `undefined`。 +`{ [field]: value }`;选项字段配置 `multiple: true` 时启用多选并返回值数组。切换字段或清空条件时 +返回 `undefined`。 ```vue