json转bpmn协议开发
This commit is contained in:
parent
21e48ea486
commit
f7be7b64da
@ -0,0 +1,14 @@
|
||||
package cn.axzo.server.repository.mapper;
|
||||
|
||||
import cn.axzo.server.service.dto.process.BpmProcessInstanceExtDO;
|
||||
import cn.axzo.server.service.dto.response.PageResult;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@Mapper
|
||||
public interface BpmProcessInstanceExtMapper extends BaseMapper<BpmProcessInstanceExtDO> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
package cn.axzo.server.service.dto.process;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@TableName(value = "bpm_process_instance_ext", autoResultMap = true)
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class BpmProcessInstanceExtDO {
|
||||
/**
|
||||
* 编号,自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 流程实例的名字
|
||||
* <p>
|
||||
* 冗余 ProcessInstance 的 name 属性,用于筛选
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 自定义的流程实例的编号
|
||||
*/
|
||||
private String customProInstId;
|
||||
/**
|
||||
* 流程实例的编号
|
||||
* <p>
|
||||
* 关联 ProcessInstance 的 id 属性
|
||||
*/
|
||||
private String processInstanceId;
|
||||
/**
|
||||
* 流程定义的编号
|
||||
* <p>
|
||||
* 关联 ProcessDefinition 的 id 属性
|
||||
*/
|
||||
private String processDefinitionId;
|
||||
/**
|
||||
* 流程分类
|
||||
* <p>
|
||||
* 冗余 ProcessDefinition 的 category 属性 数据字典 bpm_model_category
|
||||
*/
|
||||
private String category;
|
||||
/**
|
||||
* 流程实例的状态
|
||||
* <p>
|
||||
* 枚举 {@link BpmProcessInstanceStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 流程实例的结果
|
||||
* <p>
|
||||
* 枚举 {@link BpmProcessInstanceResultEnum}
|
||||
*/
|
||||
private Integer result;
|
||||
/**
|
||||
* 结束时间
|
||||
* <p>
|
||||
* 冗余 HistoricProcessInstance 的 endTime 属性
|
||||
*/
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 提交的表单值
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Map<String, Object> formVariables;
|
||||
|
||||
/**
|
||||
* 发起人所在的工作台ID(企业/项目)
|
||||
* <p>
|
||||
* 使用租户字段隔离
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 发起人所在的项目工作台中的具体单位ID
|
||||
*/
|
||||
private Long startCompanyId;
|
||||
|
||||
/**
|
||||
* 发起人的身份ID
|
||||
*/
|
||||
private Long startIdentityId;
|
||||
|
||||
/**
|
||||
* 发起人的姓名
|
||||
*/
|
||||
private String startUserName;
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
package cn.axzo.server.service.impl;
|
||||
|
||||
public class BpmProcessServiceImpl {
|
||||
}
|
||||
@ -20,11 +20,84 @@ import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DEL
|
||||
|
||||
public class BpmTransformUtil {
|
||||
|
||||
public String transformBpmnJsonToXml(DDBpmModelSaveReqVO updateReqVO) {
|
||||
|
||||
JSONObject bpmnJson = (JSONObject) updateReqVO.getBpmnJson();
|
||||
|
||||
BpmnModel bpmnModel =new BpmnModel();
|
||||
Process process=new Process();
|
||||
bpmnModel.addProcess(process);
|
||||
List<SequenceFlow> sequenceFlows = Lists.newArrayList();
|
||||
process.setId(updateReqVO.getKey());
|
||||
StartEvent startEvent = DDBpmnModelUtils.createStartEvent();
|
||||
process.addFlowElement(startEvent);
|
||||
process.setName(updateReqVO.getName());
|
||||
|
||||
ExtensionAttribute extensionAttribute=new ExtensionAttribute();
|
||||
extensionAttribute.setName("TestName");
|
||||
extensionAttribute.setNamespace("http://flowable.org/bpmn");
|
||||
extensionAttribute.setValue(bpmnJson.toJSONString());
|
||||
// process.addAttribute(extensionAttribute);
|
||||
JSONObject processNodes = bpmnJson.getJSONObject("nodeConfig");
|
||||
String lastNode = null;
|
||||
try {
|
||||
lastNode = create(startEvent.getId(), processNodes,bpmnModel,process,sequenceFlows);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new ServiceException(1245, "协议解析出错");
|
||||
}
|
||||
EndEvent endEvent = createEndEvent();
|
||||
process.addFlowElement(endEvent);
|
||||
process.addFlowElement(connect(lastNode, endEvent.getId(),sequenceFlows));
|
||||
|
||||
new BpmnAutoLayout(bpmnModel).execute();
|
||||
String xmlResult = new String(new BpmnXMLConverter().convertToXML(bpmnModel));
|
||||
System.err.println(xmlResult);
|
||||
return xmlResult;
|
||||
}
|
||||
|
||||
// @PostMapping("/jsonToBpmn")
|
||||
// public Object saveForm(@RequestBody com.alibaba.fastjson.JSONObject jsonObject) throws InvocationTargetException, IllegalAccessException {
|
||||
// System.err.println(jsonObject.toJSONString());
|
||||
// BpmnModel bpmnModel =new BpmnModel();
|
||||
// Process process=new Process();
|
||||
// bpmnModel.addProcess(process);
|
||||
// List<SequenceFlow> sequenceFlows = Lists.newArrayList();
|
||||
// process.setId("flowableV2_"+idWorker.nextId());
|
||||
// StartEvent startEvent = BpmnModelUtils.createStartEvent();
|
||||
// process.addFlowElement(startEvent);
|
||||
// com.alibaba.fastjson.JSONObject workFlowObj = jsonObject.getJSONObject("_value");
|
||||
// String name = workFlowObj.getJSONObject("workFlowDef").getString("name");
|
||||
// process.setName(name);
|
||||
//
|
||||
// ExtensionAttribute extensionAttribute=new ExtensionAttribute();
|
||||
// extensionAttribute.setName("DingDing");
|
||||
// extensionAttribute.setNamespace("http://flowable.org/bpmn");
|
||||
// extensionAttribute.setValue(jsonObject.toJSONString());
|
||||
// process.addAttribute(extensionAttribute);
|
||||
// com.alibaba.fastjson.JSONObject processNodes = workFlowObj.getJSONObject("nodeConfig");
|
||||
// String lastNode = create(startEvent.getId(), processNodes,bpmnModel,process,sequenceFlows);
|
||||
// EndEvent endEvent = createEndEvent();
|
||||
// process.addFlowElement(endEvent);
|
||||
// process.addFlowElement(connect(lastNode, endEvent.getId(),sequenceFlows));
|
||||
//
|
||||
// new BpmnAutoLayout(bpmnModel).execute();
|
||||
// System.err.println(new String(new BpmnXMLConverter().convertToXML(bpmnModel)));
|
||||
// return R.ok("保存成功");
|
||||
// }
|
||||
|
||||
private static String create(String fromId, com.alibaba.fastjson.JSONObject flowNode, BpmnModel model, Process process, List<SequenceFlow> sequenceFlows) throws InvocationTargetException, IllegalAccessException {
|
||||
String nodeType = flowNode.getString("type");
|
||||
|
||||
if ("userTask".equals(nodeType)) {
|
||||
if (DDFlowNodeType.NODE_PARALLEL.name().equals(nodeType)) {
|
||||
return createParallelGatewayBuilder(fromId, flowNode,model,process,sequenceFlows);
|
||||
}
|
||||
else if (DDFlowNodeType.NODE_ROUTER.name().equals(nodeType)) {
|
||||
return createExclusiveGatewayBuilder(fromId, flowNode,model,process,sequenceFlows);
|
||||
}
|
||||
else if (DDFlowNodeType.NODE_STARTER.name().equals(nodeType)) {
|
||||
// flowNode.put("incoming", Collections.singletonList(fromId));
|
||||
String id = fromId;
|
||||
|
||||
// 如果当前任务还有后续任务,则遍历创建后续任务
|
||||
com.alibaba.fastjson.JSONObject nextNode = flowNode.getJSONObject("childNode");
|
||||
if (Objects.nonNull(nextNode)) {
|
||||
@ -34,7 +107,20 @@ public class BpmTransformUtil {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
else if ("condition".equals(nodeType)) {
|
||||
else if (DDFlowNodeType.NODE_COPY.name().equals(nodeType)) {
|
||||
flowNode.put("incoming", Collections.singletonList(fromId));
|
||||
String id = createServiceTask(flowNode,process,sequenceFlows);
|
||||
|
||||
// 如果当前任务还有后续任务,则遍历创建后续任务
|
||||
com.alibaba.fastjson.JSONObject nextNode = flowNode.getJSONObject("childNode");
|
||||
if (Objects.nonNull(nextNode)) {
|
||||
FlowElement flowElement = model.getFlowElement(id);
|
||||
return create(id, nextNode,model,process,sequenceFlows);
|
||||
} else {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
else if (DDFlowNodeType.NODE_TASK.name().equals(nodeType)) {
|
||||
flowNode.put("incoming", Collections.singletonList(fromId));
|
||||
String id = createTask(flowNode,process,sequenceFlows);
|
||||
|
||||
@ -52,6 +138,229 @@ public class BpmTransformUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static String createExclusiveGatewayBuilder(String formId, com.alibaba.fastjson.JSONObject flowNode, BpmnModel model, Process process, List<SequenceFlow> sequenceFlows) throws InvocationTargetException, IllegalAccessException {
|
||||
String name = flowNode.getString("nodeName");
|
||||
String exclusiveGatewayId = id("exclusiveGateway");
|
||||
ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
|
||||
exclusiveGateway.setId(exclusiveGatewayId);
|
||||
exclusiveGateway.setName(name);
|
||||
process.addFlowElement(exclusiveGateway);
|
||||
process.addFlowElement(connect(formId, exclusiveGatewayId,sequenceFlows));
|
||||
|
||||
if (Objects.isNull(flowNode.getJSONArray("conditionNodes")) && Objects.isNull(flowNode.getJSONObject("childNode"))) {
|
||||
return exclusiveGatewayId;
|
||||
}
|
||||
List<com.alibaba.fastjson.JSONObject> flowNodes = Optional.ofNullable(flowNode.getJSONArray("conditionNodes")).map(e -> e.toJavaList(com.alibaba.fastjson.JSONObject.class)).orElse(Collections.emptyList());
|
||||
List<String> incoming = Lists.newArrayListWithCapacity(flowNodes.size());
|
||||
|
||||
List<com.alibaba.fastjson.JSONObject> conditions = Lists.newCopyOnWriteArrayList();
|
||||
for (com.alibaba.fastjson.JSONObject element : flowNodes) {
|
||||
com.alibaba.fastjson.JSONObject childNode = element.getJSONObject("childNode");
|
||||
|
||||
String nodeName = element.getString("nodeName");
|
||||
String expression = element.getString("conditionExpression");
|
||||
|
||||
if (Objects.isNull(childNode)) {
|
||||
incoming.add(exclusiveGatewayId);
|
||||
com.alibaba.fastjson.JSONObject condition = new com.alibaba.fastjson.JSONObject();
|
||||
condition.fluentPut("nodeName", nodeName)
|
||||
.fluentPut("expression", expression);
|
||||
conditions.add(condition);
|
||||
continue;
|
||||
}
|
||||
// 只生成一个任务,同时设置当前任务的条件
|
||||
childNode.put("incoming", Collections.singletonList(exclusiveGatewayId));
|
||||
String identifier = create(exclusiveGatewayId, childNode,model,process,sequenceFlows);
|
||||
List<SequenceFlow> flows = sequenceFlows.stream().filter(flow -> StringUtils.equals(exclusiveGatewayId, flow.getSourceRef()))
|
||||
.collect(Collectors.toList());
|
||||
flows.stream().forEach(
|
||||
e -> {
|
||||
if (StringUtils.isBlank(e.getName()) && StringUtils.isNotBlank(nodeName)) {
|
||||
e.setName(nodeName);
|
||||
}
|
||||
// 设置条件表达式
|
||||
if (Objects.isNull(e.getConditionExpression()) && StringUtils.isNotBlank(expression)) {
|
||||
e.setConditionExpression(expression);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (Objects.nonNull(identifier)) {
|
||||
incoming.add(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
com.alibaba.fastjson.JSONObject childNode = flowNode.getJSONObject("childNode");
|
||||
|
||||
if (Objects.nonNull(childNode)) {
|
||||
if (incoming == null || incoming.isEmpty()) {
|
||||
return create(exclusiveGatewayId, childNode,model,process,sequenceFlows);
|
||||
}
|
||||
else {
|
||||
// 所有 service task 连接 end exclusive gateway
|
||||
childNode.put("incoming", incoming);
|
||||
FlowElement flowElement = model.getFlowElement(incoming.get(0));
|
||||
// 1.0 先进行边连接, 暂存 nextNode
|
||||
com.alibaba.fastjson.JSONObject nextNode = childNode.getJSONObject("childNode");
|
||||
String endExId=id("exclusiveGateway")+"end";
|
||||
process.addFlowElement(DDBpmnModelUtils.createExclusiveGateWayEnd(endExId));
|
||||
childNode.put("childNode", null);
|
||||
String identifier =endExId;/*create(flowElement.getId(), childNode,model,process,sequenceFlows);*/
|
||||
for (int i = 0; i < incoming.size(); i++) {
|
||||
process.addFlowElement(connect(incoming.get(i), endExId,sequenceFlows));
|
||||
}
|
||||
|
||||
// 针对 gateway 空任务分支 添加条件表达式
|
||||
if (!conditions.isEmpty()) {
|
||||
FlowElement flowElement1 = model.getFlowElement(identifier);
|
||||
// 获取从 gateway 到目标节点 未设置条件表达式的节点
|
||||
List<SequenceFlow> flows = sequenceFlows.stream().filter(flow -> StringUtils.equals(flowElement1.getId(), flow.getTargetRef()))
|
||||
.filter(flow -> StringUtils.equals(flow.getSourceRef(), exclusiveGatewayId))
|
||||
.collect(Collectors.toList());
|
||||
flows.stream().forEach(sequenceFlow -> {
|
||||
if (!conditions.isEmpty()) {
|
||||
com.alibaba.fastjson.JSONObject condition = conditions.get(0);
|
||||
String nodeName = condition.getString("nodeName");
|
||||
String expression = condition.getString("expression");
|
||||
|
||||
if (StringUtils.isBlank(sequenceFlow.getName()) && StringUtils.isNotBlank(nodeName)) {
|
||||
sequenceFlow.setName(nodeName);
|
||||
}
|
||||
// 设置条件表达式
|
||||
if (Objects.isNull(sequenceFlow.getConditionExpression()) && StringUtils.isNotBlank(expression)) {
|
||||
sequenceFlow.setConditionExpression(expression);
|
||||
}
|
||||
|
||||
conditions.remove(0);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// 1.1 边连接完成后,在进行 nextNode 创建
|
||||
if (Objects.nonNull(childNode)) {
|
||||
return create(endExId, childNode,model,process,sequenceFlows);
|
||||
} else {
|
||||
return endExId;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
// 所有 service task 连接 end exclusive gateway
|
||||
// 1.0 先进行边连接, 暂存 nextNode
|
||||
String endExId=id("exclusiveGateway")+"end";
|
||||
process.addFlowElement(DDBpmnModelUtils.createExclusiveGateWayEnd(endExId));
|
||||
String identifier =endExId;/*create(flowElement.getId(), childNode,model,process,sequenceFlows);*/
|
||||
for (int i = 0; i < incoming.size(); i++) {
|
||||
process.addFlowElement(connect(incoming.get(i), endExId,sequenceFlows));
|
||||
}
|
||||
|
||||
// 针对 gateway 空任务分支 添加条件表达式
|
||||
if (!conditions.isEmpty()) {
|
||||
FlowElement flowElement1 = model.getFlowElement(identifier);
|
||||
// 获取从 gateway 到目标节点 未设置条件表达式的节点
|
||||
List<SequenceFlow> flows = sequenceFlows.stream().filter(flow -> StringUtils.equals(flowElement1.getId(), flow.getTargetRef()))
|
||||
.filter(flow -> StringUtils.equals(flow.getSourceRef(), exclusiveGatewayId))
|
||||
.collect(Collectors.toList());
|
||||
flows.stream().forEach(sequenceFlow -> {
|
||||
if (!conditions.isEmpty()) {
|
||||
com.alibaba.fastjson.JSONObject condition = conditions.get(0);
|
||||
String nodeName = condition.getString("nodeName");
|
||||
String expression = condition.getString("expression");
|
||||
|
||||
if (StringUtils.isBlank(sequenceFlow.getName()) && StringUtils.isNotBlank(nodeName)) {
|
||||
sequenceFlow.setName(nodeName);
|
||||
}
|
||||
// 设置条件表达式
|
||||
if (Objects.isNull(sequenceFlow.getConditionExpression()) && StringUtils.isNotBlank(expression)) {
|
||||
sequenceFlow.setConditionExpression(expression);
|
||||
}
|
||||
|
||||
conditions.remove(0);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
return endExId;
|
||||
}
|
||||
// return exclusiveGatewayId;
|
||||
}
|
||||
|
||||
private static String createParallelGatewayBuilder(String formId, com.alibaba.fastjson.JSONObject flowNode, BpmnModel model, Process process, List<SequenceFlow> sequenceFlows) throws InvocationTargetException, IllegalAccessException {
|
||||
String name = flowNode.getString("nodeName");
|
||||
ParallelGateway parallelGateway = new ParallelGateway();
|
||||
String parallelGatewayId = id("parallelGateway");
|
||||
parallelGateway.setId(parallelGatewayId);
|
||||
parallelGateway.setName(name);
|
||||
process.addFlowElement(parallelGateway);
|
||||
process.addFlowElement(connect(formId, parallelGatewayId,sequenceFlows));
|
||||
|
||||
if (Objects.isNull(flowNode.getJSONArray("conditionNodes"))
|
||||
&& Objects.isNull(flowNode.getJSONObject("childNode"))) {
|
||||
return parallelGatewayId;
|
||||
}
|
||||
|
||||
List<com.alibaba.fastjson.JSONObject> flowNodes = Optional.ofNullable(flowNode.getJSONArray("conditionNodes")).map(e -> e.toJavaList(com.alibaba.fastjson.JSONObject.class)).orElse(Collections.emptyList());
|
||||
List<String> incoming = Lists.newArrayListWithCapacity(flowNodes.size());
|
||||
for (com.alibaba.fastjson.JSONObject element : flowNodes) {
|
||||
com.alibaba.fastjson.JSONObject childNode = element.getJSONObject("childNode");
|
||||
if (Objects.isNull(childNode)) {
|
||||
incoming.add(parallelGatewayId);
|
||||
continue;
|
||||
}
|
||||
String identifier = create(parallelGatewayId, childNode,model,process,sequenceFlows);
|
||||
if (Objects.nonNull(identifier)) {
|
||||
incoming.add(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
com.alibaba.fastjson.JSONObject childNode = flowNode.getJSONObject("childNode");
|
||||
if (Objects.nonNull(childNode)) {
|
||||
// 普通结束网关
|
||||
if (CollectionUtils.isEmpty(incoming)) {
|
||||
return create(parallelGatewayId, childNode,model,process,sequenceFlows);
|
||||
} else {
|
||||
// 所有 service task 连接 end parallel gateway
|
||||
childNode.put("incoming", incoming);
|
||||
FlowElement flowElement = model.getFlowElement(incoming.get(0));
|
||||
// 1.0 先进行边连接, 暂存 nextNode
|
||||
com.alibaba.fastjson.JSONObject nextNode = childNode.getJSONObject("childNode");
|
||||
childNode.put("childNode", null);
|
||||
String identifier = create(incoming.get(0), childNode,model,process,sequenceFlows);
|
||||
for (int i = 1; i < incoming.size(); i++) {
|
||||
FlowElement flowElement1 = model.getFlowElement(incoming.get(i));
|
||||
process.addFlowElement(connect(flowElement1.getId(), identifier,sequenceFlows));
|
||||
}
|
||||
// 1.1 边连接完成后,在进行 nextNode 创建
|
||||
if (Objects.nonNull(nextNode)) {
|
||||
return create(identifier, nextNode,model,process,sequenceFlows);
|
||||
} else {
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parallelGatewayId;
|
||||
}
|
||||
|
||||
private static String createServiceTask(com.alibaba.fastjson.JSONObject flowNode, Process process, List<SequenceFlow> sequenceFlows) {
|
||||
List<String> incoming = flowNode.getJSONArray("incoming").toJavaList(String.class);
|
||||
// 自动生成id
|
||||
String id = id("serviceTask");
|
||||
if (incoming != null && !incoming.isEmpty()) {
|
||||
ServiceTask serviceTask = new ServiceTask();
|
||||
serviceTask.setName(flowNode.getString("nodeName"));
|
||||
serviceTask.setId(id);
|
||||
|
||||
// todo lvshaohua
|
||||
serviceTask.setImplementationType("class");
|
||||
serviceTask.setImplementation("com.dingding.mid.listener.Vue3Listener");
|
||||
|
||||
process.addFlowElement(serviceTask);
|
||||
process.addFlowElement(connect(incoming.get(0), id,sequenceFlows));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
private static String createTask(com.alibaba.fastjson.JSONObject flowNode, Process process, List<SequenceFlow> sequenceFlows) {
|
||||
List<String> incoming = flowNode.getJSONArray("incoming").toJavaList(String.class);
|
||||
|
||||
@ -144,4 +453,16 @@ public class BpmTransformUtil {
|
||||
sequenceFlows.add(flow);
|
||||
return flow;
|
||||
}
|
||||
|
||||
protected static StartEvent createStartEvent() {
|
||||
StartEvent startEvent = new StartEvent();
|
||||
startEvent.setId(id("start"));
|
||||
return startEvent;
|
||||
}
|
||||
|
||||
protected static EndEvent createEndEvent() {
|
||||
EndEvent endEvent = new EndEvent();
|
||||
endEvent.setId(id("end"));
|
||||
return endEvent;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user