mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-11-04 12:18:43 +08:00 
			
		
		
		
	feat: 支持回退按钮
This commit is contained in:
		@@ -41,3 +41,19 @@ export const getTaskListByProcessInstanceId = async (processInstanceId) => {
 | 
			
		||||
export const exportTask = async (params) => {
 | 
			
		||||
  return await request.download({ url: '/bpm/task/export', params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 获取所有可回退的节点
 | 
			
		||||
 * @param params
 | 
			
		||||
 */
 | 
			
		||||
export const getReturnList = async (params) => {
 | 
			
		||||
  return await request.get({ url: '/bpm/task/get-return-list', params })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 确认回退
 | 
			
		||||
 * @param params
 | 
			
		||||
 */
 | 
			
		||||
export const okRollback = async (data) => {
 | 
			
		||||
  return await request.put({ url: '/bpm/task/rollback', data })
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -229,6 +229,9 @@ const getResultCss = (result) => {
 | 
			
		||||
  } else if (result === 4) {
 | 
			
		||||
    // 已取消
 | 
			
		||||
    return 'highlight-cancel'
 | 
			
		||||
  } else if (result === 5) {
 | 
			
		||||
    // 退回
 | 
			
		||||
    return 'highlight-rollback'
 | 
			
		||||
  }
 | 
			
		||||
  return ''
 | 
			
		||||
}
 | 
			
		||||
@@ -564,6 +567,45 @@ watch(
 | 
			
		||||
  stroke: grey !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 回退 */
 | 
			
		||||
.highlight-rollback.djs-shape .djs-visual > :nth-child(1) {
 | 
			
		||||
  fill: #e6a23c !important;
 | 
			
		||||
  stroke: #e6a23c !important;
 | 
			
		||||
  fill-opacity: 0.2 !important;
 | 
			
		||||
}
 | 
			
		||||
.highlight-rollback.djs-shape .djs-visual > :nth-child(2) {
 | 
			
		||||
  fill: #e6a23c !important;
 | 
			
		||||
}
 | 
			
		||||
.highlight-rollback.djs-shape .djs-visual > path {
 | 
			
		||||
  fill: #e6a23c !important;
 | 
			
		||||
  fill-opacity: 0.2 !important;
 | 
			
		||||
  stroke: #e6a23c !important;
 | 
			
		||||
}
 | 
			
		||||
.highlight-rollback.djs-connection > .djs-visual > path {
 | 
			
		||||
  stroke: #e6a23c !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.highlight-rollback:not(.djs-connection) .djs-visual > :nth-child(1) {
 | 
			
		||||
  fill: #e6a23c !important; /* color elements as green */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
:deep(.highlight-rollback.djs-shape .djs-visual > :nth-child(1)) {
 | 
			
		||||
  fill: #e6a23c !important;
 | 
			
		||||
  stroke: #e6a23c !important;
 | 
			
		||||
  fill-opacity: 0.2 !important;
 | 
			
		||||
}
 | 
			
		||||
:deep(.highlight-rollback.djs-shape .djs-visual > :nth-child(2)) {
 | 
			
		||||
  fill: #e6a23c !important;
 | 
			
		||||
}
 | 
			
		||||
:deep(.highlight-rollback.djs-shape .djs-visual > path) {
 | 
			
		||||
  fill: #e6a23c !important;
 | 
			
		||||
  fill-opacity: 0.2 !important;
 | 
			
		||||
  stroke: #e6a23c !important;
 | 
			
		||||
}
 | 
			
		||||
:deep(.highlight-rollback.djs-connection > .djs-visual > path) {
 | 
			
		||||
  stroke: #e6a23c !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.element-overlays {
 | 
			
		||||
  width: 200px;
 | 
			
		||||
  padding: 8px;
 | 
			
		||||
 
 | 
			
		||||
@@ -69,6 +69,9 @@ const getTimelineItemIcon = (item) => {
 | 
			
		||||
  if (item.result === 4) {
 | 
			
		||||
    return 'el-icon-remove-outline'
 | 
			
		||||
  }
 | 
			
		||||
  if (item.result === 5) {
 | 
			
		||||
    return 'el-icon-back'
 | 
			
		||||
  }
 | 
			
		||||
  return ''
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -86,6 +89,9 @@ const getTimelineItemType = (item) => {
 | 
			
		||||
  if (item.result === 4) {
 | 
			
		||||
    return 'info'
 | 
			
		||||
  }
 | 
			
		||||
  if (item.result === 5) {
 | 
			
		||||
    return 'warning'
 | 
			
		||||
  }
 | 
			
		||||
  return ''
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,90 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog v-model="dialogVisible" title="回退" width="500">
 | 
			
		||||
    <el-form
 | 
			
		||||
      ref="formRef"
 | 
			
		||||
      v-loading="formLoading"
 | 
			
		||||
      :model="formData"
 | 
			
		||||
      :rules="formRules"
 | 
			
		||||
      label-width="110px"
 | 
			
		||||
    >
 | 
			
		||||
      <el-form-item label="退回节点" prop="targetDefinitionKey">
 | 
			
		||||
        <el-select v-model="formData.targetDefinitionKey" clearable style="width: 100%">
 | 
			
		||||
          <el-option
 | 
			
		||||
            v-for="item in returnList"
 | 
			
		||||
            :key="item.taskDefinitionKey"
 | 
			
		||||
            :label="item.name"
 | 
			
		||||
            :value="item.taskDefinitionKey"
 | 
			
		||||
          />
 | 
			
		||||
        </el-select>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item label="回退理由" prop="reason">
 | 
			
		||||
        <el-input v-model="formData.reason" clearable placeholder="请输入回退理由" />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
    </el-form>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
 | 
			
		||||
      <el-button @click="dialogVisible = false">取 消</el-button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts" name="TaskRollbackDialogForm" setup>
 | 
			
		||||
import * as TaskApi from '@/api/bpm/task'
 | 
			
		||||
 | 
			
		||||
const message = useMessage() // 消息弹窗
 | 
			
		||||
const dialogVisible = ref(false) // 弹窗的是否展示
 | 
			
		||||
const formLoading = ref(false) // 表单的加载中
 | 
			
		||||
const formData = ref({
 | 
			
		||||
  id: '',
 | 
			
		||||
  targetDefinitionKey: undefined,
 | 
			
		||||
  reason: ''
 | 
			
		||||
})
 | 
			
		||||
const formRules = ref({
 | 
			
		||||
  targetDefinitionKey: [{ required: true, message: '必须选择回退节点', trigger: 'change' }],
 | 
			
		||||
  reason: [{ required: true, message: '回退理由不能为空', trigger: 'blur' }]
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const formRef = ref() // 表单 Ref
 | 
			
		||||
const returnList = ref([])
 | 
			
		||||
/** 打开弹窗 */
 | 
			
		||||
const open = async (id: string) => {
 | 
			
		||||
  returnList.value = await TaskApi.getReturnList({ taskId: id })
 | 
			
		||||
  if (returnList.value.length === 0) {
 | 
			
		||||
    message.warning('当前没有可回退的节点')
 | 
			
		||||
    return false
 | 
			
		||||
  }
 | 
			
		||||
  dialogVisible.value = true
 | 
			
		||||
  resetForm()
 | 
			
		||||
  formData.value.id = id
 | 
			
		||||
}
 | 
			
		||||
defineExpose({ open }) // 提供 openModal 方法,用于打开弹窗
 | 
			
		||||
 | 
			
		||||
/** 提交表单 */
 | 
			
		||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 | 
			
		||||
const submitForm = async () => {
 | 
			
		||||
  // 校验表单
 | 
			
		||||
  if (!formRef) return
 | 
			
		||||
  const valid = await formRef.value.validate()
 | 
			
		||||
  if (!valid) return
 | 
			
		||||
  // 提交请求
 | 
			
		||||
  formLoading.value = true
 | 
			
		||||
  try {
 | 
			
		||||
    await TaskApi.okRollback(formData.value)
 | 
			
		||||
    message.success('回退成功')
 | 
			
		||||
    dialogVisible.value = false
 | 
			
		||||
    // 发送操作成功的事件
 | 
			
		||||
    emit('success')
 | 
			
		||||
  } finally {
 | 
			
		||||
    formLoading.value = false
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 重置表单 */
 | 
			
		||||
const resetForm = () => {
 | 
			
		||||
  formData.value = {
 | 
			
		||||
    id: '',
 | 
			
		||||
    targetDefinitionKey: undefined,
 | 
			
		||||
    reason: ''
 | 
			
		||||
  }
 | 
			
		||||
  formRef.value?.resetFields()
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
@@ -91,6 +91,8 @@
 | 
			
		||||
 | 
			
		||||
    <!-- 弹窗:转派审批人 -->
 | 
			
		||||
    <TaskUpdateAssigneeForm ref="taskUpdateAssigneeFormRef" @success="getDetail" />
 | 
			
		||||
    <!-- 弹窗,回退节点 -->
 | 
			
		||||
    <TaskRollbackDialog ref="taskRollbackRef" @success="getDetail" />
 | 
			
		||||
  </ContentWrap>
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
@@ -103,6 +105,7 @@ import * as TaskApi from '@/api/bpm/task'
 | 
			
		||||
import TaskUpdateAssigneeForm from './TaskUpdateAssigneeForm.vue'
 | 
			
		||||
import ProcessInstanceBpmnViewer from './ProcessInstanceBpmnViewer.vue'
 | 
			
		||||
import ProcessInstanceTaskList from './ProcessInstanceTaskList.vue'
 | 
			
		||||
import TaskRollbackDialog from './TaskRollbackDialogForm.vue'
 | 
			
		||||
import { registerComponent } from '@/utils/routerHelper'
 | 
			
		||||
 | 
			
		||||
defineOptions({ name: 'BpmProcessInstanceDetail' })
 | 
			
		||||
@@ -172,10 +175,11 @@ const handleDelegate = async (task) => {
 | 
			
		||||
  console.log(task)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//回退弹框组件
 | 
			
		||||
const taskRollbackRef = ref()
 | 
			
		||||
/** 处理审批退回的操作 */
 | 
			
		||||
const handleBack = async (task) => {
 | 
			
		||||
  message.error('暂不支持【退回】功能!')
 | 
			
		||||
  console.log(task)
 | 
			
		||||
  taskRollbackRef.value.open(task.id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 获得详情 */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user