add:添加流程触发功能:todo:子流程数据通用

This commit is contained in:
zhangzq
2024-05-08 13:47:22 +08:00
parent 7fb22d2fbf
commit a16ae9fb64
12 changed files with 158 additions and 75 deletions

View File

@@ -29,4 +29,8 @@ public class ExecutionController {
StartProcessInstanceVo startProcessInstanceVo = form.toJavaObject(StartProcessInstanceVo.class);
return new ResponseEntity<>(flowOperationService.startFormFlow(startProcessInstanceVo), HttpStatus.OK);
}
@GetMapping(value = "/confirm")
public ResponseEntity<Object> flowConfirm(String inst_id){
return new ResponseEntity<>(flowOperationService.flowConfirm(inst_id), HttpStatus.OK);
}
}

View File

@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.common.enums.StatusEnum;
import org.nl.common.utils.MapOf;
@@ -35,16 +36,23 @@ public abstract class FlowNodeActivityBehavior<T> {
public final void activity(ExecutionEntity<T> entity) {
try {
iActRuExecutionService.update(new UpdateWrapper<ActRuExecution>()
.eq("proc_inst_id",entity.getProc_inst_id())
.set("activity_id", entity.getActivityId())
.set("activity_name", entity.getActivityName())
.set("form_type", entity.getForm_type())
.set("form_id", entity.getForm_id())
.set("update_time", DateUtil.now()));
//当前节点
if (StringUtils.isNotEmpty(entity.getProc_inst_id())){
iActRuExecutionService.update(new UpdateWrapper<ActRuExecution>()
.eq("proc_inst_id",entity.getProc_inst_id())
.set("activity_id", entity.getActivityId())
.set("activity_name", entity.getActivityName())
.set("form_type", entity.getForm_type())
.set("form_id", entity.getForm_id())
.set("remark", "")
.set("status", StatusEnum.FLOW_STATUS.code("执行中"))
.set("form_data", JSONObject.toJSON(entity.getT()).toString())
.set("update_time", DateUtil.now()));
}
this.execute(entity);
this.leaveActivity(entity);
}catch (Exception ex){
ex.printStackTrace();
log.error(entity.getActivityName()+"流程执行异常:{}",ex.getMessage());
ActRuExecution execution = new ActRuExecution();
execution.setProc_inst_id(entity.getProc_inst_id());
@@ -52,7 +60,6 @@ public abstract class FlowNodeActivityBehavior<T> {
.eq("proc_inst_id",entity.getProc_inst_id())
.set("status", StatusEnum.FLOW_STATUS.code("暂停"))
.set("remark","流程节点:"+entity.getActivityName()+"执行错误"+ex.getMessage()));
throw new BadRequestException(ex.getMessage());
}
}
private final void leaveActivity(ExecutionEntity<T> entity) {
@@ -68,7 +75,6 @@ public abstract class FlowNodeActivityBehavior<T> {
historyEntity.setUpdate_time(DateUtil.now());
history.save(historyEntity);
this.leave(entity);
FlowNode currentFlowElement = (FlowNode)entity.getCurrentFlowElement();
if (currentFlowElement.getPassNode()){
CommandExecutor.getAgenda().planOperation(new SequenceFlowOperation(entity));

View File

@@ -32,6 +32,14 @@ import java.util.concurrent.CountDownLatch;
@Service("endEvent")
public class EndEventActivityBehavior extends FlowNodeActivityBehavior {
@Autowired
private IActReProcdefService reProcdefService;
@Autowired
private BpmnJSONConverter bpmnJSONConverter;
@Autowired
private CommandExecutor commandExecutor;
@Override
public void execute(ExecutionEntity entity) {
//流程结束:判断是否是子流程,是的话调用父流程
@@ -44,6 +52,30 @@ public class EndEventActivityBehavior extends FlowNodeActivityBehavior {
@Override
@SneakyThrows
public void leave(ExecutionEntity entity) {
ActRuExecution execution = iActRuExecutionService.getById(entity.getProc_inst_id());
if (StringUtils.isNotEmpty(execution.getParent_id())){
//判断当前所有子流程是否都完成:全都完成则执行父流程
int count = iActRuExecutionService.count(new QueryWrapper<ActRuExecution>()
.eq("parent_id", execution.getParent_id())
.ne("status", StatusEnum.FLOW_STATUS.code("完成")));
if (count == 0){
ActRuExecution parent = iActRuExecutionService.getById(entity.getParent_id());
ActReProcdef deployment = reProcdefService.getOne(new LambdaUpdateWrapper<ActReProcdef>().eq(ActReProcdef::getDeployment_id, entity.getDeploymentId()));
if (deployment==null){
throw new BadRequestException("当前单据类型未配置业务流程");
}
String model_json_string = deployment.getModel_editor_json();
//转流程实例:
JSONObject model_json = JSONObject.parseObject(model_json_string);
BpmnModel bpmnModel = bpmnJSONConverter.convertToBpmnModel(deployment.getModel_key(), deployment.getVersion(), model_json);
String current = parent.getActivity_id();
FlowNode flowNode = bpmnModel.getProcesses().get(current);
//通过该标识触发
flowNode.setPassNode(Boolean.TRUE);
entity.setCurrentFlowElement(flowNode);
entity.setProc_inst_id(parent.getProc_inst_id());
entity.setParent_id(parent.getParent_id());
}
}
}
}

View File

@@ -106,8 +106,4 @@ public class FormActivityBehavior extends FlowNodeActivityBehavior<JSONObject> {
}
}
@Override
public void leave(ExecutionEntity execution) {
super.leave(execution);
}
}

View File

@@ -32,9 +32,4 @@ public class IostorOutActivityBehavior extends FlowNodeActivityBehavior<PmFormDa
//生成出入库单单据
}
@Override
public void leave(ExecutionEntity execution) {
super.leave(execution);
}
}

View File

@@ -34,9 +34,4 @@ public class ServerTaskActivityBehavior extends FlowNodeActivityBehavior<JSONObj
}
super.execute(entity);
}
@Override
public void leave(ExecutionEntity entity) {
super.leave(entity);
}
}

View File

@@ -1,6 +1,7 @@
package org.nl.wms.flow_manage.flow.framework.engine.behavior.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.common.enums.StatusEnum;
import org.nl.common.utils.IdUtil;
@@ -45,6 +46,7 @@ public class StartEventActivityBehavior extends FlowNodeActivityBehavior {
execution.setForm_type(entity.getForm_type());
execution.setParent_id(entity.getParent_id());
execution.setForm_id(entity.getForm_id());
execution.setForm_data((JSONObject) JSONObject.toJSON(entity.getT()));
execution.setActivity_id(entity.getActivityId());
execution.setActivity_name(entity.getActivityName());
execution.setCreate_time(DateUtil.now());
@@ -53,9 +55,4 @@ public class StartEventActivityBehavior extends FlowNodeActivityBehavior {
entity.setProc_inst_id(execution.getProc_inst_id());
}
@Override
public void leave(ExecutionEntity execution) {
}
}

View File

@@ -26,6 +26,7 @@ import org.nl.wms.flow_manage.flow.service.execution.dao.ActRuExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.UUID;
@@ -41,9 +42,6 @@ import java.util.stream.Stream;
@Service("subProcess")
public class SubProcessActivityBehavior extends FlowNodeActivityBehavior<JSONObject> {
@Autowired
private IActReProcdefService deploymentService;
@Autowired
private IActReProcdefService reProcdefService;
@Autowired
@@ -64,17 +62,30 @@ public class SubProcessActivityBehavior extends FlowNodeActivityBehavior<JSONObj
JSONObject form = entity.getT();
JSONArray items = form.getJSONArray("item");
//子流程并行
items.stream().map((Function<Object, CompletableFuture>) o -> CompletableFuture.runAsync(() -> {
ExecutionEntity clone = (ExecutionEntity) entity.clone();
clone.setParent_id(entity.getProc_inst_id());
clone.setT(o);
clone.setCurrentFlowElement(startEvent);
commandExecutor.execute(new StartInstanceCmd(), clone);
})).parallel().forEach(CompletableFuture::join);
StringBuffer buffer = new StringBuffer();
if (items!=null){
//子流程并行,子流程单一的时候直接串行
items.stream().map((Function<Object, CompletableFuture>) o -> CompletableFuture.runAsync(() -> {
ExecutionEntity subEntity = new ExecutionEntity();
subEntity.setParent_id(entity.getProc_inst_id());
subEntity.setForm_id(entity.getForm_id());
subEntity.setForm_type(entity.getForm_type());
subEntity.setDeploymentId(entity.getDeploymentId());
subEntity.setCurrentFlowElement(startEvent);
subEntity.setT(entity.getT());
//在endEvent中有个所有子流程结束的判断如果判断成功会触发父流程startEvent暂时通过等待处理防止自动流程导致endEvent判断出错
commandExecutor.execute(new StartInstanceCmd(), subEntity);
}).exceptionally(throwable -> {
buffer.append("子流程执行异常"+throwable.getMessage());
return null;
})).parallel().forEach(CompletableFuture::join);
}
String errorMsg = buffer.toString();
if (StringUtils.isNotEmpty(errorMsg)){
throw new BadRequestException("子流程执行异常"+errorMsg);
}
}
super.execute(entity);
}
private StartEvent getStartEvent(List<FlowElement> flowElements) {
@@ -86,32 +97,4 @@ public class SubProcessActivityBehavior extends FlowNodeActivityBehavior<JSONObj
return null;
}
@Override
public void leave(ExecutionEntity<JSONObject> entity) {
ActRuExecution execution = iActRuExecutionService.getById(entity.getProc_inst_id());
if (StringUtils.isNotEmpty(execution.getParent_id())){
//判断当前所有子流程是否都完成:全都完成则执行父流程
int count = iActRuExecutionService.count(new QueryWrapper<ActRuExecution>()
.eq("parent_id", execution.getParent_id())
.ne("status", StatusEnum.FLOW_STATUS.code("完成")));
if (count == 0){
ActRuExecution parent = iActRuExecutionService.getById(entity.getParent_id());
ActReProcdef deployment = reProcdefService.getOne(new LambdaUpdateWrapper<ActReProcdef>().eq(ActReProcdef::getDeployment_id, entity.getDeploymentId()));
if (deployment==null){
throw new BadRequestException("当前单据类型未配置业务流程");
}
String model_json_string = deployment.getModel_editor_json();
//转流程实例:
JSONObject model_json = JSONObject.parseObject(model_json_string);
BpmnModel bpmnModel = bpmnJSONConverter.convertToBpmnModel(deployment.getModel_key(), deployment.getVersion(), model_json);
String current = parent.getActivity_id();
FlowNode flowNode = bpmnModel.getProcesses().get(current);
//通过该标识触发
flowNode.setPassNode(Boolean.TRUE);
entity.setCurrentFlowElement(flowNode);
entity.setProc_inst_id(parent.getProc_inst_id());
entity.setParent_id(parent.getParent_id());
}
}
}
}

View File

@@ -0,0 +1,34 @@
package org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.impl;
import org.nl.common.enums.StatusEnum;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.Command;
import org.nl.wms.flow_manage.flow.framework.engine.operation.impl.ContinuOperation;
import org.nl.wms.flow_manage.flow.framework.engine.operation.impl.SequenceFlowOperation;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
/*
* @author ZZQ
* @Date 2024/3/19 17:57
*/
public class ExeInstanceCmd implements Command {
/**
* 流程状态:用于区分流程是重试还是继续
*/
private String status;
public ExeInstanceCmd(String status) {
this.status = status;
}
@Override
public Object execute(ExecutionEntity entity) {
//获取当前流程版本信息有可能是流程线需要区分SequenceFlowOperation
if (StatusEnum.FLOW_STATUS.code("暂停").equals(status)){
CommandExecutor.getAgenda().planOperation(new ContinuOperation(entity));
}else {
CommandExecutor.getAgenda().planOperation(new SequenceFlowOperation(entity));
}
return null;
}
}

View File

@@ -58,12 +58,12 @@ public class MappingHandler extends TypeHandler<JSONObject, JSONObject> {
}
returnObj.put("form_data",form_data);
}
JSONArray dtls = data.getJSONArray("dtl");
if (dtls!=null){
JSONArray item = data.getJSONArray("item");
if (item!=null){
JSONArray itemList = new JSONArray();
BmFormStruc item_struc = iBmFormStrucService.getOne(new QueryWrapper<BmFormStruc>().eq("parent_id",form_struc.getForm_type()));
for (int i = 0; i < dtls.size(); i++) {
JSONObject dtl = dtls.getJSONObject(i);
for (int i = 0; i < item.size(); i++) {
JSONObject dtl = item.getJSONObject(i);
itemList.add(this.handler(param, dtl, item_struc));
}
returnObj.put("item",itemList);

View File

@@ -17,4 +17,6 @@ public interface IFlowOperationService {
Boolean startUp(String form_type, JSONObject mst,List<JSONObject> items);
Boolean startFormFlow(StartProcessInstanceVo params);
Boolean flowConfirm(String proc_inst_id);
}

View File

@@ -2,15 +2,19 @@ package org.nl.wms.flow_manage.flow.service.execution.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.common.enums.StatusEnum;
import org.nl.common.utils.IdUtil;
import org.nl.wms.flow_manage.flow.framework.BpmnModel;
import org.nl.wms.flow_manage.flow.framework.converter.BpmnJSONConverter;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.CommandExecutor;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.impl.ExeInstanceCmd;
import org.nl.wms.flow_manage.flow.framework.engine.cmd.unify.impl.StartInstanceCmd;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionEntity;
import org.nl.wms.flow_manage.flow.framework.entity.node.base.impl.FlowNode;
import org.nl.wms.flow_manage.flow.service.deployment.IActReProcdefService;
import org.nl.wms.flow_manage.flow.service.deployment.dao.ActReProcdef;
import org.nl.wms.flow_manage.flow.service.execution.IActRuExecutionService;
@@ -54,7 +58,7 @@ public class FlowOperationServiceImpl implements IFlowOperationService {
System.out.println(bpmnModel.getNodeFlow().size());
//创建流程参数ExecutionEntity执行流程
mst.put("dtl",items);
mst.put("item",items);
ExecutionEntity entity = new ExecutionEntity();
entity.setCurrentFlowElement(bpmnModel.getStartEvent());
entity.setT(mst);
@@ -77,4 +81,39 @@ public class FlowOperationServiceImpl implements IFlowOperationService {
return null;
}
@Override
public Boolean flowConfirm(String proc_inst_id) {
if (StringUtils.isNotEmpty(proc_inst_id)){
//当前流程
ActRuExecution execution = iActRuExecutionService.getOne(new QueryWrapper<ActRuExecution>()
.eq("proc_inst_id",proc_inst_id)
.ne("status",StatusEnum.FLOW_STATUS.code("完成")));
if (execution==null){
throw new BadRequestException("当前流程实例不存在或已经完结");
}
ActReProcdef deployment = actReProcdefService.getOne(new LambdaUpdateWrapper<ActReProcdef>()
.eq(ActReProcdef::getDeployment_id, execution.getDeployment_id()));
if (deployment==null){
throw new BadRequestException("当前单据类型未配置业务流程");
}
String model_json_string = deployment.getModel_editor_json();
//转流程实例:
JSONObject model_json = JSONObject.parseObject(model_json_string);
BpmnModel bpmnModel = bpmnJSONConverter.convertToBpmnModel(deployment.getModel_key(), deployment.getVersion(), model_json);
FlowNode flowNode = bpmnModel.getProcesses().get(execution.getActivity_id());
ExecutionEntity entity = new ExecutionEntity();
entity.setCurrentFlowElement(flowNode);
entity.setT(execution.getForm_data());
entity.setProc_inst_id(execution.getProc_inst_id());
entity.setParent_id(execution.getParent_id());
entity.setForm_type(execution.getForm_type());
entity.setForm_id(execution.getForm_id());
entity.setStartActivityId(execution.getActivity_id());
entity.setDeploymentId(execution.getDeployment_id());
//如果流程执行异常:需要重新执行,如果执行中则走下一步
commandExecutor.execute(new ExeInstanceCmd(execution.getStatus()),entity);
}
return true;
}
}