snaker工作流引擎web设计器(vue3版)
情怀!N年前使用的工作流引擎,虽然原作者已经不再维护,但是还是有那么一波人还在使用。个人看来其核心功能尚好,麻雀虽少,五脏俱全,是用来学习工作流引擎的好项目。但其流程设计器所用的技术栈可能就跟不上时代了(2016年前的开源项目)。为了让大伙或自己用得更舒心,或者也为了让更多人认识或重新认识这个工作流引擎。本人就花些许时间,使用现阶段前端主流的技术栈重新开发此款流程设计器。如大家在使用的过程中如有啥问题,欢迎留言或进群交流!
加群交流可加作者微信:mldong_ (微信号有下划线
)
交流圈子

在线体验
编辑模式
只读模式
高亮模式
xml数据
使用案例
后端工程
前端工程
如何使用
安装
npm install snakerflow-designer-vue@next --save
其他依赖
设计器依赖以下第三方库,如果工程中没有引入这些第三库将会无法正常使用,需自行安装。
npm install @logicflow/core@^1.1.28 --save
npm install @logicflow/extension@^1.1.28 --save
npm install clipboard@^2.0.11 --save
npm install vue-json-pretty@^2.1.1 --save
引入
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// 导入组件库
import SnakerFlowDesigner from 'snakerflow-designer-vue'
createApp(App).use(router).use(ElementPlus).use(SnakerFlowDesigner).mount('#app')
样例
编辑模式
<!-- https://gitee.com/mldong/snakerflow-designer-vue/blob/vue3/examples/views/Home.vue -->
<SnakerFlowDesigner ref='designerRef' v-model="flowData" @on-save="handleSave"/>
只读模式
<!-- https://gitee.com/mldong/snakerflow-designer-vue/blob/vue3/examples/views/Preview.vue -->
<SnakerFlowDesigner :viewer="true" ref='designerRef' v-model="flowData"/>
高亮模式
<!-- https://gitee.com/mldong/snakerflow-designer-vue/blob/vue3/examples/views/HighLight.vue -->
<SnakerFlowDesigner :viewer="true" ref='designerRef' v-model="flowData" :high-light="highLight"/>
XML数据
<!-- https://gitee.com/mldong/snakerflow-designer-vue/blob/vue3/examples/views/Xml.vue -->
<SnakerFlowDesigner :viewer="true" ref='designerRef' v-model="flowData"/>
属性
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|
value / v-model | 绑定值(xml或json) | string/object | -- | -- |
config | LogicFlow配置 | object | -- | -- |
viewer | 是否预览模式 | boolean | true/false | false |
highLight | 高亮数据,具体见下表 | object | -- | -- |
extendAttrConfig | 扩展属性配置,具体见下表 | object | -- | -- |
extendPropertyKeys | 配置额外扩展属性和自定义插槽一起使用,详见examples/views/CustomAssigner | Array | -- | -- |
showDoc | 是否显示码云标识 | boolean | true/false | true |
highLight
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|
historyNodeNames | 历史节点名称 | array | -- | -- |
historyEdgeNames | 历史边名称 | array | -- | -- |
activeNodeNames | 活跃节点名称 | array | -- | -- |
extendAttrConfig
样例数据
{
"items": [
{
"label": "用户标识",
"name": "userKey",
"icon": "",
"tips": "参与者处理类可根据用户标识获取参与者"
},
{
"label": "用户组标识",
"name": "groupKey",
"icon": "",
"tips": "参与者处理类可根据用户组标识获取参与者"
}
]
}
说明
参数 | 说明 | 类型 | 必填 | 默认值 |
---|
label | 显示名称 | string | 是 | -- |
name | 名称 | string | 是 | -- |
icon | 图标 | string | 否 | -- |
tips | 提示语 | string | 否 | -- |
默认配置
显示名称 | 名称 | 图标 | 提示语 |
---|
用户标识 | userKey | -- | 参与者处理类可根据用户标识获取参与者 |
用户组标识 | groupKey | -- | 参与者处理类可根据用户组标识获取参与者 |
候选用户 | candidateUsers | -- | 候选用户(提供给上一节点选择下一节点参与者的用户标识) |
候选用户组 | candidateGroups | -- | 候选用户组(提供给上一节点选择下一节点参与者的用户组标识) |
候选人处理类 | candidateHandler | -- | 获取候选人的处理类 |
额外属性1 | attr1 | -- | 其他扩展属性1 |
额外属性2 | attr2 | -- | 其他扩展属性2 |
额外属性3 | attr3 | -- | 其他扩展属性3 |
方法
方法名 | 说明 | 参数 |
---|
importXml | 导入SnakerFlow流程定义数据 | (xml) snakerflow流程定义xml |
importJson | 导入LogicFlow流程定义数据 | (data) LogicFlow流程定义json对象或json字符串 |
setHighLight | 设置高亮数据 | (data) 和属性中的hightLight数据结构一致 |
插槽slot
规则:form-item-${nodeType}-${field}
使用样例:
<SnakerFlowDesigner ref='designerRef' v-model="flowData" @on-save="handleSave">
<template #form-item-task-assignee="{model, field}">
<el-form-item label="自定义参与者">
<el-input v-model="model[field]"></el-input>
</el-form-item>
</template>
</SnakerFlowDesigner>
nodeType类型
名称 | 说明 |
---|
task | 任务节点 |
custom | 自定义节点 |
decision | 决策节点 |
end | 结束节点 |
fork | 分支节点 |
join | 合并节点 |
process | 流程 |
start | 开始节点 |
subProcess | 子流程 |
transition | 边 |
wfSubProcess | snaker子流程 |
task节点插槽slot
名称 | 说明 |
---|
form-item-task-name | 名称 |
form-item-task-displayName | 显示名称 |
form-item-task-form | 表单 |
form-item-task-assignee | 参与者 |
form-item-task-assignmentHandler | 参与者处理类 |
form-item-task-taskType | 任务类型 |
form-item-task-performType | 参与类型 |
form-item-task-preInterceptors | 前置拦截器 |
form-item-task-postInterceptors | 后置拦截器 |
form-item-task-reminderTime | 提醒时间 |
form-item-task-reminderRepeat | 重复提醒间隔 |
form-item-task-expireTime | 期待完成时间 |
form-item-task-autoExecute | 是否自动完成 |
form-item-task-width | 宽度 |
form-item-task-height | 高度 |
custom节点插槽slot
名称 | 说明 |
---|
form-item-custom-name | 名称 |
form-item-custom-displayName | 显示名称 |
form-item-custom-clazz | 类路径 |
form-item-custom-methodName | 方法名 |
form-item-custom-args | 参数变量 |
form-item-custom-preInterceptors | 前置拦截器 |
form-item-custom-postInterceptors | 后置拦截器 |
decision节点插槽slot
名称 | 说明 |
---|
form-item-decision-name | 名称 |
form-item-decision-expr | 决策表达式 |
form-item-decision-handleClass | 处理类 |
form-item-decision-preInterceptors | 前置拦截器 |
form-item-decision-postInterceptors | 后置拦截器 |
end节点插槽slot
名称 | 说明 |
---|
form-item-end-name | 名称 |
form-item-end-preInterceptors | 前置拦截器 |
form-item-end-postInterceptors | 后置拦截器 |
fork节点插槽slot
join节点插槽slot
名称 | 说明 |
---|
form-item-join-name | 名称 |
process节点插槽slot
名称 | 说明 |
---|
form-item-process-name | 流程定义名称 |
form-item-process-displayName | 流程定义显示名称 |
form-item-process-expireTime | 期望完成时间 |
form-item-process-instanceUrl | 实例启动Url |
form-item-process-instanceNoClass | 实例编号生成类 |
form-item-process-preInterceptors | 节点前置拦截器 |
form-item-process-postInterceptors | 节点后置拦截器 |
start节点插槽slot
名称 | 说明 |
---|
form-item-start-name | 名称 |
form-item-start-preInterceptors | 前置拦截器 |
form-item-start-postInterceptors | 后置拦截器 |
subProcess节点插槽slot
名称 | 说明 |
---|
form-item-subProcess-name | 流程定义名称 |
form-item-subProcess-displayName | 流程定义显示名称 |
form-item-subProcess-expireTime | 期望完成时间 |
form-item-subProcess-instanceUrl | 实例启动Url |
form-item-subProcess-instanceNoClass | 实例编号生成类 |
form-item-subProcess-preInterceptors | 节点前置拦截器 |
form-item-subProcess-postInterceptors | 节点后置拦截器 |
transition节点插槽slot
名称 | 说明 |
---|
form-item-transition-name | 名称 |
form-item-subProcess-displayName | 显示名称 |
form-item-transition-expr | 决策表达式 |
wfSubProcess节点插槽slot
名称 | 说明 |
---|
form-item-wfSubProcess-name | 子流程定义名称 |
form-item-wfSubProcess-displayName | 子流程定义显示名称 |
form-item-wfSubProcess-form | 表单 |
form-item-wfSubProcess-version | 版本号 |
form-item-wfSubProcess-width | 宽度 |
form-item-wfSubProcess-height | 高度 |
事件
事件名称 | 说明 | 回调参数 |
---|
on-save | 点击右上角工具栏保存按钮时触发 | 传递流程图数据对象data,包含json和xml数据({json, xml}) |
本地开发
安装
npm install
或
yarn install
开发
npm run serve
或
yarn serve
打包编译
npm run build
或
yarn build
校验
npm run lint
或
yarn lint
数据
JSON样例数据
{
"name": "leave",
"displayName": "请假",
"expireTime": "",
"instanceUrl": "leaveForm",
"nodes": [
{
"id": "start",
"type": "snaker:start",
"x": 340,
"y": 160,
"properties": {},
"text": {
"x": 340,
"y": 200,
"value": "开始"
}
},
{
"id": "apply",
"type": "snaker:task",
"x": 520,
"y": 160,
"properties": {
"taskType": "Major",
"performType": "ANY",
"autoExecute": "N",
"assignee": "approve.operator"
},
"text": {
"x": 520,
"y": 160,
"value": "请假申请"
}
},
{
"id": "approveDept",
"type": "snaker:task",
"x": 740,
"y": 160,
"properties": {
"assignee": "",
"taskType": "Major",
"performType": "ANY",
"autoExecute": "N",
"assignmentHandler": "com.mldong.config.FlowAssignmentHandler"
},
"text": {
"x": 740,
"y": 160,
"value": "部门领导审批"
}
},
{
"id": "end",
"type": "snaker:end",
"x": 1080,
"y": 160,
"properties": {},
"text": {
"x": 1080,
"y": 200,
"value": "结束"
}
},
{
"id": "2c75eebf-5baf-4cd0-a7b3-05466be13634",
"type": "snaker:decision",
"x": 740,
"y": 340,
"properties": {}
},
{
"id": "approveBoss",
"type": "snaker:task",
"x": 900,
"y": 480,
"properties": {
"assignee": "",
"taskType": "Major",
"performType": "ANY",
"autoExecute": "N",
"assignmentHandler": "com.mldong.config.FlowAssignmentHandler"
},
"text": {
"x": 900,
"y": 480,
"value": "公司领导审批"
}
}
],
"edges": [
{
"id": "3037be41-5682-4344-b94a-9faf5c3e62ba",
"type": "snaker:transition",
"sourceNodeId": "start",
"targetNodeId": "apply",
"startPoint": {
"x": 358,
"y": 160
},
"endPoint": {
"x": 460,
"y": 160
},
"properties": {},
"pointsList": [
{
"x": 358,
"y": 160
},
{
"x": 460,
"y": 160
}
]
},
{
"id": "c79642ae-9f28-4213-8cdf-0e0d6467b1b9",
"type": "snaker:transition",
"sourceNodeId": "apply",
"targetNodeId": "approveDept",
"startPoint": {
"x": 580,
"y": 160
},
"endPoint": {
"x": 680,
"y": 160
},
"properties": {},
"pointsList": [
{
"x": 580,
"y": 160
},
{
"x": 680,
"y": 160
}
]
},
{
"id": "09d9b143-9473-4a0f-8287-9abf6f65baf5",
"type": "snaker:transition",
"sourceNodeId": "approveDept",
"targetNodeId": "2c75eebf-5baf-4cd0-a7b3-05466be13634",
"startPoint": {
"x": 740,
"y": 200
},
"endPoint": {
"x": 740,
"y": 315
},
"properties": {},
"pointsList": [
{
"x": 740,
"y": 200
},
{
"x": 740,
"y": 315
}
]
},
{
"id": "517ef2c7-3486-4992-b554-0f538ab91751",
"type": "snaker:transition",
"sourceNodeId": "2c75eebf-5baf-4cd0-a7b3-05466be13634",
"targetNodeId": "end",
"startPoint": {
"x": 764,
"y": 339
},
"endPoint": {
"x": 1080,
"y": 178
},
"properties": {
"expr": "#f_day<3"
},
"text": {
"x": 912,
"y": 339,
"value": "请假天数小于3"
},
"pointsList": [
{
"x": 764,
"y": 339
},
{
"x": 1080,
"y": 339
},
{
"x": 1080,
"y": 178
}
]
},
{
"id": "d7ec4166-f3fc-4fd6-a2ac-a6c4d509c4dd",
"type": "snaker:transition",
"sourceNodeId": "2c75eebf-5baf-4cd0-a7b3-05466be13634",
"targetNodeId": "approveBoss",
"startPoint": {
"x": 740,
"y": 365
},
"endPoint": {
"x": 840,
"y": 480
},
"properties": {
"expr": "#f_day>=3"
},
"text": {
"x": 740,
"y": 422.5,
"value": "请假天数大于等于3"
},
"pointsList": [
{
"x": 740,
"y": 365
},
{
"x": 740,
"y": 480
},
{
"x": 840,
"y": 480
}
]
},
{
"id": "a64348ec-4168-4f36-8a61-15cf12c710b9",
"type": "snaker:transition",
"sourceNodeId": "approveBoss",
"targetNodeId": "end",
"startPoint": {
"x": 960,
"y": 480
},
"endPoint": {
"x": 1080,
"y": 142
},
"properties": {},
"pointsList": [
{
"x": 960,
"y": 480
},
{
"x": 1140,
"y": 480
},
{
"x": 1140,
"y": 112
},
{
"x": 1080,
"y": 112
},
{
"x": 1080,
"y": 142
}
]
}
]
}
XML样例数据
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<process name="leave" displayName="请假" instanceUrl="leaveForm">
<start name="start" displayName="开始" layout="340,160,120,80">
<transition name="3037be41-5682-4344-b94a-9faf5c3e62ba" to="apply" g="358,160;460,160"></transition>
</start>
<task name="apply" displayName="请假申请" layout="520,160,120,80" taskType="Major" performType="ANY" autoExecute="N" assignee="approve.operator">
<transition name="c79642ae-9f28-4213-8cdf-0e0d6467b1b9" to="approveDept" g="580,160;680,160"></transition>
</task>
<task name="approveDept" displayName="部门领导审批" layout="740,160,120,80" taskType="Major" performType="ANY" autoExecute="N" assignmentHandler="com.mldong.config.FlowAssignmentHandler">
<transition name="09d9b143-9473-4a0f-8287-9abf6f65baf5" to="2c75eebf-5baf-4cd0-a7b3-05466be13634" g="740,200;740,315"></transition>
</task>
<decision name="2c75eebf-5baf-4cd0-a7b3-05466be13634" layout="740,340,120,80">
<transition name="517ef2c7-3486-4992-b554-0f538ab91751" displayName="请假天数小于3" to="end" expr="#f_day<3" g="764,339;1080,339;1080,178"></transition>
<transition name="d7ec4166-f3fc-4fd6-a2ac-a6c4d509c4dd" displayName="请假天数大于等于3" to="approveBoss" expr="#f_day>=3" g="740,365;740,480;840,480"></transition>
</decision>
<end name="end" displayName="结束" layout="1080,160,120,80">
</end>
<task name="approveBoss" displayName="公司领导审批" layout="900,480,120,80" taskType="Major" performType="ANY" autoExecute="N" assignmentHandler="com.mldong.config.FlowAssignmentHandler">
<transition name="a64348ec-4168-4f36-8a61-15cf12c710b9" to="end" g="960,480;1140,480;1140,112;1080,112;1080,142"></transition>
</task>
</process>
高亮数据
{
"historyNodeNames": [
"start",
"apply"
],
"historyEdgeNames": [
"3037be41-5682-4344-b94a-9faf5c3e62ba",
"c79642ae-9f28-4213-8cdf-0e0d6467b1b9"
],
"activeNodeNames": [
"approveDept"
]
}
相关资料
snakerflow-designer-vue2.0
LogicFlow
snaker工作流中文文档
snaker源码