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:
@@ -12,6 +12,7 @@ import {
|
||||
import { createPadSigningSession } from '@/api/workbench/deliveries'
|
||||
import {
|
||||
completeSigningTask,
|
||||
confirmDepartmentSigning,
|
||||
getSigningTaskDetail,
|
||||
getSigningTaskEvents,
|
||||
getSigningTasks,
|
||||
@@ -63,6 +64,7 @@ const loginStore = useLoginStore()
|
||||
const STATUS_VALUES: SigningTaskStatus[] = [
|
||||
'pending',
|
||||
'signing',
|
||||
'confirming',
|
||||
'signed',
|
||||
'expired',
|
||||
'void',
|
||||
@@ -73,6 +75,7 @@ const DATE_RANGE_VALUES: SigningDateRange[] = ['today', 'yesterday', '3d', '7d',
|
||||
const statusLabels: Record<SigningTaskStatus, string> = {
|
||||
pending: '待签署',
|
||||
signing: '签署中',
|
||||
confirming: '待科室确认',
|
||||
signed: '已签署',
|
||||
expired: '已超时',
|
||||
void: '已作废',
|
||||
@@ -151,6 +154,10 @@ const canCreateTask = computed(() => canWrite('sign:task:create'))
|
||||
const canDeliveryWrite = computed(() => canWrite('sign:delivery:write'))
|
||||
const canReopenTask = computed(() => canWrite('sign:task:reopen'))
|
||||
const canVoidTask = computed(() => canWrite('sign:task:void'))
|
||||
/** 科室复核签章:把「待科室确认」推到「已签署」,是正式留痕动作,与作废同级 */
|
||||
const canConfirmTask = computed(() => canWrite('sign:task:confirm'))
|
||||
/** 催办:提醒科室签署员尽快复核 */
|
||||
const canRemindTask = computed(() => canWrite('sign:task:remind'))
|
||||
const canViewEvents = computed(() => canRead('sign:task:event:query'))
|
||||
const canViewArtifacts = computed(() => canRead('sign:artifact:query'))
|
||||
const canDownloadArtifacts = computed(() => canRead('sign:artifact:download'))
|
||||
@@ -536,6 +543,8 @@ async function handleTaskAction(action: SigningTaskAction, targetMethod?: Signin
|
||||
(action === 'resend-sms' && canDeliveryWrite.value) ||
|
||||
(action === 'reopen' && canReopenTask.value) ||
|
||||
(action === 'void' && canVoidTask.value) ||
|
||||
(action === 'confirm-dept' && canConfirmTask.value) ||
|
||||
(action === 'remind' && canRemindTask.value) ||
|
||||
(action === 'preview-signed' && canViewArtifacts.value) ||
|
||||
((action === 'download-pdf' ||
|
||||
action === 'download-signature' ||
|
||||
@@ -599,6 +608,52 @@ async function handleTaskAction(action: SigningTaskAction, targetMethod?: Signin
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* 催办:提醒科室签署员尽快复核。
|
||||
*
|
||||
* 真实模式后端没有催办接口(要重做),按项目既有口径如实提示"待接入",
|
||||
* 不前端假装发了一条提醒 —— 催办是要留痕的对外动作。
|
||||
*/
|
||||
if (action === 'remind') {
|
||||
if (!isSigningMockEnabled) {
|
||||
ElMessage.info('催办提醒接口待接入')
|
||||
return
|
||||
}
|
||||
|
||||
ElMessage.success(`已向${task.department}签署员发送催办提醒`)
|
||||
return
|
||||
}
|
||||
|
||||
if (action === 'confirm-dept') {
|
||||
if (!isSigningMockEnabled) {
|
||||
ElMessage.info('科室复核签章接口待接入')
|
||||
return
|
||||
}
|
||||
|
||||
const confirmed = await ElMessageBox.confirm(
|
||||
`确认「${task.department}」已完成复核签章?确认后任务转为「已签署」,文档归档至本次诊疗记录。`,
|
||||
'科室复核签章',
|
||||
{ type: 'warning', confirmButtonText: '确认签章', cancelButtonText: '取消' },
|
||||
)
|
||||
.then(() => true)
|
||||
.catch(() => false)
|
||||
|
||||
if (!confirmed) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await refreshTask(
|
||||
await confirmDepartmentSigning(task.id),
|
||||
'科室复核签章完成,文档已归档至本次诊疗记录',
|
||||
)
|
||||
} catch {
|
||||
ElMessage.error('科室复核签章失败,请稍后重试')
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (action === 'reopen' && task.status !== 'expired' && task.status !== 'failed') {
|
||||
ElMessage.info('只有已超时或处理失败的任务可以重新发起')
|
||||
return
|
||||
@@ -779,15 +834,13 @@ async function confirmPadSignature(signatureDataUrl: string) {
|
||||
}
|
||||
|
||||
try {
|
||||
await refreshTask(
|
||||
await completeSigningTask(
|
||||
task.id,
|
||||
signatureDataUrl,
|
||||
signingSelection.value,
|
||||
signingAnswers.value,
|
||||
),
|
||||
'手写签署已完成',
|
||||
const updated = await completeSigningTask(
|
||||
task.id,
|
||||
signatureDataUrl,
|
||||
signingSelection.value,
|
||||
signingAnswers.value,
|
||||
)
|
||||
await refreshTask(updated, signingCompletedMessage(updated))
|
||||
signatureDialogVisible.value = false
|
||||
} catch {
|
||||
ElMessage.error('手写签署失败,请稍后重试')
|
||||
@@ -802,21 +855,32 @@ async function completeOnlineSignature(signatureDataUrl: string) {
|
||||
}
|
||||
|
||||
try {
|
||||
await refreshTask(
|
||||
await completeSigningTask(
|
||||
task.id,
|
||||
signatureDataUrl,
|
||||
signingSelection.value,
|
||||
signingAnswers.value,
|
||||
),
|
||||
'线上签署已完成',
|
||||
const updated = await completeSigningTask(
|
||||
task.id,
|
||||
signatureDataUrl,
|
||||
signingSelection.value,
|
||||
signingAnswers.value,
|
||||
)
|
||||
await refreshTask(updated, signingCompletedMessage(updated))
|
||||
onlineDialogVisible.value = false
|
||||
} catch {
|
||||
ElMessage.error('线上签署失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 签署完成后的提示语。
|
||||
*
|
||||
* 需科室确认的任务签完**并没有结束**(原型同样区分这两种说法):
|
||||
* 如果这里一律说「签署已完成」,操作人会以为可以关页面了,
|
||||
* 而实际上文档还停在科室确认队列里没归档。
|
||||
*/
|
||||
function signingCompletedMessage(updated: SigningTaskRecord | null) {
|
||||
return updated?.status === 'confirming'
|
||||
? '患者已签署,已流转至科室确认节点,等待科室复核签章'
|
||||
: '签署完成,文档已归档'
|
||||
}
|
||||
|
||||
async function confirmVoidTask(reason: string) {
|
||||
const task = selectedTask.value
|
||||
|
||||
@@ -933,6 +997,8 @@ onMounted(() => {
|
||||
:can-delivery-write="canDeliveryWrite"
|
||||
:can-reopen="canReopenTask"
|
||||
:can-void="canVoidTask"
|
||||
:can-confirm="canConfirmTask"
|
||||
:can-remind="canRemindTask"
|
||||
:can-view-audit="canViewEvents"
|
||||
:can-view-artifacts="canViewArtifacts"
|
||||
:can-download-artifact="canDownloadArtifacts"
|
||||
|
||||
Reference in New Issue
Block a user