流程设计器(BPMN)
这篇解决什么
改 BPMN 画布、节点属性和发布动作。读完能对上 bpmn-js 组件、模型 META_INFO_、分类编码,以及业务表单的两条 Vue 路径。
日常 OA / HRM 单据多用 SIMPLE 设计器。分支、调用活动、监听器、令牌模拟这类复杂图画 BPMN。接单据见 业务表单开发;四步向导见 流程配置;办理见 审批通过、不通过、驳回。
默认端口 48080,管理端前缀 /admin-api。PC 开发页 http://127.0.0.1:5800。先把引擎跑起来,见 流程功能设计。
示意图:向导把 XML 和 MetaInfo 交给 BPM 模块,发布时由 Flowable 落部署和流程定义。
从哪打开
菜单在流程中心 → 流程设置 → 流程模型。官方菜单 id:1185 目录(/bpm),1186 流程设置,1193 流程模型。路由 /bpm/manager/model。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| 模型列表 | 按分类分组,行内修改 / 发布 / 更多 | ruoyi-office-vben/apps/web-antd/src/views/bpm/model/index.vue |
| 分类卡片 | 拖拽排序、跳转定义列表 | .../views/bpm/model/modules/category-draggable-model.vue |
| 四步向导 | 新建 /bpm/manager/model/create,修改 /bpm/manager/model/:type/:id | .../views/bpm/model/form/index.vue |
| 模型 API | /bpm/model/** | .../src/api/bpm/model/index.ts |
| 模型接口 | @RequestMapping("/bpm/model") | ruoyi-office/yudao-module-bpm/.../controller/admin/definition/BpmModelController.java |
按钮权限:bpm:model:query、bpm:model:create、bpm:model:update、bpm:model:deploy、bpm:model:delete。列表登录即可查;改图、发布必须有对应按钮。

本系统截图:流程中心 → 流程设置 → 流程模型。按「OA协同办公」等分类展开,表单地址列就是自定义提交路由。
流程模型
Flowable 的模型头在 ACT_RE_MODEL。图标、表单类型、可见范围、打印模板等不在标准列里,而是 JSON 写进 META_INFO_,结构和 BpmModelMetaInfoVO 一致。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
ACT_RE_MODEL | KEY_、NAME_、CATEGORY_、META_INFO_、DEPLOYMENT_ID_ | Flowable 仓库表 |
BpmModelMetaInfoVO | icon、type、formType、自定义路径、管理员、打印模板 | .../vo/model/BpmModelMetaInfoVO.java |
BpmModelSaveReqVO | 保存时再带 key / name / category / bpmnXml / simpleModel | .../vo/model/BpmModelSaveReqVO.java |
| 创建 | POST /bpm/model/create | BpmModelController#createModel |
| 修改 | PUT /bpm/model/update | BpmModelController#updateModel |
| 部署 | POST /bpm/model/deploy | BpmModelController#deployModel |
新建默认 type = SIMPLE。要画 BPMN,在第一步把流程类型改成 BPMN 设计器(BpmModelTypeEnum.BPMN = 10)。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
BPMN 10 | bpmn-js 画布,XML 存在 bpmnXml | BpmModelTypeEnum |
SIMPLE 20 | 仿钉钉节点串,JSON 存在 simpleModel | 同上 |

本系统截图:第一步基本信息。流程类型在 BPMN / SIMPLE 之间切换;标识新建后不能改。
向导四步:基本信息 → 表单设计 → 流程设计 → 更多设置。第三步才挂设计器。改完先「保存」,再点右上角「发布」。
BPMN 画布
type = 10 时,第三步渲染 BpmModelEditor:左侧 MyProcessDesigner(bpmn-js 的 Modeler),右侧 MyProcessPenal。预览用另一套 MyProcessViewer(bpmn-js 的 Viewer),详情页的流程图高亮走它。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| 第三步切换 | BpmModelType.BPMN 用 BPMN,否则用 SIMPLE | .../model/form/modules/process-design.vue |
| 编辑器壳 | 注入 processData / modelData,保存回写 XML | .../form/modules/bpm-model-editor.vue |
| 画布 | BpmnModeler,prefix 为 flowable | .../components/bpmn-process-designer/package/designer/ProcessDesigner.vue |
| 属性面板 | 常规、表单、任务、会签、监听器、自定义配置 | .../package/penal/PropertiesPanel.vue |
| 预览 | 详情里高亮当前节点 | .../package/designer/ProcessViewer.vue |
| 详情引用 | bpm-viewer.vue | .../processInstance/detail/modules/bpm-viewer.vue |
左侧工具栏和选中菜单被改成默认落「用户任务」,不要再拖出空白的普通 Task。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| 左侧面板 | CustomPaletteProvider | .../designer/plugins/palette |
| 节点菜单 | CustomContentPadProvider | .../designer/plugins/content-pad |
| 空图模板 | DefaultEmptyXML,process 的 id / name 用模型 key、名称 | .../designer/plugins/defaultEmpty |
| 令牌模拟 | bpmn-js-token-simulation | ProcessDesigner.vue |
示意图:画布改 XML,面板改节点扩展属性;保存进模型,发布才生成定义。

本系统截图:第三步流程设计。左侧是 bpmn-js 工具栏和令牌模拟,右侧是属性折叠面板。
process 的 id 就是模型 key
发布时 ProcessDefinition.key 取 BPMN 里 <process id>。和模型 key 不一致会抛 PROCESS_DEFINITION_KEY_NOT_MATCH。名称同理。向导把 process-id / process-name 传给设计器,不要在 XML 里手改成另一套。
节点配置
选中用户任务后,右侧按折叠项改。标准 BPMN 属性写在元素上;拒绝策略、空人、按钮、字段权限写在 extensionElements。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| 常规 | 节点 id、名称 | package/penal/base/ElementBaseInfo.vue |
| 表单 | formKey 绑流程表单 id,审批时补填 | package/penal/form/ElementForm.vue |
| 任务 | 候选人策略、跳过表达式 | package/penal/task/task-components/UserTask.vue |
| 多人审批 | 会签 / 或签 / 依次 | package/penal/multi-instance/ElementMultiInstance.vue |
| 执行监听器 | 节点进出时调 Java / 表达式 | package/penal/listeners/ElementListeners.vue |
| 任务监听器 | 仅 UserTask | package/penal/listeners/UserTaskListeners.vue |
| 自定义配置 | 拒绝、空人、与提交人相同、按钮、签名、意见、字段权限 | package/penal/custom-config/components/UserTaskCustomConfig.vue |
| 流转条件 | 网关出线上的表达式 | package/penal/flow-condition/FlowCondition.vue |
节点上的「表单」只支持流程表单。formKey 存的是 bpm_form.id。业务表单已经在第二步用路由绑死,审批详情按 formCustomViewPath 嵌业务页,不会在节点上再挂一张业务 Vue。
候选人、会签的完整策略见后续「选择审批人」「会签、或签、依次审批」篇。这里只要保证每个 UserTask 有名称,并且配了候选人。
第一个用户任务不能「审批人自选」
deployModel 校验 BPMN 时,取用户任务列表的第 0 个。策略若是 APPROVE_USER_SELECT(当前人指定下一节点审批人),直接发布失败。SIMPLE 设计器的第 0 个节点固定是发起人,所以它校验的是第 1 个用户任务。
用户任务必须写名称
validateBpmnXml 还要求存在 StartEvent。缺开始事件或某个 UserTask.name 为空,发布会被拦住。
第四步「更多设置」改的是模型级 MetaInfo,不是单个节点。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| 流程编号规则 | processIdRule:前缀 / 中缀 / 序列长度 | BpmModelMetaInfoVO.ProcessIdRule |
| 打印模板 | printTemplateSetting | 同上 PrintTemplateSetting |
| 自动去重 | autoApprovalType | BpmAutoApproveTypeEnum |
| 标题 / 摘要 | 待办列表怎么展示 | TitleSetting / SummarySetting |
| HTTP 通知 | 流程或任务前后回调 | HttpRequestSetting |
| 前端表单 | 第四步页 | .../model/form/modules/extra-setting.vue |
分类与自定义表单路径
分类是独立表,不是 Flowable 自带的。模型 category 存的是 bpm_category.code。发布时 createProcessDefinition 会再 setProcessDefinitionCategory,因为引擎读 XML 的 targetNamespace,对不上我们的分类编码。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| 分类表 | name / code / status / sort | bpm_category,BpmCategoryDO |
| 分类接口 | @RequestMapping("/bpm/category") | BpmCategoryController |
| 列表分组 | getCategorySimpleList + model.category === code | views/bpm/model/index.vue |
| 分类页 | 流程中心 → 流程设置 → 流程分类 | views/bpm/category/ |
第二步选表单类型:NORMAL = 10 流程表单,CUSTOM = 20 业务表单。业务表单必须填两条路径。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
formCustomCreatePath | 发起用的 Vue 路由,例如 /oa/seal/seal-apply-info | BpmModelMetaInfoVO |
formCustomViewPath | 审批详情嵌的 组件路径,例如 /oa/seal/sealapply/info/index.vue | 同上 |
| 前端校验 | CUSTOM 时两条都必填 | .../form/modules/form-design.vue |
| 发起跳转 | 大厅点卡片走 formCustomCreatePath | views/bpm/processInstance/create/ |
| 详情嵌页 | formCustomViewPath 动态 import | views/bpm/processInstance/detail/index.vue |
流程表单发布时还会按 menuConfig 同步列表菜单和创建按钮。业务表单走既有业务菜单,不要提交 menuConfig。
两条路径不能填成同一种
提交路由是浏览器地址,查看地址是 views/ 下的文件。填反以后:发起中心跳 404,审批详情空白。用印申请对应 /oa/seal/seal-apply-info 和组件 .../sealapply/info/index.vue。
发布成流程定义
POST /bpm/model/deploy 进 BpmModelServiceImpl#deployModel。同一模型再次发布会挂起旧定义,只留最新一份可发起。
示意图:先校验 XML / 表单 / 候选人 / 子流程,再部署;旧版本挂起。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| 校验 XML | 开始事件、用户任务名称、首个任务策略 | BpmModelServiceImpl#validateBpmnXml |
| 校验表单 | NORMAL 要有 formId,CUSTOM 要有两条路径 | validateFormConfig |
| 校验候选人 | 解析 BPMN 上的分配规则 | taskCandidateInvoker.validateBpmnConfig |
| 子流程 | CallActivity 的 key 必须在本租户已有激活定义 | validateCalledProcessDefinitionsDeployed |
| 部署 | repositoryService.createDeployment(),禁用 schema 校验 | BpmProcessDefinitionServiceImpl#createProcessDefinition |
| 挂起旧版 | 按模型上一个 deploymentId | updateProcessDefinitionSuspended |
| 菜单 | NORMAL 时 syncOnDeploy | BpmProcessFormMenuSyncService |
| 锁类型 | 首次发布后 formTypeLocked = true | deployModel 末尾 |
引擎表 ACT_RE_PROCDEF 没有 MetaInfo。扩展字段另表 bpm_process_definition_info,发布时从 VO 拷过去。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
process_definition_id | 对应 ProcessDefinition.getId() | BpmProcessDefinitionInfoDO |
model_id / model_type | 回到模型和 BPMN / SIMPLE | 同上 |
category | 分类编码,引擎自己的 category 靠不住 | 同上 |
form_type 与路径 | 发起大厅、详情嵌页都读这里 | 同上 |
simple_model | SIMPLE 的快照;BPMN 可空 | 同上 |
| 定义接口 | @RequestMapping("/bpm/process-definition") | BpmProcessDefinitionController |
| 定义页 | /bpm/manager/definition?key= | views/bpm/model/definition/index.vue |
发起流程只认激活定义。模型行上的「流程定义」看历史版本;「更多」里的停用实际改的是已部署定义的状态(PUT /bpm/model/update-state)。
表单类型发布后会锁
NORMAL 和 CUSTOM 第一次发布成功就不能互切,避免菜单和路由对不上。逃生口是 POST /bpm/model/unlock-form-type,不要当常规操作。
扩展时注意
加节点属性,优先扩 UserTaskCustomConfig 和 Flowable 的 extensionElements,不要改 bpmn-js 核心。新候选人策略加在任务面板和后端 BpmTaskCandidateStrategyEnum,两边常量要成对。
跨租户搬模型用 GET /bpm/model/export 或 /export-portable(角色候选人改成 role code),再 POST /bpm/model/import。导出会清掉不能跨租户复用的审批人。
画了 CallActivity,被调流程的 key 必须先在本租户发布。否则校验阶段就失败,不会拖到运行时才报系统异常。
配置与操作
管理员在 流程模型 新建或修改,四步向导里把类型选成 BPMN,第三步画节点,第四步保存后必须点发布。未发布的 XML 只存在模型草稿。
表单类型第一次发布成功会锁。改自定义路径、分类、可见范围也要再发布,发起大厅才认激活定义。
开启见 流程功能设计。截图见上文列表和画布。
