diff --git a/clinical-web/src/api/management/documents.ts b/clinical-web/src/api/management/documents.ts index 27d9722..11a2e20 100644 --- a/clinical-web/src/api/management/documents.ts +++ b/clinical-web/src/api/management/documents.ts @@ -107,7 +107,13 @@ function mapDocument(dto: TemplateResponseDto): DocumentRecord { versionId, currentVersionId: dto.currentVersionId ?? undefined, departmentId: dto.departmentId, - departmentName: dto.departmentId ? undefined : '全院通用', + ownershipScope: + dto.ownershipScope ?? (dto.departmentId ? 'DEPARTMENT' : dto.campusId ? 'CAMPUS' : 'GLOBAL'), + departmentName: dto.departmentId + ? undefined + : dto.ownershipScope === 'GLOBAL' + ? '全院通用' + : '院区通用', campusId: dto.campusId, description: dto.description ?? '', // 后端补齐这两个字段后卡片会自动显示「检查类型 / 关联项目」; diff --git a/clinical-web/src/api/management/types.ts b/clinical-web/src/api/management/types.ts index df7bd3f..c47c0ca 100644 --- a/clinical-web/src/api/management/types.ts +++ b/clinical-web/src/api/management/types.ts @@ -10,6 +10,7 @@ export interface DocumentQuery extends PageQuery { } export interface DocumentRecord { + ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT' id: string name: string code?: string @@ -75,11 +76,12 @@ export type BackendTemplateStatus = | string export interface TemplateResponseDto { + ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT' id: string templateCode: string name: string description?: string | null - campusId: string + campusId: string | null departmentId?: string | null category?: string | null /** @@ -131,20 +133,22 @@ export interface TemplateVersionResponseDto { } export interface CreateTemplateRequest { + ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT' templateCode: string name: string description?: string - campusId: string + campusId: string | null departmentId?: string | null category?: string } export interface UpdateTemplateRequest { + ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT' name: string description?: string category?: string /** 修改归属时提供院区;不传则保留原归属。 */ - campusId?: string + campusId?: string | null /** 提供院区时,null 表示该院区通用。 */ departmentId?: string | null } diff --git a/clinical-web/src/api/workbench/signing.ts b/clinical-web/src/api/workbench/signing.ts index 6208006..c2ff0f0 100644 --- a/clinical-web/src/api/workbench/signing.ts +++ b/clinical-web/src/api/workbench/signing.ts @@ -780,9 +780,13 @@ function mapAvailableTemplate(dto: AvailableTemplateVersionResponseDto): Signing name: dto.templateName, code: dto.templateCode, version: dto.versionNo, - department: dto.departmentId ? '指定科室' : '全院通用', + department: dto.departmentId + ? '指定科室' + : dto.ownershipScope === 'GLOBAL' + ? '全院通用' + : '院区通用', departmentId: dto.departmentId, - campusId: dto.campusId, + campusId: dto.campusId ?? undefined, category: dto.category || '未分类', description: `已发布版本 ${dto.versionNo}`, // 可用模板接口不返回方式 ACL;四种方式都放行,实际允许范围由后端在创建时校验。 diff --git a/clinical-web/src/api/workbench/types.ts b/clinical-web/src/api/workbench/types.ts index fe27287..0a6517a 100644 --- a/clinical-web/src/api/workbench/types.ts +++ b/clinical-web/src/api/workbench/types.ts @@ -477,12 +477,13 @@ export interface VisitResponseDto { } export interface AvailableTemplateVersionResponseDto { + ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT' templateId: string templateVersionId: string templateCode: string templateName: string category: string - campusId: string + campusId: string | null departmentId: string | null versionNo: string contentSha256: string diff --git a/clinical-web/src/views/management/documents/components/DocumentPropsDialog.vue b/clinical-web/src/views/management/documents/components/DocumentPropsDialog.vue index 5c6c21b..1d3c48e 100644 --- a/clinical-web/src/views/management/documents/components/DocumentPropsDialog.vue +++ b/clinical-web/src/views/management/documents/components/DocumentPropsDialog.vue @@ -4,7 +4,14 @@ import { ElMessage } from 'element-plus' import type { CampusRecord, DepartmentRecord } from '@/api/management/types' -import { DEFAULT_DOCUMENT_TYPE, DOCUMENT_TYPES, GENERAL_OWNERSHIP } from '../library' +import { + DEFAULT_DOCUMENT_TYPE, + DOCUMENT_TYPES, + GENERAL_OWNERSHIP, + campusOwnership, + isGlobalOwnership, + ownershipCampusId, +} from '../library' import { DOC_TEMPLATE_PERMISSIONS } from '../permissions' import type { DocumentPropsForm, DocumentTemplate } from '../types' @@ -17,7 +24,7 @@ const props = defineProps<{ /** 院区字典,与组织架构页同源;用来给上面的科室分组 */ campuses: CampusRecord[] /** - * 是否可以把文档设为「通用(全院)」。 + * 是否可以把文档设为「全院通用」。 * * 原型 canSetGeneral() 只放给系统管理员 / 医务管理;这里由页面判定后传进来, * 弹窗不自己去读角色——弹窗只负责表单。 @@ -57,7 +64,7 @@ const form = reactive({ }) interface OwnershipOption { - /** 落库值:科室取 DepartmentRecord.id,「通用(全院)」取固定哨兵 */ + /** 落库值:科室取 DepartmentRecord.id,「全院通用」取固定哨兵 */ value: string label: string } @@ -74,7 +81,7 @@ interface OwnershipGroup { * 组织架构里的科室本来就挂在院区下面(同名科室在不同院区是两条记录), * 只摊平显示名字的话既看不出属于哪个院区、勾了也定位不到唯一的科室 id, * 所以这里按科室的 campusId 归到对应院区下:显示院区名 + 科室名,取值用科室 id。 - * 「通用(全院)」不是科室、没有院区,单独放最后一组。 + * 「全院通用」不是科室、没有院区,单独放最后一组。 */ const ownershipGroups = computed(() => { const groups: OwnershipGroup[] = [] @@ -84,6 +91,8 @@ const ownershipGroups = computed(() => { .filter((department) => department.campusId === campus.id) .map((department) => ({ value: department.id, label: department.name })) + if (props.canSetGeneral) + options.unshift({ value: campusOwnership(campus.id), label: '院区通用' }) if (options.length) { groups.push({ key: campus.id, title: campus.name, options }) } @@ -114,14 +123,18 @@ const generalSelected = computed(() => form.ownership.includes(GENERAL_OWNERSHIP /** option 是勾选值:科室 id,或 GENERAL_OWNERSHIP */ function toggleOwnership(option: string) { + if (option.startsWith('__campus_common__:')) { + form.ownership = form.ownership.includes(option) ? [] : [option] + return + } if (option === GENERAL_OWNERSHIP) { - // 勾上「通用(全院)」就清掉科室勾选,取消则回到空选择—— + // 勾上「全院通用」就清掉科室勾选,取消则回到空选择—— // 两种选择混在一起会让「到底归属哪儿」没有唯一答案 form.ownership = generalSelected.value ? [] : [GENERAL_OWNERSHIP] return } - if (generalSelected.value) { + if (generalSelected.value || ownershipCampusId(form.ownership)) { form.ownership = [] } @@ -157,7 +170,9 @@ watch( ? template.departmentId ? // 回填主科室用 departmentId 本身:勾选值就是科室 id,不再经名字中转 [template.departmentId] - : [GENERAL_OWNERSHIP] + : isGlobalOwnership(template) + ? [GENERAL_OWNERSHIP] + : [campusOwnership(template.campusId ?? '')] : // 新增时预选当前用户所属科室(对得上就直接用,对不上就空着让科室自己勾) [], description: template?.description ?? '', @@ -251,11 +266,9 @@ function submit() {

- +

@@ -448,7 +461,7 @@ function submit() { /* * 文档归属:原型 V10.2 的 .cg-dept —— 卡片式复选框网格。 * 容器是浅底带框的 3 列网格,每项一张白卡(原生 checkbox + 科室名), - * 「通用(全院)」独占一行并用浅蓝底区分(原型 grid-column:1/-1)。 + * 「全院通用」独占一行并用浅蓝底区分(原型 grid-column:1/-1)。 * 科室名过长时截断:原型同一处就是 nowrap + ellipsis。 * * 与原型唯一的差别:这里按院区分成若干个 .ownership(一个院区一个), diff --git a/clinical-web/src/views/management/documents/components/DocumentTemplateCard.vue b/clinical-web/src/views/management/documents/components/DocumentTemplateCard.vue index baae624..cb5ab8a 100644 --- a/clinical-web/src/views/management/documents/components/DocumentTemplateCard.vue +++ b/clinical-web/src/views/management/documents/components/DocumentTemplateCard.vue @@ -49,7 +49,11 @@ const dotColor = computed(() => DOCUMENT_STATUS_DOT[tone.value]) const isGeneral = computed(() => isGeneralOwnership(props.template)) const ownershipLabel = computed(() => - isGeneral.value ? '🌐 全院通用' : `🏥 ${props.template.departmentName ?? '未知科室'}`, + isGeneral.value + ? props.template.ownershipScope === 'GLOBAL' || !props.template.campusId + ? '🌐 全院通用' + : `🏥 ${props.template.campusName ?? '所属院区'} · 院区通用` + : `🏥 ${props.template.departmentName ?? '未知科室'}`, ) /** @@ -91,9 +95,7 @@ const toggleAction = computed(() => // 按钮文案与权限码的对应关系集中在模板里,避免多处各写一份 const permissions = DOC_TEMPLATE_PERMISSIONS -const togglePermission = computed(() => - workflowPermission(toggleAction.value ?? 'disable'), -) +const togglePermission = computed(() => workflowPermission(toggleAction.value ?? 'disable'))