ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RuoYi-Vue-Plus集成Flowable工作流:架构设计与工程实践

RuoYi-Vue-Plus集成Flowable工作流:架构设计与工程实践 简介本资源是一个基于 RuoYi-Vue-Plus 框架深度扩展的 Flowable 工作流二次开发项目面向 Java 后端开发者、低代码平台学习者及高校毕业设计群体聚焦工作流引擎集成、在线表单动态构建与可视化流程编排等核心痛点。压缩包共 1198 个文件涵盖 502 个 Java 类支撑流程引擎、任务调度与权限适配、248 个 JS 脚本与 132 个 Vue 组件实现前端流程图渲染、表单设计器及审批界面辅以 XML 流程定义、SQL 初始化脚本、YML 配置及 Nginx/Redis 等部署配置文件整体体积为 10.81MB。目前已有 2357 人学习下载适合用于理解企业级工作流系统架构、掌握 Flowable 与 Spring Boot 深度整合实践以及快速搭建含表单流程审批的后台管理原型。项目采用 MIT 协议开源虽处于持续开发阶段但已提供完整可运行的流程建模、实例启动、任务办理与历史追踪能力。1. 项目概述为什么要在RuoYi-Vue-Plus上扩展Flowable如果你正在寻找一个既能快速搭建后台管理系统又需要强大工作流引擎支持的项目方案那么将RuoYi-Vue-Plus与Flowable工作流引擎深度整合绝对是一个值得投入精力的方向。我最近刚完成一个中型OA系统的升级核心需求就是要把原来手动流转的审批流程全部线上化、自动化。在技术选型阶段我对比了Activiti、Camunda和Flowable最终选择了Flowable 6.x版本并决定基于我们团队熟悉的RuoYi-Vue-Plus框架进行二次开发。原因很简单RuoYi-Vue-Plus提供了开箱即用的前后端分离架构、完善的权限体系和代码生成器能极大缩短基础模块的开发周期而Flowable作为Activiti的衍生品不仅完全兼容BPMN 2.0标准其轻量级、高性能以及对Spring Boot的友好支持让它成为嵌入现有系统的最佳选择。这个项目的核心目标不仅仅是“能用”而是要“好用”。我们不仅要实现流程的定义与执行更要打造一个让业务人员也能轻松上手的可视化流程设计器和表单设计器。这意味着我们需要在RuoYi-Vue-Plus优雅的Admin管理界面中无缝集成Flowable Modeler的设计能力并构建一套支持动态渲染、数据绑定的在线表单系统。最终我们实现了一个功能丰富的工作流平台支持从流程建模、表单设计、任务处理到流程监控的全生命周期管理。对于开发者而言它提供了清晰的API和扩展点对于最终用户如部门经理、HR它提供了直观、拖拽式的操作界面。接下来我将详细拆解整个二次开发过程中的核心思路、关键技术实现以及那些只有踩过坑才知道的宝贵经验。2. 整体架构设计与技术选型考量当我们决定将Flowable嵌入RuoYi-Vue-Plus时首先要解决的是架构融合问题。RuoYi-Vue-Plus本身是一个前后端分离的权限管理系统后端基于Spring Boot、Mybatis-Plus前端基于Vue3、Element-Plus。而Flowable也是一个Spring Boot应用它自带REST API和管理界面Flowable Modeler和Flowable Task。直接部署两个独立应用显然不行我们需要将它们“拧”成一个整体。2.1 融合策略嵌入式引擎与界面集成我采用的策略是“嵌入式引擎 界面深度定制”。嵌入式Flowable引擎我们不独立部署Flowable应用而是将Flowable作为一系列Jar包依赖引入到RuoYi-Vue-Plus的后端工程中。通过Spring Boot自动配置将Flowable的流程引擎、各种Service如RepositoryService、RuntimeService、TaskService注入到Spring容器中。这样Flowable的所有数据库表以ACT_开头将与RuoYi的业务表共存于同一个数据库实例中通过Mybatis-Plus的数据源进行统一管理。这种方式的优点是数据一致性高事务管理方便性能损耗小。界面集成与改造Flowable原生的Modeler流程设计器和Task任务应用是独立的AngularJS应用风格与我们的Vue3Element-Plus前端格格不入。因此我放弃了直接嵌入这些原生UI的想法转而采用“功能借鉴 前端重绘”的策略。流程设计器我们保留了Flowable官方提供的bpmn-js这个核心的BPMN 2.0图形化建模库。它是一个纯前端的JavaScript库与框架无关。我们在Vue3项目中引入bpmn-js并基于它封装成自己的Vue组件。同时我们只取用了Flowable原设计器的“属性面板”逻辑但UI完全按照Element-Plus的规范重新开发。这样设计器在视觉和交互上完全融入了RuoYi-Vue-Plus的管理后台。表单设计器Flowable原生对动态表单的支持比较弱。我们决定自研一个更符合国内业务场景的在线表单设计器。核心思路是采用JSON Schema来描述表单结构字段、类型、校验规则并开发一个可视化的拖拽界面让用户配置表单。前端根据JSON Schema动态渲染出真实的Form表单。这套设计器与流程节点绑定实现了“一个节点一个表单”。注意这里有一个关键决策点。为什么不直接用Flowable的REST API对接其原生UI因为原生UI功能固定定制化能力弱且与现有系统风格迥异用户体验割裂。深度集成虽然前期开发量较大但带来了统一的用户体验和极强的扩展性从长远看维护成本更低。2.2 技术栈明细与版本锁定清晰的版本是稳定性的基石。以下是我们项目最终使用的核心依赖版本经过生产环境验证组件版本选型理由RuoYi-Vue-Plus5.X (基于Spring Boot 2.7.x)社区活跃文档齐全集成了Sa-Token权限、Redis缓存、多数据源等实用模块。Flowable6.8.0相较于Activiti 7Flowable 6社区更活跃对Spring Boot 2.x支持更稳定。6.8.0是一个长期支持版本。Spring Boot2.7.18与RuoYi-Vue-Plus及Flowable 6.8.0版本兼容性最佳。前端框架Vue 3.2 Element-Plus 2.3RuoYi-Vue-Plus前端标准技术栈生态丰富。BPMN设计器bpmn-js 8.7Flowable官方推荐且维护的BPMN 2.0建模库功能强大。表单设计器自研基于Vue JSON Schema高度定制化能满足复杂业务表单需求如级联选择、表格子表单等。版本锁定的教训在项目初期我曾尝试使用Spring Boot 3.x和Flowable 7.0结果在自动配置和部分API上遇到了不少兼容性问题。Flowable 7对Spring Boot 3的支持当时尚不完善。因此我强烈建议在开始一个整合项目时先去官方社区和GitHub Issues查看版本兼容性矩阵选择一个经过大量项目验证的稳定组合避免在基础环境上浪费过多时间。3. 核心模块拆解与实现细节整个扩展功能可以划分为四大核心模块流程设计器、表单设计器、流程运行时API以及管理与监控。下面我逐一拆解其中的关键实现。3.1 流程设计器基于bpmn-js的深度定制我们的目标是在RuoYi的管理后台中提供一个类似Visio的、可拖拽的流程图绘制界面。bpmn-js是这个功能的核心。前端集成步骤安装依赖在Vue3项目中通过npm安装bpmn-js及其相关依赖。npm install bpmn-js bpmn-js-properties-panel camunda-bpmn-moddle --save注意虽然我们用的是Flowable但bpmn-js默认适配Camunda的属性扩展我们需要一个Flowable的“moddle”描述文件来告诉设计器Flowable特有的属性如flowable:assignee。你可以从Flowable官方源码或示例中找到flowable.json描述文件。封装Vue组件创建一个BpmnModeler.vue组件。在组件的onMounted生命周期中初始化BpmnModeler实例并配置额外的模块如属性面板、Flowable扩展。import BpmnModeler from bpmn-js/lib/Modeler; import bpmn-js/dist/assets/diagram-js.css; import bpmn-js/dist/assets/bpmn-font/css/bpmn.css; export default { mounted() { this.modeler new BpmnModeler({ container: #canvas, propertiesPanel: { parent: #properties }, // 关键注入Flowable的扩展定义 moddleExtensions: { flowable: require(path/to/your/flowable.json) } }); // 加载一个空的BPMN 2.0 XML模板 this.createNewDiagram(); }, methods: { async createNewDiagram() { const xmlStr ?xml version1.0 encodingUTF-8?...; // 简化的BPMN空模板 try { const { warnings } await this.modeler.importXML(xmlStr); if (warnings.length) { console.warn(导入警告:, warnings); } } catch (err) { console.error(导入失败:, err); } } } }自定义属性面板bpmn-js-properties-panel提供的默认面板是德语且不符合我们的业务需求。我们需要重写其渲染逻辑。例如对于一个“用户任务”节点我们需要展示“办理人”、“候选组”、“到期时间”等字段。我们通过监听元素选择事件动态生成一个基于Element-Plus表单控件的属性编辑区并与BPMN元素的业务数据Business Object绑定。当用户在属性面板修改时通过modeling.updateProperties方法更新到BPMN XML模型中。后端对接设计器最终产出的是一段符合BPMN 2.0标准的XML字符串。我们需要一个API来保存和部署这个模型。RestController RequestMapping(/workflow/model) public class FlowableModelController { Autowired private RepositoryService repositoryService; PostMapping(/deploy) public R deploy(RequestParam String name, RequestParam String key, RequestParam String category, RequestParam String bpmnXml) { try { Deployment deployment repositoryService.createDeployment() .addString(name .bpmn20.xml, bpmnXml) .name(name) .key(key) .category(category) .deploy(); return R.ok(部署成功, deployment.getId()); } catch (FlowableException e) { return R.fail(部署失败: e.getMessage()); } } }这个API接收前端传来的BPMN XML、流程名称、KEY和分类调用Flowable的RepositoryService进行部署。部署成功后该流程定义就可以被启动了。3.2 在线表单设计器JSON Schema驱动的动态表单这是让业务人员能自主配置审批表单的关键。我们的表单设计器产出物是一个JSON对象它描述了表单的所有信息。表单JSON Schema结构示例{ formKey: leave_apply_form, formName: 请假申请单, fields: [ { type: input, label: 请假类型, model: leaveType, required: true, options: [ {label: 年假, value: annual}, {label: 病假, value: sick}, {label: 事假, value: personal} ] }, { type: date-picker, label: 开始时间, model: startTime, required: true }, { type: date-picker, label: 结束时间, model: endTime, required: true }, { type: textarea, label: 请假事由, model: reason, rows: 3 } ], rules: { startTime: [{ required: true, message: 请选择开始时间, trigger: change }], endTime: [ { required: true, message: 请选择结束时间, trigger: change }, { validator: checkEndTimeAfterStart, trigger: change } ] } }设计器前端实现左侧组件库列出所有支持的表单控件输入框、下拉框、日期选择器、上传组件等每个控件是一个可拖拽的Vue组件。中间画布使用Vue的拖拽库如vuedraggable接收拖放过来的组件并实时渲染预览。画布上的每个字段组件都绑定到同一个表单数据模型。右侧属性配置面板当点击画布上的某个字段时右侧面板动态显示该字段类型对应的所有可配置属性如label、model、required、options等。修改属性画布上的组件实时更新。生成JSON点击保存时遍历画布上的所有字段配置组装成上述的JSON Schema结构提交到后端存储。后端存储与绑定表单JSON需要与流程定义关联。我们在数据库创建了一张扩展表wf_form_def主要字段包括form_key、form_name、form_json、proc_def_id关联的流程定义ID。在流程设计器里可以为每个用户任务节点指定一个form_key。当流程实例到达该节点时系统便根据form_key找到对应的JSON Schema动态渲染出任务办理表单。动态渲染引擎这是前端另一个关键组件。它接收一个form_key从后端获取对应的JSON Schema然后递归遍历fields数组根据每个字段的type动态创建对应的Element-Plus表单组件并绑定校验规则rules。这相当于一个微型的、声明式的UI渲染引擎。3.3 流程运行时API封装与业务集成流程部署好了表单也设计好了接下来就是如何让业务系统“跑”起流程。我们需要封装一套简洁的API供业务模块调用。1. 启动流程实例这是将一次具体的业务如一次请假申请与一个流程定义关联起来。Service public class FlowableRuntimeService { Autowired private RuntimeService runtimeService; Autowired private IdentityService identityService; public ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey, MapString, Object variables, String starterUserId) { // 设置流程启动人 identityService.setAuthenticatedUserId(starterUserId); // 启动流程实例 ProcessInstance instance runtimeService.startProcessInstanceByKey( processDefinitionKey, businessKey, // 通常传入业务数据的ID如 leave_apply.id variables // 流程变量可包含表单数据 ); identityService.setAuthenticatedUserId(null); return instance; } }businessKey至关重要它建立了流程实例与业务数据的关联。通过它我们可以轻松查询某个请假条对应的流程状态。variables中可以存入整个表单数据方便在后续节点和网关条件中使用。2. 任务查询与办理这是工作流系统的核心交互。我们需要为当前登录用户查询待办任务。public PageResultTaskVO queryTodoTasks(TaskQueryDTO queryDTO, Long userId) { // 构建Flowable原生任务查询 TaskQuery taskQuery taskService.createTaskQuery() .taskCandidateOrAssigned(String.valueOf(userId)) // 查询当前用户候选或待办 .active() .orderByTaskCreateTime().desc(); // 支持按流程名称模糊过滤需要关联查询 if (StringUtils.isNotBlank(queryDTO.getProcessName())) { taskQuery.processVariableValueLike(title, % queryDTO.getProcessName() %); } ListTask tasks taskQuery.listPage( (queryDTO.getPageNum() - 1) * queryDTO.getPageSize(), queryDTO.getPageSize() ); long total taskQuery.count(); // 将Task对象转换为自定义的TaskVO并补充业务信息 ListTaskVO taskVOList tasks.stream().map(task - { TaskVO vo new TaskVO(); vo.setTaskId(task.getId()); vo.setTaskName(task.getName()); vo.setProcessInstanceId(task.getProcessInstanceId()); // 通过processInstanceId或businessKey去查询业务数据填充如“申请人”、“申请时间”等 // ... return vo; }).collect(Collectors.toList()); return new PageResult(taskVOList, total); }办理任务时除了调用taskService.complete(taskId, variables)通常还需要记录审批意见、更新业务状态。Transactional(rollbackFor Exception.class) public void completeTask(String taskId, MapString, Object variables, String comment, String outcome) { // 1. 添加审批意见 if (StringUtils.isNotBlank(comment)) { taskService.addComment(taskId, null, comment); } // 2. 设置局部变量如审批结果 if (StringUtils.isNotBlank(outcome)) { taskService.setVariableLocal(taskId, outcome, outcome); } // 3. 完成任务 taskService.complete(taskId, variables); // 4. 可选监听器或后续业务逻辑如发送通知、更新业务表状态 // ... }3. 流程变量与业务数据同步这是一个常见问题。流程变量存储在ACT_RU_VARIABLE等表中而业务数据在自己的表里。如何保证一致性我的经验是关键业务状态如status应在业务表中维护。流程变量更多用于驱动路由如approvalResult或存储临时信息。在流程的开始事件监听器中将业务数据主键作为businessKey并将必要数据复制为流程变量。在任务完成监听器或ServiceTask中根据businessKey找到业务数据并根据流程结果更新其状态。这样业务数据是权威来源。3.4 历史数据、监控与高阶功能一个完整的工作流系统离不开历史查询和监控。历史数据查询Flowable提供了HistoryService可以查询已经结束的流程实例、任务、活动记录。我们可以基于此构建“已办任务”、“我发起的流程”等功能。这里要注意性能历史数据会随着时间增长需要设计合理的归档或分表策略。流程监控集成Flowable的ProcessEngineConfiguration可以暴露流程引擎的JMX Bean或通过其自带的REST API需额外引入flowable-rest模块来获取运行时信息如作业执行情况、数据库连接池状态等。但在生产环境我更推荐通过日志和自定义的监控端点来收集指标。会签与或签这是工作流中常见的多任务处理模式。会签多实例并行在用户任务上设置multiInstanceLoopCharacteristics并指定集合变量如assigneeList和完成条件如nrOfCompletedInstances nrOfInstances。所有任务同时产生需全部完成才能继续。或签多实例顺序与会签类似但设置isSequential为true。任务按顺序产生一个完成后再产生下一个常用于“依次审批”。 实现时需要在启动流程或到达该节点前准备好参与者集合变量。自定义监听器与委托表达式这是Flowable最强大的扩展点之一。执行监听器Execution Listener可以挂在流程事件开始、结束上用于记录日志、发送消息等。任务监听器Task Listener挂在任务事件创建、分配、完成上常用于自动设置办理人、发送任务通知。Java委托Java Delegate在ServiceTask中实现JavaDelegate接口可以执行复杂的业务逻辑如调用外部系统、进行复杂计算。在RuoYi-Vue-Plus中我们可以很方便地将这些监听器或委托类注册为Spring Bean然后在BPMN XML中通过delegateExpression属性引用它们例如${myTaskCompleteListener}从而实现业务逻辑与流程引擎的松耦合集成。4. 数据库设计与性能优化实践将Flowable集成进来意味着数据库里会增加近30张以ACT_开头的表。理解这些表的结构对于排查问题和性能优化至关重要。核心表分类运行时表ACT_RU_*存储运行中的流程实例、任务、变量等。这些表最活跃需要重点关注。历史表ACT_HI_*存储已完成的流程数据。数据量增长最快需定期归档。身份表ACT_ID_*存储用户、组信息。强烈建议与业务系统用户表集成而不是使用这套表。我们可以通过实现Flowable的IdmIdentityService接口将其指向我们自己的sys_user和sys_role表。其他如ACT_GE_*通用数据、ACT_RE_*存储部署的流程定义资源。集成业务用户表这是必须做的一步。在application.yml中配置flowable: async-executor-activate: false # 根据需求开启异步执行器 db-history-used: true # 使用历史数据 history-level: audit # 历史级别audit记录所有细节 # 禁用Flowable自带的身份管理 idm-enabled: false然后编写一个自定义的IdmIdentityService实现类将getUser()、getGroupsForUser()等方法映射到你的SysUserService和SysRoleService上。这样在流程中设置${assignee}为zhangsan时引擎就能找到对应的业务用户。性能优化点历史数据分级与归档将flowable.history-level设置为audit会记录所有细节包括变量变更。对于超大规模应用可以考虑设置为activity只记录节点活动或开发定时任务将超过一定时间的ACT_HI_*数据迁移到历史归档库。变量查询优化避免使用processVariableValueLike进行模糊查询尤其是在大数据量表上。如果业务需要频繁按变量查询可以考虑将关键业务变量冗余存储到业务表中或建立合适的数据库索引。异步执行器对于耗时操作如调用外部HTTP接口、生成复杂报表应在ServiceTask中设置为asynctrue并启用AsyncExecutor。这样任务会被放入异步队列立即返回避免阻塞流程线程。数据库连接池确保Flowable使用的数据源配置了合适的连接池如HikariCP并监控连接使用情况。5. 部署、运维与常见问题排查项目开发完成后部署和运维是另一道坎。部署打包由于是单体应用前后端分离但后端是一个Jar包部署相对简单。将打包好的ruoyi-admin.jar和前端静态资源Nginx配置或放入resources/static部署到服务器即可。所有Flowable的API都通过我们自定义的Controller暴露安全性由RuoYi-Vue-Plus的Sa-Token权限框架统一控制。流程定义热部署在开发环境我们可以通过前端设计器直接部署新版本流程。在生产环境建议通过版本控制Git来管理BPMN XML文件使用CI/CD流水线进行部署。Flowable支持相同key的流程定义多次部署新部署的版本会自动变为默认版本而正在运行的老实例会继续使用其启动时的版本这实现了平滑升级。常见问题与排查技巧流程启动失败提示“未找到流程定义”检查点确认流程定义的key是否正确确认该key的流程定义是否已成功部署检查ACT_RE_PROCDEF表确认调用启动API的租户ID如果有是否匹配。任务查询不到检查点首先确认流程实例是否已成功创建并运行到该任务节点查看ACT_RU_TASK表。然后检查任务候选人的设置是直接指定了assignee专办还是指定了candidateUsers或candidateGroups组办查询代码中是否使用了正确的查询方法.taskCandidateOrAssigned(userId)会同时查询候选和已指派任务。网关条件不生效流程走错分支检查点这是最常见的问题之一。首先在BPMN设计器中双击连线确认条件表达式已正确设置如${approvalResult agree}。其次检查在流程运行时变量approvalResult是否被正确设置到了流程上下文中注意变量作用域流程实例变量、任务局部变量。最有效的调试方法是在完成上一个任务时打印出所有的流程变量或者直接查询ACT_RU_VARIABLE表查看变量的值和类型字符串agree和布尔true是不同的。自定义Java委托类不执行检查点确认该类已被Spring容器管理添加了Component注解。确认在BPMN XML中ServiceTask的delegateExpression属性值是否正确引用了Bean的名字如${myServiceTask}注意大小写。查看应用启动日志是否有关于Bean创建或表达式解析的错误。历史数据量巨大系统变慢行动方案首先评估是否真的需要audit级别的历史记录可以考虑降级为activity。其次建立历史数据归档机制。可以编写一个定时任务定期将ACT_HI_*表中已结束超过N天的流程实例数据迁移到另一套归档表中并在原表中删除。Flowable本身也提供了一些历史数据清理的API但需谨慎使用避免误删关联数据。一个宝贵的调试技巧在application.yml中开启Flowable的调试日志可以让你看到引擎执行的每一步细节。logging: level: org.flowable: DEBUG # 设置为DEBUG级别可以看到详细的SQL和执行逻辑在排查复杂流程问题时这能帮你节省大量时间。整个整合过程就像是在RuoYi-Vue-Plus这座精装修的房子内精心安装了一套智能水管系统Flowable。你需要规划管线走向架构设计定制阀门和接口API封装并确保它和原有的电路、网络权限系统、业务模块完美协作。最终你得到的不是一个孤立的工具而是一个赋能所有业务模块的、强大的流程驱动能力。当看到业务人员能自己拖拽出复杂的采购审批流程时那种成就感是对所有技术细节打磨的最好回报。本文还有配套的精品资源点击获取
返回列表