|
@@ -53,7 +53,6 @@ import javax.annotation.Resource;
|
|
|
import javax.validation.Valid;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
-import java.util.stream.Collectors;
|
|
|
import java.util.stream.Stream;
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
@@ -240,10 +239,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
handleParentTask(task);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 审批通过存在“后加签”的任务。
|
|
|
* <p>
|
|
|
- * 注意:该任务不能马上完成,需要一个中间状态(ADD_SIGN_AFTER),并激活剩余所有子任务(PROCESS)为可审批处理
|
|
|
+ * 注意:该任务不能马上完成,需要一个中间状态(SIGN_AFTER),并激活剩余所有子任务(PROCESS)为可审批处理
|
|
|
*
|
|
|
* @param task 当前任务
|
|
|
* @param reqVO 前端请求参数
|
|
@@ -251,7 +251,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
private void approveAfterSignTask(Task task, BpmTaskApproveReqVO reqVO) {
|
|
|
// 1. 有向后加签,则该任务状态临时设置为 ADD_SIGN_AFTER 状态
|
|
|
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()));
|
|
|
|
|
|
// 2. 激活子任务
|
|
@@ -265,7 +265,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 处理当前任务的父任务
|
|
|
+ * 处理当前任务的父任务,主要处理“加签”的情况
|
|
|
*
|
|
|
* @param task 当前任务
|
|
|
*/
|
|
@@ -274,76 +274,79 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
if (StrUtil.isBlank(parentTaskId)) {
|
|
|
return;
|
|
|
}
|
|
|
- if (StrUtil.isNotBlank(parentTaskId)) {
|
|
|
- // 1. 判断当前任务的父任务是否还有子任务
|
|
|
- Long childrenTaskCount = getChildrenTaskCount(parentTaskId);
|
|
|
- if (childrenTaskCount > 0) {
|
|
|
- return;
|
|
|
- }
|
|
|
- // 2. 获取父任务
|
|
|
- Task parentTask = validateTaskExist(parentTaskId);
|
|
|
-
|
|
|
- // 3. 情况一:处理向前加签
|
|
|
- String scopeType = parentTask.getScopeType();
|
|
|
- if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(scopeType)) {
|
|
|
- // 3.1 如果是向前加签的任务,则调用 resolveTask 指派父任务,将 owner 重新赋值给父任务的 assignee
|
|
|
- taskService.resolveTask(parentTaskId);
|
|
|
- // 3.2 更新任务拓展表为处理中
|
|
|
- taskExtMapper.updateByTaskId(
|
|
|
- new BpmTaskExtDO().setTaskId(parentTask.getId()).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()));
|
|
|
- } else if (BpmTaskAddSignTypeEnum.AFTER.getType().equals(scopeType)) {
|
|
|
- // 3. 情况二:处理向后加签
|
|
|
- handleAfterSign(parentTask);
|
|
|
- }
|
|
|
+ // 1. 判断当前任务的父任务是否还有子任务
|
|
|
+ Long childrenTaskCount = getChildrenTaskCount(parentTaskId);
|
|
|
+ if (childrenTaskCount > 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 2. 获取父任务
|
|
|
+ Task parentTask = validateTaskExist(parentTaskId);
|
|
|
|
|
|
- // 4. 子任务已处理完成,清空 scopeType 字段,修改 parentTask 信息,方便后续可以继续向前后向后加签
|
|
|
- // 再查询一次的原因是避免报错:Task was updated by another transaction concurrently
|
|
|
- // 因为前面处理后可能会导致 parentTask rev 字段被修改,需要重新获取最新的
|
|
|
- parentTask = getTask(parentTaskId);
|
|
|
- if (parentTask == null) {
|
|
|
- // 为空的情况是:已经通过 handleAfterSign 方法将任务完成了,所以 ru_task 表会查不到数据
|
|
|
- return;
|
|
|
- }
|
|
|
- clearTaskScopeTypeAndSave(parentTask);
|
|
|
+ // 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);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 处理后加签任务
|
|
|
*
|
|
|
* @param parentTask 当前审批任务的父任务
|
|
|
*/
|
|
|
- private void handleAfterSign(Task parentTask) {
|
|
|
+ // TODO @海:这个逻辑,怎么感觉可以是 parentTask 的 parent,再去调用 handleParentTask 方法;可以微信聊下;
|
|
|
+ private void handleParentTaskForAfterSign(Task parentTask) {
|
|
|
String parentTaskId = parentTask.getId();
|
|
|
- //1. 更新 parentTask 的任务拓展表为通过,并调用 complete 完成自己
|
|
|
+ // 1. 更新 parentTask 的任务拓展表为通过,并调用 complete 完成自己
|
|
|
BpmTaskExtDO currentTaskExt = taskExtMapper.selectByTaskId(parentTask.getId());
|
|
|
- BpmTaskExtDO currentTaskUpdateEntity = new BpmTaskExtDO().setTaskId(parentTask.getId())
|
|
|
+ BpmTaskExtDO currentTaskExtUpdateObj = new BpmTaskExtDO().setTaskId(parentTask.getId())
|
|
|
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult());
|
|
|
if (currentTaskExt.getEndTime() == null) {
|
|
|
// 1.1 有这个判断是因为,以前没设置过结束时间,才去设置
|
|
|
- currentTaskUpdateEntity.setEndTime(LocalDateTime.now());
|
|
|
+ currentTaskExtUpdateObj.setEndTime(LocalDateTime.now());
|
|
|
}
|
|
|
- // 1.2 完成自己
|
|
|
- taskExtMapper.updateByTaskId(currentTaskUpdateEntity);
|
|
|
+ taskExtMapper.updateByTaskId(currentTaskExtUpdateObj);
|
|
|
+ // 1.2 完成自己(因为它已经没有子任务,所以也可以完成)
|
|
|
taskService.complete(parentTaskId);
|
|
|
|
|
|
// 2. 如果有父级,递归查询上级任务是否都已经完成
|
|
|
if (StrUtil.isEmpty(parentTask.getParentTaskId())) {
|
|
|
return;
|
|
|
}
|
|
|
- // TODO @海:这块待讨论,脑子略乱;感觉 handleAfterSign 的后半段,和 handleParentTask 有点重叠???
|
|
|
// 2.1 判断整条链路的任务是否完成
|
|
|
// 例如从 A 任务加签了一个 B 任务,B 任务又加签了一个 C 任务,C 任务加签了 D 任务
|
|
|
// 此时,D 任务完成,要一直往上找到祖先任务 A调用 complete 方法完成 A 任务
|
|
|
boolean allChildrenTaskFinish = true;
|
|
|
while (StrUtil.isNotBlank(parentTask.getParentTaskId())) {
|
|
|
parentTask = validateTaskExist(parentTask.getParentTaskId());
|
|
|
- BpmTaskExtDO bpmTaskExtDO = taskExtMapper.selectByTaskId(parentTask.getId());
|
|
|
- if (bpmTaskExtDO == null) {
|
|
|
+ BpmTaskExtDO parentTaskExt = taskExtMapper.selectByTaskId(parentTask.getId());
|
|
|
+ if (parentTaskExt == null) {
|
|
|
break;
|
|
|
}
|
|
|
- boolean currentTaskFinish = BpmProcessInstanceResultEnum.isEndResult(bpmTaskExtDO.getResult());
|
|
|
- // 2.2 如果 allChildrenTaskFinish 已经被赋值为 false ,则不会再赋值为 true,因为整个链路没有完成
|
|
|
+ boolean currentTaskFinish = BpmProcessInstanceResultEnum.isEndResult(parentTaskExt.getResult());
|
|
|
+ // 2.2 如果 allChildrenTaskFinish 已经被赋值为 false,则不会再赋值为 true,因为整个链路没有完成
|
|
|
if (allChildrenTaskFinish) {
|
|
|
allChildrenTaskFinish = currentTaskFinish;
|
|
|
}
|
|
@@ -354,19 +357,19 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
|
|
|
// 3 处理非完成状态的任务
|
|
|
// 3.1 判断当前任务的父任务是否还有子任务
|
|
|
- Long childrenTaskCount = getChildrenTaskCount(bpmTaskExtDO.getTaskId());
|
|
|
+ Long childrenTaskCount = getChildrenTaskCount(parentTaskExt.getTaskId());
|
|
|
if (childrenTaskCount > 0) {
|
|
|
continue;
|
|
|
}
|
|
|
// 3.2 没有子任务,判断当前任务状态是否为 ADD_SIGN_BEFORE 待前加签任务完成
|
|
|
- if (BpmProcessInstanceResultEnum.ADD_SIGN_BEFORE.getResult().equals(bpmTaskExtDO.getResult())) {
|
|
|
+ if (BpmProcessInstanceResultEnum.SIGN_BEFORE.getResult().equals(parentTaskExt.getResult())) {
|
|
|
// 3.3 需要修改该任务状态为处理中
|
|
|
- taskService.resolveTask(bpmTaskExtDO.getTaskId());
|
|
|
- bpmTaskExtDO.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
|
|
- taskExtMapper.updateByTaskId(bpmTaskExtDO);
|
|
|
+ taskService.resolveTask(parentTaskExt.getTaskId());
|
|
|
+ parentTaskExt.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
|
|
+ taskExtMapper.updateByTaskId(parentTaskExt);
|
|
|
}
|
|
|
// 3.4 清空 scopeType 字段,用于任务没有子任务时使用该方法,方便任务可以再次被不同的方式加签
|
|
|
- parentTask = validateTaskExist(bpmTaskExtDO.getTaskId());
|
|
|
+ parentTask = validateTaskExist(parentTaskExt.getTaskId());
|
|
|
clearTaskScopeTypeAndSave(parentTask);
|
|
|
}
|
|
|
|
|
@@ -387,7 +390,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
taskService.saveTask(task);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* 获取子任务个数
|
|
|
*
|
|
@@ -709,7 +711,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public void addSignTask(Long userId, BpmTaskAddSignReqVO reqVO) {
|
|
|
+ public void createSignTask(Long userId, BpmTaskAddSignReqVO reqVO) {
|
|
|
// 1. 获取和校验任务
|
|
|
TaskEntityImpl taskEntity = validateAddSign(userId, reqVO);
|
|
|
List<AdminUserRespDTO> userList = adminUserApi.getUserList(reqVO.getUserIdList());
|
|
@@ -728,7 +730,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
// 2.3 更新扩展表状态
|
|
|
taskExtMapper.updateByTaskId(
|
|
|
new BpmTaskExtDO().setTaskId(taskEntity.getId())
|
|
|
- .setResult(BpmProcessInstanceResultEnum.ADD_SIGN_BEFORE.getResult())
|
|
|
+ .setResult(BpmProcessInstanceResultEnum.SIGN_BEFORE.getResult())
|
|
|
.setReason(reqVO.getReason()));
|
|
|
}
|
|
|
// 2.4 记录加签方式,完成任务时需要用到判断
|
|
@@ -737,12 +739,12 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
taskService.saveTask(taskEntity);
|
|
|
|
|
|
// 3. 创建加签任务
|
|
|
- createAddSignChildrenTasks(convertList(reqVO.getUserIdList(), String::valueOf), taskEntity);
|
|
|
+ createSignTask(convertList(reqVO.getUserIdList(), String::valueOf), taskEntity);
|
|
|
|
|
|
// 4. 记录加签 comment,拼接结果为: [当前用户]向前加签/向后加签给了[多个用户],理由为:reason
|
|
|
AdminUserRespDTO currentUser = adminUserApi.getUser(userId);
|
|
|
- String comment = StrUtil.format(BpmCommentTypeEnum.ADD_SIGN.getTemplateComment(), currentUser.getNickname(), BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()),
|
|
|
- String.join(",", convertList(userList, AdminUserRespDTO::getNickname)), reqVO.getReason());
|
|
|
+ String comment = StrUtil.format(BpmCommentTypeEnum.ADD_SIGN.getComment(), currentUser.getNickname(),
|
|
|
+ BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()), String.join(",", convertList(userList, AdminUserRespDTO::getNickname)), reqVO.getReason());
|
|
|
taskService.addComment(reqVO.getId(), taskEntity.getProcessInstanceId(),
|
|
|
BpmCommentTypeEnum.ADD_SIGN.getType().toString(), comment);
|
|
|
}
|
|
@@ -786,7 +788,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
* @param addSingUserIdList 被加签的用户 ID
|
|
|
* @param taskEntity 被加签的任务
|
|
|
*/
|
|
|
- private void createAddSignChildrenTasks(List<String> addSingUserIdList, TaskEntityImpl taskEntity) {
|
|
|
+ private void createSignTask(List<String> addSingUserIdList, TaskEntityImpl taskEntity) {
|
|
|
if (CollUtil.isEmpty(addSingUserIdList)) {
|
|
|
return;
|
|
|
}
|
|
@@ -795,23 +797,22 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
if (StrUtil.isBlank(addSignId)) {
|
|
|
continue;
|
|
|
}
|
|
|
- createChildrenTask(taskEntity, addSignId);
|
|
|
+ createSignTask(taskEntity, addSignId);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 创建子任务
|
|
|
+ * 创建加签子任务
|
|
|
*
|
|
|
* @param parentTask 父任务
|
|
|
* @param assignee 子任务的执行人
|
|
|
- * @return
|
|
|
*/
|
|
|
- private void createChildrenTask(TaskEntityImpl parentTask, String assignee) {
|
|
|
+ private void createSignTask(TaskEntityImpl parentTask, String assignee) {
|
|
|
// 1. 生成子任务
|
|
|
TaskEntityImpl task = (TaskEntityImpl) taskService.newTask(IdUtil.fastSimpleUUID());
|
|
|
task = BpmTaskConvert.INSTANCE.convert(task, parentTask);
|
|
|
if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(parentTask.getScopeType())) {
|
|
|
- // 2.1 前加签,才设置审批人,否则设置 owner
|
|
|
+ // 2.1 前加签,设置审批人
|
|
|
task.setAssignee(assignee);
|
|
|
} else {
|
|
|
// 2.2.1 设置 owner 不设置 assignee 是因为不能同时审批,需要等父任务完成
|
|
@@ -825,9 +826,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- public void subSignTask(Long userId, BpmTaskSubSignReqVO reqVO) {
|
|
|
+ public void deleteSignTask(Long userId, BpmTaskSubSignReqVO reqVO) {
|
|
|
+ // 1.1 校验 task 可以被减签
|
|
|
Task task = validateSubSign(reqVO.getId());
|
|
|
- AdminUserRespDTO user = adminUserApi.getUser(userId);
|
|
|
+ // 1.2 校验取消人存在
|
|
|
AdminUserRespDTO cancelUser = null;
|
|
|
if (StrUtil.isNotBlank(task.getAssignee())) {
|
|
|
cancelUser = adminUserApi.getUser(NumberUtils.parseLong(task.getAssignee()));
|
|
@@ -836,20 +838,24 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
cancelUser = adminUserApi.getUser(NumberUtils.parseLong(task.getOwner()));
|
|
|
}
|
|
|
Assert.notNull(cancelUser, "任务中没有所有者和审批人,数据错误");
|
|
|
- //1. 获取所有需要删除的任务 ID ,包含当前任务和所有子任务
|
|
|
+
|
|
|
+ // 2. 删除任务和对应子任务
|
|
|
+ // 2.1 获取所有需要删除的任务 ID ,包含当前任务和所有子任务
|
|
|
List<String> allTaskIdList = getAllChildTaskIds(task.getId());
|
|
|
- //2. 删除任务和所有子任务
|
|
|
+ // 2.2 删除任务和所有子任务
|
|
|
taskService.deleteTasks(allTaskIdList);
|
|
|
- //3. 修改扩展表状态为取消
|
|
|
+ // 2.3 修改扩展表状态为取消
|
|
|
+ AdminUserRespDTO user = adminUserApi.getUser(userId);
|
|
|
taskExtMapper.updateBatchByTaskIdList(allTaskIdList, new BpmTaskExtDO().setResult(BpmProcessInstanceResultEnum.CANCEL.getResult())
|
|
|
.setReason(StrUtil.format("由于{}操作[减签],任务被取消", user.getNickname())));
|
|
|
- //4.记录日志到父任务中 先记录日志是因为,通过 handleParentTask 方法之后,任务可能被完成了,并且不存在了,会报异常,所以先记录
|
|
|
- String comment = StrUtil.format(BpmCommentTypeEnum.SUB_SIGN.getTemplateComment(), user.getNickname(), cancelUser.getNickname());
|
|
|
+
|
|
|
+ // 3. 记录日志到父任务中。先记录日志是因为,通过 handleParentTask 方法之后,任务可能被完成了,并且不存在了,会报异常,所以先记录
|
|
|
+ String comment = StrUtil.format(BpmCommentTypeEnum.SUB_SIGN.getComment(), user.getNickname(), cancelUser.getNickname());
|
|
|
taskService.addComment(task.getParentTaskId(), task.getProcessInstanceId(),
|
|
|
BpmCommentTypeEnum.SUB_SIGN.getType().toString(), comment);
|
|
|
- //5. 处理当前任务的父任务
|
|
|
- this.handleParentTask(task);
|
|
|
|
|
|
+ // 4. 处理当前任务的父任务
|
|
|
+ handleParentTask(task);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -860,14 +866,29 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
*/
|
|
|
private Task validateSubSign(String id) {
|
|
|
Task task = validateTaskExist(id);
|
|
|
- //必须有parentId
|
|
|
- if (StrUtil.isEmpty(task.getParentTaskId())) {
|
|
|
+
|
|
|
+ // 必须有 scopeType
|
|
|
+ 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);
|
|
|
}
|
|
|
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 集合
|
|
|
*
|
|
|
* @param parentTaskId 父级任务ID
|
|
@@ -875,25 +896,40 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
*/
|
|
|
public List<String> getAllChildTaskIds(String parentTaskId) {
|
|
|
List<String> allChildTaskIds = new ArrayList<>();
|
|
|
- //1. 先将自己放入
|
|
|
- allChildTaskIds.add(parentTaskId);
|
|
|
- //2. 递归获取子级
|
|
|
- recursiveGetChildTaskIds(parentTaskId, allChildTaskIds);
|
|
|
+ // 1. 递归获取子级
|
|
|
+ Stack<String> stack = new Stack<>();
|
|
|
+ // 1.1 将根任务ID入栈
|
|
|
+ stack.push(parentTaskId);
|
|
|
+ //控制遍历的次数不超过 Byte.MAX_VALUE,避免脏数据造成死循环
|
|
|
+ int count = 0;
|
|
|
+ // TODO @海:< 的前后空格,要注意哈;
|
|
|
+ while (!stack.isEmpty() && count<Byte.MAX_VALUE) {
|
|
|
+ // 1.2 弹出栈顶任务ID
|
|
|
+ String taskId = stack.pop();
|
|
|
+ // 1.3 将任务ID添加到结果集合中
|
|
|
+ allChildTaskIds.add(taskId);
|
|
|
+ // 1.4 获取该任务的子任务列表
|
|
|
+ // TODO @海:有个更高效的写法;一次性去 in 一层;不然每个节点,都去查询一次 db, 太浪费了;每次 in,最终就是 O(h) 查询,而不是 O(n) 查询;
|
|
|
+ List<String> childrenTaskIdList = getChildrenTaskIdList(taskId);
|
|
|
+ if (CollUtil.isNotEmpty(childrenTaskIdList)) {
|
|
|
+ for (String childTaskId : childrenTaskIdList) {
|
|
|
+ // 1.5 将子任务ID入栈,以便后续处理
|
|
|
+ stack.push(childTaskId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ count++;
|
|
|
+ }
|
|
|
return allChildTaskIds;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 递归处理子级任务
|
|
|
+ * 获取指定父级任务的所有子任务 ID 集合
|
|
|
*
|
|
|
- * @param taskId 当前任务ID
|
|
|
- * @param taskIds 结果
|
|
|
+ * @param parentTaskId 父任务 ID
|
|
|
+ * @return 所有子任务的 ID 集合
|
|
|
*/
|
|
|
- private void recursiveGetChildTaskIds(String taskId, List<String> taskIds) {
|
|
|
- List<String> childrenTaskIdList = getChildrenTaskIdList(taskId);
|
|
|
- for (String childTaskId : childrenTaskIdList) {
|
|
|
- taskIds.add(childTaskId); // 将子任务的ID添加到集合中
|
|
|
- recursiveGetChildTaskIds(childTaskId, taskIds); // 递归获取子任务的子任务
|
|
|
- }
|
|
|
+ private List<String> getChildrenTaskIdList(String parentTaskId) {
|
|
|
+ return convertList(getChildrenTaskList0(parentTaskId), Task::getId);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -902,33 +938,32 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|
|
* @param parentTaskId 父任务 ID
|
|
|
* @return 所有子任务的 ID 集合
|
|
|
*/
|
|
|
- private List<String> getChildrenTaskIdList(String parentTaskId) {
|
|
|
+ private List<Task> getChildrenTaskList0(String parentTaskId) {
|
|
|
String tableName = managementService.getTableName(TaskEntity.class);
|
|
|
- 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);
|
|
|
+ // 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
|
|
|
- public List<BpmTaskSubSignRespVO> getChildrenTaskList(String taskId) {
|
|
|
- List<String> childrenTaskIdList = getChildrenTaskIdList(taskId);
|
|
|
- if (CollUtil.isEmpty(childrenTaskIdList)) {
|
|
|
+ public List<BpmTaskSubSignRespVO> getChildrenTaskList(String parentId) {
|
|
|
+ // 1. 只查询进行中的任务 后加签的任务,可能不存在 assignee,所以还需要查询 owner
|
|
|
+ List<Task> taskList = getChildrenTaskList0(parentId);
|
|
|
+ if (CollUtil.isEmpty(taskList)) {
|
|
|
return Collections.emptyList();
|
|
|
}
|
|
|
- //1. 只查询进行中的任务
|
|
|
- List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.selectProcessListByTaskIds(childrenTaskIdList);
|
|
|
- //2. 后加签的任务,可能不存在 assignee,所以还需要查询 owner
|
|
|
- List<Task> taskList = taskService.createTaskQuery().taskIds(childrenTaskIdList).list();
|
|
|
- Map<String, Task> idTaskMap = convertMap(taskList, TaskInfo::getId);
|
|
|
- //3. 将 owner 和 assignee 统一到一个集合中
|
|
|
- List<Long> userIds = taskList.stream()
|
|
|
- .flatMap(control ->
|
|
|
- Stream.of(control.getAssignee(), control.getOwner())
|
|
|
- .filter(Objects::nonNull))
|
|
|
- .distinct()
|
|
|
- .map(NumberUtils::parseLong)
|
|
|
- .collect(Collectors.toList());
|
|
|
+ List<String> childrenTaskIdList = convertList(taskList, Task::getId);
|
|
|
+
|
|
|
+ // 2.1 将 owner 和 assignee 统一到一个集合中
|
|
|
+ List<Long> userIds = convertListByFlatMap(taskList, control ->
|
|
|
+ Stream.of(NumberUtils.parseLong(control.getAssignee()), NumberUtils.parseLong(control.getOwner()))
|
|
|
+ .filter(Objects::nonNull));
|
|
|
+ // 2.2 组装数据
|
|
|
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);
|
|
|
}
|
|
|
+
|
|
|
}
|