|
@@ -1,7 +1,6 @@
|
|
|
package com.fjhx.flow.service.flow.impl;
|
|
|
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
-import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
|
@@ -11,6 +10,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.fjhx.file.utils.ObsFileUtil;
|
|
|
import com.fjhx.flow.core.FlowBean;
|
|
|
import com.fjhx.flow.core.FlowDelegate;
|
|
|
+import com.fjhx.flow.core.FlowJumpContext;
|
|
|
import com.fjhx.flow.core.FlowThreadLocalUtil;
|
|
|
import com.fjhx.flow.entity.flow.dto.FlowResult;
|
|
|
import com.fjhx.flow.entity.flow.dto.InitiateDto;
|
|
@@ -96,7 +96,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
.findFirst().orElse(null);
|
|
|
|
|
|
if (startNode == null) {
|
|
|
- throw new ServiceException("没有找到开始节点");
|
|
|
+ throw new ServiceException("流程定义错误:没有找到开始节点");
|
|
|
}
|
|
|
|
|
|
// 生成流程id
|
|
@@ -108,6 +108,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
FlowThreadLocalUtil.setStartData(dto.getData());
|
|
|
FlowThreadLocalUtil.setCurrentData(dto.getData());
|
|
|
FlowThreadLocalUtil.setFlowId(flowId);
|
|
|
+ FlowThreadLocalUtil.setHandleTypeEnum(HandleTypeEnum.SKIP_TO_NEXT);
|
|
|
|
|
|
// 寻找下一节点
|
|
|
FlowDefinitionNode nextUserNode = getNextUserNode(startNode, flowDefinitionNodeList);
|
|
@@ -131,9 +132,11 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
}
|
|
|
// 流程进行中
|
|
|
flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
|
|
|
+ FlowThreadLocalUtil.setFlowStatusEnum(FlowStatusEnum.IN_PROGRESS);
|
|
|
} else {
|
|
|
// 流程已通过
|
|
|
flowExample.setStatus(FlowStatusEnum.PASS.getKey());
|
|
|
+ FlowThreadLocalUtil.setFlowStatusEnum(FlowStatusEnum.PASS);
|
|
|
}
|
|
|
|
|
|
// 执行开始流程方法
|
|
@@ -190,213 +193,74 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
ObsFileUtil.saveFile(dto.getFileList(), startExampleDetail.getId());
|
|
|
|
|
|
// 推送
|
|
|
- pushInitiate(flowId, flowDefinition, nextNodeType, flowExample);
|
|
|
+ pushInitiateMessage(flowId, flowDefinition, nextNodeType, flowExample);
|
|
|
|
|
|
- FlowResult flowResult = new FlowResult();
|
|
|
- flowResult.setSuccess(true);
|
|
|
- return flowResult;
|
|
|
+ return new FlowResult(true);
|
|
|
}
|
|
|
|
|
|
@DSTransactional
|
|
|
@Override
|
|
|
public FlowResult jump(JumpDto dto) {
|
|
|
- Long flowId = dto.getFlowId();
|
|
|
|
|
|
- FlowExample flowExample = flowExampleService.getById(flowId);
|
|
|
-
|
|
|
- if (flowExample == null) {
|
|
|
- throw new ServiceException("没有找到流程");
|
|
|
- }
|
|
|
-
|
|
|
- // if (flowExample.getStatus() > 1) {
|
|
|
- // throw new ServiceException("流程已结束");
|
|
|
- // }
|
|
|
-
|
|
|
- if (ObjectUtil.notEqual(flowExample.getVersion(), dto.getVersion())) {
|
|
|
- throw new ServiceException("流程已被处理");
|
|
|
- }
|
|
|
-
|
|
|
- // 获取流程委托对象
|
|
|
- FlowDelegate flowDelegate = FlowBean.getBean(flowExample.getFlowKey());
|
|
|
-
|
|
|
- // 流程节点列表
|
|
|
- List<FlowDefinitionNode> flowDefinitionNodeList = flowDefinitionNodeService.list(q -> q
|
|
|
- .eq(FlowDefinitionNode::getFlowDefinitionId, flowExample.getDefinitionId()));
|
|
|
-
|
|
|
- // 获取当前审批节点
|
|
|
- FlowDefinitionNode currentNode = flowDefinitionNodeList.stream()
|
|
|
- .filter(item -> item.getId().equals(flowExample.getDefinitionNodeId()))
|
|
|
- .findFirst().orElse(null);
|
|
|
-
|
|
|
- if (currentNode == null) {
|
|
|
- throw new ServiceException("没有找到当前审批节点");
|
|
|
- }
|
|
|
-
|
|
|
- // 查找跳转类型
|
|
|
- HandleTypeEnum handleTypeEnum = HandleTypeEnum.getEnum(dto.getHandleType());
|
|
|
+ FlowJumpContext context = new FlowJumpContext(dto);
|
|
|
|
|
|
// 发起流程参数
|
|
|
- JSONObject startData = JSONObject.parseObject(flowExample.getStartData());
|
|
|
- Map<String, Object> templateMap = flowDelegate.initTemplateMap(dto.getData(), startData);
|
|
|
+ JSONObject startData = JSONObject.parseObject(context.getFlowExample().getStartData());
|
|
|
+ Map<String, Object> templateMap = context.getFlowDelegate().initTemplateMap(dto.getData(), startData);
|
|
|
FlowThreadLocalUtil.setTemplateData(templateMap);
|
|
|
FlowThreadLocalUtil.setStartData(startData);
|
|
|
FlowThreadLocalUtil.setCurrentData(dto.getData());
|
|
|
- FlowThreadLocalUtil.setFlowId(flowId);
|
|
|
- FlowThreadLocalUtil.setBusinessId(flowExample.getBusinessId());
|
|
|
- FlowThreadLocalUtil.setHandleTypeEnum(handleTypeEnum);
|
|
|
+ FlowThreadLocalUtil.setFlowId(dto.getFlowId());
|
|
|
+ FlowThreadLocalUtil.setBusinessId(context.getFlowExample().getBusinessId());
|
|
|
|
|
|
- // 跳转节点
|
|
|
- FlowDefinitionNode nextUserNode = null;
|
|
|
- switch (handleTypeEnum) {
|
|
|
+ FlowResult flowResult;
|
|
|
+
|
|
|
+ // 流程处理逻辑
|
|
|
+ switch (context.getHandleTypeEnum()) {
|
|
|
|
|
|
// 跳转下一节点
|
|
|
case SKIP_TO_NEXT:
|
|
|
-
|
|
|
- // 寻找下一节点
|
|
|
- nextUserNode = getNextUserNode(currentNode, flowDefinitionNodeList);
|
|
|
-
|
|
|
- // 赋值流程所在id
|
|
|
- flowExample.setDefinitionNodeId(nextUserNode.getId());
|
|
|
-
|
|
|
- // 如果下一节点为结束节点
|
|
|
- if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(nextUserNode.getNodeType()))) {
|
|
|
- // 流程已通过
|
|
|
- flowExample.setStatus(FlowStatusEnum.PASS.getKey());
|
|
|
- }
|
|
|
- // 如果下一节点不为结束节点
|
|
|
- else {
|
|
|
- FlowResult handleUser = getHandleUser(nextUserNode, dto.getHandleUserId());
|
|
|
-
|
|
|
- // 如果下一节点处理用户只有1人,赋值用户id
|
|
|
- if (handleUser.getSuccess()) {
|
|
|
- flowExample.setHandleUserId(handleUser.getUserId());
|
|
|
- FlowThreadLocalUtil.setNextHandleUserId(handleUser.getUserId());
|
|
|
- }
|
|
|
- // 如果下一节点处理用户有多人,则返回用户列表让用户选择下一节点处理人id
|
|
|
- else {
|
|
|
- return handleUser;
|
|
|
- }
|
|
|
-
|
|
|
- // 流程进行中
|
|
|
- flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
|
|
|
- }
|
|
|
+ flowResult = skipToNext(context);
|
|
|
break;
|
|
|
|
|
|
// 结束流程
|
|
|
case REJECT:
|
|
|
- flowExample.setStatus(FlowStatusEnum.REJECT.getKey());
|
|
|
+ flowResult = reject(context);
|
|
|
break;
|
|
|
|
|
|
// 返回上一节点
|
|
|
case RETURN_TO_PREVIOUS:
|
|
|
-
|
|
|
- // 查找上一个节点
|
|
|
- FlowDefinitionNode lastOneUserNode = getLastOneUserNode(currentNode, flowDefinitionNodeList);
|
|
|
-
|
|
|
- // 赋值流程所在id
|
|
|
- flowExample.setDefinitionNodeId(lastOneUserNode.getId());
|
|
|
-
|
|
|
- // 如果流程回退到开始节点
|
|
|
- if (NodeTypeEnum.START.getKey().equals(lastOneUserNode.getNodeType())) {
|
|
|
- // 流程未发起
|
|
|
- flowExample.setStatus(FlowStatusEnum.READY_START.getKey());
|
|
|
- } else {
|
|
|
- FlowResult handleUser = getHandleUser(lastOneUserNode, dto.getHandleUserId());
|
|
|
-
|
|
|
- // 如果上一节点处理用户只有1人,赋值用户id
|
|
|
- if (handleUser.getSuccess()) {
|
|
|
- flowExample.setHandleUserId(handleUser.getUserId());
|
|
|
- FlowThreadLocalUtil.setNextHandleUserId(handleUser.getUserId());
|
|
|
- }
|
|
|
- // 如果下一节点处理用户有多人,则返回用户列表让用户选择上一节点处理人id
|
|
|
- else {
|
|
|
- return handleUser;
|
|
|
- }
|
|
|
-
|
|
|
- // 流程进行中
|
|
|
- flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
|
|
|
- }
|
|
|
+ flowResult = returnToPrevious(context);
|
|
|
break;
|
|
|
|
|
|
// 退回到发起人
|
|
|
case RETURN_TO_SUBMITTER:
|
|
|
-
|
|
|
- // 获取第一个用户操作节点
|
|
|
- FlowExampleDetail exampleDetail = flowExampleDetailService.getOne(q -> q
|
|
|
- .eq(FlowExampleDetail::getFlowExampleId, flowId));
|
|
|
-
|
|
|
- flowExample.setHandleUserId(exampleDetail.getCreateUser());
|
|
|
- flowExample.setDefinitionNodeId(exampleDetail.getFlowDefinitionNodeId());
|
|
|
- flowExample.setStatus(FlowStatusEnum.READY_START.getKey());
|
|
|
- FlowThreadLocalUtil.setNextHandleUserId(exampleDetail.getCreateUser());
|
|
|
+ flowResult = returnToSubmitter(context);
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
- throw new ServiceException("未知节点处理类型");
|
|
|
-
|
|
|
- }
|
|
|
+ throw new ServiceException("未知流程跳转类型");
|
|
|
|
|
|
- // 执行当前节点方法
|
|
|
- String handlingMethod = currentNode.getHandlingMethod();
|
|
|
- if (StrUtil.isNotBlank(handlingMethod)) {
|
|
|
- try {
|
|
|
- invokeMethod(flowDelegate, handlingMethod);
|
|
|
- } catch (Exception e) {
|
|
|
- if (e instanceof InvocationTargetException) {
|
|
|
- Throwable targetException = ((InvocationTargetException) e).getTargetException();
|
|
|
- log.error("跳转节点方法异常", targetException);
|
|
|
- throw new ServiceException("跳转节点方法异常:" + targetException.getMessage());
|
|
|
- }
|
|
|
- log.error("跳转节点方法异常", e);
|
|
|
- throw new ServiceException("跳转节点方法异常:" + e.getMessage());
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
- // 节点处理明细
|
|
|
- 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(JSONObject.toJSONString(dto));
|
|
|
- flowExampleDetailList.add(nodeExampleDetail);
|
|
|
-
|
|
|
- // 如果流程已结束
|
|
|
- if (FlowStatusEnum.PASS.getKey().equals(flowExample.getStatus())) {
|
|
|
-
|
|
|
- // 执行结束方法
|
|
|
- invokeEndMethod(nextUserNode, flowDelegate);
|
|
|
-
|
|
|
- // 结束流程明细
|
|
|
- FlowExampleDetail endExampleDetail = new FlowExampleDetail();
|
|
|
- endExampleDetail.setFlowExampleId(flowId);
|
|
|
- endExampleDetail.setFlowDefinitionNodeId(nextUserNode.getId());
|
|
|
- endExampleDetail.setFlowDefinitionNodeType(nextUserNode.getNodeType());
|
|
|
- endExampleDetail.setHandleType(HandleTypeEnum.SKIP_TO_NEXT.getKey());
|
|
|
- flowExampleDetailList.add(endExampleDetail);
|
|
|
-
|
|
|
+ // 如果跳转节点审批人有多个,则返回用户列表让当前节点审批人选择下一节点审批人id
|
|
|
+ if (!flowResult.getSuccess()) {
|
|
|
+ return flowResult;
|
|
|
}
|
|
|
|
|
|
- flowExample.setVersion(dto.getVersion());
|
|
|
+ FlowThreadLocalUtil.setFlowStatusEnum(context.getFlowStatusEnum());
|
|
|
+ FlowThreadLocalUtil.setHandleTypeEnum(context.getHandleTypeEnum());
|
|
|
+ FlowThreadLocalUtil.setNextHandleUserId(context.getJumpHandleUserId());
|
|
|
|
|
|
- // 不修改发起数据
|
|
|
- flowExample.setStartData(null);
|
|
|
- boolean updateFlag = flowExampleService.updateById(flowExample);
|
|
|
- if (!updateFlag) {
|
|
|
- throw new ServiceException("流程已被处理");
|
|
|
- }
|
|
|
- flowExampleDetailService.saveBatch(flowExampleDetailList);
|
|
|
+ // 执行节点方法
|
|
|
+ executiveNodeMethod(context);
|
|
|
|
|
|
- // 保存节点附件
|
|
|
- ObsFileUtil.saveFile(dto.getFileList(), nodeExampleDetail.getId());
|
|
|
+ // 保存数据
|
|
|
+ editExample(context);
|
|
|
|
|
|
// 消息推送
|
|
|
- pushJump(handleTypeEnum, nextUserNode, flowExample, currentNode);
|
|
|
+ pushJumpMessage(context);
|
|
|
|
|
|
- FlowResult flowResult = new FlowResult();
|
|
|
- flowResult.setSuccess(true);
|
|
|
return flowResult;
|
|
|
}
|
|
|
|
|
@@ -413,15 +277,151 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 流程跳转到下一个节点
|
|
|
+ */
|
|
|
+ private FlowResult skipToNext(FlowJumpContext context) {
|
|
|
+
|
|
|
+ // 寻找跳转节点
|
|
|
+ FlowDefinitionNode jumpNode = getNextUserNode(context.getCurrentNode(), context.getFlowDefinitionNodeList());
|
|
|
+ context.setJumpNode(jumpNode);
|
|
|
+
|
|
|
+ // 如果下一节点为结束节点
|
|
|
+ if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(jumpNode.getNodeType()))) {
|
|
|
+ // 流程已通过
|
|
|
+ context.setFlowStatusEnum(FlowStatusEnum.PASS);
|
|
|
+ // 流程结束,则流程节点审批人不存在
|
|
|
+ context.setJumpHandleUserId(null);
|
|
|
+ return new FlowResult(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 寻找节点审批人
|
|
|
+ FlowResult flowResult = getHandleUser(jumpNode, context.getJumpHandleUserId());
|
|
|
+ // 流程进行中
|
|
|
+ context.setFlowStatusEnum(FlowStatusEnum.IN_PROGRESS);
|
|
|
+ // 赋值流程节点审批人
|
|
|
+ context.setJumpHandleUserId(flowResult.getUserId());
|
|
|
+
|
|
|
+ return flowResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 拒绝流程
|
|
|
+ */
|
|
|
+ private FlowResult reject(FlowJumpContext context) {
|
|
|
+
|
|
|
+ // 流程已驳回
|
|
|
+ context.setFlowStatusEnum(FlowStatusEnum.REJECT);
|
|
|
+ // 流程结束,则流程节点审批人不存在
|
|
|
+ context.setJumpHandleUserId(null);
|
|
|
+
|
|
|
+ for (FlowDefinitionNode flowDefinitionNode : context.getFlowDefinitionNodeList()) {
|
|
|
+ if (NodeTypeEnum.END.getKey().equals(flowDefinitionNode.getNodeType())) {
|
|
|
+ context.setJumpNode(flowDefinitionNode);
|
|
|
+ return new FlowResult(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ throw new ServiceException("流程定义错误:未找到结束节点");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 流程跳转到上一个节点
|
|
|
+ */
|
|
|
+ private FlowResult returnToPrevious(FlowJumpContext context) {
|
|
|
+
|
|
|
+ // 寻找跳转节点
|
|
|
+ FlowDefinitionNode jumpNode = getLastOneUserNode(context.getCurrentNode(), context.getFlowDefinitionNodeList());
|
|
|
+ context.setJumpNode(jumpNode);
|
|
|
+
|
|
|
+ // 如果流程回退到开始节点
|
|
|
+ if (NodeTypeEnum.START.getKey().equals(jumpNode.getNodeType())) {
|
|
|
+ // 流程未发起
|
|
|
+ context.setFlowStatusEnum(FlowStatusEnum.READY_START);
|
|
|
+ // 流程节点处理人为流程发起人
|
|
|
+ context.setJumpHandleUserId(context.getFlowExample().getCreateUser());
|
|
|
+ return new FlowResult(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ FlowResult flowResult = getHandleUser(jumpNode, context.getJumpHandleUserId());
|
|
|
+ // 流程进行中
|
|
|
+ context.setFlowStatusEnum(FlowStatusEnum.IN_PROGRESS);
|
|
|
+ // 赋值流程节点审批人
|
|
|
+ context.setJumpHandleUserId(flowResult.getUserId());
|
|
|
+
|
|
|
+ return flowResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 退回到发起人
|
|
|
+ */
|
|
|
+ private FlowResult returnToSubmitter(FlowJumpContext context) {
|
|
|
+
|
|
|
+ // 流程未发起
|
|
|
+ context.setFlowStatusEnum(FlowStatusEnum.READY_START);
|
|
|
+ // 赋值发起人为节点审批人
|
|
|
+ context.setJumpHandleUserId(context.getFlowExample().getCreateUser());
|
|
|
+
|
|
|
+ for (FlowDefinitionNode flowDefinitionNode : context.getFlowDefinitionNodeList()) {
|
|
|
+ if (NodeTypeEnum.START.getKey().equals(flowDefinitionNode.getNodeType())) {
|
|
|
+ context.setJumpNode(flowDefinitionNode);
|
|
|
+ return new FlowResult(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ throw new ServiceException("流程定义错误:未找到开始节点");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 执行节点方法
|
|
|
- *
|
|
|
- * @param flowDelegate 流程代理对象
|
|
|
- * @param handlingMethod 流程执行方法名
|
|
|
*/
|
|
|
- private void invokeMethod(FlowDelegate flowDelegate, String handlingMethod) throws Exception {
|
|
|
- Class<? extends FlowDelegate> flowDelegateCls = flowDelegate.getClass();
|
|
|
- Method method = flowDelegateCls.getMethod(handlingMethod.trim());
|
|
|
- method.invoke(flowDelegate);
|
|
|
+ private void executiveNodeMethod(FlowJumpContext context) {
|
|
|
+
|
|
|
+ // 当前节点方法
|
|
|
+ String handlingMethod = context.getCurrentNode().getHandlingMethod();
|
|
|
+
|
|
|
+ // 流程委托对象
|
|
|
+ FlowDelegate flowDelegate = context.getFlowDelegate();
|
|
|
+
|
|
|
+ // 流程状态
|
|
|
+ FlowStatusEnum flowStatusEnum = context.getFlowStatusEnum();
|
|
|
+
|
|
|
+ // 自定义方法不为空,走自定义方法
|
|
|
+ if (StrUtil.isNotBlank(handlingMethod)) {
|
|
|
+ try {
|
|
|
+ invokeMethod(flowDelegate, handlingMethod);
|
|
|
+ } catch (Exception e) {
|
|
|
+ if (e instanceof InvocationTargetException) {
|
|
|
+ Throwable targetException = ((InvocationTargetException) e).getTargetException();
|
|
|
+ log.error("跳转节点方法异常", targetException);
|
|
|
+ throw new ServiceException("跳转节点方法异常:" + targetException.getMessage());
|
|
|
+ }
|
|
|
+ log.error("跳转节点方法异常", e);
|
|
|
+ throw new ServiceException("跳转节点方法异常:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行默认方法
|
|
|
+ else {
|
|
|
+ try {
|
|
|
+ FlowExample flowExample = context.getFlowExample();
|
|
|
+ Long flowId = flowExample.getId();
|
|
|
+ Long businessId = flowExample.getBusinessId();
|
|
|
+
|
|
|
+ JSONObject data = context.getJumpDto().getData();
|
|
|
+
|
|
|
+ flowDelegate.defaultMethod(flowId, businessId, flowStatusEnum, data);
|
|
|
+ } catch (Exception e) {
|
|
|
+
|
|
|
+ log.error("跳转节点方法异常", e);
|
|
|
+ throw new ServiceException("跳转节点方法异常:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 结束节点
|
|
|
+ if (flowStatusEnum == FlowStatusEnum.PASS) {
|
|
|
+ invokeEndMethod(context.getJumpNode(), flowDelegate);
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -456,6 +456,64 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 执行节点方法
|
|
|
+ *
|
|
|
+ * @param flowDelegate 流程代理对象
|
|
|
+ * @param handlingMethod 流程执行方法名
|
|
|
+ */
|
|
|
+ private void invokeMethod(FlowDelegate flowDelegate, String handlingMethod) throws Exception {
|
|
|
+ Class<? extends FlowDelegate> flowDelegateCls = flowDelegate.getClass();
|
|
|
+ Method method = flowDelegateCls.getMethod(handlingMethod.trim());
|
|
|
+ method.invoke(flowDelegate);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存数据
|
|
|
+ */
|
|
|
+ private void editExample(FlowJumpContext context) {
|
|
|
+
|
|
|
+ JumpDto dto = context.getJumpDto();
|
|
|
+ FlowExample flowExample = context.getFlowExample();
|
|
|
+ FlowDefinitionNode currentNode = context.getCurrentNode();
|
|
|
+ FlowDefinitionNode jumpNode = context.getJumpNode();
|
|
|
+
|
|
|
+ // 更新流程实例
|
|
|
+ flowExample.setStartData(null);
|
|
|
+ boolean updateFlag = flowExampleService.updateById(flowExample);
|
|
|
+ if (!updateFlag) {
|
|
|
+ throw new ServiceException("流程已被处理");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 节点处理明细
|
|
|
+ List<FlowExampleDetail> flowExampleDetailList = new ArrayList<>();
|
|
|
+ FlowExampleDetail nodeExampleDetail = new FlowExampleDetail();
|
|
|
+ nodeExampleDetail.setFlowExampleId(flowExample.getId());
|
|
|
+ nodeExampleDetail.setFlowDefinitionNodeId(currentNode.getId());
|
|
|
+ nodeExampleDetail.setFlowDefinitionNodeType(currentNode.getNodeType());
|
|
|
+ nodeExampleDetail.setHandleType(dto.getHandleType());
|
|
|
+ nodeExampleDetail.setHandleRemark(dto.getRemark());
|
|
|
+ nodeExampleDetail.setSubmitData(JSONObject.toJSONString(dto));
|
|
|
+ flowExampleDetailList.add(nodeExampleDetail);
|
|
|
+
|
|
|
+ // 如果流程已结束
|
|
|
+ if (FlowStatusEnum.PASS.equals(context.getFlowStatusEnum())) {
|
|
|
+ FlowExampleDetail endExampleDetail = new FlowExampleDetail();
|
|
|
+ endExampleDetail.setFlowExampleId(flowExample.getId());
|
|
|
+ endExampleDetail.setFlowDefinitionNodeId(jumpNode.getId());
|
|
|
+ endExampleDetail.setFlowDefinitionNodeType(jumpNode.getNodeType());
|
|
|
+ endExampleDetail.setHandleType(HandleTypeEnum.SKIP_TO_NEXT.getKey());
|
|
|
+ flowExampleDetailList.add(endExampleDetail);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存流程明细
|
|
|
+ flowExampleDetailService.saveBatch(flowExampleDetailList);
|
|
|
+
|
|
|
+ // 保存节点附件
|
|
|
+ ObsFileUtil.saveFile(dto.getFileList(), nodeExampleDetail.getId());
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 查找上一个节点
|
|
|
*
|
|
|
* @param currentNode 当前节点
|
|
@@ -486,12 +544,15 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
* @return 用户节点
|
|
|
*/
|
|
|
private FlowDefinitionNode getNextUserNode(FlowDefinitionNode currentNode, List<FlowDefinitionNode> flowDefinitionNodeList) {
|
|
|
+
|
|
|
// 父级节点map
|
|
|
- Map<Long, List<FlowDefinitionNode>> parentNodeMap =
|
|
|
- flowDefinitionNodeList.stream().collect(Collectors.groupingBy(FlowDefinitionNode::getParentId));
|
|
|
+ Map<Long, List<FlowDefinitionNode>> parentNodeMap = flowDefinitionNodeList.stream()
|
|
|
+ .collect(Collectors.groupingBy(FlowDefinitionNode::getParentId));
|
|
|
+
|
|
|
// 查找下个节点
|
|
|
List<FlowDefinitionNode> nextNodeList = parentNodeMap.get(currentNode.getId());
|
|
|
FlowDefinitionNode nextNode = null;
|
|
|
+
|
|
|
// 如果为分支
|
|
|
if (NodeTypeEnum.BRANCH.equals(NodeTypeEnum.getEnum(currentNode.getNodeType()))) {
|
|
|
// 循环分支
|
|
@@ -509,21 +570,27 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
}
|
|
|
}
|
|
|
if (nextNode == null) {
|
|
|
- throw new ServiceException("未识别到分支跳转节点");
|
|
|
+ throw new ServiceException("流程定义错误:分支节点未识别到有效跳转节点");
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
// 如果不为分支
|
|
|
else {
|
|
|
- if (nextNodeList == null || nextNodeList.size() != 1) {
|
|
|
- throw new ServiceException("流程定义错误");
|
|
|
+ if (nextNodeList == null || nextNodeList.size() == 0) {
|
|
|
+ throw new ServiceException("流程定义错误:用户节点未找到跳转节点");
|
|
|
+ }
|
|
|
+ if (nextNodeList.size() > 1) {
|
|
|
+ throw new ServiceException("流程定义错误:用户节点找到多个跳转节点");
|
|
|
}
|
|
|
// 查找下一个节点方法
|
|
|
nextNode = nextNodeList.get(0);
|
|
|
}
|
|
|
+
|
|
|
// 如果下一节点为分支,递归找下一节点
|
|
|
if (NodeTypeEnum.BRANCH.equals(NodeTypeEnum.getEnum(nextNode.getNodeType()))) {
|
|
|
return getNextUserNode(nextNode, flowDefinitionNodeList);
|
|
|
}
|
|
|
+
|
|
|
return nextNode;
|
|
|
}
|
|
|
|
|
@@ -558,13 +625,13 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
case DEPT_DIRECTOR:
|
|
|
SysDept sysDept = sysDeptService.getById(handleObjectId);
|
|
|
if (sysDept == null) {
|
|
|
- throw new ServiceException("部门为空");
|
|
|
+ throw new ServiceException("流程节点处理人异常:没有找到节点处理部门");
|
|
|
}
|
|
|
// 部门负责人
|
|
|
if (HandleObjectTypeEnum.DETP_LEADER.equals(handleObjectTypeEnum)) {
|
|
|
Long leaderId = sysDept.getLeaderId();
|
|
|
if (leaderId == null) {
|
|
|
- throw new ServiceException("部门负责人为空");
|
|
|
+ throw new ServiceException("流程节点处理人异常:没有找到节点处理部门负责人");
|
|
|
}
|
|
|
flowResult.setUserId(leaderId);
|
|
|
}
|
|
@@ -572,7 +639,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
else {
|
|
|
Long directorId = sysDept.getDirectorId();
|
|
|
if (directorId == null) {
|
|
|
- throw new ServiceException("部门总监为空");
|
|
|
+ throw new ServiceException("流程节点处理人异常:没有找到节点处理部门总监");
|
|
|
}
|
|
|
flowResult.setUserId(directorId);
|
|
|
}
|
|
@@ -582,7 +649,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
case POST:
|
|
|
List<SysUser> postUserList = sysUserService.getListByPostId(handleObjectId);
|
|
|
if (postUserList.size() == 0) {
|
|
|
- throw new ServiceException("岗位无用户");
|
|
|
+ throw new ServiceException("流程节点处理人异常:节点处理岗位无用户");
|
|
|
}
|
|
|
if (postUserList.size() == 1) {
|
|
|
flowResult.setSuccess(true);
|
|
@@ -596,7 +663,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
case ROLE:
|
|
|
List<SysUser> roleUserList = sysUserService.getListByRoleId(handleObjectId);
|
|
|
if (roleUserList.size() == 0) {
|
|
|
- throw new ServiceException("角色无用户");
|
|
|
+ throw new ServiceException("流程节点处理人异常:节点处理角色无用户");
|
|
|
}
|
|
|
if (roleUserList.size() == 1) {
|
|
|
flowResult.setSuccess(true);
|
|
@@ -614,23 +681,9 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 校验el表达式
|
|
|
- */
|
|
|
- public boolean expressionResult(Map<String, Object> map, String expression) {
|
|
|
- try {
|
|
|
- Expression exp = AviatorEvaluator.compile(expression);
|
|
|
- Object execute = exp.execute(map);
|
|
|
- return Boolean.parseBoolean(String.valueOf(execute));
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("el表达式校验错误", e);
|
|
|
- throw new ServiceException("el表达式校验错误:" + e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
* 开始节点消息推送
|
|
|
*/
|
|
|
- private void pushInitiate(long flowId, FlowDefinition flowDefinition, NodeTypeEnum nextNodeType, FlowExample flowExample) {
|
|
|
+ private void pushInitiateMessage(long flowId, FlowDefinition flowDefinition, NodeTypeEnum nextNodeType, FlowExample flowExample) {
|
|
|
Map<String, Object> businessData = new HashMap<>();
|
|
|
businessData.put("flowId", flowId);
|
|
|
businessData.put("flowKey", flowDefinition.getFlowKey());
|
|
@@ -654,7 +707,15 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
/**
|
|
|
* 跳转节点消息推送
|
|
|
*/
|
|
|
- private void pushJump(HandleTypeEnum handleTypeEnum, FlowDefinitionNode nextUserNode, FlowExample flowExample, FlowDefinitionNode currentNode) {
|
|
|
+ private void pushJumpMessage(FlowJumpContext context) {
|
|
|
+
|
|
|
+ FlowExample flowExample = context.getFlowExample();
|
|
|
+ HandleTypeEnum handleTypeEnum = context.getHandleTypeEnum();
|
|
|
+ FlowStatusEnum flowStatusEnum = context.getFlowStatusEnum();
|
|
|
+ FlowDefinitionNode jumpNode = context.getJumpNode();
|
|
|
+ FlowDefinitionNode currentNode = context.getCurrentNode();
|
|
|
+ Long jumpHandleUserId = context.getJumpHandleUserId();
|
|
|
+
|
|
|
Map<String, Object> businessData = new HashMap<>();
|
|
|
businessData.put("flowId", flowExample.getId());
|
|
|
businessData.put("flowKey", flowExample.getFlowKey());
|
|
@@ -668,8 +729,8 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
switch (handleTypeEnum) {
|
|
|
// 跳转下一节点
|
|
|
case SKIP_TO_NEXT:
|
|
|
- // 如果下一节点为结束节点
|
|
|
- if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(nextUserNode.getNodeType()))) {
|
|
|
+ // 如果流程结束
|
|
|
+ if (FlowStatusEnum.PASS.equals(flowStatusEnum)) {
|
|
|
title = StrUtil.format("您于【{}】发起的【{}】已经审批通过。",
|
|
|
DateUtil.formatDateTime(flowExample.getCreateTime()),
|
|
|
flowName);
|
|
@@ -678,7 +739,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
// 如果下一节点不为结束节点
|
|
|
else {
|
|
|
title = "您有一条新的待审批事项,请及时处理。";
|
|
|
- pushUserId = flowExample.getHandleUserId();
|
|
|
+ pushUserId = jumpHandleUserId;
|
|
|
}
|
|
|
break;
|
|
|
|
|
@@ -691,27 +752,35 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
pushUserId = flowExample.getCreateUser();
|
|
|
break;
|
|
|
|
|
|
- // 退回上一节点,退回到发起人
|
|
|
+ // 退回上一节点
|
|
|
case RETURN_TO_PREVIOUS:
|
|
|
- case RETURN_TO_SUBMITTER:
|
|
|
|
|
|
// 查找上次审批节点
|
|
|
FlowExampleDetail flowExampleDetail = flowExampleDetailService.getOne(
|
|
|
Wrappers.<FlowExampleDetail>lambdaQuery()
|
|
|
.eq(FlowExampleDetail::getFlowExampleId, flowExample.getId())
|
|
|
+ .eq(FlowExampleDetail::getFlowDefinitionNodeId, jumpNode.getId())
|
|
|
.orderByDesc(BaseIdPo::getId)
|
|
|
- .last("limit 1,1")
|
|
|
- );
|
|
|
+ .last("limit 1,1"));
|
|
|
|
|
|
title = StrUtil.format("您于【{}】提交的【{}】被退回,请及时处理。",
|
|
|
DateUtil.formatDateTime(flowExampleDetail.getCreateTime()),
|
|
|
flowName);
|
|
|
|
|
|
- pushUserId = flowExampleDetail.getCreateUser();
|
|
|
+ pushUserId = jumpHandleUserId;
|
|
|
+ break;
|
|
|
+
|
|
|
+ // 退回到发起人
|
|
|
+ case RETURN_TO_SUBMITTER:
|
|
|
+ title = StrUtil.format("您于【{}】提交的【{}】被退回,请及时处理。",
|
|
|
+ DateUtil.formatDateTime(flowExample.getCreateTime()),
|
|
|
+ flowName);
|
|
|
+
|
|
|
+ pushUserId = jumpHandleUserId;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
- throw new ServiceException("未知处理方法");
|
|
|
+ throw new ServiceException("未知流程跳转类型");
|
|
|
}
|
|
|
|
|
|
WebSocketPush.byUser(PushTypeEnum.MESSAGE, pushUserId, title, 0, businessData);
|
|
@@ -719,35 +788,42 @@ public class FlowProcessServiceImpl implements FlowProcessService {
|
|
|
|
|
|
// public static void main(String[] args) {
|
|
|
// HashMap<String, Object> map = new HashMap<>();
|
|
|
- //
|
|
|
// HashMap<Object, Object> dd = new HashMap<>();
|
|
|
// dd.put("A", "a1");
|
|
|
// dd.put("B", "b1");
|
|
|
// dd.put("C", "c1");
|
|
|
- //
|
|
|
- //
|
|
|
// map.put("aa", "aa");
|
|
|
// map.put("bb", "bb");
|
|
|
// map.put("cc", Arrays.asList("A", "B", "C", "D"));
|
|
|
// map.put("dd", dd);
|
|
|
- //
|
|
|
// System.out.println(expressionResult(map,
|
|
|
// "aa == 'aa' && bb == 'bb' && cc[0] == 'A' && dd.A == 'a1' "
|
|
|
// ));
|
|
|
- //
|
|
|
// }
|
|
|
|
|
|
// public static void main(String[] args) {
|
|
|
- //
|
|
|
// System.out.println(
|
|
|
// templateParse(
|
|
|
// "测试1:${Integer.parseInt(a)+1}; 测试2:${a+1}; 测试3:${b.tt}; 测试4:${b.vv}; 测试5:${b.vv[0]};",
|
|
|
// JSONObject.parseObject("{a: \"1\", b: {tt: \"t\", vv: [\"aa\", \"bb\", \"cc\"] }}"))
|
|
|
// );
|
|
|
- //
|
|
|
// }
|
|
|
|
|
|
/**
|
|
|
+ * 校验el表达式
|
|
|
+ */
|
|
|
+ public boolean expressionResult(Map<String, Object> map, String expression) {
|
|
|
+ try {
|
|
|
+ Expression exp = AviatorEvaluator.compile(expression);
|
|
|
+ Object execute = exp.execute(map);
|
|
|
+ return Boolean.parseBoolean(String.valueOf(execute));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("el表达式校验错误", e);
|
|
|
+ throw new ServiceException("el表达式校验错误:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 模板替换
|
|
|
*
|
|
|
* <p>
|