first commit
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
package com.budwk.app.bpm.util;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.expression.ExpressionUtil;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.bpm.enums.BpmProcessNodeApprovalTypeEnum;
|
||||
import com.budwk.app.bpm.enums.BpmProcessNodeTypeEnum;
|
||||
import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum;
|
||||
import com.budwk.app.bpm.models.BpmProcessNodeDefine;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 流程工具类
|
||||
*/
|
||||
public class BpmUtil {
|
||||
|
||||
/**
|
||||
* 执行动态判断表达式 获取下一个节点
|
||||
*
|
||||
* @param decisions
|
||||
* @param variables
|
||||
* @return
|
||||
*/
|
||||
public static String evalExpressionGetNextTaskNodeId(BpmProcessNodeDefine taskNode, BpmTaskApprovalTypeEnum bpmTaskApprovalTypeEnum, List<BpmProcessNodeDefine.DynamicDecision> decisions, Map<String, Object> variables) {
|
||||
if (bpmTaskApprovalTypeEnum.equals(BpmTaskApprovalTypeEnum.DYNAMIC)) {
|
||||
if (ObjectUtil.isEmpty(decisions)) {
|
||||
throw new BaseException("动态分支节点配置为空");
|
||||
}
|
||||
for (BpmProcessNodeDefine.DynamicDecision decision : decisions) {
|
||||
String expression = decision.getCondition();
|
||||
Object eval = ExpressionUtil.eval(expression, variables);
|
||||
if (Convert.toBool(eval, false)) {
|
||||
return decision.getToNodeId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} else if (bpmTaskApprovalTypeEnum.equals(BpmTaskApprovalTypeEnum.APPLY)) {
|
||||
if(ObjectUtil.isEmpty(taskNode.getDynamicDecisions())){
|
||||
return taskNode.getPassNextNodeId();
|
||||
}else{
|
||||
for (BpmProcessNodeDefine.DynamicDecision decision : decisions) {
|
||||
String expression = decision.getCondition();
|
||||
Object eval = ExpressionUtil.eval(expression, variables);
|
||||
if (Convert.toBool(eval, false)) {
|
||||
return decision.getToNodeId();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (bpmTaskApprovalTypeEnum.equals(BpmTaskApprovalTypeEnum.REJECT)) {
|
||||
return taskNode.getRejectNextNodeId();
|
||||
} else if (bpmTaskApprovalTypeEnum.equals(BpmTaskApprovalTypeEnum.BACK)) {
|
||||
return taskNode.getBackNextNodeId();
|
||||
} else if (bpmTaskApprovalTypeEnum.equals(BpmTaskApprovalTypeEnum.PASS)) {
|
||||
return taskNode.getPassNextNodeId();
|
||||
}
|
||||
throw new BaseException("{}节点{}配置错误", taskNode.getNodeName(), bpmTaskApprovalTypeEnum.name());
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证流程定义节点是否正确
|
||||
* @param nodes
|
||||
*/
|
||||
public static void validateNodes(List<BpmProcessNodeDefine> nodes) {
|
||||
//名称必填
|
||||
for (BpmProcessNodeDefine node : nodes) {
|
||||
if (StrUtil.isBlank(node.getNodeName())) {
|
||||
throw new RuntimeException("节点名称不能为空,请检查");
|
||||
}
|
||||
}
|
||||
|
||||
//code必填
|
||||
for (BpmProcessNodeDefine node : nodes) {
|
||||
if (ObjectUtil.isNull(node.getNodeCode())) {
|
||||
throw new RuntimeException("节点编码不能为空,请检查");
|
||||
}
|
||||
}
|
||||
|
||||
//节点类型必填
|
||||
for (BpmProcessNodeDefine node : nodes) {
|
||||
if (StrUtil.isBlank(node.getNodeType())) {
|
||||
throw new RuntimeException("节点类型不能为空,请检查");
|
||||
}
|
||||
}
|
||||
|
||||
//code不能重复
|
||||
Set<Integer> codes = new HashSet<>();
|
||||
for (BpmProcessNodeDefine node : nodes) {
|
||||
if (!codes.add(node.getNodeCode())) {
|
||||
throw new RuntimeException("节点编码重复,请检查");
|
||||
}
|
||||
}
|
||||
|
||||
if (nodes.stream().noneMatch(node -> node.getNodeType().equals(BpmProcessNodeTypeEnum.START.name()))) {
|
||||
throw new RuntimeException("流程定义中必须存在开始节点,请检查");
|
||||
}
|
||||
if (nodes.stream().noneMatch(node -> node.getNodeType().equals(BpmProcessNodeTypeEnum.END.name()))) {
|
||||
throw new RuntimeException("流程定义中必须存在结束节点,请检查");
|
||||
}
|
||||
if (nodes.stream().noneMatch(node -> node.getNodeType().equals(BpmProcessNodeTypeEnum.TASK.name()))) {
|
||||
throw new RuntimeException("流程定义中必须存在任务节点,请检查");
|
||||
}
|
||||
|
||||
//单个判断
|
||||
for (BpmProcessNodeDefine node : nodes) {
|
||||
if(node.getNodeType().equals(BpmProcessNodeTypeEnum.START.name())){
|
||||
validateStartNode(node, nodes);
|
||||
}else if(node.getNodeType().equals(BpmProcessNodeTypeEnum.END.name())){
|
||||
validateEndNode(node, nodes);
|
||||
}else if(node.getNodeType().equals(BpmProcessNodeTypeEnum.TASK.name())){
|
||||
validateTaskNode(node, nodes);
|
||||
}else if(node.getNodeType().equals(BpmProcessNodeTypeEnum.BACK.name())){
|
||||
validateBackNode(node, nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证开始节点
|
||||
*
|
||||
* @param startNode
|
||||
* @param nodes
|
||||
*/
|
||||
private static void validateStartNode(BpmProcessNodeDefine startNode, List<BpmProcessNodeDefine> nodes) {
|
||||
String passNextNodeId = startNode.getPassNextNodeId();
|
||||
|
||||
if (StrUtil.isBlank(passNextNodeId) && ObjectUtil.isEmpty(startNode.getDynamicDecisions())) {
|
||||
throw new RuntimeException("开始节点的通过节点或者动态决策表达式不能为空,请检查");
|
||||
}
|
||||
if (passNextNodeId.equals(startNode.getId())) {
|
||||
throw new RuntimeException("开始节点的通过节点不能指向自己,请检查");
|
||||
}
|
||||
// if (StrUtil.isBlank(startNode.getNodeApprovalType())) {
|
||||
// throw new RuntimeException("开始节点的审批完成类型不能为空,请检查");
|
||||
// }
|
||||
// if (!startNode.getNodeApprovalType().equals(BpmProcessNodeApprovalTypeEnum.NODE_APPLY.name())) {
|
||||
// throw new RuntimeException("开始节点的审批完成类型只能为申请,请检查");
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证结束节点
|
||||
*
|
||||
* @param endNode
|
||||
* @param nodes
|
||||
*/
|
||||
private static void validateEndNode(BpmProcessNodeDefine endNode, List<BpmProcessNodeDefine> nodes) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证任务节点
|
||||
*
|
||||
* @param taskNode
|
||||
* @param nodes
|
||||
*/
|
||||
private static void validateTaskNode(BpmProcessNodeDefine taskNode, List<BpmProcessNodeDefine> nodes) {
|
||||
if (StrUtil.isAllBlank(taskNode.getPassNextNodeId(), taskNode.getRejectNextNodeId(), taskNode.getBackNextNodeId()) && ObjectUtil.isEmpty(taskNode.getDynamicDecisions())) {
|
||||
throw new RuntimeException("任务节点的通过、拒绝、退回节点和动态决策不能同时为空,请检查");
|
||||
}
|
||||
|
||||
if (ObjectUtil.isEmpty(taskNode.getDynamicDecisions()) && StrUtil.isBlank(taskNode.getPassNextNodeId())) {
|
||||
throw new RuntimeException("任务节点的通过节点不能为空,请检查");
|
||||
}
|
||||
if (StrUtil.isNotBlank(taskNode.getPassNextNodeId()) && taskNode.getPassNextNodeId().equals(taskNode.getId())) {
|
||||
throw new RuntimeException("任务节点的通过节点不能指向自己,请检查");
|
||||
}
|
||||
if (StrUtil.isBlank(taskNode.getNodePerformType())) {
|
||||
throw new RuntimeException("任务节点的参与类型不能为空,请检查");
|
||||
}
|
||||
// if (StrUtil.isBlank(taskNode.getNodeApprovalType())) {
|
||||
// throw new RuntimeException("任务节点的审批完成类型不能为空,请检查");
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证退回节点
|
||||
* @param backNode
|
||||
* @param nodes
|
||||
*/
|
||||
private static void validateBackNode(BpmProcessNodeDefine backNode, List<BpmProcessNodeDefine> nodes) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取开始节点
|
||||
* @param nodes
|
||||
* @return
|
||||
*/
|
||||
public static BpmProcessNodeDefine getStartNode(List<BpmProcessNodeDefine> nodes) {
|
||||
return nodes.stream().filter(node -> node.getNodeType().equals(BpmProcessNodeTypeEnum.START.name())).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user