Merge branch 'feature/REQ-1609-syl' into 'feature/REQ-1609'
feat: 新增审批流选人逻辑 See merge request universal/infrastructure/backend/workflow-engine!1
This commit is contained in:
commit
845ff96bd8
5
pom.xml
5
pom.xml
@ -65,6 +65,11 @@
|
||||
<artifactId>maokai-api</artifactId>
|
||||
<version>${axzo-dependencies.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.karma</groupId>
|
||||
<artifactId>karma-api</artifactId>
|
||||
<version>${axzo-dependencies.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
|
||||
@ -1,19 +1,25 @@
|
||||
package cn.axzo.workflow.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 审批人所在范围枚举
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/11/16 10:14
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ApproverScopeEnum {
|
||||
entWorkspace("entWorkspace", "企业工作台"),
|
||||
projectWorkspace("projectWorkspace", "项目工作台"),
|
||||
preTaskUser("preTaskUser", "上节点审批人所在单位"),
|
||||
preTaskSpecified("preTaskSpecified", "上节点审批人指定"),
|
||||
entWorkspace("entWorkspace", "企业工作台", "entWorkspaceSelector"),
|
||||
projectWorkspace("projectWorkspace", "项目工作台","projectWorkspaceSelector"),
|
||||
preTaskUser("preTaskUser", "上节点审批人所在单位","preTaskUserSelector"),
|
||||
preTaskSpecified("preTaskSpecified", "上节点审批人指定","preTaskUserSelector"),
|
||||
;
|
||||
private String type;
|
||||
private String desc;
|
||||
private String processor;
|
||||
|
||||
ApproverScopeEnum(String type, String desc) {
|
||||
this.type = type;
|
||||
@ -35,4 +41,8 @@ public enum ApproverScopeEnum {
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public boolean selectWorkspace() {
|
||||
return this == ApproverScopeEnum.projectWorkspace;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package cn.axzo.workflow.common.enums;
|
||||
|
||||
import java.util.Arrays;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author syl
|
||||
* @date 2023/11/21
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum WorkspaceType {
|
||||
|
||||
/**
|
||||
* 工作台类型
|
||||
* 1- 企业 2-项目 6-oms
|
||||
*/
|
||||
ENT(1, "企业"),
|
||||
WORKSPACE(2, "项目"),
|
||||
OMS(6, "oms工作台");
|
||||
|
||||
private Integer code;
|
||||
private String desc;
|
||||
|
||||
public static WorkspaceType getType(Integer code) {
|
||||
return Arrays.stream(values()).filter(it -> it.getCode().equals(code))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,14 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn.task;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 统一的工作流中的人员模型,兼容不同的业务方,如安心筑"唯一"人的定义需要工作台+身份 ID+身份类型;<br/>
|
||||
@ -17,6 +19,9 @@ import java.io.Serializable;
|
||||
* @author wangli
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class BpmnTaskDelegateAssigner implements Serializable {
|
||||
|
||||
|
||||
@ -88,5 +88,14 @@
|
||||
<groupId>cn.axzo.maokai</groupId>
|
||||
<artifactId>maokai-api</artifactId>
|
||||
</dependency>
|
||||
<!-- api -->
|
||||
<dependency>
|
||||
<groupId>cn.axzo.tyr</groupId>
|
||||
<artifactId>tyr-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.karma</groupId>
|
||||
<artifactId>karma-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -0,0 +1,127 @@
|
||||
package cn.axzo.workflow.core.common.utils;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import cn.axzo.basics.common.util.AssertUtil;
|
||||
import cn.axzo.framework.domain.ServiceException;
|
||||
import cn.axzo.framework.domain.web.BizException;
|
||||
import cn.axzo.framework.domain.web.result.ApiPageResult;
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static cn.axzo.framework.domain.web.code.BaseCode.BAD_REQUEST;
|
||||
|
||||
/**
|
||||
* 内部api 使用 服务与 yoke 下游服务 下游服务统一使用 ApiResult
|
||||
* @author tanjie@axzo.cn
|
||||
* @date 2022/5/23 11:08
|
||||
*/
|
||||
@Slf4j
|
||||
public class RpcInternalUtil {
|
||||
|
||||
/**
|
||||
* 常用的RPC请求返回值解析,如果 被请求方 返回非200会抛出异常
|
||||
*/
|
||||
public static <T> ApiResult<T> rpcProcessor(Supplier<ApiResult<T>> supplier, String operationType, Object... param) {
|
||||
|
||||
return rpcProcessorMayThrow(supplier, operationType, (msg) -> {
|
||||
throw new ServiceException(msg);
|
||||
}, param);
|
||||
}
|
||||
|
||||
public static <T> ApiResult<T> rpcProcessorMayThrow(Supplier<ApiResult<T>> supplier, String operationType, Consumer<String> throwConsumer, Object... param) {
|
||||
AssertUtil.notNull(throwConsumer, "自定义的异常处理不可为空");
|
||||
log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param));
|
||||
ApiResult<T> result = null;
|
||||
|
||||
try {
|
||||
result = supplier.get();
|
||||
} catch (Throwable e) {
|
||||
log.warn("rpc process error:{}", e.getMessage());
|
||||
throwConsumer.accept("服务调用异常");
|
||||
}
|
||||
|
||||
log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result));
|
||||
Assert.notNull(result, "服务调用异常");
|
||||
// 200自定义处理
|
||||
if (HttpStatus.HTTP_OK != result.getCode()) {
|
||||
throwConsumer.accept(result.getMsg());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 常用的RPC请求返回值解析,如果 被请求方 返回非200会抛出异常
|
||||
*/
|
||||
public static <T> ApiPageResult<T> rpcPageProcessor(Supplier<ApiPageResult<T>> supplier, String operationType, Object... param) {
|
||||
|
||||
return rpcPageProcessorMayThrow(supplier, operationType, (msg) -> {
|
||||
throw new ServiceException(msg);
|
||||
}, param);
|
||||
}
|
||||
|
||||
public static <T> ApiPageResult<T> rpcPageProcessorMayThrow(Supplier<ApiPageResult<T>> supplier, String operationType, Consumer<String> throwConsumer, Object... param) {
|
||||
AssertUtil.notNull(throwConsumer, "自定义的异常处理不可为空");
|
||||
log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param));
|
||||
ApiPageResult<T> result = null;
|
||||
try {
|
||||
result = supplier.get();
|
||||
} catch (Throwable t) {
|
||||
log.warn("rpc process error:{}", t.getMessage());
|
||||
throwConsumer.accept("服务调用异常");
|
||||
}
|
||||
log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result));
|
||||
Assert.notNull(result, "服务调用异常");
|
||||
// 200自定义处理
|
||||
if (HttpStatus.HTTP_OK != result.getCode()) {
|
||||
throwConsumer.accept(result.getMsg());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> T checkAndGetData(ApiResult<T> result) {
|
||||
if (result.isError()) {
|
||||
throw new BizException(result.getRespCode(), result.getMsg());
|
||||
}
|
||||
T data = result.getData();
|
||||
if (data == null) {
|
||||
throw new BizException(BAD_REQUEST, "数据不存在");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static <T> CommonResponse<T> commonRpcProcessor(Supplier<CommonResponse<T>> supplier, String operationType, Object... param) {
|
||||
|
||||
return commonRpcProcessorMayThrow(supplier, operationType, (msg) -> {
|
||||
throw new ServiceException(msg);
|
||||
}, param);
|
||||
}
|
||||
|
||||
public static <T> CommonResponse<T> commonRpcProcessorMayThrow(Supplier<CommonResponse<T>> supplier, String operationType,
|
||||
Consumer<String> throwConsumer, Object... param) {
|
||||
AssertUtil.notNull(throwConsumer, "自定义的异常处理不可为空");
|
||||
log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param));
|
||||
CommonResponse<T> result = null;
|
||||
|
||||
try {
|
||||
result = supplier.get();
|
||||
} catch (Throwable e) {
|
||||
log.warn("rpc process error:{}", e.getMessage());
|
||||
throwConsumer.accept("服务调用异常");
|
||||
}
|
||||
|
||||
log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result));
|
||||
Assert.notNull(result, "服务调用异常");
|
||||
// 200自定义处理
|
||||
if (HttpStatus.HTTP_OK != result.getCode()) {
|
||||
throwConsumer.accept(result.getMsg());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -12,14 +12,18 @@ import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* 抽象的流程任务审批人选择器
|
||||
@ -39,7 +43,7 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
|
||||
"未获取到”审批人所在范围”的配置信息,请检查流程配置"));
|
||||
}
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask, DelegateExecution execution) {
|
||||
FlowTaskAssignerReq query = buildQuery(userTask);
|
||||
List<FlowTaskAssigner> flowTaskAssigners = null;
|
||||
try {
|
||||
@ -67,4 +71,14 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
|
||||
return result.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTypes(UserTask userTask) {
|
||||
// 默认解析格式:[{"name":"预算员", "value":"xxxx"}]
|
||||
return BpmnMetaParserHelper.getApproverSpecifyValue(userTask)
|
||||
.map(value -> value.stream()
|
||||
.map(s -> Optional.ofNullable(JSON.parseObject(s).getString("value"))
|
||||
.orElse(null))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList())).orElse(Collections.emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,28 @@
|
||||
package cn.axzo.workflow.core.deletage;
|
||||
|
||||
import cn.axzo.karma.client.feign.FlowSupportApi;
|
||||
import cn.axzo.karma.client.model.request.ListFlowTaskAssignerReq;
|
||||
import cn.axzo.karma.client.model.response.FlowTaskAssignerResp;
|
||||
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
|
||||
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
|
||||
import cn.axzo.workflow.common.enums.ApproverScopeEnum;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import cn.axzo.workflow.core.common.utils.RpcInternalUtil;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeDto;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeSelector;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
@ -11,9 +31,14 @@ import org.springframework.stereotype.Component;
|
||||
* @author wangli
|
||||
* @since 2023/11/16 11:44
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AdminTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
|
||||
|
||||
@Autowired
|
||||
private FlowSupportApi flowSupportApi;
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public boolean support(String param) {
|
||||
@ -24,4 +49,46 @@ public class AdminTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector
|
||||
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask, DelegateExecution execution) {
|
||||
Optional<ApproverScopeEnum> approverScopeOpt = BpmnMetaParserHelper
|
||||
.getApproverScope(userTask);
|
||||
if (!approverScopeOpt.isPresent()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
ApproverScopeSelector scopeProcessor = applicationContext
|
||||
.getBean(approverScopeOpt.get().getProcessor(),
|
||||
ApproverScopeSelector.class);
|
||||
ApproverScopeDto scopeDto = scopeProcessor.select(userTask, execution);
|
||||
if (CollUtil.isEmpty(scopeDto.getOrgScopes())) {
|
||||
log.info("adminTaskAssignee no get orgScopes");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<FlowTaskAssignerResp> flowTaskAssigners = null;
|
||||
try {
|
||||
ListFlowTaskAssignerReq req = ListFlowTaskAssignerReq.builder()
|
||||
.orgScopes(scopeDto.getOrgScopes().stream()
|
||||
.map(e -> BeanUtil
|
||||
.copyProperties(e, ListFlowTaskAssignerReq.OrgScope.class))
|
||||
.collect(Collectors.toList()))
|
||||
.workerTeamScopes(scopeDto.getWorkerTeamScopes().stream()
|
||||
.map(w -> BeanUtil
|
||||
.copyProperties(w, ListFlowTaskAssignerReq.OrgScope.class))
|
||||
.collect(Collectors.toList()))
|
||||
.build();
|
||||
// todo 调用中台提供查询管理员的api
|
||||
flowTaskAssigners = RpcInternalUtil.rpcProcessor(() ->
|
||||
flowSupportApi.listTaskAssignerByIdentity(req), "通过管理员查询审批人").getData();
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException("调用 API 查询审批候选人出现异常: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(flowTaskAssigners)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return BeanUtil.copyToList(flowTaskAssigners, BpmnTaskDelegateAssigner.class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
package cn.axzo.workflow.core.deletage;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
|
||||
/**
|
||||
* 任务节点的审批人查询器接口
|
||||
@ -15,18 +16,18 @@ public interface BpmnTaskAssigneeSelector {
|
||||
|
||||
/**
|
||||
* 判断是否支持当前审批指定类型
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
boolean support(String param);
|
||||
|
||||
/**
|
||||
* 查询具体审批人
|
||||
*
|
||||
* @param userTask
|
||||
* @return
|
||||
*/
|
||||
List<BpmnTaskDelegateAssigner> select(UserTask userTask);
|
||||
List<BpmnTaskDelegateAssigner> select(UserTask userTask, DelegateExecution execution);
|
||||
|
||||
/**
|
||||
* 审批人筛选项获取类型
|
||||
*/
|
||||
default List<String> getTypes(UserTask userTask) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,11 +5,11 @@ import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 基于"固定人元"查询审批人
|
||||
@ -25,7 +25,7 @@ public class FixedPersonTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSel
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask, DelegateExecution execution) {
|
||||
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
|
||||
BpmnMetaParserHelper.getApproverSpecifyValue(userTask)
|
||||
.ifPresent(list -> list.forEach(i -> assigners.add(JSON.parseObject(i,
|
||||
|
||||
@ -1,8 +1,28 @@
|
||||
package cn.axzo.workflow.core.deletage;
|
||||
|
||||
import cn.axzo.karma.client.feign.FlowSupportApi;
|
||||
import cn.axzo.karma.client.model.request.ListFlowTaskAssignerReq;
|
||||
import cn.axzo.karma.client.model.response.FlowTaskAssignerResp;
|
||||
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
|
||||
import cn.axzo.workflow.common.enums.ApproverScopeEnum;
|
||||
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import cn.axzo.workflow.core.common.utils.RpcInternalUtil;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeDto;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeSelector;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
@ -11,8 +31,15 @@ import org.springframework.stereotype.Component;
|
||||
* @author wangli
|
||||
* @since 2023/11/16 11:38
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class IdentityTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
|
||||
|
||||
@Autowired
|
||||
private FlowSupportApi flowSupportApi;
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public boolean support(String param) {
|
||||
return ApproverSpecifyEnum.identity.getType().equals(param);
|
||||
@ -23,4 +50,44 @@ public class IdentityTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelect
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask, DelegateExecution execution) {
|
||||
Optional<ApproverScopeEnum> approverScopeOpt = BpmnMetaParserHelper.getApproverScope(userTask);
|
||||
List<String> identityCodes = super.getTypes(userTask);
|
||||
if (CollUtil.isEmpty(identityCodes) || !approverScopeOpt.isPresent()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
ApproverScopeSelector scopeProcessor = applicationContext
|
||||
.getBean(approverScopeOpt.get().getProcessor(),
|
||||
ApproverScopeSelector.class);
|
||||
ApproverScopeDto scopeDto = scopeProcessor.select(userTask, execution);
|
||||
if (CollUtil.isEmpty(scopeDto.getOrgScopes())) {
|
||||
log.info("identityTaskAssignee no get orgScopes");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<FlowTaskAssignerResp> flowTaskAssigners = null;
|
||||
try {
|
||||
ListFlowTaskAssignerReq req = ListFlowTaskAssignerReq.builder()
|
||||
.orgScopes(scopeDto.getOrgScopes().stream()
|
||||
.map(e -> BeanUtil
|
||||
.copyProperties(e, ListFlowTaskAssignerReq.OrgScope.class))
|
||||
.collect(Collectors.toList()))
|
||||
.workerTeamScopes(scopeDto.getWorkerTeamScopes().stream()
|
||||
.map(w -> BeanUtil
|
||||
.copyProperties(w, ListFlowTaskAssignerReq.OrgScope.class))
|
||||
.collect(Collectors.toList()))
|
||||
.identityCodes(identityCodes)
|
||||
.build();
|
||||
flowTaskAssigners = RpcInternalUtil.rpcProcessor(() ->
|
||||
flowSupportApi.listTaskAssignerByIdentity(req), "通过身份查询审批人").getData();
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException("调用 API 查询审批候选人出现异常: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(flowTaskAssigners)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return BeanUtil.copyToList(flowTaskAssigners, BpmnTaskDelegateAssigner.class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import org.flowable.bpmn.model.UserTask;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* todo 本期需求不实现
|
||||
* 给予"发起人多级主管"查询审批人
|
||||
*
|
||||
* @author wangli
|
||||
|
||||
@ -1,18 +1,51 @@
|
||||
package cn.axzo.workflow.core.deletage;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
|
||||
|
||||
import cn.axzo.maokai.api.client.OrganizationalNodeUserApi;
|
||||
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
|
||||
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq.IdentityPair;
|
||||
import cn.axzo.maokai.api.vo.response.FlowTaskAssigner;
|
||||
import cn.axzo.workflow.common.enums.ApproverScopeEnum;
|
||||
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import cn.axzo.workflow.core.common.utils.RpcInternalUtil;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeDto;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeSelector;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 基于"发起人多级主管"查询审批人
|
||||
* 基于"发起人主管"查询审批人
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/11/16 11:41
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class InitiatorLeaderTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
|
||||
|
||||
@Autowired
|
||||
private OrganizationalNodeUserApi organizationalNodeUserApi;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public boolean support(String param) {
|
||||
return ApproverSpecifyEnum.initiatorLeader.getType().equals(param);
|
||||
@ -22,4 +55,53 @@ public class InitiatorLeaderTaskAssigneeSelector extends AbstractBpmnTaskAssigne
|
||||
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask, DelegateExecution execution) {
|
||||
Optional<ApproverScopeEnum> approverScopeOpt = BpmnMetaParserHelper
|
||||
.getApproverScope(userTask);
|
||||
List<String> positions = super.getTypes(userTask);
|
||||
Map<String, Object> variables = execution.getVariables();
|
||||
if (CollUtil.isEmpty(positions) || !approverScopeOpt.isPresent() || CollUtil
|
||||
.isEmpty(variables)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
ApproverScopeSelector scopeProcessor = applicationContext
|
||||
.getBean(approverScopeOpt.get().getProcessor(), ApproverScopeSelector.class);
|
||||
ApproverScopeDto scopeDto = scopeProcessor.select(userTask, execution);
|
||||
|
||||
// 获取发起人
|
||||
BpmnTaskDelegateAssigner initiator = (BpmnTaskDelegateAssigner) variables
|
||||
.get(INTERNAL_INITIATOR);
|
||||
if (Objects.isNull(initiator) || StringUtils.isBlank(initiator.getAssigneeType())
|
||||
|| CollUtil.isEmpty(scopeDto.getOrgScopes())) {
|
||||
log.info("initiatorLeaderTaskAssignee can not query assigner info or orgScopes");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<FlowTaskAssigner> flowTaskAssigners = null;
|
||||
try {
|
||||
FlowTaskAssignerReq req = FlowTaskAssignerReq.builder()
|
||||
.orgScopes(scopeDto.getOrgScopes().stream()
|
||||
.map(o -> FlowTaskAssignerReq.OrgScope.builder()
|
||||
.ouId(o.getOuId())
|
||||
.workspaceId(o.getWorkspaceId())
|
||||
.build())
|
||||
.collect(Collectors.toList()))
|
||||
.sponsor(IdentityPair.builder()
|
||||
.identityId(Long.valueOf(initiator.getAssignee()))
|
||||
.identityType(Integer.valueOf(initiator.getAssigneeType())).build())
|
||||
.build();
|
||||
flowTaskAssigners = RpcInternalUtil.rpcProcessor(() ->
|
||||
organizationalNodeUserApi.listFlowTaskAssigner(req), "通过发起人主管查询审批人").getData();
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException("调用 API 查询审批候选人出现异常: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(flowTaskAssigners)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return BeanUtil.copyToList(flowTaskAssigners, BpmnTaskDelegateAssigner.class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package cn.axzo.workflow.core.deletage;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -20,7 +21,7 @@ public class MockTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask, DelegateExecution execution) {
|
||||
List<BpmnTaskDelegateAssigner> users = new ArrayList<>();
|
||||
return users;
|
||||
}
|
||||
|
||||
@ -1,8 +1,27 @@
|
||||
package cn.axzo.workflow.core.deletage;
|
||||
|
||||
import cn.axzo.maokai.api.client.OrganizationalNodeUserApi;
|
||||
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
|
||||
import cn.axzo.maokai.api.vo.response.FlowTaskAssigner;
|
||||
import cn.axzo.workflow.common.enums.ApproverScopeEnum;
|
||||
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import cn.axzo.workflow.core.common.utils.RpcInternalUtil;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeDto;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeSelector;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
@ -11,8 +30,16 @@ import org.springframework.stereotype.Component;
|
||||
* @author wangli
|
||||
* @since 2023/11/16 11:35
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PositionTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
|
||||
|
||||
@Autowired
|
||||
private OrganizationalNodeUserApi organizationalNodeUserApi;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public boolean support(String param) {
|
||||
return ApproverSpecifyEnum.position.getType().equals(param);
|
||||
@ -22,4 +49,40 @@ public class PositionTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelect
|
||||
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask, DelegateExecution execution) {
|
||||
Optional<ApproverScopeEnum> approverScopeOpt = BpmnMetaParserHelper.getApproverScope(userTask);
|
||||
List<String> positions = super.getTypes(userTask);
|
||||
if (CollUtil.isEmpty(positions) || !approverScopeOpt.isPresent()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
ApproverScopeSelector scopeProcessor = applicationContext.getBean(approverScopeOpt.get().getProcessor(),
|
||||
ApproverScopeSelector.class);
|
||||
ApproverScopeDto scopeDto = scopeProcessor.select(userTask, execution);
|
||||
if (CollUtil.isEmpty(scopeDto.getOrgScopes())) {
|
||||
log.info("positionTaskAssignee no get orgScopes");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<FlowTaskAssigner> flowTaskAssigners = null;
|
||||
try {
|
||||
FlowTaskAssignerReq req = FlowTaskAssignerReq.builder()
|
||||
.orgScopes(scopeDto.getOrgScopes().stream()
|
||||
.map(e -> BeanUtil.copyProperties(e, FlowTaskAssignerReq.OrgScope.class))
|
||||
.collect(Collectors.toList()))
|
||||
.jobCodes(positions)
|
||||
.build();
|
||||
flowTaskAssigners = RpcInternalUtil.rpcProcessor(() ->
|
||||
organizationalNodeUserApi.listFlowTaskAssigner(req), "通过岗位查询审批人").getData();
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException("调用 API 查询审批候选人出现异常: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(flowTaskAssigners)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return BeanUtil.copyToList(flowTaskAssigners, BpmnTaskDelegateAssigner.class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,29 @@
|
||||
package cn.axzo.workflow.core.deletage;
|
||||
|
||||
import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq;
|
||||
import cn.axzo.tyr.client.feign.TyrSaasRoleUserApi;
|
||||
import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO;
|
||||
import cn.axzo.tyr.client.model.roleuser.req.RoleUserParam;
|
||||
import cn.axzo.workflow.common.enums.ApproverScopeEnum;
|
||||
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
|
||||
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO.OrgScope;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import cn.axzo.workflow.core.common.utils.RpcInternalUtil;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeDto;
|
||||
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeSelector;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
@ -11,8 +32,14 @@ import org.springframework.stereotype.Component;
|
||||
* @author wangli
|
||||
* @since 2023/11/16 11:37
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RoleTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
@Autowired
|
||||
private TyrSaasRoleUserApi tyrSaasRoleUserApi;
|
||||
@Override
|
||||
public boolean support(String param) {
|
||||
return ApproverSpecifyEnum.role.getType().equals(param);
|
||||
@ -22,4 +49,59 @@ public class RoleTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector {
|
||||
protected FlowTaskAssignerReq buildQuery(UserTask userTask) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmnTaskDelegateAssigner> select(UserTask userTask, DelegateExecution execution) {
|
||||
Optional<ApproverScopeEnum> approverScopeOpt = BpmnMetaParserHelper.getApproverScope(userTask);
|
||||
List<String> roles = super.getTypes(userTask);
|
||||
if (CollUtil.isEmpty(roles) || !approverScopeOpt.isPresent()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Set<Long> roleIds = roles.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
|
||||
ApproverScopeSelector scopeProcessor = applicationContext.getBean(approverScopeOpt.get().getProcessor(),
|
||||
ApproverScopeSelector.class);
|
||||
ApproverScopeDto scopeDto = scopeProcessor.select(userTask, execution);
|
||||
if (CollUtil.isEmpty(scopeDto.getOrgScopes())) {
|
||||
log.info("roleTaskAssignee no get orgScopes");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Set<Long> workspaceIdSet = scopeDto.getOrgScopes().stream()
|
||||
.map(OrgScope::getWorkspaceId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
List<SaasRoleUserDTO> flowTaskAssigners = null;
|
||||
try {
|
||||
// ouIds、workspaceIds 只能传其中一个 然后代码过滤
|
||||
RoleUserParam param = RoleUserParam.builder()
|
||||
.roleIds(roleIds)
|
||||
.ouIds(scopeDto.getOrgScopes().stream()
|
||||
.map(OrgScope::getOuId)
|
||||
.collect(Collectors.toList()))
|
||||
.build();
|
||||
param.setPageSize(-1L);
|
||||
flowTaskAssigners = RpcInternalUtil.rpcProcessor(() ->
|
||||
tyrSaasRoleUserApi.roleUserList(param), "通过角色查询审批人").getData()
|
||||
.stream()
|
||||
.filter(f -> workspaceIdSet.contains(f.getWorkspaceId()))
|
||||
.collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
throw new WorkflowEngineException("调用 API 查询审批候选人出现异常: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(flowTaskAssigners)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return flowTaskAssigners.stream().map(u -> BpmnTaskDelegateAssigner.builder()
|
||||
.assignee(String.valueOf(u.getIdentityId()))
|
||||
.assigneeType(String.valueOf(u.getIdentityType()))
|
||||
.tenantId(String.valueOf(u.getWorkspaceId()))
|
||||
.ouId(String.valueOf(u.getOuId()))
|
||||
.personId(String.valueOf(u.getNaturalPersonId()))
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package cn.axzo.workflow.core.deletage.approverscope;
|
||||
|
||||
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO.OrgScope;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author syl
|
||||
* @date 2023/11/21
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ApproverScopeDto {
|
||||
|
||||
/**
|
||||
* 组织架构范围
|
||||
* 可能是企业、项目等
|
||||
**/
|
||||
private List<OrgScope> orgScopes;
|
||||
/**
|
||||
* 班组组织架构范围 - 目前用于选择身份
|
||||
**/
|
||||
private List<OrgScope> workerTeamScopes;
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package cn.axzo.workflow.core.deletage.approverscope;
|
||||
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
|
||||
/**
|
||||
* @author syl
|
||||
* @date 2023/11/21
|
||||
*/
|
||||
public interface ApproverScopeSelector {
|
||||
|
||||
default ApproverScopeDto select(UserTask userTask, DelegateExecution execution){
|
||||
return ApproverScopeDto.builder().build();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package cn.axzo.workflow.core.deletage.approverscope;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
|
||||
|
||||
import cn.axzo.workflow.common.enums.WorkspaceType;
|
||||
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
|
||||
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO.OrgScope;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author syl
|
||||
* @date 2023/11/21
|
||||
*/
|
||||
@Component
|
||||
public class EntWorkspaceSelector implements ApproverScopeSelector {
|
||||
|
||||
@Override
|
||||
public ApproverScopeDto select(UserTask userTask, DelegateExecution execution) {
|
||||
// 获取组织信息
|
||||
CooperationOrgDTO orgDTO =(CooperationOrgDTO) execution.getVariables().get(BIZ_ORG_RELATION);
|
||||
if (Objects.isNull(orgDTO)) {
|
||||
return ApproverScopeDto.builder().build();
|
||||
}
|
||||
List<OrgScope> orgScopes = orgDTO.getOrgScopes().stream()
|
||||
.filter(o -> WorkspaceType.ENT == WorkspaceType.getType(o.getWorkspaceType()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<OrgScope> workerTeamScopes = CollUtil.defaultIfEmpty(orgDTO.getWorkerTeamScopes(),
|
||||
Collections.emptyList())
|
||||
.stream()
|
||||
.filter(o -> WorkspaceType.ENT == WorkspaceType.getType(o.getWorkspaceType()))
|
||||
.collect(Collectors.toList());
|
||||
return ApproverScopeDto.builder().orgScopes(orgScopes)
|
||||
.workerTeamScopes(workerTeamScopes).build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package cn.axzo.workflow.core.deletage.approverscope;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
|
||||
|
||||
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
|
||||
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO.OrgScope;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author syl
|
||||
* @date 2023/11/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PreTaskUserSelector implements ApproverScopeSelector {
|
||||
|
||||
@Override
|
||||
public ApproverScopeDto select(UserTask userTask, DelegateExecution execution) {
|
||||
Optional<UserTask> preUserTaskOpt = BpmnMetaParserHelper.getPreNode(userTask);
|
||||
if (!preUserTaskOpt.isPresent()) {
|
||||
log.info("the current node has no pre node, skip");
|
||||
return ApproverScopeDto.builder().build();
|
||||
}
|
||||
|
||||
// 上级节点
|
||||
String preActivityId = preUserTaskOpt.get().getId();
|
||||
// 获取上一级节点
|
||||
List<BpmnTaskDelegateAssigner> assigners = (List<BpmnTaskDelegateAssigner>) execution
|
||||
.getVariableLocal(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + preActivityId);
|
||||
List<OrgScope> entOrg = assigners.stream()
|
||||
.map(a -> {
|
||||
CooperationOrgDTO.OrgScope orgScope = new CooperationOrgDTO.OrgScope()
|
||||
.setWorkspaceId(Long.valueOf(a.getTenantId()));
|
||||
if (StringUtils.isNotBlank(a.getOuId())) {
|
||||
orgScope.setOuId(Long.valueOf(a.getOuId()));
|
||||
}
|
||||
return orgScope;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return ApproverScopeDto.builder().orgScopes(entOrg).build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package cn.axzo.workflow.core.deletage.approverscope;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION;
|
||||
|
||||
import cn.axzo.workflow.common.enums.WorkspaceType;
|
||||
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
|
||||
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO.OrgScope;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author syl
|
||||
* @date 2023/11/21
|
||||
*/
|
||||
@Component
|
||||
public class ProjectWorkspaceSelector implements ApproverScopeSelector {
|
||||
|
||||
@Override
|
||||
public ApproverScopeDto select(UserTask userTask, DelegateExecution execution) {
|
||||
// 发起项目部
|
||||
CooperationOrgDTO orgDTO =(CooperationOrgDTO) execution.getVariables().get(BIZ_ORG_RELATION);
|
||||
if (Objects.isNull(orgDTO)) {
|
||||
return ApproverScopeDto.builder().build();
|
||||
}
|
||||
List<OrgScope> orgScopes = orgDTO.getOrgScopes().stream()
|
||||
.filter(o -> WorkspaceType.WORKSPACE == WorkspaceType.getType(o.getWorkspaceType()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<OrgScope> workerTeamScopes = CollUtil.defaultIfEmpty(orgDTO.getWorkerTeamScopes(),
|
||||
Collections.emptyList())
|
||||
.stream()
|
||||
.filter(o -> WorkspaceType.WORKSPACE == WorkspaceType.getType(o.getWorkspaceType()))
|
||||
.collect(Collectors.toList());
|
||||
return ApproverScopeDto.builder().orgScopes(orgScopes)
|
||||
.workerTeamScopes(workerTeamScopes).build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,32 +1,5 @@
|
||||
package cn.axzo.workflow.core.engine.listener;
|
||||
|
||||
import cn.axzo.workflow.common.constant.BpmnConstants;
|
||||
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
|
||||
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
|
||||
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector;
|
||||
import cn.axzo.workflow.core.deletage.BpmnTaskCalculateDTO;
|
||||
import cn.axzo.workflow.core.deletage.BpmnTaskDelegate;
|
||||
import cn.axzo.workflow.core.deletage.MockTaskAssigneeSelector;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.ExecutionListener;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_ALLOW_SKIP_USER_TASK;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_121;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
|
||||
@ -39,6 +12,32 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprove
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNodeType;
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getProcessServerVersion;
|
||||
|
||||
import cn.axzo.workflow.common.constant.BpmnConstants;
|
||||
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
|
||||
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
|
||||
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector;
|
||||
import cn.axzo.workflow.core.deletage.BpmnTaskCalculateDTO;
|
||||
import cn.axzo.workflow.core.deletage.BpmnTaskDelegate;
|
||||
import cn.axzo.workflow.core.deletage.MockTaskAssigneeSelector;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.ExecutionListener;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* 每一个任务节点创建 Execution 时执行的监听, 用于 BPMN 文件中为节点设置指定类型监听
|
||||
@ -90,7 +89,7 @@ public class EngineExecutionStartListener implements ExecutionListener {
|
||||
// 这里只会是 human 这一种情况, 因为 nobody 在转 BPMN 协议时,Activity 直接变成了 ReceiveTask 节点了。
|
||||
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
|
||||
getApproverSpecify(userTask).ifPresent(specify -> {
|
||||
assigners.addAll(approverSelect(specify.getType(), userTask));
|
||||
assigners.addAll(approverSelect(specify.getType(), userTask, execution));
|
||||
});
|
||||
|
||||
// 查询审批候选人
|
||||
@ -131,7 +130,7 @@ public class EngineExecutionStartListener implements ExecutionListener {
|
||||
execution.setTransientVariable(BPM_ALLOW_SKIP_USER_TASK, true);
|
||||
break;
|
||||
case transferToAdmin:
|
||||
approverSelect(ApproverEmptyHandleTypeEnum.transferToAdmin.getType(), userTask);
|
||||
approverSelect(ApproverEmptyHandleTypeEnum.transferToAdmin.getType(), userTask , execution);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -146,16 +145,16 @@ public class EngineExecutionStartListener implements ExecutionListener {
|
||||
* @param userTask 当前节点, 这个对象会包含配置元数据, 可以在该方法中或者基于 BpmnTaskAssigneeSelector 建一个抽象类, 做解析元数据公共方法
|
||||
* @return
|
||||
*/
|
||||
private List<BpmnTaskDelegateAssigner> approverSelect(String type, UserTask userTask) {
|
||||
private List<BpmnTaskDelegateAssigner> approverSelect(String type, UserTask userTask, DelegateExecution execution) {
|
||||
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
|
||||
|
||||
// 如果开启了 mock 模式(workflow.mock=true), 则直接返回 mock 的审批人
|
||||
if (Objects.nonNull(objectProvider.getIfAvailable())) {
|
||||
objectProvider.ifAvailable(selector -> assigners.addAll(selector.select(userTask)));
|
||||
objectProvider.ifAvailable(selector -> assigners.addAll(selector.select(userTask, execution)));
|
||||
} else {
|
||||
selectors.forEach(select -> {
|
||||
if (select.support(type)) {
|
||||
assigners.addAll(select.select(userTask));
|
||||
assigners.addAll(select.select(userTask, execution));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user