现代企业运营中,流程化管理已成为提升效率的关键。传统纸质审批或简单的电子表单已经无法满足企业对于流程透明化、标准化和自动化的需求。RuoYi-Vue-Pro集成的BPM(业务流程管理)系统正是为解决这一问题而生。
为什么选择工作流引擎?想象一下这样的场景:当员工提交请假申请后,系统能自动根据请假天数判断审批路径——3天以内直接主管审批即可,3-7天需要部门负责人审批,超过7天则必须经过HR总监批准。这种智能路由正是BPM系统的核心能力。
RuoYi-Vue-Pro的工作流模块基于Activiti7深度定制,主要解决以下痛点:
sql复制-- 核心流程分类表结构
CREATE TABLE `bpm_category` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号',
`name` varchar(255) DEFAULT NULL COMMENT '分类名',
`code` varchar(255) DEFAULT NULL COMMENT '分类标志',
`status` int DEFAULT NULL COMMENT '状态',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号'
) ENGINE=InnoDB COMMENT='流程分类';
确保开发环境满足以下要求:
提示:生产环境建议使用MySQL主从架构,工作流的历史数据会随时间增长而累积
执行项目中的SQL脚本,重点关注以下表:
bpm_form:表单定义表bpm_process_definition_info:流程定义表bpm_oa_leave:请假业务表bash复制# 初始化数据库
mysql -u root -p < ruoyi-vue-pro.sql
在src/views/bpm目录下,主要功能模块包括:
modeler:流程设计器process:流程实例管理task:待办任务中心form:动态表单设计配置前端API请求基地址:
javascript复制// .env.development
VUE_APP_BASE_API = '/dev-api'
使用内置表单设计器创建请假申请单,包含以下字段:
| 字段名 | 类型 | 必填 | 校验规则 |
|---|---|---|---|
| 请假类型 | 单选 | 是 | 病假/年假/事假 |
| 开始时间 | 日期 | 是 | 大于当前时间 |
| 结束时间 | 日期 | 是 | 大于开始时间 |
| 请假原因 | 文本 | 是 | 10-200字符 |
表单JSON配置示例:
json复制{
"fields": [
{
"type": "select",
"name": "type",
"label": "请假类型",
"options": [
{"label":"病假","value":1},
{"label":"年假","value":2}
]
}
]
}
在流程设计器中构建如下节点:
day <= 3时自动通过注意:网关分支必须设置明确的condition表达式,避免流程卡死
在bpm_oa_leave表中关键字段:
process_instance_id:关联流程实例result:存储最终审批结果审批逻辑代码片段:
java复制@Transactional
public void approve(Long leaveId, Boolean result) {
Leave leave = leaveMapper.selectById(leaveId);
if (leave.getResult() != 0) {
throw new ServiceException("该申请已处理");
}
leave.setResult(result ? 1 : 2);
leaveMapper.updateById(leave);
// 触发流程推进
taskService.complete(
taskService.createTaskQuery()
.processInstanceId(leave.getProcessInstanceId())
.singleResult().getId());
}
实现三种审批人指定方式:
java复制// 获取部门负责人示例
public List<Long> getDeptLeaders(Long deptId) {
return sysUserMapper.selectList(
new QueryWrapper<SysUser>()
.eq("dept_id", deptId)
.eq("post_code", "dept_leader")
).stream().map(SysUser::getUserId)
.collect(Collectors.toList());
}
在流程定义中添加监听器实现自动审批:
xml复制<activiti:executionListener
event="take"
class="com.ruoyi.bpm.listener.AutoApproveListener"/>
监听器逻辑判断:
java复制public class AutoApproveListener implements ExecutionListener {
@Override
public void notify(DelegateExecution execution) {
Integer days = (Integer)execution.getVariable("day");
if (days < 1) {
execution.setVariable("approved", true);
}
}
}
在application.yml中配置数据隔离策略:
yaml复制ruoyi:
workflow:
data-isolation: tenant # 可选user/dept/tenant
SQL查询自动注入条件:
sql复制SELECT * FROM bpm_oa_leave
WHERE ${dataScope}
AND deleted = 0
为高频查询字段添加索引:
sql复制ALTER TABLE `bpm_oa_leave`
ADD INDEX `idx_user_status` (`user_id`, `result`);
ALTER TABLE `bpm_process_instance_copy`
ADD INDEX `idx_task_user` (`task_id`, `user_id`);
创建归档表并配置定时任务:
java复制@Scheduled(cron = "0 0 2 * * ?")
public void archiveHistoricProcess() {
// 归档3个月前的完成流程
historicService.createHistoricProcessInstanceQuery()
.finishedBefore(DateUtils.addMonths(new Date(), -3))
.list()
.forEach(instance -> {
archiveService.saveArchive(instance);
runtimeService.deleteProcessInstance(instance.getId());
});
}
properties复制# application-cluster.properties
spring.activiti.async-executor-activate=true
spring.activiti.job-executor-activate=false
流程卡住怎么办?
ACT_RU_TASK表当前任务ACT_RU_EVENT_SUBSCR事件订阅runtimeService.trigger()手动触发事件审批人看不到待办?
ACT_RU_IDENTITYLINK身份关联性能慢如何优化?
sql复制-- 查询运行中流程耗时统计
SELECT PROC_DEF_ID_, avg(DURATION_)
FROM ACT_RU_TASK
GROUP BY PROC_DEF_ID_
ORDER BY 2 DESC;
实现钉钉审批同步:
java复制@DingTalkEventListener
public void handleApproveEvent(ApproveEvent event) {
String instanceId = event.getProcessInstanceId();
if (event.isAgree()) {
taskService.complete(
taskService.createTaskQuery()
.processInstanceId(instanceId)
.singleResult().getId());
}
}
集成e签宝示例:
yaml复制esign:
app-id: your_app_id
app-secret: your_secret
api-host: https://openapi.esign.cn
使用EasyExcel导出数据:
java复制public void exportLeaveRecord(HttpServletResponse response) {
List<LeaveRecordVO> records = leaveService.getLeaveRecords();
ExcelUtil.export(response, "请假记录", records);
}
报表统计SQL示例:
sql复制SELECT
u.user_name,
COUNT(*) as total,
SUM(IF(l.result=1,1,0)) as approved
FROM bpm_oa_leave l
JOIN sys_user u ON l.user_id = u.user_id
GROUP BY u.user_id
在实际项目中,我们总结出以下经验:
调试技巧:
act_ge_bytearray表查看流程定义XMLACT_RU_VARIABLE检查运行时变量java复制// 流程调试工具方法
public void debugProcess(String instanceId) {
DelegateExecution execution = runtimeService
.createExecutionQuery()
.executionId(instanceId)
.singleResult();
log.info("当前节点:{}", execution.getCurrentActivityId());
log.info("流程变量:{}", runtimeService.getVariables(instanceId));
}