mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-19 03:30:06 +08:00
feat: 【工作流】--加减签review修改
This commit is contained in:
parent
52ebcaaad7
commit
aca65a66b5
@ -3,11 +3,13 @@ package cn.iocoder.yudao.framework.common.util.collection;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
@ -267,4 +269,19 @@ public class CollectionUtils {
|
|||||||
return deptId == null ? Collections.emptyList() : Collections.singleton(deptId);
|
return deptId == null ? Collections.emptyList() : Collections.singleton(deptId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T, U> List<U> convertListByMultiAttr(Collection<T> from,
|
||||||
|
Function<T, ? extends Stream<? extends U>> func) {
|
||||||
|
if (CollUtil.isEmpty(from)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, U> Set<U> convertSetByMultiAttr(Collection<T> from,
|
||||||
|
Function<T, ? extends Stream<? extends U>> func) {
|
||||||
|
if (CollUtil.isEmpty(from)) {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,13 @@ public enum BpmCommentTypeEnum {
|
|||||||
* 操作类型
|
* 操作类型
|
||||||
*/
|
*/
|
||||||
private final Integer type;
|
private final Integer type;
|
||||||
// TODO @海:desc 可以改成 name;相当于操作名;
|
|
||||||
/**
|
/**
|
||||||
* 操作名字
|
* 操作名字
|
||||||
*/
|
*/
|
||||||
private final String desc;
|
private final String name;
|
||||||
// TODO @海:直接改成 comment 哈;简单一点;
|
|
||||||
/**
|
/**
|
||||||
* 操作描述
|
* 操作描述
|
||||||
*/
|
*/
|
||||||
private final String templateComment;
|
private final String comment;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,13 +30,13 @@ public enum BpmProcessInstanceResultEnum {
|
|||||||
* 相当于是 通过 APPROVE 的特殊状态
|
* 相当于是 通过 APPROVE 的特殊状态
|
||||||
* 例如:A审批, A 后加签了 B,并且审批通过了任务,但是 B 还未审批,则当前任务状态为“待后加签任务完成”
|
* 例如:A审批, A 后加签了 B,并且审批通过了任务,但是 B 还未审批,则当前任务状态为“待后加签任务完成”
|
||||||
*/
|
*/
|
||||||
ADD_SIGN_AFTER(7, "待后加签任务完成"),
|
SIGN_AFTER(7, "待后加签任务完成"),
|
||||||
/**
|
/**
|
||||||
* 【加签】源任务未审批,但是向前加签了,所以源任务状态变为“待前加签任务完成”
|
* 【加签】源任务未审批,但是向前加签了,所以源任务状态变为“待前加签任务完成”
|
||||||
* 相当于是 处理中 PROCESS 的特殊状态
|
* 相当于是 处理中 PROCESS 的特殊状态
|
||||||
* 例如:A 审批, A 前加签了 B,B 还未审核
|
* 例如:A 审批, A 前加签了 B,B 还未审核
|
||||||
*/
|
*/
|
||||||
ADD_SIGN_BEFORE(8, "待前加签任务完成"),
|
SIGN_BEFORE(8, "待前加签任务完成"),
|
||||||
/**
|
/**
|
||||||
* 【加签】后加签任务被创建时的初始状态
|
* 【加签】后加签任务被创建时的初始状态
|
||||||
* 相当于是 处理中 PROCESS 的特殊状态
|
* 相当于是 处理中 PROCESS 的特殊状态
|
||||||
@ -71,7 +71,7 @@ public enum BpmProcessInstanceResultEnum {
|
|||||||
public static boolean isEndResult(Integer result) {
|
public static boolean isEndResult(Integer result) {
|
||||||
return ObjectUtils.equalsAny(result, APPROVE.getResult(), REJECT.getResult(),
|
return ObjectUtils.equalsAny(result, APPROVE.getResult(), REJECT.getResult(),
|
||||||
CANCEL.getResult(), BACK.getResult(),
|
CANCEL.getResult(), BACK.getResult(),
|
||||||
ADD_SIGN_AFTER.getResult());
|
SIGN_AFTER.getResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,8 +74,7 @@ public class BpmTaskController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @海:/return-list,不用带 get;
|
@GetMapping("/return-list")
|
||||||
@GetMapping("/get-return-list")
|
|
||||||
@Operation(summary = "获取所有可回退的节点", description = "用于【流程详情】的【回退】按钮")
|
@Operation(summary = "获取所有可回退的节点", description = "用于【流程详情】的【回退】按钮")
|
||||||
@Parameter(name = "taskId", description = "当前任务ID", required = true)
|
@Parameter(name = "taskId", description = "当前任务ID", required = true)
|
||||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||||
@ -99,8 +98,7 @@ public class BpmTaskController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @海:create-sign?创建加签任务;
|
@PutMapping("/create-sign")
|
||||||
@PutMapping("/add-sign")
|
|
||||||
@Operation(summary = "加签", description = "before 前加签,after 后加签")
|
@Operation(summary = "加签", description = "before 前加签,after 后加签")
|
||||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||||
public CommonResult<Boolean> addSignTask(@Valid @RequestBody BpmTaskAddSignReqVO reqVO) {
|
public CommonResult<Boolean> addSignTask(@Valid @RequestBody BpmTaskAddSignReqVO reqVO) {
|
||||||
@ -108,8 +106,7 @@ public class BpmTaskController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @海:delete-sign?删除加签任务;然后 @DeleteMapping;这样感觉可以保持统一;
|
@DeleteMapping("/delete-sign")
|
||||||
@PutMapping("/sub-sign")
|
|
||||||
@Operation(summary = "减签")
|
@Operation(summary = "减签")
|
||||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||||
public CommonResult<Boolean> subSignTask(@Valid @RequestBody BpmTaskSubSignReqVO reqVO) {
|
public CommonResult<Boolean> subSignTask(@Valid @RequestBody BpmTaskSubSignReqVO reqVO) {
|
||||||
@ -117,13 +114,12 @@ public class BpmTaskController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @海:/children-list,不用带 task 和 get;
|
@GetMapping("children-list")
|
||||||
// TODO @海:taskId 是不是改成 parentId?另外,它的 swagger 注解也加下哈;
|
|
||||||
@GetMapping("/get-children-task-list")
|
|
||||||
@Operation(summary = "获取能被减签的任务")
|
@Operation(summary = "获取能被减签的任务")
|
||||||
|
@Parameter(name = "parentId", description = "父级任务ID", required = true)
|
||||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||||
public CommonResult<List<BpmTaskSubSignRespVO>> getChildrenTaskList(@RequestParam("taskId") String taskId) {
|
public CommonResult<List<BpmTaskSubSignRespVO>> getChildrenTaskList(@RequestParam("parentId") String parentId) {
|
||||||
return success(taskService.getChildrenTaskList(taskId));
|
return success(taskService.getChildrenTaskList(parentId));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@ package cn.iocoder.yudao.module.bpm.convert.task;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
||||||
@ -168,20 +170,15 @@ public interface BpmTaskConvert {
|
|||||||
Map<Long, AdminUserRespDTO> userMap,
|
Map<Long, AdminUserRespDTO> userMap,
|
||||||
Map<String, Task> idTaskMap){
|
Map<String, Task> idTaskMap){
|
||||||
return CollectionUtils.convertList(bpmTaskExtDOList, task -> {
|
return CollectionUtils.convertList(bpmTaskExtDOList, task -> {
|
||||||
// TODO @海:setId、name,可以链式调用
|
BpmTaskSubSignRespVO bpmTaskSubSignRespVO = new BpmTaskSubSignRespVO()
|
||||||
BpmTaskSubSignRespVO bpmTaskSubSignRespVO = new BpmTaskSubSignRespVO();
|
.setName(task.getName())
|
||||||
bpmTaskSubSignRespVO.setName(task.getName());
|
.setId(task.getTaskId());
|
||||||
bpmTaskSubSignRespVO.setId(task.getTaskId());
|
|
||||||
Task sourceTask = idTaskMap.get(task.getTaskId());
|
|
||||||
// TODO @海:下面这行注释,应该放到 idTaskMap.get(task.getTaskId()) 上面;原因是,应该注释之后,下面的逻辑是个整体;
|
|
||||||
// 后加签任务不会直接设置 assignee ,所以不存在 assignee 的情况,则去取 owner
|
// 后加签任务不会直接设置 assignee ,所以不存在 assignee 的情况,则去取 owner
|
||||||
// TODO @海:可以使用 ObjUtil.default 方法
|
Task sourceTask = idTaskMap.get(task.getTaskId());
|
||||||
String assignee = StrUtil.isNotEmpty(sourceTask.getAssignee()) ? sourceTask.getAssignee() : sourceTask.getOwner();
|
String assignee = ObjectUtil.defaultIfBlank(sourceTask.getOwner(),sourceTask.getAssignee());
|
||||||
// TODO @海:这里可以使用 MapUtils.findAndThen 写起来更简单一点;
|
MapUtils.findAndThen(userMap,NumberUtils.parseLong(assignee),
|
||||||
AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(assignee));
|
assignUser-> bpmTaskSubSignRespVO.setAssigneeUser(convert3(assignUser)));
|
||||||
if (assignUser != null) {
|
|
||||||
bpmTaskSubSignRespVO.setAssigneeUser(convert3(assignUser));
|
|
||||||
}
|
|
||||||
return bpmTaskSubSignRespVO;
|
return bpmTaskSubSignRespVO;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -176,9 +176,9 @@ public interface BpmTaskService {
|
|||||||
/**
|
/**
|
||||||
* 获取指定任务的子任务和审批人信息
|
* 获取指定任务的子任务和审批人信息
|
||||||
*
|
*
|
||||||
* @param taskId 指定任务ID
|
* @param parentId 指定任务ID
|
||||||
* @return 子任务列表
|
* @return 子任务列表
|
||||||
*/
|
*/
|
||||||
List<BpmTaskSubSignRespVO> getChildrenTaskList(String taskId);
|
List<BpmTaskSubSignRespVO> getChildrenTaskList(String parentId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ import javax.annotation.Resource;
|
|||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
@ -240,11 +239,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
handleParentTask(task);
|
handleParentTask(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @海:我们是不是加签统一认为是 SIGN,这样 SIGN_AFTER 就是后置;SIGN_BEFORE 就是前置;
|
|
||||||
/**
|
/**
|
||||||
* 审批通过存在“后加签”的任务。
|
* 审批通过存在“后加签”的任务。
|
||||||
* <p>
|
* <p>
|
||||||
* 注意:该任务不能马上完成,需要一个中间状态(ADD_SIGN_AFTER),并激活剩余所有子任务(PROCESS)为可审批处理
|
* 注意:该任务不能马上完成,需要一个中间状态(SIGN_AFTER),并激活剩余所有子任务(PROCESS)为可审批处理
|
||||||
*
|
*
|
||||||
* @param task 当前任务
|
* @param task 当前任务
|
||||||
* @param reqVO 前端请求参数
|
* @param reqVO 前端请求参数
|
||||||
@ -252,7 +251,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
private void approveAfterSignTask(Task task, BpmTaskApproveReqVO reqVO) {
|
private void approveAfterSignTask(Task task, BpmTaskApproveReqVO reqVO) {
|
||||||
// 1. 有向后加签,则该任务状态临时设置为 ADD_SIGN_AFTER 状态
|
// 1. 有向后加签,则该任务状态临时设置为 ADD_SIGN_AFTER 状态
|
||||||
taskExtMapper.updateByTaskId(
|
taskExtMapper.updateByTaskId(
|
||||||
new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.ADD_SIGN_AFTER.getResult())
|
new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.SIGN_AFTER.getResult())
|
||||||
.setReason(reqVO.getReason()).setEndTime(LocalDateTime.now()));
|
.setReason(reqVO.getReason()).setEndTime(LocalDateTime.now()));
|
||||||
|
|
||||||
// 2. 激活子任务
|
// 2. 激活子任务
|
||||||
@ -275,50 +274,50 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
if (StrUtil.isBlank(parentTaskId)) {
|
if (StrUtil.isBlank(parentTaskId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO @海洋:279 这个判断就不需要啦;括号层级少一级噢;
|
// 1. 判断当前任务的父任务是否还有子任务
|
||||||
if (StrUtil.isNotBlank(parentTaskId)) {
|
Long childrenTaskCount = getChildrenTaskCount(parentTaskId);
|
||||||
// 1. 判断当前任务的父任务是否还有子任务
|
if (childrenTaskCount > 0) {
|
||||||
Long childrenTaskCount = getChildrenTaskCount(parentTaskId);
|
return;
|
||||||
if (childrenTaskCount > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// TODO @海:如果非向前、向后加签,就直接 return 掉;就是把 3. 那判断做次提前;万一有别的父子任务经过这个逻辑,其实我们是不处理的,对哇?
|
|
||||||
// 2. 获取父任务
|
|
||||||
Task parentTask = validateTaskExist(parentTaskId);
|
|
||||||
|
|
||||||
// 3.1 情况一:处理向前加签
|
|
||||||
String scopeType = parentTask.getScopeType();
|
|
||||||
if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(scopeType)) {
|
|
||||||
// 3.1.1 如果是向前加签的任务,则调用 resolveTask 指派父任务,将 owner 重新赋值给父任务的 assignee,这样它就可以被审批
|
|
||||||
taskService.resolveTask(parentTaskId);
|
|
||||||
// 3.1.2 更新任务拓展表为处理中
|
|
||||||
taskExtMapper.updateByTaskId(
|
|
||||||
new BpmTaskExtDO().setTaskId(parentTask.getId()).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()));
|
|
||||||
} else if (BpmTaskAddSignTypeEnum.AFTER.getType().equals(scopeType)) {
|
|
||||||
// 3.2 情况二:处理向后加签
|
|
||||||
handleAfterSign(parentTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 子任务已处理完成,清空 scopeType 字段,修改 parentTask 信息,方便后续可以继续向前后向后加签
|
|
||||||
// 再查询一次的原因是避免报错:Task was updated by another transaction concurrently
|
|
||||||
// 因为前面处理后可能会导致 parentTask rev 字段被修改,需要重新获取最新的
|
|
||||||
parentTask = getTask(parentTaskId);
|
|
||||||
if (parentTask == null) {
|
|
||||||
// 为空的情况是:已经通过 handleAfterSign 方法将任务完成了,所以 ru_task 表会查不到数据
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
clearTaskScopeTypeAndSave(parentTask);
|
|
||||||
}
|
}
|
||||||
|
// 2. 获取父任务
|
||||||
|
Task parentTask = validateTaskExist(parentTaskId);
|
||||||
|
|
||||||
|
// 3. 处理加签情况
|
||||||
|
String scopeType = parentTask.getScopeType();
|
||||||
|
if(!validateSignType(scopeType)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 3.1 情况一:处理向前加签
|
||||||
|
if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(scopeType)) {
|
||||||
|
// 3.1.1 如果是向前加签的任务,则调用 resolveTask 指派父任务,将 owner 重新赋值给父任务的 assignee,这样它就可以被审批
|
||||||
|
taskService.resolveTask(parentTaskId);
|
||||||
|
// 3.1.2 更新任务拓展表为处理中
|
||||||
|
taskExtMapper.updateByTaskId(
|
||||||
|
new BpmTaskExtDO().setTaskId(parentTask.getId()).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()));
|
||||||
|
} else if (BpmTaskAddSignTypeEnum.AFTER.getType().equals(scopeType)) {
|
||||||
|
// 3.2 情况二:处理向后加签
|
||||||
|
handleParentTaskForAfterSign(parentTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 子任务已处理完成,清空 scopeType 字段,修改 parentTask 信息,方便后续可以继续向前后向后加签
|
||||||
|
// 再查询一次的原因是避免报错:Task was updated by another transaction concurrently
|
||||||
|
// 因为前面处理后可能会导致 parentTask rev 字段被修改,需要重新获取最新的
|
||||||
|
parentTask = getTask(parentTaskId);
|
||||||
|
if (parentTask == null) {
|
||||||
|
// 为空的情况是:已经通过 handleAfterSign 方法将任务完成了,所以 ru_task 表会查不到数据
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearTaskScopeTypeAndSave(parentTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @海:可以把这个方法名,改成 handleParentTaskForAfterSign。= = 虽然这个名字也有点丑,但是目的是体现出它是 handleParentTask 的一种衍生
|
|
||||||
/**
|
/**
|
||||||
* 处理后加签任务
|
* 处理后加签任务
|
||||||
*
|
*
|
||||||
* @param parentTask 当前审批任务的父任务
|
* @param parentTask 当前审批任务的父任务
|
||||||
*/
|
*/
|
||||||
// TODO @海:这个逻辑,怎么感觉可以是 parentTask 的 parent,再去调用 handleParentTask 方法;可以微信聊下;
|
// TODO @海:这个逻辑,怎么感觉可以是 parentTask 的 parent,再去调用 handleParentTask 方法;可以微信聊下;
|
||||||
private void handleAfterSign(Task parentTask) {
|
private void handleParentTaskForAfterSign(Task parentTask) {
|
||||||
String parentTaskId = parentTask.getId();
|
String parentTaskId = parentTask.getId();
|
||||||
// 1. 更新 parentTask 的任务拓展表为通过,并调用 complete 完成自己
|
// 1. 更新 parentTask 的任务拓展表为通过,并调用 complete 完成自己
|
||||||
BpmTaskExtDO currentTaskExt = taskExtMapper.selectByTaskId(parentTask.getId());
|
BpmTaskExtDO currentTaskExt = taskExtMapper.selectByTaskId(parentTask.getId());
|
||||||
@ -363,7 +362,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 3.2 没有子任务,判断当前任务状态是否为 ADD_SIGN_BEFORE 待前加签任务完成
|
// 3.2 没有子任务,判断当前任务状态是否为 ADD_SIGN_BEFORE 待前加签任务完成
|
||||||
if (BpmProcessInstanceResultEnum.ADD_SIGN_BEFORE.getResult().equals(parentTaskExt.getResult())) {
|
if (BpmProcessInstanceResultEnum.SIGN_BEFORE.getResult().equals(parentTaskExt.getResult())) {
|
||||||
// 3.3 需要修改该任务状态为处理中
|
// 3.3 需要修改该任务状态为处理中
|
||||||
taskService.resolveTask(parentTaskExt.getTaskId());
|
taskService.resolveTask(parentTaskExt.getTaskId());
|
||||||
parentTaskExt.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
parentTaskExt.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
||||||
@ -731,7 +730,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
// 2.3 更新扩展表状态
|
// 2.3 更新扩展表状态
|
||||||
taskExtMapper.updateByTaskId(
|
taskExtMapper.updateByTaskId(
|
||||||
new BpmTaskExtDO().setTaskId(taskEntity.getId())
|
new BpmTaskExtDO().setTaskId(taskEntity.getId())
|
||||||
.setResult(BpmProcessInstanceResultEnum.ADD_SIGN_BEFORE.getResult())
|
.setResult(BpmProcessInstanceResultEnum.SIGN_BEFORE.getResult())
|
||||||
.setReason(reqVO.getReason()));
|
.setReason(reqVO.getReason()));
|
||||||
}
|
}
|
||||||
// 2.4 记录加签方式,完成任务时需要用到判断
|
// 2.4 记录加签方式,完成任务时需要用到判断
|
||||||
@ -740,11 +739,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
taskService.saveTask(taskEntity);
|
taskService.saveTask(taskEntity);
|
||||||
|
|
||||||
// 3. 创建加签任务
|
// 3. 创建加签任务
|
||||||
createAddSignChildrenTasks(convertList(reqVO.getUserIdList(), String::valueOf), taskEntity);
|
createSignTask(convertList(reqVO.getUserIdList(), String::valueOf), taskEntity);
|
||||||
|
|
||||||
// 4. 记录加签 comment,拼接结果为: [当前用户]向前加签/向后加签给了[多个用户],理由为:reason
|
// 4. 记录加签 comment,拼接结果为: [当前用户]向前加签/向后加签给了[多个用户],理由为:reason
|
||||||
AdminUserRespDTO currentUser = adminUserApi.getUser(userId);
|
AdminUserRespDTO currentUser = adminUserApi.getUser(userId);
|
||||||
String comment = StrUtil.format(BpmCommentTypeEnum.ADD_SIGN.getTemplateComment(), currentUser.getNickname(),
|
String comment = StrUtil.format(BpmCommentTypeEnum.ADD_SIGN.getComment(), currentUser.getNickname(),
|
||||||
BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()), String.join(",", convertList(userList, AdminUserRespDTO::getNickname)), reqVO.getReason());
|
BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()), String.join(",", convertList(userList, AdminUserRespDTO::getNickname)), reqVO.getReason());
|
||||||
taskService.addComment(reqVO.getId(), taskEntity.getProcessInstanceId(),
|
taskService.addComment(reqVO.getId(), taskEntity.getProcessInstanceId(),
|
||||||
BpmCommentTypeEnum.ADD_SIGN.getType().toString(), comment);
|
BpmCommentTypeEnum.ADD_SIGN.getType().toString(), comment);
|
||||||
@ -783,14 +782,13 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
return taskEntity;
|
return taskEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @海:方法名,要不改成 createSignTask;
|
|
||||||
/**
|
/**
|
||||||
* 创建加签子任务
|
* 创建加签子任务
|
||||||
*
|
*
|
||||||
* @param addSingUserIdList 被加签的用户 ID
|
* @param addSingUserIdList 被加签的用户 ID
|
||||||
* @param taskEntity 被加签的任务
|
* @param taskEntity 被加签的任务
|
||||||
*/
|
*/
|
||||||
private void createAddSignChildrenTasks(List<String> addSingUserIdList, TaskEntityImpl taskEntity) {
|
private void createSignTask(List<String> addSingUserIdList, TaskEntityImpl taskEntity) {
|
||||||
if (CollUtil.isEmpty(addSingUserIdList)) {
|
if (CollUtil.isEmpty(addSingUserIdList)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -799,18 +797,17 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
if (StrUtil.isBlank(addSignId)) {
|
if (StrUtil.isBlank(addSignId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
createChildrenTask(taskEntity, addSignId);
|
createSignTask(taskEntity, addSignId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @海:注释要不改成,创建加签子任务;然后方法名,就是 createSignTask;因为它还是在创建加签任务,目前哈;
|
|
||||||
/**
|
/**
|
||||||
* 创建子任务
|
* 创建加签子任务
|
||||||
*
|
*
|
||||||
* @param parentTask 父任务
|
* @param parentTask 父任务
|
||||||
* @param assignee 子任务的执行人
|
* @param assignee 子任务的执行人
|
||||||
*/
|
*/
|
||||||
private void createChildrenTask(TaskEntityImpl parentTask, String assignee) {
|
private void createSignTask(TaskEntityImpl parentTask, String assignee) {
|
||||||
// 1. 生成子任务
|
// 1. 生成子任务
|
||||||
TaskEntityImpl task = (TaskEntityImpl) taskService.newTask(IdUtil.fastSimpleUUID());
|
TaskEntityImpl task = (TaskEntityImpl) taskService.newTask(IdUtil.fastSimpleUUID());
|
||||||
task = BpmTaskConvert.INSTANCE.convert(task, parentTask);
|
task = BpmTaskConvert.INSTANCE.convert(task, parentTask);
|
||||||
@ -832,8 +829,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
public void subSignTask(Long userId, BpmTaskSubSignReqVO reqVO) {
|
public void subSignTask(Long userId, BpmTaskSubSignReqVO reqVO) {
|
||||||
// 1.1 校验 task 可以被减签
|
// 1.1 校验 task 可以被减签
|
||||||
Task task = validateSubSign(reqVO.getId());
|
Task task = validateSubSign(reqVO.getId());
|
||||||
// TODO @海:adminUserApi.getUser(userId) 是不是应该放到 3. 那;
|
|
||||||
AdminUserRespDTO user = adminUserApi.getUser(userId);
|
|
||||||
// 1.2 校验取消人存在
|
// 1.2 校验取消人存在
|
||||||
AdminUserRespDTO cancelUser = null;
|
AdminUserRespDTO cancelUser = null;
|
||||||
if (StrUtil.isNotBlank(task.getAssignee())) {
|
if (StrUtil.isNotBlank(task.getAssignee())) {
|
||||||
@ -844,20 +839,22 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
}
|
}
|
||||||
Assert.notNull(cancelUser, "任务中没有所有者和审批人,数据错误");
|
Assert.notNull(cancelUser, "任务中没有所有者和审批人,数据错误");
|
||||||
|
|
||||||
// TODO @海:1. 和 2. 可以写一行注释;其实就是删除任务,和它的子任务;本质上,1. 和 2. 还有 3. 是一块逻辑,写成 1.1 1.2 1.3 会更易懂
|
// 2. 删除任务和对应子任务
|
||||||
// 1. 获取所有需要删除的任务 ID ,包含当前任务和所有子任务
|
// 2.1 获取所有需要删除的任务 ID ,包含当前任务和所有子任务
|
||||||
List<String> allTaskIdList = getAllChildTaskIds(task.getId());
|
List<String> allTaskIdList = getAllChildTaskIds(task.getId());
|
||||||
// 2. 删除任务和所有子任务
|
// 2.2 删除任务和所有子任务
|
||||||
taskService.deleteTasks(allTaskIdList);
|
taskService.deleteTasks(allTaskIdList);
|
||||||
// 3. 修改扩展表状态为取消
|
// 2.3 修改扩展表状态为取消
|
||||||
|
AdminUserRespDTO user = adminUserApi.getUser(userId);
|
||||||
taskExtMapper.updateBatchByTaskIdList(allTaskIdList, new BpmTaskExtDO().setResult(BpmProcessInstanceResultEnum.CANCEL.getResult())
|
taskExtMapper.updateBatchByTaskIdList(allTaskIdList, new BpmTaskExtDO().setResult(BpmProcessInstanceResultEnum.CANCEL.getResult())
|
||||||
.setReason(StrUtil.format("由于{}操作[减签],任务被取消", user.getNickname())));
|
.setReason(StrUtil.format("由于{}操作[减签],任务被取消", user.getNickname())));
|
||||||
|
|
||||||
// 4. 记录日志到父任务中。先记录日志是因为,通过 handleParentTask 方法之后,任务可能被完成了,并且不存在了,会报异常,所以先记录
|
// 3. 记录日志到父任务中。先记录日志是因为,通过 handleParentTask 方法之后,任务可能被完成了,并且不存在了,会报异常,所以先记录
|
||||||
String comment = StrUtil.format(BpmCommentTypeEnum.SUB_SIGN.getTemplateComment(), user.getNickname(), cancelUser.getNickname());
|
String comment = StrUtil.format(BpmCommentTypeEnum.SUB_SIGN.getComment(), user.getNickname(), cancelUser.getNickname());
|
||||||
taskService.addComment(task.getParentTaskId(), task.getProcessInstanceId(),
|
taskService.addComment(task.getParentTaskId(), task.getProcessInstanceId(),
|
||||||
BpmCommentTypeEnum.SUB_SIGN.getType().toString(), comment);
|
BpmCommentTypeEnum.SUB_SIGN.getType().toString(), comment);
|
||||||
// 5. 处理当前任务的父任务
|
|
||||||
|
// 4. 处理当前任务的父任务
|
||||||
handleParentTask(task);
|
handleParentTask(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -869,14 +866,28 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
*/
|
*/
|
||||||
private Task validateSubSign(String id) {
|
private Task validateSubSign(String id) {
|
||||||
Task task = validateTaskExist(id);
|
Task task = validateTaskExist(id);
|
||||||
// 必须有 parentId
|
|
||||||
// TODO @海:是不是通过 scopeType 去判断更合适哈?因为别的情况下,也可能有 parentId
|
// 必须有 scopeType
|
||||||
if (StrUtil.isEmpty(task.getParentTaskId())) {
|
String scopeType = task.getScopeType();
|
||||||
|
if (StrUtil.isEmpty(scopeType)) {
|
||||||
|
throw exception(TASK_SUB_SIGN_NO_PARENT);
|
||||||
|
}
|
||||||
|
// 并且值为 向前和向后加签
|
||||||
|
if (!validateSignType(scopeType)) {
|
||||||
throw exception(TASK_SUB_SIGN_NO_PARENT);
|
throw exception(TASK_SUB_SIGN_NO_PARENT);
|
||||||
}
|
}
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断当前类型是否为加签
|
||||||
|
* @param scopeType 任务的 scopeType
|
||||||
|
* @return 当前 scopeType 为加签则返回 true
|
||||||
|
*/
|
||||||
|
private boolean validateSignType(String scopeType){
|
||||||
|
return StrUtil.equalsAny(scopeType,BpmTaskAddSignTypeEnum.BEFORE.getType(),scopeType, BpmTaskAddSignTypeEnum.AFTER.getType());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有要被取消的删除的任务 ID 集合
|
* 获取所有要被取消的删除的任务 ID 集合
|
||||||
*
|
*
|
||||||
@ -885,12 +896,24 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
*/
|
*/
|
||||||
public List<String> getAllChildTaskIds(String parentTaskId) {
|
public List<String> getAllChildTaskIds(String parentTaskId) {
|
||||||
List<String> allChildTaskIds = new ArrayList<>();
|
List<String> allChildTaskIds = new ArrayList<>();
|
||||||
// TODO @海:这里可以把递归改成 for 循环,可以试试看哈;整体思路,是一层一层查询;然后判断某一层查不出来了,就是结束了;
|
// 1. 递归获取子级
|
||||||
// 最好不用无限递归,一般是 for (int i = 0; i < Short.MAX),避免脏数据导致无限递归;
|
Stack<String> stack = new Stack<>();
|
||||||
//1. 先将自己放入
|
// 1.1 将根任务ID入栈
|
||||||
allChildTaskIds.add(parentTaskId);
|
stack.push(parentTaskId);
|
||||||
//2. 递归获取子级
|
while (!stack.isEmpty()) {
|
||||||
recursiveGetChildTaskIds(parentTaskId, allChildTaskIds);
|
// 1.2 弹出栈顶任务ID
|
||||||
|
String taskId = stack.pop();
|
||||||
|
// 1.3 将任务ID添加到结果集合中
|
||||||
|
allChildTaskIds.add(taskId);
|
||||||
|
// 1.4 获取该任务的子任务列表
|
||||||
|
List<String> childrenTaskIdList = getChildrenTaskIdList(taskId);
|
||||||
|
if (childrenTaskIdList != null && !childrenTaskIdList.isEmpty()) {
|
||||||
|
for (String childTaskId : childrenTaskIdList) {
|
||||||
|
// 1.5 将子任务ID入栈,以便后续处理
|
||||||
|
stack.push(childTaskId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return allChildTaskIds;
|
return allChildTaskIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,7 +931,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @海:一般情况下,除非对性能特别有要求,才只查询 ID_ 单字段;一般层级不多,数据量不大;其实整查就好啦,无非是带宽稍微浪费电,但是基本看不出啥性能差距;
|
|
||||||
/**
|
/**
|
||||||
* 获取指定父级任务的所有子任务 ID 集合
|
* 获取指定父级任务的所有子任务 ID 集合
|
||||||
*
|
*
|
||||||
@ -916,38 +939,43 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
* @return 所有子任务的 ID 集合
|
* @return 所有子任务的 ID 集合
|
||||||
*/
|
*/
|
||||||
private List<String> getChildrenTaskIdList(String parentTaskId) {
|
private List<String> getChildrenTaskIdList(String parentTaskId) {
|
||||||
String tableName = managementService.getTableName(TaskEntity.class);
|
return convertList(getChildrenTaskList0(parentTaskId), Task::getId);
|
||||||
String sql = "select ID_ from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}";
|
|
||||||
List<Task> childrenTaskList = taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).list();
|
|
||||||
return convertList(childrenTaskList, Task::getId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定父级任务的所有子任务 ID 集合
|
||||||
|
*
|
||||||
|
* @param parentTaskId 父任务 ID
|
||||||
|
* @return 所有子任务的 ID 集合
|
||||||
|
*/
|
||||||
|
private List<Task> getChildrenTaskList0(String parentTaskId) {
|
||||||
|
String tableName = managementService.getTableName(TaskEntity.class);
|
||||||
|
// taskService.createTaskQuery() 没有 parentId 参数,所以写 sql 查询
|
||||||
|
String sql = "select ID_,OWNER_,ASSIGNEE_ from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}";
|
||||||
|
return taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).list();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<BpmTaskSubSignRespVO> getChildrenTaskList(String taskId) {
|
public List<BpmTaskSubSignRespVO> getChildrenTaskList(String parentId) {
|
||||||
// 1. 只查询进行中的任务
|
// 1. 只查询进行中的任务 后加签的任务,可能不存在 assignee,所以还需要查询 owner
|
||||||
List<String> childrenTaskIdList = getChildrenTaskIdList(taskId);
|
List<Task> taskList = getChildrenTaskList0(parentId);
|
||||||
if (CollUtil.isEmpty(childrenTaskIdList)) {
|
if (CollUtil.isEmpty(taskList)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
// TODO @海:bpmTaskExtDOList 可以改成 taskExtList;因为当前已经在 bpm 模块,不用前缀;然后,DO 一般情况下不用带;
|
List<String> childrenTaskIdList = convertList(taskList, Task::getId);
|
||||||
List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.selectProcessListByTaskIds(childrenTaskIdList);
|
|
||||||
|
|
||||||
// 2. 后加签的任务,可能不存在 assignee,所以还需要查询 owner
|
|
||||||
// TODO @海:1. 和 2. 是不是有点重复哈;1. 先查询到了子节点,然后返回了 ids 集合;然后又去 in 查询了一次。。。。按道理,taskService 查询 taskList 就完事?
|
|
||||||
List<Task> taskList = taskService.createTaskQuery().taskIds(childrenTaskIdList).list();
|
|
||||||
Map<String, Task> idTaskMap = convertMap(taskList, TaskInfo::getId);
|
|
||||||
|
|
||||||
// 3. 将 owner 和 assignee 统一到一个集合中
|
// 2. 将 owner 和 assignee 统一到一个集合中
|
||||||
// TODO @海:下面 userId 的获取,可以考虑抽个小方法;
|
List<Long> userIds = convertListByMultiAttr(taskList,control ->
|
||||||
List<Long> userIds = taskList.stream()
|
Stream.of(NumberUtils.parseLong(control.getAssignee()), NumberUtils.parseLong(control.getOwner()))
|
||||||
.flatMap(control ->
|
.filter(Objects::nonNull));
|
||||||
Stream.of(control.getAssignee(), control.getOwner())
|
|
||||||
.filter(Objects::nonNull))
|
// 3. 组装数据
|
||||||
.distinct()
|
|
||||||
.map(NumberUtils::parseLong)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
|
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
|
||||||
return BpmTaskConvert.INSTANCE.convertList(bpmTaskExtDOList, userMap, idTaskMap);
|
List<BpmTaskExtDO> taskExtList = taskExtMapper.selectProcessListByTaskIds(childrenTaskIdList);
|
||||||
|
Map<String, Task> idTaskMap = convertMap(taskList, TaskInfo::getId);
|
||||||
|
return BpmTaskConvert.INSTANCE.convertList(taskExtList, userMap, idTaskMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user