Parcourir la source

完成流程实例的取消

YunaiV il y a 3 ans
Parent
commit
2630ad8eaa
12 fichiers modifiés avec 115 ajouts et 18 suppressions
  1. 11 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.http
  2. 8 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.java
  3. 23 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceCancelReqVO.java
  4. 5 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java
  5. 1 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java
  6. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/BpmProcessInstanceResultEnum.java
  7. 9 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java
  8. 19 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java
  9. 2 2
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java
  10. 3 7
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/listener/BpmProcessInstanceEventListener.java
  11. 11 0
      yudao-admin-ui/src/api/bpm/processInstance.js
  12. 22 4
      yudao-admin-ui/src/views/bpm/processInstance/index.vue

+ 11 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.http

@@ -12,6 +12,17 @@ Authorization: Bearer {{token}}
   }
 }
 
+### 请求 /bpm/process-instance/cancel 接口 => 成功
+DELETE {{baseUrl}}/bpm/process-instance/cancel
+Content-Type: application/json
+tenant-id: 1
+Authorization: Bearer {{token}}
+
+{
+  "id": "b9220387-7088-11ec-bcae-a2380e71991a",
+  "reason": "我就取消"
+}
+
 ### 请求 /bpm/process-instance/my-page 接口 => 成功
 GET {{baseUrl}}/bpm/process-instance/my-page
 tenant-id: 1

+ 8 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.controller.task;
 
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
@@ -34,6 +35,13 @@ public class BpmProcessInstanceController {
         return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
     }
 
+    @DeleteMapping("/cancel")
+    @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")
+    public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
+        processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
+        return success(true);
+    }
+
     @GetMapping("/my-page")
     @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用")
     public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(

+ 23 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceCancelReqVO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.Map;
+
+@ApiModel("流程实例的取消 Request VO")
+@Data
+public class BpmProcessInstanceCancelReqVO {
+
+    @ApiModelProperty(value = "流程实例的编号", required = true, example = "1024")
+    @NotEmpty(message = "流程实例的编号不能为空")
+    private String id;
+
+    @ApiModelProperty(value = "取消原因", required = true, example = "不请假了!")
+    @NotEmpty(message = "取消原因不能为空")
+    private String reason;
+
+}

+ 5 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmProcessInstanceExtMapper.java

@@ -5,6 +5,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessIn
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
 @Mapper
@@ -22,4 +23,8 @@ public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInsta
                 .orderByDesc("id"));
     }
 
+    default void updateByProcessInstanceId(String processInstanceId, BpmProcessInstanceExtDO updateObj) {
+        update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>().eq("process_instance_id", processInstanceId));
+    }
+
 }

+ 1 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java

@@ -10,7 +10,6 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
 public interface BpmErrorCodeConstants {
 
     // ==========  通用流程处理 模块 1-009-000-000 ==========
-    ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009000001, "流程实例不存在");
     ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常");
 
     // ========== OA 流程模块 1-009-001-000 ==========
@@ -34,7 +33,7 @@ public interface BpmErrorCodeConstants {
     ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003002, "流程定义处于挂起状态");
 
     // ========== 流程实例 1-009-004-000 ==========
-
+    ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "流程取消失败,流程不处于运行中");
 
     // ========== 动态表单模块 1-009-010-000 ==========
     ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/BpmProcessInstanceResultEnum.java

@@ -15,7 +15,7 @@ public enum BpmProcessInstanceResultEnum {
     PROCESS(1, "处理中"),
     PASS(2, "通过"),
     REJECT(3, "不通过"),
-    CANCEL(4, "撤销");
+    CANCEL(4, "已取消");
 
     /**
      * 结果

+ 9 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
 
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
@@ -28,6 +29,14 @@ public interface BpmProcessInstanceService {
      */
     String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO);
 
+    /**
+     * 取消流程实例
+     *
+     * @param userId 用户编号
+     * @param cancelReqVO 取消信息
+     */
+    void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);
+
     /**
      * 获得流程实例的分页
      *

+ 19 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
+import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
@@ -37,8 +38,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.function.Consumer;
 
-import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED;
-import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS;
+import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 
@@ -127,6 +127,23 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
         processInstanceExtMapper.insert(instanceExt);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void cancelProcessInstance(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) {
+        // 校验流程实例存在
+        ProcessInstance instance = getProcessInstance(cancelReqVO.getId());
+        if (instance == null) {
+            throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
+        }
+
+        // 通过删除流程实例,实现流程实例的取消
+        runtimeService.deleteProcessInstance(cancelReqVO.getId(), cancelReqVO.getReason());
+        // 更新流程实例的拓展表为取消状态
+        processInstanceExtMapper.updateByProcessInstanceId(cancelReqVO.getId(),
+                new BpmProcessInstanceExtDO().setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
+                        .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()));
+    }
+
     @Override
     public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
                                                                                  BpmProcessInstanceMyPageReqVO pageReqVO) {

+ 2 - 2
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java

@@ -42,7 +42,6 @@ import java.io.InputStream;
 import java.util.*;
 
 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.HIGHLIGHT_IMG_ERROR;
-import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 
@@ -228,7 +227,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
         HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
         // 如果不存在实例。 说明数据异常
         if (hpi == null) {
-            throw exception(PROCESS_INSTANCE_NOT_EXISTS);
+//            throw exception(PROCESS_INSTANCE_NOT_EXISTS);
+            throw new RuntimeException("不存在");
         }
         // 如果有结束时间 返回model的流程图
         if (!ObjectUtils.isEmpty(hpi.getEndTime())) {

+ 3 - 7
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/listener/BpmProcessInstanceEventListener.java

@@ -25,17 +25,13 @@ public class BpmProcessInstanceEventListener implements ActivitiEventListener {
 
     @Override
     public void onEvent(ActivitiEvent event) {
-        // 不处理  ActivitiEventType.PROCESS_STARTED 事件。原因:事件发布时,流程实例还没进行入库,就已经发布了 ActivitiEvent 事件
+        // 不处理 ActivitiEventType.PROCESS_STARTED 事件。原因:事件发布时,流程实例还没进行入库,就已经发布了 ActivitiEvent 事件
+        // 不处理 ActivitiEventType.PROCESS_CANCELLED 事件。原因:直接在 BpmTaskService#cancelProcessInstance 更新记录
 
         // 正常完成
         if (event.getType() == ActivitiEventType.PROCESS_COMPLETED
             || event.getType() == ActivitiEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT) {
-            return;
-        }
-        // 取消
-        if (event.getType() == ActivitiEventType.PROCESS_CANCELLED) {
-            // TODO
-            System.out.println();
+            // TODO 芋艿:更新
         }
     }
 

+ 11 - 0
yudao-admin-ui/src/api/bpm/processInstance.js

@@ -7,3 +7,14 @@ export function getMyProcessInstancePage(query) {
     params: query
   })
 }
+
+export function cancelProcessInstance(id, reason) {
+  return request({
+    url: '/bpm/process-instance/cancel',
+    method: 'DELETE',
+    data: {
+      id,
+      reason
+    }
+  })
+}

+ 22 - 4
yudao-admin-ui/src/views/bpm/processInstance/index.vue

@@ -103,8 +103,9 @@
       </el-table-column>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
-<!--          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"-->
-<!--                     v-hasPermi="['bpm:process-instance-ext:update']">修改</el-button>-->
+          <!-- TODO 芋艿:权限 -->
+          <el-button type="text" size="small" icon="el-icon-delete" v-if="scope.row.result === 1"
+                     @click="handleCancel(scope.row)">取消</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -162,8 +163,9 @@ import {
   deleteProcessInstanceExt,
   getProcessInstanceExt,
   getProcessInstanceExtPage,
-  exportProcessInstanceExtExcel
+  exportProcessInstanceExtExcel, cancelProcessInstance
 } from "@/api/bpm/processInstance";
+import {deleteErrorCode} from "@/api/system/errorCode";
 
 export default {
   name: "ProcessInstanceExt",
@@ -283,7 +285,23 @@ export default {
           this.getList();
         });
       });
-    }
+    },
+    /** 取消按钮操作 */
+    handleCancel(row) {
+      const id = row.id;
+      this.$prompt('请输出取消原因?', "取消流程", {
+        type: 'warning',
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/, // 判断非空,且非空格
+        inputErrorMessage: "取消原因不能为空",
+      }).then(({ value }) => {
+        return cancelProcessInstance(id, value);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("取消成功");
+      })
+    },
   }
 };
 </script>