update - 测试新增加签逻辑后的审批日志中,无法对加签功能正常使用/展示的问题
This commit is contained in:
parent
491d064c01
commit
16f45358f7
@ -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 = "审批拒绝自动结束";
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ public class BpmnTaskCountersignDTO implements Serializable {
|
||||
*/
|
||||
@ApiModelProperty(value = "加签类型")
|
||||
@NotEmpty(message = "加签类型不能为空")
|
||||
private String countersignType ;
|
||||
private String countersignType = "FORWARD_COUNTERSIGN";
|
||||
|
||||
/**
|
||||
* 附件列表
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,4 +34,5 @@ public class ProcessNodeDetailVO {
|
||||
*/
|
||||
private String formKey;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -61,6 +61,9 @@ public class BpmnHistoricTaskInstanceVO {
|
||||
@ApiModelProperty(value = "删除原因")
|
||||
private String deleteReason;
|
||||
|
||||
@ApiModelProperty(value = "操作描述")
|
||||
private String operationDesc;
|
||||
|
||||
@ApiModelProperty(value = "审批人的快照信息", notes = "完整的审批人信息,assignee 仅是唯一标识")
|
||||
private BpmnTaskDelegateAssigner assigneeSnapshot;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 =
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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())) {
|
||||
|
||||
@ -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 -> {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user