|
@@ -128,6 +128,11 @@
|
|
|
<el-radio label="rollback">回退</el-radio>
|
|
<el-radio label="rollback">回退</el-radio>
|
|
|
</el-radio-group>
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
+ <el-form-item v-if="form.action === 'pass' && nextNodes.length > 0" label="选择分支">
|
|
|
|
|
+ <el-select v-model="form.targetNodeId" placeholder="请选择下一节点" style="width: 100%">
|
|
|
|
|
+ <el-option v-for="n in nextNodes" :key="n.nodeId" :label="n.nodeName" :value="n.nodeId" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
<el-form-item v-if="form.action === 'rollback'" label="回退说明">
|
|
<el-form-item v-if="form.action === 'rollback'" label="回退说明">
|
|
|
<el-alert type="warning" :closable="false" show-icon>
|
|
<el-alert type="warning" :closable="false" show-icon>
|
|
|
<template #title>
|
|
<template #title>
|
|
@@ -224,7 +229,8 @@
|
|
|
import { ref, reactive, computed, watch } from 'vue'
|
|
import { ref, reactive, computed, watch } from 'vue'
|
|
|
import { ElMessage } from 'element-plus'
|
|
import { ElMessage } from 'element-plus'
|
|
|
import { getProgress, getInstanceAttachments, updateInstanceFormData } from '@/api/flow/instance'
|
|
import { getProgress, getInstanceAttachments, updateInstanceFormData } from '@/api/flow/instance'
|
|
|
-import { approveTask, rejectTask, returnTask, addSignTask, getTransferableUsers } from '@/api/flow/task'
|
|
|
|
|
|
|
+import { approveTask, rejectTask, returnTask, addSignTask, getTransferableUsers, listNextNodes } from '@/api/flow/task'
|
|
|
|
|
+import type { NextNode } from '@/types/flow'
|
|
|
import { beforeFileUpload, getFileUrl, getFileName, parseAttachments, collectAttachmentUrls } from '@/utils/file'
|
|
import { beforeFileUpload, getFileUrl, getFileName, parseAttachments, collectAttachmentUrls } from '@/utils/file'
|
|
|
import { useFileUpload } from '@/composables/useFileUpload'
|
|
import { useFileUpload } from '@/composables/useFileUpload'
|
|
|
import { instanceStatusText, instanceStatusTagType, taskStatusText, taskStatusType, recordActionText, recordActionType } from '@/utils/flow'
|
|
import { instanceStatusText, instanceStatusTagType, taskStatusText, taskStatusType, recordActionText, recordActionType } from '@/utils/flow'
|
|
@@ -258,9 +264,11 @@ type ApprovalActionType = 'pass' | 'reject' | 'rollback'
|
|
|
const form = reactive<{
|
|
const form = reactive<{
|
|
|
action: ApprovalActionType
|
|
action: ApprovalActionType
|
|
|
comment: string
|
|
comment: string
|
|
|
|
|
+ targetNodeId?: string
|
|
|
}>({
|
|
}>({
|
|
|
action: 'pass',
|
|
action: 'pass',
|
|
|
- comment: ''
|
|
|
|
|
|
|
+ comment: '',
|
|
|
|
|
+ targetNodeId: undefined
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
const fileUpload = reactive(useFileUpload())
|
|
const fileUpload = reactive(useFileUpload())
|
|
@@ -313,6 +321,13 @@ function isImage(url: string): boolean {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 查找当前登录用户需要处理的待办任务
|
|
// 查找当前登录用户需要处理的待办任务
|
|
|
|
|
+// 分支选择
|
|
|
|
|
+const nextNodes = ref<NextNode[]>([])
|
|
|
|
|
+
|
|
|
|
|
+async function loadNextNodes(taskId: number) {
|
|
|
|
|
+ try { nextNodes.value = await listNextNodes(taskId) } catch { nextNodes.value = [] }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const myPendingTask = computed<FlowTask | null>(() => {
|
|
const myPendingTask = computed<FlowTask | null>(() => {
|
|
|
if (!progress.value) return null
|
|
if (!progress.value) return null
|
|
|
for (const node of progress.value.nodes) {
|
|
for (const node of progress.value.nodes) {
|
|
@@ -359,6 +374,10 @@ async function loadProgress() {
|
|
|
async function submitApprove() {
|
|
async function submitApprove() {
|
|
|
const task = myPendingTask.value
|
|
const task = myPendingTask.value
|
|
|
if (!task) return
|
|
if (!task) return
|
|
|
|
|
+ if (form.action === 'pass' && nextNodes.value.length > 0 && !form.targetNodeId) {
|
|
|
|
|
+ ElMessage.warning('存在多个下游分支,请选择一个目标节点')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
submitting.value = true
|
|
submitting.value = true
|
|
|
try {
|
|
try {
|
|
|
const data: ApprovalAction = {
|
|
const data: ApprovalAction = {
|
|
@@ -368,6 +387,9 @@ async function submitApprove() {
|
|
|
if (fileUpload.attachmentList.length > 0) {
|
|
if (fileUpload.attachmentList.length > 0) {
|
|
|
data.attachmentUrls = collectAttachmentUrls(fileUpload.attachmentList)
|
|
data.attachmentUrls = collectAttachmentUrls(fileUpload.attachmentList)
|
|
|
}
|
|
}
|
|
|
|
|
+ if (form.action === 'pass' && form.targetNodeId) {
|
|
|
|
|
+ data.targetNodeId = form.targetNodeId
|
|
|
|
|
+ }
|
|
|
switch (form.action) {
|
|
switch (form.action) {
|
|
|
case 'pass':
|
|
case 'pass':
|
|
|
await approveTask(task.id, data)
|
|
await approveTask(task.id, data)
|
|
@@ -483,9 +505,21 @@ watch(() => props.instanceId, (id) => {
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+// 切换到"通过"时加载下游节点列表
|
|
|
|
|
+watch(() => form.action, (action) => {
|
|
|
|
|
+ nextNodes.value = []
|
|
|
|
|
+ form.targetNodeId = undefined
|
|
|
|
|
+ if (action === 'pass' && myPendingTask.value) {
|
|
|
|
|
+ loadNextNodes(myPendingTask.value.id)
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
watch(() => props.modelValue, async (val) => {
|
|
watch(() => props.modelValue, async (val) => {
|
|
|
if (val && props.instanceId) {
|
|
if (val && props.instanceId) {
|
|
|
await loadProgress()
|
|
await loadProgress()
|
|
|
|
|
+ if (form.action === 'pass' && myPendingTask.value) {
|
|
|
|
|
+ loadNextNodes(myPendingTask.value.id)
|
|
|
|
|
+ }
|
|
|
await loadTransferableUsers()
|
|
await loadTransferableUsers()
|
|
|
loadAttachments()
|
|
loadAttachments()
|
|
|
}
|
|
}
|