针对一些开发中可能遇到的问题,进行设想和总结
写在最前
一些已经掌握的技术点分享
bpmn-js生成的xml结构
- 主要分成2大块
- bpmndi节点 是图像渲染的部分,和我们的业务逻辑关系不大
- process包含了几种节点,
1.开始 startEvent
2.线 sequenceFlow
3.任务(方块) task
4.判断节点,网关(菱形) exclusiveGateway
5.结束 endEvent
更多元素内容参考BPMN2规范内容 - 每个都包含id,name属性,name就是现实在上面的文字
- 任务,判断 节点包含 incoming,outgoing子节点
- 线 只有 起点-sourceRef,指向-targetRef 属性
- 起点只有 outgoing 节点,结束 只有 incoming 节点
incoming,outgoing,sourceRef,targetRef 都是指向一个id
我们只要通过这些数据就能记录某次操作去向何方,并且通过时间可以得知当前运行时的流程 当前执行到哪里已经过去所有的操作过程.
给一个基础的"单步操作记录实体"设计:
/// <summary>
/// 每一步操作,包括了开始和结束,进入和离开
/// </summary>
public class Operation
{
public string Id { get; set; }
/// <summary>
/// 从哪来
/// </summary>
public string From { get; set; }
/// <summary>
/// 现在在哪里
/// </summary>
public string Here { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
/// 做了啥
/// </summary>
public string Remark { get; set; }
}
- bpmn-js 有一些发布于npm的扩展包,比如
Properties Panel
大胆猜测 其实Properties Panel 无非是修改了xml的字段属性(由于是nodejs的项目,目前还没办法测试)
下面介绍一下我的解决方案和一些思路
首先,我画了一个简化安桩流程图如下
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="http://bpmn.io" exporterVersion="0.10.1">
<collaboration id="Collaboration_13mq84e">
<participant id="Participant_0g75ubx" processRef="Process_1" />
</collaboration>
<process id="Process_1" isExecutable="false">
<!--泳道-->
<laneSet>
<lane id="Lane_05t1wqa" name="经销商">
<flowNodeRef>Task_1</flowNodeRef>
<flowNodeRef>Task_1y56h2p</flowNodeRef>
<flowNodeRef>StartEvent_1</flowNodeRef>
</lane>
<lane id="Lane_1vbqiw2" name="服务商">
<flowNodeRef>Task_1ubxr83</flowNodeRef>
<flowNodeRef>ExclusiveGateway_01todg7</flowNodeRef>
<flowNodeRef>Task_0cxcj51</flowNodeRef>
<flowNodeRef>IntermediateThrowEvent_0pknvty</flowNodeRef>
</lane>
</laneSet>
<!--/泳道-->
<!--开始-->
<startEvent id="StartEvent_1" name="开始">
<outgoing>SequenceFlow_1</outgoing>
</startEvent>
<!--/开始-->
<sequenceFlow id="SequenceFlow_1" name="" sourceRef="StartEvent_1" targetRef="Task_1" />
<task id="Task_1" name="收集信息并创建工单">
<incoming>SequenceFlow_1</incoming>
<outgoing>SequenceFlow_13cmz0x</outgoing>
</task>
<sequenceFlow id="SequenceFlow_13cmz0x" sourceRef="Task_1" targetRef="Task_1y56h2p" />
<task id="Task_1y56h2p" name="选择服务商">
<incoming>SequenceFlow_13cmz0x</incoming>
<incoming>SequenceFlow_0pfete3</incoming>
<outgoing>SequenceFlow_00i63bm</outgoing>
</task>
<task id="Task_1ubxr83" name="签收">
<incoming>SequenceFlow_00i63bm</incoming>
<outgoing>SequenceFlow_1v2dj37</outgoing>
</task>
<sequenceFlow id="SequenceFlow_1v2dj37" sourceRef="Task_1ubxr83" targetRef="ExclusiveGateway_01todg7" />
<exclusiveGateway id="ExclusiveGateway_01todg7" name="是否合格">
<incoming>SequenceFlow_1v2dj37</incoming>
<outgoing>SequenceFlow_0j75wny</outgoing>
<outgoing>SequenceFlow_0pfete3</outgoing>
</exclusiveGateway>
<sequenceFlow id="SequenceFlow_0j75wny" name="是" sourceRef="ExclusiveGateway_01todg7" targetRef="Task_0cxcj51" />
<task id="Task_0cxcj51" name="安装">
<incoming>SequenceFlow_0j75wny</incoming>
<outgoing>SequenceFlow_14n5686</outgoing>
</task>
<sequenceFlow id="SequenceFlow_14n5686" sourceRef="Task_0cxcj51" targetRef="IntermediateThrowEvent_0pknvty" />
<sequenceFlow id="SequenceFlow_00i63bm" sourceRef="Task_1y56h2p" targetRef="Task_1ubxr83" />
<sequenceFlow id="SequenceFlow_0pfete3" name="否" sourceRef="ExclusiveGateway_01todg7" targetRef="Task_1y56h2p" />
<!--结束-->
<endEvent id="IntermediateThrowEvent_0pknvty" name="结束">
<incoming>SequenceFlow_14n5686</incoming>
</endEvent>
<!--结束-->
</process>
<bpmndi:BPMNDiagram id="BpmnDiagram_1">
<!--图像渲染部分省略-->
</bpmndi:BPMNDiagram>
</definitions>
现有问题汇总:
1.如何应用表达式
2.如何绑定视图
3.如何通过视图泳道来判断权限等问题
4.如何生成流程
5.流程如何运行
我的方案
后端设计好表达式和视图,并指定特定的Id/Name标识,通过 Properties Panel 加到流程图上(xml) 以下拉框等方式让用户选择,并指定给 方块/菱形 ,这样 视图引擎运行到某个task或者 gateway的时候,可以通过 其上绑定的属性 找到指定的 方法/视图.
后端我建议我们自己开发一套流程解析引擎
大致包括数据内容:
1.流程图
2.运行时任务
3.任务操作
4.表达式
5.视图
6.相关数据
...
针对流程图的修改,我建议每次修改都必须重新生成新的流程图,之前的 运行时任务 不能迁移到新流程上.
要废弃老流程图,必须在其上的运行时任务都结束/终止
关于泳道
流程图中保存了泳道,我们可以把对应的用户存入其中,而泳道的子节点涵盖了所有在其中的模块Id如图:
关于引擎如何运作
我们需要有
一个展示方法:传入[流程图],[运行时任务],[当前用户],方法通过查询所有[任务操作]返回视图/表达式表单 等待用户操作
一个操作方法:传入[操作结果],[流程图],[运行时任务],[当前用户],方法会添加一个[任务操作],这样就任务就到"下一步"了
总结,我们需要有一个通用的方法来解析传入的task/gateway,他们可能包含不同的表单,判断,而通用方法需要给出指定的操作
关于数据隔离
参考之前我做的一个流程项目,他们的做法是 每个新的 流程图 都会有自己独立的表 由系统自动创建,但他们的设计和我们的不太一样,他们的引擎生成的每个表的字段非常多,几乎涵盖了所有相关数据,我认为这个是没有必要的.
方案风险
1.Properties Panel 的二次开发
由于这个东西是nodejs的 集成到我们.net项目中没有相关经验,二次开发修改成我们想要的样子,比如视图选择框等功能难度较大.
2.子流程开发问题
如何双击进入某个流程的子流程,这个也是需要对bpmn进行深入研究的
3.流程解析引擎
如果需要实现所有bpmn2.0的规范与要求,我们自主开发的流程引擎短时间内肯定做不到,但要实现安装2的需求,并部分实现bpmn2.0是可能的
4.表单设计器
针对每一步需要填写的表单资料,如何设计,是固定还是需要有编辑器,如果要编辑器,则需要开发时间,但一劳永逸