Commit ba502fc5282b7f00a731abd7f352561f7409dfcd

Authored by YunaiV
1 parent 3fce4827

BPM:调整抄送逻辑的实现,改成审批通过、不通过时,可选择抄送

Showing 15 changed files with 236 additions and 683 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmCommentTypeEnum.java
... ... @@ -4,25 +4,29 @@ import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
5 5  
6 6 /**
7   - * 流程任务 -- comment类型枚举
  7 + * 流程任务的 Comment 评论类型枚举
  8 + *
  9 + * @author kehaiyou
8 10 */
9 11 @Getter
10 12 @AllArgsConstructor
11 13 public enum BpmCommentTypeEnum {
12 14  
13   - APPROVE(1, "通过", ""),
14   - REJECT(2, "不通过", ""),
15   - CANCEL(3, "已取消", ""),
16   - BACK(4, "退回", ""),
17   - DELEGATE(5, "委派", ""),
18   - ADD_SIGN(6, "加签", "[{}]{}给了[{}],理由为:{}"),
19   - SUB_SIGN(7, "减签", "[{}]操作了【减签】,审批人[{}]的任务被取消"),
  15 + APPROVE("1", "审批通过", ""), // 理由:直接使用用户的评论
  16 + REJECT("2", "不通过", ""),
  17 + CANCEL("3", "已取消", ""),
  18 + BACK("4", "退回", ""),
  19 + DELEGATE("5", "委派", ""),
  20 + ADD_SIGN("6", "加签", "[{}]{}给了[{}],理由为:{}"),
  21 + SUB_SIGN("7", "减签", "[{}]操作了【减签】,审批人[{}]的任务被取消"),
20 22 ;
21 23  
22 24 /**
23 25 * 操作类型
  26 + *
  27 + * 由于 BPM Comment 类型为 String,所以这里就不使用 Integer
24 28 */
25   - private final Integer type;
  29 + private final String type;
26 30 /**
27 31 * 操作名字
28 32 */
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java
... ... @@ -3,23 +3,27 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyCreateReqVO;
7   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyMyPageReqVO;
8   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageItemRespVO;
9   -import cn.iocoder.yudao.module.bpm.convert.cc.BpmProcessInstanceCopyConvert;
  6 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  7 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.cc.BpmProcessInstanceCopyRespVO;
  10 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
10 11 import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
  12 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceCopyService;
11 13 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
12 14 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
13   -import cn.iocoder.yudao.module.bpm.service.task.cc.BpmProcessInstanceCopyService;
14 15 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
15 16 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
16 17 import io.swagger.v3.oas.annotations.Operation;
17 18 import io.swagger.v3.oas.annotations.tags.Tag;
18 19 import jakarta.annotation.Resource;
19 20 import jakarta.validation.Valid;
  21 +import org.flowable.engine.history.HistoricProcessInstance;
20 22 import org.springframework.security.access.prepost.PreAuthorize;
21 23 import org.springframework.validation.annotation.Validated;
22   -import org.springframework.web.bind.annotation.*;
  24 +import org.springframework.web.bind.annotation.GetMapping;
  25 +import org.springframework.web.bind.annotation.RequestMapping;
  26 +import org.springframework.web.bind.annotation.RestController;
23 27  
24 28 import java.util.Map;
25 29 import java.util.stream.Stream;
... ... @@ -31,35 +35,27 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
31 35  
32 36 @Tag(name = "管理后台 - 流程实例抄送")
33 37 @RestController
34   -@RequestMapping("/bpm/process-instance/cc")
  38 +@RequestMapping("/bpm/process-instance/copy")
35 39 @Validated
36 40 public class BpmProcessInstanceCopyController {
37 41  
38 42 @Resource
39 43 private BpmProcessInstanceCopyService processInstanceCopyService;
40 44 @Resource
41   - private BpmProcessInstanceService bpmProcessInstanceService;
42   -
43   - @Resource
44   - private AdminUserApi adminUserApi;
45   -
  45 + private BpmProcessInstanceService processInstanceService;
46 46 @Resource
47 47 private BpmTaskService bpmTaskService;
48 48  
49   - @PostMapping("/create")
50   - @Operation(summary = "抄送流程")
51   - @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:create')")
52   - public CommonResult<Boolean> createProcessInstanceCopy(@Valid @RequestBody BpmProcessInstanceCopyCreateReqVO createReqVO) {
53   - processInstanceCopyService.createProcessInstanceCopy(getLoginUserId(), createReqVO);
54   - return success(true);
55   - }
  49 + @Resource
  50 + private AdminUserApi adminUserApi;
56 51  
57   - @GetMapping("/my-page")
  52 + @GetMapping("/page")
58 53 @Operation(summary = "获得抄送流程分页列表")
59 54 @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:query')")
60   - public CommonResult<PageResult<BpmProcessInstanceCopyPageItemRespVO>> getProcessInstanceCopyPage(
61   - @Valid BpmProcessInstanceCopyMyPageReqVO pageReqVO) {
62   - PageResult<BpmProcessInstanceCopyDO> pageResult = processInstanceCopyService.getMyProcessInstanceCopyPage(getLoginUserId(), pageReqVO);
  55 + public CommonResult<PageResult<BpmProcessInstanceCopyRespVO>> getProcessInstanceCopyPage(
  56 + @Valid BpmProcessInstanceCopyPageReqVO pageReqVO) {
  57 + PageResult<BpmProcessInstanceCopyDO> pageResult = processInstanceCopyService.getProcessInstanceCopyPage(
  58 + getLoginUserId(), pageReqVO);
63 59 if (CollUtil.isEmpty(pageResult.getList())) {
64 60 return success(new PageResult<>(pageResult.getTotal()));
65 61 }
... ... @@ -67,11 +63,17 @@ public class BpmProcessInstanceCopyController {
67 63 // 拼接返回
68 64 Map<String, String> taskNameMap = bpmTaskService.getTaskNameByTaskIds(
69 65 convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getTaskId));
70   - Map<String, String> processNameMap = bpmProcessInstanceService.getProcessInstanceNameMap(
  66 + Map<String, HistoricProcessInstance> processInstanceMap = processInstanceService.getHistoricProcessInstanceMap(
71 67 convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessInstanceId));
72 68 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(),
73 69 copy -> Stream.of(copy.getStartUserId(), Long.parseLong(copy.getCreator()))));
74   - return success(BpmProcessInstanceCopyConvert.INSTANCE.convertPage(pageResult, taskNameMap, processNameMap, userMap));
  70 + return success(BeanUtils.toBean(pageResult, BpmProcessInstanceCopyRespVO.class, copyVO -> {
  71 + MapUtils.findAndThen(userMap, Long.valueOf(copyVO.getCreator()), user -> copyVO.setCreatorName(user.getNickname()));
  72 + MapUtils.findAndThen(userMap, copyVO.getStartUserId(), user -> copyVO.setStartUserName(user.getNickname()));
  73 + MapUtils.findAndThen(taskNameMap, copyVO.getTaskId(), copyVO::setTaskName);
  74 + MapUtils.findAndThen(processInstanceMap, copyVO.getProcessInstanceId(),
  75 + processInstance -> copyVO.setProcessInstanceStartTime(DateUtils.of(processInstance.getStartTime())));
  76 + }));
75 77 }
76 78  
77 79 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.task;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4   -import cn.hutool.core.util.StrUtil;
5 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 6 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
9 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
10 8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
11 9 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
12   -import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
  10 +import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
13 11 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
14 12 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
15 13 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
... ... @@ -66,15 +64,7 @@ public class BpmTaskController {
66 64 convertSet(pageResult.getList(), Task::getProcessInstanceId));
67 65 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
68 66 convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
69   - return success(BeanUtils.toBean(pageResult, BpmTaskRespVO.class, taskVO -> {
70   - ProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
71   - if (processInstance == null) {
72   - return;
73   - }
74   - AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
75   - taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class,
76   - processInstanceVO -> processInstanceVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class))));
77   - }));
  67 + return success(BpmTaskConvert.INSTANCE.buildTodoTaskPage(pageResult, processInstanceMap, userMap));
78 68 }
79 69  
80 70 @GetMapping("done-page")
... ... @@ -87,18 +77,9 @@ public class BpmTaskController {
87 77 convertSet(pageResult.getList(), HistoricTaskInstance::getProcessInstanceId));
88 78 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
89 79 convertSet(processInstanceMap.values(), instance -> Long.valueOf(instance.getStartUserId())));
90   - return success(BeanUtils.toBean(pageResult, BpmTaskRespVO.class, taskVO -> {
91   - HistoricProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
92   - if (processInstance == null) {
93   - return;
94   - }
95   - AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
96   - taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class,
97   - processInstanceVO -> processInstanceVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class))));
98   - }));
  80 + return success(BpmTaskConvert.INSTANCE.buildDoneTaskPage(pageResult, processInstanceMap, userMap));
99 81 }
100 82  
101   - // TODO @芋艿:怎么优化下
102 83 @GetMapping("/list-by-process-instance-id")
103 84 @Operation(summary = "获得指定流程实例的任务列表", description = "包括完成的、未完成的")
104 85 @Parameter(name = "processInstanceId", description = "流程实例的编号", required = true)
... ... @@ -118,33 +99,7 @@ public class BpmTaskController {
118 99 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
119 100 Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
120 101 convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
121   - List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(taskList, task -> {
122   - BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
123   - taskVO.setStatus((Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS));
124   - // 流程实例
125   - AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
126   - taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class,
127   - processInstanceVO -> processInstanceVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class))));
128   - // 用户信息
129   - AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
130   - if (assignUser != null) {
131   - taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
132   - DeptRespDTO dept = deptMap.get(assignUser.getDeptId());
133   - if (dept != null) {
134   - taskVO.getAssigneeUser().setDeptName(dept.getName());
135   - }
136   - }
137   - return taskVO;
138   - });
139   -
140   - // 拼接父子关系
141   - Map<String, List<BpmTaskRespVO>> childrenTaskMap = convertMultiMap(
142   - filterList(taskVOList, r -> StrUtil.isNotEmpty(r.getParentTaskId())),
143   - BpmTaskRespVO::getParentTaskId);
144   - for (BpmTaskRespVO taskVO : taskVOList) {
145   - taskVO.setChildren(childrenTaskMap.get(taskVO.getId()));
146   - }
147   - return success(filterList(taskVOList, r -> StrUtil.isEmpty(r.getParentTaskId())));
  102 + return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId(taskList, processInstance, userMap, deptMap));
148 103 }
149 104  
150 105 @PutMapping("/approve")
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCopyPageItemRespVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/cc/BpmProcessInstanceCopyRespVO.java
1   -package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.cc;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
... ... @@ -7,37 +7,32 @@ import java.time.LocalDateTime;
7 7  
8 8 @Schema(description = "管理后台 - 流程实例抄送的分页 Item Response VO")
9 9 @Data
10   -public class BpmProcessInstanceCopyPageItemRespVO {
  10 +public class BpmProcessInstanceCopyRespVO {
11 11  
12   - @Schema(description = "抄送主键")
  12 + @Schema(description = "抄送主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
13 13 private Long id;
14 14  
15   - @Schema(description = "发起人 ID")
  15 + @Schema(description = "发起人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
16 16 private Long startUserId;
  17 + @Schema(description = "发起人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
  18 + private String startUserName;
17 19  
18   - @Schema(description = "发起人别名")
19   - private String startUserNickname;
20   -
21   - @Schema(description = "流程实例的主键")
  20 + @Schema(description = "流程实例编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "A233")
22 21 private String processInstanceId;
23   -
24 22 @Schema(description = "流程实例的名称")
25 23 private String processInstanceName;
  24 + @Schema(description = "流程实例的发起时间")
  25 + private LocalDateTime processInstanceStartTime;
26 26  
27 27 @Schema(description = "发起抄送的任务编号")
28 28 private String taskId;
29   -
30 29 @Schema(description = "发起抄送的任务名称")
31 30 private String taskName;
32 31  
33   - @Schema(description = "抄送原因")
34   - private String reason;
35   -
36 32 @Schema(description = "抄送人")
37 33 private String creator;
38   -
39   - @Schema(description = "抄送人别名")
40   - private String creatorNickname;
  34 + @Schema(description = "抄送人昵称")
  35 + private String creatorName;
41 36  
42 37 @Schema(description = "抄送时间")
43 38 private LocalDateTime createTime;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCopyCreateReqVO.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import jakarta.validation.constraints.NotBlank;
5   -import jakarta.validation.constraints.NotEmpty;
6   -import lombok.Data;
7   -
8   -@Schema(description = "管理后台 - 流程实例抄送的创建 Request VO")
9   -@Data
10   -public class BpmProcessInstanceCopyCreateReqVO {
11   -
12   - @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
13   - @NotEmpty(message = "任务编号不能为空")
14   - private String taskId;
15   -
16   - @Schema(description = "抄送原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "请帮忙审查下!")
17   - @NotBlank(message = "抄送原因不能为空")
18   - private String reason;
19   -
20   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCopyMyPageReqVO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCopyPageReqVO.java
... ... @@ -15,14 +15,11 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
15 15 @Data
16 16 @EqualsAndHashCode(callSuper = true)
17 17 @ToString(callSuper = true)
18   -public class BpmProcessInstanceCopyMyPageReqVO extends PageParam {
  18 +public class BpmProcessInstanceCopyPageReqVO extends PageParam {
19 19  
20 20 @Schema(description = "流程名称", example = "芋道")
21 21 private String processInstanceName;
22 22  
23   - @Schema(description = "流程编号", example = "123456768")
24   - private String processInstanceId;
25   -
26 23 @Schema(description = "创建时间")
27 24 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
28 25 private LocalDateTime[] createTime;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
4 5 import lombok.Data;
5 6  
6   -import jakarta.validation.constraints.NotEmpty;
  7 +import java.util.Collection;
7 8  
8 9 @Schema(description = "管理后台 - 通过流程任务的 Request VO")
9 10 @Data
... ... @@ -17,4 +18,7 @@ public class BpmTaskApproveReqVO {
17 18 @NotEmpty(message = "审批意见不能为空")
18 19 private String reason;
19 20  
  21 + @Schema(description = "抄送的用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2")
  22 + private Collection<Long> copyUserIds;
  23 +
20 24 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java deleted
1   -package cn.iocoder.yudao.module.bpm.convert.cc;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
5   -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageItemRespVO;
7   -import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
8   -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
9   -import org.mapstruct.Mapper;
10   -import org.mapstruct.factory.Mappers;
11   -
12   -import java.util.List;
13   -import java.util.Map;
14   -
15   -/**
16   - * 流程抄送 Convert
17   - *
18   - * @author 芋艿
19   - */
20   -@Mapper
21   -public interface BpmProcessInstanceCopyConvert {
22   -
23   - BpmProcessInstanceCopyConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceCopyConvert.class);
24   -
25   - default PageResult<BpmProcessInstanceCopyPageItemRespVO> convertPage(PageResult<BpmProcessInstanceCopyDO> page,
26   - Map<String, String> taskNameMap,
27   - Map<String, String> processInstaneNameMap,
28   - Map<Long, AdminUserRespDTO> userMap) {
29   - List<BpmProcessInstanceCopyPageItemRespVO> list = BeanUtils.toBean(page.getList(),
30   - BpmProcessInstanceCopyPageItemRespVO.class,
31   - copy -> {
32   - MapUtils.findAndThen(userMap, Long.valueOf(copy.getCreator()), user -> user.setNickname(user.getNickname()));
33   - MapUtils.findAndThen(userMap, copy.getStartUserId(), user -> copy.setStartUserNickname(user.getNickname()));
34   - MapUtils.findAndThen(taskNameMap, copy.getTaskId(), copy::setTaskName);
35   - MapUtils.findAndThen(processInstaneNameMap, copy.getProcessInstanceId(), copy::setProcessInstanceName);
36   - });
37   - return new PageResult<>(list, page.getTotal());
38   - }
39   -
40   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
1 1 package cn.iocoder.yudao.module.bpm.convert.task;
2 2  
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
3 6 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
4 7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
  10 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
  11 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
5 12 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
  13 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
6 14 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  15 +import org.flowable.engine.history.HistoricProcessInstance;
7 16 import org.flowable.engine.runtime.ProcessInstance;
8 17 import org.flowable.task.api.Task;
  18 +import org.flowable.task.api.history.HistoricTaskInstance;
9 19 import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
10 20 import org.mapstruct.Mapper;
11 21 import org.mapstruct.factory.Mappers;
12 22  
13 23 import java.util.Date;
  24 +import java.util.List;
  25 +import java.util.Map;
  26 +
  27 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
14 29  
15 30 /**
16 31 * Bpm 任务 Convert
... ... @@ -22,6 +37,71 @@ public interface BpmTaskConvert {
22 37  
23 38 BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
24 39  
  40 + default PageResult<BpmTaskRespVO> buildTodoTaskPage(PageResult<Task> pageResult,
  41 + Map<String, ProcessInstance> processInstanceMap,
  42 + Map<Long, AdminUserRespDTO> userMap) {
  43 + return BeanUtils.toBean(pageResult, BpmTaskRespVO.class, taskVO -> {
  44 + ProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
  45 + if (processInstance == null) {
  46 + return;
  47 + }
  48 + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
  49 + taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class,
  50 + processInstanceVO -> processInstanceVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class))));
  51 + });
  52 + }
  53 +
  54 + default PageResult<BpmTaskRespVO> buildDoneTaskPage(PageResult<HistoricTaskInstance> pageResult,
  55 + Map<String, HistoricProcessInstance> processInstanceMap,
  56 + Map<Long, AdminUserRespDTO> userMap) {
  57 + List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(pageResult.getList(), task -> {
  58 + BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
  59 + taskVO.setStatus((Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS));
  60 + // 流程实例
  61 + HistoricProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
  62 + if (processInstance != null) {
  63 + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
  64 + taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class,
  65 + processInstanceVO -> processInstanceVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class))));
  66 + }
  67 + return taskVO;
  68 + });
  69 + return new PageResult<>(taskVOList, pageResult.getTotal());
  70 + }
  71 +
  72 + default List<BpmTaskRespVO> buildTaskListByProcessInstanceId(List<HistoricTaskInstance> taskList,
  73 + HistoricProcessInstance processInstance,
  74 + Map<Long, AdminUserRespDTO> userMap,
  75 + Map<Long, DeptRespDTO> deptMap) {
  76 + List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(taskList, task -> {
  77 + BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
  78 + taskVO.setStatus((Integer) task.getTaskLocalVariables().get(BpmConstants.TASK_VARIABLE_STATUS));
  79 + // 流程实例
  80 + AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
  81 + taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class,
  82 + processInstanceVO -> processInstanceVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class))));
  83 + // 用户信息
  84 + AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(task.getAssignee()));
  85 + if (assignUser != null) {
  86 + taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceRespVO.User.class));
  87 + DeptRespDTO dept = deptMap.get(assignUser.getDeptId());
  88 + if (dept != null) {
  89 + taskVO.getAssigneeUser().setDeptName(dept.getName());
  90 + }
  91 + }
  92 + return taskVO;
  93 + });
  94 +
  95 + // 拼接父子关系
  96 + Map<String, List<BpmTaskRespVO>> childrenTaskMap = convertMultiMap(
  97 + filterList(taskVOList, r -> StrUtil.isNotEmpty(r.getParentTaskId())),
  98 + BpmTaskRespVO::getParentTaskId);
  99 + for (BpmTaskRespVO taskVO : taskVOList) {
  100 + taskVO.setChildren(childrenTaskMap.get(taskVO.getId()));
  101 + }
  102 + return filterList(taskVOList, r -> StrUtil.isEmpty(r.getParentTaskId()));
  103 + }
  104 +
25 105 default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser,
26 106 Task task) {
27 107 BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java
... ... @@ -29,7 +29,7 @@ public class BpmProcessInstanceCopyDO extends BaseDO {
29 29 /**
30 30 * 发起人 Id
31 31 *
32   - * 关联 system_users 的 id 属性
  32 + * 冗余 ProcessInstance 的 startUserId 字段
33 33 */
34 34 private Long startUserId;
35 35 /**
... ... @@ -44,6 +44,12 @@ public class BpmProcessInstanceCopyDO extends BaseDO {
44 44 * 关联 ProcessInstance 的 id 属性
45 45 */
46 46 private String processInstanceId;
  47 + /**
  48 + * 流程分类
  49 + *
  50 + * 冗余 ProcessInstance 的 category 字段
  51 + */
  52 + private String category;
47 53  
48 54 /**
49 55 * 任务主键
... ... @@ -51,7 +57,6 @@ public class BpmProcessInstanceCopyDO extends BaseDO {
51 57 * 关联 Task 的 id 属性
52 58 */
53 59 private String taskId;
54   -
55 60 /**
56 61 * 任务名称
57 62 *
... ... @@ -60,22 +65,10 @@ public class BpmProcessInstanceCopyDO extends BaseDO {
60 65 private String taskName;
61 66  
62 67 /**
63   - * 用户编号
  68 + * 用户编号(被抄送的用户编号)
64 69 *
65 70 * 关联 system_users 的 id 属性
66 71 */
67 72 private Long userId;
68 73  
69   - /**
70   - * 抄送原因
71   - */
72   - private String reason;
73   -
74   - /**
75   - * 流程分类
76   - *
77   - * 冗余 ProcessInstance 的 category 字段
78   - */
79   - private String category;
80   -
81 74 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java
... ... @@ -3,19 +3,19 @@ package cn.iocoder.yudao.module.bpm.dal.mysql.cc;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyMyPageReqVO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
7 7 import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9 9  
10 10 @Mapper
11 11 public interface BpmProcessInstanceCopyMapper extends BaseMapperX<BpmProcessInstanceCopyDO> {
12 12  
13   - default PageResult<BpmProcessInstanceCopyDO> selectPage(Long loginUserId, BpmProcessInstanceCopyMyPageReqVO reqVO) {
  13 + default PageResult<BpmProcessInstanceCopyDO> selectPage(Long loginUserId, BpmProcessInstanceCopyPageReqVO reqVO) {
14 14 return selectPage(reqVO, new LambdaQueryWrapperX<BpmProcessInstanceCopyDO>()
15 15 .eqIfPresent(BpmProcessInstanceCopyDO::getUserId, loginUserId)
16   - .eqIfPresent(BpmProcessInstanceCopyDO::getProcessInstanceId, reqVO.getProcessInstanceId())
17 16 .likeIfPresent(BpmProcessInstanceCopyDO::getProcessInstanceName, reqVO.getProcessInstanceName())
18 17 .betweenIfPresent(BpmProcessInstanceCopyDO::getCreateTime, reqVO.getCreateTime())
19 18 .orderByDesc(BpmProcessInstanceCopyDO::getId));
20 19 }
  20 +
21 21 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/cc/BpmProcessInstanceCopyService.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyService.java
1   -package cn.iocoder.yudao.module.bpm.service.task.cc;
  1 +package cn.iocoder.yudao.module.bpm.service.task;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyCreateReqVO;
5   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyMyPageReqVO;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
6 5 import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
7 6  
  7 +import java.util.Collection;
  8 +
8 9 /**
9 10 * 流程抄送 Service 接口
10 11 *
... ... @@ -15,17 +16,19 @@ public interface BpmProcessInstanceCopyService {
15 16 /**
16 17 * 流程实例的抄送
17 18 *
18   - * @param userId 当前登录用户
19   - * @param createReqVO 创建的抄送请求
  19 + * @param userIds 抄送的用户编号
  20 + * @param taskId 流程任务编号
20 21 */
21   - void createProcessInstanceCopy(Long userId, BpmProcessInstanceCopyCreateReqVO createReqVO);
  22 + void createProcessInstanceCopy(Collection<Long> userIds, String taskId);
22 23  
23 24 /**
24   - * 抄送的流程的分页
  25 + * 获得抄送的流程的分页
  26 + *
25 27 * @param userId 当前登录用户
26 28 * @param pageReqVO 分页请求
27 29 * @return 抄送的分页结果
28 30 */
29   - PageResult<BpmProcessInstanceCopyDO> getMyProcessInstanceCopyPage(Long userId,
30   - BpmProcessInstanceCopyMyPageReqVO pageReqVO);
  31 + PageResult<BpmProcessInstanceCopyDO> getProcessInstanceCopyPage(Long userId,
  32 + BpmProcessInstanceCopyPageReqVO pageReqVO);
  33 +
31 34 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/cc/BpmProcessInstanceCopyServiceImpl.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java
1   -package cn.iocoder.yudao.module.bpm.service.task.cc;
  1 +package cn.iocoder.yudao.module.bpm.service.task;
2 2  
3 3 import cn.hutool.core.util.ObjectUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyCreateReqVO;
6   -import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyMyPageReqVO;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
7 6 import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
8 7 import cn.iocoder.yudao.module.bpm.dal.mysql.cc.BpmProcessInstanceCopyMapper;
9 8 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
10   -import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
11   -import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
  9 +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
12 10 import jakarta.annotation.Resource;
13 11 import lombok.extern.slf4j.Slf4j;
  12 +import org.flowable.engine.repository.ProcessDefinition;
14 13 import org.flowable.engine.runtime.ProcessInstance;
15 14 import org.flowable.task.api.Task;
16 15 import org.springframework.context.annotation.Lazy;
17 16 import org.springframework.stereotype.Service;
18 17 import org.springframework.validation.annotation.Validated;
19 18  
  19 +import java.util.Collection;
  20 +import java.util.List;
  21 +
20 22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  23 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
21 24  
22 25 /**
23 26 * 流程抄送 Service 实现类
... ... @@ -33,38 +36,47 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy
33 36 private BpmProcessInstanceCopyMapper processInstanceCopyMapper;
34 37  
35 38 @Resource
36   - @Lazy
37   - private BpmTaskService bpmTaskService;
  39 + @Lazy // 延迟加载,避免循环依赖
  40 + private BpmTaskService taskService;
  41 +
  42 + @Resource
  43 + @Lazy // 延迟加载,避免循环依赖
  44 + private BpmProcessInstanceService processInstanceService;
38 45 @Resource
39   - @Lazy
40   - private BpmProcessInstanceService bpmProcessInstanceService;
  46 + @Lazy // 延迟加载,避免循环依赖
  47 + private BpmProcessDefinitionService processDefinitionService;
41 48  
42 49 @Override
43   - public void createProcessInstanceCopy(Long userId, BpmProcessInstanceCopyCreateReqVO reqVO) {
  50 + public void createProcessInstanceCopy(Collection<Long> userIds, String taskId) {
44 51 // 1.1 校验任务存在
45   - Task task = bpmTaskService.getTask(reqVO.getTaskId());
  52 + Task task = taskService.getTask(taskId);
46 53 if (ObjectUtil.isNull(task)) {
47 54 throw exception(ErrorCodeConstants.TASK_NOT_EXISTS);
48 55 }
49   - // 1.2 校验流程存在
  56 + // 1.2 校验流程实例存在
50 57 String processInstanceId = task.getProcessInstanceId();
51   - ProcessInstance processInstance = bpmProcessInstanceService.getProcessInstance(processInstanceId);
  58 + ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);
52 59 if (processInstance == null) {
53   - log.warn("[createProcessInstanceCopy][任务({}) 对应的流程不存在]", reqVO.getTaskId());
54 60 throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);
55 61 }
  62 + // 1.3 校验流程定义存在
  63 + ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
  64 + processInstance.getProcessDefinitionId());
  65 + if (processDefinition == null) {
  66 + throw exception(ErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS);
  67 + }
56 68  
57 69 // 2. 创建抄送流程
58   - BpmProcessInstanceCopyDO copy = new BpmProcessInstanceCopyDO()
59   - .setTaskId(reqVO.getTaskId()).setTaskName(task.getName())
60   - .setProcessInstanceId(processInstanceId).setStartUserId(Long.valueOf(processInstance.getStartUserId()))
61   - .setProcessInstanceName(processInstance.getName()).setCategory(processInstance.getProcessDefinitionCategory())
62   - .setReason(reqVO.getReason());
63   - processInstanceCopyMapper.insert(copy);
  70 + List<BpmProcessInstanceCopyDO> copyList = convertList(userIds, userId -> new BpmProcessInstanceCopyDO()
  71 + .setUserId(userId).setStartUserId(Long.valueOf(processInstance.getStartUserId()))
  72 + .setProcessInstanceId(processInstanceId).setProcessInstanceName(processInstance.getName())
  73 + .setCategory(processDefinition.getCategory()).setTaskId(taskId).setTaskName(task.getName()));
  74 + processInstanceCopyMapper.insertBatch(copyList);
64 75 }
65 76  
66 77 @Override
67   - public PageResult<BpmProcessInstanceCopyDO> getMyProcessInstanceCopyPage(Long userId, BpmProcessInstanceCopyMyPageReqVO pageReqVO) {
  78 + public PageResult<BpmProcessInstanceCopyDO> getProcessInstanceCopyPage(Long userId,
  79 + BpmProcessInstanceCopyPageReqVO pageReqVO) {
68 80 return processInstanceCopyMapper.selectPage(userId, pageReqVO);
69 81 }
70 82  
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
... ... @@ -68,10 +68,14 @@ public class BpmTaskServiceImpl implements BpmTaskService {
68 68 private HistoryService historyService;
69 69 @Resource
70 70 private RuntimeService runtimeService;
  71 + @Resource
  72 + private ManagementService managementService;
71 73  
72 74 @Resource
73 75 private BpmProcessInstanceService processInstanceService;
74 76 @Resource
  77 + private BpmProcessInstanceCopyService processInstanceCopyService;
  78 + @Resource
75 79 private BpmModelService bpmModelService;
76 80 @Resource
77 81 private BpmMessageService messageService;
... ... @@ -79,12 +83,12 @@ public class BpmTaskServiceImpl implements BpmTaskService {
79 83 @Resource
80 84 private AdminUserApi adminUserApi;
81 85  
82   - @Resource
83   - private ManagementService managementService;
84   -
85 86 @Override
86 87 public PageResult<Task> getTodoTaskPage(Long userId, BpmTaskPageReqVO pageVO) {
87   - TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(String.valueOf(userId)) // 分配给自己
  88 + TaskQuery taskQuery = taskService.createTaskQuery()
  89 + .taskAssignee(String.valueOf(userId)) // 分配给自己
  90 + .active()
  91 + .includeProcessVariables()
88 92 .orderByTaskCreateTime().desc(); // 创建时间倒序
89 93 if (StrUtil.isNotBlank(pageVO.getName())) {
90 94 taskQuery.taskNameLike("%" + pageVO.getName() + "%");
... ... @@ -103,9 +107,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
103 107  
104 108 @Override
105 109 public PageResult<HistoricTaskInstance> getDoneTaskPage(Long userId, BpmTaskPageReqVO pageVO) {
106   - HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery().finished() // 已完成
107   - .includeTaskLocalVariables()
  110 + HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()
  111 + .finished() // 已完成
108 112 .taskAssignee(String.valueOf(userId)) // 分配给自己
  113 + .includeTaskLocalVariables()
109 114 .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
110 115 if (StrUtil.isNotBlank(pageVO.getName())) {
111 116 taskQuery.taskNameLike("%" + pageVO.getName() + "%");
... ... @@ -155,30 +160,34 @@ public class BpmTaskServiceImpl implements BpmTaskService {
155 160 throw exception(PROCESS_INSTANCE_NOT_EXISTS);
156 161 }
157 162  
  163 + // 2. 抄送用户
  164 + if (CollUtil.isNotEmpty(reqVO.getCopyUserIds())) {
  165 + processInstanceCopyService.createProcessInstanceCopy(reqVO.getCopyUserIds(), reqVO.getId());
  166 + }
  167 +
158 168 // 情况一:被委派的任务,不调用 complete 去完成任务
159 169 if (DelegationState.PENDING.equals(task.getDelegationState())) {
160 170 approveDelegateTask(reqVO, task);
161 171 return;
162 172 }
163 173  
164   - // 情况二:后加签的任务
  174 + // 情况二:审批有【后】加签的任务
165 175 if (BpmTaskAddSignTypeEnum.AFTER.getType().equals(task.getScopeType())) {
166   - // 后加签处理
167 176 approveAfterSignTask(task, reqVO);
168 177 return;
169 178 }
170 179  
171   - // 情况三:自己审批的任务,调用 complete 去完成任务
172   - // 完成任务,审批通过
  180 + // 情况三:审批普通的任务。大多数情况下,都是这样
  181 + // 更新流程任务 status 为审批通过
173 182 updateTaskStatus(task.getId(), BpmProcessInstanceResultEnum.APPROVE.getResult());
  183 + // 添加评论
  184 + taskService.addComment(task.getId(), task.getProcessInstanceId(),
  185 + BpmCommentTypeEnum.APPROVE.getType(), reqVO.getReason());
  186 + // 调用 BPM complete 去完成任务
174 187 taskService.complete(task.getId(), instance.getProcessVariables());
175   -// // 更新任务拓展表为通过
176   -// taskExtMapper.updateByTaskId(
177   -// new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.APPROVE.getResult())
178   -// .setReason(reqVO.getReason()));
  188 +
179 189 // 处理加签任务
180   -// handleParentTask(task);
181   - handleParentTaskNew(task.getParentTaskId());
  190 + handleParentTaskIfSign(task.getParentTaskId());
182 191 }
183 192  
184 193 /**
... ... @@ -209,8 +218,15 @@ public class BpmTaskServiceImpl implements BpmTaskService {
209 218 // new BpmTaskExtDO().setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()));
210 219 }
211 220  
212   - // TODO 芋艿:名字
213   - private void handleParentTaskNew(String parentTaskId) {
  221 + /**
  222 + * 如果父任务是有前后【加签】的任务,如果它【加签】出来的子任务都被处理,需要处理父任务:
  223 + *
  224 + * 1. 如果是【向前】加签,则需要重新激活父任务,让它可以被审批
  225 + * 2. 如果是【向后】加签,则需要完成父任务,让它完成审批
  226 + *
  227 + * @param parentTaskId 父任务编号
  228 + */
  229 + private void handleParentTaskIfSign(String parentTaskId) {
214 230 if (StrUtil.isBlank(parentTaskId)) {
215 231 return;
216 232 }
... ... @@ -227,7 +243,9 @@ public class BpmTaskServiceImpl implements BpmTaskService {
227 243 }
228 244  
229 245 // 2. 子任务已处理完成,清空 scopeType 字段,修改 parentTask 信息,方便后续可以继续向前后向后加签
230   - clearTaskScopeTypeAndSave(parentTask);
  246 + TaskEntityImpl parentTaskImpl = (TaskEntityImpl) parentTask;
  247 + parentTaskImpl.setScopeType(null);
  248 + taskService.saveTask(parentTaskImpl);
231 249  
232 250 // 3.1 情况一:处理向【向前】加签
233 251 if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(scopeType)) {
... ... @@ -243,18 +261,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
243 261 }
244 262  
245 263 // 4. 递归处理父任务
246   - handleParentTaskNew(parentTask.getParentTaskId());
247   - }
248   -
249   - /**
250   - * 清空 scopeType 字段,用于任务没有子任务时使用该方法,方便任务可以再次被不同的方式加签
251   - *
252   - * @param task 需要被清空的任务
253   - */
254   - private void clearTaskScopeTypeAndSave(Task task) {
255   - TaskEntityImpl taskImpl = (TaskEntityImpl) task;
256   - taskImpl.setScopeType(null);
257   - taskService.saveTask(task);
  264 + handleParentTaskIfSign(parentTask.getParentTaskId());
258 265 }
259 266  
260 267 /**
... ... @@ -797,7 +804,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
797 804 BpmCommentTypeEnum.SUB_SIGN.getType().toString(), comment);
798 805  
799 806 // 4. 处理当前任务的父任务
800   - handleParentTaskNew(task.getParentTaskId());
  807 + handleParentTaskIfSign(task.getParentTaskId());
801 808 }
802 809  
803 810 /**
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/cc/dto/BpmDelegateExecutionDTO.java deleted
1   -package cn.iocoder.yudao.module.bpm.service.task.cc.dto;
2   -
3   -import org.flowable.bpmn.model.FlowElement;
4   -import org.flowable.bpmn.model.FlowableListener;
5   -import org.flowable.engine.delegate.DelegateExecution;
6   -import org.flowable.engine.delegate.ReadOnlyDelegateExecution;
7   -import org.flowable.variable.api.persistence.entity.VariableInstance;
8   -
9   -import java.util.Collection;
10   -import java.util.List;
11   -import java.util.Map;
12   -import java.util.Set;
13   -
14   -/**
15   - * 仅为了传输processInstanceId
16   - */
17   -public class BpmDelegateExecutionDTO implements DelegateExecution {
18   -
19   - public BpmDelegateExecutionDTO(String getProcessInstanceId) {
20   - this.getProcessInstanceId = getProcessInstanceId;
21   - }
22   -
23   - private final String getProcessInstanceId;
24   -
25   - @Override
26   - public String getId() {
27   - return null;
28   - }
29   -
30   - @Override
31   - public String getProcessInstanceId() {
32   - return null;
33   - }
34   -
35   - @Override
36   - public String getRootProcessInstanceId() {
37   - return null;
38   - }
39   -
40   - @Override
41   - public String getEventName() {
42   - return null;
43   - }
44   -
45   - @Override
46   - public void setEventName(String eventName) {
47   -
48   - }
49   -
50   - @Override
51   - public String getProcessInstanceBusinessKey() {
52   - return null;
53   - }
54   -
55   - @Override
56   - public String getProcessInstanceBusinessStatus() {
57   - return null;
58   - }
59   -
60   - @Override
61   - public String getProcessDefinitionId() {
62   - return null;
63   - }
64   -
65   - @Override
66   - public String getPropagatedStageInstanceId() {
67   - return null;
68   - }
69   -
70   - @Override
71   - public String getParentId() {
72   - return null;
73   - }
74   -
75   - @Override
76   - public String getSuperExecutionId() {
77   - return null;
78   - }
79   -
80   - @Override
81   - public String getCurrentActivityId() {
82   - return null;
83   - }
84   -
85   - @Override
86   - public String getTenantId() {
87   - return null;
88   - }
89   -
90   - @Override
91   - public FlowElement getCurrentFlowElement() {
92   - return null;
93   - }
94   -
95   - @Override
96   - public void setCurrentFlowElement(FlowElement flowElement) {
97   -
98   - }
99   -
100   - @Override
101   - public FlowableListener getCurrentFlowableListener() {
102   - return null;
103   - }
104   -
105   - @Override
106   - public void setCurrentFlowableListener(FlowableListener currentListener) {
107   -
108   - }
109   -
110   - @Override
111   - public ReadOnlyDelegateExecution snapshotReadOnly() {
112   - return null;
113   - }
114   -
115   - @Override
116   - public DelegateExecution getParent() {
117   - return null;
118   - }
119   -
120   - @Override
121   - public List<? extends DelegateExecution> getExecutions() {
122   - return null;
123   - }
124   -
125   - @Override
126   - public void setActive(boolean isActive) {
127   -
128   - }
129   -
130   - @Override
131   - public boolean isActive() {
132   - return false;
133   - }
134   -
135   - @Override
136   - public boolean isEnded() {
137   - return false;
138   - }
139   -
140   - @Override
141   - public void setConcurrent(boolean isConcurrent) {
142   -
143   - }
144   -
145   - @Override
146   - public boolean isConcurrent() {
147   - return false;
148   - }
149   -
150   - @Override
151   - public boolean isProcessInstanceType() {
152   - return false;
153   - }
154   -
155   - @Override
156   - public void inactivate() {
157   -
158   - }
159   -
160   - @Override
161   - public boolean isScope() {
162   - return false;
163   - }
164   -
165   - @Override
166   - public void setScope(boolean isScope) {
167   -
168   - }
169   -
170   - @Override
171   - public boolean isMultiInstanceRoot() {
172   - return false;
173   - }
174   -
175   - @Override
176   - public void setMultiInstanceRoot(boolean isMultiInstanceRoot) {
177   -
178   - }
179   -
180   - @Override
181   - public Map<String, Object> getVariables() {
182   - return null;
183   - }
184   -
185   - @Override
186   - public Map<String, VariableInstance> getVariableInstances() {
187   - return null;
188   - }
189   -
190   - @Override
191   - public Map<String, Object> getVariables(Collection<String> collection) {
192   - return null;
193   - }
194   -
195   - @Override
196   - public Map<String, VariableInstance> getVariableInstances(Collection<String> collection) {
197   - return null;
198   - }
199   -
200   - @Override
201   - public Map<String, Object> getVariables(Collection<String> collection, boolean b) {
202   - return null;
203   - }
204   -
205   - @Override
206   - public Map<String, VariableInstance> getVariableInstances(Collection<String> collection, boolean b) {
207   - return null;
208   - }
209   -
210   - @Override
211   - public Map<String, Object> getVariablesLocal() {
212   - return null;
213   - }
214   -
215   - @Override
216   - public Map<String, VariableInstance> getVariableInstancesLocal() {
217   - return null;
218   - }
219   -
220   - @Override
221   - public Map<String, Object> getVariablesLocal(Collection<String> collection) {
222   - return null;
223   - }
224   -
225   - @Override
226   - public Map<String, VariableInstance> getVariableInstancesLocal(Collection<String> collection) {
227   - return null;
228   - }
229   -
230   - @Override
231   - public Map<String, Object> getVariablesLocal(Collection<String> collection, boolean b) {
232   - return null;
233   - }
234   -
235   - @Override
236   - public Map<String, VariableInstance> getVariableInstancesLocal(Collection<String> collection, boolean b) {
237   - return null;
238   - }
239   -
240   - @Override
241   - public Object getVariable(String s) {
242   - return null;
243   - }
244   -
245   - @Override
246   - public VariableInstance getVariableInstance(String s) {
247   - return null;
248   - }
249   -
250   - @Override
251   - public Object getVariable(String s, boolean b) {
252   - return null;
253   - }
254   -
255   - @Override
256   - public VariableInstance getVariableInstance(String s, boolean b) {
257   - return null;
258   - }
259   -
260   - @Override
261   - public Object getVariableLocal(String s) {
262   - return null;
263   - }
264   -
265   - @Override
266   - public VariableInstance getVariableInstanceLocal(String s) {
267   - return null;
268   - }
269   -
270   - @Override
271   - public Object getVariableLocal(String s, boolean b) {
272   - return null;
273   - }
274   -
275   - @Override
276   - public VariableInstance getVariableInstanceLocal(String s, boolean b) {
277   - return null;
278   - }
279   -
280   - @Override
281   - public <T> T getVariable(String s, Class<T> aClass) {
282   - return null;
283   - }
284   -
285   - @Override
286   - public <T> T getVariableLocal(String s, Class<T> aClass) {
287   - return null;
288   - }
289   -
290   - @Override
291   - public Set<String> getVariableNames() {
292   - return null;
293   - }
294   -
295   - @Override
296   - public Set<String> getVariableNamesLocal() {
297   - return null;
298   - }
299   -
300   - @Override
301   - public void setVariable(String s, Object o) {
302   -
303   - }
304   -
305   - @Override
306   - public void setVariable(String s, Object o, boolean b) {
307   -
308   - }
309   -
310   - @Override
311   - public Object setVariableLocal(String s, Object o) {
312   - return null;
313   - }
314   -
315   - @Override
316   - public Object setVariableLocal(String s, Object o, boolean b) {
317   - return null;
318   - }
319   -
320   - @Override
321   - public void setVariables(Map<String, ?> map) {
322   -
323   - }
324   -
325   - @Override
326   - public void setVariablesLocal(Map<String, ?> map) {
327   -
328   - }
329   -
330   - @Override
331   - public boolean hasVariables() {
332   - return false;
333   - }
334   -
335   - @Override
336   - public boolean hasVariablesLocal() {
337   - return false;
338   - }
339   -
340   - @Override
341   - public boolean hasVariable(String s) {
342   - return false;
343   - }
344   -
345   - @Override
346   - public boolean hasVariableLocal(String s) {
347   - return false;
348   - }
349   -
350   - @Override
351   - public void removeVariable(String s) {
352   -
353   - }
354   -
355   - @Override
356   - public void removeVariableLocal(String s) {
357   -
358   - }
359   -
360   - @Override
361   - public void removeVariables(Collection<String> collection) {
362   -
363   - }
364   -
365   - @Override
366   - public void removeVariablesLocal(Collection<String> collection) {
367   -
368   - }
369   -
370   - @Override
371   - public void removeVariables() {
372   -
373   - }
374   -
375   - @Override
376   - public void removeVariablesLocal() {
377   -
378   - }
379   -
380   - @Override
381   - public void setTransientVariable(String s, Object o) {
382   -
383   - }
384   -
385   - @Override
386   - public void setTransientVariableLocal(String s, Object o) {
387   -
388   - }
389   -
390   - @Override
391   - public void setTransientVariables(Map<String, Object> map) {
392   -
393   - }
394   -
395   - @Override
396   - public Object getTransientVariable(String s) {
397   - return null;
398   - }
399   -
400   - @Override
401   - public Map<String, Object> getTransientVariables() {
402   - return null;
403   - }
404   -
405   - @Override
406   - public void setTransientVariablesLocal(Map<String, Object> map) {
407   -
408   - }
409   -
410   - @Override
411   - public Object getTransientVariableLocal(String s) {
412   - return null;
413   - }
414   -
415   - @Override
416   - public Map<String, Object> getTransientVariablesLocal() {
417   - return null;
418   - }
419   -
420   - @Override
421   - public void removeTransientVariableLocal(String s) {
422   -
423   - }
424   -
425   - @Override
426   - public void removeTransientVariable(String s) {
427   -
428   - }
429   -
430   - @Override
431   - public void removeTransientVariables() {
432   -
433   - }
434   -
435   - @Override
436   - public void removeTransientVariablesLocal() {
437   -
438   - }
439   -}