review: 278 281行

This commit is contained in:
smallNorthLee 2025-03-04 22:28:25 +08:00
parent 4e57bd157f
commit 9e151b3966
1 changed files with 60 additions and 55 deletions

View File

@ -149,7 +149,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
}
private Map<String, String> getFormFieldsPermission(BpmnModel bpmnModel,
String activityId, String taskId) {
String activityId, String taskId) {
// 1. 获取流程活动编号流程活动 Id 为空事从流程任务中获取流程活动 Id
if (StrUtil.isEmpty(activityId) && StrUtil.isNotEmpty(taskId)) {
activityId = Optional.ofNullable(taskService.getHistoricTask(taskId))
@ -232,57 +232,62 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
@Override
public List<ActivityNode> getNextFlowNodes(Long loginUserId, BpmApprovalDetailReqVO reqVO) {
// 1 校验任务存在
// 1.1 校验任务存在
Task task = taskService.getTask(reqVO.getTaskId());
if (task == null) {
throw exception(TASK_NOT_EXISTS);
}
// 2 校验任务是否由当前用户审批
// 1.2 校验任务是否由当前用户审批
if (StrUtil.isNotBlank(task.getAssignee())
&& ObjectUtil.notEqual(loginUserId, NumberUtils.parseLong(task.getAssignee()))) {
throw exception(TASK_OPERATE_FAIL_ASSIGN_NOT_SELF);
}
// 3 校验流程实例存在
// 1.3 校验流程实例存在
ProcessInstance instance = getProcessInstance(task.getProcessInstanceId());
if (instance == null) {
throw exception(PROCESS_INSTANCE_NOT_EXISTS);
}
// 4 获取 BpmnModel
// 1.4 校验BpmnModel
BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(task.getProcessDefinitionId());
if (bpmnModel == null) {
return null;
}
//1.5 流程实例是否存在
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(task.getProcessInstanceId());
if (historicProcessInstance == null) {
throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);
}
// 2 设置流程变量
Map<String, Object> processVariables = new HashMap<>();
// 获取历史中流程变量
// 2.1 获取历史中流程变量
Map<String, Object> historicVariables = historicProcessInstance.getProcessVariables();
if (CollUtil.isNotEmpty(historicVariables)) {
processVariables.putAll(historicVariables);
}
// 合并前端传递的流程变量以前端为准
if (CollUtil.isNotEmpty(reqVO.getProcessVariables())){
// 2.2 合并前端传递的流程变量以前端为准
if (CollUtil.isNotEmpty(reqVO.getProcessVariables())) {
processVariables.putAll(reqVO.getProcessVariables());
}
// 获取流程定义信息
BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService
.getProcessDefinitionInfo(task.getProcessDefinitionId());
// 获取当前任务节点的信息
// 3 获取当前任务节点的信息
FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
// 获取下一个将要执行的节点集合
// 3.1 获取下一个将要执行的节点集合
List<FlowNode> nextFlowNodes = BpmnModelUtils.getNextFlowNodes(flowElement, bpmnModel, processVariables);
return convertList(nextFlowNodes, node -> {
List<Long> candidateUserIds = getTaskCandidateUserList(bpmnModel, node.getId(),
loginUserId, processDefinitionInfo.getProcessDefinitionId(), processVariables);
//存在一个节点多人审批的情况
List<UserSimpleBaseVO> candidateUsers = new ArrayList<>();
for (Long candidateUserId : candidateUserIds) {
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(candidateUserIds);
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
candidateUsers.add(BpmProcessInstanceConvert.INSTANCE.buildUser(candidateUserId, userMap, deptMap));
loginUserId, historicProcessInstance.getProcessDefinitionId(), processVariables);
// 3.2 获取节点的审批人信息
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(candidateUserIds);
if (CollUtil.isEmpty(userMap)) {
return null;
}
// 3.3 获取节点的审批人部门信息
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
// 3.4 存在一个节点多人审批的情况组装审批人信息
List<UserSimpleBaseVO> candidateUsers = new ArrayList<>();
userMap.forEach((key, value) -> {
candidateUsers.add(BpmProcessInstanceConvert.INSTANCE.buildUser(key, userMap, deptMap));
});
return new ActivityNode().setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())
.setId(node.getId())
.setName(node.getName())
@ -356,15 +361,15 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
* 主要是拼接审批人的用户信息部门信息
*/
private BpmApprovalDetailRespVO buildApprovalDetail(BpmApprovalDetailReqVO reqVO,
BpmnModel bpmnModel,
ProcessDefinition processDefinition,
BpmProcessDefinitionInfoDO processDefinitionInfo,
HistoricProcessInstance processInstance,
Integer processInstanceStatus,
List<ActivityNode> endApprovalNodeInfos,
List<ActivityNode> runningApprovalNodeInfos,
List<ActivityNode> simulateApprovalNodeInfos,
BpmTaskRespVO todoTask) {
BpmnModel bpmnModel,
ProcessDefinition processDefinition,
BpmProcessDefinitionInfoDO processDefinitionInfo,
HistoricProcessInstance processInstance,
Integer processInstanceStatus,
List<ActivityNode> endApprovalNodeInfos,
List<ActivityNode> runningApprovalNodeInfos,
List<ActivityNode> simulateApprovalNodeInfos,
BpmTaskRespVO todoTask) {
// 1. 获取所有需要读取用户信息的 userIds
List<ActivityNode> approveNodes = newArrayList(
asList(endApprovalNodeInfos, runningApprovalNodeInfos, simulateApprovalNodeInfos));
@ -386,9 +391,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
* 获得已结束的活动节点们
*/
private List<ActivityNode> getEndActivityNodeList(Long startUserId, BpmnModel bpmnModel,
BpmProcessDefinitionInfoDO processDefinitionInfo,
HistoricProcessInstance historicProcessInstance, Integer processInstanceStatus,
List<HistoricActivityInstance> activities, List<HistoricTaskInstance> tasks) {
BpmProcessDefinitionInfoDO processDefinitionInfo,
HistoricProcessInstance historicProcessInstance, Integer processInstanceStatus,
List<HistoricActivityInstance> activities, List<HistoricTaskInstance> tasks) {
// 遍历 tasks 列表只处理已结束的 UserTask
// 为什么不通过 activities 因为加签场景下它只存在于 tasks没有 activities导致如果遍历 activities
// 的话它无法成为一个节点
@ -400,7 +405,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
.setNodeType(START_USER_NODE_ID.equals(task.getTaskDefinitionKey())
? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()
: ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的解决办理节点的识别
BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))
BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))
.setStatus(FlowableUtils.getTaskStatus(task))
.setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
.setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime()))
@ -456,11 +461,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
* 获得进行中的活动节点们
*/
private List<ActivityNode> getRunApproveNodeList(Long startUserId,
BpmnModel bpmnModel,
ProcessDefinition processDefinition,
Map<String, Object> processVariables,
List<HistoricActivityInstance> activities,
List<HistoricTaskInstance> tasks) {
BpmnModel bpmnModel,
ProcessDefinition processDefinition,
Map<String, Object> processVariables,
List<HistoricActivityInstance> activities,
List<HistoricTaskInstance> tasks) {
// 构建运行中的任务子流程基于 activityId 分组
List<HistoricActivityInstance> runActivities = filterList(activities, activity -> activity.getEndTime() == null
&& (StrUtil.equalsAny(activity.getActivityType(), ELEMENT_TASK_USER, ELEMENT_CALL_ACTIVITY)));
@ -521,9 +526,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
* 获得预测未来的活动节点们
*/
private List<ActivityNode> getSimulateApproveNodeList(Long startUserId, BpmnModel bpmnModel,
BpmProcessDefinitionInfoDO processDefinitionInfo,
Map<String, Object> processVariables,
List<HistoricActivityInstance> activities) {
BpmProcessDefinitionInfoDO processDefinitionInfo,
Map<String, Object> processVariables,
List<HistoricActivityInstance> activities) {
// TODO @芋艿可优化在驳回场景下未来的预测准确性不高原因是驳回后HistoricActivityInstance
// 包括了历史的操作不是只有 startEvent 到当前节点的记录
Set<String> runActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId);
@ -545,8 +550,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
}
private ActivityNode buildNotRunApproveNodeForSimple(Long startUserId, BpmnModel bpmnModel,
BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
BpmSimpleModelNodeVO node, Set<String> runActivityIds) {
BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
BpmSimpleModelNodeVO node, Set<String> runActivityIds) {
// TODO @芋艿可优化在驳回场景下未来的预测准确性不高原因是驳回后HistoricActivityInstance
// 包括了历史的操作不是只有 startEvent 到当前节点的记录
if (runActivityIds.contains(node.getId())) {
@ -590,8 +595,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
}
private ActivityNode buildNotRunApproveNodeForBpmn(Long startUserId, BpmnModel bpmnModel,
BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
FlowElement node, Set<String> runActivityIds) {
BpmProcessDefinitionInfoDO processDefinitionInfo, Map<String, Object> processVariables,
FlowElement node, Set<String> runActivityIds) {
if (runActivityIds.contains(node.getId())) {
return null;
}
@ -622,7 +627,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
}
private List<Long> getTaskCandidateUserList(BpmnModel bpmnModel, String activityId,
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
Set<Long> userIds = taskCandidateInvoker.calculateUsersByActivity(bpmnModel, activityId,
startUserId, processDefinitionId, processVariables);
return new ArrayList<>(userIds);
@ -658,11 +663,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
Set<String> finishedTaskActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,
activityInstance -> activityInstance.getEndTime() != null
&& ObjectUtil.notEqual(activityInstance.getActivityType(),
BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
Set<String> finishedSequenceFlowActivityIds = convertSet(activities, HistoricActivityInstance::getActivityId,
activityInstance -> activityInstance.getEndTime() != null
&& ObjectUtil.equals(activityInstance.getActivityType(),
BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW));
// 特殊会签情况下会有部分已完成审批部分未完成待审批此时需要 finishedTaskActivityIds 移除掉
finishedTaskActivityIds.removeAll(unfinishedTaskActivityIds);
// 特殊如果流程实例被拒绝则需要计算是哪个活动节点
@ -714,8 +719,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
}
private String createProcessInstance0(Long userId, ProcessDefinition definition,
Map<String, Object> variables, String businessKey,
Map<String, List<Long>> startUserSelectAssignees) {
Map<String, Object> variables, String businessKey,
Map<String, List<Long>> startUserSelectAssignees) {
// 1.1 校验流程定义
if (definition == null) {
throw exception(PROCESS_DEFINITION_NOT_EXISTS);
@ -744,8 +749,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态审批中
BpmProcessInstanceStatusEnum.RUNNING.getStatus());
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_SKIP_EXPRESSION_ENABLED, true); // 跳过表达式需要添加此变量为
// true不影响没配置
// skipExpression 的节点
// true不影响没配置
// skipExpression 的节点
if (CollUtil.isNotEmpty(startUserSelectAssignees)) {
// 设置流程变量发起人自选审批人
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,
@ -784,20 +789,20 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
private void validateStartUserSelectAssignees(Long userId, ProcessDefinition definition,
Map<String, List<Long>> startUserSelectAssignees,
Map<String,Object> variables) {
Map<String, Object> variables) {
// 1. 获取预测的节点信息
BpmApprovalDetailRespVO detailRespVO = getApprovalDetail(userId, new BpmApprovalDetailReqVO()
.setProcessDefinitionId(definition.getId())
.setProcessVariables(variables));
List<ActivityNode> activityNodes = detailRespVO.getActivityNodes();
if (CollUtil.isEmpty(activityNodes)){
if (CollUtil.isEmpty(activityNodes)) {
return;
}
// 2.1 移除掉不是发起人或者审批人自选审批人节点
activityNodes.removeIf(task ->
ObjectUtil.notEqual(BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy(), task.getCandidateStrategy())
&& ObjectUtil.notEqual(BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy(), task.getCandidateStrategy()));
&& ObjectUtil.notEqual(BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy(), task.getCandidateStrategy()));
// 2.2 流程发起时要先获取当前流程的预测走向节点发起时只校验预测的节点发起人自选审批人的审批人和抄送人是否都配置了
activityNodes.forEach(task -> {
List<Long> assignees = startUserSelectAssignees != null ? startUserSelectAssignees.get(task.getId()) : null;