Commit 2630ad8eaacbf2d86f969682507c470a1128d334

Authored by YunaiV
1 parent 2017b031

完成流程实例的取消

yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.http
@@ -12,6 +12,17 @@ Authorization: Bearer {{token}} @@ -12,6 +12,17 @@ Authorization: Bearer {{token}}
12 } 12 }
13 } 13 }
14 14
  15 +### 请求 /bpm/process-instance/cancel 接口 => 成功
  16 +DELETE {{baseUrl}}/bpm/process-instance/cancel
  17 +Content-Type: application/json
  18 +tenant-id: 1
  19 +Authorization: Bearer {{token}}
  20 +
  21 +{
  22 + "id": "b9220387-7088-11ec-bcae-a2380e71991a",
  23 + "reason": "我就取消"
  24 +}
  25 +
15 ### 请求 /bpm/process-instance/my-page 接口 => 成功 26 ### 请求 /bpm/process-instance/my-page 接口 => 成功
16 GET {{baseUrl}}/bpm/process-instance/my-page 27 GET {{baseUrl}}/bpm/process-instance/my-page
17 tenant-id: 1 28 tenant-id: 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.java
1 package cn.iocoder.yudao.adminserver.modules.bpm.controller.task; 1 package cn.iocoder.yudao.adminserver.modules.bpm.controller.task;
2 2
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO;
3 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; 4 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
4 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; 5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; 6 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
@@ -34,6 +35,13 @@ public class BpmProcessInstanceController { @@ -34,6 +35,13 @@ public class BpmProcessInstanceController {
34 return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO)); 35 return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
35 } 36 }
36 37
  38 + @DeleteMapping("/cancel")
  39 + @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")
  40 + public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
  41 + processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
  42 + return success(true);
  43 + }
  44 +
37 @GetMapping("/my-page") 45 @GetMapping("/my-page")
38 @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用") 46 @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用")
39 public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage( 47 public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceCancelReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +
  7 +import javax.validation.constraints.NotEmpty;
  8 +import javax.validation.constraints.NotNull;
  9 +import java.util.Map;
  10 +
  11 +@ApiModel("流程实例的取消 Request VO")
  12 +@Data
  13 +public class BpmProcessInstanceCancelReqVO {
  14 +
  15 + @ApiModelProperty(value = "流程实例的编号", required = true, example = "1024")
  16 + @NotEmpty(message = "流程实例的编号不能为空")
  17 + private String id;
  18 +
  19 + @ApiModelProperty(value = "取消原因", required = true, example = "不请假了!")
  20 + @NotEmpty(message = "取消原因不能为空")
  21 + private String reason;
  22 +
  23 +}
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 @@ -5,6 +5,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessIn
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
7 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; 7 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  8 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
10 @Mapper 11 @Mapper
@@ -22,4 +23,8 @@ public interface BpmProcessInstanceExtMapper extends BaseMapperX&lt;BpmProcessInsta @@ -22,4 +23,8 @@ public interface BpmProcessInstanceExtMapper extends BaseMapperX&lt;BpmProcessInsta
22 .orderByDesc("id")); 23 .orderByDesc("id"));
23 } 24 }
24 25
  26 + default void updateByProcessInstanceId(String processInstanceId, BpmProcessInstanceExtDO updateObj) {
  27 + update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>().eq("process_instance_id", processInstanceId));
  28 + }
  29 +
25 } 30 }
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; @@ -10,7 +10,6 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
10 public interface BpmErrorCodeConstants { 10 public interface BpmErrorCodeConstants {
11 11
12 // ========== 通用流程处理 模块 1-009-000-000 ========== 12 // ========== 通用流程处理 模块 1-009-000-000 ==========
13 - ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009000001, "流程实例不存在");  
14 ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常"); 13 ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常");
15 14
16 // ========== OA 流程模块 1-009-001-000 ========== 15 // ========== OA 流程模块 1-009-001-000 ==========
@@ -34,7 +33,7 @@ public interface BpmErrorCodeConstants { @@ -34,7 +33,7 @@ public interface BpmErrorCodeConstants {
34 ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003002, "流程定义处于挂起状态"); 33 ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003002, "流程定义处于挂起状态");
35 34
36 // ========== 流程实例 1-009-004-000 ========== 35 // ========== 流程实例 1-009-004-000 ==========
37 - 36 + ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "流程取消失败,流程不处于运行中");
38 37
39 // ========== 动态表单模块 1-009-010-000 ========== 38 // ========== 动态表单模块 1-009-010-000 ==========
40 ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在"); 39 ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/BpmProcessInstanceResultEnum.java
@@ -15,7 +15,7 @@ public enum BpmProcessInstanceResultEnum { @@ -15,7 +15,7 @@ public enum BpmProcessInstanceResultEnum {
15 PROCESS(1, "处理中"), 15 PROCESS(1, "处理中"),
16 PASS(2, "通过"), 16 PASS(2, "通过"),
17 REJECT(3, "不通过"), 17 REJECT(3, "不通过"),
18 - CANCEL(4, "撤销"); 18 + CANCEL(4, "已取消");
19 19
20 /** 20 /**
21 * 结果 21 * 结果
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java
1 package cn.iocoder.yudao.adminserver.modules.bpm.service.task; 1 package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
2 2
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO;
3 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; 4 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
4 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; 5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; 6 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
@@ -29,6 +30,14 @@ public interface BpmProcessInstanceService { @@ -29,6 +30,14 @@ public interface BpmProcessInstanceService {
29 String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO); 30 String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO);
30 31
31 /** 32 /**
  33 + * 取消流程实例
  34 + *
  35 + * @param userId 用户编号
  36 + * @param cancelReqVO 取消信息
  37 + */
  38 + void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);
  39 +
  40 + /**
32 * 获得流程实例的分页 41 * 获得流程实例的分页
33 * 42 *
34 * @param userId 用户编号 43 * @param userId 用户编号
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; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.lang.Assert; 4 import cn.hutool.core.lang.Assert;
  5 +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO;
5 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; 6 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
6 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; 7 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
7 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; 8 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
@@ -37,8 +38,7 @@ import java.util.Map; @@ -37,8 +38,7 @@ import java.util.Map;
37 import java.util.Set; 38 import java.util.Set;
38 import java.util.function.Consumer; 39 import java.util.function.Consumer;
39 40
40 -import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED;  
41 -import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS; 41 +import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
42 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 42 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
43 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 43 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
44 44
@@ -128,6 +128,23 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -128,6 +128,23 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
128 } 128 }
129 129
130 @Override 130 @Override
  131 + @Transactional(rollbackFor = Exception.class)
  132 + public void cancelProcessInstance(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) {
  133 + // 校验流程实例存在
  134 + ProcessInstance instance = getProcessInstance(cancelReqVO.getId());
  135 + if (instance == null) {
  136 + throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
  137 + }
  138 +
  139 + // 通过删除流程实例,实现流程实例的取消
  140 + runtimeService.deleteProcessInstance(cancelReqVO.getId(), cancelReqVO.getReason());
  141 + // 更新流程实例的拓展表为取消状态
  142 + processInstanceExtMapper.updateByProcessInstanceId(cancelReqVO.getId(),
  143 + new BpmProcessInstanceExtDO().setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
  144 + .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()));
  145 + }
  146 +
  147 + @Override
131 public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, 148 public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
132 BpmProcessInstanceMyPageReqVO pageReqVO) { 149 BpmProcessInstanceMyPageReqVO pageReqVO) {
133 // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 150 // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页
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; @@ -42,7 +42,6 @@ import java.io.InputStream;
42 import java.util.*; 42 import java.util.*;
43 43
44 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.HIGHLIGHT_IMG_ERROR; 44 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.HIGHLIGHT_IMG_ERROR;
45 -import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;  
46 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 45 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
47 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 46 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
48 47
@@ -228,7 +227,8 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -228,7 +227,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
228 HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); 227 HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
229 // 如果不存在实例。 说明数据异常 228 // 如果不存在实例。 说明数据异常
230 if (hpi == null) { 229 if (hpi == null) {
231 - throw exception(PROCESS_INSTANCE_NOT_EXISTS); 230 +// throw exception(PROCESS_INSTANCE_NOT_EXISTS);
  231 + throw new RuntimeException("不存在");
232 } 232 }
233 // 如果有结束时间 返回model的流程图 233 // 如果有结束时间 返回model的流程图
234 if (!ObjectUtils.isEmpty(hpi.getEndTime())) { 234 if (!ObjectUtils.isEmpty(hpi.getEndTime())) {
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 { @@ -25,17 +25,13 @@ public class BpmProcessInstanceEventListener implements ActivitiEventListener {
25 25
26 @Override 26 @Override
27 public void onEvent(ActivitiEvent event) { 27 public void onEvent(ActivitiEvent event) {
28 - // 不处理 ActivitiEventType.PROCESS_STARTED 事件。原因:事件发布时,流程实例还没进行入库,就已经发布了 ActivitiEvent 事件 28 + // 不处理 ActivitiEventType.PROCESS_STARTED 事件。原因:事件发布时,流程实例还没进行入库,就已经发布了 ActivitiEvent 事件
  29 + // 不处理 ActivitiEventType.PROCESS_CANCELLED 事件。原因:直接在 BpmTaskService#cancelProcessInstance 更新记录
29 30
30 // 正常完成 31 // 正常完成
31 if (event.getType() == ActivitiEventType.PROCESS_COMPLETED 32 if (event.getType() == ActivitiEventType.PROCESS_COMPLETED
32 || event.getType() == ActivitiEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT) { 33 || event.getType() == ActivitiEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT) {
33 - return;  
34 - }  
35 - // 取消  
36 - if (event.getType() == ActivitiEventType.PROCESS_CANCELLED) {  
37 - // TODO  
38 - System.out.println(); 34 + // TODO 芋艿:更新
39 } 35 }
40 } 36 }
41 37
yudao-admin-ui/src/api/bpm/processInstance.js
@@ -7,3 +7,14 @@ export function getMyProcessInstancePage(query) { @@ -7,3 +7,14 @@ export function getMyProcessInstancePage(query) {
7 params: query 7 params: query
8 }) 8 })
9 } 9 }
  10 +
  11 +export function cancelProcessInstance(id, reason) {
  12 + return request({
  13 + url: '/bpm/process-instance/cancel',
  14 + method: 'DELETE',
  15 + data: {
  16 + id,
  17 + reason
  18 + }
  19 + })
  20 +}
yudao-admin-ui/src/views/bpm/processInstance/index.vue
@@ -103,8 +103,9 @@ @@ -103,8 +103,9 @@
103 </el-table-column> 103 </el-table-column>
104 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> 104 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
105 <template slot-scope="scope"> 105 <template slot-scope="scope">
106 -<!-- <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"-->  
107 -<!-- v-hasPermi="['bpm:process-instance-ext:update']">修改</el-button>--> 106 + <!-- TODO 芋艿:权限 -->
  107 + <el-button type="text" size="small" icon="el-icon-delete" v-if="scope.row.result === 1"
  108 + @click="handleCancel(scope.row)">取消</el-button>
108 </template> 109 </template>
109 </el-table-column> 110 </el-table-column>
110 </el-table> 111 </el-table>
@@ -162,8 +163,9 @@ import { @@ -162,8 +163,9 @@ import {
162 deleteProcessInstanceExt, 163 deleteProcessInstanceExt,
163 getProcessInstanceExt, 164 getProcessInstanceExt,
164 getProcessInstanceExtPage, 165 getProcessInstanceExtPage,
165 - exportProcessInstanceExtExcel 166 + exportProcessInstanceExtExcel, cancelProcessInstance
166 } from "@/api/bpm/processInstance"; 167 } from "@/api/bpm/processInstance";
  168 +import {deleteErrorCode} from "@/api/system/errorCode";
167 169
168 export default { 170 export default {
169 name: "ProcessInstanceExt", 171 name: "ProcessInstanceExt",
@@ -283,7 +285,23 @@ export default { @@ -283,7 +285,23 @@ export default {
283 this.getList(); 285 this.getList();
284 }); 286 });
285 }); 287 });
286 - } 288 + },
  289 + /** 取消按钮操作 */
  290 + handleCancel(row) {
  291 + const id = row.id;
  292 + this.$prompt('请输出取消原因?', "取消流程", {
  293 + type: 'warning',
  294 + confirmButtonText: "确定",
  295 + cancelButtonText: "取消",
  296 + inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/, // 判断非空,且非空格
  297 + inputErrorMessage: "取消原因不能为空",
  298 + }).then(({ value }) => {
  299 + return cancelProcessInstance(id, value);
  300 + }).then(() => {
  301 + this.getList();
  302 + this.msgSuccess("取消成功");
  303 + })
  304 + },
287 } 305 }
288 }; 306 };
289 </script> 307 </script>