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

SpringBoot + Activiti6.0实战:手把手教你搞定请假审批系统(附完整源码)

SpringBoot与Activiti6.0深度整合构建企业级请假审批系统实战指南在当今企业数字化转型浪潮中业务流程自动化已成为提升运营效率的关键。本文将带您深入探索如何利用SpringBoot与Activiti6.0构建一个功能完备的请假审批系统从环境搭建到生产部署全程采用工程化实践方案。1. 环境准备与基础配置1.1 技术栈选型与依赖管理现代Java企业应用开发中SpringBoot已成为事实上的标准框架而Activiti作为成熟的BPMN2.0流程引擎二者的结合能够快速实现复杂业务流程的数字化。以下是核心依赖配置dependencies !-- SpringBoot基础依赖 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Activiti集成 -- dependency groupIdorg.activiti/groupId artifactIdactiviti-spring-boot-starter-basic/artifactId version6.0.0/version /dependency !-- 数据库支持 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency /dependencies1.2 数据库配置策略Activiti引擎需要特定的数据库表结构支持正确的初始化策略对系统稳定性至关重要。推荐采用以下配置组合配置项推荐值适用场景spring.activiti.database-schema-updatetrue开发环境spring.activiti.database-schema-updatefalse生产环境spring.activiti.history-levelfull需要完整审计# 开发环境配置示例 spring.datasource.urljdbc:mysql://localhost:3306/activiti_demo spring.datasource.usernameroot spring.datasource.passwordyourpassword spring.activiti.database-schema-updatetrue spring.activiti.history-levelfull提示生产环境务必关闭database-schema-update避免意外修改表结构2. 流程建模与部署2.1 BPMN2.0流程设计规范请假审批流程通常包含以下核心节点开始事件流程触发点用户任务请假申请节点排他网关根据请假天数路由用户任务部门审批节点条件天数3结束事件流程终止点!-- 简化版BPMN定义示例 -- process idvacationProcess name请假审批流程 startEvent idstartEvent/ userTask idapplyTask name请假申请/ exclusiveGateway iddecisionGateway/ sequenceFlow sourceRefstartEvent targetRefapplyTask/ sequenceFlow sourceRefapplyTask targetRefdecisionGateway/ /process2.2 流程部署最佳实践推荐采用资源目录自动部署方式将流程定义文件放置在特定目录src/main/resources/processes/ ├── vacation-process.bpmn20.xml └── department-approval.bpmn20.xml通过RepositoryService进行动态部署验证Autowired private RepositoryService repositoryService; public void deployProcess() { Deployment deployment repositoryService.createDeployment() .addClasspathResource(processes/vacation-process.bpmn20.xml) .name(请假流程部署) .deploy(); logger.info(流程部署成功ID: {}, deployment.getId()); }3. 系统集成与业务实现3.1 用户体系整合方案企业现有用户系统与Activiti身份管理的对接是关键挑战。推荐采用以下整合模式public void syncUserToActiviti(User user) { // 创建Activiti用户 User activitiUser identityService.newUser(user.getId().toString()); activitiUser.setFirstName(user.getRealName()); activitiUser.setEmail(user.getEmail()); identityService.saveUser(activitiUser); // 同步角色关系 user.getRoles().forEach(role - { Group group identityService.createGroupQuery() .groupId(role.getId().toString()) .singleResult(); if (group null) { group identityService.newGroup(role.getId().toString()); group.setName(role.getName()); group.setType(role.getType()); identityService.saveGroup(group); } // 建立用户-组关系 identityService.createMembership( user.getId().toString(), role.getId().toString() ); }); }3.2 业务数据与流程数据分离设计遵循流程数据与业务数据分离原则设计数据库表结构请假申请表结构示例字段名类型描述idBIGINT主键process_instance_idVARCHAR流程实例IDapplicant_idBIGINT申请人IDstart_dateDATE开始日期end_dateDATE结束日期reasonVARCHAR请假原因业务服务层实现流程启动逻辑public String startVacationProcess(VacationRequest request) { // 1. 保存业务数据 VacationApply apply new VacationApply(); apply.setApplicantId(request.getUserId()); apply.setDays(request.getDays()); apply vacationRepository.save(apply); // 2. 启动流程实例 MapString, Object variables new HashMap(); variables.put(days, request.getDays()); variables.put(formId, apply.getId()); ProcessInstance instance runtimeService.startProcessInstanceByKey( vacationProcess, variables ); // 3. 关联业务与流程数据 apply.setProcessInstanceId(instance.getId()); vacationRepository.save(apply); return instance.getId(); }4. 核心功能实现细节4.1 动态任务查询与分页结合Spring Data JPA实现高效的任务查询public PageTaskDTO getPendingTasks(Long userId, int page, int size) { // 获取用户所在角色组 ListString groupIds identityService.createGroupQuery() .groupMember(userId.toString()) .list() .stream() .map(Group::getId) .collect(Collectors.toList()); // 构建任务查询 TaskQuery query taskService.createTaskQuery() .taskCandidateOrAssigned(userId.toString()) .taskCandidateGroupIn(groupIds) .orderByTaskCreateTime() .desc(); // 分页处理 ListTask tasks query.listPage((page-1)*size, size); long total query.count(); // 转换为DTO ListTaskDTO dtos tasks.stream() .map(this::convertToDTO) .collect(Collectors.toList()); return new PageImpl(dtos, PageRequest.of(page-1, size), total); }4.2 审批操作完整实现审批服务需要处理多种业务场景Transactional public void processApproval(ApprovalRequest request) { // 1. 验证任务有效性 Task task taskService.createTaskQuery() .taskId(request.getTaskId()) .singleResult(); if (task null) { throw new BusinessException(任务不存在或已完成); } // 2. 保存审批意见 Approval approval new Approval(); approval.setTaskId(task.getId()); approval.setComment(request.getComment()); approval.setResult(request.getResult()); approvalRepository.save(approval); // 3. 处理审批结果 MapString, Object variables new HashMap(); variables.put(approvalResult, request.getResult()); if (request.getResult() ApprovalResult.REJECT) { // 拒绝时终止流程 runtimeService.deleteProcessInstance( task.getProcessInstanceId(), 审批拒绝 ); } else { // 认领并完成任务 taskService.claim(task.getId(), request.getUserId().toString()); taskService.complete(task.getId(), variables); } }4.3 流程可视化实现生成带高亮的流程图需要特殊处理public void generateProcessImage(String processInstanceId, HttpServletResponse response) { try { // 获取BPMN模型 ProcessInstance instance runtimeService.createProcessInstanceQuery() .processInstanceId(processInstanceId) .singleResult(); BpmnModel model repositoryService.getBpmnModel( instance.getProcessDefinitionId() ); // 获取当前活动节点 ListString activeIds runtimeService.getActiveActivityIds(processInstanceId); // 生成图像流 InputStream imageStream processEngine.getProcessEngineConfiguration() .getProcessDiagramGenerator() .generateDiagram( model, png, activeIds, Collections.emptyList(), 宋体, 宋体, 宋体, null, 1.0 ); // 输出响应 response.setContentType(image/png); IOUtils.copy(imageStream, response.getOutputStream()); } catch (Exception e) { logger.error(流程图生成失败, e); throw new RuntimeException(流程图生成失败); } }5. 生产环境注意事项5.1 性能优化建议针对高并发场景的配置调整# Activiti异步执行器配置 spring.activiti.async-executor-activatetrue spring.activiti.async-executor-core-pool-size10 spring.activiti.async-executor-max-pool-size50 spring.activiti.async-executor-queue-capacity10005.2 监控与日志方案集成Spring Boot Actuator监控端点端点功能描述/actuator/activiti流程引擎状态/actuator/processes已部署流程/actuator/tasks运行中任务统计日志记录关键操作Aspect Component public class ActivitiLogAspect { AfterReturning( pointcut execution(* org.activiti.engine..*.*(..)), returning result ) public void logActivitiOperation(JoinPoint jp, Object result) { String operation jp.getSignature().getName(); logger.info(Activiti操作 {} 执行成功结果: {}, operation, result); } }5.3 异常处理机制统一异常处理增强系统健壮性ControllerAdvice public class ActivitiExceptionHandler { ExceptionHandler(ActivitiException.class) public ResponseEntityErrorResponse handleActivitiError(ActivitiException e) { ErrorResponse response new ErrorResponse(); response.setCode(ACTIVITI_ERROR); response.setMessage(e.getMessage()); return ResponseEntity .status(HttpStatus.INTERNAL_SERVER_ERROR) .body(response); } ExceptionHandler(ActivitiObjectNotFoundException.class) public ResponseEntityErrorResponse handleNotFound(ActivitiObjectNotFoundException e) { return ResponseEntity .status(HttpStatus.NOT_FOUND) .body(new ErrorResponse(PROCESS_NOT_FOUND, e.getMessage())); } }在项目实际部署中我们发现流程定义的热更新是个常见需求。通过扩展RepositoryService可以实现不重启服务的流程版本更新这对7×24小时运行的系统尤为重要。另外建议对历史流程数据定期归档避免核心表数据膨胀影响查询性能。
http://www.gsyq.cn/news/1394240.html

相关文章:

  • Unity插件汉化实战:编辑器翻译文件深度解析与安全修改指南
  • 跨平台视频播放神器:zyfun如何让你的观影体验焕然一新?
  • 告别MATLAB默认字体:一个属性编辑器搞定所有图表文字个性化(宋体/Times New Roman混排)
  • AlphaProof Nexus:AI数学智能体一次性破解9道Erdős世纪难题
  • 【收藏】2026 年版 Java 程序员学大模型完整落地指南,小白也能快速上手
  • 2026年山东留学市场变了:这样挑机构更靠谱 - 资讯速览
  • 2026年金华义乌电商侵权应诉与专利维权完全指南:从链接恢复到反制诉讼的一站式解决方案 - 年度推荐企业名录
  • 2026年行李箱性价比横评:原创设计、材质工艺与价格合理性全对比 - 科技焦点
  • 贵州蓝马会务会展服务:贵州舞台租赁哪家好 - LYL仔仔
  • 解锁Windows智能家居控制:HASS.Agent让你的PC成为Home Assistant的完美伴侣
  • 用NE555和几个电阻电容,我焊出了一个能出三种波形的信号发生器(附完整电路图)
  • 【紧急修复版】ChatGPT插件安装失败?立即执行这6个终端诊断命令——已验证修复2023Q4以来全部17类ERR_PLUGIN_INIT错误
  • 律师案件太多管不过来怎么办?诉讼期限管理和进度追踪的实战方法
  • FPGA硬件加速器设计:HLS性能预测与自动化设计空间探索实践
  • 开源MES系统:如何用openMES实现制造业数字化转型的三大突破
  • Ice:macOS菜单栏管理终极解决方案 - 完整配置与使用指南
  • 八大网盘直链解析:本地化下载助手的终极解决方案
  • 对比直接使用厂商API与通过Taotoken聚合调用的成本差异
  • 告别网页卡顿!用PotPlayer+DPL列表,一键流畅看B站、斗鱼、虎牙直播(保姆级教程)
  • 基于BERT-BiGRUA与TCN的社交媒体负面舆情智能预警实战
  • 太阳能路灯选购指南:公园广场景区小区厂家怎么选? - 资讯速览
  • RuntimeUnityEditor架构解析:核心组件与工作原理
  • COMSOL材料扫描功能实战:如何用5.0+版本快速对比10种材料性能?
  • 贝叶斯网络与高斯混合模型在机器人任务导向抓取规划中的应用
  • 肿瘤干细胞的特征图谱:从定义到治疗靶向
  • 【Elasticsearch从入门到精通】第42篇:Elasticsearch倒排索引原理——Lucene的核心数据结构
  • ARM A64 SIMD指令SQRSHRN与SQSHRN详解与应用
  • 告别海投焦虑:AI找工作助手全平台自动投递简历的终极指南
  • C# 类型系统
  • 基于QuaDRiGa的双移动空地链路信道建模实战与验证