Merge branch 'feature/REQ-1309' into dev
This commit is contained in:
commit
6e5ff939b4
@ -17,6 +17,8 @@
|
|||||||
- ACT_GE_*:“GE“代表自动生成的数据,包括bpmn.xml、flowable自带流程图等文件,用于各种用例。
|
- ACT_GE_*:“GE“代表自动生成的数据,包括bpmn.xml、flowable自带流程图等文件,用于各种用例。
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[库表定义](https://blog.csdn.net/qq_31237581/article/details/130132221)
|
||||||
|
|
||||||
**Flowable 的扩展:**
|
**Flowable 的扩展:**
|
||||||
```text
|
```text
|
||||||
- flw_*:Flowable 新版本扩展功能相关的表,流程迁移的表。
|
- flw_*:Flowable 新版本扩展功能相关的表,流程迁移的表。
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package cn.axzo.workflow.common.model.request.bpmn;
|
package cn.axzo.workflow.common.model.request.bpmn;
|
||||||
|
|
||||||
|
import cn.axzo.workflow.common.enums.BpmFlowNodeType;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -25,7 +26,7 @@ public class BpmnJsonNode {
|
|||||||
@ApiModelProperty(value = "父节点ID")
|
@ApiModelProperty(value = "父节点ID")
|
||||||
private String parentId;
|
private String parentId;
|
||||||
@ApiModelProperty(value = "节点类型 NODE_STARTER/NODE_TASK/NODE_ROUTER/NODE_CONDITION")
|
@ApiModelProperty(value = "节点类型 NODE_STARTER/NODE_TASK/NODE_ROUTER/NODE_CONDITION")
|
||||||
private String type;
|
private BpmFlowNodeType type;
|
||||||
@ApiModelProperty(value = "节点名称")
|
@ApiModelProperty(value = "节点名称")
|
||||||
private String name;
|
private String name;
|
||||||
@ApiModelProperty(value = "子节点信息")
|
@ApiModelProperty(value = "子节点信息")
|
||||||
@ -54,11 +55,11 @@ public class BpmnJsonNode {
|
|||||||
this.parentId = parentId;
|
this.parentId = parentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getType() {
|
public BpmFlowNodeType getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(String type) {
|
public void setType(BpmFlowNodeType type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@ public enum BpmErrorCode implements IProjectRespCode {
|
|||||||
// ========== convertor 02-001 ==========
|
// ========== convertor 02-001 ==========
|
||||||
CONVERTOR_UNKNOW_NODE_TYPE("02001", "节点类型【{}】暂不支持"),
|
CONVERTOR_UNKNOW_NODE_TYPE("02001", "节点类型【{}】暂不支持"),
|
||||||
CONVERTOR_META_DATA_FORMAT_ERROR("02002", "JSON 数据格式有误"),
|
CONVERTOR_META_DATA_FORMAT_ERROR("02002", "JSON 数据格式有误"),
|
||||||
|
CONVERTOR_COMMON_ERROR("02003", "JSON 转 BPMN 失败, 原因:【{}】"),
|
||||||
|
|
||||||
|
|
||||||
// ========== bpmn model 03-001 ==========
|
// ========== bpmn model 03-001 ==========
|
||||||
|
|||||||
@ -60,7 +60,7 @@ public class BpmTransformUtil {
|
|||||||
process.setId(model.getKey());
|
process.setId(model.getKey());
|
||||||
process.setName(model.getName());
|
process.setName(model.getName());
|
||||||
|
|
||||||
if (BpmFlowNodeType.NODE_STARTER.getType().equals(bpmnJson.getType())) {
|
if (BpmFlowNodeType.NODE_STARTER.equals(bpmnJson.getType())) {
|
||||||
process.addFlowElement(createStartEvent(bpmnJson.getId(), Objects.nonNull(bpmnJson.getProperty()) ?
|
process.addFlowElement(createStartEvent(bpmnJson.getId(), Objects.nonNull(bpmnJson.getProperty()) ?
|
||||||
bpmnJson.getProperty().getFormKey() : ""));
|
bpmnJson.getProperty().getFormKey() : ""));
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ public class BpmTransformUtil {
|
|||||||
if (StringUtils.isNotBlank(parentId)) {
|
if (StringUtils.isNotBlank(parentId)) {
|
||||||
BpmnJsonNode parentNode = childNodeMap.get(parentId);
|
BpmnJsonNode parentNode = childNodeMap.get(parentId);
|
||||||
if (parentNode != null) {
|
if (parentNode != null) {
|
||||||
if (BpmFlowNodeType.NODE_CONDITION.getType().equals(parentNode.getType())) {
|
if (BpmFlowNodeType.NODE_CONDITION.equals(parentNode.getType())) {
|
||||||
sequenceFlowId = parentNode.getId();
|
sequenceFlowId = parentNode.getId();
|
||||||
flow.setName(parentNode.getName());
|
flow.setName(parentNode.getName());
|
||||||
if (!ObjectUtils.isEmpty(parentNode.getProperty()) && !Boolean.TRUE.equals(parentNode.getProperty().getDefaultCondition())) {
|
if (!ObjectUtils.isEmpty(parentNode.getProperty()) && !Boolean.TRUE.equals(parentNode.getProperty().getDefaultCondition())) {
|
||||||
@ -157,7 +157,7 @@ public class BpmTransformUtil {
|
|||||||
|
|
||||||
public static String create(String fromId, BpmnJsonNode flowNode, Process process, BpmnModel bpmnModel,
|
public static String create(String fromId, BpmnJsonNode flowNode, Process process, BpmnModel bpmnModel,
|
||||||
List<SequenceFlow> sequenceFlows, Map<String, BpmnJsonNode> childNodeMap) throws InvocationTargetException, IllegalAccessException {
|
List<SequenceFlow> sequenceFlows, Map<String, BpmnJsonNode> childNodeMap) throws InvocationTargetException, IllegalAccessException {
|
||||||
String nodeType = flowNode.getType();
|
String nodeType = flowNode.getType().getType();
|
||||||
if (BpmFlowNodeType.NODE_ROUTER.isEqual(nodeType)) {
|
if (BpmFlowNodeType.NODE_ROUTER.isEqual(nodeType)) {
|
||||||
return createExclusiveGatewayBuilder(fromId, flowNode, process, bpmnModel, sequenceFlows, childNodeMap);
|
return createExclusiveGatewayBuilder(fromId, flowNode, process, bpmnModel, sequenceFlows, childNodeMap);
|
||||||
} else if (BpmFlowNodeType.NODE_TASK.isEqual(nodeType)) {
|
} else if (BpmFlowNodeType.NODE_TASK.isEqual(nodeType)) {
|
||||||
@ -273,7 +273,7 @@ public class BpmTransformUtil {
|
|||||||
if (Objects.nonNull(childNode) && StringUtils.isNotBlank(childNode.getId())) {
|
if (Objects.nonNull(childNode) && StringUtils.isNotBlank(childNode.getId())) {
|
||||||
String parentId = childNode.getParentId();
|
String parentId = childNode.getParentId();
|
||||||
BpmnJsonNode parentChildNode = childNodeMap.get(parentId);
|
BpmnJsonNode parentChildNode = childNodeMap.get(parentId);
|
||||||
if (BpmFlowNodeType.NODE_ROUTER.getType().equals(parentChildNode.getType())) {
|
if (BpmFlowNodeType.NODE_ROUTER.equals(parentChildNode.getType())) {
|
||||||
String endExId = parentChildNode.getId() + "end";
|
String endExId = parentChildNode.getId() + "end";
|
||||||
process.addFlowElement(createExclusiveGateWayEnd(endExId));
|
process.addFlowElement(createExclusiveGateWayEnd(endExId));
|
||||||
if (incoming == null || incoming.isEmpty()) {
|
if (incoming == null || incoming.isEmpty()) {
|
||||||
|
|||||||
@ -0,0 +1,93 @@
|
|||||||
|
package cn.axzo.workflow.core.common.utils;
|
||||||
|
|
||||||
|
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
|
||||||
|
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.CONVERTOR_COMMON_ERROR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPMN json 格式转换工具
|
||||||
|
*
|
||||||
|
* @author wangli
|
||||||
|
* @since 2023/10/12 11:43
|
||||||
|
*/
|
||||||
|
public class BpmnJsonConverterUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 BpmnModel 转成 JSON 格式对应对象
|
||||||
|
*
|
||||||
|
* @param bpmnModel Flowable 标准模型
|
||||||
|
* @return {@link BpmnJsonNode} json 格式对象,可以直接解析
|
||||||
|
*/
|
||||||
|
public static BpmnJsonNode convertToJson(BpmnModel bpmnModel) {
|
||||||
|
return new BpmnJsonNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 json 格式数据转的 BpmnJsonNode 对象,转换成 Flowable 标准的模型 {@link BpmnModel}
|
||||||
|
*
|
||||||
|
* @param bpmnJsonNode json 格式对象,可以直接解析
|
||||||
|
* @return {@link BpmnModel}
|
||||||
|
*/
|
||||||
|
public static BpmnModel convertToBpmn(BpmnJsonNode bpmnJsonNode) {
|
||||||
|
if (Objects.isNull(bpmnJsonNode)) {
|
||||||
|
throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "JSON 数据为空");
|
||||||
|
}
|
||||||
|
switch (bpmnJsonNode.getType()) {
|
||||||
|
case NODE_STARTER:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return new BpmnModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String jsonStr = "{\n" +
|
||||||
|
" \"id\": \"NODE_STARTER\",\n" +
|
||||||
|
" \"type\": \"NODE_STARTER\",\n" +
|
||||||
|
" \"name\": \"发起\",\n" +
|
||||||
|
" \"children\": {\n" +
|
||||||
|
" \"id\": \"NODE_CONFIG\",\n" +
|
||||||
|
" \"parentId\": \"NODE_STARTER\",\n" +
|
||||||
|
" \"type\": \"NODE_TASK\",\n" +
|
||||||
|
" \"name\": \"权限配置\",\n" +
|
||||||
|
" \"children\": {\n" +
|
||||||
|
" \"id\": \"NODE_RELEASE_DEV\",\n" +
|
||||||
|
" \"parentId\": \"NODE_CONFIG\",\n" +
|
||||||
|
" \"type\": \"NODE_TASK\",\n" +
|
||||||
|
" \"name\": \"发布 DEV\",\n" +
|
||||||
|
" \"children\": {\n" +
|
||||||
|
" \"id\": \"NODE_RELEASE_TEST\",\n" +
|
||||||
|
" \"parentId\": \"NODE_RELEASE_DEV\",\n" +
|
||||||
|
" \"type\": \"NODE_TASK\",\n" +
|
||||||
|
" \"name\": \"发布 TEST\",\n" +
|
||||||
|
" \"children\": {\n" +
|
||||||
|
" \"id\": \"NODE_RELEASE_PRE\",\n" +
|
||||||
|
" \"parentId\": \"NODE_RELEASE_TEST\",\n" +
|
||||||
|
" \"type\": \"NODE_TASK\",\n" +
|
||||||
|
" \"name\": \"发布 PRE\",\n" +
|
||||||
|
" \"children\": {\n" +
|
||||||
|
" \"id\": \"NODE_RELEASE_PROD\",\n" +
|
||||||
|
" \"parentId\": \"NODE_RELEASE_PRE\",\n" +
|
||||||
|
" \"type\": \"NODE_TASK\",\n" +
|
||||||
|
" \"name\": \"发布生产\",\n" +
|
||||||
|
" \"children\": {\n" +
|
||||||
|
" \"id\": \"NODE_ACCEPTANCE\",\n" +
|
||||||
|
" \"parentId\": \"NODE_RELEASE_PROD\",\n" +
|
||||||
|
" \"type\": \"NODE_TASK\",\n" +
|
||||||
|
" \"name\": \"产品验收\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }";
|
||||||
|
BpmnJsonNode bpmnJsonNode = JSON.parseObject(jsonStr, BpmnJsonNode.class);
|
||||||
|
BpmnModel bpmnModel = convertToBpmn(bpmnJsonNode);
|
||||||
|
System.out.println("bpmnModel = " + bpmnModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,7 +10,7 @@ import org.springframework.beans.factory.ObjectProvider;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import static org.flowable.common.engine.impl.AbstractEngineConfiguration.DB_SCHEMA_UPDATE_FALSE;
|
import static org.flowable.common.engine.impl.AbstractEngineConfiguration.DB_SCHEMA_UPDATE_TRUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flowable 引擎相关全局配置
|
* Flowable 引擎相关全局配置
|
||||||
@ -28,7 +28,7 @@ public class FlowableConfiguration {
|
|||||||
return configuration -> {
|
return configuration -> {
|
||||||
configuration.setEventListeners(Lists.newArrayList(listeners));
|
configuration.setEventListeners(Lists.newArrayList(listeners));
|
||||||
configuration.setActivityBehaviorFactory(customActivityBehaviorFactory);
|
configuration.setActivityBehaviorFactory(customActivityBehaviorFactory);
|
||||||
configuration.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_FALSE);
|
configuration.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_TRUE);
|
||||||
configuration.setEnableSafeBpmnXml(false);
|
configuration.setEnableSafeBpmnXml(false);
|
||||||
// configuration.setCreateDiagramOnDeploy(false);
|
// configuration.setCreateDiagramOnDeploy(false);
|
||||||
};
|
};
|
||||||
@ -36,7 +36,7 @@ public class FlowableConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public EngineConfigurationConfigurer<SpringFormEngineConfiguration> formEngineConfigurer() {
|
public EngineConfigurationConfigurer<SpringFormEngineConfiguration> formEngineConfigurer() {
|
||||||
return configuration -> configuration.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_FALSE);
|
return configuration -> configuration.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
package cn.axzo.workflow.core.converter.json;
|
||||||
|
|
||||||
|
import org.flowable.bpmn.model.BaseElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* @author wangli
|
||||||
|
* @since 2023/10/12 11:06
|
||||||
|
*/
|
||||||
|
public abstract class AbstractBpmnJsonConverter {
|
||||||
|
|
||||||
|
|
||||||
|
protected abstract void convertElementToJson();
|
||||||
|
|
||||||
|
protected abstract BaseElement convertJsonToElement();
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package cn.axzo.workflow.core.converter.json;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* @author wangli
|
||||||
|
* @since 2023/10/12 11:04
|
||||||
|
*/
|
||||||
|
public class StartEventJsonConverter {
|
||||||
|
|
||||||
|
}
|
||||||
@ -4,11 +4,11 @@ import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
|
|||||||
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
|
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
|
||||||
import cn.axzo.workflow.core.service.support.FlowNodeForecastService;
|
import cn.axzo.workflow.core.service.support.FlowNodeForecastService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.bpmn.model.BpmnModel;
|
|
||||||
import org.flowable.bpmn.model.FlowElement;
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
|
import org.flowable.common.engine.impl.util.IoUtil;
|
||||||
import org.flowable.engine.RepositoryService;
|
import org.flowable.engine.RepositoryService;
|
||||||
import org.flowable.engine.RuntimeService;
|
import org.flowable.engine.RuntimeService;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.repository.Deployment;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,6 +39,7 @@ public class TestController {
|
|||||||
private RuntimeService runtimeService;
|
private RuntimeService runtimeService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private RepositoryService repositoryService;
|
private RepositoryService repositoryService;
|
||||||
|
|
||||||
@GetMapping("/test")
|
@GetMapping("/test")
|
||||||
public void test(@RequestParam String processInstanceId) {
|
public void test(@RequestParam String processInstanceId) {
|
||||||
List<FlowElement> flowElements = forecastService.performProcessForecasting(processInstanceId, null);
|
List<FlowElement> flowElements = forecastService.performProcessForecasting(processInstanceId, null);
|
||||||
@ -50,13 +52,18 @@ public class TestController {
|
|||||||
System.out.println("detailVOS = " + detailVOS);
|
System.out.println("detailVOS = " + detailVOS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作 act_ge_bytearray
|
||||||
|
*
|
||||||
|
* @param processInstanceId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@GetMapping("/test3")
|
@GetMapping("/test3")
|
||||||
public String test3(@RequestParam String processInstanceId) {
|
public String test3(@RequestParam String processInstanceId) {
|
||||||
ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
|
Deployment deploy =
|
||||||
.includeProcessVariables().singleResult();
|
repositoryService.createDeployment().addBytes("自定义资源", processInstanceId.getBytes()).deploy();
|
||||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(instance.getProcessDefinitionId());
|
InputStream is = repositoryService.getResourceAsStream(deploy.getId(), "自定义资源");
|
||||||
// ObjectNode jsonNodes = new BpmnJsonConverter().convertToJson(bpmnModel);
|
byte[] bytes = IoUtil.readInputStream(is, "自定义资源");
|
||||||
// return JSON.toJSONString(jsonNodes);
|
return new String(bytes);
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user