feat(documents): 支持全院通用和院区通用归属选择与展示
This commit is contained in:
@@ -107,7 +107,13 @@ function mapDocument(dto: TemplateResponseDto): DocumentRecord {
|
|||||||
versionId,
|
versionId,
|
||||||
currentVersionId: dto.currentVersionId ?? undefined,
|
currentVersionId: dto.currentVersionId ?? undefined,
|
||||||
departmentId: dto.departmentId,
|
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,
|
campusId: dto.campusId,
|
||||||
description: dto.description ?? '',
|
description: dto.description ?? '',
|
||||||
// 后端补齐这两个字段后卡片会自动显示「检查类型 / 关联项目」;
|
// 后端补齐这两个字段后卡片会自动显示「检查类型 / 关联项目」;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export interface DocumentQuery extends PageQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DocumentRecord {
|
export interface DocumentRecord {
|
||||||
|
ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT'
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
code?: string
|
code?: string
|
||||||
@@ -75,11 +76,12 @@ export type BackendTemplateStatus =
|
|||||||
| string
|
| string
|
||||||
|
|
||||||
export interface TemplateResponseDto {
|
export interface TemplateResponseDto {
|
||||||
|
ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT'
|
||||||
id: string
|
id: string
|
||||||
templateCode: string
|
templateCode: string
|
||||||
name: string
|
name: string
|
||||||
description?: string | null
|
description?: string | null
|
||||||
campusId: string
|
campusId: string | null
|
||||||
departmentId?: string | null
|
departmentId?: string | null
|
||||||
category?: string | null
|
category?: string | null
|
||||||
/**
|
/**
|
||||||
@@ -131,20 +133,22 @@ export interface TemplateVersionResponseDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateTemplateRequest {
|
export interface CreateTemplateRequest {
|
||||||
|
ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT'
|
||||||
templateCode: string
|
templateCode: string
|
||||||
name: string
|
name: string
|
||||||
description?: string
|
description?: string
|
||||||
campusId: string
|
campusId: string | null
|
||||||
departmentId?: string | null
|
departmentId?: string | null
|
||||||
category?: string
|
category?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateTemplateRequest {
|
export interface UpdateTemplateRequest {
|
||||||
|
ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT'
|
||||||
name: string
|
name: string
|
||||||
description?: string
|
description?: string
|
||||||
category?: string
|
category?: string
|
||||||
/** 修改归属时提供院区;不传则保留原归属。 */
|
/** 修改归属时提供院区;不传则保留原归属。 */
|
||||||
campusId?: string
|
campusId?: string | null
|
||||||
/** 提供院区时,null 表示该院区通用。 */
|
/** 提供院区时,null 表示该院区通用。 */
|
||||||
departmentId?: string | null
|
departmentId?: string | null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -780,9 +780,13 @@ function mapAvailableTemplate(dto: AvailableTemplateVersionResponseDto): Signing
|
|||||||
name: dto.templateName,
|
name: dto.templateName,
|
||||||
code: dto.templateCode,
|
code: dto.templateCode,
|
||||||
version: dto.versionNo,
|
version: dto.versionNo,
|
||||||
department: dto.departmentId ? '指定科室' : '全院通用',
|
department: dto.departmentId
|
||||||
|
? '指定科室'
|
||||||
|
: dto.ownershipScope === 'GLOBAL'
|
||||||
|
? '全院通用'
|
||||||
|
: '院区通用',
|
||||||
departmentId: dto.departmentId,
|
departmentId: dto.departmentId,
|
||||||
campusId: dto.campusId,
|
campusId: dto.campusId ?? undefined,
|
||||||
category: dto.category || '未分类',
|
category: dto.category || '未分类',
|
||||||
description: `已发布版本 ${dto.versionNo}`,
|
description: `已发布版本 ${dto.versionNo}`,
|
||||||
// 可用模板接口不返回方式 ACL;四种方式都放行,实际允许范围由后端在创建时校验。
|
// 可用模板接口不返回方式 ACL;四种方式都放行,实际允许范围由后端在创建时校验。
|
||||||
|
|||||||
@@ -477,12 +477,13 @@ export interface VisitResponseDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AvailableTemplateVersionResponseDto {
|
export interface AvailableTemplateVersionResponseDto {
|
||||||
|
ownershipScope?: 'GLOBAL' | 'CAMPUS' | 'DEPARTMENT'
|
||||||
templateId: string
|
templateId: string
|
||||||
templateVersionId: string
|
templateVersionId: string
|
||||||
templateCode: string
|
templateCode: string
|
||||||
templateName: string
|
templateName: string
|
||||||
category: string
|
category: string
|
||||||
campusId: string
|
campusId: string | null
|
||||||
departmentId: string | null
|
departmentId: string | null
|
||||||
versionNo: string
|
versionNo: string
|
||||||
contentSha256: string
|
contentSha256: string
|
||||||
|
|||||||
@@ -4,7 +4,14 @@ import { ElMessage } from 'element-plus'
|
|||||||
|
|
||||||
import type { CampusRecord, DepartmentRecord } from '@/api/management/types'
|
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 { DOC_TEMPLATE_PERMISSIONS } from '../permissions'
|
||||||
import type { DocumentPropsForm, DocumentTemplate } from '../types'
|
import type { DocumentPropsForm, DocumentTemplate } from '../types'
|
||||||
|
|
||||||
@@ -17,7 +24,7 @@ const props = defineProps<{
|
|||||||
/** 院区字典,与组织架构页同源;用来给上面的科室分组 */
|
/** 院区字典,与组织架构页同源;用来给上面的科室分组 */
|
||||||
campuses: CampusRecord[]
|
campuses: CampusRecord[]
|
||||||
/**
|
/**
|
||||||
* 是否可以把文档设为「通用(全院)」。
|
* 是否可以把文档设为「全院通用」。
|
||||||
*
|
*
|
||||||
* 原型 canSetGeneral() 只放给系统管理员 / 医务管理;这里由页面判定后传进来,
|
* 原型 canSetGeneral() 只放给系统管理员 / 医务管理;这里由页面判定后传进来,
|
||||||
* 弹窗不自己去读角色——弹窗只负责表单。
|
* 弹窗不自己去读角色——弹窗只负责表单。
|
||||||
@@ -57,7 +64,7 @@ const form = reactive<DocumentPropsForm>({
|
|||||||
})
|
})
|
||||||
|
|
||||||
interface OwnershipOption {
|
interface OwnershipOption {
|
||||||
/** 落库值:科室取 DepartmentRecord.id,「通用(全院)」取固定哨兵 */
|
/** 落库值:科室取 DepartmentRecord.id,「全院通用」取固定哨兵 */
|
||||||
value: string
|
value: string
|
||||||
label: string
|
label: string
|
||||||
}
|
}
|
||||||
@@ -74,7 +81,7 @@ interface OwnershipGroup {
|
|||||||
* 组织架构里的科室本来就挂在院区下面(同名科室在不同院区是两条记录),
|
* 组织架构里的科室本来就挂在院区下面(同名科室在不同院区是两条记录),
|
||||||
* 只摊平显示名字的话既看不出属于哪个院区、勾了也定位不到唯一的科室 id,
|
* 只摊平显示名字的话既看不出属于哪个院区、勾了也定位不到唯一的科室 id,
|
||||||
* 所以这里按科室的 campusId 归到对应院区下:显示院区名 + 科室名,取值用科室 id。
|
* 所以这里按科室的 campusId 归到对应院区下:显示院区名 + 科室名,取值用科室 id。
|
||||||
* 「通用(全院)」不是科室、没有院区,单独放最后一组。
|
* 「全院通用」不是科室、没有院区,单独放最后一组。
|
||||||
*/
|
*/
|
||||||
const ownershipGroups = computed<OwnershipGroup[]>(() => {
|
const ownershipGroups = computed<OwnershipGroup[]>(() => {
|
||||||
const groups: OwnershipGroup[] = []
|
const groups: OwnershipGroup[] = []
|
||||||
@@ -84,6 +91,8 @@ const ownershipGroups = computed<OwnershipGroup[]>(() => {
|
|||||||
.filter((department) => department.campusId === campus.id)
|
.filter((department) => department.campusId === campus.id)
|
||||||
.map((department) => ({ value: department.id, label: department.name }))
|
.map((department) => ({ value: department.id, label: department.name }))
|
||||||
|
|
||||||
|
if (props.canSetGeneral)
|
||||||
|
options.unshift({ value: campusOwnership(campus.id), label: '院区通用' })
|
||||||
if (options.length) {
|
if (options.length) {
|
||||||
groups.push({ key: campus.id, title: campus.name, options })
|
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 */
|
/** option 是勾选值:科室 id,或 GENERAL_OWNERSHIP */
|
||||||
function toggleOwnership(option: string) {
|
function toggleOwnership(option: string) {
|
||||||
|
if (option.startsWith('__campus_common__:')) {
|
||||||
|
form.ownership = form.ownership.includes(option) ? [] : [option]
|
||||||
|
return
|
||||||
|
}
|
||||||
if (option === GENERAL_OWNERSHIP) {
|
if (option === GENERAL_OWNERSHIP) {
|
||||||
// 勾上「通用(全院)」就清掉科室勾选,取消则回到空选择——
|
// 勾上「全院通用」就清掉科室勾选,取消则回到空选择——
|
||||||
// 两种选择混在一起会让「到底归属哪儿」没有唯一答案
|
// 两种选择混在一起会让「到底归属哪儿」没有唯一答案
|
||||||
form.ownership = generalSelected.value ? [] : [GENERAL_OWNERSHIP]
|
form.ownership = generalSelected.value ? [] : [GENERAL_OWNERSHIP]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generalSelected.value) {
|
if (generalSelected.value || ownershipCampusId(form.ownership)) {
|
||||||
form.ownership = []
|
form.ownership = []
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +170,9 @@ watch(
|
|||||||
? template.departmentId
|
? template.departmentId
|
||||||
? // 回填主科室用 departmentId 本身:勾选值就是科室 id,不再经名字中转
|
? // 回填主科室用 departmentId 本身:勾选值就是科室 id,不再经名字中转
|
||||||
[template.departmentId]
|
[template.departmentId]
|
||||||
: [GENERAL_OWNERSHIP]
|
: isGlobalOwnership(template)
|
||||||
|
? [GENERAL_OWNERSHIP]
|
||||||
|
: [campusOwnership(template.campusId ?? '')]
|
||||||
: // 新增时预选当前用户所属科室(对得上就直接用,对不上就空着让科室自己勾)
|
: // 新增时预选当前用户所属科室(对得上就直接用,对不上就空着让科室自己勾)
|
||||||
[],
|
[],
|
||||||
description: template?.description ?? '',
|
description: template?.description ?? '',
|
||||||
@@ -251,11 +266,9 @@ function submit() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="field-tip">
|
<p class="field-tip">
|
||||||
<template v-if="isMock">
|
<template v-if="isMock"> 勾选科室设置可见范围,支持多科室与全院通用。 </template>
|
||||||
勾选科室设置可见范围,支持多科室与通用(全院)。
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
选择一个归属科室,或选择「通用(全院)」供文档所属院区使用。归属仍受账号权限限制。
|
全院通用可供所有院区使用;院区通用仅供对应院区使用;也可选择一个专用科室。查看和维护仍受账号权限限制。
|
||||||
</template>
|
</template>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -448,7 +461,7 @@ function submit() {
|
|||||||
/*
|
/*
|
||||||
* 文档归属:原型 V10.2 的 .cg-dept —— 卡片式复选框网格。
|
* 文档归属:原型 V10.2 的 .cg-dept —— 卡片式复选框网格。
|
||||||
* 容器是浅底带框的 3 列网格,每项一张白卡(原生 checkbox + 科室名),
|
* 容器是浅底带框的 3 列网格,每项一张白卡(原生 checkbox + 科室名),
|
||||||
* 「通用(全院)」独占一行并用浅蓝底区分(原型 grid-column:1/-1)。
|
* 「全院通用」独占一行并用浅蓝底区分(原型 grid-column:1/-1)。
|
||||||
* 科室名过长时截断:原型同一处就是 nowrap + ellipsis。
|
* 科室名过长时截断:原型同一处就是 nowrap + ellipsis。
|
||||||
*
|
*
|
||||||
* 与原型唯一的差别:这里按院区分成若干个 .ownership(一个院区一个),
|
* 与原型唯一的差别:这里按院区分成若干个 .ownership(一个院区一个),
|
||||||
|
|||||||
@@ -49,7 +49,11 @@ const dotColor = computed(() => DOCUMENT_STATUS_DOT[tone.value])
|
|||||||
|
|
||||||
const isGeneral = computed(() => isGeneralOwnership(props.template))
|
const isGeneral = computed(() => isGeneralOwnership(props.template))
|
||||||
const ownershipLabel = computed(() =>
|
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<TemplateVersionAction | null>(() =>
|
|||||||
|
|
||||||
// 按钮文案与权限码的对应关系集中在模板里,避免多处各写一份
|
// 按钮文案与权限码的对应关系集中在模板里,避免多处各写一份
|
||||||
const permissions = DOC_TEMPLATE_PERMISSIONS
|
const permissions = DOC_TEMPLATE_PERMISSIONS
|
||||||
const togglePermission = computed(() =>
|
const togglePermission = computed(() => workflowPermission(toggleAction.value ?? 'disable'))
|
||||||
workflowPermission(toggleAction.value ?? 'disable'),
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -110,7 +112,8 @@ const togglePermission = computed(() =>
|
|||||||
|
|
||||||
<div class="tpl-tags">
|
<div class="tpl-tags">
|
||||||
<span class="exam-tag" :class="isGeneral ? 'is-general' : 'is-department'">
|
<span class="exam-tag" :class="isGeneral ? 'is-general' : 'is-department'">
|
||||||
{{ ownershipLabel }}<template v-if="!isGeneral && sharedCount"> ·+{{ sharedCount }} 科室</template>
|
{{ ownershipLabel
|
||||||
|
}}<template v-if="!isGeneral && sharedCount"> ·+{{ sharedCount }} 科室</template>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="examType" class="exam-tag is-exam">🔬 检查类型:{{ examType }}</span>
|
<span v-if="examType" class="exam-tag is-exam">🔬 检查类型:{{ examType }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ import {
|
|||||||
canInitiateSigning,
|
canInitiateSigning,
|
||||||
DOCUMENT_LIBRARY_STATUSES,
|
DOCUMENT_LIBRARY_STATUSES,
|
||||||
GENERAL_OWNERSHIP,
|
GENERAL_OWNERSHIP,
|
||||||
|
ownershipCampusId,
|
||||||
|
isGlobalOwnership,
|
||||||
|
CAMPUS_OWNERSHIP_PREFIX,
|
||||||
readLibraryStatus,
|
readLibraryStatus,
|
||||||
resolveOwnershipDepartmentId,
|
resolveOwnershipDepartmentId,
|
||||||
templateWorkflowAction,
|
templateWorkflowAction,
|
||||||
@@ -79,6 +82,7 @@ const useMockLibrary = mockFlags.documents
|
|||||||
|
|
||||||
/** 没有绑定科室的文书归到这一组(全院通用),不属于任何一个科室页签 */
|
/** 没有绑定科室的文书归到这一组(全院通用),不属于任何一个科室页签 */
|
||||||
const GENERAL_GROUP_KEY = '__all__'
|
const GENERAL_GROUP_KEY = '__all__'
|
||||||
|
const CAMPUS_GROUP_KEY = '__campus_common__'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面操作的服务端校验兜底。
|
* 页面操作的服务端校验兜底。
|
||||||
@@ -211,12 +215,16 @@ const departmentTabs = computed<DepartmentTab[]>(() => {
|
|||||||
|
|
||||||
const knownKeys = new Set(campusDepartments.map((department) => department.id))
|
const knownKeys = new Set(campusDepartments.map((department) => department.id))
|
||||||
const orphans = library.value.filter(
|
const orphans = library.value.filter(
|
||||||
(group) => group.key !== GENERAL_GROUP_KEY && !knownKeys.has(group.key),
|
(group) =>
|
||||||
|
group.key !== GENERAL_GROUP_KEY &&
|
||||||
|
group.key !== CAMPUS_GROUP_KEY &&
|
||||||
|
!knownKeys.has(group.key),
|
||||||
)
|
)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{ key: null, label: '全部', count: allTemplates.value.length },
|
{ key: null, label: '全部', count: allTemplates.value.length },
|
||||||
{ key: GENERAL_GROUP_KEY, label: '全院通用', count: countOf(GENERAL_GROUP_KEY) },
|
{ key: GENERAL_GROUP_KEY, label: '全院通用', count: countOf(GENERAL_GROUP_KEY) },
|
||||||
|
{ key: CAMPUS_GROUP_KEY, label: '院区通用', count: countOf(CAMPUS_GROUP_KEY) },
|
||||||
...campusDepartments.map((department) => ({
|
...campusDepartments.map((department) => ({
|
||||||
key: department.id,
|
key: department.id,
|
||||||
label: allCampusesSelected.value
|
label: allCampusesSelected.value
|
||||||
@@ -282,7 +290,7 @@ function cloneLibrary(source: DocumentDepartment[]): DocumentDepartment[] {
|
|||||||
* 把扁平的模板列表组织成页面需要的 科室 → 分类 → 文书 树。
|
* 把扁平的模板列表组织成页面需要的 科室 → 分类 → 文书 树。
|
||||||
*
|
*
|
||||||
* 分组键使用 departmentId,并用组织接口返回的科室字典补齐名称;没有绑定科室的模板
|
* 分组键使用 departmentId,并用组织接口返回的科室字典补齐名称;没有绑定科室的模板
|
||||||
* 归入“全院通用”。这样同一科室的模板无论接口返回顺序如何都会落进同一个分组。
|
* 按明确归属范围分别归入“全院通用”或“院区通用”。同一科室的模板落入同一分组。
|
||||||
*/
|
*/
|
||||||
function groupDocuments(
|
function groupDocuments(
|
||||||
records: DocumentRecord[],
|
records: DocumentRecord[],
|
||||||
@@ -294,10 +302,15 @@ function groupDocuments(
|
|||||||
)
|
)
|
||||||
|
|
||||||
records.forEach((record) => {
|
records.forEach((record) => {
|
||||||
const departmentKey = record.departmentId ?? GENERAL_GROUP_KEY
|
const departmentKey =
|
||||||
|
record.departmentId ?? (isGlobalOwnership(record) ? GENERAL_GROUP_KEY : CAMPUS_GROUP_KEY)
|
||||||
const departmentName =
|
const departmentName =
|
||||||
record.departmentName ??
|
record.departmentName ??
|
||||||
(record.departmentId ? (departmentNames.get(record.departmentId) ?? '未知科室') : '全院通用')
|
(record.departmentId
|
||||||
|
? (departmentNames.get(record.departmentId) ?? '未知科室')
|
||||||
|
: isGlobalOwnership(record)
|
||||||
|
? '全院通用'
|
||||||
|
: '院区通用')
|
||||||
|
|
||||||
let department = grouped.get(departmentKey)
|
let department = grouped.get(departmentKey)
|
||||||
|
|
||||||
@@ -314,7 +327,11 @@ function groupDocuments(
|
|||||||
department.categories.push(category)
|
department.categories.push(category)
|
||||||
}
|
}
|
||||||
|
|
||||||
category.documents.push({ ...record, departmentName })
|
category.documents.push({
|
||||||
|
...record,
|
||||||
|
departmentName,
|
||||||
|
campusName: campuses.value.find((campus) => campus.id === record.campusId)?.name,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// 全院通用的模板排最前,其余按科室名排序,保证每次进页面分组顺序稳定
|
// 全院通用的模板排最前,其余按科室名排序,保证每次进页面分组顺序稳定
|
||||||
@@ -539,7 +556,12 @@ function generateTemplateCode(name: string) {
|
|||||||
*/
|
*/
|
||||||
function sharedDepartmentNames(ownership: string[], primaryDepartmentId: string | null): string[] {
|
function sharedDepartmentNames(ownership: string[], primaryDepartmentId: string | null): string[] {
|
||||||
return ownership
|
return ownership
|
||||||
.filter((value) => value !== GENERAL_OWNERSHIP && value !== primaryDepartmentId)
|
.filter(
|
||||||
|
(value) =>
|
||||||
|
value !== GENERAL_OWNERSHIP &&
|
||||||
|
!value.startsWith(CAMPUS_OWNERSHIP_PREFIX) &&
|
||||||
|
value !== primaryDepartmentId,
|
||||||
|
)
|
||||||
.map((id) => departments.value.find((department) => department.id === id)?.name)
|
.map((id) => departments.value.find((department) => department.id === id)?.name)
|
||||||
.filter((name): name is string => Boolean(name))
|
.filter((name): name is string => Boolean(name))
|
||||||
}
|
}
|
||||||
@@ -567,9 +589,11 @@ function locateLocalDocument(id: string) {
|
|||||||
/** 演示模式:把新文书追加进本地文库(分组按科室名匹配已有分组) */
|
/** 演示模式:把新文书追加进本地文库(分组按科室名匹配已有分组) */
|
||||||
function addLocalTemplate(form: DocumentPropsForm, departmentId: string | null): DocumentTemplate {
|
function addLocalTemplate(form: DocumentPropsForm, departmentId: string | null): DocumentTemplate {
|
||||||
const department = departments.value.find((item) => item.id === departmentId)
|
const department = departments.value.find((item) => item.id === departmentId)
|
||||||
const departmentName = department?.name ?? '全院通用'
|
const global = form.ownership.includes(GENERAL_OWNERSHIP)
|
||||||
|
const campusId = global ? null : department?.campusId || ownershipCampusId(form.ownership)
|
||||||
|
const departmentName = department?.name ?? (global ? '全院通用' : '院区通用')
|
||||||
// 真实模式用 departmentId 当分组键,演示模式没有 UUID,用品名保持同样语义
|
// 真实模式用 departmentId 当分组键,演示模式没有 UUID,用品名保持同样语义
|
||||||
const departmentKey = department?.id ?? GENERAL_GROUP_KEY
|
const departmentKey = department?.id ?? (global ? GENERAL_GROUP_KEY : CAMPUS_GROUP_KEY)
|
||||||
let departmentGroup = library.value.find((item) => item.key === departmentKey)
|
let departmentGroup = library.value.find((item) => item.key === departmentKey)
|
||||||
|
|
||||||
if (!departmentGroup) {
|
if (!departmentGroup) {
|
||||||
@@ -607,7 +631,9 @@ function addLocalTemplate(form: DocumentPropsForm, departmentId: string | null):
|
|||||||
versionId: `local-version-${timestamp}`,
|
versionId: `local-version-${timestamp}`,
|
||||||
departmentId: departmentId,
|
departmentId: departmentId,
|
||||||
departmentName,
|
departmentName,
|
||||||
campusId: campuses.value[0]?.id ?? '',
|
campusId,
|
||||||
|
ownershipScope: global ? 'GLOBAL' : departmentId ? 'DEPARTMENT' : 'CAMPUS',
|
||||||
|
campusName: campuses.value.find((campus) => campus.id === campusId)?.name,
|
||||||
contentHtml: '',
|
contentHtml: '',
|
||||||
sharedDepartments: sharedDepartmentNames(form.ownership, departmentId),
|
sharedDepartments: sharedDepartmentNames(form.ownership, departmentId),
|
||||||
}
|
}
|
||||||
@@ -626,9 +652,11 @@ function addLocalTemplate(form: DocumentPropsForm, departmentId: string | null):
|
|||||||
*/
|
*/
|
||||||
function updateLocalProps(form: DocumentPropsForm, departmentId: string | null) {
|
function updateLocalProps(form: DocumentPropsForm, departmentId: string | null) {
|
||||||
const target = departments.value.find((item) => item.id === departmentId)
|
const target = departments.value.find((item) => item.id === departmentId)
|
||||||
const targetName = target?.name ?? '全院通用'
|
const global = form.ownership.includes(GENERAL_OWNERSHIP)
|
||||||
|
const campusId = global ? null : target?.campusId || ownershipCampusId(form.ownership)
|
||||||
|
const targetName = target?.name ?? (global ? '全院通用' : '院区通用')
|
||||||
// 与 addLocalTemplate 同一套分组键口径:演示模式没有 UUID 时落 GENERAL_GROUP_KEY
|
// 与 addLocalTemplate 同一套分组键口径:演示模式没有 UUID 时落 GENERAL_GROUP_KEY
|
||||||
const targetKey = target?.id ?? GENERAL_GROUP_KEY
|
const targetKey = target?.id ?? (global ? GENERAL_GROUP_KEY : CAMPUS_GROUP_KEY)
|
||||||
const located = locateLocalDocument(form.id ?? '')
|
const located = locateLocalDocument(form.id ?? '')
|
||||||
|
|
||||||
if (!located) {
|
if (!located) {
|
||||||
@@ -644,6 +672,9 @@ function updateLocalProps(form: DocumentPropsForm, departmentId: string | null)
|
|||||||
document.updatedAt = new Date().toISOString()
|
document.updatedAt = new Date().toISOString()
|
||||||
document.departmentId = departmentId
|
document.departmentId = departmentId
|
||||||
document.departmentName = targetName
|
document.departmentName = targetName
|
||||||
|
document.campusId = campusId
|
||||||
|
document.campusName = campuses.value.find((campus) => campus.id === campusId)?.name
|
||||||
|
document.ownershipScope = global ? 'GLOBAL' : departmentId ? 'DEPARTMENT' : 'CAMPUS'
|
||||||
// 主科室进 departmentId,其余勾选科室留在 sharedDepartments(与新建时同一口径)
|
// 主科室进 departmentId,其余勾选科室留在 sharedDepartments(与新建时同一口径)
|
||||||
document.sharedDepartments = sharedDepartmentNames(form.ownership, departmentId)
|
document.sharedDepartments = sharedDepartmentNames(form.ownership, departmentId)
|
||||||
|
|
||||||
@@ -705,10 +736,10 @@ async function handlePropsSubmit(form: DocumentPropsForm) {
|
|||||||
ElMessage.error('所选科室不存在,请刷新后重试')
|
ElMessage.error('所选科室不存在,请刷新后重试')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const campusId =
|
const global = form.ownership.includes(GENERAL_OWNERSHIP)
|
||||||
targetDepartment?.campusId ||
|
const campusId = global ? null : targetDepartment?.campusId || ownershipCampusId(form.ownership)
|
||||||
(form.id ? propsTemplate.value?.campusId : appStore.selectedCampusId || campuses.value[0]?.id)
|
const ownershipScope = global ? 'GLOBAL' : departmentId ? 'DEPARTMENT' : 'CAMPUS'
|
||||||
if (!campusId) {
|
if (!global && !campusId) {
|
||||||
ElMessage.error('无法确定文档所属院区,请选择院区后重试')
|
ElMessage.error('无法确定文档所属院区,请选择院区后重试')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -719,6 +750,7 @@ async function handlePropsSubmit(form: DocumentPropsForm) {
|
|||||||
category: form.category,
|
category: form.category,
|
||||||
campusId,
|
campusId,
|
||||||
departmentId,
|
departmentId,
|
||||||
|
ownershipScope,
|
||||||
})
|
})
|
||||||
closePropsDialog()
|
closePropsDialog()
|
||||||
await loadLibrary()
|
await loadLibrary()
|
||||||
@@ -732,6 +764,7 @@ async function handlePropsSubmit(form: DocumentPropsForm) {
|
|||||||
description: form.description,
|
description: form.description,
|
||||||
campusId,
|
campusId,
|
||||||
departmentId,
|
departmentId,
|
||||||
|
ownershipScope,
|
||||||
category: form.category,
|
category: form.category,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -131,22 +131,32 @@ export function templateWorkflowLabel(
|
|||||||
case 'PUBLISHED':
|
case 'PUBLISHED':
|
||||||
return '停用'
|
return '停用'
|
||||||
default:
|
default:
|
||||||
return record.backendStatus
|
return record.backendStatus ? '' : readLibraryStatus(record) === '停用' ? '启用' : '停用'
|
||||||
? ''
|
|
||||||
: readLibraryStatus(record) === '停用'
|
|
||||||
? '启用'
|
|
||||||
: '停用'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档归属:原型把「通用(全院)」当作科室清单里的一个选项一起勾选,
|
* 文档归属:原型把「全院通用」当作科室清单里的一个选项一起勾选,
|
||||||
* 勾中它就等于全院通用,其余科室勾选一并作废(见 docDeptPicks / openDocProps)。
|
* 勾中它就等于全院通用,其余科室勾选一并作废(见 docDeptPicks / openDocProps)。
|
||||||
*/
|
*/
|
||||||
export const GENERAL_OWNERSHIP = '通用(全院)'
|
export const GENERAL_OWNERSHIP = '全院通用'
|
||||||
|
export const CAMPUS_OWNERSHIP_PREFIX = '__campus_common__:'
|
||||||
|
export function campusOwnership(campusId: string): string {
|
||||||
|
return `${CAMPUS_OWNERSHIP_PREFIX}${campusId}`
|
||||||
|
}
|
||||||
|
export function ownershipCampusId(ownership: string[]): string | null {
|
||||||
|
const value = ownership.find((item) => item.startsWith(CAMPUS_OWNERSHIP_PREFIX))
|
||||||
|
return value ? value.slice(CAMPUS_OWNERSHIP_PREFIX.length) : null
|
||||||
|
}
|
||||||
|
export function isGlobalOwnership(record: DocumentRecord): boolean {
|
||||||
|
return (
|
||||||
|
record.ownershipScope === 'GLOBAL' ||
|
||||||
|
(!record.ownershipScope && !record.campusId && !record.departmentId)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 归属勾选 → 后端可落库的科室 id(勾了通用(全院)就没有科室 id)。
|
* 归属勾选 → 后端可落库的科室 id(勾了全院通用就没有科室 id)。
|
||||||
*
|
*
|
||||||
* 勾选值本身就是 DepartmentRecord.id:同名科室在不同院区是两条记录,
|
* 勾选值本身就是 DepartmentRecord.id:同名科室在不同院区是两条记录,
|
||||||
* 这里不再拿名字去反查(反查只能取到第一条,会把院区指错)。
|
* 这里不再拿名字去反查(反查只能取到第一条,会把院区指错)。
|
||||||
@@ -156,13 +166,19 @@ export function resolveOwnershipDepartmentId(ownership: string[]): string | null
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return ownership.find((value) => value !== GENERAL_OWNERSHIP) ?? null
|
return (
|
||||||
|
ownership.find(
|
||||||
|
(value) => value !== GENERAL_OWNERSHIP && !value.startsWith(CAMPUS_OWNERSHIP_PREFIX),
|
||||||
|
) ?? null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 归属徽标文案:全院通用用 🌐,科室用 🏥(与原型 tpl-card 的标签一致) */
|
/** 归属徽标文案:全院通用用 🌐,科室用 🏥(与原型 tpl-card 的标签一致) */
|
||||||
export function readOwnershipLabel(record: DocumentRecord): string {
|
export function readOwnershipLabel(record: DocumentRecord): string {
|
||||||
if (!record.departmentId) {
|
if (!record.departmentId) {
|
||||||
return '🌐 全院通用'
|
return isGlobalOwnership(record)
|
||||||
|
? '🌐 全院通用'
|
||||||
|
: `🏥 ${record.campusName ?? '所属院区'} · 院区通用`
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = record.departmentName ?? '未知科室'
|
const name = record.departmentName ?? '未知科室'
|
||||||
@@ -180,12 +196,6 @@ export function isGeneralOwnership(record: DocumentRecord): boolean {
|
|||||||
* 与原型 docTypes 同一份取值,属性弹窗用下拉而不是自由输入:
|
* 与原型 docTypes 同一份取值,属性弹窗用下拉而不是自由输入:
|
||||||
* 类型是分组的键,自由输入会让「知情同意书 / 知情同意书 」这类写法分成两组。
|
* 类型是分组的键,自由输入会让「知情同意书 / 知情同意书 」这类写法分成两组。
|
||||||
*/
|
*/
|
||||||
export const DOCUMENT_TYPES = [
|
export const DOCUMENT_TYPES = ['知情同意书', '风险告知书', '入院告知', '检查预约单', '授权委托']
|
||||||
'知情同意书',
|
|
||||||
'风险告知书',
|
|
||||||
'入院告知',
|
|
||||||
'检查预约单',
|
|
||||||
'授权委托',
|
|
||||||
]
|
|
||||||
|
|
||||||
export const DEFAULT_DOCUMENT_TYPE = '知情同意书'
|
export const DEFAULT_DOCUMENT_TYPE = '知情同意书'
|
||||||
|
|||||||
Reference in New Issue
Block a user