# 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_ (`微信号有下划线`) # 交流圈子 ![纷传](doc/images/fenchuan.jpg) 快速开发平台 [在线体验] (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)