update - 迁移部分 2090 原分支代码
This commit is contained in:
parent
0df7a1ce0d
commit
5e7debcb7a
@ -18,10 +18,6 @@
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-consumer-spring-cloud-starter</artifactId>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-spring-boot-starter</artifactId>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>workflow-engine-common</artifactId>
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn.process;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.BpmPageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用于超管查询所有的流程实例入参模型
|
||||
*
|
||||
* @author wangli
|
||||
* @since 06/03/2024 2:35 pm
|
||||
*/
|
||||
@ApiModel("用于超管查询所有的流程实例入参模型")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class BpmnProcessInstanceAdminPageReqVO extends BpmPageParam {
|
||||
|
||||
@ApiModelProperty(value = "流程名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "审批业务分类")
|
||||
private String category;
|
||||
|
||||
@ApiModelProperty(value = "流程状态")
|
||||
private String businessStatus;
|
||||
|
||||
@ApiModelProperty(value = "租户Id")
|
||||
private String tenantId;
|
||||
|
||||
@ApiModelProperty(value = "开始时间")
|
||||
private Date startTime;
|
||||
|
||||
@ApiModelProperty(value = "结束时间")
|
||||
private Date endTime;
|
||||
|
||||
}
|
||||
@ -5,10 +5,12 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.NO_TENANT_ID;
|
||||
|
||||
@ -29,6 +31,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.NO_TENANT_ID;
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmnTaskDelegateAssigner implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8106887960942113552L;
|
||||
@ -102,6 +105,31 @@ public class BpmnTaskDelegateAssigner implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean compareToOther(BpmnTaskDelegateAssigner other) {
|
||||
return Objects.equals(personId, other.getPersonId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 对引擎表中存的真实 assignee 进行比对
|
||||
*
|
||||
* @param assignee
|
||||
* @return
|
||||
*/
|
||||
public final boolean compareToOther(String assignee) {
|
||||
if (!StringUtils.hasText(assignee)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
String[] split = assignee.split("\\|");
|
||||
if (Objects.equals(split[1], personId)) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("审批人模型数据比对发现意外数据, assignee: " + assignee);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static BpmnTaskDelegateAssigner buildDummyAssigner(String assignee,
|
||||
String assigneeType,
|
||||
String assignerName) {
|
||||
|
||||
@ -0,0 +1,109 @@
|
||||
package cn.axzo.workflow.common.model.response.bpmn.process;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 超管流程实例的分页响应模型
|
||||
*
|
||||
* @author wangli
|
||||
* @since 06/03/2024 2:37 pm
|
||||
*/
|
||||
@ApiModel("超管流程实例的分页响应模型")
|
||||
@Data
|
||||
public class BpmnProcessInstanceAdminPageItemVO {
|
||||
|
||||
/**
|
||||
* 流程实例 ID
|
||||
*/
|
||||
@ApiModelProperty(value = "流程实例 ID")
|
||||
private String processInstanceId;
|
||||
|
||||
/**
|
||||
* 流程实例名称
|
||||
*/
|
||||
@ApiModelProperty(value = "流程实例名称")
|
||||
private String processInstanceName;
|
||||
|
||||
/**
|
||||
* 业务状态
|
||||
*/
|
||||
@ApiModelProperty(value = "业务状态")
|
||||
private String businessStatus;
|
||||
|
||||
/**
|
||||
* 业务状态描述
|
||||
*/
|
||||
@ApiModelProperty(value = "业务状态描述")
|
||||
private String businessStatusDesc;
|
||||
|
||||
/**
|
||||
* 分类
|
||||
*/
|
||||
@ApiModelProperty(value = "审批业务分类")
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 分类描述
|
||||
*/
|
||||
@ApiModelProperty(value = "审批业务分类描述")
|
||||
private String categoryDesc;
|
||||
|
||||
/**
|
||||
* 分类关联项目部类型
|
||||
*/
|
||||
@ApiModelProperty(value = "项目部类型")
|
||||
private String workspaceTypeCode;
|
||||
|
||||
/**
|
||||
* 租户 ID
|
||||
*/
|
||||
@ApiModelProperty(value = "租户 ID")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 流程实例的总节点数
|
||||
*/
|
||||
@ApiModelProperty(value = "流程实例的总节点数")
|
||||
private Integer totalNodeCount;
|
||||
|
||||
/**
|
||||
* 当前运行到的节点
|
||||
*/
|
||||
@ApiModelProperty(value = "当前运行到的节点")
|
||||
private Integer currentNodeCount;
|
||||
|
||||
/**
|
||||
* 最近已完成的节点的结束时间
|
||||
*/
|
||||
@ApiModelProperty(value = "最近已完成的节点的结束时间")
|
||||
private Date leastCompleteActivityEndTime;
|
||||
|
||||
/**
|
||||
* 当前活动 ID
|
||||
*/
|
||||
@ApiModelProperty(value = "当前活动 ID")
|
||||
private String currentActivityId;
|
||||
|
||||
/**
|
||||
* 当期活动的名称
|
||||
*/
|
||||
@ApiModelProperty(value = "当期活动的名称")
|
||||
private String currentActivityName;
|
||||
|
||||
/**
|
||||
* 流程实例开始时间
|
||||
*/
|
||||
@ApiModelProperty(value = "流程实例开始时间")
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 流程实例结束事件
|
||||
*/
|
||||
@ApiModelProperty(value = "流程实例结束事件")
|
||||
private Date endTime;
|
||||
|
||||
}
|
||||
@ -14,6 +14,7 @@ import cn.axzo.workflow.core.engine.event.BizSpecifyAssigneeEventImpl;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
|
||||
@ -42,10 +43,11 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_ALLOW_SKIP_USER
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.DUMMY_ASSIGNEE;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.DUMMY_ASSIGNEE_TYPE;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_121;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_130;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_BUSINESS;
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_TASK;
|
||||
import static cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner.buildDummyAssigner;
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprovalMethod;
|
||||
@ -89,6 +91,16 @@ public class EngineExecutionStartListener implements ExecutionListener {
|
||||
if (execution.hasVariable(assigneeListVariableName)) {
|
||||
return;
|
||||
}
|
||||
if (Objects.equals(NODE_STARTER.getType(), currentActivityId)) {
|
||||
// UserTask 多实例, 该变量用于引擎
|
||||
BpmnTaskDelegateAssigner initiator = execution.getVariable(INTERNAL_INITIATOR,
|
||||
BpmnTaskDelegateAssigner.class);
|
||||
execution.setVariable(assigneeListVariableName, initiator.buildAssigneeId());
|
||||
|
||||
execution.setVariable(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId,
|
||||
Lists.newArrayList(initiator));
|
||||
return;
|
||||
}
|
||||
|
||||
Process mainProcess = ProcessDefinitionUtil.getBpmnModel(execution.getProcessDefinitionId()).getMainProcess();
|
||||
UserTask userTask = (UserTask) mainProcess.getFlowElement(currentActivityId);
|
||||
@ -96,67 +108,81 @@ public class EngineExecutionStartListener implements ExecutionListener {
|
||||
// 从 version=1.2.1-SNAPSHOT 开始,才给 process 节点增加了 serverVersion 属性
|
||||
Optional<String> processServerVersion = getProcessServerVersion(mainProcess);
|
||||
if (processServerVersion.isPresent()) {
|
||||
Optional<BpmnFlowNodeType> nodeType = getNodeType(userTask);
|
||||
if ((Objects.equals(FLOW_SERVER_VERSION_121, processServerVersion.get()) || Objects.equals(FLOW_SERVER_VERSION_130, processServerVersion.get()))
|
||||
&& nodeType.isPresent()
|
||||
&& (Objects.equals(NODE_TASK, nodeType.get()) || Objects.equals(NODE_BUSINESS, nodeType.get()))) {
|
||||
getApprovalMethod(userTask).ifPresent(method -> {
|
||||
List<String> assigneeIdList = new ArrayList<>();
|
||||
switch (method) {
|
||||
case autoPassed:
|
||||
case autoRejection:
|
||||
// Do nothing.
|
||||
// 统一由 cn.axzo.workflow.server.controller.listener.task.AutoOperatorEventListener 来处理
|
||||
break;
|
||||
case bizSpecify:
|
||||
// 构建一个虚拟的审批人,避免因为没有审批人而导致流程触发了"审批人为空时"的处理逻辑, 当业务传入审批人时,需要更新这里的变量
|
||||
BpmnTaskDelegateAssigner dummyApprover = buildDummyAssigner(DUMMY_ASSIGNEE,
|
||||
DUMMY_ASSIGNEE_TYPE, "dummyApprover");
|
||||
|
||||
List<String> dummyAssigneeIdList = new ArrayList<>();
|
||||
dummyAssigneeIdList.add(dummyApprover.buildAssigneeId());
|
||||
execution.setVariable(assigneeListVariableName, dummyAssigneeIdList);
|
||||
|
||||
execution.setVariable(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId, Lists.newArrayList(dummyApprover));
|
||||
|
||||
// 触发事件
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
CommandContextUtil.getProcessEngineConfiguration();
|
||||
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
|
||||
eventDispatcher.dispatchEvent(new BizSpecifyAssigneeEventImpl(ADD_ASSIGNEE, execution),
|
||||
processEngineConfiguration.getEngineCfgKey());
|
||||
break;
|
||||
default:
|
||||
// 这里只会是 human 这一种情况, 因为 nobody 在转 BPMN 协议时,Activity 直接变成了 ReceiveTask 节点了。
|
||||
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
|
||||
getApproverSpecify(userTask).ifPresent(specify -> {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("当前审批节点ID: {}, 节点名称: {}, 审批人指定方式: {}", userTask.getId(),
|
||||
userTask.getName(), specify.getDesc());
|
||||
}
|
||||
assigners.addAll(approverSelect(specify.getType(), userTask, execution, true));
|
||||
});
|
||||
|
||||
// 审批候选人为空时的兜底
|
||||
emptyAssigneeHandle(assigners, userTask, execution);
|
||||
|
||||
for (BpmnTaskDelegateAssigner user : assigners) {
|
||||
assigneeIdList.add(user.buildAssigneeId());
|
||||
}
|
||||
|
||||
execution.setVariable(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId,
|
||||
assigners);
|
||||
break;
|
||||
}
|
||||
// UserTask 多实例, 该变量用于引擎
|
||||
execution.setVariable(assigneeListVariableName, assigneeIdList);
|
||||
});
|
||||
}
|
||||
calcTaskAssigner121(execution, userTask, processServerVersion.get(), assigneeListVariableName,
|
||||
currentActivityId);
|
||||
} else {
|
||||
defaultCalcTaskAssigner(execution, userTask, currentActivityId, assigneeListVariableName);
|
||||
calcTaskAssignerDefault(execution, userTask, currentActivityId, assigneeListVariableName);
|
||||
}
|
||||
}
|
||||
|
||||
private void calcTaskAssigner121(DelegateExecution execution, UserTask userTask, String processServerVersion,
|
||||
String assigneeListVariableName, String currentActivityId) {
|
||||
Optional<BpmnFlowNodeType> nodeType = getNodeType(userTask);
|
||||
DefaultArtifactVersion supportVersion = new DefaultArtifactVersion(FLOW_SERVER_VERSION_121);
|
||||
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(processServerVersion);
|
||||
if (currentVersion.compareTo(supportVersion) >= 0 && nodeType.isPresent()
|
||||
&& (Objects.equals(NODE_TASK, nodeType.get()) || Objects.equals(NODE_BUSINESS, nodeType.get()))) {
|
||||
getApprovalMethod(userTask).ifPresent(method -> {
|
||||
List<String> assigneeIdList = new ArrayList<>();
|
||||
switch (method) {
|
||||
case autoPassed:
|
||||
case autoRejection:
|
||||
// Do nothing.
|
||||
// 统一由 cn.axzo.workflow.server.controller.listener.task.AutoOperatorEventListener 来处理
|
||||
break;
|
||||
case bizSpecify:
|
||||
// 构建一个虚拟的审批人,避免因为没有审批人而导致流程触发了"审批人为空时"的处理逻辑, 当业务传入审批人时,需要更新这里的变量
|
||||
BpmnTaskDelegateAssigner dummyApprover = buildDummyAssigner(DUMMY_ASSIGNEE,
|
||||
DUMMY_ASSIGNEE_TYPE, "dummyApprover");
|
||||
|
||||
List<String> dummyAssigneeIdList = new ArrayList<>();
|
||||
dummyAssigneeIdList.add(dummyApprover.buildAssigneeId());
|
||||
execution.setVariable(assigneeListVariableName, dummyAssigneeIdList);
|
||||
|
||||
execution.setVariable(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId, Lists.newArrayList(dummyApprover));
|
||||
|
||||
// 触发事件
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
CommandContextUtil.getProcessEngineConfiguration();
|
||||
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
|
||||
eventDispatcher.dispatchEvent(new BizSpecifyAssigneeEventImpl(ADD_ASSIGNEE, execution),
|
||||
processEngineConfiguration.getEngineCfgKey());
|
||||
break;
|
||||
default:
|
||||
// 这里只会是 human 这一种情况, 因为 nobody 在转 BPMN 协议时,Activity 直接变成了 ReceiveTask 节点了。
|
||||
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
|
||||
getApproverSpecify(userTask).ifPresent(specify -> {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("当前审批节点ID: {}, 节点名称: {}, 审批人指定方式: {}", userTask.getId(),
|
||||
userTask.getName(), specify.getDesc());
|
||||
}
|
||||
assigners.addAll(approverSelect(specify.getType(), userTask, execution, true));
|
||||
});
|
||||
|
||||
// 审批候选人为空时的兜底
|
||||
emptyAssigneeHandle(assigners, userTask, execution);
|
||||
|
||||
for (BpmnTaskDelegateAssigner user : assigners) {
|
||||
assigneeIdList.add(user.buildAssigneeId());
|
||||
}
|
||||
|
||||
execution.setVariable(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId,
|
||||
assigners);
|
||||
break;
|
||||
}
|
||||
// UserTask 多实例, 该变量用于引擎
|
||||
execution.setVariable(assigneeListVariableName, assigneeIdList);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算节点的待审批人为空时, 执行模型配置中的审批人为空时的处理方式
|
||||
*
|
||||
* @param assigners 节点计算的待审批人集合, 可能为空
|
||||
* @param userTask 当前节点
|
||||
* @param execution 当前执行实例
|
||||
*/
|
||||
private void emptyAssigneeHandle(List<BpmnTaskDelegateAssigner> assigners, UserTask userTask,
|
||||
DelegateExecution execution) {
|
||||
// 审批人为空并且当前节点设置了自动跳过条件
|
||||
@ -250,7 +276,7 @@ public class EngineExecutionStartListener implements ExecutionListener {
|
||||
* @param assigneeListVariableName
|
||||
*/
|
||||
@Deprecated
|
||||
private void defaultCalcTaskAssigner(DelegateExecution execution, UserTask userTask, String currentActivityId,
|
||||
private void calcTaskAssignerDefault(DelegateExecution execution, UserTask userTask, String currentActivityId,
|
||||
String assigneeListVariableName) {
|
||||
|
||||
BpmnTaskCalculateDTO calculateDTO = new BpmnTaskCalculateDTO();
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package cn.axzo.workflow.core.service;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
|
||||
@ -8,6 +9,7 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyP
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.HistoricProcessInstanceSearchDTO;
|
||||
import cn.axzo.workflow.common.model.response.BpmPageResult;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.HistoricProcessInstanceVO;
|
||||
@ -46,6 +48,14 @@ public interface BpmnProcessInstanceService {
|
||||
*/
|
||||
Boolean abortProcessInstance(BpmnProcessInstanceAbortDTO dto);
|
||||
|
||||
/**
|
||||
* 超管查询所有流程实例数据
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
BpmPageResult<BpmnProcessInstanceAdminPageItemVO> getAdminProcessInstancePage(BpmnProcessInstanceAdminPageReqVO dto);
|
||||
|
||||
/**
|
||||
* 获得流程实例的分页 / 我发起的审批列表
|
||||
*
|
||||
|
||||
@ -62,6 +62,15 @@ public interface CategoryService {
|
||||
*/
|
||||
List<CategoryItemVO> list(CategorySearchDTO dto);
|
||||
|
||||
/**
|
||||
* 查询指定类型和指定标签的数据
|
||||
*
|
||||
* @param type
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
List<CategoryItemVO> listByValue(String type, List<String> values);
|
||||
|
||||
/**
|
||||
* 分页搜索
|
||||
*
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
package cn.axzo.workflow.core.service.converter;
|
||||
|
||||
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.runtime.ActivityInstance;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
|
||||
import static org.mapstruct.NullValueCheckStrategy.ALWAYS;
|
||||
|
||||
/**
|
||||
* 流程实例分页模型的 MapStruts 转换器
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/1/25 16:31
|
||||
*/
|
||||
@Mapper(
|
||||
componentModel = "spring",
|
||||
nullValueCheckStrategy = ALWAYS,
|
||||
imports = Arrays.class
|
||||
)
|
||||
public interface BpmnProcessInstanceAdminPageItemConverter extends EntityConverter<BpmnProcessInstanceAdminPageItemVO,
|
||||
HistoricProcessInstance> {
|
||||
|
||||
@Mapping(target = "processInstanceId", source = "id")
|
||||
@Mapping(target = "processInstanceName", source = "name")
|
||||
@Mapping(target = "businessStatus", source = "businessStatus")
|
||||
@Mapping(target = "category", source = "processDefinitionKey")
|
||||
@Mapping(target = "startTime", source = "startTime")
|
||||
@Mapping(target = "endTime", source = "endTime")
|
||||
@Mapping(target = "tenantId", source = "tenantId")
|
||||
@Override
|
||||
BpmnProcessInstanceAdminPageItemVO toVo(HistoricProcessInstance entity);
|
||||
|
||||
default List<BpmnProcessInstanceAdminPageItemVO> toVos(List<HistoricProcessInstance> instances,
|
||||
Map<String, List<FlowElement>> instanceFlowElementMap,
|
||||
Map<String, ActivityInstance> liveActivityMap,
|
||||
Map<String, ActivityInstance> leastEndActivityMap,
|
||||
Map<String, CategoryItemVO> categoryMap) {
|
||||
List<BpmnProcessInstanceAdminPageItemVO> result = new ArrayList<>();
|
||||
instances.forEach(i -> {
|
||||
BpmnProcessInstanceAdminPageItemVO vo = toVo(i);
|
||||
if (Objects.equals(PROCESSING.getStatus(), i.getBusinessStatus())) {
|
||||
List<FlowElement> flowElements =
|
||||
instanceFlowElementMap.get(i.getId()).stream().filter(UserTask.class::isInstance).collect(Collectors.toList());
|
||||
vo.setTotalNodeCount(flowElements.size());
|
||||
|
||||
// 进行中的节点
|
||||
ActivityInstance activityInstance = liveActivityMap.get(i.getId());
|
||||
for (int j = 0; j < flowElements.size(); j++) {
|
||||
if (Objects.equals(flowElements.get(j).getId(), activityInstance.getActivityId())) {
|
||||
vo.setCurrentNodeCount(j + 1);
|
||||
vo.setCurrentActivityId(activityInstance.getActivityId());
|
||||
vo.setCurrentActivityName(activityInstance.getActivityName());
|
||||
}
|
||||
}
|
||||
|
||||
// 最后已结束的节点
|
||||
ActivityInstance leastEndActivity = leastEndActivityMap.get(i.getId());
|
||||
vo.setLeastCompleteActivityEndTime(leastEndActivity.getEndTime());
|
||||
|
||||
}
|
||||
CategoryItemVO category = categoryMap.getOrDefault(i.getProcessDefinitionKey(), new CategoryItemVO());
|
||||
vo.setCategoryDesc(category.getLabel());
|
||||
vo.setWorkspaceTypeCode(category.getWorkspaceTypeCode());
|
||||
vo.setBusinessStatusDesc(BpmnProcessInstanceResultEnum.valueOfStatus(vo.getBusinessStatus()).getDesc());
|
||||
result.add(vo);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package cn.axzo.workflow.core.service.impl;
|
||||
|
||||
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
|
||||
@ -11,10 +12,12 @@ import cn.axzo.workflow.common.model.request.bpmn.process.HistoricProcessInstanc
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.common.model.response.BpmPageResult;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.HistoricProcessInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
|
||||
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnCollectionUtils;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomAbortProcessInstanceCmd;
|
||||
@ -23,8 +26,10 @@ import cn.axzo.workflow.core.engine.cmd.CustomForecastUserTaskAssigneeCmd;
|
||||
import cn.axzo.workflow.core.engine.listener.EngineExecutionStartListener;
|
||||
import cn.axzo.workflow.core.service.BpmnProcessDefinitionService;
|
||||
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
|
||||
import cn.axzo.workflow.core.service.CategoryService;
|
||||
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
||||
import cn.axzo.workflow.core.service.converter.BpmnHistoricProcessInstanceConverter;
|
||||
import cn.axzo.workflow.core.service.converter.BpmnProcessInstanceAdminPageItemConverter;
|
||||
import cn.axzo.workflow.core.service.converter.BpmnProcessInstanceConverter;
|
||||
import cn.axzo.workflow.core.service.converter.BpmnProcessInstancePageItemConverter;
|
||||
import cn.axzo.workflow.core.service.support.FlowNodeForecastService;
|
||||
@ -50,7 +55,10 @@ import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.history.HistoricProcessInstanceQuery;
|
||||
import org.flowable.engine.history.NativeHistoricProcessInstanceQuery;
|
||||
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
|
||||
import org.flowable.engine.impl.persistence.entity.ActivityInstanceEntity;
|
||||
import org.flowable.engine.repository.ProcessDefinition;
|
||||
import org.flowable.engine.runtime.ActivityInstance;
|
||||
import org.flowable.engine.runtime.NativeActivityInstanceQuery;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.engine.runtime.ProcessInstanceQuery;
|
||||
import org.flowable.form.api.FormInfo;
|
||||
@ -63,15 +71,19 @@ import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_MODEL_CATEGORY;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_121;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_130;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
|
||||
@ -88,6 +100,7 @@ import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR;
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_BUSINESS;
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_CARBON_COPY;
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_ID_NOT_EXISTS;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS;
|
||||
import static cn.axzo.workflow.core.common.code.BpmnProcessDefinitionRespCode.PROCESS_DEFINITION_ID_NOT_EXISTS;
|
||||
@ -113,6 +126,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
|
||||
@Resource
|
||||
private HistoryService historyService;
|
||||
@Resource
|
||||
private BpmnProcessInstanceAdminPageItemConverter instanceAdminPageItemConverter;
|
||||
@Resource
|
||||
private BpmnProcessInstancePageItemConverter instancePageItemConverter;
|
||||
@Resource
|
||||
private BpmnProcessInstanceConverter instanceConverter;
|
||||
@ -130,6 +145,8 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
|
||||
private SpringProcessEngineConfiguration springProcessEngineConfiguration;
|
||||
@Resource
|
||||
private ExtAxHiTaskInstService extAxHiTaskInstService;
|
||||
@Resource
|
||||
private CategoryService categoryService;
|
||||
|
||||
@Override
|
||||
public HistoricProcessInstance getProcessInstanceByBusinessKey(String businessKey, @Nullable String tenantId,
|
||||
@ -327,6 +344,93 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BpmPageResult<BpmnProcessInstanceAdminPageItemVO> getAdminProcessInstancePage(BpmnProcessInstanceAdminPageReqVO dto) {
|
||||
HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
|
||||
if (StringUtils.isNotBlank(dto.getName())) {
|
||||
query.processInstanceNameLike(dto.getName());
|
||||
}
|
||||
if (StringUtils.isNotBlank(dto.getCategory())) {
|
||||
query.processDefinitionCategory(dto.getCategory());
|
||||
}
|
||||
if (StringUtils.isNotBlank(dto.getTenantId())) {
|
||||
query.processInstanceTenantId(dto.getTenantId());
|
||||
}
|
||||
if (StringUtils.isNotBlank(dto.getBusinessStatus())) {
|
||||
query.processInstanceBusinessStatus(dto.getBusinessStatus());
|
||||
}
|
||||
if (Objects.nonNull(dto.getStartTime()) && Objects.nonNull(dto.getEndTime())) {
|
||||
query.startedAfter(dto.getStartTime());
|
||||
query.startedBefore(dto.getEndTime());
|
||||
}
|
||||
List<HistoricProcessInstance> instances = query.orderByProcessInstanceStartTime().desc()
|
||||
.listPage((dto.getPageNo() - 1) * dto.getPageSize(), dto.getPageSize());
|
||||
|
||||
if (CollectionUtils.isEmpty(instances)) {
|
||||
return BpmPageResult.empty();
|
||||
}
|
||||
|
||||
List<String> processingInstanceIds =
|
||||
instances.stream().filter(i -> Objects.equals(PROCESSING.getStatus(), i.getBusinessStatus()))
|
||||
.map(HistoricProcessInstance::getId).distinct().collect(Collectors.toList());
|
||||
Map<String, List<FlowElement>> instanceFlowElementMap = new HashMap<>();
|
||||
processingInstanceIds.forEach(i -> {
|
||||
// 查询每个流程推测出来的总节点数
|
||||
instanceFlowElementMap.put(i, forecastService.performProcessForecasting(i, null));
|
||||
});
|
||||
|
||||
// 实例对应的当前运行到的节点
|
||||
Map<String, ActivityInstance> liveActivityMap = getInstanceCurrentActivity(processingInstanceIds, false);
|
||||
// 实例对应的最后一个已经完成的节点
|
||||
Map<String, ActivityInstance> leastEndActivityMap = getInstanceLastActivity(processingInstanceIds);
|
||||
|
||||
List<String> categories = instances.stream().map(HistoricProcessInstance::getProcessDefinitionKey)
|
||||
.distinct().collect(Collectors.toList());
|
||||
Map<String, CategoryItemVO> categoryLabelMap = categoryService.listByValue(BPM_MODEL_CATEGORY, categories)
|
||||
.stream().collect(Collectors.toMap(CategoryItemVO::getValue, Function.identity(), (s, t) -> s));
|
||||
|
||||
List<BpmnProcessInstanceAdminPageItemVO> vos = instanceAdminPageItemConverter.toVos(instances,
|
||||
instanceFlowElementMap, liveActivityMap, leastEndActivityMap,
|
||||
categoryLabelMap);
|
||||
return new BpmPageResult<>(vos, query.count());
|
||||
}
|
||||
|
||||
private Map<String, ActivityInstance> getInstanceLastActivity(List<String> processInstanceIds) {
|
||||
return getInstanceCurrentActivity(processInstanceIds, true);
|
||||
}
|
||||
|
||||
private Map<String, ActivityInstance> getInstanceCurrentActivity(List<String> processInstanceIds,
|
||||
boolean leastEndActivity) {
|
||||
if (CollectionUtils.isEmpty(processInstanceIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
NativeActivityInstanceQuery nativeQuery = runtimeService.createNativeActivityInstanceQuery();
|
||||
String tableName = managementService.getTableName(ActivityInstanceEntity.class);
|
||||
StringBuilder querySql = new StringBuilder();
|
||||
querySql.append("SELECT * FROM (")
|
||||
.append("SELECT *, ROW_NUMBER() OVER (PARTITION BY PROC_INST_ID_ ORDER BY START_TIME_ DESC) AS rn ")
|
||||
.append(" FROM ")
|
||||
.append(tableName)
|
||||
.append(" WHERE PROC_INST_ID_ in (");
|
||||
for (int i = 0; i < processInstanceIds.size(); i++) {
|
||||
querySql.append("#{processInstanceId_").append(i).append("}");
|
||||
if (i < processInstanceIds.size() - 1) {
|
||||
querySql.append(",");
|
||||
}
|
||||
nativeQuery.parameter("processInstanceId_" + i, processInstanceIds.get(i));
|
||||
}
|
||||
querySql.append(") and TASK_ID_ is not null ");
|
||||
if (leastEndActivity) {
|
||||
querySql.append(" and END_TIME_ is not null");
|
||||
}
|
||||
querySql.append(") as t WHERE rn = 1");
|
||||
return nativeQuery.sql(querySql.toString()).list().stream()
|
||||
.collect(Collectors.toMap(ActivityInstance::getProcessInstanceId, Function.identity(),
|
||||
(s, t) -> s));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public HistoricProcessInstance getHistoricProcessInstance(String id, String tenantId) {
|
||||
HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().processInstanceId(id);
|
||||
|
||||
@ -230,6 +230,16 @@ public class CategoryServiceImpl extends ServiceImpl<ExtAxDictMapper, ExtAxDict>
|
||||
return categoryConverter.toVos(extAxDicts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CategoryItemVO> listByValue(String type, List<String> values) {
|
||||
LambdaQueryWrapper<ExtAxDict> queryWrapper = Wrappers.lambdaQuery(ExtAxDict.class)
|
||||
.eq(StringUtils.isNotBlank(type), ExtAxDict::getType, type)
|
||||
.in(!CollectionUtils.isEmpty(values), ExtAxDict::getValue, values)
|
||||
.eq(ExtAxDict::getIsDelete, 0);
|
||||
List<ExtAxDict> extAxDicts = dictMapper.selectList(queryWrapper);
|
||||
return categoryConverter.toVos(extAxDicts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean checkCategoryStatus(Long tenantId, String categoryCode) {
|
||||
Optional<CategoryItemVO> optCategory = get(BPM_MODEL_CATEGORY, categoryCode);
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
package cn.axzo.workflow.server.controller.listener.task;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
|
||||
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.HistoryService;
|
||||
@ -21,14 +24,20 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
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.INTERNAL_DELETE_PROCESS_FLAG;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_TENANT_ID;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_ID;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_NAME;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_TYPE_REJECT;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_TASK;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED;
|
||||
import static cn.axzo.workflow.core.common.enums.BpmnProcessTaskResultEnum.REJECTION_AUTO_COMPLETED;
|
||||
@ -45,23 +54,129 @@ import static cn.axzo.workflow.core.common.enums.BpmnProcessTaskResultEnum.REJEC
|
||||
public class AutoOperatorEventListener implements BpmnTaskEventListener, Ordered {
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Integer.MIN_VALUE + 103;
|
||||
return Integer.MIN_VALUE + 102;
|
||||
}
|
||||
|
||||
private final TaskService taskService;
|
||||
private final RuntimeService runtimeService;
|
||||
private final RepositoryService repositoryService;
|
||||
private final HistoryService historyService;
|
||||
private final ExtAxHiTaskInstService extAxHiTaskInstService;
|
||||
|
||||
@Override
|
||||
public void onCreated(DelegateTask delegateTask) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("AutoOperatorEventListener#onCreated...{}", delegateTask.getTaskDefinitionKey());
|
||||
}
|
||||
|
||||
if (Objects.equals(NODE_STARTER.getType(), delegateTask.getId())) {
|
||||
BpmnTaskDelegateAssigner initiator = delegateTask.getVariable(INTERNAL_INITIATOR,
|
||||
BpmnTaskDelegateAssigner.class);
|
||||
delegateTask.setVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + delegateTask.getId(),
|
||||
initiator);
|
||||
delegateTask.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + delegateTask.getId(),
|
||||
APPROVED.getStatus());
|
||||
// 直接完成
|
||||
taskService.complete(delegateTask.getId(), runtimeService.getVariables(delegateTask.getExecutionId()));
|
||||
return;
|
||||
}
|
||||
Process mainProcess = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId()).getMainProcess();
|
||||
UserTask userTask = (UserTask) mainProcess.getFlowElement(delegateTask.getTaskDefinitionKey());
|
||||
|
||||
// 如果 approverMethod = 自动通过或自动驳回时
|
||||
checkApprovalMethod(delegateTask, userTask);
|
||||
|
||||
boolean exists = checkApproverExists(delegateTask, userTask, mainProcess);
|
||||
if (exists) {
|
||||
taskService.addComment(delegateTask.getId(), delegateTask.getProcessInstanceId(), COMMENT_TYPE_ADVICE,
|
||||
"同一审批人,自动过审");
|
||||
autoPass(delegateTask);
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("AutoOperatorEventListener#onCreated...end: {}", delegateTask.getTaskDefinitionKey());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验当前的审批人是否存在过前一个节点
|
||||
*
|
||||
* @param delegateTask
|
||||
* @param userTask
|
||||
* @param mainProcess
|
||||
*/
|
||||
private boolean checkApproverExists(DelegateTask delegateTask, UserTask userTask, Process mainProcess) {
|
||||
AtomicBoolean exists = new AtomicBoolean(false);
|
||||
historyService.createHistoricActivityInstanceQuery()
|
||||
.processInstanceId(delegateTask.getProcessInstanceId())
|
||||
.orderByHistoricActivityInstanceStartTime()
|
||||
.desc().list().stream()
|
||||
.filter(i -> !Objects.equals(i.getActivityId(), userTask.getId()))
|
||||
.filter(i -> Objects.equals(i.getActivityType(), "userTask"))
|
||||
.findFirst()
|
||||
.ifPresent(i -> {
|
||||
// 与发起人比对
|
||||
if (Objects.equals(NODE_STARTER.getType(), i.getActivityId())) {
|
||||
BpmnTaskDelegateAssigner initiator = delegateTask.getVariable(INTERNAL_INITIATOR,
|
||||
BpmnTaskDelegateAssigner.class);
|
||||
// FIXME 这里可能需要进行多版本处理
|
||||
if (initiator.compareToOther(delegateTask.getAssignee())) {
|
||||
exists.compareAndSet(false, true);
|
||||
}
|
||||
} else {
|
||||
FlowElement flowElement = mainProcess.getFlowElement(i.getActivityId());
|
||||
BpmnMetaParserHelper.getNodeType(flowElement).ifPresent(j -> {
|
||||
if (Objects.equals(NODE_TASK, j)) {
|
||||
// TODO 这里可能需要用 extAxHiTaskInstService 来支撑, 而不是用引擎自带表
|
||||
historyService.createHistoricTaskInstanceQuery()
|
||||
.processInstanceId(delegateTask.getProcessInstanceId())
|
||||
.taskDefinitionKey(i.getActivityId()).list()
|
||||
.stream().map(HistoricTaskInstance::getAssignee)
|
||||
.filter(k -> Objects.equals(k, delegateTask.getAssignee()))
|
||||
.findAny().ifPresent(k -> {
|
||||
exists.compareAndSet(false, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return exists.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果审批人为空时, 读取 approverEmptyHandleType = 自动通过或自动驳回时
|
||||
*
|
||||
* @param delegateTask
|
||||
* @param userTask
|
||||
*/
|
||||
private void checkApproverEmptyHandle(DelegateTask delegateTask, UserTask userTask) {
|
||||
if (!StringUtils.hasLength(delegateTask.getAssignee())) {
|
||||
BpmnMetaParserHelper.getApproverEmptyHandleType(userTask)
|
||||
.ifPresent(approverEmptyHandleTypeEnum -> {
|
||||
switch (approverEmptyHandleTypeEnum) {
|
||||
case autoPassed:
|
||||
autoPass(delegateTask);
|
||||
break;
|
||||
case autoRejection:
|
||||
autoReject(delegateTask);
|
||||
break;
|
||||
case autoSkipped:
|
||||
// autoReject(delegateTask);
|
||||
// 非产品需求, 暂时不实现, 这里的功能似乎可以用 taskService.deleteTask 来实现
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果 approverMethod = 自动通过或自动驳回时
|
||||
*
|
||||
* @param delegateTask
|
||||
* @param userTask
|
||||
*/
|
||||
private void checkApprovalMethod(DelegateTask delegateTask, UserTask userTask) {
|
||||
|
||||
BpmnMetaParserHelper.getApprovalMethod(userTask)
|
||||
.ifPresent(approvalMethodEnum -> {
|
||||
switch (approvalMethodEnum) {
|
||||
@ -72,33 +187,10 @@ public class AutoOperatorEventListener implements BpmnTaskEventListener, Ordered
|
||||
autoReject(delegateTask);
|
||||
break;
|
||||
default:
|
||||
// 如果审批人为空时, 读取 approverEmptyHandleType = 自动通过或自动驳回时
|
||||
if (!StringUtils.hasLength(delegateTask.getAssignee())) {
|
||||
BpmnMetaParserHelper.getApproverEmptyHandleType(userTask)
|
||||
.ifPresent(approverEmptyHandleTypeEnum -> {
|
||||
switch (approverEmptyHandleTypeEnum) {
|
||||
case autoPassed:
|
||||
autoPass(delegateTask);
|
||||
break;
|
||||
case autoRejection:
|
||||
autoReject(delegateTask);
|
||||
break;
|
||||
case autoSkipped:
|
||||
// autoReject(delegateTask);
|
||||
// 非产品需求, 暂时不实现, 这里的功能似乎可以用 taskService.deleteTask 来实现
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
checkApproverEmptyHandle(delegateTask, userTask);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("AutoOperatorEventListener#onCreated...end: {}", delegateTask.getTaskDefinitionKey());
|
||||
}
|
||||
}
|
||||
|
||||
private void autoReject(DelegateTask delegateTask) {
|
||||
|
||||
@ -45,7 +45,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_ASSIGNEE_SKIP_
|
||||
public class MessagePushTaskEventListener implements BpmnTaskEventListener, Ordered {
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Integer.MIN_VALUE + 104;
|
||||
return Integer.MIN_VALUE + 103;
|
||||
}
|
||||
|
||||
private final RuntimeService runtimeService;
|
||||
|
||||
@ -4,7 +4,5 @@
|
||||
|
||||
1. SnapshotBpmTaskTaskEventListener `(Integer.MIN_VALUE + 100)`
|
||||
2. RocketMqBpmTaskEventListener `(Integer.MIN_VALUE+101)`
|
||||
3. StartNodeAutoCompleteEventListener `(Integer.MIN_VALUE+102)`
|
||||
4. AutoOperatorEventListener `(Integer.MIN_VALUE+103)`
|
||||
5. PushPendingTaskEventListener `(Integer.MIN_VALUE+104)`
|
||||
6. HistoryTaskHandleEventListener`(Integer.MIN_VALUE+105)`
|
||||
3. ApprovalMethodAutoOperatorEventListener `(Integer.MIN_VALUE+102)`
|
||||
4. MessagePushTaskEventListener `(Integer.MIN_VALUE+103)`
|
||||
|
||||
Loading…
Reference in New Issue
Block a user