# snakerflow-designer-vue
**Repository Path**: mldong/snakerflow-designer-vue
## Basic Information
- **Project Name**: snakerflow-designer-vue
- **Description**: 基于Logicflow的工作流设计器-用于snakerflow
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: https://www.mldong.com/
- **GVP Project**: No
## Statistics
- **Stars**: 245
- **Forks**: 125
- **Created**: 2022-01-19
- **Last Updated**: 2025-05-26
## Categories & Tags
**Categories**: workflow
**Tags**: logicFlow, Vue, 流程设计器, 工作流, SnakerFlow
## README
# snaker工作流引擎web设计器
情怀!N年前使用的工作流引擎,虽然原作者已经不再维护,但是还是有那么一波人还在使用。个人看来其核心功能尚好,麻雀虽少,五脏俱全,是用来学习工作流引擎的好项目。但其流程设计器所用的技术栈可能就跟不上时代了(2016年前的开源项目)。为了让大伙或自己用得更舒心,或者也为了让更多人认识或重新认识这个工作流引擎。本人就花些许时间,使用现阶段前端主流的技术栈重新开发此款流程设计器。如大家在使用的过程中如有啥问题,欢迎留言或进群交流!
# 加群交流可加作者微信:mldong_ (`微信号有下划线`)
# 交流圈子

快速开发平台
[在线体验] (https://snaker.mldong.com/)
[编辑模式] (https://snaker.mldong.com/)
[只读模式] (https://snaker.mldong.com/preview)
[高亮模式] (https://snaker.mldong.com/highLight)
[xml数据] (https://snaker.mldong.com/xml)
# 使用案例
[后端工程] (https://gitee.com/mldong/mldong)
[前端工程] (https://gitee.com/mldong/mldong-vue)
# 如何使用
## Vue2
### 安装
```bash
npm install snakerflow-designer-vue@latest --save
```
### 其他依赖
设计器依赖以下第三方库,如果工程中没有引入这些第三库将会无法正常使用,需自行安装。
```bash
npm install @logicflow/core@^1.1.3 --save
npm install @logicflow/extension@^1.1.3 --save
npm install clipboard@^2.0.10 --save
npm install vue-json-pretty@^1.8.2 --save
```
### 引入
```js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false
// 导入组件库
import SnakerFlowDesigner from 'snakerflow-designer-vue'
// 注册组件库
Vue.use(SnakerFlowDesigner)
Vue.use(ElementUI)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
```
## Vue3
### 安装
```bash
npm install snakerflow-designer-vue@next --save
```
### 其他依赖
设计器依赖以下第三方库,如果工程中没有引入这些第三库将会无法正常使用,需自行安装。
```bash
npm install @logicflow/core@^1.1.21 --save
npm install @logicflow/extension@^1.1.21 --save
npm install clipboard@^2.0.11 --save
npm install vue-json-pretty@^2.1.1 --save
```
### 引入
```js
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')
```
## 样例
### 编辑模式
```html
```
### 只读模式
```html
```
### 高亮模式
```html
```
### XML数据
```html
```
## 属性
| 参数 | 说明 | 类型 |可选值 |默认值 |
| ---- | ---- | ---- | ---- |---- |
| 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 |
| disabledClickNodes | 禁止点击的节点,例:['snaker:start','snaker:end'] | Array | - |
### highLight
| 参数 | 说明 | 类型 |可选值 |默认值 |
| ---- | ---- | ---- | ---- |---- |
| historyNodeNames | 历史节点名称 | array |-- |-- |
| historyEdgeNames | 历史边名称 | array |-- |-- |
| activeNodeNames | 活跃节点名称 | array |-- |-- |
### extendAttrConfig
#### 样例数据
``` json
{
"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}`
使用样例:
``` html
```
### 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
| 名称 | 说明 |
| ---- | ---- |
| form-item-end-name | 名称 |
### 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}) |
# 本地开发
## 安装
```bash
npm install
```
## 开发
```bash
npm run serve
```
## 打包编译
```bash
npm run build
```
## 校验
```bash
npm run lint
```
# 数据
## JSON样例数据
``` 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
```
## 高亮数据
``` json
{
"historyNodeNames": [
"start",
"apply"
],
"historyEdgeNames": [
"3037be41-5682-4344-b94a-9faf5c3e62ba",
"c79642ae-9f28-4213-8cdf-0e0d6467b1b9"
],
"activeNodeNames": [
"approveDept"
]
}
```
# 相关资料
[LogicFlow] (http://logic-flow.org/)
[snaker工作流中文文档] (https://yunmel.gitbooks.io/snakerflow/content/)
[snaker源码] (https://gitee.com/yuqs/snakerflow)