# snakerflow-designer-vue
**Repository Path**: iveslight/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**: 0
- **Forks**: 129
- **Created**: 2025-04-22
- **Last Updated**: 2025-04-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## 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)