简介:这是一套基于Java的低代码BPM工作流引擎项目资源,集成表单引擎、流程引擎与权限控制,适合国内企业快速搭建业务审批与自动化流程。包内含2000个文件,其中Java源代码约1694个,构成核心业务逻辑;另有HTML/CSS/JS等前端界面文件、XML与properties配置、SQL数据库脚本及Markdown说明文档,整体约150.96MB,能够支撑从部署到二次开发的完整流程。压缩包目录结构清晰,适合开发者直接导入项目进行功能扩展,也适合运维人员根据文档调整配置。已有177人学习下载,对于希望深入理解Activiti/JFlow等流程引擎实现原理,或需要一套“开箱即用”的中国化BPM解决方案的Java工程师而言,具有较高的参考价值。引擎本身强调配置灵活和易集成,可通过低代码方式快速生成表单与流程,大大降低企业信息化建设的技术门槛。
1. 为什么“适合中国国情”这句话,才是选工作流引擎的关键
我们给一家制造企业做审批中台,需求单上有三行字:会签、逐级审批、退回到发起人后允许改单重提。把需求丢给技术选型组,组长拿 Activiti 试了一周,回来直摇头。这个场景在 BPM 领域非常典型:国外的 Activiti 流程引擎模型严谨,但“适合中国国情”从来不是它设计的出发点。标题里这句话,实际上是国内做低代码开发平台时工作流引擎选型的核心分水岭。今天要讲的,就是这条线上的主力方案:Java 版驰骋 BPM(JFlow)——表单引擎加流程引擎加权限控制打包好的工作流引擎,方便集成、配置灵活,在国内项目里落地概率比从 Activiti 上二次开发高得多。下面只按一线集成它的常规做法来讲。
2. 先拆引擎模型:JFlow 为什么把表单、流程、权限打包在一起
在动手集成之前,得先把 JFlow(驰骋 BPM 的 Java 版)的设计模型讲清楚。这个模型决定了后面所有配置和二次开发的基本盘。国外引擎和国内引擎的差别,不在画流程图的体验上,而在“谁帮你把周边配套做完”这件事上。
2.1 Activiti 是流程虚拟机,JFlow 是审批工作台
Activiti 的优势在 BPMN 2.0 标准、事件机制和执行引擎的灵活性,本质是一个流程虚拟机。流程怎么走、网关怎么分支、Timer 怎么触发,它都能处理得很好。但它刻意不回答另一些问题:表单怎么渲染、待办列表怎么查、谁能看到哪个流程实例、审批人怎么按组织架构解析。用 Activiti 做一个能上线的审批系统,不是“装好就能用”,而是从页面、接口到数据权限全重做一遍。等于只买了发动机,车身、方向盘、座椅全得自己焊。
JFlow 的定位不一样,它更像一个审批工作台。表单引擎、流程引擎、权限控制三件事默认绑定在一起,同时以 Java 库的形式对外暴露,方便嵌进 Spring 生态。对开发者的意义是:接到项目时不用先写一套组织权限和待办中心,直接在这个底座上扩展业务表。这正是低代码开发平台场景下它比 Activiti 好用的核心原因——低代码平台要的是“拖出来能跑”,不是“画完图还要写三套代码”。
2.2 表单引擎:不只是表单,是数据契约
表单引擎做的事比“做个页面”重。拖控件生成界面之后,它会同时整理出对应的数据库字段结构、控件权限(可读、可写、隐藏)和表单状态。也就是说,表单不只是 UI,它是单据的数据契约。
一单业务在 JFlow 里的跑法是这样的:发起人打开一张绑定了流程的表单,填写后引擎自动创建流程实例,并把表单数据作为流程实例的上下文;审批时,每个节点的表单可以一样,也可以在流程设计器里做节点级别的表单差异化配置。比如经办节点能看到发票明细的增删按钮,审批节点只能看只读汇总。
我一般会先把主表字段定下来,再拖控件,最后绑定流程。这个顺序比边画边改省事得多。表单设计器里生成的字段,默认会落到引擎管理的业务表里,开发者不需要手工建表。如果业务表已经存在,只需要把表单字段名和表字段名对齐,引擎同样能接管数据的读写。
2.3 流程引擎:节点、方向、规则是“中国式审批”的落点
中国式审批和欧美流程最大的区别在规则的缠绕程度。Activiti 上要费劲实现的退回、撤回、会签、加签、跳过节点等能力,在 JFlow 里大多是内置的节点属性和方向属性。几类最常见的规则:
| 节点属性 | 可选值举例 | 典型业务场景 |
|---|---|---|
| 审批人来源 | 发起人部门领导 / 指定角色 / 指定人员 | 差旅申请按部门经理审批 |
| 退回规则 | 退回上一节点 / 退回发起人 / 退回指定节点 | 财务退回经办人改单 |
| 会签规则 | 按百分比 / 按票数 / 全部通过 | 合同多方评审 |
| 加签方式 | 前加签 / 后加签 / 并签 | 供应链流程临时增加法务审批 |
| 取回限制 | 是否允许节点撤销 | 发起后发现填错主动撤回 |
这一组规则是产品定义阶段就做好的,不是开发者从流程引擎 API 层面去拼。所以国内项目里的审批需求,JFlow 的匹配度往往比 Activiti 高。会签、或签、加签、退回,每一类都对应一个明确的属性配置项。这也是标题里“配置灵活”四个字的真正落点。
2.4 权限控制:组织模型与数据权限的双轨约束
权限不是一套独立的 RBAC 按钮,而是两轨并行。第一轨是组织模型:引擎默认带一套部门、岗位、用户模型,你可以把企业微信、钉钉或自研系统的组织数据同步过来,按部门、按岗位授权。第二轨是数据范围:同一个流程,不同人看到的数据不同。“只看自己发起的”“看本部门的”“看本岗位处理的”,这些在引擎里直接控制待办和已办的可见性。
这两轨合起来构成引擎级权限。“方便集成”的正确理解是:它不替换你的权限体系,而是作为审批域的权限执行点。业务系统把当前用户上下文传进来,引擎负责在流程节点和数据范围上做判断。搞清楚这一点,后面做组织同步的时候就不会走偏。
3. 把 JFlow 装进 Spring Boot:最小集成与第一条流程
标题里写着“方便集成”,但这四个字得落到工程里才算数。下面按我常用的集成路径讲,从工程接入讲到跑通第一条流程。
3.1 先搞定接入方式:Servlet 映射还是组件调用
Java 版驰骋 BPM 常见的交付形态是一个独立的 Web 应用,自带门户和设计器,对外暴露 HTTP 协议接口。集成的常见做法有两种:第一种,把引擎作为独立服务部署,业务系统通过 HTTP 接口调用;第二种,把引擎模块嵌入业务系统的 Web 工程,由引擎的 Servlet 统一接管门户路径。
我偏向第二种,尤其是项目里已经有统一认证、统一权限的场景。做法是:把引擎 jar 包放到工程的 lib 目录,在 Spring Boot 里注册引擎 Servlet,指定 URL 映射,再把数据源指向初始化好的业务库。一个最小接入的配置长这样:
@Bean public ServletRegistrationBean<Servlet> bpmServletRegistration() { // 引擎的 Servlet 类由发行包的 jar 包提供,这里只做 URL 映射和参数注入 ServletRegistrationBean<Servlet> registration = new ServletRegistrationBean<>(new BPMEngineServlet(), "/WF/*", "/Comm/*"); registration.setName("bpmEngine"); registration.setLoadOnStartup(1); // 引擎需要知道租户标识和门户路径,用 init 参数传入,具体参数名以发行包说明为准 registration.addInitParameter("bpm.tenantId", "default"); registration.addInitParameter("bpm.webRoot", "/wfengine"); return registration; }逻辑说明:核心是把引擎 Servlet 的映射路径收缩到/WF/*、/Comm/*这类带前缀的路径下,避免和 Spring Boot 自身的接口互相抢占。loadOnStartup保证 Web 应用启动时就装载引擎的缓存,避免第一次访问时出现初始化延迟。
参数说明:URL 映射前缀尽量用一个独立上下文,引擎的登录页、设计器都在这套前缀下访问。bpm.tenantId用于多租户场景的租户隔离,单租户填 default 即可;bpm.webRoot是门户相对路径,用于生成页面跳转链接。这两个参数名每个发行版可能略有差异,以实际包内的说明为准。一线常见的翻车是把/全量交给引擎,结果业务接口全部被接管,顺手还跟安全框架撞了路径。
3.2 先把组织模型建起来,再谈流程
启动之后,第一次要做的事是进引擎门户,用管理员账号登录,然后把组织模型搭建出来:创建部门树、岗位清单、用户账号。这里有一个关键建议:不要手工把业务用户在这套模型里重录一遍,而是把业务系统的用户表通过接口或定时任务同步过来。至少先把“部门—岗位—用户”三层建好,审批人范围才能被准确解析。
组织同步这件事,我在第 6 章会展开讲。这里先提醒一个容易忽略的点:同步不是只同步用户名单,还要同步“用户挂在哪个部门、哪个岗位”。很多项目走流程时报“未找到审批人”,根因就是组织树上有部门、有账号,但账号没有挂到任何岗位下,解析不到人。
3.3 第一条流程:发起、审批、归档
在引擎设计器里建流程的步骤大体是这样:
- 新建流程,填流程编号和名称。
- 画节点:发起节点、审批节点、结束节点。
- 配置审批节点的审批人范围,比如“部门经理”。
- 发布流程。
- 用测试账号发起流程,模拟审批,在待办列表里确认流转。
这个过程花不了十分钟,但这一步验证的是整条链路:登录、组织数据、表单绑定、节点流转、待办生成。任何一个环节有问题都会在这个最小流程上报出来。跑通之后再看日志确认流转轨迹,常见做法是过滤引擎关键字:
# 引擎日志通常在应用日志的 bpmEngine 通道输出,按关键字过滤最有效 grep -E "StartFlow|Node|审批人|eng_node|Flow" app.log | tail -n 50逻辑说明:StartFlow对应流程发起动作,Node对应当前节点编号,审批人是引擎打出的审批人解析结果。这条命令能快速看到一条流程从发起到落库的完整轨迹。
参数说明:-E表示扩展正则,tail -n 50只取最后 50 行。实际排查时把关键字换成你的流程编号更精确,比如grep "Flow_20250101",能直接把某条具体流程的日志全捞出来。最小流程跑不通,九成问题出现在组织模型或者表单绑定,这两处优先查。
4. 做一条能投产的审批流:表单、会签、退回怎么配
跑通最小流程之后,就得面对真实业务了。这一章往后考虑的都不是“能不能跑”,而是“生产环境怎么设计”。产线上的配置不是点哪里的问题,而是每个参数背后的口径问题。
4.1 从一张带明细的表单说起:主从表与字段权限
大部分国内审批单不是单表,是主从表结构。报销单头有报销人、报销部门、总金额,从表有费用明细行。表单设计器支持主从表,做法是主表对应主记录,从表对应明细集合。配置的要点不在画控件,而在给表单字段设置“节点可见性”和“编辑权限”。
比如报销单里的金额字段:经办节点可编辑,审批节点只读;退回发起人后,总金额允许重新计算。这属于字段级权限,是权限控制的一部分。节点可见性在流程节点上配置,表单本身不写死。这样设计的好处是,同一张表单在不同节点呈现不同状态,而不是为每个节点单独做一套表单,维护成本差一个量级。
4.2 会签节点:三种模式怎么选
会签是“多个审批人同时收到单据,收齐意见后按规则合并结果”。设计器里通常有三种模式:全部通过、百分比通过、票数通过。全部通过要求所有会签人同意;百分比通过达到设定比例即通过;票数通过达到指定票数即通过。
配置时需要注意的参数有:会签范围(按角色、按部门)、会签人数上限、超时是否自动跳过、是否允许弃权。实际项目里最迷惑的是“百分比会签的分子是什么”——是全部应参与人数,还是实际参与人数。两种口径结果完全不同,比如 5 人应参与、3 人实际参与,按应参与算需要 3 票,按实际参与算 2 票就可能通过。我一般会在需求确认阶段锁定口径,并在设计器的节点注释里写明,免得后续上线运营扯皮。
4.3 退回与加签:把人治翻译成规则
退回规则有两条容易踩的线:一是退回目标,二是退回后是否允许原路返回。退回目标有三种常用设置:退回上一节点、退回发起人、退回指定节点。退回上一节点适合逐级退回,退回发起人适合“填错了重新改”。项目管理里需求经常是“退回到某一层,那一层改完后流程接着走”,不是全部推翻重来。
加签则是流程已走到某个节点,临时需要增加审批人。JFlow 里常见做法是:当前审批人在处理界面上加签,加签人审批完后回到原节点继续流转。加签分为前加签、后加签、并签。供应链里“法务临时介入”就是典型的后加签场景。配置上只需要在节点属性里打开加签开关,并限定加签范围即可。这里给一组报销单场景的节点参数参考:
| 配置项 | 报销单场景取值 |
|---|---|
| 审批人来源 | 发起人部门经理 |
| 退回规则 | 退回上一节点 |
| 允许取回 | 开启 |
| 表单编辑权限 | 经办可写,审批只读 |
| 加签 | 开启后加签,范围限法务、财务 |
这套组合几乎覆盖 80% 的行政类审批单。做需求时先把这张表填出来,再进设计器配置,效率比边问边配高很多。
5. 生产环境集成 JFlow 常遇到的 5 个坑与排查思路
二开框架本身不是难事,难在产线上的坑。以下五条,是我在实际项目里踩过或帮别人排查过的,每条按“现象、原因、解决”展开。
5.1 发起后没有产生流程实例
现象:表单数据保存成功,但待办列表为空,流程实例查不到。
原因:最常见的是表单没有正确绑定流程版本。流程发布前改了流程定义,但表单仍然引用旧版本;或者发起入口拿到的流程定义是未发布状态。其次是主键生成策略冲突,业务表主键和引擎实例主键重复。
解决:先去流程管理里核对“表单—流程版本”绑定关系,确认发布状态;再用grep "StartFlow"看发起动作是否到达引擎。如果日志里只有表单保存记录、没有流程创建记录,问题就在绑定关系上。
5.2 审批人解析为空,报“未找到审批人”
现象:配置了“审批人是发起人部门经理”,走到节点时报未找到审批人,流程挂住。
原因:组织模型三层中,用户没有挂到该部门的岗位下;或者“部门经理”这个岗位没有分配任何用户。看起来组织树很完整,实际岗位关系是空的。
解决:在设计器的“审批人计算”预览界面里看解析结果,逐个检查“部门—岗位—用户”的挂接。这个界面会直接把解析出来的人员名单列给你,空名单就是挂接问题,不用去翻底层表。
5.3 会签百分比和预期不一致
现象:配置了 50% 通过,实际票数达到 50% 却没通过,或者不到 50% 就通过了。
原因:分子分母口径没对齐。若是“实际参与人数”口径,有人超时未办,分母变小,比例就会偏差;若是“应参与人数”口径,缺勤的人不会被剔除,容易卡住流程。
解决:在节点配置里固定口径,选“应参与人数”还是“实际参与人数”,并在节点注释写明。如果超时未办是常态,建议同时打开“超时自动跳过”,避免分母长期失真。
5.4 并行节点退回报“节点实例重复”
现象:流程走到并行分支尽头,某分支被退回,流程控制台报节点实例重复或状态冲突。
原因:退回目标选成了“退回上一节点”,而上一节点是并行分支。并行分支各支路都被退回,汇聚点收到多次状态变更,引擎无法合并。
解决:把退回目标改成“退回到汇聚后的上一节点”,或者直接退回到发起人重走。并行分支的退回规则,要在测试环境用双分支流程提前压一遍,别等上线了再试。
5.5 登录跳转 404,页面样式丢失
现象:集成到 Spring Boot 后,引擎页面能打开,提交登录时 404,或者页面没有样式。
原因:两层原因最常见。第一,安全框架拦截了引擎 Servlet 的路径,登录请求没到达引擎;第二,URL 映射前缀和静态资源路径不一致,登录跳转回门户路径时找不到页面。
解决:先直连 IP 加端口测试,确认引擎本身没问题,再逐层叠加安全框架。Security 配置里把引擎前缀放行,静态资源路径保持和门户前缀一致。排这种问题,先绕过安全层验引擎,再绕过代理层验安全层,一次只变一个变量。
6. 组织架构同步:一个能规避三年返工的集成技巧
最后落一个高阶技巧:把业务系统的组织架构做成动态同步。标题里强调“方便集成、配置灵活”,但正因如此,很多团队把组织同步做成一次性导入。项目上线后部门调整、人员调岗、离职,全靠手工去引擎后台改,三个月后组织模型和业务系统完全对不上,流程审批人开始解析错人。
这里说的同步,不是写一个全量替换 Job,而是维护一张映射表:
| 字段 | 说明 |
|---|---|
| biz_user_id | 业务系统用户主键 |
| engine_user_no | 引擎侧账号 |
| dept_code | 当前部门编码,以源系统为准 |
| sync_status | 同步状态:sync / pending / error |
| last_sync_time | 最后同步时间,作为增量拉取的游标 |
同步策略用“每日增量 + 每周全量对账”。增量脚本每晚跑一次,处理人员新增、调岗、离职;全量对账每周跑一次,把两边数据比对,纠偏遗漏。增量部分的核心逻辑是幂等,同一变更重复执行不能产生副作用:
public void syncIncremental() { // 以 lastSyncTime 为游标,从业务系统拉取组织变更 List<OrgDiff> diffs = bizOrgClient.fetchDiffs(lastSyncTime); for (OrgDiff diff : diffs) { if ("dept_change".equals(diff.getType())) { engineOrgService.moveDept(diff.getEngineDeptNo(), diff.getNewParentDeptNo()); } if ("user_leave".equals(diff.getType())) { engineOrgService.disableUser(diff.getEngineUserNo()); } // 同步完成才推进游标,避免失败后漏拉 mappingRepo.save(new SyncLog(diff.getBizUserId(), diff.getEngineUserNo(), "sync", now())); lastSyncTime = diff.getChangeTime(); } }逻辑说明:fetchDiffs按游标拉取变更列表,moveDept和disableUser是对引擎侧组织的两个标准操作。同步只处理“组织关系”,不直接改业务表数据。
参数说明:lastSyncTime是增量游标,每次只拉这个时间点之后的变化,减少接口压力。sync_status记为 error 的变更要有补偿机制,我一般会在第二天增量开始时重放上一轮 error 记录,防止漏同步。
最早那版项目,我牵头直接在引擎后台上手工建了一百多个账号,三个月后组织调整,两套系统同步改,改一次出一回错,运维同事差点跟我翻脸。之后养成的习惯是:组织同步和流程配置放同一个迭代设计,映射表先建,同步脚本先写,再上流程。血泪经验,希望帮到你。
本文还有配套的精品资源,点击获取