芋道源码yudao-cloud工作流实战:绩效审批系统二开指南

张开发
2026/4/16 3:53:17 15 分钟阅读

分享文章

芋道源码yudao-cloud工作流实战:绩效审批系统二开指南
1. 为什么选择yudao-cloud工作流做绩效审批系统第一次接触yudao-cloud的工作流模块时我就被它的设计理念打动了。作为一个长期奋战在企业管理系统开发一线的程序员我深知传统工作流引擎的痛点配置复杂、学习成本高、与业务系统集成困难。而yudao-cloud的BPM模块完美解决了这些问题。在实际项目中我们团队需要开发一个绩效评分审批系统。核心需求很简单员工填写月度绩效后自动流转给直属领导审批。但传统方案需要自己搭建Activiti或Flowable环境还要处理各种繁琐的XML配置。而yudao-cloud已经封装好了这些底层技术提供了开箱即用的RESTful API和可视化设计器。举个具体例子传统方案要实现审批人动态指定这个常见需求可能需要写一堆JavaDelegate代码。但在yudao-cloud里只需要在前端界面勾选用户类型然后绑定员工表的leader_id字段即可。这种设计让开发效率提升了至少3倍。2. 环境准备与基础配置2.1 数据库初始化在开始之前我们需要先准备好数据库环境。yudao-cloud的工作流模块依赖一些预置的表结构官方提供了完整的SQL脚本。这里有个小技巧建议先用Docker启动一个干净的MySQL实例避免与现有业务数据库产生冲突。# 启动MySQL容器 docker run --name yudao-mysql -e MYSQL_ROOT_PASSWORD123456 -p 3306:3306 -d mysql:8.0 # 导入SQL假设脚本已下载到本地 mysql -h127.0.0.1 -uroot -p123456 yudao-bpm.sql导入完成后你会看到新增了约40张表其中最重要的是ACT_RU_开头的运行时表和ACT_HI_开头的历史表。不过好消息是这些表我们基本不需要直接操作yudao-cloud已经封装好了所有常用操作。2.2 服务启动与验证接下来启动BPM服务模块。在IDEA中直接运行BpmServerApplication类即可。这里有个容易踩的坑确保你的Nacos配置中心已经正确配置特别是以下关键参数spring: activiti: database-schema-update: true async-executor-activate: true check-process-definitions: false启动成功后访问前端BPM菜单如果能看到流程模型、我的待办等菜单项说明环境已经就绪。建议此时先创建一个测试流程练练手熟悉基本操作。3. 绩效审批流程设计实战3.1 数据模型设计我们的绩效系统需要三张核心表绩效主表performance存储月度绩效整体信息绩效明细表performance_score记录每个任务项的评分详情审批记录表performance_approve保存审批过程数据CREATE TABLE performance ( id bigint NOT NULL AUTO_INCREMENT, employee_id bigint NOT NULL COMMENT 员工ID, year_month varchar(7) NOT NULL COMMENT 年月, status tinyint NOT NULL DEFAULT 0 COMMENT 0-草稿 1-待审批 2-已通过, PRIMARY KEY (id) ) COMMENT绩效主表; CREATE TABLE performance_score ( id bigint NOT NULL AUTO_INCREMENT, performance_id bigint NOT NULL, task_name varchar(100) NOT NULL, self_score int DEFAULT NULL COMMENT 自评分, leader_score int DEFAULT NULL COMMENT 领导评分, process_instance_id varchar(64) DEFAULT NULL COMMENT 流程实例ID, PRIMARY KEY (id) ) COMMENT绩效明细表;特别注意process_instance_id字段这是关联工作流的关键字段。当员工提交绩效时系统会自动生成流程实例并记录这个ID。3.2 可视化流程设计进入yudao-cloud的流程模型界面点击新建流程标识符填performance_approval流程名称写绩效审批流程表单类型选择业务表单在设计器界面从左侧拖拽节点到画布开始节点 → 员工提交用户任务 → 领导审批排他网关 → 判断是否通过结束节点 → 流程结束关键配置在领导审批节点审批人类型选择用户审批人表达式填${leaderId}表单字段配置关联performance_score表的字段保存后点击发布一个完整的审批流程就设计好了。整个过程不到10分钟相比传统方式节省了大量时间。4. 业务系统集成技巧4.1 服务调用方式yudao-cloud提供了两种集成方式Feign客户端推荐直接调用REST API首先在pom.xml中添加依赖dependency groupIdcn.iocoder.boot/groupId artifactIdyudao-module-bpm-api/artifactId version${yudao.version}/version /dependency然后定义Feign接口FeignClient(name yudao-bpm) public interface BpmApi { PostMapping(/process-instance/create) CommonResultString startProcess( RequestParam Long userId, RequestBody ProcessInstanceCreateReqDTO dto); GetMapping(/task/list-by-process-instance-id) CommonResultListTaskRespDTO getTasks( RequestParam String processInstanceId); }4.2 关键业务代码实现当员工点击提交绩效时我们需要保存绩效数据启动审批流程更新流程实例IDTransactional public void submitPerformance(PerformanceSubmitReq req) { // 1. 保存绩效数据 Performance performance new Performance(); BeanUtils.copyProperties(req, performance); performance.setStatus(1); // 待审批状态 performanceMapper.insert(performance); // 2. 启动流程 ProcessInstanceCreateReqDTO dto new ProcessInstanceCreateReqDTO(); dto.setProcessDefinitionKey(performance_approval); dto.setBusinessKey(performance.getId().toString()); // 设置领导ID变量 MapString, Object variables new HashMap(); variables.put(leaderId, getLeaderId(req.getEmployeeId())); dto.setVariables(variables); CommonResultString result bpmApi.startProcess(req.getEmployeeId(), dto); if (!result.isSuccess()) { throw new ServiceException(流程启动失败); } // 3. 更新流程实例ID performance.setProcessInstanceId(result.getData()); performanceMapper.updateById(performance); }5. 审批功能深度优化5.1 动态审批人处理实际业务中审批人往往需要动态确定。我们可以在流程启动前通过变量传递审批人信息// 获取员工的直属领导 Long leaderId employeeService.getLeaderId(employeeId); // 设置流程变量 MapString, Object variables new HashMap(); variables.put(leaderId, leaderId); ProcessInstanceCreateReqDTO dto new ProcessInstanceCreateReqDTO() .setVariables(variables);更复杂的场景可以使用监听器Component public class PerformanceTaskListener implements TaskListener { Override public void notify(DelegateTask delegateTask) { String eventName delegateTask.getEventName(); if (create.equals(eventName)) { String businessKey delegateTask.getProcessInstanceBusinessKey(); Long performanceId Long.valueOf(businessKey); Performance performance performanceMapper.selectById(performanceId); // 设置部门负责人为审批人 Long deptLeaderId departmentService.getDeptLeader( performance.getDepartmentId()); delegateTask.setAssignee(deptLeaderId.toString()); } } }5.2 审批回调处理当领导完成审批后系统需要更新业务数据状态。可以通过两种方式实现统一回调接口消息队列通知推荐第一种方式在yudao-cloud中配置回调地址RestController RequestMapping(/performance/callback) public class PerformanceCallbackController { PostMapping(/approve) public CommonResultBoolean handleApprove( RequestParam String processInstanceId, RequestParam Boolean approved) { // 根据流程实例ID查询业务数据 Performance performance performanceMapper.selectOne( new LambdaQueryWrapperPerformance() .eq(Performance::getProcessInstanceId, processInstanceId)); // 更新状态 performance.setStatus(approved ? 2 : 3); performanceMapper.updateById(performance); return CommonResult.success(true); } }记得在流程设计器中配置回调地址为/performance/callback/approve6. 常见问题排查指南在实际开发中我遇到过几个典型问题流程无法启动检查bpm服务是否正常注册到Nacos数据库连接配置是否正确。可以查看bpm服务的启动日志重点检查Activiti引擎初始化部分。审批人显示错误确保流程变量正确传递特别是leaderId的值类型要与表单配置匹配。可以在流程实例详情页查看变量列表。回调接口不触发检查yudao-cloud的任务监听器配置确保回调URL可访问。建议先用Postman测试接口可用性。历史数据查询慢当流程实例数量超过1万时建议给ACT_HI_*表添加合适的索引特别是PROC_INST_ID_和BUSINESS_KEY_字段。有个特别实用的调试技巧在application-dev.yml中开启SQL日志logging: level: org.activiti.engine.impl.persistence.entity: debug这样可以在控制台看到Activiti生成的所有SQL语句方便定位问题。

更多文章