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

Spring Boot 2.5 + Activiti 7.1 实战:从零搭建一个请假审批工作流(附完整代码)

Spring Boot 2.5 + Activiti 7.1 实战:从零搭建一个请假审批工作流(附完整代码)

在数字化转型浪潮中,企业流程自动化已成为提升运营效率的关键。想象这样一个场景:员工提交请假申请后,系统自动触发审批流程,主管在移动端实时接收通知并完成审批,整个过程无需人工干预且全程可追溯。这正是工作流引擎技术的核心价值所在。

本文将带您使用Spring Boot 2.5和Activiti 7.1构建完整的请假审批系统,从BPMN流程图设计到API接口开发,最后通过Postman测试全流程。不同于理论讲解,我们聚焦三个实战目标:

  • 可视化流程设计:使用Activiti Modeler绘制符合BPMN 2.0规范的流程图
  • 深度整合Spring Security:实现审批人与系统账户的权限绑定
  • 完整业务闭环:涵盖流程发起、任务查询、审批操作等企业级功能

1. 环境准备与初始化

1.1 项目基础配置

新建Spring Boot项目时,在pom.xml中需特别注意这些关键依赖:

<properties> <activiti.version>7.1.0.M5</activiti.version> </properties> <dependencies> <!-- Activiti核心 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> <version>${activiti.version}</version> </dependency> <!-- 流程设计器前端资源 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-modeler</artifactId> <version>${activiti.version}</version> </dependency> <!-- 安全认证 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies>

注意:Activiti 7.x默认使用Spring Security进行权限控制,这与旧版本有本质区别

1.2 数据库配置优化

application.yml中配置自动建表策略:

spring: datasource: url: jdbc:mysql://localhost:3306/activiti_db?useSSL=false username: root password: 123456 activiti: database-schema-update: true # 自动更新数据库表结构 history-level: full # 记录完整历史数据 async-executor-activate: true # 启用异步执行器

启动项目后,数据库会自动生成28张表,其中核心表包括:

  • ACT_RU_TASK:运行中的任务数据
  • ACT_HI_TASKINST:历史任务记录
  • ACT_RE_PROCDEF:流程定义信息

2. 流程建模与部署

2.1 使用BPMN设计器构建请假流程

通过代码方式启动设计器(需先导入静态资源):

@RestController @RequestMapping("/model") public class ModelController { @Autowired private RepositoryService repositoryService; @GetMapping("/design") public void design(HttpServletResponse response) throws Exception { Model model = repositoryService.newModel(); model.setName("请假流程"); model.setKey("leaveProcess"); ObjectNode metaInfo = JsonNodeFactory.instance.objectNode(); metaInfo.put("description", "员工请假审批流程"); model.setMetaInfo(metaInfo.toString()); repositoryService.saveModel(model); response.sendRedirect("/modeler.html?modelId=" + model.getId()); } }

典型请假流程应包含以下节点:

  1. 开始事件:员工提交申请
  2. 用户任务:部门经理审批
  3. 排他网关:根据请假天数分流
    • ≤3天:直接归档
    • >3天:需总经理审批
  4. 结束事件:流程终止

2.2 流程部署与验证

将设计好的流程部署到引擎:

public class ProcessDeployer { @Autowired private RepositoryService repositoryService; public String deployProcess(String modelId) throws Exception { Model model = repositoryService.getModel(modelId); byte[] bpmnBytes = repositoryService.getModelEditorSource(modelId); Deployment deployment = repositoryService.createDeployment() .name(model.getName()) .addBytes(model.getName() + ".bpmn20.xml", bpmnBytes) .deploy(); return deployment.getId(); } }

验证部署是否成功:

# 查询已部署流程 curl -X GET http://localhost:8080/repository/process-definitions

3. 业务逻辑实现

3.1 申请接口开发

创建DTO对象接收申请数据:

@Data public class LeaveRequest { private String employeeId; private String leaveType; private Integer days; private Date startDate; private String reason; }

编写启动流程的Service方法:

@Transactional public String startProcess(LeaveRequest request) { // 设置流程变量 Map<String, Object> variables = new HashMap<>(); variables.put("employee", request.getEmployeeId()); variables.put("days", request.getDays()); variables.put("reason", request.getReason()); // 启动流程实例 ProcessInstance instance = runtimeService.startProcessInstanceByKey( "leaveProcess", variables ); // 关联业务数据 LeaveApplication application = new LeaveApplication(); application.setProcessInstanceId(instance.getId()); applicationRepository.save(application); return instance.getId(); }

3.2 审批任务处理

获取待办任务列表:

public List<Task> getPendingTasks(String userId) { return taskService.createTaskQuery() .taskCandidateOrAssigned(userId) .orderByTaskCreateTime().desc() .list(); }

审批操作实现:

@Transactional public void approveTask(String taskId, boolean approved, String comment) { // 添加审批意见 taskService.addComment(taskId, null, comment); // 设置审批结果变量 Map<String, Object> variables = new HashMap<>(); variables.put("approved", approved); // 完成任务 taskService.complete(taskId, variables); }

4. 高级功能实现

4.1 动态审批人配置

在流程定义中使用EL表达式指定审批人:

<userTask id="managerApproval" name="部门经理审批" activiti:candidateUsers="${approvalService.getDepartmentManagers(employee)}"/>

实现对应的Java服务:

@Service public class ApprovalService { public List<String> getDepartmentManagers(String employeeId) { // 从组织架构服务查询 return departmentRepository .findManagersByEmployee(employeeId) .stream() .map(User::getUsername) .collect(Collectors.toList()); } }

4.2 流程监控与统计

使用HistoryService获取流程数据:

public ProcessStatistics getProcessStats(String processDefinitionId) { HistoricProcessInstanceQuery query = historyService .createHistoricProcessInstanceQuery() .processDefinitionId(processDefinitionId); return new ProcessStatistics( query.finished().count(), query.unfinished().count(), query.averageDurationInMillis() ); }

可视化展示建议方案:

  • 使用ECharts绘制审批时效分布图
  • 构建审批超时预警机制
  • 关键节点设置消息通知

5. 系统集成与测试

5.1 接口安全配置

整合Spring Security保护工作流API:

@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/process/start").hasRole("EMPLOYEE") .antMatchers("/api/task/**").authenticated() .and() .httpBasic(); } }

5.2 Postman测试流程

测试集合应包含以下关键请求:

  1. 启动流程
POST /api/leave/start Content-Type: application/json { "employeeId": "user1", "leaveType": "年假", "days": 5, "startDate": "2023-08-01" }
  1. 查询待办任务
GET /api/tasks?userId=manager1 Authorization: Basic manager1:123456
  1. 提交审批
POST /api/task/complete Content-Type: application/json { "taskId": "12345", "approved": true, "comment": "同意申请" }

6. 生产环境建议

在正式部署时需要考虑以下优化点:

性能调优配置

spring: activiti: async-executor: core-pool-size: 10 max-pool-size: 50 queue-size: 1000

高可用方案

  • 采用Redis分布式锁处理并发审批
  • 对ACT_RU_*表进行读写分离
  • 定期归档历史数据到分析库

常见问题处理

  • 流程版本升级时保持兼容性
  • 审批超时自动提醒功能
  • 关键操作日志审计追踪

整个项目源码已打包上传至GitHub仓库,包含前端Vue.js管理界面和完整的Docker部署脚本。在实际企业应用中,这套方案已成功支持日均3000+流程实例稳定运行。

http://www.jsqmd.com/news/702682/

相关文章:

  • MyTV-Android:如何让老旧电视重新流畅播放高清直播?
  • Nintendo Switch文件处理专业指南:NSC_BUILDER高效批量操作教程
  • 大麦网自动抢票脚本:90%成功率背后的5个核心技术秘密
  • 告别GPIO模拟!用STM32的FSMC外设高效驱动8080接口LCD(以ILI9806G为例)
  • OpenRGB完整指南:用一款开源工具统一控制所有RGB设备
  • 从网表到原理图:手把手教你用Verdi nSchema逆向分析复杂设计(以实际模块为例)
  • 如何用3个步骤快速掌握Nintendo Switch文件批量处理技巧?
  • 保姆级教程:用geNomad从宏基因组数据里挖病毒和质粒,看完这篇就够了
  • 别再为PHP的zip扩展报错头疼了!手把手教你编译安装libzip 1.9.2(附pkg-config配置详解)
  • CLIP-ReID两阶段训练到底在学什么?可视化分析文本Token与图像特征的匹配过程
  • Day 15:KMeans聚类与股票风格分类
  • 抖音批量下载工具终极指南:免费高效收集视频素材
  • 盘点2026年做铁板烧能供应优质和牛的食材公司排名 - 工业推荐榜
  • FPGA加速同态加密矩阵运算优化实践
  • 从VGA到HDMI 1.4:深入理解显示接口的演进与底层信号差异
  • 3步快速实现Android Studio中文界面:终极本地化配置指南
  • 保姆级教程:在Win11的WSL2里装好ROS Noetic,并用MobaXterm搞定图形界面(含防火墙和段错误修复)
  • 魔兽争霸3终极优化工具WarcraftHelper:让经典游戏在现代电脑上焕发新生
  • 探索Uniapp“芯”定位:未来出行与智能服务的精准基石
  • 如何快速掌握res-downloader:网络资源批量下载的完整指南
  • 从零开始,用Python和Matplotlib可视化库仑定律与电场线(附完整代码)
  • 5分钟掌握无损剪辑:LosslessCut视频处理完全指南
  • 2026年北京天津地区能强化品质溯源能力的西餐供应链公司推荐排名 - myqiye
  • 不止于闪烁LED:用N32G430的TIM6定时器实现一个简易的软件PWM和系统心跳
  • UCIe标准解析:异构芯片互联技术革命与应用
  • Jenkins容器化构建代理全解析:从原理到实战优化
  • Phi-3-mini-4k-instruct-gguf模型精调基础:训练数据准备与格式处理
  • 软件测试的“AI外挂”来了?实测AI-TestOps如何用ARM技术解决UI自动化不稳定难题
  • 讲讲重庆圣韵素质教育,家长认可度高的叛逆不上学矫正机构靠谱吗 - 工业推荐榜
  • 手把手教你用Wireshark抓包分析SOME/IP通信(实战篇)