update - 完善 BPMN 协议 JSON 转换功能
This commit is contained in:
parent
e29b94cd0c
commit
26894bb889
@ -0,0 +1,47 @@
|
||||
package cn.axzo.workflow.common.model.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 组织架构人员选择器
|
||||
* 协同组织列表的限制条件
|
||||
*
|
||||
* @author tanjie@axzo.cn
|
||||
* @date 2023/11/14 11:29
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CooperationOrgDTO {
|
||||
|
||||
/**
|
||||
* 企业组织架构
|
||||
*/
|
||||
private List<OrgScope> entOrg;
|
||||
/**
|
||||
* 项目部工作台
|
||||
*/
|
||||
private Long projWorkspaceId;
|
||||
|
||||
/**
|
||||
* 参与项目部工作台的指定单位
|
||||
*/
|
||||
private List<Long> projOuId;
|
||||
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class OrgScope {
|
||||
private Long workspaceId;
|
||||
|
||||
private Long ouId;
|
||||
}
|
||||
}
|
||||
@ -51,40 +51,3 @@ public class BpmnFieldConf {
|
||||
private List<BpmnFieldOptionConf> options;
|
||||
|
||||
}
|
||||
/**
|
||||
* 单选/多选的选项配置
|
||||
*/
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
class BpmnFieldOptionConf {
|
||||
/**
|
||||
* 选项的名称
|
||||
*/
|
||||
@ApiModelProperty(value = "选项的名称", example = "选项1")
|
||||
@NotBlank(message = "选项的名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 选项的值
|
||||
*/
|
||||
@ApiModelProperty(value = "选项的值", example = "1")
|
||||
@NotBlank(message = "选项的值不能为空")
|
||||
private String value;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 单选/多选的选项配置
|
||||
*/
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class BpmnFieldOptionConf {
|
||||
|
||||
/**
|
||||
* 选项的名称
|
||||
*/
|
||||
@ApiModelProperty(value = "选项的名称", example = "选项1")
|
||||
@NotBlank(message = "选项的名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 选项的值
|
||||
*/
|
||||
@ApiModelProperty(value = "选项的值", example = "1")
|
||||
@NotBlank(message = "选项的值不能为空")
|
||||
private String value;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@ -90,7 +90,7 @@ public class BpmnJsonNodeProperty {
|
||||
* 按钮权限
|
||||
*/
|
||||
@ApiModelProperty(value = "发起人节点/任务节点: 按钮权限集合")
|
||||
private List<BpmnButtonConf> buttonPermission;
|
||||
private BpmnButtonConf buttonPermission;
|
||||
|
||||
|
||||
//************* 条件节点Start **************//
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn.process;
|
||||
|
||||
import cn.axzo.workflow.common.model.dto.CooperationOrgDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -31,6 +33,13 @@ public class BpmnProcessInstanceCreateDTO {
|
||||
*/
|
||||
private Map<String, Object> variables = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 组织关系
|
||||
*/
|
||||
@ApiModelProperty(value = "组织关系")
|
||||
@NotNull(message = "组织关系不能为空")
|
||||
private CooperationOrgDTO cooperationOrg;
|
||||
|
||||
/**
|
||||
* 业务的唯一标识
|
||||
* <p>
|
||||
|
||||
@ -1,27 +1,66 @@
|
||||
package cn.axzo.workflow.core.common.utils;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.*;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonMetaInfo;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnFieldConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelCreateDTO;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.converter.json.*;
|
||||
import cn.axzo.workflow.core.converter.json.AbstractBpmnJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.EndEventJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.ExclusiveGatewayJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.NotSupportConverter;
|
||||
import cn.axzo.workflow.core.converter.json.ParallelGatewayJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.ReceiveTaskJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.SequenceFlowJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.ServiceTaskJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.StartEventJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.UserTaskJsonConverter;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.flowable.bpmn.BpmnAutoLayout;
|
||||
import org.flowable.bpmn.converter.BpmnXMLConverter;
|
||||
import org.flowable.bpmn.model.BaseElement;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.EndEvent;
|
||||
import org.flowable.bpmn.model.ExclusiveGateway;
|
||||
import org.flowable.bpmn.model.ExtensionAttribute;
|
||||
import org.flowable.bpmn.model.ExtensionElement;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.bpmn.model.Gateway;
|
||||
import org.flowable.bpmn.model.ParallelGateway;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.*;
|
||||
import org.flowable.bpmn.model.ReceiveTask;
|
||||
import org.flowable.bpmn.model.SequenceFlow;
|
||||
import org.flowable.bpmn.model.ServiceTask;
|
||||
import org.flowable.bpmn.model.StartEvent;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.image.ProcessDiagramGenerator;
|
||||
import org.flowable.image.impl.DefaultProcessDiagramGenerator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.*;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.END_EVENT_ID;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_NODE_JSON;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.SEQUENCE_FLOW_ID;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.START_EVENT_ID;
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY;
|
||||
import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.CONVERTOR_COMMON_ERROR;
|
||||
|
||||
@ -45,6 +84,7 @@ public class BpmnJsonConverterUtil {
|
||||
converters.put(ParallelGateway.class, new ParallelGatewayJsonConverter());
|
||||
converters.put(UserTask.class, new UserTaskJsonConverter());
|
||||
converters.put(ServiceTask.class, new ServiceTaskJsonConverter());
|
||||
converters.put(ReceiveTask.class, new ReceiveTaskJsonConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,9 +126,11 @@ public class BpmnJsonConverterUtil {
|
||||
mainProcess.setDocumentation(documentation);
|
||||
mainProcess.addAttribute(extensionAttribute);
|
||||
|
||||
|
||||
// 设置流程的通知管理配置
|
||||
setProcessNoticeConfig(noticeConf, mainProcess);
|
||||
// 设置流程的默认的按钮配置
|
||||
setProcessButtonConfig(buttonConf, mainProcess);
|
||||
// 设置流程的字段元数据配置
|
||||
setProcessFieldConfig(fieldConf, mainProcess);
|
||||
|
||||
bpmnModel.addProcess(mainProcess);
|
||||
@ -112,12 +154,56 @@ public class BpmnJsonConverterUtil {
|
||||
}
|
||||
|
||||
private static void setProcessFieldConfig(List<BpmnFieldConf> fieldConf, Process mainProcess) {
|
||||
// TODO
|
||||
ExtensionElement fieldConfigElement = new ExtensionElement();
|
||||
fieldConfigElement.setName("fieldConfig");
|
||||
|
||||
if (!CollectionUtils.isEmpty(fieldConf)) {
|
||||
fieldConf.forEach(i -> {
|
||||
ExtensionElement field = new ExtensionElement();
|
||||
field.setName("filed");
|
||||
|
||||
ExtensionAttribute fieldDataType = new ExtensionAttribute();
|
||||
fieldDataType.setName("type");
|
||||
fieldDataType.setValue(i.getType());
|
||||
field.addAttribute(fieldDataType);
|
||||
|
||||
ExtensionAttribute fieldName = new ExtensionAttribute();
|
||||
fieldName.setName("name");
|
||||
fieldName.setValue(i.getName());
|
||||
field.addAttribute(fieldName);
|
||||
|
||||
ExtensionAttribute fieldCode = new ExtensionAttribute();
|
||||
fieldCode.setName("code");
|
||||
fieldCode.setValue(i.getCode());
|
||||
field.addAttribute(fieldCode);
|
||||
|
||||
if (!CollectionUtils.isEmpty(i.getOptions())) {
|
||||
i.getOptions().forEach(j -> {
|
||||
ExtensionElement option = new ExtensionElement();
|
||||
option.setName("option");
|
||||
|
||||
ExtensionAttribute optionName = new ExtensionAttribute();
|
||||
optionName.setName("name");
|
||||
optionName.setValue(j.getName());
|
||||
option.addAttribute(optionName);
|
||||
|
||||
ExtensionAttribute optionValue = new ExtensionAttribute();
|
||||
optionValue.setName("value");
|
||||
optionValue.setValue(j.getValue());
|
||||
option.addAttribute(optionValue);
|
||||
|
||||
field.addChildElement(option);
|
||||
});
|
||||
}
|
||||
fieldConfigElement.addChildElement(field);
|
||||
});
|
||||
}
|
||||
mainProcess.addExtensionElement(fieldConfigElement);
|
||||
}
|
||||
|
||||
private static void setProcessButtonConfig(BpmnButtonConf buttonConf, Process mainProcess) {
|
||||
ExtensionElement buttonConfigElement = new ExtensionElement();
|
||||
buttonConfigElement.setName("buttonConfigElement");
|
||||
buttonConfigElement.setName("buttonConfig");
|
||||
|
||||
buildMetaButton(buttonConf.getInitiator(), "initiator", buttonConfigElement);
|
||||
buildMetaButton(buttonConf.getCurrent(), "current", buttonConfigElement);
|
||||
@ -127,7 +213,7 @@ public class BpmnJsonConverterUtil {
|
||||
mainProcess.addExtensionElement(buttonConfigElement);
|
||||
}
|
||||
|
||||
private static void buildMetaButton(List<BpmnButtonMetaInfo> buttonMetaInfos, String buttonType,
|
||||
public static void buildMetaButton(List<BpmnButtonMetaInfo> buttonMetaInfos, String buttonType,
|
||||
ExtensionElement buttonConfigElement) {
|
||||
if (!CollectionUtils.isEmpty(buttonMetaInfos)) {
|
||||
ExtensionElement initiator = new ExtensionElement();
|
||||
@ -135,11 +221,15 @@ public class BpmnJsonConverterUtil {
|
||||
buttonMetaInfos.forEach(i -> {
|
||||
ExtensionElement button = new ExtensionElement();
|
||||
button.setName(i.getBtnKey());
|
||||
ExtensionAttribute attribute = new ExtensionAttribute();
|
||||
attribute.setName("name");
|
||||
attribute.setValue(i.getBtnName());
|
||||
button.addAttribute(attribute);
|
||||
button.setElementText(String.valueOf(i.getEnabled()));
|
||||
ExtensionAttribute nameAttribute = new ExtensionAttribute();
|
||||
nameAttribute.setName("name");
|
||||
nameAttribute.setValue(i.getBtnName());
|
||||
button.addAttribute(nameAttribute);
|
||||
|
||||
ExtensionAttribute valueAttribute = new ExtensionAttribute();
|
||||
valueAttribute.setName("value");
|
||||
valueAttribute.setValue(String.valueOf(i.getEnabled()));
|
||||
button.addAttribute(valueAttribute);
|
||||
initiator.addChildElement(button);
|
||||
});
|
||||
buttonConfigElement.addChildElement(initiator);
|
||||
@ -148,7 +238,7 @@ public class BpmnJsonConverterUtil {
|
||||
|
||||
private static void setProcessNoticeConfig(BpmnNoticeConf noticeConf, Process mainProcess) {
|
||||
ExtensionElement noticeConfigElement = new ExtensionElement();
|
||||
noticeConfigElement.setName("noticeConfigElement");
|
||||
noticeConfigElement.setName("noticeConfig");
|
||||
|
||||
// 通知消息模板配置
|
||||
ExtensionElement noticeMessage = new ExtensionElement();
|
||||
@ -223,7 +313,17 @@ public class BpmnJsonConverterUtil {
|
||||
case NODE_CONDITION:
|
||||
clz = SequenceFlow.class;
|
||||
break;
|
||||
case NODE_BUSINESS:
|
||||
// "业务节点"是很特殊包装节点,因为它在前端有两种配法:
|
||||
// 一种是: 可以不配置人, 当运行到该节点时, 需要由外部发送信号来触发(这个信号的发送方通常是程序应用), 流程继续运行.
|
||||
// 另外一种是: 可以配置人, 当运行到该节点时, 有需要人为来处理. 这种情况下, 该节点就是一个普通的任务节点.
|
||||
clz = ReceiveTask.class;
|
||||
if (!Objects.equals("nobody", bpmnJsonNode.getProperty().getApprovalMethod())) {
|
||||
clz = UserTask.class;
|
||||
}
|
||||
break;
|
||||
case NODE_TRIGGER:
|
||||
// 这个类型目前暂不支持
|
||||
case NODE_CARBON_COPY:
|
||||
// 这里可以细化, 带后续有实际场景了,再处理, 现目前只有 "抄送" 功能可能会用到
|
||||
clz = ServiceTask.class;
|
||||
@ -238,12 +338,15 @@ public class BpmnJsonConverterUtil {
|
||||
// 通用链接当前节点和前一个节点的 SequenceFlow
|
||||
if (preNodeIdList.size() > 1) {
|
||||
// 如果涉及到网关,那么 incoming 就是大于 1
|
||||
preNodeIdList.forEach(income -> {
|
||||
Map<String, List<String>> tmpIncomeMap = new HashMap<>();
|
||||
tmpIncomeMap.put("incoming", Lists.newArrayList(income));
|
||||
bpmnJsonNode.setIncoming(tmpIncomeMap);
|
||||
mainProcess.addFlowElement(convertJsonToElement(SequenceFlow.class, bpmnJsonNode, mainProcess));
|
||||
});
|
||||
preNodeIdList.stream()
|
||||
// 过滤掉自己
|
||||
.filter(income -> !Objects.equals(bpmnJsonNode.getId(), income))
|
||||
.forEach(income -> {
|
||||
Map<String, List<String>> tmpIncomeMap = new HashMap<>();
|
||||
tmpIncomeMap.put("incoming", Lists.newArrayList(income));
|
||||
bpmnJsonNode.setIncoming(tmpIncomeMap);
|
||||
mainProcess.addFlowElement(convertJsonToElement(SequenceFlow.class, bpmnJsonNode, mainProcess));
|
||||
});
|
||||
} else {
|
||||
FlowElement sequenceFlow = convertJsonToElement(SequenceFlow.class, bpmnJsonNode, mainProcess);
|
||||
mainProcess.addFlowElement(sequenceFlow);
|
||||
@ -264,9 +367,12 @@ public class BpmnJsonConverterUtil {
|
||||
List<String> gatewayPreIds = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(bpmnJsonNode.getBranches())) {
|
||||
for (BpmnJsonNode branch : bpmnJsonNode.getBranches()) {
|
||||
BpmnJsonNode children = branch.getChildren();
|
||||
children.setPreJsonNode(branch);
|
||||
gatewayPreIds.add(create(children, mainProcess, bpmnModel, flowElement.getId()));
|
||||
BpmnJsonNode children = Objects.isNull(branch.getChildren()) ? bpmnJsonNode.getChildren() :
|
||||
branch.getChildren();
|
||||
if (Objects.nonNull(children)) {
|
||||
children.setPreJsonNode(branch);
|
||||
gatewayPreIds.add(create(children, mainProcess, bpmnModel, flowElement.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,6 +435,48 @@ public class BpmnJsonConverterUtil {
|
||||
model.getButtonConf(), model.getFieldConf());
|
||||
System.out.println("bpmnModel = " + bpmnModel);
|
||||
transformBytes(bpmnModel);
|
||||
|
||||
generateImage(bpmnModel);
|
||||
}
|
||||
|
||||
public static void generateImage(BpmnModel bpmnModel) {
|
||||
String pngName = "/Users/wangli/work/company/yizhi/workflow-engine/workflow-engine-server/src/main" +
|
||||
"/resources/test.png";
|
||||
ProcessDiagramGenerator diagramGenerator = new DefaultProcessDiagramGenerator();
|
||||
|
||||
// 设置字体渲染选项
|
||||
System.setProperty("java.awt.headless", "false");
|
||||
System.setProperty("awt.useSystemAAFontSettings", "on");
|
||||
System.setProperty("swing.aatext", "true");
|
||||
System.setProperty("sun.java2d.xrender", "true");
|
||||
|
||||
try {
|
||||
// 创建输出流
|
||||
OutputStream outputStream = Files.newOutputStream(new File(pngName).toPath());
|
||||
// 生成图像并写入输出流
|
||||
InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", new ArrayList<>(), 1.0d, true);
|
||||
|
||||
// 将图像流写入输出流
|
||||
try {
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = imageStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 处理异常
|
||||
} finally {
|
||||
try {
|
||||
imageStream.close();
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
// 处理异常
|
||||
}
|
||||
}
|
||||
// 关闭输出流
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
// 处理异常
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
package cn.axzo.workflow.core.converter.json;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.ReceiveTask;
|
||||
|
||||
/**
|
||||
* 接收任务节点
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2023/10/13 17:01
|
||||
*/
|
||||
public class ReceiveTaskJsonConverter extends AbstractBpmnJsonConverter<ReceiveTask> {
|
||||
|
||||
@Override
|
||||
public ReceiveTask convertJsonToElement(BpmnJsonNode node, Process process) {
|
||||
ReceiveTask receiveTask = new ReceiveTask();
|
||||
|
||||
receiveTask.setId(node.getId());
|
||||
receiveTask.setName(node.getName());
|
||||
|
||||
return receiveTask;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,17 +1,23 @@
|
||||
package cn.axzo.workflow.core.converter.json;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNodeProperty;
|
||||
import org.flowable.bpmn.model.ExtensionAttribute;
|
||||
import org.flowable.bpmn.model.ExtensionElement;
|
||||
import org.flowable.bpmn.model.FlowableListener;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.BaseExecutionListener;
|
||||
import org.flowable.engine.delegate.TaskListener;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnJsonConverterUtil.buildMetaButton;
|
||||
import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION;
|
||||
|
||||
/**
|
||||
@ -28,6 +34,14 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
|
||||
|
||||
userTask.setId(node.getId());
|
||||
userTask.setName(node.getName());
|
||||
|
||||
// "设置审批人"
|
||||
setApprovalExtensionElement(node, userTask);
|
||||
// "权限设置"
|
||||
setFieldExtensionElement(node, userTask);
|
||||
// "高级设置"
|
||||
setButtonExtensionElement(node, userTask);
|
||||
|
||||
setTaskListeners(userTask);
|
||||
|
||||
if (!Objects.equals(NODE_STARTER, node.getType())) {
|
||||
@ -37,6 +51,118 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
|
||||
return userTask;
|
||||
}
|
||||
|
||||
private static void setButtonExtensionElement(BpmnJsonNode node, UserTask userTask) {
|
||||
if (Objects.isNull(node.getProperty())) {
|
||||
return;
|
||||
}
|
||||
BpmnButtonConf buttonConf = node.getProperty().getButtonPermission();
|
||||
ExtensionElement buttonConfigElement = new ExtensionElement();
|
||||
buttonConfigElement.setName("buttonConfig");
|
||||
|
||||
if (Objects.nonNull(buttonConf)) {
|
||||
buildMetaButton(buttonConf.getInitiator(), "initiator", buttonConfigElement);
|
||||
buildMetaButton(buttonConf.getCurrent(), "current", buttonConfigElement);
|
||||
buildMetaButton(buttonConf.getHistory(), "history", buttonConfigElement);
|
||||
buildMetaButton(buttonConf.getCarbonCopy(), "carbonCopy", buttonConfigElement);
|
||||
}
|
||||
|
||||
userTask.addExtensionElement(buttonConfigElement);
|
||||
}
|
||||
|
||||
private static void setFieldExtensionElement(BpmnJsonNode node, UserTask userTask) {
|
||||
if (Objects.isNull(node.getProperty())) {
|
||||
return;
|
||||
}
|
||||
ExtensionElement fieldElement = new ExtensionElement();
|
||||
fieldElement.setName("fieldPermission");
|
||||
fieldElement.setElementText(node.getProperty().getFieldPermission());
|
||||
userTask.addExtensionElement(fieldElement);
|
||||
}
|
||||
|
||||
private static void setApprovalExtensionElement(BpmnJsonNode node, UserTask userTask) {
|
||||
BpmnJsonNodeProperty property = node.getProperty();
|
||||
if (Objects.isNull(property)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 审批方式
|
||||
ExtensionElement approvalMethodElement = new ExtensionElement();
|
||||
approvalMethodElement.setName("approvalMethod");
|
||||
|
||||
ExtensionAttribute approvalMethodValueAttribute = new ExtensionAttribute();
|
||||
approvalMethodValueAttribute.setName("value");
|
||||
approvalMethodValueAttribute.setValue(property.getApprovalMethod());
|
||||
approvalMethodElement.addAttribute(approvalMethodValueAttribute);
|
||||
|
||||
ExtensionAttribute approvalMethodDescAttribute = new ExtensionAttribute();
|
||||
approvalMethodDescAttribute.setName("desc");
|
||||
approvalMethodDescAttribute.setValue("审批方式");
|
||||
approvalMethodElement.addAttribute(approvalMethodDescAttribute);
|
||||
|
||||
userTask.addExtensionElement(approvalMethodElement);
|
||||
|
||||
// 审批人所在范围
|
||||
ExtensionElement approverScopeElement = new ExtensionElement();
|
||||
approverScopeElement.setName("approverScope");
|
||||
|
||||
ExtensionAttribute approverScopeValueAttribute = new ExtensionAttribute();
|
||||
approverScopeValueAttribute.setName("value");
|
||||
approverScopeValueAttribute.setValue(property.getApproverScope());
|
||||
approverScopeElement.addAttribute(approverScopeValueAttribute);
|
||||
|
||||
ExtensionAttribute approverScopeDescAttribute = new ExtensionAttribute();
|
||||
approverScopeDescAttribute.setName("desc");
|
||||
approverScopeDescAttribute.setValue("审批人所在范围");
|
||||
approverScopeElement.addAttribute(approverScopeDescAttribute);
|
||||
userTask.addExtensionElement(approverScopeElement);
|
||||
|
||||
// 审批人指定
|
||||
ExtensionElement approverSpecifyElement = new ExtensionElement();
|
||||
approverSpecifyElement.setName("approverSpecify");
|
||||
|
||||
ExtensionAttribute approverSpecifyValueAttribute = new ExtensionAttribute();
|
||||
approverSpecifyValueAttribute.setName("value");
|
||||
approverSpecifyValueAttribute.setValue(property.getApproverSpecify());
|
||||
approverSpecifyElement.addAttribute(approverSpecifyValueAttribute);
|
||||
|
||||
ExtensionAttribute approverSpecifyDescAttribute = new ExtensionAttribute();
|
||||
approverSpecifyDescAttribute.setName("desc");
|
||||
approverSpecifyDescAttribute.setValue("审批人指定");
|
||||
approverSpecifyElement.addAttribute(approverSpecifyDescAttribute);
|
||||
// 审批人指定的具体值
|
||||
approverSpecifyElement.setElementText(StringUtils.collectionToCommaDelimitedString(property.getSpecifyValue()));
|
||||
userTask.addExtensionElement(approverSpecifyElement);
|
||||
|
||||
// 多人审批时审批模式
|
||||
ExtensionElement approverModeTypeElement = new ExtensionElement();
|
||||
approverModeTypeElement.setName("approverModeType");
|
||||
|
||||
ExtensionAttribute approverModeTypeValueAttribute = new ExtensionAttribute();
|
||||
approverModeTypeValueAttribute.setName("value");
|
||||
approverModeTypeValueAttribute.setValue(property.getMultiMode().getType());
|
||||
approverModeTypeElement.addAttribute(approverModeTypeValueAttribute);
|
||||
|
||||
ExtensionAttribute approverModeTypeDescAttribute = new ExtensionAttribute();
|
||||
approverModeTypeDescAttribute.setName("desc");
|
||||
approverModeTypeDescAttribute.setValue("多人审批时审批模式");
|
||||
approverModeTypeElement.addAttribute(approverModeTypeDescAttribute);
|
||||
userTask.addExtensionElement(approverModeTypeElement);
|
||||
|
||||
// 审批人为空时
|
||||
ExtensionElement approverEmptyHandleTypeElement = new ExtensionElement();
|
||||
approverEmptyHandleTypeElement.setName("approverEmptyHandleType");
|
||||
ExtensionAttribute approverEmptyHandleTypeValueAttribute = new ExtensionAttribute();
|
||||
approverEmptyHandleTypeValueAttribute.setName("value");
|
||||
approverEmptyHandleTypeValueAttribute.setValue(property.getApproverEmptyHandleType());
|
||||
approverEmptyHandleTypeElement.addAttribute(approverEmptyHandleTypeValueAttribute);
|
||||
|
||||
ExtensionAttribute approverEmptyHandleTypeDescAttribute = new ExtensionAttribute();
|
||||
approverEmptyHandleTypeDescAttribute.setName("desc");
|
||||
approverEmptyHandleTypeDescAttribute.setValue("审批人为空时");
|
||||
approverEmptyHandleTypeElement.addAttribute(approverEmptyHandleTypeDescAttribute);
|
||||
userTask.addExtensionElement(approverEmptyHandleTypeElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置执行监听
|
||||
*
|
||||
|
||||
@ -107,6 +107,7 @@ public class BpmnProcessModelServiceImpl implements BpmnProcessModelService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String createBpmModel(@Valid BpmnModelCreateDTO dto) {
|
||||
Model existModel = repositoryService.createModelQuery()
|
||||
.modelKey(dto.getKey())
|
||||
|
||||
365
workflow-engine-server/src/main/resources/test.bpmn20.xml
Normal file
365
workflow-engine-server/src/main/resources/test.bpmn20.xml
Normal file
File diff suppressed because one or more lines are too long
@ -229,7 +229,557 @@
|
||||
"parentId": "0",
|
||||
"type": "NODE_STARTER",
|
||||
"name": "发起人",
|
||||
"children": null,
|
||||
"children": {
|
||||
"id": "2",
|
||||
"parentId": "1",
|
||||
"type": "NODE_TASK",
|
||||
"name": "一级审批",
|
||||
"children": {
|
||||
"id": "3",
|
||||
"parentId": "2",
|
||||
"type": "NODE_EXCLUSIVE_GATEWAY",
|
||||
"name": "排它网关",
|
||||
"children": {
|
||||
"id": "11",
|
||||
"parentId": "3",
|
||||
"type": "NODE_CARBON_COPY",
|
||||
"name": "主流程抄送节点",
|
||||
"children": {
|
||||
"id": "12",
|
||||
"parentId": "3",
|
||||
"type": "NODE_EMPTY",
|
||||
"name": "结束",
|
||||
"children": null,
|
||||
"branches": null,
|
||||
"property": null
|
||||
},
|
||||
"branches": null,
|
||||
"property": null
|
||||
},
|
||||
"branches": [
|
||||
{
|
||||
"id": "4",
|
||||
"parentId": "3",
|
||||
"type": "NODE_CONDITION",
|
||||
"name": "条件1",
|
||||
"property": {
|
||||
"groups": [
|
||||
{
|
||||
"conditionsType": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"fieldDataType": "string",
|
||||
"fieldCode": "title",
|
||||
"operator": "contains",
|
||||
"defaultValue": "测试"
|
||||
},
|
||||
{
|
||||
"fieldDataType": "number",
|
||||
"fieldCode": "price",
|
||||
"operator": "eq",
|
||||
"defaultValue": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"defaultBranch": false,
|
||||
"groupsType": "and"
|
||||
},
|
||||
"children": {
|
||||
"id": "7",
|
||||
"parentId": "4",
|
||||
"type": "NODE_TASK",
|
||||
"name": "条件1审核节点",
|
||||
"children": {
|
||||
"id": "8",
|
||||
"parentId": "7",
|
||||
"type": "NODE_CARBON_COPY",
|
||||
"name": "条件1抄送节点",
|
||||
"children": null,
|
||||
"property": null,
|
||||
"branches": null
|
||||
},
|
||||
"property": {
|
||||
"approvalMethod": "autoPassed",
|
||||
"approverScope": "entWorkspace",
|
||||
"approverSpecify": "position",
|
||||
"specifyValue": [
|
||||
"job1",
|
||||
"job2"
|
||||
],
|
||||
"isMultiTask": "true",
|
||||
"multiMode": "AND",
|
||||
"approverEmptyHandleType": "autoPassed",
|
||||
"fieldPermission": null,
|
||||
"buttonPermission": {
|
||||
"initiator": [
|
||||
{
|
||||
"btnKey": "BPMN_APPROVE",
|
||||
"enabled": true,
|
||||
"btnName": "同意"
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REJECT",
|
||||
"btnName": "拒绝",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REVOCATION",
|
||||
"btnName": "撤回",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_FORWARD",
|
||||
"btnName": "转交",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COUNTERSIGN",
|
||||
"btnName": "加签",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COMMENT",
|
||||
"btnName": "评论",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_ROLLBACK",
|
||||
"btnName": "回退",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COPY",
|
||||
"btnName": "抄送",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"carbonCopy": [
|
||||
{
|
||||
"btnKey": "BPMN_APPROVE",
|
||||
"enabled": true,
|
||||
"btnName": "同意"
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REJECT",
|
||||
"btnName": "拒绝",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REVOCATION",
|
||||
"btnName": "撤回",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_FORWARD",
|
||||
"btnName": "转交",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COUNTERSIGN",
|
||||
"btnName": "加签",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COMMENT",
|
||||
"btnName": "评论",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_ROLLBACK",
|
||||
"btnName": "回退",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COPY",
|
||||
"btnName": "抄送",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"history": [
|
||||
{
|
||||
"btnKey": "BPMN_APPROVE",
|
||||
"enabled": true,
|
||||
"btnName": "同意"
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REJECT",
|
||||
"btnName": "拒绝",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REVOCATION",
|
||||
"btnName": "撤回",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_FORWARD",
|
||||
"btnName": "转交",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COUNTERSIGN",
|
||||
"btnName": "加签",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COMMENT",
|
||||
"btnName": "评论",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_ROLLBACK",
|
||||
"btnName": "回退",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COPY",
|
||||
"btnName": "抄送",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"current": [
|
||||
{
|
||||
"btnKey": "BPMN_APPROVE",
|
||||
"enabled": true,
|
||||
"btnName": "同意"
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REJECT",
|
||||
"btnName": "拒绝",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REVOCATION",
|
||||
"btnName": "撤回",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_FORWARD",
|
||||
"btnName": "转交",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COUNTERSIGN",
|
||||
"btnName": "加签",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COMMENT",
|
||||
"btnName": "评论",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_ROLLBACK",
|
||||
"btnName": "回退",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COPY",
|
||||
"btnName": "抄送",
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"branches": null
|
||||
},
|
||||
"branches": null
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"parentId": "3",
|
||||
"type": "NODE_CONDITION",
|
||||
"name": "条件2",
|
||||
"property": {
|
||||
"groups": [
|
||||
{
|
||||
"conditionsType": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"fieldDataType": "number",
|
||||
"fieldCode": "size",
|
||||
"operator": "between",
|
||||
"leftValue": "31",
|
||||
"leftOperator": "le",
|
||||
"rightValue": "34",
|
||||
"rightOperator": "gt"
|
||||
},
|
||||
{
|
||||
"fieldDataType": "radio",
|
||||
"fieldCode": "sex",
|
||||
"operator": "eq",
|
||||
"defaultValue": "2"
|
||||
},
|
||||
{
|
||||
"fieldDataType": "checkbox",
|
||||
"fieldCode": "color",
|
||||
"operator": "in",
|
||||
"defaultValues": [
|
||||
"red",
|
||||
"blue"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"defaultBranch": false,
|
||||
"groupsType": "and"
|
||||
},
|
||||
"children": {
|
||||
"id": "9",
|
||||
"parentId": "5",
|
||||
"type": "NODE_BUSINESS",
|
||||
"name": "条件2业务节点",
|
||||
"children": {
|
||||
"id": "10",
|
||||
"parentId": "9",
|
||||
"type": "NODE_TASK",
|
||||
"name": "条件2审批节点",
|
||||
"children": {
|
||||
"id": "13",
|
||||
"parentId": "10",
|
||||
"type": "NODE_BUSINESS",
|
||||
"name": "业务节点有审批人",
|
||||
"property": {
|
||||
"approvalMethod": "human",
|
||||
"approverScope": "projectWorkspace",
|
||||
"approverSpecify": "identity",
|
||||
"specifyValue": [
|
||||
"worker",
|
||||
"team_worker"
|
||||
],
|
||||
"isMultiTask": "true",
|
||||
"multiMode": "AND",
|
||||
"approverEmptyHandleType": "transferToAdmin",
|
||||
"fieldPermission": null,
|
||||
"buttonPermission": null
|
||||
},
|
||||
"children": null,
|
||||
"branches": null
|
||||
},
|
||||
"property": {
|
||||
"approvalMethod": "human",
|
||||
"approverScope": "projectWorkspace",
|
||||
"approverSpecify": "position",
|
||||
"specifyValue": [
|
||||
"job1",
|
||||
"job2"
|
||||
],
|
||||
"isMultiTask": "true",
|
||||
"multiMode": "AND",
|
||||
"approverEmptyHandleType": "autoPassed",
|
||||
"fieldPermission": null,
|
||||
"buttonPermission": null
|
||||
},
|
||||
"branches": null
|
||||
},
|
||||
"property": {
|
||||
"approvalMethod": "nobody"
|
||||
},
|
||||
"branches": null
|
||||
},
|
||||
"branches": null
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"parentId": "3",
|
||||
"type": "NODE_CONDITION",
|
||||
"name": "默认条件",
|
||||
"property": {
|
||||
"defaultBranch": true
|
||||
},
|
||||
"children": null,
|
||||
"branches": null
|
||||
}
|
||||
],
|
||||
"property": null
|
||||
},
|
||||
"branches": null,
|
||||
"property": {
|
||||
"approvalMethod": "human",
|
||||
"approverScope": "projectWorkspace",
|
||||
"approverSpecify": "position",
|
||||
"specifyValue": [
|
||||
"job1",
|
||||
"job2"
|
||||
],
|
||||
"isMultiTask": "true",
|
||||
"multiMode": "AND",
|
||||
"approverEmptyHandleType": "autoPassed",
|
||||
"fieldPermission": null,
|
||||
"buttonPermission": {
|
||||
"initiator": [
|
||||
{
|
||||
"btnKey": "BPMN_APPROVE",
|
||||
"enabled": true,
|
||||
"btnName": "同意"
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REJECT",
|
||||
"btnName": "拒绝",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REVOCATION",
|
||||
"btnName": "撤回",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_FORWARD",
|
||||
"btnName": "转交",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COUNTERSIGN",
|
||||
"btnName": "加签",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COMMENT",
|
||||
"btnName": "评论",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_ROLLBACK",
|
||||
"btnName": "回退",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COPY",
|
||||
"btnName": "抄送",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"carbonCopy": [
|
||||
{
|
||||
"btnKey": "BPMN_APPROVE",
|
||||
"enabled": true,
|
||||
"btnName": "同意"
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REJECT",
|
||||
"btnName": "拒绝",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REVOCATION",
|
||||
"btnName": "撤回",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_FORWARD",
|
||||
"btnName": "转交",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COUNTERSIGN",
|
||||
"btnName": "加签",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COMMENT",
|
||||
"btnName": "评论",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_ROLLBACK",
|
||||
"btnName": "回退",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COPY",
|
||||
"btnName": "抄送",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"history": [
|
||||
{
|
||||
"btnKey": "BPMN_APPROVE",
|
||||
"enabled": true,
|
||||
"btnName": "同意"
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REJECT",
|
||||
"btnName": "拒绝",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REVOCATION",
|
||||
"btnName": "撤回",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_FORWARD",
|
||||
"btnName": "转交",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COUNTERSIGN",
|
||||
"btnName": "加签",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COMMENT",
|
||||
"btnName": "评论",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_ROLLBACK",
|
||||
"btnName": "回退",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COPY",
|
||||
"btnName": "抄送",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"current": [
|
||||
{
|
||||
"btnKey": "BPMN_APPROVE",
|
||||
"enabled": true,
|
||||
"btnName": "同意"
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REJECT",
|
||||
"btnName": "拒绝",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_REVOCATION",
|
||||
"btnName": "撤回",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_FORWARD",
|
||||
"btnName": "转交",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COUNTERSIGN",
|
||||
"btnName": "加签",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COMMENT",
|
||||
"btnName": "评论",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_ROLLBACK",
|
||||
"btnName": "回退",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"btnKey": "BPMN_COPY",
|
||||
"btnName": "抄送",
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"branches": null,
|
||||
"property": null
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user