在工作中,有些工作需求flow able自带的节点属性并不能满足,就需要添加一些自定义的节点属性
对于上面就是实际项目中的效果,那么如何做呢?
1、修改bpmnjson的数据
{
"name": "nodetypepackage",
"properties": [
{
"id": "nodetype",
"type": "dragon-nodetype-combobox",
"title": "节点类型",
"value": "",
"description": "节点类型",
"popular": true,
"items": [
{
"key": "协同",
"value": "coordination"
},
{
"key": "评审",
"value": "review"
},
{
"key": "普通",
"value": ""
}
]
}
]
}
2、把我们定义的package放入任务节点中去
{
"type" : "node",
"id" : "UserTask",
"title" : "\u7528\u6237\u4efb\u52a1",
"description" : "\u4efb\u52a1\u624b\u52a8\u5206\u914d\u7ed9\u4e00\u4e2a\u7279\u5b9a\u7684\u4eba",
"view" : "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:svg=\"http://www.w3.org/2000/svg\"\n xmlns:oryx=\"http://www.b3mn.org/oryx\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n\n width=\"102\"\n height=\"82\"\n version=\"1.0\">\n <defs></defs>\n <oryx:magnets>\n \t<oryx:magnet oryx:cx=\"1\" oryx:cy=\"20\" oryx:anchors=\"left\" />\n \t<oryx:magnet oryx:cx=\"1\" oryx:cy=\"40\" oryx:anchors=\"left\" />\n \t<oryx:magnet oryx:cx=\"1\" oryx:cy=\"60\" oryx:anchors=\"left\" />\n \t\n \t<oryx:magnet oryx:cx=\"25\" oryx:cy=\"79\" oryx:anchors=\"bottom\" />\n \t<oryx:magnet oryx:cx=\"50\" oryx:cy=\"79\" oryx:anchors=\"bottom\" />\n \t<oryx:magnet oryx:cx=\"75\" oryx:cy=\"79\" oryx:anchors=\"bottom\" />\n \t\n \t<oryx:magnet oryx:cx=\"99\" oryx:cy=\"20\" oryx:anchors=\"right\" />\n \t<oryx:magnet oryx:cx=\"99\" oryx:cy=\"40\" oryx:anchors=\"right\" />\n \t<oryx:magnet oryx:cx=\"99\" oryx:cy=\"60\" oryx:anchors=\"right\" />\n \t\n \t<oryx:magnet oryx:cx=\"25\" oryx:cy=\"1\" oryx:anchors=\"top\" />\n \t<oryx:magnet oryx:cx=\"50\" oryx:cy=\"1\" oryx:anchors=\"top\" />\n \t<oryx:magnet oryx:cx=\"75\" oryx:cy=\"1\" oryx:anchors=\"top\" />\n \t\n \t<oryx:magnet oryx:cx=\"50\" oryx:cy=\"40\" oryx:default=\"yes\" />\n </oryx:magnets>\n <g pointer-events=\"fill\" oryx:minimumSize=\"50 40\">\n\t<rect id=\"text_frame\" oryx:anchors=\"bottom top right left\" x=\"1\" y=\"1\" width=\"94\" height=\"79\" rx=\"10\" ry=\"10\" stroke=\"none\" stroke-width=\"0\" fill=\"none\" />\n\t<rect id=\"bg_frame\" oryx:resize=\"vertical horizontal\" x=\"0\" y=\"0\" width=\"100\" height=\"80\" rx=\"10\" ry=\"10\" stroke=\"#bbbbbb\" stroke-width=\"1\" fill=\"#f9f9f9\" />\n\t\t<text \n\t\t\tfont-size=\"12\" \n\t\t\tid=\"text_name\" \n\t\t\tx=\"50\" \n\t\t\ty=\"40\" \n\t\t\toryx:align=\"middle center\"\n\t\t\toryx:fittoelem=\"text_frame\"\n\t\t\tstroke=\"#373e48\">\n\t\t</text>\n\t\n\t<g id=\"userTask\" transform=\"translate(3,3)\">\n\t\t<path oryx:anchors=\"top left\"\n \t\tstyle=\"fill:#d1b575;stroke:none;\"\n \t\t d=\"m 1,17 16,0 0,-1.7778 -5.333332,-3.5555 0,-1.7778 c 1.244444,0 1.244444,-2.3111 1.244444,-2.3111 l 0,-3.0222 C 12.555557,0.8221 9.0000001,1.0001 9.0000001,1.0001 c 0,0 -3.5555556,-0.178 -3.9111111,3.5555 l 0,3.0222 c 0,0 0,2.3111 1.2444443,2.3111 l 0,1.7778 L 1,15.2222 1,17 17,17\" \n />\n\t\t\n\t</g>\n \n\t<g id=\"parallel\">\n\t\t<path oryx:anchors=\"bottom\" fill=\"none\" stroke=\"#bbbbbb\" d=\"M46 70 v8 M50 70 v8 M54 70 v8\" stroke-width=\"2\" />\n\t</g>\n\t\n\t<g id=\"sequential\">\n\t\t<path oryx:anchors=\"bottom\" fill=\"none\" stroke=\"#bbbbbb\" stroke-width=\"2\" d=\"M46,76h10M46,72h10 M46,68h10\"/>\n\t</g>\n\t\n\n\t<g id=\"compensation\">\n\t\t<path oryx:anchors=\"bottom\" fill=\"none\" stroke=\"#bbbbbb\" d=\"M 62 74 L 66 70 L 66 78 L 62 74 L 62 70 L 58 74 L 62 78 L 62 74\" stroke-width=\"1\" />\n\t</g>\n </g>\n</svg>",
"icon" : "activity/list/type.user.png",
"groups" : [ "\u4efb\u52a1" ],
"propertyPackages" : [ "overrideidpackage", "namepackage", "documentationpackage", "asynchronousdefinitionpackage", "exclusivedefinitionpackage", "executionlistenerspackage", "multiinstance_typepackage", "multiinstance_cardinalitypackage", "multiinstance_collectionpackage", "multiinstance_variablepackage", "multiinstance_conditionpackage", "isforcompensationpackage", "usertaskassignmentpackage", "formkeydefinitionpackage", "formreferencepackage", "duedatedefinitionpackage", "prioritydefinitionpackage", "formpropertiespackage", "tasklistenerspackage", "skipexpressionpackage","nodetypepackage","editdatapackage" ],
"hiddenPropertyPackages" : [ ],
"roles" : [ "Activity", "sequence_start", "sequence_end", "ActivitiesMorph", "all" ]
}
3、定义一个自定义userTask解析器BruceUserTaskJsonConverter
public class BruceUserTaskJsonConverter extends UserTaskJsonConverter {
public static final String IS_EDITDATA = "iseditdata";
public static final String NODE_TYPE = "nodetype";
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 setCustomTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,
Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
removeTypes(convertersToBpmnMap,convertersToJsonMap);
fillTypes(convertersToBpmnMap,convertersToJsonMap);
}
public static void removeTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,
Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
convertersToJsonMap.remove(UserTask.class);
convertersToBpmnMap.remove(StencilConstants.STENCIL_TASK_USER);
}
public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {
convertersToBpmnMap.put(STENCIL_TASK_USER, BruceUserTaskJsonConverter.class);
}
public static void fillBpmnTypes(
Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
convertersToJsonMap.put(UserTask.class, BruceUserTaskJsonConverter.class);
}
@Override
public void convertToJson(BaseElement baseElement, ActivityProcessor processor, BpmnModel model, FlowElementsContainer container, ArrayNode shapesArrayNode, double subProcessX, double subProcessY){
super.convertToJson(baseElement, processor, model, container, shapesArrayNode, subProcessX, subProcessY);
}
@Override
protected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode,
Map<String, JsonNode> shapeMap) {
UserTask flowElement = (UserTask) super.convertJsonToElement(elementNode, modelNode, shapeMap);
List<CustomProperty> customProperties = new ArrayList<>();
// 自定义属性扩展 节点可编辑
String isEditdata = getPropertyValueAsString(IS_EDITDATA, elementNode);
if (StringUtils.isNotBlank(isEditdata)) {
CustomProperty editData = this.createProperty(IS_EDITDATA, isEditdata);
customProperties.add(editData);
}
// 扩展 节点类型
String nodetype = getPropertyValueAsString(NODE_TYPE, elementNode);
if (StringUtils.isNotBlank(nodetype)) {
CustomProperty nodeType = this.createProperty(NODE_TYPE, nodetype);
customProperties.add(nodeType);
}
if (CollectionUtils.isNotEmpty(customProperties)) {
flowElement.setCustomProperties(customProperties);
}
return flowElement;
}
/**
* 创建自定义属性
*
* @param propertyName 属性名称
* @param propertyValue 属性值
*/
private CustomProperty createProperty(String propertyName, String propertyValue) {
CustomProperty customProperty = new CustomProperty();
customProperty.setId(propertyName);
customProperty.setName(propertyName);
customProperty.setSimpleValue(propertyValue);
return customProperty;
}
}
4、定义一个自定义初始化类CustomPropertyInit (注意这个类必须建在org.flowable.editor.language.json.converter下面)
public class CustomPropertyInit {
public void init() {
Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap = BpmnJsonConverter.convertersToJsonMap;
Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap = BpmnJsonConverter.convertersToBpmnMap;
//添加自定义的任务json转化器
BruceUserTaskJsonConverter.setCustomTypes(convertersToBpmnMap, convertersToJsonMap);
}
}
5、初始化CustomPropertyInit类
在flowableConfig中初始化
public void configure(SpringProcessEngineConfiguration configure) {
//配置中文
configure.setActivityFontName(activityFontName);
configure.setLabelFontName(labelFontName);
configure.setAnnotationFontName(annotationFontName);
//设置自定义的uuid生成策略
configure.setIdGenerator(new UuidGenerator());
configure.setXmlEncoding(xmlEncoding);
//全局监听
Map<String, List<FlowableEventListener>> typedListeners = this.createGlobEventListeners();
configure.setTypedEventListeners(typedListeners);
//启用任务关系计数
configure.setEnableTaskRelationshipCounts(true);
/**
* 兼容V5
*/
configure.setDatabaseSchemaUpdate("true");
configure.setFlowable5CompatibilityEnabled(true);
configure.setFlowable5CompatibilityHandlerFactory(createSpringFlowable5CompatibilityHandlerFactory());
/**
* 自定义节点属性初始化
*/
createCustomPropertyInit().init();
}
@Bean
public CustomPropertyInit createCustomPropertyInit() {
CustomPropertyInit customPropertyInit = new CustomPropertyInit();
return customPropertyInit;
}