最近在做框架的工作流集成,基于django+vue的平台,查了很多资料,python并没有像java那边有flowable,Activiti这样的工作流引擎,技术选型了很久最终选择了spiffworkflow这个包,基于python,发展了10来年的库,功能也很完善了,加上我们自己的web功能,后期可以做成python,django开源的开源工作流引擎
这是我们框架的地址:(dvadmin)gitee.com/liqianglog/… 欢迎star
Bpmn知识点
1.bpmn文件格式可以为xml bpmn两种
2.bpmn xml根节点为 bpmn:definitions 包含一个bpmn:process节点,里面包含了数据节点的描述,还有一个bpmn:BPMNDiagram节点,这个是可视化节点的坐标信息,在给流程引擎解析xml时候可以没有这个节点,这个节点主要是在bpmn可视化建模软件里绘图时候用到的坐标信息,相当于是给人看的,流程引擎解析流程并不需要这个节点
Spiffworkflow学习
1.启动一个工作流流程的步骤如下
- step1:首先得创建一个
WorkflowSpec对象,这个实例表示工作流的定义
- Step2:创建一个
Workflow对象,这个实例表示工作流的建模,我们需要拿到这个实例来做一些操作
实例代码:新建一个bpmnworkflow
def parse_workflow(parser, process, bpmn_files, dmn_files=None, load_all=True):
"""
解析workflow 返回BpmnWorkflow对象
"""
# parser.add_bpmn_files(bpmn_files)
parser.add_bpmn_xml(bpmn_files)
if dmn_files:
parser.add_dmn_files(dmn_files)
top_level = parser.get_spec(process)
if load_all:
subprocesses = parser.find_all_specs()
else:
subprocesses = parser.get_subprocess_specs(process)
return BpmnWorkflow(top_level, subprocesses, script_engine=PythonScriptEngine(scripting_additions={}))
parser.add_bpmn_files是解析一个标准的bpmn2.0xml文件对象
parser.add_bpmn_xml是解析标准的bpmn xml 字符串对象
启动流程
def run(workflow):
"""
启动流程
"""
start_event = workflow.get_tasks_from_spec_name("Start")
TASK_HANDLERS.get(StartEvent)(start_event)
while not workflow.is_completed():
all_tasks = workflow.get_tasks()
for task in all_tasks:
# print(task.task_spec.name)
handler = TASK_HANDLERS.get(type(task.task_spec))
if handler is not None:
handler(task)
workflow.refresh_waiting_tasks()
workflow.do_engine_steps()
end_event = workflow.get_tasks_from_spec_name("End")
TASK_HANDLERS.get(EndEvent)(end_event)
可以根据workflow对象拿到具体的task,比如read_tasks 开始事件start_event结束事件end_event
自定义scriptEngine,适用场景:对应scriptTask,serviceTask,在bpmn文件中调用定义好的变量,函数等
class DvflowScriptEngine(PythonScriptEngine):
def call_service(self, operation_name, operation_params, task_data):
print(f'call service {operation_name}, {operation_params}')
data_dict = {
'code': 200,
'msg': 'test is ok'
}
return json.dumps(data_dict)
SCRIPT_ADDITIONS = {
'script_engine_callback_event': script_engine_callback_event,
}
def parse_workflow(parser, process, bpmn_files, dmn_files=None, load_all=True):
"""
解析workflow 返回BpmnWorkflow对象
"""
# parser.add_bpmn_files(bpmn_files)
parser.add_bpmn_xml(bpmn_files)
if dmn_files:
parser.add_dmn_files(dmn_files)
top_level = parser.get_spec(process)
if load_all:
subprocesses = parser.find_all_specs()
else:
subprocesses = parser.get_subprocess_specs(process)
return BpmnWorkflow(top_level, subprocesses, script_engine=DvflowScriptEngine(scripting_additions=SCRIPT_ADDITIONS))
这里返回的BpmnWorkflow对象里的script_engine参数对应上面我们自定义的scriptEngine,这样script_additions的映射关系就添加到了系统里,我们可以在bpmn文件里调用这个script_engine_callback_event