From e467f03f23e8833f4b3432073c55be46efc2260d Mon Sep 17 00:00:00 2001 From: yelan Date: Tue, 1 Sep 2026 10:13:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(management):=20=E6=8E=A5=E5=85=A5=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E7=94=A8=E6=88=B7=E6=9D=83=E9=99=90=E4=B8=8E=E6=8A=A5?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/TemplatePermissionPanel.vue | 381 ++++++++++++++ .../management/document-permissions/index.vue | 171 +++++- .../management/document-permissions/types.ts | 13 + .../components/DocumentPreviewDialog.vue | 59 ++- .../components/DocumentTemplateCard.vue | 19 +- .../components/TemplateEditorDialog.vue | 498 ++++++++++++++++++ .../src/views/management/documents/index.vue | 397 +++++++++++++- .../src/views/management/documents/types.ts | 18 + .../src/views/management/reports/index.vue | 165 +++++- .../users/components/UserEditorDialog.vue | 380 +++++++++++++ .../src/views/management/users/index.vue | 282 +++++++++- .../src/views/management/users/types.ts | 19 + 12 files changed, 2361 insertions(+), 41 deletions(-) create mode 100644 clinical-web/src/views/management/document-permissions/components/TemplatePermissionPanel.vue create mode 100644 clinical-web/src/views/management/documents/components/TemplateEditorDialog.vue create mode 100644 clinical-web/src/views/management/users/components/UserEditorDialog.vue diff --git a/clinical-web/src/views/management/document-permissions/components/TemplatePermissionPanel.vue b/clinical-web/src/views/management/document-permissions/components/TemplatePermissionPanel.vue new file mode 100644 index 0000000..a3dd930 --- /dev/null +++ b/clinical-web/src/views/management/document-permissions/components/TemplatePermissionPanel.vue @@ -0,0 +1,381 @@ + + + + + diff --git a/clinical-web/src/views/management/document-permissions/index.vue b/clinical-web/src/views/management/document-permissions/index.vue index f5f1259..2a7f819 100644 --- a/clinical-web/src/views/management/document-permissions/index.vue +++ b/clinical-web/src/views/management/document-permissions/index.vue @@ -2,24 +2,118 @@ import { onMounted, ref } from 'vue' import { ElMessage } from 'element-plus' +import { getDepartments } from '@/api/management/organization' +import { getDocuments } from '@/api/management/documents' +import { + createTemplatePermission, + deleteTemplatePermission, + getTemplatePermissions, + isPermissionMockEnabled, +} from '@/api/management/document-permissions' +import { getRoles } from '@/api/management/roles' +import { getUsers } from '@/api/management/users' +import type { DocumentRecord, TemplatePermissionRecord } from '@/api/management/types' + import DepartmentPermissionTable from './components/DepartmentPermissionTable.vue' import RolePermissionMatrix from './components/RolePermissionMatrix.vue' +import TemplatePermissionPanel from './components/TemplatePermissionPanel.vue' import { departmentPermissionRows, permissionColumns, rolePermissionRows } from './mock' -import type { DepartmentPermissionRow, PermissionKey, RolePermissionRow } from './types' +import type { + DepartmentPermissionRow, + PermissionKey, + PermissionSubjectOption, + RolePermissionRow, + TemplatePermissionForm, +} from './types' const loading = ref(true) const roles = ref([]) const departments = ref([]) +const templates = ref([]) +const selectedTemplateId = ref('') +const templatePermissions = ref([]) +const permissionSubjects = ref([]) +const permissionLoading = ref(false) +const permissionSaving = ref(false) async function loadPermissions() { loading.value = true - await Promise.resolve() - roles.value = rolePermissionRows.map((role) => ({ - ...role, - permissions: { ...role.permissions }, - })) - departments.value = departmentPermissionRows.map((row) => ({ ...row })) - loading.value = false + + try { + if (isPermissionMockEnabled) { + roles.value = rolePermissionRows.map((role) => ({ + ...role, + permissions: { ...role.permissions }, + })) + departments.value = departmentPermissionRows.map((row) => ({ ...row })) + return + } + + const [templatesResult, rolesResult, departmentsResult, usersResult] = await Promise.allSettled( + [ + getDocuments({ page: 1, pageSize: 200, status: 'all' }), + getRoles(), + getDepartments(), + getUsers({ page: 1, pageSize: 200, status: 'all' }), + ], + ) + + if (templatesResult.status === 'rejected') { + throw templatesResult.reason + } + + templates.value = templatesResult.value.records + selectedTemplateId.value = templates.value[0]?.id ?? '' + permissionSubjects.value = [ + ...(rolesResult.status === 'fulfilled' + ? rolesResult.value.map((role) => ({ + type: 'ROLE' as const, + id: role.id, + label: role.name, + })) + : []), + ...(departmentsResult.status === 'fulfilled' + ? departmentsResult.value.map((department) => ({ + type: 'DEPARTMENT' as const, + id: department.id, + label: department.name, + })) + : []), + ...(usersResult.status === 'fulfilled' + ? usersResult.value.records.map((user) => ({ + type: 'USER' as const, + id: user.id, + label: `${user.name}${user.employeeNo ? `(${user.employeeNo})` : ''}`, + })) + : []), + ] + await loadTemplatePermissions() + } catch { + templates.value = [] + permissionSubjects.value = [] + templatePermissions.value = [] + ElMessage.error('权限配置加载失败,请稍后重试') + } finally { + loading.value = false + } +} + +async function loadTemplatePermissions() { + if (!selectedTemplateId.value || isPermissionMockEnabled) { + templatePermissions.value = [] + return + } + + permissionLoading.value = true + + try { + templatePermissions.value = await getTemplatePermissions(selectedTemplateId.value) + } catch { + templatePermissions.value = [] + ElMessage.error('模板权限加载失败,请稍后重试') + } finally { + permissionLoading.value = false + } } function toggleRolePermission(roleId: string, permission: PermissionKey) { @@ -37,6 +131,47 @@ function adjustDepartmentPermission(row: DepartmentPermissionRow) { ElMessage.info(`原型演示:调整${row.department}文档权限`) } +async function addTemplatePermission(form: TemplatePermissionForm) { + if (!selectedTemplateId.value) { + return + } + + permissionSaving.value = true + + try { + await createTemplatePermission(selectedTemplateId.value, form) + await loadTemplatePermissions() + ElMessage.success('模板权限已添加') + } catch { + ElMessage.error('模板权限添加失败,请稍后重试') + } finally { + permissionSaving.value = false + } +} + +async function deleteTemplatePermissionRecord(permissionId: string) { + if (!selectedTemplateId.value || !window.confirm('确定删除这条模板权限吗?')) { + return + } + + permissionSaving.value = true + + try { + await deleteTemplatePermission(selectedTemplateId.value, permissionId) + await loadTemplatePermissions() + ElMessage.success('模板权限已删除') + } catch { + ElMessage.error('模板权限删除失败,请稍后重试') + } finally { + permissionSaving.value = false + } +} + +function selectTemplate(templateId: string) { + selectedTemplateId.value = templateId + void loadTemplatePermissions() +} + onMounted(loadPermissions) @@ -61,7 +196,7 @@ onMounted(loadPermissions) - diff --git a/clinical-web/src/views/management/document-permissions/types.ts b/clinical-web/src/views/management/document-permissions/types.ts index 9df1cb0..dbde5ce 100644 --- a/clinical-web/src/views/management/document-permissions/types.ts +++ b/clinical-web/src/views/management/document-permissions/types.ts @@ -24,3 +24,16 @@ export interface DepartmentPermissionRow { commonDocuments: DepartmentDocumentAccess otherDocuments: DepartmentDocumentAccess } + +export interface PermissionSubjectOption { + id: string + type: 'ROLE' | 'DEPARTMENT' | 'USER' + label: string +} + +export interface TemplatePermissionForm { + subjectType: PermissionSubjectOption['type'] + subjectId: string + permissionLevel: 'VIEW' | 'USE' | 'MAINTAIN' + effect: 'ALLOW' | 'DENY' +} diff --git a/clinical-web/src/views/management/documents/components/DocumentPreviewDialog.vue b/clinical-web/src/views/management/documents/components/DocumentPreviewDialog.vue index 4624197..415ddc0 100644 --- a/clinical-web/src/views/management/documents/components/DocumentPreviewDialog.vue +++ b/clinical-web/src/views/management/documents/components/DocumentPreviewDialog.vue @@ -7,6 +7,8 @@ import type { DocumentTemplate } from '../types' const props = defineProps<{ visible: boolean template: DocumentTemplate | null + loading: boolean + error: boolean }>() const emit = defineEmits<{ @@ -49,7 +51,18 @@ const statusLabel = computed(() => {
-
+
正在加载模板内容…
+
+ 模板内容加载失败,请关闭后重试。 +
+