通用审核系统:用 X6 画出审批流程
git: https://github.com/fengnovo/universal-audit
线上地址:https://universal-audit.keen-tech.top/designer?mode=demo&name=费用报销流程&owner=财务共享中心
最近整理了一个通用审核系统前端演示项目。它不连接真实后端接口,不接数据库,也不包含登录鉴权,而是用前端页面模拟审批工作台、流程管理、流程编排、待办已办和发起审批这些核心场景。
项目使用 Next.js、React、Tailwind CSS、AntV X6 和 lucide-react 实现。它更像一个产品原型和交互样板:先把审批系统里最重要的角色、页面和流程编排体验做出来,再把后端流转和数据存储留给后续接入。
先用大白话理解
审批系统可以先不要想得太复杂。它本质上就是三件事:
所以这套系统不是单纯做几张表单,而是在表达一个核心关系:流程模板定义规则,申请单触发规则,审批任务按规则流转。
系统解决什么问题
通用审核系统用于管理公司里的审批事项:
- 普通员工提交审批申请。
- 审批人查看待办任务,并处理通过或驳回。
- 管理员创建和维护审批流程。
- 流程管理员在流程编排页面中,把审批步骤像画图一样画出来。
它的核心流转可以概括为:
先建流程 -> 再画步骤 -> 员工提交 -> 审批人处理这也是审核系统的主干:流程模板定义规则,申请单触发实例,审批任务按规则流转。
从角色看,几类用户关心的东西完全不同:
这个项目做得比较清楚的一点,是没有把所有功能塞到一个页面里,而是按角色拆成工作台、流程管理、流程编排、待办已办和发起审批。
页面结构
项目里有五个主要页面。
审核工作台
访问 /,默认进入审核工作台。这个页面展示待处理任务、运行中流程、本月通过率、平均处理时长、最近待办、流程健康度和最近提交。
如果你是审批人,优先看最近待办;如果你是管理员,优先看运行中流程和流程健康度。
流程管理
访问 /processes,展示流程模板列表。每一行代表一个审批流程模板,包含流程名称、负责人、版本、状态、节点数和操作。
点击“新建流程”会打开弹窗,填写流程名称、负责人和流程类型后,点击“创建并编排”,系统会进入流程设计器,并加载一个新建流程骨架。
流程编排
访问 /designer,这是项目最核心的页面。左侧是节点库,中间是 X6 画布,右侧是节点或连线属性面板,顶部提供撤销、重做、适配、清空和导出。
节点库里有开始、审批人、会签、条件判断、抄送通知和结束节点。流程管理员可以把节点拖到画布里,再通过端口连线。
待办已办
访问 /tasks,审批人可以看到审批任务列表。列表包含审批事项、金额、状态、时效和操作按钮。通过按钮表示同意,驳回按钮表示不同意。
发起审批
访问 /apply,普通员工填写审批类型、申请金额、申请部门、期望完成日期、审批标题、申请说明和附件。右侧会展示预计流转路径。
这五个页面可以用一张图串起来:
流程编排的交互设计
流程设计器启动时,会先创建 X6 画布,然后注册选择、键盘、剪贴板、历史记录和对齐线插件。
如果地址参数里没有新建模式,系统加载默认演示流程;如果包含:
mode=new则加载新建流程骨架。这个骨架包含开始节点、审批节点和结束节点,避免用户从完全空白的画布开始。
最基础的编排动作是:
从左侧拖节点 -> 放到画布 -> 拖动端口创建连线 -> 编辑节点和连线属性比如:
开始 -> 审批人 -> 结束表示申请提交后,先进入审批人处理,然后流程结束。
设计器里的操作可以拆成这条流水线:
大白话说:X6 画布负责让人“画得出来”,右侧属性面板负责让规则“说得清楚”,导出 JSON 负责让后端“读得懂”。
节点属性
点击画布中的任意节点,右侧会显示节点属性。常见配置包括:
- 节点名称
- 审批人或角色
- 条件表达式
- 通知对象
- 备注说明
不同节点代表不同审批步骤:
- 开始:流程起点。
- 审批人:某个人或某个角色处理。
- 会签:多个人一起审批。
- 条件判断:按金额、部门等条件分支。
- 抄送通知:给相关人发送通知。
- 结束:流程终点。
修改节点名称后,画布中的节点文字会同步更新。这让属性面板不只是表单,而是和画布形成了实时联动。
这些节点可以按职责理解:
节点本身表示“这一步做什么”,节点属性表示“这一步由谁做、按什么条件做、要通知谁”。
连线属性为什么重要
很多流程设计器只重视节点属性,但这个项目里连线属性也被单独做出来了。点击已有连线后,右侧会显示:
- 连线文字
- 起点节点
- 起点端口
- 终点节点
- 终点端口
这解决了一个很实际的问题:用户手动拖拽连线手柄,有时很难准确命中目标端口。更稳定的做法是选中连线后,在右侧属性面板里通过下拉框改起点、终点和端口。
比如原来是:
开始 -> 审批节点想改成:
开始 -> 审批人可以选中连线,在右侧把“终点节点”改成“审批人”,再选择终点端口。对复杂审批流来说,这种属性化编辑比纯拖拽更可控。
连线不是视觉装饰,它就是审批流转方向:
为什么要做连线属性面板?因为复杂流程里,靠鼠标拖动端点很容易接错。下拉框改起点和终点虽然看起来笨一点,但更稳定,也更适合做流程维护。
导出 JSON
点击“导出 JSON”后,系统会读取当前画布中的节点和连线,并导出结构化数据。
导出内容包含:
nodes:节点编号、节点类型、节点名称、审批人、条件表达式、备注和坐标。edges:连线编号、起点、终点和连线文字。
这里其实已经隐含了后端接入方式:前端负责把流程画成节点和边,后端可以保存这份 JSON,并在真实审批实例中根据节点和连线驱动流转。
这个边界和工作流系统很像:画布是编辑态,JSON 是协议,后端运行时消费协议。
导出的 JSON 可以理解成两张表:
记录有哪些审批步骤:节点 ID、节点类型、名称、审批人、条件表达式、备注、坐标。
记录步骤之间怎么走:边 ID、起点、终点、连线文字和端口信息。
未来可以读取 nodes 和 edges,按规则创建审批任务并推动流程流转。
举个最简单的例子:
{
"nodes": [
{ "id": "start_1", "type": "start", "label": "开始" },
{ "id": "approve_1", "type": "approver", "label": "部门经理审批", "assignee": "部门经理" },
{ "id": "end_1", "type": "end", "label": "结束" }
],
"edges": [
{ "source": "start_1", "target": "approve_1", "label": "提交" },
{ "source": "approve_1", "target": "end_1", "label": "通过" }
]
}这段数据的意思很直白:申请提交后先到部门经理,部门经理通过后流程结束。前端画的是图,后端真正需要保存的是这份结构化规则。
本地演示边界
这个项目明确是前端演示项目。所有列表数据都是静态模拟数据,新建流程只保存在当前浏览器本地。
本地存储主要保存两类内容:
- 侧边栏折叠状态。
- 流程管理中新建的流程草稿。
刷新页面后,流程管理会重新读取这些本地流程草稿;如果清空浏览器本地存储,新建流程草稿也会消失。
这种设计适合产品演示和交互验证。它先把流程管理、流程编排、待办处理和发起申请这些前端体验跑顺,不急着把后端模型一次性做重。
本地演示和真实系统的边界可以这样看:
这不是缺点,反而是这个项目目标清楚的地方:它先把“审批系统长什么样、流程怎么画”讲明白。
常用操作
流程设计器支持一些典型快捷操作:
- 撤销:
Ctrl + Z - 重做:
Ctrl + Shift + Z - 复制节点:选中后
Ctrl + C - 粘贴节点:
Ctrl + V - 删除节点或连线:选中后按
Delete - 缩放画布:按住
Ctrl或Command滚动鼠标滚轮 - 平移画布:按住
Space后拖动画布
这些快捷键让设计器更像一个真正的工作台,而不是只能点按钮的页面。
我喜欢的几个点
第一,角色路径清楚。员工、审批人、管理员、流程管理员各自关心的页面不同,产品结构没有混在一起。
第二,流程编排以节点和连线为核心。审批系统天然适合图模型,节点表示步骤,连线表示流转方向。
第三,连线属性面板做得很实用。对复杂流程来说,靠下拉框改端点比拖动手柄更稳定。
第四,导出 JSON 把前后端边界留出来了。前端可以先完成编排体验,后端以后接保存、发布、执行和版本管理。
第五,演示项目没有假装自己是完整系统。它明确不接后端、不接数据库、不含鉴权,这反而让项目目标更干净。
后续可以怎么扩展
如果要把它从前端演示推进成真正的审核系统,可以继续补:
- 流程模板保存、发布和版本管理。
- 审批实例运行时引擎。
- 用户、角色、部门和权限体系。
- 条件分支表达式校验。
- 待办任务流转、催办和超时策略。
- 审批记录、审计日志和附件存储。
- 流程 JSON 的导入、回滚和 diff。
但无论后端怎么加,前端这条边界都值得保留:用户在画布上编排节点和连线,系统把它导出为结构化流程数据。
有了这个边界,审批系统才不会只是几张静态表单,而是能逐步长成真正可配置的流程平台。
最后更新:2025-11-18
