update - 完善配置台功能模型

This commit is contained in:
wangli 2023-11-15 20:59:34 +08:00
parent 1b3b0876f6
commit 50c1bd5fc6
20 changed files with 373 additions and 1437 deletions

View File

@ -37,7 +37,37 @@ public interface BpmnConstants {
String COUNTERSIGN_ORIGIN_ASSIGNER = "COUNTERSIGN_ORIGIN_ASSIGNER"; String COUNTERSIGN_ORIGIN_ASSIGNER = "COUNTERSIGN_ORIGIN_ASSIGNER";
String PROCESS_PREFIX = "Flowable"; String PROCESS_PREFIX = "Flowable";
String FLOW_NODE_JSON = "jsonValue"; String FLOW_NODE_JSON = "jsonMetaValue";
String FLOW_SERVER_VERSION = "serverVersion";
String FLOW_SERVER_VERSION_121 = "1.2.1";
String CONFIG_NOTICE = "noticeConfig";
String TEMPLATE_NOTICE_MESSAGE_ID = "noticeMessageId";
String TEMPLATE_PENDING_MESSAGE_ID = "pendingMessageId";
String TEMPLATE_SMS_MESSAGE_ID = "smsMessageId";
String CONFIG_BUTTON = "buttonConfig";
String CONFIG_BUTTON_META = "button";
String CONFIG_FIELD = "fieldConfig";
String CONFIG_APPROVAL_METHOD = "approvalMethod";
String CONFIG_APPROVER_SCOPE = "approverScope";
String CONFIG_APPROVER_SPECIFY = "approverSpecify";
String CONFIG_APPROVER_MODE_TYPE = "approverModeType";
String CONFIG_APPROVER_EMPTY_HANDLE_TYPE = "approverEmptyHandleType";
String CONFIG_FIELD_META = "field";
String CONFIG_FIELD_PERMISSION = "fieldPermission";
String CONFIG_FIELD_OPTION = "option";
String CONFIG_BUTTON_TYPE_INITIATOR = "initiator";
String CONFIG_BUTTON_TYPE_CURRENT = "current";
String CONFIG_BUTTON_TYPE_HISTORY = "history";
String CONFIG_BUTTON_TYPE_CARBON_COPY = "carbonCopy";
String ELEMENT_ATTRIBUTE_NAME = "name";
String ELEMENT_ATTRIBUTE_VALUE = "value";
String ELEMENT_ATTRIBUTE_DESC = "desc";
String ELEMENT_ATTRIBUTE_CODE = "code";
String ELEMENT_ATTRIBUTE_KEY = "key";
String ELEMENT_ATTRIBUTE_ORDER = "order";
String ELEMENT_ATTRIBUTE_TYPE = "type";
String START_EVENT_ID = "startEventNode"; String START_EVENT_ID = "startEventNode";
String SEQUENCE_FLOW_ID = "SequenceFlowId"; String SEQUENCE_FLOW_ID = "SequenceFlowId";
String END_EVENT_ID = "endEventNode"; String END_EVENT_ID = "endEventNode";

View File

@ -5,6 +5,7 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
@ -18,7 +19,7 @@ import java.util.List;
@Accessors(chain = true) @Accessors(chain = true)
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class CooperationOrgDTO { public class CooperationOrgDTO implements Serializable {
/** /**
* 企业组织架构 * 企业组织架构
@ -34,14 +35,14 @@ public class CooperationOrgDTO {
*/ */
private List<Long> projOuId; private List<Long> projOuId;
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public static class OrgScope { public static class OrgScope implements Serializable {
private Long workspaceId; private Long workspaceId;
private Long ouId; private Long ouId;
} }
} }

View File

@ -12,12 +12,23 @@ import lombok.experimental.Accessors;
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
public class BpmnButtonMetaInfo { public class BpmnButtonMetaInfo {
private Integer order;
private String btnKey; private String btnKey;
private String btnName; private String btnName;
private Boolean enabled; private Boolean enabled;
public Integer getOrder() {
return order;
}
public void setOrder(Integer order) {
this.order = order;
}
public String getBtnKey() { public String getBtnKey() {
return btnKey; return btnKey;
} }

View File

@ -9,9 +9,10 @@ import java.io.Serializable;
/** /**
* 统一的工作流中的人员模型,兼容不同的业务方,如安心筑"唯一"人的定义需要工作台+身份 ID+身份类型;而枢智业务则只需要简单的 userId 即可 * 统一的工作流中的人员模型,兼容不同的业务方,如安心筑"唯一"人的定义需要工作台+身份 ID+身份类型;<br/>
* 而枢智业务则只需要简单的 userId 即可
* <p> * <p>
* 为了解决各种业务的差异,统一定义该模型,大范围覆盖小范围的方式进行兼容. * 为了解决各种业务的差异,统一定义该模型,大范围覆盖小范围的方式进行兼容.
* *
* @author wangli * @author wangli
*/ */

View File

@ -57,10 +57,31 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_META;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_TYPE_CARBON_COPY;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_TYPE_CURRENT;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_TYPE_HISTORY;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_TYPE_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_META;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_OPTION;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_NOTICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_CODE;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_KEY;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_NAME;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_ORDER;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_VALUE;
import static cn.axzo.workflow.common.constant.BpmnConstants.END_EVENT_ID; 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.FLOW_NODE_JSON;
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_121;
import static cn.axzo.workflow.common.constant.BpmnConstants.SEQUENCE_FLOW_ID; 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.constant.BpmnConstants.START_EVENT_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.TEMPLATE_NOTICE_MESSAGE_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.TEMPLATE_PENDING_MESSAGE_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.TEMPLATE_SMS_MESSAGE_ID;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY; import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY;
import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.CONVERTOR_COMMON_ERROR; import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.CONVERTOR_COMMON_ERROR;
@ -115,16 +136,19 @@ public class BpmnJsonConverterUtil {
// 提交的 BpmnJsonNode 全部都是任务是可执行节点, 这里的转换是全局都会增加开始和结束节点. 因为前段的提交的数据是不包含开始和结束 // 提交的 BpmnJsonNode 全部都是任务是可执行节点, 这里的转换是全局都会增加开始和结束节点. 因为前段的提交的数据是不包含开始和结束
BpmnModel bpmnModel = new BpmnModel(); BpmnModel bpmnModel = new BpmnModel();
ExtensionAttribute extensionAttribute = new ExtensionAttribute(); ExtensionAttribute serverVersion = new ExtensionAttribute();
extensionAttribute.setName(FLOW_NODE_JSON); serverVersion.setName(FLOW_SERVER_VERSION);
extensionAttribute.setNamespace("http://flowable.org/bpmn"); serverVersion.setValue(FLOW_SERVER_VERSION_121);
extensionAttribute.setValue(JSON.toJSONString(bpmnJsonNode)); ExtensionAttribute jsonMetaValue = new ExtensionAttribute();
jsonMetaValue.setName(FLOW_NODE_JSON);
jsonMetaValue.setValue(JSON.toJSONString(bpmnJsonNode));
Process mainProcess = new Process(); Process mainProcess = new Process();
mainProcess.setId(id); mainProcess.setId(id);
mainProcess.setName(name); mainProcess.setName(name);
mainProcess.setDocumentation(documentation); mainProcess.setDocumentation(documentation);
mainProcess.addAttribute(extensionAttribute); mainProcess.addAttribute(serverVersion);
mainProcess.addAttribute(jsonMetaValue);
// 设置流程的通知管理配置 // 设置流程的通知管理配置
setProcessNoticeConfig(noticeConf, mainProcess); setProcessNoticeConfig(noticeConf, mainProcess);
@ -155,40 +179,40 @@ public class BpmnJsonConverterUtil {
private static void setProcessFieldConfig(List<BpmnFieldConf> fieldConf, Process mainProcess) { private static void setProcessFieldConfig(List<BpmnFieldConf> fieldConf, Process mainProcess) {
ExtensionElement fieldConfigElement = new ExtensionElement(); ExtensionElement fieldConfigElement = new ExtensionElement();
fieldConfigElement.setName("fieldConfig"); fieldConfigElement.setName(CONFIG_FIELD);
if (!CollectionUtils.isEmpty(fieldConf)) { if (!CollectionUtils.isEmpty(fieldConf)) {
fieldConf.forEach(i -> { fieldConf.forEach(i -> {
ExtensionElement field = new ExtensionElement(); ExtensionElement field = new ExtensionElement();
field.setName("filed"); field.setName(CONFIG_FIELD_META);
ExtensionAttribute fieldDataType = new ExtensionAttribute(); ExtensionAttribute fieldDataType = new ExtensionAttribute();
fieldDataType.setName("type"); fieldDataType.setName(ELEMENT_ATTRIBUTE_TYPE);
fieldDataType.setValue(i.getType()); fieldDataType.setValue(i.getType());
field.addAttribute(fieldDataType); field.addAttribute(fieldDataType);
ExtensionAttribute fieldName = new ExtensionAttribute(); ExtensionAttribute fieldName = new ExtensionAttribute();
fieldName.setName("name"); fieldName.setName(ELEMENT_ATTRIBUTE_NAME);
fieldName.setValue(i.getName()); fieldName.setValue(i.getName());
field.addAttribute(fieldName); field.addAttribute(fieldName);
ExtensionAttribute fieldCode = new ExtensionAttribute(); ExtensionAttribute fieldCode = new ExtensionAttribute();
fieldCode.setName("code"); fieldCode.setName(ELEMENT_ATTRIBUTE_CODE);
fieldCode.setValue(i.getCode()); fieldCode.setValue(i.getCode());
field.addAttribute(fieldCode); field.addAttribute(fieldCode);
if (!CollectionUtils.isEmpty(i.getOptions())) { if (!CollectionUtils.isEmpty(i.getOptions())) {
i.getOptions().forEach(j -> { i.getOptions().forEach(j -> {
ExtensionElement option = new ExtensionElement(); ExtensionElement option = new ExtensionElement();
option.setName("option"); option.setName(CONFIG_FIELD_OPTION);
ExtensionAttribute optionName = new ExtensionAttribute(); ExtensionAttribute optionName = new ExtensionAttribute();
optionName.setName("name"); optionName.setName(ELEMENT_ATTRIBUTE_NAME);
optionName.setValue(j.getName()); optionName.setValue(j.getName());
option.addAttribute(optionName); option.addAttribute(optionName);
ExtensionAttribute optionValue = new ExtensionAttribute(); ExtensionAttribute optionValue = new ExtensionAttribute();
optionValue.setName("value"); optionValue.setName(ELEMENT_ATTRIBUTE_VALUE);
optionValue.setValue(j.getValue()); optionValue.setValue(j.getValue());
option.addAttribute(optionValue); option.addAttribute(optionValue);
@ -203,33 +227,44 @@ public class BpmnJsonConverterUtil {
private static void setProcessButtonConfig(BpmnButtonConf buttonConf, Process mainProcess) { private static void setProcessButtonConfig(BpmnButtonConf buttonConf, Process mainProcess) {
ExtensionElement buttonConfigElement = new ExtensionElement(); ExtensionElement buttonConfigElement = new ExtensionElement();
buttonConfigElement.setName("buttonConfig"); buttonConfigElement.setName(CONFIG_BUTTON);
buildMetaButton(buttonConf.getInitiator(), "initiator", buttonConfigElement); buildMetaButton(buttonConf.getInitiator(), CONFIG_BUTTON_TYPE_INITIATOR, buttonConfigElement);
buildMetaButton(buttonConf.getCurrent(), "current", buttonConfigElement); buildMetaButton(buttonConf.getCurrent(), CONFIG_BUTTON_TYPE_CURRENT, buttonConfigElement);
buildMetaButton(buttonConf.getHistory(), "history", buttonConfigElement); buildMetaButton(buttonConf.getHistory(), CONFIG_BUTTON_TYPE_HISTORY, buttonConfigElement);
buildMetaButton(buttonConf.getCarbonCopy(), "carbonCopy", buttonConfigElement); buildMetaButton(buttonConf.getCarbonCopy(), CONFIG_BUTTON_TYPE_CARBON_COPY, buttonConfigElement);
mainProcess.addExtensionElement(buttonConfigElement); mainProcess.addExtensionElement(buttonConfigElement);
} }
public static void buildMetaButton(List<BpmnButtonMetaInfo> buttonMetaInfos, String buttonType, public static void buildMetaButton(List<BpmnButtonMetaInfo> buttonMetaInfos, String buttonType,
ExtensionElement buttonConfigElement) { ExtensionElement buttonConfigElement) {
if (!CollectionUtils.isEmpty(buttonMetaInfos)) { if (!CollectionUtils.isEmpty(buttonMetaInfos)) {
ExtensionElement initiator = new ExtensionElement(); ExtensionElement initiator = new ExtensionElement();
initiator.setName(buttonType); initiator.setName(buttonType);
buttonMetaInfos.forEach(i -> { buttonMetaInfos.forEach(i -> {
ExtensionElement button = new ExtensionElement(); ExtensionElement button = new ExtensionElement();
button.setName(i.getBtnKey()); button.setName(CONFIG_BUTTON_META);
ExtensionAttribute keyAttribute = new ExtensionAttribute();
keyAttribute.setName(ELEMENT_ATTRIBUTE_KEY);
keyAttribute.setValue(i.getBtnKey());
button.addAttribute(keyAttribute);
ExtensionAttribute nameAttribute = new ExtensionAttribute(); ExtensionAttribute nameAttribute = new ExtensionAttribute();
nameAttribute.setName("name"); nameAttribute.setName(ELEMENT_ATTRIBUTE_NAME);
nameAttribute.setValue(i.getBtnName()); nameAttribute.setValue(i.getBtnName());
button.addAttribute(nameAttribute); button.addAttribute(nameAttribute);
ExtensionAttribute valueAttribute = new ExtensionAttribute(); ExtensionAttribute valueAttribute = new ExtensionAttribute();
valueAttribute.setName("value"); valueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
valueAttribute.setValue(String.valueOf(i.getEnabled())); valueAttribute.setValue(String.valueOf(i.getEnabled()));
button.addAttribute(valueAttribute); button.addAttribute(valueAttribute);
ExtensionAttribute orderAttribute = new ExtensionAttribute();
orderAttribute.setName(ELEMENT_ATTRIBUTE_ORDER);
orderAttribute.setValue(String.valueOf(i.getEnabled()));
button.addAttribute(orderAttribute);
initiator.addChildElement(button); initiator.addChildElement(button);
}); });
buttonConfigElement.addChildElement(initiator); buttonConfigElement.addChildElement(initiator);
@ -238,25 +273,34 @@ public class BpmnJsonConverterUtil {
private static void setProcessNoticeConfig(BpmnNoticeConf noticeConf, Process mainProcess) { private static void setProcessNoticeConfig(BpmnNoticeConf noticeConf, Process mainProcess) {
ExtensionElement noticeConfigElement = new ExtensionElement(); ExtensionElement noticeConfigElement = new ExtensionElement();
noticeConfigElement.setName("noticeConfig"); noticeConfigElement.setName(CONFIG_NOTICE);
// 通知消息模板配置 // 通知消息模板配置
ExtensionElement noticeMessage = new ExtensionElement(); ExtensionElement noticeMessage = new ExtensionElement();
noticeMessage.setName("noticeMessageId"); noticeMessage.setName(TEMPLATE_NOTICE_MESSAGE_ID);
noticeMessage.setElementText(noticeConf.getNoticeMessageId()); ExtensionAttribute noticeMessageAttribute = new ExtensionAttribute();
noticeMessageAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
noticeMessageAttribute.setValue(noticeConf.getNoticeMessageId());
noticeMessage.addAttribute(noticeMessageAttribute);
noticeConfigElement.addChildElement(noticeMessage); noticeConfigElement.addChildElement(noticeMessage);
// 代办消息模板配置 // 代办消息模板配置
ExtensionElement pendingMessage = new ExtensionElement(); ExtensionElement pendingMessage = new ExtensionElement();
pendingMessage.setName("pendingMessageId"); pendingMessage.setName(TEMPLATE_PENDING_MESSAGE_ID);
pendingMessage.setElementText(noticeConf.getPendingMessageId()); ExtensionAttribute pendingMessageAttribute = new ExtensionAttribute();
pendingMessageAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
pendingMessageAttribute.setValue(noticeConf.getPendingMessageId());
pendingMessage.addAttribute(pendingMessageAttribute);
noticeConfigElement.addChildElement(pendingMessage); noticeConfigElement.addChildElement(pendingMessage);
// 短信模板配置 // 短信模板配置
if (Objects.nonNull(noticeConf.getSmsId())) { if (Objects.nonNull(noticeConf.getSmsId())) {
ExtensionElement smsMessage = new ExtensionElement(); ExtensionElement smsMessage = new ExtensionElement();
smsMessage.setName("smsMessageId"); smsMessage.setName(TEMPLATE_SMS_MESSAGE_ID);
smsMessage.setElementText(noticeConf.getSmsId()); ExtensionAttribute smsMessageAttribute = new ExtensionAttribute();
smsMessageAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
smsMessageAttribute.setValue(noticeConf.getSmsId());
smsMessage.addAttribute(smsMessageAttribute);
noticeConfigElement.addChildElement(smsMessage); noticeConfigElement.addChildElement(smsMessage);
} }
mainProcess.addExtensionElement(noticeConfigElement); mainProcess.addExtensionElement(noticeConfigElement);
@ -283,7 +327,7 @@ public class BpmnJsonConverterUtil {
/** /**
* 创建对应类型节点并保存在 bpmnModel * 创建对应类型节点并保存在 bpmnModel
* *
* @param preNodeId 上级节点的 Id,用于链接当前创建节点 * @param preNodeIds 上级节点的 Id 结合,用于链接当前创建节点
* @param bpmnJsonNode 前端传入节点数据,不是全数据,而是对应层级 * @param bpmnJsonNode 前端传入节点数据,不是全数据,而是对应层级
* @param mainProcess Process 对象 * @param mainProcess Process 对象
* @param bpmnModel 最终的 BPMN model * @param bpmnModel 最终的 BPMN model
@ -398,7 +442,10 @@ public class BpmnJsonConverterUtil {
Process process) { Process process) {
AbstractBpmnJsonConverter converter = converters.getOrDefault(clz, new NotSupportConverter()); AbstractBpmnJsonConverter converter = converters.getOrDefault(clz, new NotSupportConverter());
FlowElement flowElement = converter.convertJsonToElement(bpmnJsonNode, process); FlowElement flowElement = converter.convertJsonToElement(bpmnJsonNode, process);
converter.addJsonValueAttribute(flowElement, copy(bpmnJsonNode)); if (Objects.nonNull(bpmnJsonNode)) {
converter.addTypeAttribute(flowElement, copy(bpmnJsonNode));
converter.addJsonValueAttribute(flowElement, copy(bpmnJsonNode));
}
return flowElement; return flowElement;
} }

View File

@ -7,6 +7,7 @@ import org.flowable.bpmn.model.ExtensionAttribute;
import org.flowable.bpmn.model.FlowElement; import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.Process;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_NODE_JSON; import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_NODE_JSON;
/** /**
@ -21,10 +22,17 @@ public abstract class AbstractBpmnJsonConverter<T extends FlowElement> {
throw new WorkflowEngineException("暂不支持 BPMN 转 JSON"); throw new WorkflowEngineException("暂不支持 BPMN 转 JSON");
} }
public final void addJsonValueAttribute(T t, BpmnJsonNode jsonNode) { public final void addTypeAttribute(T flowElement, BpmnJsonNode node) {
ExtensionAttribute typeAttribute = new ExtensionAttribute();
typeAttribute.setName(ELEMENT_ATTRIBUTE_TYPE);
typeAttribute.setValue(node.getType().getType());
flowElement.addAttribute(typeAttribute);
}
public final void addJsonValueAttribute(T flowElement, BpmnJsonNode jsonNode) {
ExtensionAttribute extensionAttribute = new ExtensionAttribute(); ExtensionAttribute extensionAttribute = new ExtensionAttribute();
extensionAttribute.setName(FLOW_NODE_JSON); extensionAttribute.setName(FLOW_NODE_JSON);
extensionAttribute.setValue(JSON.toJSONString(jsonNode)); extensionAttribute.setValue(JSON.toJSONString(jsonNode));
t.addAttribute(extensionAttribute); flowElement.addAttribute(extensionAttribute);
} }
} }

View File

@ -1,11 +1,13 @@
package cn.axzo.workflow.core.converter.json; package cn.axzo.workflow.core.converter.json;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf; 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.BpmnJsonNode;
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNodeProperty; import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNodeProperty;
import org.flowable.bpmn.model.ExtensionAttribute; import org.flowable.bpmn.model.ExtensionAttribute;
import org.flowable.bpmn.model.ExtensionElement; import org.flowable.bpmn.model.ExtensionElement;
import org.flowable.bpmn.model.FlowableListener; import org.flowable.bpmn.model.FlowableListener;
import org.flowable.bpmn.model.MultiInstanceLoopCharacteristics;
import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask; import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.delegate.BaseExecutionListener; import org.flowable.engine.delegate.BaseExecutionListener;
@ -16,6 +18,23 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_ALLOW_SKIP_USER_TASK;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVAL_METHOD;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_EMPTY_HANDLE_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_MODE_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_SCOPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_SPECIFY;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_TYPE_CARBON_COPY;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_TYPE_CURRENT;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_TYPE_HISTORY;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_TYPE_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_PERMISSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_VALUE;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.OR_SIGN_EXPRESSION;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER; import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
import static cn.axzo.workflow.core.common.utils.BpmnJsonConverterUtil.buildMetaButton; import static cn.axzo.workflow.core.common.utils.BpmnJsonConverterUtil.buildMetaButton;
import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION; import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION;
@ -35,6 +54,18 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
userTask.setId(node.getId()); userTask.setId(node.getId());
userTask.setName(node.getName()); userTask.setName(node.getName());
// 设置审批人为空时,允许自动通过
setAutoCompleted(node, userTask);
// 设置会签或签
setMultiInstance(node, userTask);
// 设置全局任务监听器
setTaskListeners(userTask);
// 设置全局执行监听器
if (!Objects.equals(NODE_STARTER, node.getType())) {
setExecutionListeners(userTask);
}
//以下是保存配置信息, 引擎完全不会 care 这里的信息
// "设置审批人" // "设置审批人"
setApprovalExtensionElement(node, userTask); setApprovalExtensionElement(node, userTask);
// "权限设置" // "权限设置"
@ -42,28 +73,53 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
// "高级设置" // "高级设置"
setButtonExtensionElement(node, userTask); setButtonExtensionElement(node, userTask);
setTaskListeners(userTask);
if (!Objects.equals(NODE_STARTER, node.getType())) {
setExecutionListeners(userTask);
}
return userTask; return userTask;
} }
private static void setAutoCompleted(BpmnJsonNode node, UserTask userTask) {
if (Objects.nonNull(node.getProperty()) &&
Objects.equals(node.getProperty().getApproverEmptyHandleType(), "autoPassed")) {
userTask.setSkipExpression("${" + BPM_ALLOW_SKIP_USER_TASK + "}");
}
}
private static void setMultiInstance(BpmnJsonNode node, UserTask userTask) {
if (Objects.isNull(node.getProperty())) {
return;
}
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics =
new MultiInstanceLoopCharacteristics();
// 审批人集合参数
multiInstanceLoopCharacteristics.setInputDataItem(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO + userTask.getId());
// 迭代集合
multiInstanceLoopCharacteristics.setElementVariable("assigneeName");
// 并行
multiInstanceLoopCharacteristics.setSequential(false);
userTask.setAssignee("${assigneeName}");
// 设置多实例属性
userTask.setLoopCharacteristics(multiInstanceLoopCharacteristics);
// 设置会签或签
if (BpmnFlowNodeMode.OR.equals(node.getProperty().getMultiMode())) {
multiInstanceLoopCharacteristics.setCompletionCondition(OR_SIGN_EXPRESSION);
} else if (BpmnFlowNodeMode.AND.equals(node.getProperty().getMultiMode())) {
multiInstanceLoopCharacteristics.setCompletionCondition(AND_SIGN_EXPRESSION);
}
}
private static void setButtonExtensionElement(BpmnJsonNode node, UserTask userTask) { private static void setButtonExtensionElement(BpmnJsonNode node, UserTask userTask) {
if (Objects.isNull(node.getProperty())) { if (Objects.isNull(node.getProperty())) {
return; return;
} }
BpmnButtonConf buttonConf = node.getProperty().getButtonPermission(); BpmnButtonConf buttonConf = node.getProperty().getButtonPermission();
ExtensionElement buttonConfigElement = new ExtensionElement(); ExtensionElement buttonConfigElement = new ExtensionElement();
buttonConfigElement.setName("buttonConfig"); buttonConfigElement.setName(CONFIG_BUTTON);
if (Objects.nonNull(buttonConf)) { if (Objects.nonNull(buttonConf)) {
buildMetaButton(buttonConf.getInitiator(), "initiator", buttonConfigElement); buildMetaButton(buttonConf.getInitiator(), CONFIG_BUTTON_TYPE_INITIATOR, buttonConfigElement);
buildMetaButton(buttonConf.getCurrent(), "current", buttonConfigElement); buildMetaButton(buttonConf.getCurrent(), CONFIG_BUTTON_TYPE_CURRENT, buttonConfigElement);
buildMetaButton(buttonConf.getHistory(), "history", buttonConfigElement); buildMetaButton(buttonConf.getHistory(), CONFIG_BUTTON_TYPE_HISTORY, buttonConfigElement);
buildMetaButton(buttonConf.getCarbonCopy(), "carbonCopy", buttonConfigElement); buildMetaButton(buttonConf.getCarbonCopy(), CONFIG_BUTTON_TYPE_CARBON_COPY, buttonConfigElement);
} }
userTask.addExtensionElement(buttonConfigElement); userTask.addExtensionElement(buttonConfigElement);
@ -74,7 +130,7 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
return; return;
} }
ExtensionElement fieldElement = new ExtensionElement(); ExtensionElement fieldElement = new ExtensionElement();
fieldElement.setName("fieldPermission"); fieldElement.setName(CONFIG_FIELD_PERMISSION);
fieldElement.setElementText(node.getProperty().getFieldPermission()); fieldElement.setElementText(node.getProperty().getFieldPermission());
userTask.addExtensionElement(fieldElement); userTask.addExtensionElement(fieldElement);
} }
@ -87,15 +143,15 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
// 审批方式 // 审批方式
ExtensionElement approvalMethodElement = new ExtensionElement(); ExtensionElement approvalMethodElement = new ExtensionElement();
approvalMethodElement.setName("approvalMethod"); approvalMethodElement.setName(CONFIG_APPROVAL_METHOD);
ExtensionAttribute approvalMethodValueAttribute = new ExtensionAttribute(); ExtensionAttribute approvalMethodValueAttribute = new ExtensionAttribute();
approvalMethodValueAttribute.setName("value"); approvalMethodValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
approvalMethodValueAttribute.setValue(property.getApprovalMethod()); approvalMethodValueAttribute.setValue(property.getApprovalMethod());
approvalMethodElement.addAttribute(approvalMethodValueAttribute); approvalMethodElement.addAttribute(approvalMethodValueAttribute);
ExtensionAttribute approvalMethodDescAttribute = new ExtensionAttribute(); ExtensionAttribute approvalMethodDescAttribute = new ExtensionAttribute();
approvalMethodDescAttribute.setName("desc"); approvalMethodDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
approvalMethodDescAttribute.setValue("审批方式"); approvalMethodDescAttribute.setValue("审批方式");
approvalMethodElement.addAttribute(approvalMethodDescAttribute); approvalMethodElement.addAttribute(approvalMethodDescAttribute);
@ -103,30 +159,30 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
// 审批人所在范围 // 审批人所在范围
ExtensionElement approverScopeElement = new ExtensionElement(); ExtensionElement approverScopeElement = new ExtensionElement();
approverScopeElement.setName("approverScope"); approverScopeElement.setName(CONFIG_APPROVER_SCOPE);
ExtensionAttribute approverScopeValueAttribute = new ExtensionAttribute(); ExtensionAttribute approverScopeValueAttribute = new ExtensionAttribute();
approverScopeValueAttribute.setName("value"); approverScopeValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
approverScopeValueAttribute.setValue(property.getApproverScope()); approverScopeValueAttribute.setValue(property.getApproverScope());
approverScopeElement.addAttribute(approverScopeValueAttribute); approverScopeElement.addAttribute(approverScopeValueAttribute);
ExtensionAttribute approverScopeDescAttribute = new ExtensionAttribute(); ExtensionAttribute approverScopeDescAttribute = new ExtensionAttribute();
approverScopeDescAttribute.setName("desc"); approverScopeDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
approverScopeDescAttribute.setValue("审批人所在范围"); approverScopeDescAttribute.setValue("审批人所在范围");
approverScopeElement.addAttribute(approverScopeDescAttribute); approverScopeElement.addAttribute(approverScopeDescAttribute);
userTask.addExtensionElement(approverScopeElement); userTask.addExtensionElement(approverScopeElement);
// 审批人指定 // 审批人指定
ExtensionElement approverSpecifyElement = new ExtensionElement(); ExtensionElement approverSpecifyElement = new ExtensionElement();
approverSpecifyElement.setName("approverSpecify"); approverSpecifyElement.setName(CONFIG_APPROVER_SPECIFY);
ExtensionAttribute approverSpecifyValueAttribute = new ExtensionAttribute(); ExtensionAttribute approverSpecifyValueAttribute = new ExtensionAttribute();
approverSpecifyValueAttribute.setName("value"); approverSpecifyValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
approverSpecifyValueAttribute.setValue(property.getApproverSpecify()); approverSpecifyValueAttribute.setValue(property.getApproverSpecify());
approverSpecifyElement.addAttribute(approverSpecifyValueAttribute); approverSpecifyElement.addAttribute(approverSpecifyValueAttribute);
ExtensionAttribute approverSpecifyDescAttribute = new ExtensionAttribute(); ExtensionAttribute approverSpecifyDescAttribute = new ExtensionAttribute();
approverSpecifyDescAttribute.setName("desc"); approverSpecifyDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
approverSpecifyDescAttribute.setValue("审批人指定"); approverSpecifyDescAttribute.setValue("审批人指定");
approverSpecifyElement.addAttribute(approverSpecifyDescAttribute); approverSpecifyElement.addAttribute(approverSpecifyDescAttribute);
// 审批人指定的具体值 // 审批人指定的具体值
@ -135,29 +191,29 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
// 多人审批时审批模式 // 多人审批时审批模式
ExtensionElement approverModeTypeElement = new ExtensionElement(); ExtensionElement approverModeTypeElement = new ExtensionElement();
approverModeTypeElement.setName("approverModeType"); approverModeTypeElement.setName(CONFIG_APPROVER_MODE_TYPE);
ExtensionAttribute approverModeTypeValueAttribute = new ExtensionAttribute(); ExtensionAttribute approverModeTypeValueAttribute = new ExtensionAttribute();
approverModeTypeValueAttribute.setName("value"); approverModeTypeValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
approverModeTypeValueAttribute.setValue(property.getMultiMode().getType()); approverModeTypeValueAttribute.setValue(property.getMultiMode().getType());
approverModeTypeElement.addAttribute(approverModeTypeValueAttribute); approverModeTypeElement.addAttribute(approverModeTypeValueAttribute);
ExtensionAttribute approverModeTypeDescAttribute = new ExtensionAttribute(); ExtensionAttribute approverModeTypeDescAttribute = new ExtensionAttribute();
approverModeTypeDescAttribute.setName("desc"); approverModeTypeDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
approverModeTypeDescAttribute.setValue("多人审批时审批模式"); approverModeTypeDescAttribute.setValue("多人审批时审批模式");
approverModeTypeElement.addAttribute(approverModeTypeDescAttribute); approverModeTypeElement.addAttribute(approverModeTypeDescAttribute);
userTask.addExtensionElement(approverModeTypeElement); userTask.addExtensionElement(approverModeTypeElement);
// 审批人为空时 // 审批人为空时
ExtensionElement approverEmptyHandleTypeElement = new ExtensionElement(); ExtensionElement approverEmptyHandleTypeElement = new ExtensionElement();
approverEmptyHandleTypeElement.setName("approverEmptyHandleType"); approverEmptyHandleTypeElement.setName(CONFIG_APPROVER_EMPTY_HANDLE_TYPE);
ExtensionAttribute approverEmptyHandleTypeValueAttribute = new ExtensionAttribute(); ExtensionAttribute approverEmptyHandleTypeValueAttribute = new ExtensionAttribute();
approverEmptyHandleTypeValueAttribute.setName("value"); approverEmptyHandleTypeValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
approverEmptyHandleTypeValueAttribute.setValue(property.getApproverEmptyHandleType()); approverEmptyHandleTypeValueAttribute.setValue(property.getApproverEmptyHandleType());
approverEmptyHandleTypeElement.addAttribute(approverEmptyHandleTypeValueAttribute); approverEmptyHandleTypeElement.addAttribute(approverEmptyHandleTypeValueAttribute);
ExtensionAttribute approverEmptyHandleTypeDescAttribute = new ExtensionAttribute(); ExtensionAttribute approverEmptyHandleTypeDescAttribute = new ExtensionAttribute();
approverEmptyHandleTypeDescAttribute.setName("desc"); approverEmptyHandleTypeDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
approverEmptyHandleTypeDescAttribute.setValue("审批人为空时"); approverEmptyHandleTypeDescAttribute.setValue("审批人为空时");
approverEmptyHandleTypeElement.addAttribute(approverEmptyHandleTypeDescAttribute); approverEmptyHandleTypeElement.addAttribute(approverEmptyHandleTypeDescAttribute);
userTask.addExtensionElement(approverEmptyHandleTypeElement); userTask.addExtensionElement(approverEmptyHandleTypeElement);

View File

@ -16,11 +16,12 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_COMPLETED; import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_COMPLETED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_STARTED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED; import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED;
import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION; import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION;
/** /**
* 任务节点完成事件(枢智使用) * 活动节点完成事件
* *
* @author wangli * @author wangli
* @since 2023/7/24 17:36 * @since 2023/7/24 17:36
@ -34,7 +35,8 @@ public class EngineActivityEventListener extends AbstractFlowableEventListener {
@Override @Override
public Collection<? extends FlowableEventType> getTypes() { public Collection<? extends FlowableEventType> getTypes() {
return Lists.newArrayList(ACTIVITY_COMPLETED, return Lists.newArrayList(ACTIVITY_STARTED,
ACTIVITY_COMPLETED,
MULTI_INSTANCE_ACTIVITY_COMPLETED, MULTI_INSTANCE_ACTIVITY_COMPLETED,
MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION); MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION);
} }

View File

@ -6,6 +6,7 @@ import cn.axzo.workflow.core.deletage.BpmnTaskCalculateDTO;
import cn.axzo.workflow.core.deletage.BpmnTaskDelegate; import cn.axzo.workflow.core.deletage.BpmnTaskDelegate;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.ExtensionElement;
import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask; import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RepositoryService; import org.flowable.engine.RepositoryService;
@ -19,8 +20,13 @@ import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_ALLOW_SKIP_USER_TASK; import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_ALLOW_SKIP_USER_TASK;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVAL_METHOD;
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_121;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
@ -42,12 +48,22 @@ public class EngineExecutionStartListener implements ExecutionListener {
public void notify(DelegateExecution execution) { public void notify(DelegateExecution execution) {
log.info("execution Start: {}", JSON.toJSONString(execution)); log.info("execution Start: {}", JSON.toJSONString(execution));
String currentActivityId = execution.getCurrentActivityId(); String currentActivityId = execution.getCurrentActivityId();
String variable = INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO + currentActivityId; String assigneeListVariableName = INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO + currentActivityId;
List usersValue = (List) execution.getVariable(variable); List<String> assigneeList = (List<String>) execution.getVariable(assigneeListVariableName);
if (CollectionUtils.isEmpty(usersValue)) { if (!CollectionUtils.isEmpty(assigneeList)) {
Process mainProcess = repositoryService.getBpmnModel(execution.getProcessDefinitionId()).getMainProcess(); return;
UserTask userTask = (UserTask) mainProcess.getFlowElement(currentActivityId); }
Process mainProcess = repositoryService.getBpmnModel(execution.getProcessDefinitionId()).getMainProcess();
UserTask userTask = (UserTask) mainProcess.getFlowElement(currentActivityId);
String flowServerVersion = mainProcess.getAttributeValue(null, FLOW_SERVER_VERSION);
if (Objects.equals(FLOW_SERVER_VERSION_121, flowServerVersion)) {
Map<String, List<ExtensionElement>> extensionElements = userTask.getExtensionElements();
extensionElements.get(CONFIG_APPROVAL_METHOD);
} else {
// 枢智版本的逻辑
BpmnTaskCalculateDTO calculateDTO = new BpmnTaskCalculateDTO(); BpmnTaskCalculateDTO calculateDTO = new BpmnTaskCalculateDTO();
calculateDTO.setTaskId(userTask.getId()); calculateDTO.setTaskId(userTask.getId());
calculateDTO.setCategory(userTask.getCategory()); calculateDTO.setCategory(userTask.getCategory());
@ -76,16 +92,12 @@ public class EngineExecutionStartListener implements ExecutionListener {
// UserTask 非多实例 // UserTask 非多实例
if (!userTask.hasMultiInstanceLoopCharacteristics()) { if (!userTask.hasMultiInstanceLoopCharacteristics()) {
//TODO by zuoqinbo assigneeIdList.size==0情况
if (!CollectionUtils.isEmpty(assigneeIdList)) { if (!CollectionUtils.isEmpty(assigneeIdList)) {
userTask.setAssignee(assigneeIdList.get(0)); userTask.setAssignee(assigneeIdList.get(0));
} }
// remove by wangli, 暂时去除审批人变量, 通过上面直接赋值
// execution.setVariable("assigneeUserId", assigneeIdList.get(0));
} else { } else {
// UserTask 多实例, 该变量用于引擎 // UserTask 多实例, 该变量用于引擎
execution.setVariable(variable, assigneeIdList); execution.setVariable(assigneeListVariableName, assigneeIdList);
} }
// 将当次审批节点下计算出来的人存储起来,方便后续对 task 保持审批人快照 // 将当次审批节点下计算出来的人存储起来,方便后续对 task 保持审批人快照
execution.setVariableLocal(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId, execution.setVariableLocal(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId,

View File

@ -1,12 +1,14 @@
package cn.axzo.workflow.server.controller.listener; package cn.axzo.workflow.server.controller.listener.activiti;
import cn.axzo.workflow.core.listener.BpmnActivityEventListener; import cn.axzo.workflow.core.listener.BpmnActivityEventListener;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.event.FlowableEvent; import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl; import org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
/** /**
* 自定义实现的流程监听器, 实现了 Ordered 接口 * 自定义实现的活动节点监听器, 实现了 Ordered 接口
* *
* 注意:Order 值越小,优先级越高 * 注意:Order 值越小,优先级越高
* *
@ -14,8 +16,8 @@ import org.flowable.engine.delegate.event.impl.FlowableActivityEventImpl;
* @since 2023/7/24 17:33 * @since 2023/7/24 17:33
*/ */
@Slf4j @Slf4j
//@Component @Component
public class CustomBpmActivityEventListener implements BpmnActivityEventListener { public class CustomBpmActivityEventListener implements BpmnActivityEventListener, Ordered {
@Override @Override
public void onEvent(FlowableEvent event) { public void onEvent(FlowableEvent event) {

View File

@ -1,179 +0,0 @@
{
"entity":{
"active":true,
"businessKey":"custom_business_key",
"concurrent":false,
"countEnabled":true,
"deadLetterJobCount":0,
"deleted":false,
"deploymentId":"d1b73ff5-5b46-11ee-8bb7-82ab12666657",
"ended":false,
"eventScope":false,
"eventSubscriptionCount":0,
"eventSubscriptions":[ ],
"executions":[ ],
"externalWorkerJobCount":0,
"id":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"idPrefix":"PRC-",
"identityLinkCount":0,
"identityLinks":[
{
"deleted":false,
"group":false,
"id":"b79b95fd-5b67-11ee-b32a-a2d9caa60032",
"idPrefix":"IDL-",
"inserted":true,
"originalPersistentState":{ },
"persistentState":{
"processInstanceId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"type":"starter",
"userId":"66647"
},
"processInstanceId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"type":"starter",
"updated":false,
"user":true,
"userId":"66647"
}
],
"inserted":true,
"isActive":true,
"isConcurrent":false,
"isCountEnabled":true,
"isEventScope":false,
"isMultiInstanceRoot":false,
"isScope":true,
"jobCount":0,
"multiInstanceRoot":false,
"name":"auth_point_instance",
"originalPersistentState":{ },
"persistentState":{
"suspensionState":1,
"isEventScope":false,
"isActive":true,
"startUserId":"66647",
"startActivityId":"NODE1639041346796_0.5413743892974803_0",
"variableCount":0,
"rootProcessInstanceId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"startTime":1695621151522,
"suspendedJobCount":0,
"processDefinitionId":"auth_point:1:d1e1f978-5b46-11ee-8bb7-82ab12666657",
"isScope":true,
"isConcurrent":false,
"isMultiInstanceRoot":false,
"timerJobCount":0,
"taskCount":0,
"eventSubscriptionCount":0,
"externalWorkerJobCount":0,
"businessKey":"custom_business_key",
"name":"auth_point_instance",
"isCountEnabled":true,
"identityLinkCount":0,
"jobCount":0,
"deadLetterJobCount":0
},
"processDefinitionId":"auth_point:1:d1e1f978-5b46-11ee-8bb7-82ab12666657",
"processDefinitionKey":"auth_point",
"processDefinitionName":"权限点发布",
"processDefinitionVersion":1,
"processInstance":{
"$ref":"@"
},
"processInstanceBusinessKey":"custom_business_key",
"processInstanceId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"processInstanceType":true,
"processVariables":{
"applyUserId":"66647"
},
"queryVariables":[ ],
"revision":1,
"revisionNext":2,
"rootProcessInstance":{
"$ref":"@"
},
"rootProcessInstanceId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"scope":true,
"startActivityId":"NODE1639041346796_0.5413743892974803_0",
"startTime":1695621151522,
"startUserId":"66647",
"suspended":false,
"suspendedJobCount":0,
"suspensionState":1,
"taskCount":0,
"tenantId":"926",
"timerJobCount":0,
"transientVariables":{ },
"transientVariablesLocal":{ },
"updated":false,
"usedVariablesCache":{ },
"variableCount":0,
"variableInstanceEntities":{
"applyUserId":{
"byteArrayRef":{
"deleted":false
},
"cachedValue":"66647",
"deleted":false,
"executionId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"id":"b79b20cb-5b67-11ee-b32a-a2d9caa60032",
"idPrefix":"VAR-",
"inserted":true,
"name":"applyUserId",
"originalPersistentState":{ },
"persistentState":{
"executionId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"textValue":"66647",
"name":"applyUserId",
"typeName":"string"
},
"processDefinitionId":"auth_point:1:d1e1f978-5b46-11ee-8bb7-82ab12666657",
"processInstanceId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"readOnly":false,
"revision":0,
"revisionNext":1,
"textValue":"66647",
"type":{
"cachable":true,
"readOnly":false,
"typeName":"string"
},
"typeName":"string",
"updated":false,
"value":"66647"
}
},
"variableInstances":{
"applyUserId":{
"$ref":"$.entity.variableInstanceEntities.applyUserId"
}
},
"variableInstancesLocal":{
"applyUserId":{
"$ref":"$.entity.variableInstanceEntities.applyUserId"
}
},
"variableNames":[
"applyUserId"
],
"variableNamesLocal":[
"applyUserId"
],
"variables":{
"applyUserId":"66647"
},
"variablesLocal":{
"applyUserId":"66647"
}
},
"execution":{
"$ref":"$.entity"
},
"executionId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"processDefinitionId":"auth_point:1:d1e1f978-5b46-11ee-8bb7-82ab12666657",
"processInstanceId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"scopeDefinitionId":"auth_point:1:d1e1f978-5b46-11ee-8bb7-82ab12666657",
"scopeId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"scopeType":"bpmn",
"subScopeId":"b79b20ca-5b67-11ee-b32a-a2d9caa60032",
"type":"PROCESS_CREATED"
}

View File

@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.delegate.event.FlowableCancelledEvent;
import org.flowable.engine.delegate.event.FlowableProcessStartedEvent; import org.flowable.engine.delegate.event.FlowableProcessStartedEvent;
import org.springframework.core.Ordered;
/** /**
* 自定义实现的流程监听器, 实现了 Ordered 接口 * 自定义实现的流程监听器, 实现了 Ordered 接口
@ -17,7 +18,7 @@ import org.flowable.engine.delegate.event.FlowableProcessStartedEvent;
*/ */
@Slf4j @Slf4j
//@Component //@Component
public class CustomBpmnProcessEventListener implements BpmnProcessEventListener { public class CustomBpmnProcessEventListener implements BpmnProcessEventListener, Ordered {
@Override @Override
public void onCreated(FlowableEngineEntityEvent event) { public void onCreated(FlowableEngineEntityEvent event) {
log.info("Process onCreated: ClassName: {}, event: {}", event.getClass().getName(), JSON.toJSONString(event)); log.info("Process onCreated: ClassName: {}, event: {}", event.getClass().getName(), JSON.toJSONString(event));

View File

@ -15,6 +15,7 @@ import org.flowable.engine.delegate.event.FlowableProcessStartedEvent;
import org.flowable.engine.delegate.event.impl.FlowableProcessCancelledEventImpl; import org.flowable.engine.delegate.event.impl.FlowableProcessCancelledEventImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.Deployment;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -35,7 +36,7 @@ import static cn.axzo.workflow.common.enums.ProcessInstanceEventEnum.PROCESS_INS
*/ */
@Slf4j @Slf4j
@Component @Component
public class RocketMqBpmnProcessEventListener implements BpmnProcessEventListener { public class RocketMqBpmnProcessEventListener implements BpmnProcessEventListener, Ordered {
@Resource @Resource
private EventProducer<?> eventProducer; private EventProducer<?> eventProducer;

View File

@ -12,6 +12,7 @@ import org.flowable.engine.RuntimeService;
import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.Deployment;
import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.service.delegate.DelegateTask; import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -32,7 +33,7 @@ import static cn.axzo.workflow.common.enums.ProcessTaskEventEnum.PROCESS_TASK_DE
*/ */
@Slf4j @Slf4j
@Component @Component
public class RocketMqBpmnTaskEventListener implements BpmnTaskEventListener { public class RocketMqBpmnTaskEventListener implements BpmnTaskEventListener, Ordered {
@Resource @Resource
private EventProducer<?> eventProducer; private EventProducer<?> eventProducer;

View File

@ -4,6 +4,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.listener.BpmnTaskEventListener; import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.flowable.task.service.delegate.DelegateTask; import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -23,7 +24,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELAT
*/ */
@Slf4j @Slf4j
@Component @Component
public class SnapshotBpmnTaskTaskEventListener implements BpmnTaskEventListener { public class SnapshotBpmnTaskTaskEventListener implements BpmnTaskEventListener, Ordered {
@Override @Override
public void onAssigned(DelegateTask delegateTask) { public void onAssigned(DelegateTask delegateTask) {

View File

@ -4,9 +4,13 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.listener.BpmnTaskEventListener; import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService; import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService; import org.flowable.engine.TaskService;
import org.flowable.task.service.delegate.DelegateTask; import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -25,10 +29,11 @@ import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
@Slf4j @Slf4j
@Component @Component
@AllArgsConstructor @AllArgsConstructor
public class StartNodeAutoCompleteEventListener implements BpmnTaskEventListener { public class StartNodeAutoCompleteEventListener implements BpmnTaskEventListener, Ordered {
private final TaskService taskService; private final TaskService taskService;
private final RuntimeService runtimeService; private final RuntimeService runtimeService;
private final RepositoryService repositoryService;
@Override @Override
public int getOrder() { public int getOrder() {
@ -37,6 +42,9 @@ public class StartNodeAutoCompleteEventListener implements BpmnTaskEventListener
@Override @Override
public void onCreated(DelegateTask delegateTask) { public void onCreated(DelegateTask delegateTask) {
Process mainProcess = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId()).getMainProcess();
UserTask userTask = (UserTask) mainProcess.getFlowElement(delegateTask.getTaskDefinitionKey());
if (Objects.equals(NODE_STARTER.getType(), delegateTask.getTaskDefinitionKey()) if (Objects.equals(NODE_STARTER.getType(), delegateTask.getTaskDefinitionKey())
&& !StringUtils.hasLength(delegateTask.getAssignee())) { && !StringUtils.hasLength(delegateTask.getAssignee())) {
BpmnTaskDelegateAssigner initiator = delegateTask.getVariable(INTERNAL_INITIATOR, BpmnTaskDelegateAssigner initiator = delegateTask.getVariable(INTERNAL_INITIATOR,

View File

@ -1,5 +0,0 @@
### 本包下的监听器执行顺序
1. SnapshotBpmTaskTaskEventListener `(Integer.MIN_VALUE)`
2. RocketMqBpmTaskEventListener `(Integer.MIN_VALUE+1)`
3. StartNodeAutoCompleteEventListener `(Integer.MIN_VALUE+2)`

View File

@ -1,7 +1,12 @@
package cn.axzo.workflow.server.controller.web.bpmn; package cn.axzo.workflow.server.controller.web.bpmn;
import cn.axzo.workflow.client.feign.bpmn.ProcessTaskApi; import cn.axzo.workflow.client.feign.bpmn.ProcessTaskApi;
import cn.axzo.workflow.common.model.request.bpmn.task.*; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAssigneeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult; import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO; import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO; import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
@ -145,7 +150,7 @@ public class BpmnTaskController implements ProcessTaskApi {
public CommonResponse<List<BpmnHistoricTaskInstanceVO>> getTaskListFlatByProcessInstanceId( public CommonResponse<List<BpmnHistoricTaskInstanceVO>> getTaskListFlatByProcessInstanceId(
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
@Nullable @RequestParam(required = false) String tenantId) { @Nullable @RequestParam(required = false) String tenantId) {
log.info("获取历史已审批的列表详情 getTaskListByProcessInstanceId===>>>参数:{}", processInstanceId); log.info("获取历史已审批的列表详情 getTaskListFlatByProcessInstanceId===>>>参数:{}", processInstanceId);
return success(bpmnTaskService.getHistoricTaskListByProcessInstanceId(processInstanceId, tenantId)); return success(bpmnTaskService.getHistoricTaskListByProcessInstanceId(processInstanceId, tenantId));
} }
@ -159,7 +164,7 @@ public class BpmnTaskController implements ProcessTaskApi {
public CommonResponse<List<BpmnHistoricTaskInstanceGroupVO>> getTaskListGroupByProcessInstanceId( public CommonResponse<List<BpmnHistoricTaskInstanceGroupVO>> getTaskListGroupByProcessInstanceId(
@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
@Nullable @RequestParam(required = false) String tenantId) { @Nullable @RequestParam(required = false) String tenantId) {
log.info("获取历史已审批的列表详情 getTaskListByProcessInstanceId===>>>参数:{}", processInstanceId); log.info("获取历史已审批的列表详情 getTaskListGroupByProcessInstanceId===>>>参数:{}", processInstanceId);
return success(bpmnTaskService.getHistoricTaskListGroupByProcessInstanceId(processInstanceId, tenantId)); return success(bpmnTaskService.getHistoricTaskListGroupByProcessInstanceId(processInstanceId, tenantId));
} }

View File

@ -57,41 +57,49 @@
"buttonConf": { "buttonConf": {
"initiator": [ "initiator": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -99,41 +107,49 @@
], ],
"carbonCopy": [ "carbonCopy": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -141,41 +157,49 @@
], ],
"history": [ "history": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -183,41 +207,49 @@
], ],
"current": [ "current": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -314,41 +346,49 @@
"buttonPermission": { "buttonPermission": {
"initiator": [ "initiator": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -356,41 +396,49 @@
], ],
"carbonCopy": [ "carbonCopy": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -398,41 +446,49 @@
], ],
"history": [ "history": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -440,41 +496,49 @@
], ],
"current": [ "current": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -611,41 +675,49 @@
"buttonPermission": { "buttonPermission": {
"initiator": [ "initiator": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -653,41 +725,49 @@
], ],
"carbonCopy": [ "carbonCopy": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -695,41 +775,49 @@
], ],
"history": [ "history": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true
@ -737,41 +825,49 @@
], ],
"current": [ "current": [
{ {
"order": 1,
"btnKey": "BPMN_APPROVE", "btnKey": "BPMN_APPROVE",
"enabled": true, "enabled": true,
"btnName": "同意" "btnName": "同意"
}, },
{ {
"order": 2,
"btnKey": "BPMN_REJECT", "btnKey": "BPMN_REJECT",
"btnName": "拒绝", "btnName": "拒绝",
"enabled": true "enabled": true
}, },
{ {
"order": 3,
"btnKey": "BPMN_REVOCATION", "btnKey": "BPMN_REVOCATION",
"btnName": "撤回", "btnName": "撤回",
"enabled": true "enabled": true
}, },
{ {
"order": 4,
"btnKey": "BPMN_FORWARD", "btnKey": "BPMN_FORWARD",
"btnName": "转交", "btnName": "转交",
"enabled": true "enabled": true
}, },
{ {
"order": 5,
"btnKey": "BPMN_COUNTERSIGN", "btnKey": "BPMN_COUNTERSIGN",
"btnName": "加签", "btnName": "加签",
"enabled": true "enabled": true
}, },
{ {
"order": 6,
"btnKey": "BPMN_COMMENT", "btnKey": "BPMN_COMMENT",
"btnName": "评论", "btnName": "评论",
"enabled": true "enabled": true
}, },
{ {
"order": 7,
"btnKey": "BPMN_ROLLBACK", "btnKey": "BPMN_ROLLBACK",
"btnName": "回退", "btnName": "回退",
"enabled": true "enabled": true
}, },
{ {
"order": 8,
"btnKey": "BPMN_COPY", "btnKey": "BPMN_COPY",
"btnName": "抄送", "btnName": "抄送",
"enabled": true "enabled": true