diff --git a/src/api/bpm/processInstance/index.ts b/src/api/bpm/processInstance/index.ts index 1e8f04dac..7d024b1d3 100644 --- a/src/api/bpm/processInstance/index.ts +++ b/src/api/bpm/processInstance/index.ts @@ -36,6 +36,7 @@ export type ApprovalTaskInfo = { assigneeUser: User status: number reason: string + attachments?: string[] signPicUrl: string } diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue b/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue index abfc479bf..7f6134c15 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue @@ -44,6 +44,16 @@ :rows="4" /> + + + + + + () // 运行中的任务 @@ -580,6 +618,7 @@ let pendingNextNodesTask: Promise | null = null // 跟踪 onChange 触 const approveReasonForm = reactive({ reason: '', signPicUrl: '', + attachments: [] as string[], nextAssignees: {} }) const approveReasonRule = computed(() => { @@ -599,7 +638,8 @@ const approveReasonRule = computed(() => { // 拒绝表单 const rejectFormRef = ref() const rejectReasonForm = reactive({ - reason: '' + reason: '', + attachments: [] as string[] }) const rejectReasonRule = computed(() => { return { @@ -736,6 +776,12 @@ const closePopover = (type: string, formRef: FormInstance | undefined) => { if (formRef) { formRef.resetFields() } + if (type === 'approve') { + approveReasonForm.attachments = [] + } + if (type === 'reject') { + rejectReasonForm.attachments = [] + } popOverVisible.value[type] = false nextAssigneesActivityNode.value = [] // 清理 Timeline 组件中的自定义审批人数据 @@ -837,6 +883,7 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) => const data = { id: runningTask.value.id, reason: approveReasonForm.reason, + attachments: approveReasonForm.attachments, variables, // 审批通过, 把修改的字段值赋于流程实例变量 nextAssignees: approveReasonForm.nextAssignees // 下个自选节点选择的审批人信息 } as any @@ -861,7 +908,8 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) => // 审批不通过数据 const data = { id: runningTask.value.id, - reason: rejectReasonForm.reason + reason: rejectReasonForm.reason, + attachments: rejectReasonForm.attachments } await TaskApi.rejectTask(data) popOverVisible.value.reject = false @@ -869,6 +917,8 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) => } // 重置表单 formRef.resetFields() + approveReasonForm.attachments = [] + rejectReasonForm.attachments = [] // 加载最新数据 reload() } finally { diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue index 91f333e8e..a2d6bd2e5 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue @@ -129,14 +129,33 @@
- 审批意见:{{ task.reason }} +
审批意见:{{ task.reason }}
+
+ +
{ } } +/** 是否展示审批意见和附件 */ +const shouldShowReasonAndAttachment = ( + task: ProcessInstanceApi.ApprovalTaskInfo, + nodeType: NodeType +) => { + return ( + Boolean(task.reason || task.attachments?.length) && + [NodeType.START_USER_NODE, NodeType.USER_TASK_NODE, NodeType.END_EVENT_NODE].includes(nodeType) + ) +} + +/** 获取附件名 */ +const getAttachmentName = (url: string) => { + const cleanUrl = url.split(/[?#]/)[0] + const fileName = cleanUrl.slice(cleanUrl.lastIndexOf('/') + 1) + try { + return decodeURIComponent(fileName) + } catch { + return fileName + } +} + +/** 是否图片附件 */ +const isImageAttachment = (url: string) => { + const ext = url.split(/[?#]/)[0]?.split('.').pop()?.toLowerCase() + return ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'webp'].includes(ext || '') +} + // 选择自定义审批人 const userSelectFormRef = ref() const handleSelectUser = (activityId, selectedList) => {