用语义化html(如data-status)描述流程节点状态,css属性选择器动态控制样式,js仅更新状态值;流程数据由后端json驱动,支持条件分支与权限控制,前端防重+后端幂等保障审批正确性。

怎么用 HTML + 简单 JS 实现流程节点可视化
纯 HTML 无法驱动审批逻辑,但能清晰展示当前审批所处阶段、节点状态和流向。关键不是“画流程图”,而是让每个节点知道它当前是 pending、approved 还是 rejected,并据此切换样式。
常见错误是直接用 SVG 手动画箭头——后期改节点顺序或增删步骤时,HTML 和 SVG 路径要同步改两处,极易出错。更稳妥的做法是用语义化结构描述流程,再靠 CSS 控制视觉连接。
- 用
<ol></ol>或带data-step的<div> 表示节点顺序,天然支持动态插入/删除 <li>每个节点加 <code>data-status="pending"属性,JS 只需更新这个值,CSS 自动响应 - 用
::after伪元素画连接线,避免手动维护 SVG 坐标 - 别在 HTML 里硬编码“张三 → 李四 → 王五”,把人员信息从后端 JSON 注入,前端只负责渲染
- 节点容器写成
<div class="step" data-status="approved">财务审核</div> - CSS 中用属性选择器:
.step[data-status="approved"] { background: #4caf50; color: white; } - 驳回状态加边框警示:
.step[data-status="rejected"] { border: 2px solid #f44336; } - 连接线颜色也跟着最后通过的节点走,比如
.step[data-status="approved"] + .step::before画绿线 - 点击后立即设
button.disabled = true,文字改为"审批中..." - 用
fetch()发请求前检查全局标记:if (isApproving) return; - 成功或失败后都恢复按钮,并清除标记:
button.disabled = false; isApproving = false; - 别用
setTimeout模拟加载态,真实请求时间不可控,应以 Promise settle 为准
如何让“已审批”节点显示绿色,“被驳回”节点标红
CSS 类名绑定状态比写一堆 if-else 切换更轻量。不需要框架也能做到状态驱动样式。
核心是统一约定状态值:pending(待审)、approved(通过)、rejected(驳回)、skipped(跳过)。其他值如 processing 容易和后端状态混淆,不建议引入。
点击节点触发审批动作时,怎么避免重复提交
用户手快连点两次,后端可能收到两条 approve 请求,导致状态错乱。防重不能只靠前端,但前端必须做第一道拦截。
最简方案是按钮置灰 + 文字提示,配合请求锁。不要依赖 disabled 属性后就以为万事大吉——用户可能禁用 JS 或绕过限制,所以后端仍需幂等设计(如用 approval_id 去重)。
为什么不能只用 HTML 静态写死整个流程
因为真实审批流会动态变化:某节点可能被跳过,条件分支(如金额 >10w 需追加法务审核),甚至中途撤回重走。静态 HTML 无法响应这些。
真正可维护的做法是把流程定义抽成 JSON,例如:
{
"steps": [
{ "id": "hr", "name": "HR初审", "status": "approved" },
{ "id": "mgr", "name": "部门经理", "status": "pending" },
{ "id": "finance", "name": "财务复核", "status": "pending", "visible": false }
]
}
然后用 JS 渲染 DOM,根据 visible 控制是否显示,根据 status 绑定样式。这样改流程只需改数据,不动 HTML 结构。
容易被忽略的是“节点权限”——不是所有用户都能看到全部节点。前端隐藏不等于后端不校验,该字段必须由后端决定并下发,不能靠 JS 判断角色后自行过滤。











