瀏覽代碼

BPM:优化 task 加减签的实现

YunaiV 1 年之前
父節點
當前提交
2d424fc9a6

+ 1 - 1
src/api/bpm/processInstance/index.ts

@@ -47,7 +47,7 @@ export const cancelProcessInstance = async (id: number, reason: string) => {
   return await request.delete({ url: '/bpm/process-instance/cancel', data: data })
 }
 
-export const getProcessInstance = async (id: number) => {
+export const getProcessInstance = async (id: string) => {
   return await request.get({ url: '/bpm/process-instance/get?id=' + id })
 }
 

+ 13 - 19
src/api/bpm/task/index.ts

@@ -4,23 +4,23 @@ export type TaskVO = {
   id: number
 }
 
-export const getTodoTaskPage = async (params) => {
+export const getTodoTaskPage = async (params: any) => {
   return await request.get({ url: '/bpm/task/todo-page', params })
 }
 
-export const getDoneTaskPage = async (params) => {
+export const getDoneTaskPage = async (params: any) => {
   return await request.get({ url: '/bpm/task/done-page', params })
 }
 
-export const approveTask = async (data) => {
+export const approveTask = async (data: any) => {
   return await request.put({ url: '/bpm/task/approve', data })
 }
 
-export const rejectTask = async (data) => {
+export const rejectTask = async (data: any) => {
   return await request.put({ url: '/bpm/task/reject', data })
 }
 
-export const getTaskListByProcessInstanceId = async (processInstanceId) => {
+export const getTaskListByProcessInstanceId = async (processInstanceId: string) => {
   return await request.get({
     url: '/bpm/task/list-by-process-instance-id?processInstanceId=' + processInstanceId
   })
@@ -46,23 +46,17 @@ export const transferTask = async (data: any) => {
   return await request.put({ url: '/bpm/task/transfer', data })
 }
 
-/**
- * 加签
- */
-export const taskAddSign = async (data) => {
+// 加签
+export const signCreateTask = async (data: any) => {
   return await request.put({ url: '/bpm/task/create-sign', data })
 }
 
-/**
- * 获取减签任务列表
- */
-export const getChildrenTaskList = async (id: string) => {
-  return await request.get({ url: '/bpm/task/children-list?parentId=' + id })
+// 减签
+export const signDeleteTask = async (data: any) => {
+  return await request.delete({ url: '/bpm/task/delete-sign', data })
 }
 
-/**
- * 减签
- */
-export const taskSubSign = async (data) => {
-  return await request.delete({ url: '/bpm/task/delete-sign', data })
+// 获取减签任务列表
+export const getChildrenTaskList = async (id: string) => {
+  return await request.get({ url: '/bpm/task/list-by-parent-task-id?parentTaskId=' + id })
 }

+ 14 - 9
src/views/bpm/processInstance/detail/ProcessInstanceTaskList.vue

@@ -50,8 +50,9 @@
         </el-timeline>
       </div>
     </el-col>
-    <!-- 子任务  -->
-    <ProcessInstanceChildrenTaskList ref="processInstanceChildrenTaskList" />
+
+    <!-- 弹窗:子任务  -->
+    <TaskSignList ref="taskSignListRef" @success="refresh" />
   </el-card>
 </template>
 <script lang="ts" setup>
@@ -59,7 +60,7 @@ import { formatDate, formatPast2 } from '@/utils/formatTime'
 import { propTypes } from '@/utils/propTypes'
 import { DICT_TYPE } from '@/utils/dict'
 import { isEmpty } from '@/utils/is'
-import ProcessInstanceChildrenTaskList from './ProcessInstanceChildrenTaskList.vue'
+import TaskSignList from './dialog/TaskSignList.vue'
 
 defineOptions({ name: 'BpmProcessInstanceTaskList' })
 
@@ -69,6 +70,7 @@ defineProps({
 })
 
 /** 获得任务对应的 icon */
+// TODO @芋艿:对应的 icon 需要调整
 const getTimelineItemIcon = (item) => {
   if (item.status === 1) {
     return 'el-icon-time'
@@ -114,12 +116,15 @@ const getTimelineItemType = (item: any) => {
   return ''
 }
 
-/**
- * 子任务
- */
-const processInstanceChildrenTaskList = ref()
+/** 子任务 */
+const taskSignListRef = ref()
+const openChildrenTask = (item: any) => {
+  taskSignListRef.value.open(item)
+}
 
-const openChildrenTask = (item) => {
-  processInstanceChildrenTaskList.value.open(item)
+/** 刷新数据 */
+const emit = defineEmits(['refresh']) // 定义 success 事件,用于操作成功后的回调
+const refresh = () => {
+  emit('refresh')
 }
 </script>

+ 12 - 10
src/views/bpm/processInstance/detail/TaskAddSignDialogForm.vue → src/views/bpm/processInstance/detail/dialog/TaskSignCreateForm.vue

@@ -7,8 +7,8 @@
       :rules="formRules"
       label-width="110px"
     >
-      <el-form-item label="加签处理人" prop="userIdList">
-        <el-select v-model="formData.userIdList" multiple clearable style="width: 100%">
+      <el-form-item label="加签处理人" prop="userIds">
+        <el-select v-model="formData.userIds" multiple clearable style="width: 100%">
           <el-option
             v-for="item in userList"
             :key="item.id"
@@ -36,18 +36,19 @@
 import * as TaskApi from '@/api/bpm/task'
 import * as UserApi from '@/api/system/user'
 
-const message = useMessage() // 消息弹窗
-defineOptions({ name: 'BpmTaskUpdateAssigneeForm' })
+defineOptions({ name: 'TaskSignCreateForm' })
 
+const message = useMessage() // 消息弹窗
 const dialogVisible = ref(false) // 弹窗的是否展示
 const formLoading = ref(false) // 表单的加载中
 const formData = ref({
   id: '',
-  userIdList: [],
-  type: ''
+  userIds: [],
+  type: '',
+  reason: ''
 })
 const formRules = ref({
-  userIdList: [{ required: true, message: '加签处理人不能为空', trigger: 'change' }],
+  userIds: [{ required: true, message: '加签处理人不能为空', trigger: 'change' }],
   reason: [{ required: true, message: '加签理由不能为空', trigger: 'change' }]
 })
 
@@ -75,7 +76,7 @@ const submitForm = async (type: string) => {
   formLoading.value = true
   formData.value.type = type
   try {
-    await TaskApi.taskAddSign(formData.value)
+    await TaskApi.signCreateTask(formData.value)
     message.success('加签成功')
     dialogVisible.value = false
     // 发送操作成功的事件
@@ -89,8 +90,9 @@ const submitForm = async (type: string) => {
 const resetForm = () => {
   formData.value = {
     id: '',
-    userIdList: [],
-    type: ''
+    userIds: [],
+    type: '',
+    reason: ''
   }
   formRef.value?.resetFields()
 }

+ 11 - 7
src/views/bpm/processInstance/detail/TaskSubSignDialogForm.vue → src/views/bpm/processInstance/detail/dialog/TaskSignDeleteForm.vue

@@ -9,8 +9,10 @@
     >
       <el-form-item label="减签任务" prop="id">
         <el-radio-group v-model="formData.id">
-          <el-radio-button v-for="item in subTaskList" :key="item.id" :label="item.id">
-            {{ item.name }}({{ item.assigneeUser.deptName }}{{ item.assigneeUser.nickname }}--审批)
+          <el-radio-button v-for="item in childrenTaskList" :key="item.id" :label="item.id">
+            {{ item.name }}
+            ({{ item.assigneeUser?.deptName || item.ownerUser?.deptName }} -
+            {{ item.assigneeUser?.nickname || item.ownerUser?.nickname }})
           </el-radio-button>
         </el-radio-group>
       </el-form-item>
@@ -24,10 +26,12 @@
     </template>
   </Dialog>
 </template>
-<script lang="ts" name="TaskRollbackDialogForm" setup>
+<script lang="ts" setup>
 import * as TaskApi from '@/api/bpm/task'
 import { isEmpty } from '@/utils/is'
 
+defineOptions({ name: 'TaskSignDeleteForm' })
+
 const message = useMessage() // 消息弹窗
 const dialogVisible = ref(false) // 弹窗的是否展示
 const formLoading = ref(false) // 表单的加载中
@@ -41,11 +45,11 @@ const formRules = ref({
 })
 
 const formRef = ref() // 表单 Ref
-const subTaskList = ref([])
+const childrenTaskList = ref([])
 /** 打开弹窗 */
 const open = async (id: string) => {
-  subTaskList.value = await TaskApi.getChildrenTaskList(id)
-  if (isEmpty(subTaskList.value)) {
+  childrenTaskList.value = await TaskApi.getChildrenTaskList(id)
+  if (isEmpty(childrenTaskList.value)) {
     message.warning('当前没有可减签的任务')
     return false
   }
@@ -64,7 +68,7 @@ const submitForm = async () => {
   // 提交请求
   formLoading.value = true
   try {
-    await TaskApi.taskSubSign(formData.value)
+    await TaskApi.signDeleteTask(formData.value)
     message.success('减签成功')
     dialogVisible.value = false
     // 发送操作成功的事件

+ 37 - 27
src/views/bpm/processInstance/detail/ProcessInstanceChildrenTaskList.vue → src/views/bpm/processInstance/detail/dialog/TaskSignList.vue

@@ -1,23 +1,31 @@
 <template>
-  <el-drawer v-model="drawerVisible" title="子任务" size="70%">
+  <el-drawer v-model="drawerVisible" title="子任务" size="880px">
     <!-- 当前任务 -->
     <template #header>
-      <h4>【{{ baseTask.name }} 】审批人:{{ baseTask.assigneeUser?.nickname }}</h4>
+      <h4>【{{ parentTask.name }} 】审批人:{{ parentTask?.assigneeUser?.nickname }}</h4>
       <el-button
         style="margin-left: 5px"
-        v-if="isSubSignButtonVisible(baseTask)"
+        v-if="isSignDeleteButtonVisible(parentTask)"
         type="danger"
         plain
-        @click="handleSubSign(baseTask)"
+        @click="handleSignDelete(parentTask)"
       >
         <Icon icon="ep:remove" /> 减签
       </el-button>
     </template>
     <!-- 子任务列表 -->
-    <el-table :data="baseTask.children" style="width: 100%" row-key="id" border>
-      <el-table-column prop="assigneeUser.nickname" label="审批人" />
-      <el-table-column prop="assigneeUser.deptName" label="所在部门" />
-      <el-table-column label="审批状态" prop="status">
+    <el-table :data="parentTask.children" style="width: 100%" row-key="id" border>
+      <el-table-column prop="assigneeUser.nickname" label="审批人" min-width="100">
+        <template #default="scope">
+          {{ scope.row.assigneeUser?.nickname || scope.row.ownerUser?.nickname }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="assigneeUser.deptName" label="所在部门" min-width="100">
+        <template #default="scope">
+          {{ scope.row.assigneeUser?.deptName || scope.row.ownerUser?.deptName }}
+        </template>
+      </el-table-column>
+      <el-table-column label="审批状态" prop="status" width="120">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT" :value="scope.row.status" />
         </template>
@@ -36,61 +44,63 @@
         width="180"
         :formatter="dateFormatter"
       />
-      <el-table-column label="操作" prop="operation">
+      <el-table-column label="操作" prop="operation" width="90">
         <template #default="scope">
           <el-button
-            v-if="isSubSignButtonVisible(scope.row)"
+            v-if="isSignDeleteButtonVisible(scope.row)"
             type="danger"
             plain
-            @click="handleSubSign(scope.row)"
+            size="small"
+            @click="handleSignDelete(scope.row)"
           >
             <Icon icon="ep:remove" /> 减签
           </el-button>
         </template>
       </el-table-column>
     </el-table>
+
     <!-- 减签 -->
-    <TaskSubSignDialogForm ref="taskSubSignDialogForm" />
+    <TaskSignDeleteForm ref="taskSignDeleteFormRef" @success="handleSignDeleteSuccess" />
   </el-drawer>
 </template>
 <script lang="ts" setup>
 import { isEmpty } from '@/utils/is'
 import { DICT_TYPE } from '@/utils/dict'
 import { dateFormatter } from '@/utils/formatTime'
-import TaskSubSignDialogForm from './TaskSubSignDialogForm.vue'
+import TaskSignDeleteForm from './TaskSignDeleteForm.vue'
 
-defineOptions({ name: 'ProcessInstanceChildrenTaskList' })
+defineOptions({ name: 'TaskSignList' })
 
 const message = useMessage() // 消息弹窗
 const drawerVisible = ref(false) // 抽屉的是否展示
+const parentTask = ref({} as any)
 
-const baseTask = ref<object>({})
 /** 打开弹窗 */
 const open = async (task: any) => {
   if (isEmpty(task.children)) {
     message.warning('该任务没有子任务')
     return
   }
-  baseTask.value = task
+  parentTask.value = task
   // 展开抽屉
   drawerVisible.value = true
 }
 defineExpose({ open }) // 提供 openModal 方法,用于打开弹窗
 
 /** 发起减签 */
-const taskSubSignDialogForm = ref()
-const handleSubSign = (item) => {
-  taskSubSignDialogForm.value.open(item.id)
-  // TODO @海洋:减签后,需要刷新下界面哈
+const taskSignDeleteFormRef = ref()
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const handleSignDelete = (item: any) => {
+  taskSignDeleteFormRef.value.open(item.id)
+}
+const handleSignDeleteSuccess = () => {
+  emit('success')
+  // 关闭抽屉
+  drawerVisible.value = false
 }
 
 /** 是否显示减签按钮 */
-const isSubSignButtonVisible = (task: any) => {
-  if (task && task.children && !isEmpty(task.children)) {
-    // 有子任务,且子任务有任意一个是 待处理 和 待前置任务完成 则显示减签按钮
-    const subTask = task.children.find((item) => item.status === 1 || item.status === 9)
-    return !isEmpty(subTask)
-  }
-  return false
+const isSignDeleteButtonVisible = (task: any) => {
+  return task && task.children && !isEmpty(task.children)
 }
 </script>

+ 7 - 7
src/views/bpm/processInstance/detail/index.vue

@@ -92,7 +92,7 @@
     </el-card>
 
     <!-- 审批记录 -->
-    <ProcessInstanceTaskList :loading="tasksLoad" :tasks="tasks" />
+    <ProcessInstanceTaskList :loading="tasksLoad" :tasks="tasks" @refresh="getTaskList" />
 
     <!-- 高亮流程图 -->
     <ProcessInstanceBpmnViewer
@@ -110,7 +110,7 @@
     <!-- 弹窗:委派,将任务委派给别人处理,处理完成后,会重新回到原审批人手中-->
     <TaskDelegateForm ref="taskDelegateForm" @success="getDetail" />
     <!-- 弹窗:加签,当前任务审批人为A,向前加签选了一个C,则需要C先审批,然后再是A审批,向后加签B,A审批完,需要B再审批完,才算完成这个任务节点 -->
-    <TaskAddSignDialogForm ref="taskAddSignDialogForm" @success="getDetail" />
+    <TaskSignCreateForm ref="taskSignCreateFormRef" @success="getDetail" />
   </ContentWrap>
 </template>
 <script lang="ts" setup>
@@ -125,7 +125,7 @@ import ProcessInstanceTaskList from './ProcessInstanceTaskList.vue'
 import TaskReturnForm from './dialog/TaskReturnForm.vue'
 import TaskDelegateForm from './dialog/TaskDelegateForm.vue'
 import TaskTransferForm from './dialog/TaskTransferForm.vue'
-import TaskAddSignDialogForm from './TaskAddSignDialogForm.vue'
+import TaskSignCreateForm from './dialog/TaskSignCreateForm.vue'
 import { registerComponent } from '@/utils/routerHelper'
 import { isEmpty } from '@/utils/is'
 import * as UserApi from '@/api/system/user'
@@ -137,7 +137,7 @@ const message = useMessage() // 消息弹窗
 const { proxy } = getCurrentInstance() as any
 
 const userId = useUserStore().getUser.id // 当前登录的编号
-const id = query.id as unknown as number // 流程实例的编号
+const id = query.id as unknown as string // 流程实例的编号
 const processInstanceLoading = ref(false) // 流程实例的加载中
 const processInstance = ref<any>({}) // 流程实例
 const bpmnXML = ref('') // BPMN XML
@@ -205,9 +205,9 @@ const handleBack = async (task: any) => {
 }
 
 /** 处理审批加签的操作 */
-const taskAddSignDialogForm = ref()
-const handleSign = async (task) => {
-  taskAddSignDialogForm.value.open(task.id)
+const taskSignCreateFormRef = ref()
+const handleSign = async (task: any) => {
+  taskSignCreateFormRef.value.open(task.id)
 }
 
 /** 获得详情 */

+ 6 - 1
src/views/bpm/processInstance/index.vue

@@ -133,7 +133,7 @@
           <el-button
             link
             type="primary"
-            v-if="scope.row.result === 1"
+            v-if="scope.row.status === 1"
             v-hasPermi="['bpm:process-instance:query']"
             @click="handleCancel(scope.row)"
           >
@@ -234,6 +234,11 @@ const handleCancel = async (row) => {
   await getList()
 }
 
+/** 激活时 **/
+onActivated(() => {
+  getList()
+})
+
 /** 初始化 **/
 onMounted(() => {
   getList()