|
@@ -2,22 +2,25 @@ package com.fjhx.flow.service.flow.impl;
|
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.extra.spring.SpringUtil;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
|
import com.fjhx.flow.core.FlowBean;
|
|
|
import com.fjhx.flow.core.FlowDelegate;
|
|
|
import com.fjhx.flow.core.FlowThreadLocalUtil;
|
|
|
import com.fjhx.flow.entity.flow.dto.InitiateDto;
|
|
|
+import com.fjhx.flow.entity.flow.dto.JumpDto;
|
|
|
import com.fjhx.flow.entity.flow.po.FlowDefinition;
|
|
|
import com.fjhx.flow.entity.flow.po.FlowDefinitionNode;
|
|
|
import com.fjhx.flow.entity.flow.po.FlowExample;
|
|
|
import com.fjhx.flow.entity.flow.po.FlowExampleDetail;
|
|
|
-import com.fjhx.flow.enums.FlowStatus;
|
|
|
-import com.fjhx.flow.enums.HandleType;
|
|
|
+import com.fjhx.flow.enums.FlowStatusEnum;
|
|
|
+import com.fjhx.flow.enums.HandleTypeEnum;
|
|
|
import com.fjhx.flow.enums.NodeTypeEnum;
|
|
|
import com.fjhx.flow.service.flow.*;
|
|
|
import com.googlecode.aviator.AviatorEvaluator;
|
|
|
import com.googlecode.aviator.Expression;
|
|
|
import com.ruoyi.common.constant.StatusConstant;
|
|
|
+import com.ruoyi.common.core.domain.BaseIdPo;
|
|
|
import com.ruoyi.common.exception.ServiceException;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
@@ -30,6 +33,7 @@ import java.lang.reflect.Method;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
@@ -60,15 +64,10 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
// 找到代码定义的流程bean
|
|
|
Class<? extends FlowDelegate> flowDelegateCls = FlowBean.getBean(dto.getFlowKey());
|
|
|
|
|
|
- // 实例化bean
|
|
|
- FlowDelegate flowDelegate;
|
|
|
+ // 获取流程委托对象
|
|
|
+ FlowDelegate flowDelegate = getFlowDelegate(flowDelegateCls);
|
|
|
|
|
|
- flowDelegate = SpringUtil.getBean(flowDelegateCls);
|
|
|
- if (flowDelegate == null) {
|
|
|
- throw new ServiceException("没有把流程bean注册到spring中");
|
|
|
- }
|
|
|
-
|
|
|
- // 查找流程定义
|
|
|
+ // 查找可用流程
|
|
|
FlowDefinition flowDefinition = flowDefinitionService.getOne(q -> q
|
|
|
.eq(FlowDefinition::getFlowKey, dto.getFlowKey())
|
|
|
.eq(FlowDefinition::getCurrentVersion, StatusConstant.YES));
|
|
@@ -78,8 +77,8 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
}
|
|
|
|
|
|
// 流程节点列表
|
|
|
- List<FlowDefinitionNode> flowDefinitionNodeList = flowDefinitionNodeService
|
|
|
- .list(q -> q.eq(FlowDefinitionNode::getFlowDefinitionId, flowDefinition.getId()));
|
|
|
+ List<FlowDefinitionNode> flowDefinitionNodeList = flowDefinitionNodeService.list(
|
|
|
+ q -> q.eq(FlowDefinitionNode::getFlowDefinitionId, flowDefinition.getId()));
|
|
|
|
|
|
// 父级节点map
|
|
|
Map<Long, List<FlowDefinitionNode>> parentNodeMap = flowDefinitionNodeList.stream()
|
|
@@ -127,43 +126,24 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
startExampleDetail.setFlowExampleId(flowId);
|
|
|
startExampleDetail.setFlowDefinitionNodeId(startNode.getId());
|
|
|
startExampleDetail.setFlowDefinitionNodeType(startNode.getNodeType());
|
|
|
- startExampleDetail.setHandleType(HandleType.NEXT.getKey());
|
|
|
+ startExampleDetail.setHandleType(HandleTypeEnum.NEXT.getKey());
|
|
|
flowExampleDetailList.add(startExampleDetail);
|
|
|
|
|
|
// 如果下个节点是结束节点
|
|
|
if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(nextUserNode.getNodeType()))) {
|
|
|
- // 走非默认方法
|
|
|
- String handlingMethod = nextUserNode.getHandlingMethod();
|
|
|
- if (StrUtil.isNotBlank(handlingMethod)) {
|
|
|
- try {
|
|
|
- Method method = flowDelegateCls.getMethod(handlingMethod);
|
|
|
- method.invoke(flowDelegate);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new ServiceException("未找到指定处理方法:" + handlingMethod);
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 执行流程结束方法
|
|
|
- flowDelegate.end();
|
|
|
- }
|
|
|
-
|
|
|
+ // 添加明细
|
|
|
+ flowExampleDetailList.add(executeEndFun(flowId, nextUserNode, flowDelegateCls, flowDelegate));
|
|
|
// 流程已通过
|
|
|
- flowExample.setStatus(FlowStatus.HAVE_PASSED.getKey());
|
|
|
-
|
|
|
- // 结束流程
|
|
|
- FlowExampleDetail endExampleDetail = new FlowExampleDetail();
|
|
|
- endExampleDetail.setFlowExampleId(flowId);
|
|
|
- endExampleDetail.setFlowDefinitionNodeId(nextUserNode.getId());
|
|
|
- endExampleDetail.setFlowDefinitionNodeType(nextUserNode.getNodeType());
|
|
|
- endExampleDetail.setHandleType(HandleType.OVER.getKey());
|
|
|
- flowExampleDetailList.add(endExampleDetail);
|
|
|
+ flowExample.setStatus(FlowStatusEnum.HAVE_PASSED.getKey());
|
|
|
} else {
|
|
|
// 流程进行中
|
|
|
- flowExample.setStatus(FlowStatus.IN_PROGRESS.getKey());
|
|
|
+ flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
|
|
|
}
|
|
|
|
|
|
flowExample.setTitle(StrUtil.format(flowDefinition.getTitleTemplate(), templateMap, true));
|
|
|
+ flowExample.setFlowKey(dto.getFlowKey());
|
|
|
flowExample.setDefinitionId(flowDefinition.getId());
|
|
|
- flowExample.setDefintionNodeId(nextUserNode.getId());
|
|
|
+ flowExample.setDefinitionNodeId(nextUserNode.getId());
|
|
|
flowExample.setBusinessId(businessId);
|
|
|
flowExample.setStartData(dto.getData().toJSONString());
|
|
|
flowExampleService.save(flowExample);
|
|
@@ -180,6 +160,202 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void jump(JumpDto dto) {
|
|
|
+ Long flowId = dto.getFlowId();
|
|
|
+ FlowExample flowExample = flowExampleService.getById(flowId);
|
|
|
+ if (flowExample == null) {
|
|
|
+ throw new ServiceException("没有找到流程");
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer status = flowExample.getStatus();
|
|
|
+ if (status > 1) {
|
|
|
+ throw new ServiceException("流程已结束");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 找到代码定义的流程bean
|
|
|
+ Class<? extends FlowDelegate> flowDelegateCls = FlowBean.getBean(flowExample.getFlowKey());
|
|
|
+
|
|
|
+ // 获取流程委托对象
|
|
|
+ FlowDelegate flowDelegate = getFlowDelegate(flowDelegateCls);
|
|
|
+
|
|
|
+ // 流程节点列表
|
|
|
+ List<FlowDefinitionNode> flowDefinitionNodeList = flowDefinitionNodeService.list(
|
|
|
+ q -> q.eq(FlowDefinitionNode::getFlowDefinitionId, flowExample.getDefinitionId()));
|
|
|
+
|
|
|
+ // 获取当前审批节点
|
|
|
+ Long definitionNodeId = flowExample.getDefinitionNodeId();
|
|
|
+ FlowDefinitionNode currentNode = flowDefinitionNodeList.stream()
|
|
|
+ .filter(item -> item.getId().equals(definitionNodeId)).findFirst().orElse(null);
|
|
|
+
|
|
|
+ if (currentNode == null) {
|
|
|
+ throw new ServiceException("没有找到当前审批节点");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查找跳转节点
|
|
|
+ HandleTypeEnum handleTypeEnum = HandleTypeEnum.getEnum(dto.getHandleType());
|
|
|
+
|
|
|
+ // 发起流程参数
|
|
|
+ JSONObject startDataJson = JSONObject.parseObject(flowExample.getStartData());
|
|
|
+ Map<String, Object> templateMap = flowDelegate.initTemplateMap(dto.getData(), startDataJson);
|
|
|
+ FlowThreadLocalUtil.setTemplateData(templateMap);
|
|
|
+ FlowThreadLocalUtil.setStartData(dto.getData());
|
|
|
+ FlowThreadLocalUtil.setCurrentData(dto.getData());
|
|
|
+ FlowThreadLocalUtil.setFlowId(flowId);
|
|
|
+ FlowThreadLocalUtil.setBusinessId(flowExample.getBusinessId());
|
|
|
+ FlowThreadLocalUtil.setHandleTypeEnum(handleTypeEnum);
|
|
|
+
|
|
|
+ // 流程实例明细列表
|
|
|
+ List<FlowExampleDetail> flowExampleDetailList = new ArrayList<>();
|
|
|
+
|
|
|
+ // 节点处理
|
|
|
+ FlowExampleDetail nodeExampleDetail = new FlowExampleDetail();
|
|
|
+ nodeExampleDetail.setFlowExampleId(flowId);
|
|
|
+ nodeExampleDetail.setFlowDefinitionNodeId(currentNode.getId());
|
|
|
+ nodeExampleDetail.setFlowDefinitionNodeType(currentNode.getNodeType());
|
|
|
+ nodeExampleDetail.setHandleType(dto.getHandleType());
|
|
|
+ nodeExampleDetail.setHandleRemark(dto.getRemark());
|
|
|
+ nodeExampleDetail.setSubmitData(dto.getData().toJSONString());
|
|
|
+ flowExampleDetailList.add(nodeExampleDetail);
|
|
|
+
|
|
|
+ FlowDefinitionNode jumpUserNode = null;
|
|
|
+
|
|
|
+ switch (handleTypeEnum) {
|
|
|
+ case NEXT:
|
|
|
+ // 父级节点map
|
|
|
+ Map<Long, List<FlowDefinitionNode>> parentNodeMap = flowDefinitionNodeList.stream()
|
|
|
+ .collect(Collectors.groupingBy(FlowDefinitionNode::getParentId));
|
|
|
+ // 寻找下一节点
|
|
|
+ jumpUserNode = getNextUserNode(currentNode, parentNodeMap);
|
|
|
+ // 赋值流程所在id
|
|
|
+ flowExample.setDefinitionNodeId(jumpUserNode.getId());
|
|
|
+ // 如果下个节点是结束节点
|
|
|
+ if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(jumpUserNode.getNodeType()))) {
|
|
|
+ // 流程已通过
|
|
|
+ flowExample.setStatus(FlowStatusEnum.HAVE_PASSED.getKey());
|
|
|
+ // 结束流程
|
|
|
+ FlowExampleDetail endExampleDetail = new FlowExampleDetail();
|
|
|
+ endExampleDetail.setFlowExampleId(flowId);
|
|
|
+ endExampleDetail.setFlowDefinitionNodeId(jumpUserNode.getId());
|
|
|
+ endExampleDetail.setFlowDefinitionNodeType(jumpUserNode.getNodeType());
|
|
|
+ endExampleDetail.setHandleType(HandleTypeEnum.OVER.getKey());
|
|
|
+ flowExampleDetailList.add(endExampleDetail);
|
|
|
+ } else {
|
|
|
+ // 流程进行中
|
|
|
+ flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case PREVIOUS:
|
|
|
+ // 节点id对象map
|
|
|
+ Map<Long, FlowDefinitionNode> nodeMap = flowDefinitionNodeList.stream()
|
|
|
+ .collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
|
|
|
+ // 查找上一个节点
|
|
|
+ jumpUserNode = getLastOneUserNode(currentNode, nodeMap);
|
|
|
+ // 赋值流程所在id
|
|
|
+ flowExample.setDefinitionNodeId(jumpUserNode.getId());
|
|
|
+ // 如果流程回退到开始节点
|
|
|
+ if (NodeTypeEnum.START.equals(NodeTypeEnum.getEnum(jumpUserNode.getNodeType()))) {
|
|
|
+ // 流程进行中
|
|
|
+ flowExample.setStatus(FlowStatusEnum.UNINITIATED.getKey());
|
|
|
+ } else {
|
|
|
+ // 流程进行中
|
|
|
+ flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case OVER:
|
|
|
+ flowExample.setStatus(FlowStatusEnum.REJECTED.getKey());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 开启一个事务
|
|
|
+ TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
|
|
|
+
|
|
|
+ try {
|
|
|
+ flowExampleService.updateById(flowExample);
|
|
|
+ flowExampleDetailService.saveBatch(flowExampleDetailList);
|
|
|
+
|
|
|
+ if (jumpUserNode != null) {
|
|
|
+ String handlingMethod = jumpUserNode.getHandlingMethod();
|
|
|
+ if (StrUtil.isNotBlank(handlingMethod)) {
|
|
|
+ invokeMethod(flowDelegateCls, flowDelegate, handlingMethod);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ flowDelegate.rejected();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提交事务
|
|
|
+ platformTransactionManager.commit(transaction);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 提交事务
|
|
|
+ platformTransactionManager.rollback(transaction);
|
|
|
+ log.error("业务错误", e);
|
|
|
+ throw new ServiceException("业务代码错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行结束方法
|
|
|
+ *
|
|
|
+ * @param flowId 流程id
|
|
|
+ * @param nextUserNode 下个用户节点
|
|
|
+ * @param flowDelegateCls 流程代理class
|
|
|
+ * @param flowDelegate 流程代理对象
|
|
|
+ * @return 节点明细
|
|
|
+ */
|
|
|
+ private FlowExampleDetail executeEndFun(Long flowId, FlowDefinitionNode nextUserNode,
|
|
|
+ Class<? extends FlowDelegate> flowDelegateCls, FlowDelegate flowDelegate) {
|
|
|
+
|
|
|
+ // 走非默认方法
|
|
|
+ String handlingMethod = nextUserNode.getHandlingMethod();
|
|
|
+ if (StrUtil.isNotBlank(handlingMethod)) {
|
|
|
+ // 执行节点方法
|
|
|
+ invokeMethod(flowDelegateCls, flowDelegate, handlingMethod);
|
|
|
+ } else {
|
|
|
+ // 执行流程结束方法
|
|
|
+ flowDelegate.end();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 结束流程
|
|
|
+ FlowExampleDetail endExampleDetail = new FlowExampleDetail();
|
|
|
+ endExampleDetail.setFlowExampleId(flowId);
|
|
|
+ endExampleDetail.setFlowDefinitionNodeId(nextUserNode.getId());
|
|
|
+ endExampleDetail.setFlowDefinitionNodeType(nextUserNode.getNodeType());
|
|
|
+ endExampleDetail.setHandleType(HandleTypeEnum.OVER.getKey());
|
|
|
+ return endExampleDetail;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行节点方法
|
|
|
+ *
|
|
|
+ * @param flowDelegateCls 流程代理class
|
|
|
+ * @param flowDelegate 流程代理对象
|
|
|
+ * @param handlingMethod 流程执行方法名
|
|
|
+ */
|
|
|
+ private void invokeMethod(Class<? extends FlowDelegate> flowDelegateCls, FlowDelegate flowDelegate, String handlingMethod) {
|
|
|
+ try {
|
|
|
+ Method method = flowDelegateCls.getMethod(handlingMethod.trim());
|
|
|
+ method.invoke(flowDelegate);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("自定义处理方法异常:{}", handlingMethod, e);
|
|
|
+ throw new ServiceException("自定义处理方法异常:" + handlingMethod);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取流程委托对象
|
|
|
+ *
|
|
|
+ * @param flowDelegateCls 流程代理class
|
|
|
+ * @return 流程委托对象
|
|
|
+ */
|
|
|
+ private FlowDelegate getFlowDelegate(Class<? extends FlowDelegate> flowDelegateCls) {
|
|
|
+ FlowDelegate flowDelegate = SpringUtil.getBean(flowDelegateCls);
|
|
|
+ if (flowDelegate == null) {
|
|
|
+ throw new ServiceException("没有把流程bean加入到spring中");
|
|
|
+ }
|
|
|
+ return flowDelegate;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 查找下一个用户执行节点
|
|
|
*
|
|
@@ -227,9 +403,24 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 查找上一个节点
|
|
|
+ *
|
|
|
+ * @param currentNode 当前节点
|
|
|
+ * @param nodeMap id节点map
|
|
|
+ * @return 用户节点
|
|
|
+ */
|
|
|
+ private FlowDefinitionNode getLastOneUserNode(FlowDefinitionNode currentNode, Map<Long, FlowDefinitionNode> nodeMap) {
|
|
|
+ FlowDefinitionNode lastOneUserNode = nodeMap.get(currentNode.getParentId());
|
|
|
+ if (NodeTypeEnum.BRANCH.equals(NodeTypeEnum.getEnum(lastOneUserNode.getNodeType()))) {
|
|
|
+ return getLastOneUserNode(lastOneUserNode, nodeMap);
|
|
|
+ }
|
|
|
+ return lastOneUserNode;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 校验el表达式
|
|
|
*/
|
|
|
- public static boolean expressionResult(Map<String, Object> map, String expression) {
|
|
|
+ public boolean expressionResult(Map<String, Object> map, String expression) {
|
|
|
Expression exp = AviatorEvaluator.compile(expression);
|
|
|
Object execute = exp.execute(map);
|
|
|
return Boolean.parseBoolean(String.valueOf(execute));
|