feat(签署任务): 新增「待科室确认」节点整条链路
原型 V10.2 的 needConfirm:检验 / 基因检测 / 自费类文书要求患者签完之后 由科室再复核签章,避免漏签补签。此前仓库完全没有这个节点,现在补全。 状态模型 - SigningTaskStatus 增加 confirming(待科室确认),BackendSigningTaskStatus 增加 WAITING_CONFIRM;文档侧 DocumentRecord / TemplateResponseDto / SigningTemplate / CreateSigningTaskInput 增加 needConfirm。 - normalizeTaskStatus、mapSigningTask、mapDocument、toBackendTaskQuery 的 statusMap、 mapAvailableTemplate、readLocalSigningTemplates 同步;needConfirm 取不到一律按 false, 不凭空给任务多插一道人工节点。 流转 - completeSigningTask 按 needConfirm 决定落 confirming 还是 signed; 新增 confirmDepartmentSigning(科室复核签章 → 已签署)。 真实模式暂未接入(后端要重做),如实提示"待接入",不前端自己改状态。 - 任务事件与记录页事件补「已推送至 X 确认队列」「科室复核签章完成,文档归档」两条留痕。 工作台 - 列表徽标走 .task-status--confirming(原型 tg-cfm 橙),状态筛选加「待科室确认」。 - 详情动作按原型给:🏛 科室复核签章(确认完成)+ 催办 + 在线预览 + 下载已签 PDF; 该状态下不给「作废」(原型只在待签署/已超时给)。 - 新增「科室确认节点」卡(待患者签署后 / 待科室确认 / ✓ 已确认三分支)—— 原型放在文书签名区那一格,这里做成紧跟文书的独立卡,真实模板与回退纸样都能显示。 - confirming 时文书只读(患者已签完,不该再改填写项)。 - 签署完成提示语按 needConfirm 分流:需科室确认的说「已流转至科室确认节点」, 否则说「签署完成,文档已归档」—— 一律说"完成"会让人以为可以关页面了。 - 新增权限码 sign:task:confirm / sign:task:remind。 记录查询与报表 - 记录查询状态筛选与演示数据加该状态(2 条样本)。 - 报表 STATUS_LABELS / STATUS_COLUMNS / ReportStatusCounts / ReportGroupRow 加这一栏, 单独成列不并进「已签署」——并进去会让已签署虚高,科室复核本来就是这类文书的卡点。 - 时效样本按「有签署用时」取,待科室确认同样计入;总览统计块加一块。 演示数据 - 工作台补 task-009(confirming + needConfirm),否则该状态的徽标、动作、 筛选、报表栏在演示环境里一次都走不到。 - 注意:演示文库的麻精同意书**没有** needConfirm(原型里也确实没有), 所以「新建任务 → 签署 → 落待科室确认」这条流转靠探针夹具验证,没有改产品种子。 验证:probe-dept-confirm.cjs(新建)36/36 PASS,含真实落笔签署后落待科室确认; 回归 probe-new-task 104/104、probe-method-domain 14/14、probe-workbench-lib 42/42、 probe-report-analytics 92/92(断言按七状态更新);vue-tsc 与 eslint 0 错。
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import type {
|
||||
SigningAnswers,
|
||||
@@ -18,7 +18,7 @@ import LinkedPrescriptionCard from './LinkedPrescriptionCard.vue'
|
||||
import SigningArtifactList from './SigningArtifactList.vue'
|
||||
import type { SigningTaskAction } from '../types'
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
task: SigningTaskRecord | null
|
||||
loading: boolean
|
||||
auditEvents: SigningTaskEvent[]
|
||||
@@ -33,6 +33,10 @@ defineProps<{
|
||||
canDeliveryWrite: boolean
|
||||
canReopen: boolean
|
||||
canVoid: boolean
|
||||
/** 科室复核签章(sign:task:confirm):只有「待科室确认」的任务用得上 */
|
||||
canConfirm: boolean
|
||||
/** 催办(sign:task:remind) */
|
||||
canRemind: boolean
|
||||
canViewAudit: boolean
|
||||
canViewArtifacts: boolean
|
||||
canDownloadArtifact: boolean
|
||||
@@ -50,6 +54,22 @@ const emit = defineEmits<{
|
||||
|
||||
const documentRef = ref<InstanceType<typeof SigningDocumentInteractive> | null>(null)
|
||||
|
||||
/**
|
||||
* 科室确认节点的三种形态(原型文书签名区那一格的三分支):
|
||||
* 待患者签署后 / 待科室确认 / ✓ 已确认。
|
||||
*
|
||||
* 只看任务状态,不另存一份「科室签没签」的布尔量 —— 两个来源迟早会打架。
|
||||
*/
|
||||
const confirmNodeState = computed<'idle' | 'waiting' | 'done'>(() => {
|
||||
const status = props.task?.status
|
||||
|
||||
if (status === 'signed') {
|
||||
return 'done'
|
||||
}
|
||||
|
||||
return status === 'confirming' ? 'waiting' : 'idle'
|
||||
})
|
||||
|
||||
/**
|
||||
* 原型任务详情:主按钮 = 当前方式的签署入口,另外三种方式各给一个「转为 X」的次按钮。
|
||||
* 原型的四种方式都走这一套(`待签署` 下四个 if/else 分支,主按钮与其余三个各不相同),
|
||||
@@ -168,6 +188,43 @@ defineExpose({ getDocumentElement })
|
||||
<span v-else-if="task.method === 'wx'" class="action-hint">公众号推送接口待接入</span>
|
||||
</template>
|
||||
|
||||
<!-- 待科室确认:患者已签完,此刻要动的是科室那一道章(原型 confirmDept 的动作组)。
|
||||
预览与下载放在这里,是因为科室复核时要先看患者签了什么 -->
|
||||
<template v-else-if="task.status === 'confirming'">
|
||||
<button
|
||||
v-if="canConfirm"
|
||||
type="button"
|
||||
class="action-button"
|
||||
@click="emit('action', 'confirm-dept')"
|
||||
>
|
||||
🏛 科室复核签章(确认完成)
|
||||
</button>
|
||||
<button
|
||||
v-if="canRemind"
|
||||
type="button"
|
||||
class="action-button action-button--ghost"
|
||||
@click="emit('action', 'remind')"
|
||||
>
|
||||
催办
|
||||
</button>
|
||||
<button
|
||||
v-if="canViewArtifacts"
|
||||
type="button"
|
||||
class="action-button action-button--ghost"
|
||||
@click="emit('action', 'preview-signed')"
|
||||
>
|
||||
在线预览
|
||||
</button>
|
||||
<button
|
||||
v-if="canDownloadArtifact"
|
||||
type="button"
|
||||
class="action-button action-button--ghost"
|
||||
@click="emit('action', 'download-pdf')"
|
||||
>
|
||||
下载已签 PDF
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<template v-else-if="task.status === 'expired' && canReopen">
|
||||
<button type="button" class="action-button" @click="emit('action', 'reopen')">
|
||||
↻ 重新发起
|
||||
@@ -243,13 +300,44 @@ defineExpose({ getDocumentElement })
|
||||
v-if="task.documentContentHtml"
|
||||
ref="documentRef"
|
||||
:task="task"
|
||||
:interactive="allowLocalSigning && task.status !== 'signed' && task.status !== 'void'"
|
||||
:interactive="
|
||||
allowLocalSigning &&
|
||||
task.status !== 'signed' &&
|
||||
task.status !== 'void' &&
|
||||
task.status !== 'confirming'
|
||||
"
|
||||
:signature-injections="signatureInjections"
|
||||
@selection-change="emit('selectionChange', $event)"
|
||||
@field-change="(answers, progress) => emit('fieldChange', answers, progress)"
|
||||
@signature-request="emit('signatureRequest', $event)"
|
||||
/>
|
||||
<SigningDocumentPreview v-else :task="task" />
|
||||
<!-- 科室确认节点(原型:文书签名区里的「科室确认(签章)」那一格)。
|
||||
它跟着文书走,不跟产物走 —— 科室复核的是患者签了什么,不是下载了什么 -->
|
||||
<section
|
||||
v-if="task.needConfirm"
|
||||
class="dept-confirm"
|
||||
:class="`is-${confirmNodeState}`"
|
||||
aria-label="科室确认节点"
|
||||
>
|
||||
<span class="dept-confirm__label">科室确认(签章)</span>
|
||||
<span v-if="confirmNodeState === 'done'" class="dept-confirm__tag is-done">
|
||||
✓ {{ task.department }}已确认
|
||||
</span>
|
||||
<span v-else-if="confirmNodeState === 'waiting'" class="dept-confirm__tag is-waiting">
|
||||
待科室确认
|
||||
</span>
|
||||
<span v-else class="dept-confirm__hint">待患者签署后</span>
|
||||
<span class="dept-confirm__note">
|
||||
{{
|
||||
confirmNodeState === 'done'
|
||||
? '科室复核签章完成,文档已归档至本次诊疗记录'
|
||||
: confirmNodeState === 'waiting'
|
||||
? '患者已签署,等待科室复核签章后归档'
|
||||
: '本文书需科室复核签章,患者签署后自动流转'
|
||||
}}
|
||||
</span>
|
||||
</section>
|
||||
<!-- 顺序照原型:文书 → 签署文件(归档结果)→ 关联处方 → 操作留痕 -->
|
||||
<SigningArtifactList
|
||||
v-if="canViewArtifacts"
|
||||
@@ -365,6 +453,68 @@ defineExpose({ getDocumentElement })
|
||||
background: var(--err-l);
|
||||
}
|
||||
|
||||
/* 科室确认节点:原型文书签名区里「科室确认(签章)」那一格的独立呈现。
|
||||
三种形态用左边框颜色区分:待患者签署(灰)/ 待科室确认(橙)/ 已确认(绿) */
|
||||
.dept-confirm {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
padding: 10px 14px;
|
||||
margin-top: 14px;
|
||||
background: var(--card);
|
||||
border: 1px solid var(--line);
|
||||
border-left: 3px solid #c0c8cd;
|
||||
border-radius: var(--r);
|
||||
box-shadow: var(--sh);
|
||||
}
|
||||
|
||||
.dept-confirm.is-waiting {
|
||||
border-left-color: #c07f00;
|
||||
}
|
||||
|
||||
.dept-confirm.is-done {
|
||||
border-left-color: var(--ok);
|
||||
}
|
||||
|
||||
.dept-confirm__label {
|
||||
color: var(--ink);
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.dept-confirm__tag {
|
||||
padding: 2px 9px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* 原型 .tag.tg-cfm */
|
||||
.dept-confirm__tag.is-waiting {
|
||||
color: #c07f00;
|
||||
background: #fff3e0;
|
||||
}
|
||||
|
||||
/* 原型 .tag.tg-done */
|
||||
.dept-confirm__tag.is-done {
|
||||
color: var(--ok);
|
||||
background: var(--ok-l);
|
||||
}
|
||||
|
||||
.dept-confirm__hint {
|
||||
color: var(--mut);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.dept-confirm__note {
|
||||
flex: 1;
|
||||
min-width: 180px;
|
||||
color: var(--mut);
|
||||
font-size: 11.5px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.detail-empty {
|
||||
display: grid;
|
||||
flex: 1;
|
||||
|
||||
Reference in New Issue
Block a user