当前位置: 首页 > news >正文

保姆级教程:在RuoYi-Vue-Pro项目中,从零搭建一个请假审批工作流(Flowable实战)

从零构建RuoYi-Vue-Pro请假审批工作流全流程实战

1. 工作流技术选型与项目准备

在当今企业级应用开发中,工作流引擎已成为处理复杂业务流程的核心组件。Flowable作为Activiti的分支项目,以其轻量级、高性能和丰富的功能特性,成为众多Java开发者的首选。而RuoYi-Vue-Pro作为一款基于Spring Boot和Vue.js的快速开发平台,与Flowable的整合能够为开发者提供开箱即用的工作流解决方案。

为什么选择Flowable?

  • 完整的BPMN 2.0支持:可视化建模与标准兼容
  • 嵌入式设计:可直接集成到Spring应用中
  • 高性能运行时:优化的执行引擎处理高并发
  • 丰富的REST API:便于前后端分离架构调用
  • 活跃的社区:持续更新维护,问题响应快

在开始前,请确保你的开发环境已具备以下条件:

# 基础环境检查清单 Java 8+ Maven 3.6+ MySQL 5.7+ Node.js 12+

RuoYi-Vue-Pro项目结构中对Flowable的支持主要体现在以下几个模块:

ruoyi-vue-pro ├── ruoyi-admin # 后台管理模块 ├── ruoyi-common # 通用工具模块 ├── ruoyi-flowable # 工作流引擎模块 ★核心 ├── ruoyi-generator # 代码生成模块 └── ruoyi-system # 系统基础模块

2. 请假审批表单设计与实现

2.1 数据库表结构设计

工作流表单是业务流程的数据载体,在RuoYi-Vue-Pro中主要通过bpm_form表进行管理。对于请假审批场景,我们需要设计包含以下字段的表单:

CREATE TABLE `bpm_oa_leave` ( `id` bigint NOT NULL COMMENT '主键ID', `user_id` bigint NOT NULL COMMENT '申请人ID', `type` tinyint NOT NULL COMMENT '请假类型(1事假 2病假 3年假)', `reason` varchar(255) NOT NULL COMMENT '请假原因', `start_time` datetime NOT NULL COMMENT '开始时间', `end_time` datetime NOT NULL COMMENT '结束时间', `duration` decimal(10,1) NOT NULL COMMENT '请假时长(天)', `status` tinyint DEFAULT '0' COMMENT '状态(0审批中 1通过 2拒绝)', `create_time` datetime DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='OA请假表';

2.2 前端表单开发

在Vue组件中,我们使用Element UI构建表单界面:

<template> <el-form :model="form" :rules="rules" ref="formRef"> <el-form-item label="请假类型" prop="type"> <el-select v-model="form.type"> <el-option label="事假" :value="1"></el-option> <el-option label="病假" :value="2"></el-option> <el-option label="年假" :value="3"></el-option> </el-select> </el-form-item> <el-form-item label="开始时间" prop="start_time"> <el-date-picker v-model="form.start_time" type="datetime"></el-date-picker> </el-form-item> <!-- 其他表单项 --> </el-form> </template>

2.3 后端接口实现

Spring Boot控制器处理表单提交:

@PostMapping("/submit") public Result<String> submitLeave(@Valid @RequestBody LeaveCreateReqVO reqVO) { Long leaveId = leaveService.createLeave(reqVO); return Result.success(leaveId.toString()); }

3. Flowable流程模型设计与部署

3.1 流程模型创建

在RuoYi-Vue-Pro的管理后台,我们可以通过可视化设计器创建请假审批流程:

  1. 开始节点:设置表单关联
  2. 用户任务:领导审批节点
  3. 排他网关:根据审批结果分流
  4. 用户任务:HR备案节点(审批通过时)
  5. 结束节点:流程终止

关键BPMN元素说明

元素类型作用配置要点
StartEvent流程开始关联表单KEY
UserTask人工任务设置办理人/组
ExclusiveGateway条件分流设置流转条件
EndEvent流程结束可记录结果

3.2 流程部署实现

流程部署涉及的主要数据库表:

// 部署代码示例 Deployment deployment = repositoryService.createDeployment() .addBpmnModel("leave-approval.bpmn", bpmnModel) .name("请假审批流程") .category("OA") .deploy();

部署后主要数据表变化:

  1. ACT_RE_DEPLOYMENT:部署记录
  2. ACT_RE_PROCDEF:流程定义
  3. ACT_GE_BYTEARRAY:存储BPMN文件

4. 流程任务分配与规则配置

4.1 任务分配策略

RuoYi-Vue-Pro通过bpm_task_assign_rule表实现灵活的任务分配:

INSERT INTO `bpm_task_assign_rule` (`id`, `model_id`, `process_definition_id`, `task_definition_key`, `type`, `options`) VALUES (1, 'leave_model', 'leave_process:1', 'leader_approve', 30, '[1]'); -- 用户ID=1

常用分配类型

类型值说明适用场景
10角色固定角色审批
20部门成员本部门人员审批
30指定用户特定人员审批
40用户组用户组轮询

4.2 动态任务分配

对于更复杂的场景,可以使用Spring EL表达式:

<userTask id="hrTask" name="HR备案" flowable:assignee="${hrService.getHrAssignee(execution)}"/>

对应的Java服务类:

public class HrService { public String getHrAssignee(DelegateExecution execution) { // 根据业务逻辑返回处理人 return "hr1"; } }

5. 流程实例运行与任务处理

5.1 流程实例启动

前端发起流程请求:

axios.post('/bpm/process-instance/create', { processDefinitionId: 'leave_process:1', formVariables: { leaveId: 123, applicant: 'user1' } })

后端处理逻辑:

public String startProcess(ProcessStartReqVO reqVO) { // 1. 校验流程定义 BpmProcessDefinition definition = validateProcessDefinition(reqVO.getProcessDefinitionId()); // 2. 创建流程实例 ProcessInstance instance = runtimeService.startProcessInstanceById( reqVO.getProcessDefinitionId(), reqVO.getBusinessKey(), reqVO.getVariables()); // 3. 记录扩展信息 processInstanceExtMapper.insert(new BpmProcessInstanceExt() .setId(instance.getProcessInstanceId()) .setStatus(ProcessInstanceStatusEnum.RUNNING.getStatus())); return instance.getProcessInstanceId(); }

5.2 任务审批实现

审批接口的核心处理逻辑:

@Transactional public void approveTask(TaskApproveReqVO reqVO) { // 1. 校验任务 Task task = validateTask(reqVO.getId()); // 2. 处理审批意见 if (reqVO.getApproved()) { taskService.complete(task.getId(), reqVO.getVariables()); } else { handleReject(task, reqVO.getReason()); } // 3. 记录审批日志 createTaskExt(task, reqVO); }

6. 流程监控与数据分析

6.1 运行时数据查询

常用查询场景及对应表:

查询需求主要表示例查询
待办任务ACT_RU_TASKSELECT * FROM ACT_RU_TASK WHERE ASSIGNEE_ = ?
已办任务ACT_HI_TASKINSTSELECT * FROM ACT_HI_TASKINST WHERE ASSIGNEE_ = ? AND END_TIME_ IS NOT NULL
流程状态ACT_RU_EXECUTIONSELECT * FROM ACT_RU_EXECUTION WHERE PROC_INST_ID_ = ?

6.2 历史数据分析

通过历史表可以生成各类统计报表:

-- 部门请假统计 SELECT d.dept_name, COUNT(*) as total, SUM(CASE WHEN l.status = 1 THEN 1 ELSE 0 END) as approved, SUM(l.duration) as days FROM bpm_oa_leave l JOIN sys_user u ON l.user_id = u.user_id JOIN sys_dept d ON u.dept_id = d.dept_id GROUP BY d.dept_id

7. 性能优化与常见问题排查

7.1 性能优化建议

  1. 数据库索引优化

    ALTER TABLE ACT_RU_TASK ADD INDEX idx_assignee (ASSIGNEE_); ALTER TABLE ACT_HI_TASKINST ADD INDEX idx_assignee_end (ASSIGNEE_, END_TIME_);
  2. 历史数据归档

    historyService.createHistoricProcessInstanceQuery() .finishedBefore(archiveDate) .delete();
  3. 异步任务处理

    <serviceTask id="notifyService" flowable:async="true" flowable:class="com.example.flowable.AsyncNotifyService"/>

7.2 常见问题解决方案

问题1:流程实例卡住不执行

  • 检查点:
    • ACT_RU_EXECUTION表中相关实例的IS_ACTIVE_字段
    • ACT_RU_TASK是否存在未处理任务
    • 流程日志中是否有异常堆栈

问题2:任务分配不正确

  • 排查步骤:
    1. 确认bpm_task_assign_rule配置
    2. 检查流程定义XML中的assignee设置
    3. 验证候选人或组的查询逻辑

问题3:高并发下性能下降

  • 优化方案:
    • 启用Flowable的异步执行器
    • 增加流程引擎配置中的线程池大小
    • 对频繁查询添加缓存层

8. 扩展功能与最佳实践

8.1 消息通知集成

审批过程中的消息通知方案:

// 任务创建时发送通知 taskService.addTaskListener(TaskListener.EVENTNAME_CREATE, delegateTask -> { String assignee = delegateTask.getAssignee(); String message = "您有新的待办任务:" + delegateTask.getName(); smsService.send(assignee, message); });

8.2 与业务系统深度集成

深度集成方案

  1. 数据关联

    runtimeService.setVariable(executionId, "businessData", businessData);
  2. 业务规则引擎

    <businessRuleTask id="checkRule" flowable:ruleVariablesInput="${order}" flowable:resultVariable="ruleResult"/>
  3. 自定义事件监听

    runtimeService.addEventListener(new CustomEventListener(), ExecutionListener.EVENTNAME_START, ExecutionListener.EVENTNAME_END);

8.3 移动端适配技巧

针对移动端的优化策略:

  1. 简化表单字段:只保留核心审批信息
  2. 离线处理能力:使用Service Worker缓存待办数据
  3. 推送通知:集成WebPush或App推送
  4. 审批快捷操作:提供"同意/拒绝"快速按钮
// 移动端审批API简化示例 POST /mobile/task/approve { "taskId": "123", "action": "approve", // or "reject" "comment": "OK" }
http://www.jsqmd.com/news/707942/

相关文章:

  • 回收华润万家购物卡避坑指南:小白必看实用干货 - 团团收购物卡回收
  • org-roam-ui API 详解:构建自定义集成与扩展
  • 天津猎头公司前十名推荐!哪家猎头公司做得最好? - 榜单推荐
  • jq数据聚合终极指南:多源JSON数据的合并与汇总技巧
  • 在Ubuntu上5分钟搞定OpenHarmony 4.0轻量系统到QEMU RISC-V的编译(附Python 3.10报错修复)
  • 终极A/B测试指南:揭秘Netflix与Amazon如何设计大规模实验
  • EzySlice 与 Unity3D 2018+ 的完美集成:完整部署与配置教程
  • 超分模型训练数据怎么选?深度对比BSRGAN、Real-ESRGAN和SwinIR的数据配方
  • 2026年抗菌板公司推荐及选购参考/医疗抗菌板,医院抗菌板,木纹抗菌板索洁板,冰火板 - 品牌策略师
  • 2026/4/25 测试
  • 攻克XYFlow节点定位难题:从测试到实战的完整解决方案
  • Lean3定理证明器10个核心概念:从基础类型到高阶证明
  • Compose LazyList状态管理全解:从滚动监听、恢复,到与Paging3的完美集成
  • 天赐范式第24天:基于能量流形拓扑的化学反应形式化验证框架:天赐范式 v7.5 的收敛性分析与实证报告
  • 预算有限怎么选?国产污水重金属检测仪哪家性价比高?认准宁波普瑞思仪器科技 - 品牌推荐大师
  • OpenBullet2作业管理与监控:构建企业级自动化测试平台
  • 从操作数到智能体:operand/agency框架构建多智能体协作系统实战
  • 告别碎片化:手把手带你用AGL Unified Code Base (UCB) 快速搭建车载原型
  • ZoroCloud测评记录:Intel Gold 6138/1GB内存/100Mbps带宽/9929CMIN2/原生双ISP洛杉矶VPS(Debian GNU/Linux 12)
  • 如何快速生成NW.js专业文档:5个高效工具和最佳实践
  • Claude Code能打开浏览器后,普通人怎么把活交出去丨阿隆向前冲
  • envd TensorBoard集成教程:实时监控深度学习训练进度
  • ext-ds Vector 完全解析:从基础使用到高级技巧
  • 机器学习模型可视化实战:Matplotlib核心技巧解析
  • 告别PS!Qwen-Image-Edit-2509一键部署,用文字就能轻松编辑图片
  • Qianfan-OCR一文详解:单模型搞定OCR/布局分析/多语言提取三合一
  • Elden Ring FPS解锁工具:完整指南与实用技巧
  • 10大Rust算法实战案例:从机器学习到环境监测的完整指南
  • Ryzen SDT:免费开源工具解锁AMD处理器隐藏性能,新手也能轻松上手
  • QQ音乐加密音频完整解密指南:使用qmcdump实现无损转换的终极教程