feat - 增加后加签的代码,待测试

This commit is contained in:
wangli 2025-10-14 20:03:59 +08:00
parent 0a1be99b3e
commit 5187af00cd
4 changed files with 77 additions and 14 deletions

View File

@ -42,6 +42,8 @@ public interface BpmnConstants {
@Deprecated
String OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT = "[_ASSIGNEE_INFO_SNAPSHOT_]";
String INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT = "[_ACTIVITY_INFO_SNAPSHOT_]";
String INTERNAL_ACTIVITY_FORWARD_COUNTERSIGN = "[_FORWARD_COUNTERSIGN_]";
String INTERNAL_ACTIVITY_BACK_COUNTERSIGN = "[_BACK_COUNTERSIGN_]";
String BIZ_NODE_ALTER = "[_BIZ_NODE_ALTER_]";
String INITIATOR_SPECIFY = "[_INITIATOR_SPECIFY_]";
String SIGNATURE_COLLECTION = "[_SIGNATURE_COLLECTION_]";

View File

@ -1,6 +1,7 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
@ -11,6 +12,8 @@ import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.cfg.IdGenerator;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
@ -32,19 +35,24 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.code.OtherRespCode.ASSIGNEE_NODE_ID_NOT_EXISTS;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_ASSIGNER_SHOW_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_FORWARD_COUNTERSIGN;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum.FORWARD_COUNTERSIGN;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.COUNTERSIGN;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCategoryVersion;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addMultiTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.completeVirtualTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVirtualTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.deleteMultiTasks;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.getDuplicatePendingTasks;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerCount;
@ -105,6 +113,7 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand<Void> implemen
TaskService taskService = processEngineConfiguration.getTaskService();
TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(originTaskId).singleResult();
// 1.5.4 版本要求审批人必须回传 nodeId
validTargetAssigneeNodeId(task.getProcessDefinitionId());
validTask(historicTaskInstance, task, originTaskAssignee, null);
@ -139,7 +148,7 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand<Void> implemen
break;
case BACK_COUNTERSIGN:
// 加签的另一种方式
backCountSign(commandContext, task, valuTargetAssigneeList);
backCountSign(commandContext, historicTaskInstance, task, valuTargetAssigneeList);
break;
default:
// 共享签不区分顺序
@ -162,6 +171,9 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand<Void> implemen
CommandContextUtil.getProcessEngineConfiguration(commandContext);
IdGenerator idGenerator = processEngineConfiguration.getIdGenerator();
TaskService taskService = processEngineConfiguration.getTaskService();
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
// 记录前加签的审批人快照
runtimeService.setVariable(task.getProcessInstanceId(), INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + INTERNAL_ACTIVITY_FORWARD_COUNTERSIGN + task.getId(), valuTargetAssigneeList);
if (task instanceof TaskEntityImpl) {
TaskEntityImpl taskEntity = (TaskEntityImpl) task;
taskEntity.setCountEnabled(true);
@ -187,7 +199,7 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand<Void> implemen
taskService.saveTask(subTask);
// 设置快照信息
subTask.setVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + subTask.getId(), e.toJson());
taskService.setAssignee(subTask.getParentTaskId(), e.buildAssigneeId());
taskService.setAssignee(subTask.getId(), e.buildAssigneeId());
});
}
}
@ -196,11 +208,47 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand<Void> implemen
* 后加签
*
* @param commandContext
* @param historicTaskInstance
* @param task
* @param valuTargetAssigneeList
*/
private void backCountSign(CommandContext commandContext, TaskEntity task, List<BpmnTaskDelegateAssigner> valuTargetAssigneeList) {
private void backCountSign(CommandContext commandContext,
HistoricTaskInstance historicTaskInstance,
TaskEntity task,
List<BpmnTaskDelegateAssigner> valuTargetAssigneeList) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskService taskService = processEngineConfiguration.getTaskService();
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(historicTaskInstance.getProcessDefinitionId());
FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
if (flowElement instanceof UserTask) {
UserTask userTask = (UserTask) flowElement;
BpmnFlowNodeMode nodeMode = Objects.equals(userTask.getLoopCharacteristics().getCompletionCondition(), AND_SIGN_EXPRESSION) ? BpmnFlowNodeMode.AND : BpmnFlowNodeMode.OR;
switch (nodeMode) {
case AND:
// 这里仅是加签还需要再触发当前人的同意
shareCountSign(commandContext, task, valuTargetAssigneeList);
break;
case OR:
// 修改审批人快照
List<BpmnTaskDelegateAssigner> originAssigners = runtimeService.getVariable(task.getProcessInstanceId(), INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(), List.class);
originAssigners.removeIf(e -> !Objects.equals(e.buildAssigneeId(), originTaskAssignee.buildAssigneeId()));
originAssigners.addAll(valuTargetAssigneeList);
runtimeService.setVariable(task.getProcessInstanceId(), INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(), originAssigners);
// 后加签的人
valuTargetAssigneeList.forEach(e -> addMultiTask(commandContext, task, e));
// 删除除当前审批人的task
List<Task> currentTasks = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).taskDefinitionKey(task.getTaskDefinitionKey()).active().list();
currentTasks.removeIf(e -> Objects.equals(e.getAssignee(), originTaskAssignee.buildAssigneeId()));
deleteMultiTasks(commandContext, currentTasks);
break;
default:
break;
}
}
}
/**

View File

@ -1,10 +1,10 @@
package cn.axzo.workflow.core.engine.cmd.helper;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.model.AddComment;
import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
@ -51,6 +51,12 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ASSIGNEE_HAS_BEEN_EXISTS;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_HAS_BEEN_COMPLETE;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_TYPE_MISMATCH;
import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ASSIGNER_LIMIT_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
@ -61,12 +67,6 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_ATTACHMENTS_VA
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ASSIGNEE_HAS_BEEN_EXISTS;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_HAS_BEEN_COMPLETE;
import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_TYPE_MISMATCH;
import static org.flowable.task.api.Task.DEFAULT_PRIORITY;
/**
@ -225,7 +225,7 @@ public class CustomTaskHelper {
}
/**
* 校验人员数量是否超过限制
* 校验人员数量是否超过60个人的限制
*
* @param runtimeService
* @param taskEntity

View File

@ -41,6 +41,7 @@ import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@ -51,12 +52,16 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_BACK_COUNTERSIGN;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_FORWARD_COUNTERSIGN;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE;
import static cn.axzo.workflow.common.constant.BpmnConstants.SUPPORT_UPGRADE_VARIABLE;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.ApprovalMethodEnum.nobody;
import static cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum.BACK_COUNTERSIGN;
import static cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum.FORWARD_COUNTERSIGN;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.GENERAL;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR;
@ -145,9 +150,17 @@ public class TaskEntityEventHandle implements EntityEventHandle<TaskEntity> {
} else {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
@SuppressWarnings("unchecked")
List<BpmnTaskDelegateAssigner> assigneeList = runtimeService.getVariable(taskEntity.getProcessInstanceId(),
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + taskEntity.getTaskDefinitionKey(), List.class);
List<BpmnTaskDelegateAssigner> assigneeList = new ArrayList<>();
if (Objects.equals(FORWARD_COUNTERSIGN.getType(), taskEntity.getScopeType())) {
assigneeList.addAll(runtimeService.getVariable(taskEntity.getProcessInstanceId(),
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + INTERNAL_ACTIVITY_FORWARD_COUNTERSIGN + taskEntity.getParentTaskId(), List.class));
} else if (Objects.equals(BACK_COUNTERSIGN.getType(), taskEntity.getScopeType())) {
assigneeList.addAll(runtimeService.getVariable(taskEntity.getProcessInstanceId(),
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + INTERNAL_ACTIVITY_BACK_COUNTERSIGN + taskEntity.getParentTaskId(), List.class));
} else {
assigneeList.addAll(runtimeService.getVariable(taskEntity.getProcessInstanceId(),
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + taskEntity.getTaskDefinitionKey(), List.class));
}
ListUtils.emptyIfNull(assigneeList).stream().filter(e -> Objects.equals(e.buildAssigneeId(), taskEntity.getAssignee())).findAny()
.ifPresent(assignee -> {
ExtAxProcessLog queryLog = new ExtAxProcessLog();