update - 测试新增加签逻辑后的审批日志中,无法对加签功能正常使用/展示的问题

This commit is contained in:
wangli 2023-11-28 18:58:00 +08:00
parent 491d064c01
commit 16f45358f7
17 changed files with 152 additions and 87 deletions

View File

@ -74,6 +74,8 @@ public interface BpmnConstants {
* 其他类型 @see org.flowable.engine.impl.persistence.entity.CommentEntity
*/
String COMMENT_TYPE_ADVICE = "advice";
String COMMENT_TYPE_OPERATION = "operation";
String INITIATOR_REVOKE_THE_APPROVAL = "发起人主动撤销审批";
String APPROVAL_ENDS_AUTOMATICALLY = "审批拒绝自动结束";

View File

@ -4,7 +4,10 @@ package cn.axzo.workflow.common.enums;
public enum BpmnFlowNodeMode {
GENERAL("GENERAL", "普通"),
OR("OR", "或签"),
AND("AND", "会签");
AND("AND", "会签"),
BUSINESS("BUSINESS", "业务节点"),
COPY("COPY", "抄送节点"),
;
private String type;
private String desc;
@ -13,6 +16,7 @@ public enum BpmnFlowNodeMode {
this.type = type;
this.desc = desc;
}
public boolean isEqual(String type) {
return this.type.equals(type);
}

View File

@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
@ -59,6 +60,7 @@ public class BpmnProcessInstanceCreateDTO {
private String businessKey;
@ApiModelProperty(value = "发起人信息")
@Valid
private BpmnTaskDelegateAssigner initiator;
/**
@ -71,6 +73,7 @@ public class BpmnProcessInstanceCreateDTO {
* 下级审批人
*/
@ApiModelProperty(value = "下级审批人", notes = "可为空,定义选择审批人,如果不为空,则覆盖下一级任务的审核人")
@Valid
private BpmnTaskDelegateAssigner nextApprover;
}

View File

@ -1,11 +1,13 @@
package cn.axzo.workflow.common.model.request.bpmn.task;
import cn.axzo.workflow.common.valid.group.ValidGroup;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
@ -14,10 +16,11 @@ import java.util.List;
*/
@ApiModel("审批任务节点的入参模型")
@Data
@Validated
public class BpmnTaskAuditDTO {
@ApiModelProperty(value = "任务编号", required = true, example = "1024")
@NotEmpty(message = "任务编号不能为空", groups = {ValidGroup.Insert.class, ValidGroup.Update.class})
@NotEmpty(message = "任务编号不能为空")
private String taskId;
/**
@ -36,11 +39,14 @@ public class BpmnTaskAuditDTO {
* 当前审核人信息
*/
@ApiModelProperty(value = "当前审核人信息", notes = "可为空,则该任务不验证用户归属")
@Valid
@NotNull(message = "审批人不能为空")
private BpmnTaskDelegateAssigner approver;
/**
* 下级审批人
*/
@ApiModelProperty(value = "下级审批人信息", notes = "可为空,定义选择审批人,如果不为空,则覆盖下一级任务的审核人")
@Valid
private BpmnTaskDelegateAssigner nextApprover;
}

View File

@ -35,7 +35,7 @@ public class BpmnTaskCountersignDTO implements Serializable {
*/
@ApiModelProperty(value = "加签类型")
@NotEmpty(message = "加签类型不能为空")
private String countersignType ;
private String countersignType = "FORWARD_COUNTERSIGN";
/**
* 附件列表

View File

@ -6,6 +6,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
@ -24,6 +25,7 @@ import java.io.Serializable;
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Validated
public class BpmnTaskDelegateAssigner implements Serializable {
private static final long serialVersionUID = -8106887960942113552L;
@ -76,10 +78,10 @@ public class BpmnTaskDelegateAssigner implements Serializable {
*/
private String ouId;
public String buildAssigneeId() {
public final String buildAssigneeId() {
if (StringUtils.hasLength(assigneeType)) {
return assignee + "_" + assigneeType + "_" + tenantId;
return tenantId + "|" + assignee + "|" + assigneeType;
}
return assignee;
return tenantId + "|" + assignee;
}
}

View File

@ -34,4 +34,5 @@ public class ProcessNodeDetailVO {
*/
private String formKey;
}

View File

@ -61,6 +61,9 @@ public class BpmnHistoricTaskInstanceVO {
@ApiModelProperty(value = "删除原因")
private String deleteReason;
@ApiModelProperty(value = "操作描述")
private String operationDesc;
@ApiModelProperty(value = "审批人的快照信息", notes = "完整的审批人信息,assignee 仅是唯一标识")
private BpmnTaskDelegateAssigner assigneeSnapshot;

View File

@ -30,7 +30,7 @@ public class MockTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
BpmnTaskDelegateAssigner task_2 = new BpmnTaskDelegateAssigner();
task_2.setAssignee("1");
task_2.setAssignerName("王粒");
task_2.setTenantId("");
task_2.setTenantId("10001");
users.add(task_2);
}
@ -39,13 +39,13 @@ public class MockTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
BpmnTaskDelegateAssigner task_10_1 = new BpmnTaskDelegateAssigner();
task_10_1.setAssignee("1");
task_10_1.setAssignerName("王粒");
task_10_1.setTenantId("");
task_10_1.setTenantId("10002");
users.add(task_10_1);
BpmnTaskDelegateAssigner task_10_2 = new BpmnTaskDelegateAssigner();
task_10_2.setAssignee("2");
task_10_2.setAssignerName("王粒");
task_10_2.setTenantId("");
task_10_2.setTenantId("10003");
users.add(task_10_2);
}
@ -54,19 +54,19 @@ public class MockTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
BpmnTaskDelegateAssigner task_13_1 = new BpmnTaskDelegateAssigner();
task_13_1.setAssignee("1");
task_13_1.setAssignerName("王粒");
task_13_1.setTenantId("");
task_13_1.setTenantId("10004");
users.add(task_13_1);
BpmnTaskDelegateAssigner task_13_2 = new BpmnTaskDelegateAssigner();
task_13_2.setAssignee("2");
task_13_2.setAssignerName("王粒");
task_13_2.setTenantId("");
task_13_2.setTenantId("10005");
users.add(task_13_2);
BpmnTaskDelegateAssigner task_13_3 = new BpmnTaskDelegateAssigner();
task_13_3.setAssignee("3");
task_13_3.setAssignerName("王粒");
task_13_3.setTenantId("");
task_13_3.setTenantId("10006");
users.add(task_13_3);
}
return users;

View File

@ -102,7 +102,7 @@ public class EngineExecutionStartListener implements ExecutionListener {
// UserTask 多实例, 该变量用于引擎
execution.setVariable(assigneeListVariableName, assigneeIdList);
execution.setVariableLocal(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId,
execution.setVariable(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId,
assigners);
break;
}

View File

@ -4,7 +4,6 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@ -39,12 +38,12 @@ public interface BpmnProcessInstanceConverter extends EntityConverter<BpmnProces
default BpmnProcessInstanceVO toVo(HistoricProcessInstance processInstance,
BpmnProcessDefinitionVO processDefinition,
HistoricVariableInstance initiatorVariableInstance) {
BpmnTaskDelegateAssigner assigner) {
BpmnProcessInstanceVO vo = toVo(processInstance);
vo.setCategory(processDefinition.getCategory());
vo.setProcessDefinitionId(processDefinition.getId());
vo.setProcessDefinitionKey(processInstance.getProcessDefinitionKey());
vo.setInitiator((BpmnTaskDelegateAssigner) initiatorVariableInstance.getValue());
vo.setInitiator(assigner);
return vo;
}
}

View File

@ -31,6 +31,8 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.ReceiveTask;
import org.flowable.bpmn.model.ServiceTask;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.db.SuspensionState;
import org.flowable.common.engine.impl.identity.Authentication;
@ -48,7 +50,6 @@ import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.form.api.FormInfo;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@ -352,9 +353,6 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
if (Objects.isNull(processInstance)) {
throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS);
}
HistoricVariableInstance initiatorVariableInstance = historyService.createHistoricVariableInstanceQuery()
.processInstanceId(processInstance.getId()).variableName(INTERNAL_INITIATOR).singleResult();
// 获得流程定义
BpmnProcessDefinitionVO processDefinition = processDefinitionService
.getProcessDefinition(processInstance.getProcessDefinitionId());
@ -363,7 +361,15 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
processInstance.getProcessDefinitionId());
}
return instanceConverter.toVo(processInstance, processDefinition, initiatorVariableInstance);
BpmnTaskDelegateAssigner assigner;
if (dto.getHasVariable()) {
assigner = (BpmnTaskDelegateAssigner) processInstance.getProcessVariables().get(INTERNAL_INITIATOR);
} else {
assigner = (BpmnTaskDelegateAssigner) runtimeService.getVariable(processInstance.getId(),
INTERNAL_INITIATOR);
}
return instanceConverter.toVo(processInstance, processDefinition, assigner);
}
@Override
@ -553,19 +559,35 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
List<FlowElement> flowElements = forecastService.performProcessForecasting(processInstanceId, instance);
List<ProcessNodeDetailVO> resultList = new ArrayList<>(flowElements.size() + 1);
flowElements.stream().filter(UserTask.class::isInstance).forEach(i -> {
UserTask userTask = (UserTask) i;
ProcessNodeDetailVO node = new ProcessNodeDetailVO().setId(userTask.getId())
.setName(userTask.getName())
.setFormKey(userTask.getFormKey());
if (userTask.getBehavior() instanceof MultiInstanceActivityBehavior) {
MultiInstanceActivityBehavior behavior = (MultiInstanceActivityBehavior) userTask.getBehavior();
node.setNodeMode(Objects.equals(AND_SIGN_EXPRESSION, behavior.getCompletionCondition()) ? AND : OR);
} else if (userTask.getBehavior() instanceof UserTaskActivityBehavior) {
node.setNodeMode(BpmnFlowNodeMode.GENERAL);
}
resultList.add(node);
});
flowElements.stream().filter(i -> (i instanceof UserTask || i instanceof ReceiveTask || i instanceof ServiceTask))
.forEach(i -> {
ProcessNodeDetailVO node = new ProcessNodeDetailVO();
if (i instanceof UserTask) {
UserTask userTask = (UserTask) i;
node.setId(userTask.getId())
.setName(userTask.getName())
.setFormKey(userTask.getFormKey());
if (userTask.getBehavior() instanceof MultiInstanceActivityBehavior) {
MultiInstanceActivityBehavior behavior =
(MultiInstanceActivityBehavior) userTask.getBehavior();
node.setNodeMode(Objects.equals(AND_SIGN_EXPRESSION, behavior.getCompletionCondition()) ?
AND : OR);
} else if (userTask.getBehavior() instanceof UserTaskActivityBehavior) {
node.setNodeMode(BpmnFlowNodeMode.GENERAL);
}
} else if (i instanceof ReceiveTask) {
ReceiveTask receiveTask = (ReceiveTask) i;
node.setId(receiveTask.getId())
.setName(receiveTask.getName());
node.setNodeMode(BpmnFlowNodeMode.BUSINESS);
} else {
ServiceTask serviceTask = (ServiceTask) i;
node.setId(serviceTask.getId())
.setName(serviceTask.getName());
node.setNodeMode(BpmnFlowNodeMode.COPY);
}
resultList.add(node);
});
// 处理发起节点
/*List<FlowElement> startNodes =

View File

@ -86,6 +86,7 @@ import java.util.stream.Collectors;
import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ENDS_AUTOMATICALLY;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_ORIGIN_ASSIGNER;
import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_REMAIN_ASSIGNER_LIST;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_DELETE_PROCESS_FLAG;
@ -292,12 +293,11 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Transactional(rollbackFor = Exception.class)
public void approveTask(BpmnTaskAuditDTO dto) {
// 校验任务存在
String tenantId = Objects.isNull(dto.getApprover()) ? "" : dto.getApprover().getTenantId();
String assignee = Objects.isNull(dto.getApprover()) ? null : dto.getApprover().buildAssigneeId();
TaskEntity task = (TaskEntity) checkTask(tenantId, assignee, dto.getTaskId());
String assignee = dto.getApprover().buildAssigneeId();
TaskEntity task = (TaskEntity) checkTask(assignee, dto.getTaskId());
// 校验流程实例存在
HistoricProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId(),
tenantId, true);
null, true);
if (instance == null) {
throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS);
}
@ -309,8 +309,6 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
if (Objects.nonNull(dto.getNextApprover())) {
runtimeService.setVariable(task.getExecutionId(), INTERNAL_SPECIFY_NEXT_APPROVER, dto.getNextApprover());
}
taskService.setAssignee(task.getId(), assignee);
saveAttachment(dto.getAttachmentList(), instance.getId(), task.getId());
// 主动设置下级审批人
@ -343,15 +341,15 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
BpmnTaskDelegateAssigner remainAssigner = remainAssignerList.remove(0);
log.info("加签父任务:{},下一级流程处理人:{},", parentTaskId,
JSONUtil.toJsonStr(Lists.newArrayList(remainAssigner)));
this.createSubTask(taskEntity, parentTaskId, remainAssigner.buildAssigneeId());
this.createSubTask(taskEntity, parentTaskId, remainAssigner);
taskService.setVariable(taskEntity.getId(), COUNTERSIGN_REMAIN_ASSIGNER_LIST, remainAssignerList);
} else {
String originAssigneeId = (String) taskService.getVariable(taskEntity.getId(),
COUNTERSIGN_ORIGIN_ASSIGNER);
taskService.setAssignee(parentTaskId, originAssigneeId);
//没有剩余加签人进行加签,则是最后一个完成加签的操作
if (BpmnCountersignType.FORWARD_COUNTERSIGN.getType().equals(taskEntity.getScopeType())) {
String originAssigneeId = (String) taskService.getVariable(taskEntity.getId(),
COUNTERSIGN_ORIGIN_ASSIGNER);
//加签父任务向前加签回归原始发起加签的用户
taskService.setAssignee(parentTaskId, originAssigneeId);
log.info("加签父任务:{},向前加签,回归流程原始处理人:{},", parentTaskId, originAssigneeId);
} else if (BpmnCountersignType.BACK_COUNTERSIGN.getType().equals(taskEntity.getScopeType())) {
//向后加签 会直接完成该任务
@ -382,19 +380,19 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
//为了保证顺序优先使用当前剩余加签人列表
newTargetAssignerList.addAll(countersignDTO.getTargetAssignerList());
//再添加之前剩余加签人列表
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(targetAssignerList)) {
if (!CollectionUtils.isEmpty(targetAssignerList)) {
newTargetAssignerList.addAll(targetAssignerList);
}
log.info("正在进行加签任务:{},待加签人合并列表:{}", taskEntity.getId(), JSONUtil.toJsonStr(newTargetAssignerList));
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(newTargetAssignerList)) {
if (!CollectionUtils.isEmpty(newTargetAssignerList)) {
String parentTaskId = taskEntity.getParentTaskId();
if (cn.azxo.framework.common.utils.StringUtils.isBlank(parentTaskId)) {
if (!StringUtils.hasLength(parentTaskId)) {
parentTaskId = taskEntity.getId();
}
String finalParentTaskId = parentTaskId;
BpmnTaskDelegateAssigner removeAssigner = newTargetAssignerList.remove(0);
//创建一个待加签任务并且分配给下一个加签人
this.createSubTask(taskEntity, finalParentTaskId, removeAssigner.buildAssigneeId());
this.createSubTask(taskEntity, finalParentTaskId, removeAssigner);
//动态设置剩余加签人列表,用于任务传递
taskService.setVariable(taskEntity.getId(), COUNTERSIGN_REMAIN_ASSIGNER_LIST, newTargetAssignerList);
}
@ -407,7 +405,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
* @param assignee 子任务的执行人
* @return
*/
protected TaskEntity createSubTask(TaskEntity parentTask, String parentTaskId, String assignee) {
protected TaskEntity createSubTask(TaskEntity parentTask, String parentTaskId, BpmnTaskDelegateAssigner assigner) {
TaskEntity task = null;
if (parentTask != null) {
//1.生成新的工作流子任务
@ -415,7 +413,6 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
task.setCategory(parentTask.getCategory());
task.setDescription(parentTask.getDescription());
task.setTenantId(parentTask.getTenantId());
task.setAssignee(assignee);
task.setName(parentTask.getName());
task.setParentTaskId(parentTaskId);
task.setProcessDefinitionId(parentTask.getProcessDefinitionId());
@ -427,6 +424,9 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
task.setCreateTime(new Date());
log.info("流程加签父任务:{},正在创建加签子任务:{},", parentTaskId, JSONUtil.toJsonStr(Lists.newArrayList(task)));
taskService.saveTask(task);
taskService.setAssignee(task.getId(), assigner.buildAssigneeId());
taskService.setVariable(task.getId(), INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + task.getId(),
assigner);
}
return task;
}
@ -435,7 +435,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Transactional(rollbackFor = Exception.class)
public void rejectTask(BpmnTaskAuditDTO dto) {
// 校验任务存在
Task task = checkTask(dto.getApprover().getTenantId(), dto.getApprover().buildAssigneeId(), dto.getTaskId());
Task task = checkTask(dto.getApprover().buildAssigneeId(), dto.getTaskId());
// 校验流程实例存在
HistoricProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId(),
@ -522,7 +522,10 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
taskService.getProcessInstanceComments(processInstanceId).stream().collect(Collectors.groupingBy(Comment::getTaskId));
Map<String, HistoricVariableInstance> variableInstanceMap =
historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list().stream().collect(Collectors.toMap(HistoricVariableInstance::getVariableName, Function.identity(), (s, t) -> s));
historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId)
.list().stream()
.collect(Collectors.toMap(HistoricVariableInstance::getVariableName,
Function.identity(), (s, t) -> s));
Set<String> taskDefinitionKeys = new HashSet<>();
int count = 0;
@ -544,12 +547,17 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
vo.getAssignee())).filter(i -> Objects.equals(i.getType(), TYPE_COMMENT)).collect(Collectors.toList());
vo.setComments(commentConverter.toVos(comments));
HistoricVariableInstance assgineeSnapshot =
Optional<Comment> operation = taskComments.stream().filter(i -> Objects.equals(i.getTaskId(),
vo.getTaskId()))
.filter(i -> Objects.equals(COMMENT_TYPE_OPERATION, i.getType())).findFirst();
operation.ifPresent(i -> vo.setOperationDesc(i.getFullMessage()));
HistoricVariableInstance assginerSnapshot =
variableInstanceMap.getOrDefault(INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + vo.getTaskId(),
null);
BpmnTaskDelegateAssigner assigner = Objects.nonNull(assgineeSnapshot) ?
(BpmnTaskDelegateAssigner) assgineeSnapshot.getValue() : null;
BpmnTaskDelegateAssigner assigner = Objects.nonNull(assginerSnapshot) ?
(BpmnTaskDelegateAssigner) assginerSnapshot.getValue() : null;
vo.setAssignee(Objects.isNull(assigner) ? "" : assigner.getAssignee());
vo.setAssigneeSnapshot(assigner);
count++;
@ -612,24 +620,21 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
*
* 校验任务是否存在 并且是否是分配给自己的任务
*
* @param tenantId 租户ID
* @param assignee 用户ID
* @param taskId 任务ID
*/
private Task checkTask(String tenantId, String assignee, String taskId) {
private Task checkTask(String assignee, String taskId) {
Task task = getTask(taskId, null, null);
List<BpmnTaskDelegateAssigner> assigners = (List<BpmnTaskDelegateAssigner>) taskService.getVariable(taskId,
INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey());
if (CollectionUtils.isEmpty(assigners)) {
if (Objects.isNull(task)) {
throw new WorkflowEngineException(TASK_COMPLETE_FAIL_NOT_EXISTS);
}
assigners.stream()
.filter(i -> Objects.equals(i.buildAssigneeId(), assignee))
.filter(i -> Objects.equals(i.getTenantId(), tenantId))
.findFirst()
.orElseThrow(() -> new WorkflowEngineException(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF));
return task;
if (!StringUtils.hasLength(assignee)) {
return task;
} else if (StringUtils.hasLength(assignee) && Objects.equals(task.getAssignee(), assignee)) {
return task;
} else {
throw new WorkflowEngineException(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF);
}
}
private Task getTask(String id, String assignee, String tenantId) {
@ -703,15 +708,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Override
@Transactional(rollbackFor = Exception.class)
public void countersignTask(BpmnTaskCountersignDTO dto) {
String tenantId = dto.getOriginAssigner().getTenantId();
Task task = taskService.createTaskQuery().taskId(dto.getTaskId()).active().singleResult();
if (Objects.isNull(task)) {
throw new WorkflowEngineException(TASK_COMPLETE_FAIL_NOT_EXISTS);
}
if (org.apache.commons.lang.StringUtils.isNotEmpty(tenantId)) {
task.setTenantId(tenantId);
}
saveAttachment(dto.getAttachmentList(), task.getProcessInstanceId(), task.getId());
Task task = checkTask(dto.getOriginAssigner().buildAssigneeId(), dto.getTaskId());
if (BpmnCountersignType.isValidAppType(dto.getCountersignType()) != null) {
//加签不能改变BPMN2.0原流程定义因为下一个流程实例不需要加签
String parentTaskId = task.getParentTaskId();
@ -719,11 +716,22 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
//更新当前父任务信息如果该父任务被加签后当前任务用户将看不到该代办信息
//或者其他方式隐藏
if (StringUtil.isEmpty(parentTaskId)) {
task.setOwner(task.getId());
task.setAssignee(task.getId());
// task.setOwner(task.getId());
task.setAssignee(task.getAssignee() + "|" + task.getId());
}
((TaskEntity) task).setScopeType(dto.getCountersignType());
taskService.saveTask(task);
// 设置评论
StringBuilder message = new StringBuilder("添加 ");
for (int i = 0; i < dto.getTargetAssignerList().size(); i++) {
message.append(dto.getTargetAssignerList().get(i).getAssignerName());
if (i < dto.getTargetAssignerList().size() - 1) {
message.append("");
}
}
message.append("").append(dto.getTargetAssignerList().size()).append(" 人会签");
taskService.addComment(task.getId(), task.getProcessInstanceId(), COMMENT_TYPE_OPERATION,
message.toString());
//更新父任务待加签人列表
taskService.setVariable(task.getId(), COUNTERSIGN_ORIGIN_ASSIGNER, originAssigner.buildAssigneeId());
//该父任务加签时会创建子任务用于分配给其他人加签
@ -733,6 +741,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
} else {
throw new WorkflowEngineException(TASK_APOSTILLE_NOT_SUPPORT);
}
saveAttachment(dto.getAttachmentList(), task.getProcessInstanceId(), task.getId());
}
@Override

View File

@ -65,6 +65,9 @@ public abstract class AbstractForecast<T extends FlowElement> implements Forecas
* @return
*/
public List<? extends FlowElement> calcRealOutgoingNodes(List<T> flowElements, ProcessInstance instance) {
if (!CollectionUtils.isEmpty(flowElements) && flowElements.size() == 1) {
return flowElements;
}
return Collections.emptyList();
}

View File

@ -142,7 +142,9 @@ public class RocketMqMessagePushEventListener implements BpmnMessagePushEventLis
variables.put(VAR_PROCESS_INSTANCE_NAME, processInstance.getName());
variables.put(VAR_PROCESS_INSTANCE_ID, processInstance.getId());
variables.put(VAR_PROCESS_START_TIME, sdf.format(processInstance.getCreateAt()));
variables.put(VAR_PROCESS_END_TIME, sdf.format(processInstance.getEndTime()));
if (Objects.nonNull(processInstance.getEndTime())) {
variables.put(VAR_PROCESS_END_TIME, sdf.format(processInstance.getEndTime()));
}
variables.put(VAR_PROCESS_RESULT, processInstance.getResult().getDesc());
if (!StringUtils.hasLength(event.getTaskId())) {

View File

@ -3,6 +3,8 @@ package cn.axzo.workflow.server.controller.listener.task;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
@ -31,7 +33,15 @@ public class SnapshotBpmnTaskTaskEventListener implements BpmnTaskEventListener,
List<BpmnTaskDelegateAssigner> assignerList =
(List<BpmnTaskDelegateAssigner>) delegateTask.getVariable(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + delegateTask.getTaskDefinitionKey());
if (CollectionUtils.isEmpty(assignerList)) {
return;
// 加签
TaskService taskService = CommandContextUtil.getProcessEngineConfiguration().getTaskService();
BpmnTaskDelegateAssigner assigner = taskService.getVariable(delegateTask.getId(),
INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT, BpmnTaskDelegateAssigner.class);
if (Objects.isNull(assigner)) {
return;
} else {
assignerList.add(assigner);
}
}
// identityId_identityType
assignerList.stream().filter(i -> Objects.equals(delegateTask.getAssignee(), i.buildAssigneeId())).findFirst().ifPresent(i -> {

View File

@ -14,7 +14,6 @@ import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstance
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
import cn.axzo.workflow.common.valid.group.ValidGroup;
import cn.axzo.workflow.core.service.BpmnProcessTaskService;
import cn.azxo.framework.common.model.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
@ -72,7 +71,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
*/
@PutMapping("/approve")
@Override
public CommonResponse<Boolean> approveTask(@Validated(ValidGroup.Insert.class) @RequestBody BpmnTaskAuditDTO dto) {
public CommonResponse<Boolean> approveTask(@Validated @RequestBody BpmnTaskAuditDTO dto) {
log.info("同意 approveTask===>>>参数:{}", dto);
bpmnProcessTaskService.approveTask(dto);
return success(true);
@ -83,7 +82,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
*/
@PutMapping("/reject")
@Override
public CommonResponse<Boolean> rejectTask(@Validated(ValidGroup.Update.class) @RequestBody BpmnTaskAuditDTO dto) {
public CommonResponse<Boolean> rejectTask(@Validated @RequestBody BpmnTaskAuditDTO dto) {
log.info("拒绝 rejectTask===>>>参数:{}", dto);
bpmnProcessTaskService.rejectTask(dto);
return success(true);
@ -104,7 +103,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
* 评论
*/
@Override
public CommonResponse<Boolean> commentTask(BpmnTaskCommentDTO commentDTO) {
public CommonResponse<Boolean> commentTask(@Validated @RequestBody BpmnTaskCommentDTO commentDTO) {
bpmnProcessTaskService.commentTask(commentDTO);
return success(true);
}
@ -115,13 +114,13 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
*/
@Override
@PutMapping("/countersign")
public CommonResponse<Boolean> countersignTask(BpmnTaskCountersignDTO countersignDTO) {
public CommonResponse<Boolean> countersignTask(@Validated @RequestBody BpmnTaskCountersignDTO countersignDTO) {
bpmnProcessTaskService.countersignTask(countersignDTO);
return success(true);
}
@Override
public CommonResponse<Boolean> remindTask(BpmnTaskRemindDTO dto) {
public CommonResponse<Boolean> remindTask(@Validated @RequestBody BpmnTaskRemindDTO dto) {
bpmnProcessTaskService.remindTask(dto);
return success(true);
}