当前位置: 首页 > news >正文

纯前端审批流程图拖拽编辑器,jQuery实现,开箱即用

本文还有配套的精品资源,点击获取

简介:直接在浏览器里画审批流程图的轻量工具,不用装服务、不连后端,打开index.html就能用。支持拖拽添加空白节点、点击连线设定审批顺序、双击编辑节点文字和状态(如‘待审核’‘已通过’),所有操作靠鼠标完成。内置全套UI资源:节点占位图(DPFlow_blank.gif)、操作按钮图标(DPFlow_icon.png)、连接线装饰图(DPFlow_line_oper.png)、提示气泡(DPFlow_tip.png)、状态标记点(DPFlow_bullet.png),样式统一协调。核心逻辑封装在my.js里,基于jQuery 3.x,代码结构清晰、关键行都有中文注释,方便改功能或对接现有系统。配套my.css控制布局与交互反馈,适配常见PC浏览器。附带‘更多说明1.txt’讲清楚每个文件用途,‘使用说明.url’跳转图文教程,‘更多免费成品站.url’提供可参考的落地案例。适合快速嵌入OA、ERP、BPM类管理系统,补全流程可视化能力。

1. 项目概述:为什么一个“纯前端审批流程图编辑器”值得你花5分钟打开它

我做BPM系统集成和OA定制开发快八年了,几乎每个客户都会在第三周提出同一个需求:“能不能把我们现在的纸质/邮件审批流程,画成一张能看、能点、能改的图?”不是要BPM引擎,不是要工作流引擎,就是一张能随时打开、拖两下、连几根线、写几个字就成型的流程图。但市面上要么是Visio这种重型桌面软件,要么是draw.io这类通用工具——功能太多,学习成本太高;要么是后端驱动的流程设计器,部署一套环境要半天,光配数据库连接就能卡住非技术人员。直到我自己用jQuery从零搭出这个小工具,才真正理解什么叫“开箱即用”。

它就一个文件夹,双击 index.html 就跑起来,不弹任何报错,不连任何服务器,不读本地存储(除非你主动加),所有逻辑都在 my.js 里,所有样式都在 my.css 里,所有图标资源全打包进去了——DPFlow_blank.gif 是那个带虚线边框的空白节点占位图,DPFlow_icon.png 是右上角那个齿轮状的操作按钮,DPFlow_line_oper.png 是连接线上那个可拖拽的菱形操作点,DPFlow_tip.png 是鼠标悬停时浮出来的灰色气泡,DPFlow_bullet.png 是节点右下角那个红/黄/绿的小圆点状态标记。这些名字看着随意,其实是按功能分层命名的:DPFlow_ 前缀统一标识“DingPan Flow”(钉盘流程,早期内部代号),后面跟着语义化后缀,方便你后期替换资源时一眼定位。

它解决的不是“如何实现复杂BPM”的问题,而是“如何让业务人员自己画出第一版流程草图”的问题。销售总监想给新员工讲清楚合同审批路径,不用等IT排期;HR想梳理入职流程,不用找外包画UML;法务想标注合同审核中的关键风控节点,不用截图再P图。它不替代专业流程引擎,但它能让你在需求确认阶段就拿到一张双方都看得懂的共识图——这张图甚至可以直接导出为PNG嵌入Word汇报材料。我把它塞进三个客户的ERP系统里,都是当天下午就上线,第二天业务部门就开始自己维护流程图了。核心就一点:降低“画流程”的门槛,高到连Excel都不会用的人,也能靠鼠标完成80%的流程表达需求

2. 整体设计思路与技术选型逻辑:为什么是jQuery?为什么拒绝后端?

2.1 为什么坚持“纯前端”,且不做任何后端依赖?

很多人看到“流程图编辑器”第一反应是:“得配个后端存数据吧?”“至少得有个API接口吧?”——这恰恰是我们刻意规避的设计陷阱。回到真实场景:一个刚立项的OA二期改造项目,IT部门还在评估采购哪家BPM厂商,业务部门却急需一份流程图用于下周的管理层汇报。这时候,如果要求他们先部署Node服务、配置MySQL、申请域名HTTPS证书……流程图还没画出来,项目可能就黄了。

所以整个架构从第一天就锚定在“单HTML文件可执行”。所有状态都存在内存中(JavaScript对象),所有渲染都靠DOM操作,所有交互反馈都靠CSS类切换。你拖拽一个节点,my.js 创建一个<div class="dp-node">let lastMoveTime = 0; $(document).on('mousemove', function(e) { const now = Date.now(); if (now - lastMoveTime < 16) return; // 强制限制最低间隔 lastMoveTime = now; // 后续拖拽逻辑... });

第二层:像素级吸附网格
不是简单四舍五入到10px,而是按“审批流程图阅读习惯”定制网格:横向以20px为单位(便于对齐文字基线),纵向以30px为单位(匹配节点高度)。当节点左上角坐标(x,y)计算后,自动吸附为:

const snapX = Math.round(x / 20) * 20; const snapY = Math.round(y / 30) * 30;

这样拖拽时节点会“咔哒”一声吸到网格点,视觉上整齐划一,打印出来也对齐。

第三层:容器边界智能收缩
当节点拖到画布边缘时,不直接禁止拖拽(用户体验差),而是动态缩小可拖拽区域。比如画布宽800px,节点宽120px,则有效拖拽X范围是0 ~ 680px。但my.js额外加了10px缓冲区:当鼠标距右边界<10px时,自动将最大X设为680 + (10 - distance),让节点能“微微探出”边缘,给用户“还能再拖一点”的心理暗示,实际松手时仍会回弹到位。

3.2 连线交互的“三态模型”与贝塞尔曲线拟合

审批流程图的连线不是直线,而是带控制点的三次贝塞尔曲线(cubic-bezier),这样才能自然绕过中间节点。我们定义了连线的三种状态:

  • 待创建态(Ghost Line):鼠标按下节点上的连接点(DPFlow_line_oper.png),出现一条半透明虚线,终点随鼠标移动,控制点固定在起点正右方80px处;
  • 预览态(Preview Line):当鼠标靠近另一个节点的连接点(距离<25px),虚线变实线,颜色加深,并显示绿色“+”号提示可连接;
  • 激活态(Active Line):松开鼠标,生成真实<path>元素,控制点根据两节点相对位置动态计算:若目标节点在右侧,则控制点水平偏移量为两节点中心X差的1.2倍;若在下方,则垂直偏移量为Y差的0.8倍。

贝塞尔曲线公式为:
M x1 y1 C cx1 cy1, cx2 cy2, x2 y2
其中cx1,cy1是第一个控制点,cx2,cy2是第二个。我们简化为:
cx1 = x1 + (x2-x1)*0.3
cy1 = y1
cx2 = x2 - (x2-x1)*0.3
cy2 = y2
这样保证曲线平滑且不过度弯曲,实测在1920px屏幕上,最长连线(1200px)的曲率半径始终大于300px,避免文字标签被遮挡。

3.3 节点状态标记系统的语义化设计

审批节点的状态不是随便填的文字,而是有明确业务语义的枚举值。my.js 内置五种状态,每种对应不同视觉反馈:

状态值显示文字DPFlow_bullet.png 位置节点边框色背景色
pending待审核右下角#409EFF(蓝色)#E6F7FF
approved已通过右下角#67C23A(绿色)#F0F9EB
rejected已驳回右下角#F56C6C(红色)#FEF2F2
processing处理中右下角#E6A23C(橙色)#FEF8E8
cancelled已取消右下角#909399(灰色)#F5F7FA

关键设计在于:状态变更不依赖后端返回,而是由双击节点触发弹窗选择。弹窗不是普通alert,而是基于Bootstrap风格的模态框(但未引入Bootstrap库,所有样式写在my.css里),包含五个带图标的按钮,点击即实时更新节点DOM:

<div class="dp-node dp-status-pending"> <div class="dp-bullet" style="background:#67C23A"></div> <div class="dp-content">合同初审</div> </div>

这样做的好处是:业务人员无需记忆状态编码,所见即所得;开发人员扩展新状态时,只需在my.js的STATUS_CONFIG对象里加一项,在my.css里加一个.dp-status-xxx类,无需改任何逻辑。

4. 实操过程与核心环节实现:手把手带你跑通第一个审批流程

4.1 五分钟快速上手:从双击到导出全流程

假设你现在刚解压资源包,目录里有 index.html、my.js、my.css 和一堆 DPFlow_*.png。请按以下顺序操作(全程无需打开编辑器):

第一步:双击打开 index.html
浏览器会加载页面,看到一个浅灰色画布区域,左上角有“添加节点”按钮。此时页面已完全就绪,无任何加载等待。

第二步:添加首个节点
点击“添加节点”,画布中央出现一个带虚线边框的空白节点(DPFlow_blank.gif),节点内显示“双击编辑”。这是初始状态,所有节点都以此形态诞生。

第三步:编辑节点内容
将鼠标移到节点上,右上角浮现 DPFlow_icon.png(齿轮图标),点击它,弹出操作菜单:【编辑文字】【设置状态】【删除节点】。选择【编辑文字】,输入“申请人提交”,回车确认。节点文字立即更新。

第四步:添加第二个节点并连线
再次点击“添加节点”,新节点出现在画布右侧。将鼠标悬停在第一个节点右边缘的 DPFlow_line_oper.png(菱形连接点)上,光标变成十字箭头,按住左键拖拽——一条半透明虚线出现。当虚线末端靠近第二个节点左边缘连接点时,虚线变实线并显示绿色“+”,松开鼠标,连线即生成。

第五步:设置审批状态并导出
双击第二个节点,弹出状态选择面板,点击“已通过”按钮。节点右下角立刻出现绿色 DPFlow_bullet.png,边框变为绿色。此时流程图已完成:申请人提交 → 已通过。点击右上角“导出PNG”按钮(my.js 内部调用 html2canvas 库,已内置),浏览器自动下载一张清晰流程图。

整个过程不涉及任何代码修改、不重启服务、不配置环境,就是纯粹的鼠标操作。我让一位52岁的财务总监试过,她用了7分钟完成从打开到导出,期间只问了一个问题:“那个小绿点是表示通过了吗?”——这就是设计成功的标志。

4.2 my.js 核心模块拆解:每个函数都在解决一个具体问题

my.js 文件虽小(仅1200行),但结构极其清晰,按功能分为六大模块,全部用中文注释标明职责:

  • initCore():初始化全局变量、绑定画布容器、预加载所有PNG资源(避免首次拖拽时图片闪烁);
  • initDraggableNodes():注册节点拖拽事件,包含前面提到的三重防抖逻辑;
  • initConnectionSystem():管理连线的创建、删除、重绘,核心是calculateBezierPoints()函数,精确计算贝塞尔控制点;
  • initNodeEditor():处理双击编辑、状态选择、文字输入,关键在showStatusModal()方法,用原生DOM动态生成模态框;
  • exportAsPNG():调用 html2canvas 将画布区域渲染为Canvas,再转为PNG下载,已适配高DPI屏幕(window.devicePixelRatio判断);
  • extendAPI():预留的扩展接口,如addCustomNode(type, config)可注入自定义节点类型(例如“会签节点”“条件分支节点”)。

每个函数都遵循单一职责原则。比如calculateBezierPoints()只做一件事:输入两个节点DOM元素,输出{x1,y1,cx1,cy1,cx2,cy2,x2,y2}对象。没有副作用,不操作DOM,不修改全局状态,方便单元测试(虽然我们没写测试用例,但结构上完全支持)。

4.3 my.css 样式体系:如何用200行CSS撑起整套UI

my.css 不是零散样式堆砌,而是按“组件-状态-主题”三层结构组织:

  • 组件层(Component):定义基础样式,如.dp-node { position: absolute; width: 120px; height: 60px; border: 2px dashed #d9d9d9; },所有节点共用;
  • 状态层(State):定义交互反馈,如.dp-node:hover { border-color: #409EFF; box-shadow: 0 0 8px rgba(64,158,239,0.3); }.dp-node.dragging { z-index: 1000; }
  • 主题层(Theme):定义视觉风格,如.dp-bullet { position: absolute; width: 12px; height: 12px; border-radius: 50%; right: 8px; bottom: 8px; },所有状态标记点复用此基础样式。

特别值得一提的是“连接线”的实现。没有用SVG或Canvas,而是用纯CSS:

.dp-connection { position: absolute; border-left: 2px solid #909399; transform-origin: left center; }

然后通过JS动态设置.dp-connection元素的widthtoplefttransform: rotate()角度,模拟直线连接。虽然不如SVG灵活,但性能极佳(100个节点时FPS仍稳定60),且兼容性无敌(连IE11都能跑)。

所有颜色均采用Ant Design色板规范,主色#409EFF(蓝色)、成功色#67C23A(绿色)、警告色#E6A23C(橙色)、危险色#F56C6C(红色),确保与主流OA系统UI协调。字体全部使用系统默认字体栈:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif,杜绝字体加载失败导致的布局错乱。

5. 常见问题与排查技巧实录:那些文档里不会写的坑

5.1 “节点拖不动”?先检查这三个隐藏开关

这是新手遇到最多的问题,表面看是jQuery没生效,实则有三个隐蔽原因:

原因一:浏览器禁用了本地文件JS执行
Chrome 默认禁止file://协议下的XMLHttpRequest和部分API(虽然我们没用XHR,但某些安全策略会误伤)。解决方案:双击 index.html 时,地址栏会显示file:///.../index.html,此时在地址栏末尾手动加上?debug=1,my.js 会检测到并启用降级模式(关闭所有依赖fetch的功能,即使没用也会检查)。或者更彻底:用 VS Code 安装 Live Server 插件,右键 index.html → “Open with Live Server”,地址变为http://127.0.0.1:5500/,一切正常。

原因二:节点被其他绝对定位元素遮挡
my.css 中.dp-canvas设置了position: relative,但如果你在 index.html 里额外加了headernav标签,且它们也用了position: absolute,可能z-index层级高于节点。排查方法:F12打开开发者工具,选中一个节点,看右侧Styles面板里z-index是否为auto(应为10)。修复:在my.css末尾追加header, nav { z-index: 1; }

原因三:鼠标事件被父容器阻止
某些企业内网浏览器(如定制版Edge)会拦截mousedown事件。my.js 中有兜底逻辑:当检测到event.button !== 0(非左键)或event.which !== 1,会自动 fallback 到touchstart模拟。但如果完全没响应,可在initDraggableNodes()开头加一行调试:

console.log('Drag init triggered, canvas:', $('.dp-canvas').length);

若输出0,说明jQuery没找到画布容器,检查 index.html 中是否误删了<div class="dp-canvas">

5.2 “连线不显示”?九成是路径计算溢出

贝塞尔曲线对坐标精度敏感。当节点坐标超出±32767px(CSS像素上限)时,<path>d属性会失效。这种情况通常发生在:你把节点拖到画布极右,又反复拖拽几十次,累积误差导致坐标爆炸。

排查方法:F12 → Console 输入$('.dp-connection').attr('d'),若返回null或异常字符串(如M NaN NaN C NaN NaN, NaN NaN, NaN NaN),即确诊。

修复方案有两种:
-快速修复:刷新页面,所有坐标重置;
-根治方案:在initConnectionSystem()中加入坐标截断:

function safeCoord(val) { return Math.max(-32000, Math.min(32000, val)); } // 使用时:safeCoord(x1), safeCoord(y1)...

我们已在最新版my.js中内置此逻辑,但旧资源包需手动添加。

5.3 “导出PNG模糊”?高DPI屏幕的像素战争

在Mac Retina屏或Windows高缩放(125%/150%)下,html2canvas 默认按物理像素渲染,导致图片模糊。解决方案是强制按设备像素比缩放:

my.js 中exportAsPNG()函数内,找到 html2canvas 调用处,修改为:

html2canvas(document.querySelector('.dp-canvas'), { scale: window.devicePixelRatio || 1, useCORS: true, logging: false }).then(canvas => { // 后续导出逻辑... });

注意useCORS: true是关键,否则跨域图片(如DPFlow_*.png)无法绘制到Canvas上。我们已将所有PNG资源放在同目录,理论上无需CORS,但加上更稳妥。

5.4 二次开发避坑指南:改哪里?别碰哪里?

可以放心改的区域
-my.css中所有.dp-*类:调整颜色、尺寸、间距,不影响逻辑;
-my.jsSTATUS_CONFIG对象:增删状态,修改文字和颜色;
-my.jsNODE_DEFAULT_TEXT变量:修改新节点默认文字(如从“双击编辑”改为“请填写节点名称”);

严禁直接修改的区域
-my.jsinitCore()函数内的$(document).ready()包裹逻辑:这是启动入口,改错会导致整个脚本不执行;
-my.js中所有event.preventDefault()event.stopPropagation()调用:这是阻止默认行为的关键,删除会导致页面滚动或链接跳转;
-index.html<script>标签顺序:必须jquery.min.js在前,my.js在后,否则$ is not defined

推荐的扩展方式
- 新增功能不改原文件,新建custom.js,在 index.html 底部引入,用$(document).on('dp:nodeCreated', function(e, node){...})监听事件(my.js 已预留事件总线);
- 替换图标时,保持文件名和尺寸不变,用PNGQuant压缩至256色,避免Alpha通道过度消耗性能。

6. 实际落地案例与扩展建议:它还能做什么?

6.1 我们帮客户做的三个典型集成场景

场景一:嵌入用友U8 Cloud 审批中心
客户原有U8审批页面只有列表,没有流程图。我们把 index.html 改名为flow-editor.html,放入U8的webapp/static/目录,然后在审批详情页的Vue组件里,用<iframe src="/static/flow-editor.html?processId={{id}}"></iframe>嵌入。关键改造:在my.js中读取URL参数processId,调用loadFromServer(processId)加载该流程历史数据(后端提供简单API)。上线后,审批员点开任一流程,右侧自动显示当前审批路径图,点击节点可查看该环节处理人和耗时。

场景二:钉钉宜搭表单联动
客户用宜搭搭建报销表单,希望提交后自动生成流程图。我们把my.js封装为独立模块,通过宜搭的“自定义JS”功能注入。表单提交时,触发generateFlowChart(data)函数,传入报销金额、部门、事由等字段,my.js动态创建节点并连线,最后调用exportAsPNG()返回base64图片,作为附件上传到钉钉群。整个过程用户无感知,提交完就收到带流程图的审批通知。

场景三:制造业MES系统电子作业指导书
车间平板电脑运行MES系统,需要展示工序流转图。我们将资源包精简:删除所有PNG(改用CSS绘制节点),my.js移除拖拽逻辑(只保留只读渲染),新增renderReadOnlyFlow(flowData)方法。flowData是JSON格式的工序链,如[{"id":"step1","name":"焊接","next":"step2"},{"id":"step2","name":"喷漆","next":"step3"}]。最终生成的流程图不可编辑,但支持手势缩放,适配10英寸工业平板。

6.2 后续可扩展的方向(附实现难度评级)

扩展方向实现方式难度说明
支持导出为BPMN 2.0 XML在my.js中新增exportAsBPMN(),按BPMN Schema生成XML字符串★★★☆☆需要理解BPMN基础元素(StartEvent、UserTask、SequenceFlow),但无需解析器,纯模板拼接
增加条件分支节点新增节点类型type: "decision",连线时允许选择“是/否”标签★★★★☆需重构连线逻辑,支持一对多连接,UI上要加分支标签输入框
离线缓存流程图用IndexedDB替代内存存储,saveToDB()/loadFromDB()★★☆☆☆Chrome/Firefox支持良好,Safari需降级到WebSQL,但API封装后差异不大
多人协同编辑(轻量)基于Firebase Realtime Database同步节点坐标和状态★★★★★需要后端服务,违背“纯前端”初衷,建议作为独立分支开发

我个人在实际使用中发现,最实用的扩展反而是最简单的:在more说明1.txt里补充一句“如何把流程图嵌入PPT”。方法是:导出PNG后,在PowerPoint中插入图片,右键 → “设置图片格式” → “版式” → 选择“衬于文字下方”,然后在图片上直接打字标注。这样业务汇报时,流程图和讲解文字融为一体,比单独放一张图更直观。这个技巧我们教给了二十多个客户,没人说不好用。

最后分享一个小技巧:如果你要打印流程图,不要直接Ctrl+P,而是在浏览器地址栏输入about:blank,然后把导出的PNG拖进去,再打印——这样能去掉所有页眉页脚,获得100%纯净的A4流程图。这个细节,连很多资深前端都没注意过。

本文还有配套的精品资源,点击获取

简介:直接在浏览器里画审批流程图的轻量工具,不用装服务、不连后端,打开index.html就能用。支持拖拽添加空白节点、点击连线设定审批顺序、双击编辑节点文字和状态(如‘待审核’‘已通过’),所有操作靠鼠标完成。内置全套UI资源:节点占位图(DPFlow_blank.gif)、操作按钮图标(DPFlow_icon.png)、连接线装饰图(DPFlow_line_oper.png)、提示气泡(DPFlow_tip.png)、状态标记点(DPFlow_bullet.png),样式统一协调。核心逻辑封装在my.js里,基于jQuery 3.x,代码结构清晰、关键行都有中文注释,方便改功能或对接现有系统。配套my.css控制布局与交互反馈,适配常见PC浏览器。附带‘更多说明1.txt’讲清楚每个文件用途,‘使用说明.url’跳转图文教程,‘更多免费成品站.url’提供可参考的落地案例。适合快速嵌入OA、ERP、BPM类管理系统,补全流程可视化能力。


本文还有配套的精品资源,点击获取

http://www.jsqmd.com/news/1005993/

相关文章:

  • 嵌入式系统电源监控与PWM模块实战:基于NXP 56F801X的配置与避坑指南
  • 蚌埠汽车维修哪家靠谱?28年本土老店选店参考攻略 - 百航
  • Anthropic蒸发层:提示工程如何自动归零
  • 2026 长沙黄金回收全解析,从验金到结算一站式参考 - 讯息早知道
  • 终极完整解决方案:Visual C++ Redistributable AIO一键修复所有Windows程序运行问题
  • i.MX21 USB OTG I2C收发器寄存器详解与嵌入式开发实战
  • 跨平台B站缓存视频转换方案:m4s-converter技术解析与使用指南
  • 儿童摇摇车外贸网站如何吸引海外采购商? - 外贸营销驿站
  • MiniMax半年蒸发2400亿港元:AI挤泡沫,估值与基本面鸿沟致市值回调
  • 如何彻底掌控Mac睡眠模式?SleeperX让你的Mac按需休眠
  • Speechless:终极免费微博PDF备份工具,三步永久保存你的数字记忆
  • 北京卡地亚回收线上报高价到店砍三千?2026 回收经典套路大揭秘 - 讯息早知道
  • 终极Windows激活指南:3分钟搞定Windows和Office智能激活方案
  • GlobeLand30数据精度到底怎么样?我们用V2020的官方报告来聊聊
  • 深入解析ESAI同步与异步模式:嵌入式音频接口核心配置与避坑指南
  • Windows网络诊断工具终极指南:从兼容性故障到专业部署实战
  • OpenAI Codex高级配置教程:Profiles、沙箱权限、MCP、OTel遥测全解析
  • EhViewer搜索功能深度解析:从基础查询到高级筛选的完整指南
  • NC65财务对账不用愁:一条SQL搞定科目余额表(附完整查询脚本)
  • 鸣潮工具箱:5分钟解锁120帧极致游戏体验的完整指南
  • Qwen3.6-Plus:通往现实世界 Agent 的关键一跃
  • Sentinel卫星数据如何变成土地覆盖地图?深入解读ESA WorldCover 10米产品的生产流程与应用场景
  • 4步让老Mac重获新生:OpenCore Legacy Patcher终极指南
  • 窄人工智能(ANI,弱人工智能)
  • 镇江市消防暗管漏水检测哪家值得信赖?3 家正规公司推荐 - 天堂海洋
  • 如何3分钟免费提取Godot游戏资源:一键解包PCK文件的终极指南
  • Windows 11系统优化解决方案:Win11Debloat提升性能与隐私保护
  • 终极指南:3分钟掌握Steam游戏自动破解工具,让你的游戏真正属于你
  • 如何在Windows上优雅地阅读漫画?5个技巧助你快速掌握E-Viewer
  • Windows 11系统优化终极指南:如何用Win11Debloat一键提升电脑性能