声明:此处activiti版本为6.0
此文章介绍后端自定义属性解析,前端添加自定义属性方法连接:activiti自定义属性(一)_ruoyi activiti自定义标题-CSDN博客
1、涉及到的类如下:
简介:DefaultXmlParser :xml自定义属性解析类 :实现解析指定节点下扩展字段xml节点
CustomBpmnJsonConverter:用于转换BPMN与JSON供activiti解析界面属性并应用,在ActivitiConfig中引入使用
CustomBpmnXmlConverter:用于xml与BPMN转换
CustomUserTaskJsonConverter:用户节点自定义扩展属性解析(xml与json互转)
CustomUserTaskXmlConverter:用户节点自定义扩展属性解析xml
ActivitiConfig:springboot整合activiti配置类
代码如下:
DefaultXmlParser :
import org.activiti.bpmn.converter.child.BaseChildElementParser;
import org.activiti.bpmn.model.*;import javax.xml.stream.XMLStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** xml自定义属性解析类 :实现解析指定节点下扩展字段xml节点**/
public class DefaultXmlParser extends BaseChildElementParser {//元素名称private String elementName;public DefaultXmlParser() {}public DefaultXmlParser(String elementName) {this.elementName = elementName;}public String getElementName() {return elementName;}/*** 解析指定节点下扩展字段xml节点* @param xtr xml字节流读取器* @param parentElement 父节点对象* @param model 流程图模型对象* @throws Exception*/public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model) throws Exception {Map<String, List<ExtensionElement>> map = parentElement.getExtensionElements();List<ExtensionElement> extensionElementList = new ArrayList<>();ExtensionElement extensionElement = new ExtensionElement();extensionElement.setName(getElementName());extensionElement.setElementText(xtr.getElementText());extensionElement.setNamespacePrefix("activiti");extensionElement.setNamespace("http://activiti.org/bpmn");extensionElementList.add(extensionElement);map.put(getElementName(), extensionElementList);}
}
CustomBpmnJsonConverter:
import org.activiti.bpmn.model.BaseElement;
import org.activiti.editor.language.json.converter.BaseBpmnJsonConverter;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;import java.util.Map;/*** 自定义bpmn解析,用于转换BPMN与JSON供activiti解析界面属性并应用**/
public class CustomBpmnJsonConverter extends BpmnJsonConverter {/*** 获取bpmn组件解析map* @return*/public static Map<String,Class<? extends BaseBpmnJsonConverter>> getConvertersToBpmnMap(){return convertersToBpmnMap;}/*** 获取bpmn组件解析map* @return*/public static Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> getConvertersToJsonMap(){return convertersToJsonMap;}}
CustomBpmnXmlConverter:
import org.activiti.bpmn.converter.BpmnXMLConverter;/*** 自定义bpmn解析,用于xml转换成BPMN**/
public class CustomBpmnXmlConverter extends BpmnXMLConverter {static {// 添加自定义用户节点xml解析器addConverter(new CustomUserTaskXmlConverter());}
}
CustomUserTaskJsonConverter:用户节点自定义扩展属性解析(xml与json互转)
用到的常量为自定义属性名
import com.self.common.constant.activiti.ActivitiNodeConstant;
import com.self.common.utils.StringUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.bpmn.model.*;
import org.activiti.editor.language.json.converter.BaseBpmnJsonConverter;
import org.activiti.editor.language.json.converter.UserTaskJsonConverter;import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** 用户节点自定义扩展属性解析(xml与json互转)*/
public class CustomUserTaskJsonConverter extends UserTaskJsonConverter {/*** xml => json* 将 xml格式的模型数据解析出来放入到节点的json自定义扩展属性中** @param propertiesNode* @param baseElement*/@Overrideprotected void convertElementToJson(ObjectNode propertiesNode, BaseElement baseElement) {super.convertElementToJson(propertiesNode, baseElement);//获取扩展属性并进行设置UserTask userTask = (UserTask) baseElement;Map<String, List<ExtensionElement>> map = userTask.getExtensionElements();for(String key : map.keySet()){List<ExtensionElement> extensionElementList = map.get(key);if (extensionElementList != null && extensionElementList.size() > 0) {propertiesNode.put(extensionElementList.get(0).getName(), extensionElementList.get(0).getElementText());}}}/*** json => xml* 将 json格式的模型数据解析出来放入到节点的自定义扩展属性中** @param elementNode* @param modelNode* @param shapeMap* @return*/@Overrideprotected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode, Map<String, JsonNode> shapeMap) {FlowElement flowElement = super.convertJsonToElement(elementNode, modelNode, shapeMap);//解析UserTask userTask = (UserTask) flowElement;List<CustomProperty> cpList = new ArrayList<>();//是否为并行节点,常量为自定义属性名handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_PARALLEL);//是否可以AA跳handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK);//节点审批人为空是否跳过handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_APPROVAL_NULL_SKIP_TASK);//跳过节点时意见handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK_OPINION);//是否可以修改表单handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_ACTMODIFY_FROM);//附件是否必填handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_FILE_REQUIRED);//是否可以查看流转记录handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_RECORD);//是否可配置审批记录查看权限handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_RECORD_PERMISSIONS);//抄送用户handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_CC_USERS);//是否显示流程图handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_PNG);userTask.setCustomProperties(cpList);return userTask;}public static void fillTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {fillJsonTypes(convertersToBpmnMap);fillBpmnTypes(convertersToJsonMap);}public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {convertersToBpmnMap.put(STENCIL_TASK_USER, CustomUserTaskJsonConverter.class);}public static void fillBpmnTypes(Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {convertersToJsonMap.put(UserTask.class, CustomUserTaskJsonConverter.class);}/*** 处理自定义属性** @param cpList 自定义属性列表* @param elementNode 任务节点* @param key 自定义属性key*/private void handleCustomProperties(List<CustomProperty> cpList, JsonNode elementNode, String key) {String value = getPropertyValueAsString(key, elementNode);if (StringUtils.isNotBlank(value)) {CustomProperty cp = new CustomProperty();cp.setName(key);cp.setSimpleValue(value);cpList.add(cp);}}}
CustomUserTaskXmlConverter:用户节点自定义扩展属性解析xml
用到的常量为自定义属性名
import com.self.activiti.config.extension.DefaultXmlParser;
import com.self.common.constant.activiti.ActivitiNodeConstant;
import org.activiti.bpmn.converter.UserTaskXMLConverter;/*** 用户节点自定义扩展属性解析xml*/
public class CustomUserTaskXmlConverter extends UserTaskXMLConverter {public CustomUserTaskXmlConverter() {super();//是否为并行节点childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_PARALLEL, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_PARALLEL));//是否可以AA跳childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK));//节点审批人为空是否跳过childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_APPROVAL_NULL_SKIP_TASK, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_APPROVAL_NULL_SKIP_TASK));//跳过节点时意见childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK_OPINION, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK_OPINION));//是否可以修改表单childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACTMODIFY_FROM, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACTMODIFY_FROM));//附件是否必填childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_FILE_REQUIRED, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_FILE_REQUIRED));//是否可以查看流转记录childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_RECORD, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_RECORD));//是否可配置审批记录查看权限childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_RECORD_PERMISSIONS, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_RECORD_PERMISSIONS));//抄送用户childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_CC_USERS, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_CC_USERS));//是否显示流程图childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_PNG, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_PNG));}
}
ActivitiConfig:
重点在于下面这句:
import com.self.activiti.id.MyIdGenerator;
import org.activiti.engine.*;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;/*** acitiviti配置类*/
@Configuration
public class ActivitiConfig {@Autowiredprivate DataSource dataSource;@Autowiredprivate PlatformTransactionManager transactionManager;//流程配置,与spring整合采用SpringProcessEngineConfiguration这个实现@Beanpublic SpringProcessEngineConfiguration processEngineConfiguration(){SpringProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration();processEngineConfiguration.setDataSource(dataSource);processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_TRUE);processEngineConfiguration.setDatabaseType(ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL);processEngineConfiguration.setIdGenerator(new MyIdGenerator());processEngineConfiguration.setTransactionManager(transactionManager);processEngineConfiguration.setJobManager(new MyJobManager());//自定义任务管理// 将自定义用户任务组件bpmn解析替换activiti中用户任务组件默认解析CustomUserTaskJsonConverter.fillTypes(CustomBpmnJsonConverter.getConvertersToBpmnMap(), CustomBpmnJsonConverter.getConvertersToJsonMap());// processEngineConfiguration.setJobExecutorActivate(true);//JobExecutor是管理几个线程计时器的组成部分,JobExecutor对多线程的处理较为笨重缓慢
// processEngineConfiguration.setAsyncExecutorEnabled(true);//定义为true,使用AsyncExecutor代替默认的JobExecutor;processEngineConfiguration.setAsyncExecutorActivate(true);//定义为true,工作流引擎在启动时就建立启动AsyncExecutor线程//流程图字体processEngineConfiguration.setActivityFontName("宋体");processEngineConfiguration.setAnnotationFontName("宋体");processEngineConfiguration.setLabelFontName("宋体");return processEngineConfiguration;}//流程引擎,与spring整合使用factoryBean@Beanpublic ProcessEngineFactoryBean processEngine(ProcessEngineConfiguration processEngineConfiguration){ProcessEngineFactoryBean processEngineFactoryBean = new ProcessEngineFactoryBean();processEngineFactoryBean.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);((ProcessEngineConfigurationImpl) processEngineConfiguration).setIdGenerator(new MyIdGenerator());return processEngineFactoryBean;}//八大接口@Beanpublic RepositoryService repositoryService(ProcessEngine processEngine){return processEngine.getRepositoryService();}@Beanpublic RuntimeService runtimeService(ProcessEngine processEngine){return processEngine.getRuntimeService();}@Beanpublic TaskService taskService(ProcessEngine processEngine){return processEngine.getTaskService();}@Beanpublic HistoryService historyService(ProcessEngine processEngine){return processEngine.getHistoryService();}@Beanpublic FormService formService(ProcessEngine processEngine){return processEngine.getFormService();}@Beanpublic IdentityService identityService(ProcessEngine processEngine){return processEngine.getIdentityService();}@Beanpublic ManagementService managementService(ProcessEngine processEngine){return processEngine.getManagementService();}@Beanpublic DynamicBpmnService dynamicBpmnService(ProcessEngine processEngine){return processEngine.getDynamicBpmnService();}}
ActivitiNodeConstant:常量表
/*** activiti节点类型常量表**/
public class ActivitiNodeConstant {//会签节点名称后缀public static final String NODE_NAME_COUNTERSIGN_SUFFIX = "-会签";//流程节点类型 -- 互斥网关public static final String NODE_NAME_EXCLUSIVE_GATEWAY = "exclusiveGateway";//流程节点类型 -- 并行网关public static final String NODE_NAME_PARALLEL_GATEWAY = "parallelGateway";//流程节点类型 -- 包容网关public static final String NODE_NAME_INCLUSIVE_GATEWAY = "inclusiveGateway";//流程节点类型 -- 开始事件public static final String NODE_NAME_START_EVENT = "startEvent";//流程节点类型 -- 结束事件public static final String NODE_NAME_END_EVENT = "endEvent";//流程节点类型 -- 边界事件public static final String NODE_NAME_BOUNDARY_EVENT = "boundaryEvent";//流程节点类型 -- 用户任务public static final String NODE_NAME_USER_TASK = "userTask";//流程节点类型 -- 服务任务public static final String NODE_NAME_SERVICE_TASK = "serviceTask";//节点自定义属性 -- 是否为并行节点public static final String CUSTOM_PROPERTIES_PARALLEL = "isparallel";//节点自定义属性 -- 是否可以AA跳public static final String CUSTOM_PROPERTIES_SKIP_TASK = "skiptask";//节点自定义属性 -- 节点审批人为空是否跳过public static final String CUSTOM_PROPERTIES_APPROVAL_NULL_SKIP_TASK = "approvalnullskiptask";//节点自定义属性 -- 跳过节点时意见public static final String CUSTOM_PROPERTIES_SKIP_TASK_OPINION = "skiptaskopinion";//节点自定义属性 -- 是否可以修改表单public static final String CUSTOM_PROPERTIES_ACTMODIFY_FROM = "actmodifyfrom";//节点自定义属性 -- 附件是否必填public static final String CUSTOM_PROPERTIES_FILE_REQUIRED = "filerequired";//节点自定义属性 -- 是否可以查看流转记录public static final String CUSTOM_PROPERTIES_ACT_APPROVAL_RECORD = "actapprovalrecord";//节点自定义属性 -- 是否可配置审批记录查看权限public static final String CUSTOM_PROPERTIES_ACT_RECORD_PERMISSIONS = "actrecordpermissions";//节点自定义属性 -- 抄送用户public static final String CUSTOM_PROPERTIES_CC_USERS = "ccusers";//节点自定义属性 -- 是否显示流程图public static final String CUSTOM_PROPERTIES_ACT_APPROVAL_PNG = "actapprovalpng";}
使用方法:
1、读取xml文件,转为bpmnModel
private BpmnModel inputStream2Xml(InputStream inputStream) throws Exception {//读取xml文件XMLInputFactory factory = XMLInputFactory.newInstance();XMLStreamReader reader = factory.createXMLStreamReader(new InputStreamReader(inputStream, "UTF-8"));BpmnModel bpmnModel = new CustomBpmnXmlConverter().convertToBpmnModel(reader);// bpmnModel转jsonBpmnJsonConverter converter = new BpmnJsonConverter();converter.convertToJson(bpmnModel);return bpmnModel;}