add:添加流程触发功能:todo:子流程数据通用
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,8 +106,4 @@ public class FormActivityBehavior extends FlowNodeActivityBehavior<JSONObject> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leave(ExecutionEntity execution) {
|
||||
super.leave(execution);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,4 @@ public class IostorOutActivityBehavior extends FlowNodeActivityBehavior<PmFormDa
|
||||
//生成出入库单单据
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leave(ExecutionEntity execution) {
|
||||
super.leave(execution);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,4 @@ public class ServerTaskActivityBehavior extends FlowNodeActivityBehavior<JSONObj
|
||||
}
|
||||
super.execute(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leave(ExecutionEntity entity) {
|
||||
super.leave(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user