能搜到这里,说明activity已经对你不陌生。
以前,我们公司是使用eclipse自带的插件来画流程图,后来公司用了官方提供的editor编辑器画流程图,他们有共同的点,就是太丑而且功能太多,显然如果放在我们面前一堆没用的东西,我们肯定要愤怒的删库(说说而已)!!
那怎么办呢?肯定是使用自己相中的开源流程编辑框架或是自己公司牛的一批,自己做了个前端的框架。那么问题也来了,前端返回的JSON数据格式都是不相同的,怎么才能保存到数据库并且确保可以运行呢?
这就要说到这个东东了 ------BpmnModel!!
官方提供代码如下:
Process process=new Process();
BpmnModel bm=new BpmnModel();
UserTask userTask1= new UserTask();
UserTask userTask2= new UserTask();
SequenceFlow sequenceFlow1= new SequenceFlow();
SequenceFlow sequenceFlow2= new SequenceFlow();
巴拉巴拉一堆,就是没有说关键的东西,怎么把坐标存进去?虽然官方也提供了自动布局,比如:
new BpmnAutoLayout(bpmnModel).execute();
但是这怎么能难道可爱的用户呢?用户说我画了个方块,你给我出来个不规则的图怎么行?为啥不一样?
我:卒(zu)~~
我的天啊那咋办,翻源码呗,看了好久,最终写出了自己的转换类;
敲黑板!!!
public static BpmnModel convertToBpmnModel(String json) throws XMLStreamException{
//创建json对象
JSONObject jsonData = JSONObject.fromObject(json);
String name = jsonData.getString("title");//获取titleString key = jsonData.getString("key");//获取流程key
JSONObject jsonObjectnode = jsonData.getJSONObject("nodes");//获取所有的节点信息
JSONObject jsonObjectLine = jsonData.getJSONObject("lines");//获取所有的线条信息
// JSONObject jsonObjectAreas = jsonData.getJSONObject("areas");//获取所有的area信息
//创建流程对象
Process process=new Process();
process.setName(name);
process.setId(key);
BpmnModel bm=new BpmnModel();
GraphicInfo graphicInfo = null;
//创建节点对象*/
String startNodeId="";
for (Object nodeId: jsonObjectnode.keySet()){
JSONObject jsonEntry=jsonObjectnode.getJSONObject(String.valueOf(nodeId));
String type=String.valueOf(jsonEntry.get("type")).replace("\"", "");
if("start round".equals(type)){
StartEvent startEvent= new StartEvent();
startEvent.setId(String.valueOf(nodeId));
startEvent.setName(String.valueOf(jsonEntry.get("name")).replace("\"", ""));
process.addFlowElement(startEvent);
graphicInfo = new GraphicInfo();
graphicInfo.setElement(startEvent);
startNodeId=String.valueOf(nodeId);
}else if("end round".equals(type)){
EndEvent endEvent= new EndEvent();
endEvent.setId(String.valueOf(nodeId));
endEvent.setName(String.valueOf(jsonEntry.get("name")).replace("\"", ""));
process.addFlowElement(endEvent);
graphicInfo = new GraphicInfo();
graphicInfo.setElement(endEvent);
startNodeId=String.valueOf(nodeId);
}else if("task".equals(type)){
UserTask userTask= new UserTask();
userTask.setId(String.valueOf(nodeId));
userTask.setName(String.valueOf(jsonEntry.get("name")).replace("\"", ""));
userTask.setAssignee(String.valueOf(jsonEntry.get("assignee")).replace("\"", ""));
process.addFlowElement(userTask);
graphicInfo = new GraphicInfo();
graphicInfo.setElement(userTask);
startNodeId=String.valueOf(nodeId);
}else if("node".equals(type)){
ServiceTask serviceTask= new ServiceTask();
serviceTask.setId(String.valueOf(nodeId));
serviceTask.setName(String.valueOf(jsonEntry.get("name")).replace("\"", ""));
//将java的任务放到
//固定写死调用类 因为自动任务是调用插件
serviceTask.setImplementationType("expression");
serviceTask.setImplementation("${serviceTaskNController.implementPlug(execution)}");
FieldExtension field = new FieldExtension();
field.setFieldName("plugin");
field.setStringValue(String.valueOf(jsonEntry.get("plugin")).replace("\"", ""));
serviceTask.getFieldExtensions().add(field);
process.addFlowElement(serviceTask);
graphicInfo = new GraphicInfo();
graphicInfo.setElement(serviceTask);
startNodeId=String.valueOf(nodeId);
}
//设置布局
graphicInfo.setX(Double.valueOf(String.valueOf(jsonEntry.get("left")).replace("\"", "")));
graphicInfo.setY(Double.valueOf(String.valueOf(jsonEntry.get("top")).replace("\"", "")));
graphicInfo.setWidth(Double.valueOf(String.valueOf(jsonEntry.get("width")).replace("\"", "")));
graphicInfo.setHeight(Double.valueOf(String.valueOf(jsonEntry.get("height")).replace("\"", "")));
bm.addGraphicInfo(graphicInfo.getElement().getId(),graphicInfo);
//创建箭头线对象
for (Object lineId: jsonObjectLine.keySet()) {
JSONObject jsonEntryline=jsonObjectLine.getJSONObject(String.valueOf(lineId));
if(!String.valueOf(jsonEntryline.get("from")).replace("\"", "").equals(startNodeId)){
continue;
}
SequenceFlow sequenceFlow= new SequenceFlow();
sequenceFlow.setId(String.valueOf(lineId));
sequenceFlow.setName(String.valueOf(jsonEntryline.get("name")).replace("\"", ""));
sequenceFlow.setSourceRef(String.valueOf(jsonEntryline.get("from")).replace("\"", ""));
sequenceFlow.setTargetRef(String.valueOf(jsonEntryline.get("to")).replace("\"", ""));
//sequenceFlow.setConditionExpression(String.valueOf(jsonEntryline.get("expression")).replace("\"", ""));
if(null!=jsonEntryline.get("expression")&&
!"".equals(String.valueOf(jsonEntryline.get("expression")).replace("\"", ""))){
String expression=String.valueOf(jsonEntryline.get("expression")).replace("\"", "");
sequenceFlow.setConditionExpression(expression);
}else{
if(!startNodeId.equals(sequenceFlow.getSourceRef())){
//如果用户不输入,默认状态值大于0就走下一个节点
sequenceFlow.setConditionExpression("${status==1||status==2}");
}
}
//添加线条到流程
String []fromXY=String.valueOf(jsonEntryline.get("fromXY")).replace("\"", "").split(",");
String []toXY=String.valueOf(jsonEntryline.get("toXY")).replace("\"", "").split(",");
// 定位线条坐标
List<GraphicInfo> graphicInfoForWaypoints = new ArrayList<GraphicInfo>();
//箭头开始
graphicInfo = new GraphicInfo();
graphicInfo.setElement(sequenceFlow);
graphicInfo.setX(Double.valueOf(fromXY[0]));
graphicInfo.setY(Double.valueOf(fromXY[1]));
graphicInfoForWaypoints.add(graphicInfo);
//箭头身体
graphicInfo = new GraphicInfo();
graphicInfo.setElement(sequenceFlow);
if(Double.valueOf(fromXY[0])>Double.valueOf(toXY[0])){
graphicInfo.setX(Double.valueOf(fromXY[0])-12);
}else if(Double.valueOf(toXY[0])>Double.valueOf(fromXY[0])){
graphicInfo.setX(Double.valueOf(fromXY[0])+12);
}else{
graphicInfo.setX(Double.valueOf(fromXY[0]));
}
graphicInfo.setY(Double.valueOf(fromXY[1]));
graphicInfoForWaypoints.add(graphicInfo);
//箭头身体
graphicInfo = new GraphicInfo();
graphicInfo.setElement(sequenceFlow);
if(Double.valueOf(fromXY[0])>Double.valueOf(toXY[0])){
graphicInfo.setX(Double.valueOf(fromXY[0])-12);
}else if(Double.valueOf(toXY[0])>Double.valueOf(fromXY[0])){
graphicInfo.setX(Double.valueOf(fromXY[0])+12);
}else{
graphicInfo.setX(Double.valueOf(fromXY[0]));
}
graphicInfo.setY(Double.valueOf(fromXY[1]));
graphicInfoForWaypoints.add(graphicInfo);
//箭头结束
graphicInfo = new GraphicInfo();
graphicInfo.setElement(sequenceFlow);
graphicInfo.setX(Double.valueOf(toXY[0]));
graphicInfo.setY(Double.valueOf(toXY[1]));
graphicInfoForWaypoints.add(graphicInfo);
bm.addFlowGraphicInfoList(sequenceFlow.getId(), graphicInfoForWaypoints);
process.addFlowElement(sequenceFlow);
}
}
bm.addProcess(process);
return bm;
自此功能全部完成,拿着这个bpmn各种转xml 转json 部署启动都没问题的;值得注意的是,这玩意真的挺复杂的,画出的图不是没有字就是没有线条!
没有字的问题我找到了,如果尺寸太小,字体就不会出现,字体的默认大小是10,有兴趣的可以去试试节点设置多长多宽才会显示文字;
没有线条的问题,我还真是找不到,不过我用各种流转换来转换去,最终发现添加了这个方法之后,线条也出现了,方法如下:
public static BpmnModel converterXMLToBpmn(byte[] xmlJson)throws XMLStreamException, UnsupportedEncodingException{
ByteArrayInputStream bis=new ByteArrayInputStream(xmlJson);
BpmnXMLConverter converter=new BpmnXMLConverter();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(bis);
BpmnModel bpmnModel = converter.convertToBpmnModel((XMLStreamReader) reader);
return bpmnModel;
}