SpringBootVue3Flowable 企业BPM流程审批全链路从表单设计、节点权限到移动审批怎么落地企业审批项目最容易低估的工作量是把“画流程图”误认为“审批平台已经完成”。真正上线时实施人员还会追问表单从哪里来部门负责人找不到怎么办审批人能改哪些字段拒绝、退回、转办按钮由谁控制审批通过后车辆、预算或资产状态谁来回写手机端为什么看得到待办却打不开业务表单▲ 审批平台的主线不是一个 Flowable API而是设计态、运行态、业务态和移动端共同闭环引言企业审批真正要交付的是“一张单走得完”工作流引擎解决的是流程实例、任务、网关和历史轨迹企业审批平台还要补齐引擎之外的产品层设计态完成模型、表单、审批人、字段权限和按钮权限发布前校验节点配置员工再填写并提交真实业务单PC 与手机围绕同一个流程实例办理流程结束后回写业务资源并保留轨迹、抄送和审计记录。本文不再把候选人、驳回算法、动态表单等单点各拆一遍而是以一张“公务用车申请”为线索把这些能力如何串成一条可交付链路讲清楚。先说明版本当前项目 BOM 使用Flowable 8.0.0后端为 Spring Boot 3.5 系列。部分历史资料仍写 Flowable 7.x实际开发应以当前yudao-dependencies/pom.xml为准。一、平台地图Flowable 是引擎三端围绕同一个审批详情工作1.1 后端、PC 和移动端各管什么后端yudao-module-bpm负责模型、部署、流程实例、任务、候选人计算、审批轨迹和状态事件。PC 管理端承担完整设计器、模型配置、发起大厅和审批详情UniApp 端复用同一套 BPM API提供待办、我的、已办、抄送和移动办理。▲ approval-detail 是三端共享的事实入口业务服务只通过 businessKey 和状态事件参与闭环三端真正共享的“单一真相源”是审批详情接口。它一次返回流程定义与流程实例已结束、进行中和未来活动节点当前用户的待办任务流程表单和业务表单字段权限当前节点允许展示的操作按钮退回目标和后续节点预测所需信息。这比让 PC、App 各自拼任务、历史、表单权限可靠得多。二、设计态第一步BPMN 和 SIMPLE 最后都要变成可部署定义流程模型列表不只是名称管理它同时展示设计器类型、绑定表单和最后发布版本。▲ 同一平台可以让技术人员使用 BPMN让业务实施人员使用 SIMPLE 节点树2.1 两种设计器解决不同复杂度BPMN(10)适合复杂网关、事件、子流程和标准建模SIMPLE(20)适合顺序审批、条件分支、会签和常见人事流程。SIMPLE 并不是另一套运行引擎它在发布时通过SimpleModelUtils.buildBpmnModel()编译成 Flowable 可识别的BpmnModel。publicvoiddeployModel(StringmodelId){BpmModelDOmodelvalidateModelExists(modelId);BpmnModelbpmnModel;if(BpmModelTypeEnum.BPMN.getType().equals(model.getType())){bpmnModelparseBpmnXml(model.getBpmnXml());}else{bpmnModelSimpleModelUtils.buildBpmnModel(model.getSimpleModel());}taskCandidateInvoker.validateBpmnConfig(bpmnModel);deployProcessDefinition(model,bpmnModel);}这里最重要的不是编译代码而是发布前校验。节点没有审批人、表达式不合法、候选人参数缺失都应该挡在发布按钮前不能等员工发起后才产生无人接收的任务。2.2 用车申请怎么画一条典型用车流程是“发起人 → 部门负责人 → 车管员 → 结束”。部门负责人来自发起人部门车管员来自指定岗位或用户组。若用车天数超过 3 天还可以通过条件分支增加行政负责人审批。流程图只表达“往哪走”并不保存车辆、出发时间、同行人等业务字段。▲ 节点上配置谁来审批表单和权限在模型的其它设计步骤完成三、设计态第二步NORMAL 与 CUSTOM 表单怎么选平台只有两类表单不需要创造第三种概念。公务用车必须校验车辆时段冲突、审批通过后锁定车辆、还车后释放因此更适合 CUSTOM。模型元数据保存formCustomCreatePath /oa/car/car-apply-info formCustomViewPath oa/car/carapply/info/index发起路径负责创建和编辑查看路径负责审批详情中的只读或按权限编辑。配置路径一旦与实际 Vue 文件不一致待办详情就会空白这类问题应修模型配置或数据不能在通用动态加载器里为脏路径堆特殊别名。3.1 业务单先保存再用 businessKey 发起CUSTOM 表单不是把所有字段塞进 Flowable 变量。通常先保存业务主表取得业务 ID再发起流程Transactional(rollbackForException.class)publicLongsubmitCarApplyBill(CarApplyBillSaveReqVOreqVO){LongbillIdsaveCarApplyBill(reqVO);MapString,ObjectvariablesbuildProcessVariables(billId);StringprocessInstanceIdprocessInstanceApi.createProcessInstance(getLoginUserId(),PROCESS_DEFINITION_KEY,billId.toString(),variables);updateProcessInstanceId(billId,processInstanceId);returnbillId;}businessKey把流程实例与业务单绑定。流程变量只放网关、候选人和摘要需要的字段不复制整张业务表。四、设计态第三步审批人不是一个 userId而是一套解析策略企业流程最容易变化的是“谁审批”。当前候选人策略覆盖角色、部门成员、部门负责人、岗位、指定用户、发起人自选、审批人自选、表单用户、表达式和空审批人处理等常见方式。用车流程可以这样配置部门负责人节点根据发起人的部门向上解析负责人车管员节点按岗位或用户组计算特殊长途用车条件分支后指定行政负责人部门负责人为空按模型配置自动通过、拒绝或转流程管理员。运行时由BpmTaskCandidateInvoker.calculateUsers()统一计算候选人而不是每个业务模块自己查一次组织表。4.1 为什么要保留“发起人自选”固定角色适合稳定流程但项目评审、跨部门会签常常需要发起人从允许范围内选人。前端选择的名单必须经过后端授权范围校验不能把用户提交的任意 ID 直接写入流程变量。4.2 空审批人必须有显式策略部门负责人离职、岗位未配置、表达式返回空集合都可能产生空审批人。平台要在设计态允许配置处理方式并在发布或运行时给出明确结果“任务创建了但没人看到”是最难排查的流程事故之一。五、设计态第四步字段权限和按钮权限都属于节点同一张用车申请发起人可以填写车辆、时间和事由部门负责人只能查看车管员可能被允许修改车辆与司机财务复核只能看到费用字段某些节点允许退回某些节点只允许同意和拒绝。5.1 两种表单有两条字段权限链NORMAL 表单把字段权限写入流程定义扩展属性运行时返回formFieldsPermissionform-create 根据disabled/hidden/required渲染。CUSTOM 表单使用BpmFormFieldPermissionDO保存字段权限业务页通过useBusinessFieldPermission和BasicForm应用。它允许复杂业务页继续使用自己的组件同时由流程节点决定哪些字段可见、只读或必填。const{fieldPermission,applyPermission}useBusinessFieldPermission(processDefinitionKey);awaitloadApprovalDetail(processInstanceId);applyPermission(formSchema.value,fieldPermission.value);5.2 操作按钮不能在页面写死审批详情底部的通过、拒绝、抄送、转办、委派、加签、退回和取消来自当前任务的buttonsSetting。▲ 同一详情页根据当前任务权限展示按钮业务页面不需要为每个节点写一套底栏前端的核心判断类似functionisShowButton(type:BpmTaskOperationButtonType){constsettingrunningTask.value?.buttonsSetting?.find((item)item.typetype,);returnsetting?.enabletrue;}按钮显隐只能改善交互后端办理接口仍要校验任务归属和当前状态不能把安全边界交给 Vue。六、运行态一个 approval-detail 接口把表单、轨迹与权限拼起来员工打开待办详情时页面不能顺序调用十几个接口再猜状态。BpmProcessInstanceServiceImpl.getApprovalDetail()聚合流程定义、实例、活动节点、任务与权限PC 和移动端都围绕这份响应渲染。publicBpmApprovalDetailRespVOgetApprovalDetail(LonguserId,StringprocessInstanceId,StringtaskId){BpmApprovalDetailRespVOdetaildoGetApprovalDetail(userId,processInstanceId,taskId);detail.setFormFieldsPermission(getNormalFormPermission(detail));detail.setBusinessFieldsPermission(getBusinessFormPermission(detail));detail.setTodoTask(findTodoTask(userId,taskId));returndetail;}它解决三个容易不一致的问题时间轴显示当前节点但按钮却来自旧任务业务表单已经只读底栏仍显示提交PC 判断可退回手机端却认为不可退回。6.1 通过任务后业务单必须收到结果Flowable 完成任务只会推动流程。业务模块还需要知道流程处于审批中、已通过、已拒绝或已取消。平台通过FlowBillService和流程状态事件把结果回写publicinterfaceFlowBillService{voidupdateProcessStatus(StringbusinessKey,Integerstatus);defaultvoidonProcessApproved(StringbusinessKey){}defaultvoidonProcessRejected(StringbusinessKey){}defaultvoidonProcessCancelled(StringbusinessKey){}}用车审批通过后业务服务锁定车辆和时段驳回或取消后释放占用。费用报销、资产领用、用印外借也各自实现自己的业务回写。审批平台不能把所有业务规则塞进 BPM 模块BPM 只负责发布事件与统一契约。七、驳回、撤回、重提与抄送四种动作不能混成“退回”这五个动作对应五种不同语义拒绝当前审批人按模型策略终止流程或退回指定节点发起人撤销流程发起人取消运行中的实例业务单同步回写取消审批人撤回已办审批人在满足条件时取回刚完成的任务驳回后重提发起人修改原业务单复用业务关系重新进入流程抄送只产生知会记录不创建待办也不代表审批同意。产品文案和状态必须区分这些动作。尤其是抄送它只让某人知情评论只是沟通审批意见才是任务办理结果。批量通过也不是“勾选后循环调用通过”。意见必填、节点需改业务字段、需要签名、需要自选下一审批人或处于加签/委派中的任务都应在资格预检中排除。八、移动审批API 可以同源业务组件却不能假装自动出现移动端审批工作台按viewType区分待办、我的、已办和抄送详情页继续读取同一个审批详情接口。▲ 手机端同样展示业务表单、审批进度和底栏操作但页面组件注册方式与 PC 不同PC 可以通过import.meta.glob按业务表单路径动态加载组件小程序构建存在静态分析限制UniApp 端采用静态 import v-if注册。新增一个 CUSTOM 移动流程通常要改三处在bpm-menu-config.ts登记processDefinitionKey、发起路径和查看组件在form-detail.vue静态导入并增加条件分支在对应pages-oa、pages-hrm等业务分包实现创建和详情页。exportconstBPM_MENU_CONFIG{oa_car_apply_bill:{mobileCreatePath:/pages-oa/car/apply/create,mobileViewComponent:OaCarApplyDetail,},};因此“PC 配完流程App 自动支持所有业务表单”并不真实。NORMAL 通用表单可以更自动化CUSTOM 复杂单据仍需要移动端适配。九、一张用车申请的完整时序这条时序里没有让业务模块直接操作 Flowable 的运行表也没有让 BPM 模块理解车辆冲突。两边通过流程实例、businessKey和状态事件协作。十、新增一类审批单据的接入清单后端创建业务主表、子表与附件关系定义稳定的processDefinitionKey保存业务单后发起流程并记录processInstanceId实现FlowBillService的状态回写对审批通过、拒绝、取消分别处理资源占用Controller 和 Service 校验租户、权限与数据范围。PCAPI 类型按后端真实 JSON 定义创建 list/info 页面业务表单支持embedded、editable和字段权限暴露校验与取值方法供审批底栏调用模型配置正确填写 create/view 路径用同一实例验证发起、待办、已办和抄送视图。移动端注册流程 key 与移动路径创建业务分包页面在审批详情静态注册业务组件处理viewType、只读态和按钮权限审批人特殊可编辑字段通过beforeApproval校验验证拒绝操作不会被业务必填字段错误拦截。十一、边界哪些能力不能宣传成“零代码”11.1 复杂业务表单仍需要开发动态表单可以覆盖请示、登记和中等复杂审批车辆冲突、预算占用、资产回写、报销分摊等业务规则必须落在独立服务中。11.2 两种设计器的能力并不完全相同SIMPLE 面向常见审批BPMN 面向标准模型和复杂控制流。不能因为最终都部署到 Flowable就宣称两者表达能力完全一致。11.3 移动端不是 PC 路由的自动镜像CUSTOM 表单需要静态注册和分包页面。新增 PC 页面后不做移动适配手机端只能看到任务壳不能完成业务办理。11.4 批量审批有资格边界需要填业务字段、签名、附加任务表单或自选下一审批人的任务应回到单条详情办理。常见问题FAQFlowable 已经提供任务 API为什么还要做 BPM 模块引擎 API 不负责业务表单、组织候选人、字段权限、按钮配置、业务状态回写和多端产品体验。BPM 模块的价值就是把这些企业能力围绕引擎组织起来。SIMPLE 设计器是不是绕开了 BPMN不是。SIMPLE 保存的是更适合业务人员理解的节点结构发布时仍会编译为 BPMN 模型并交给 Flowable 运行。NORMAL 动态表单和 CUSTOM 业务表单怎么选简单登记、请示优先 NORMAL存在复杂主子表、资源冲突、金额计算、附件规则或审批后回写时优先 CUSTOM。字段隐藏和只读只在前端做可以吗不可以。前端权限用于展示后端仍要校验当前用户、任务归属和允许修改的业务字段敏感字段不能只靠disabled。PC 能打开业务表单为什么 App 打不开PC 支持按路径动态加载UniApp 小程序端需要静态 import 和条件注册。应检查bpm-menu-config.ts、form-detail.vue和业务分包页面。结语企业审批平台的完成标准不是流程设计器能拖出几个节点而是任意一张真实业务单都能走完模型可发布、审批人找得到、不同节点看到正确字段和按钮、PC 与手机办理同一个实例、流程结果最终回到业务资源。RuoYi Office 用 Flowable 8 承载流程运行用 Vue3 设计态和审批详情组织产品能力再通过businessKey、FlowBillService与状态事件连接用车、用印、资产、报销等业务。把这条端到端主线打通后条件网关、会签、加签、抄送和批量办理才不是一堆孤立功能。如果这篇对你有用点个「在看」或收藏。打开演示地址直接查看系统。