news 2026/5/29 19:17:04

Jeecg-Boot免费版如何自己动手集成Activiti 6工作流?保姆级源码解析与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Jeecg-Boot免费版如何自己动手集成Activiti 6工作流?保姆级源码解析与避坑指南

Jeecg-Boot免费版集成Activiti 6工作流实战指南

在开源低代码平台Jeecg-Boot的实际应用中,工作流引擎的缺失常常成为项目落地的瓶颈。本文将带你从零开始,通过源码级改造将Activiti 6深度集成到Jeecg-Boot免费版中,特别针对单租户场景下的多租户适配、前后端联调等核心痛点提供解决方案。

1. 环境准备与基础配置

1.1 依赖管理

首先在pom.xml中添加Activiti核心依赖,注意版本兼容性:

<dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> <version>6.0.0</version> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-modeler</artifactId> <version>6.0.0</version> </dependency>

注意:Jeecg-Boot默认使用MyBatis-Plus 3.4.0,与Activiti 6.0.0存在SQL语法兼容问题,建议添加如下配置解决:

mybatis-plus.global-config.db-config.column-format=``

1.2 数据库初始化

执行以下SQL创建Activiti基础表结构:

-- 使用Jeecg-Boot的DataSource自动建表 spring.activiti.database-schema-update=true spring.activiti.history-level=audit

常见问题排查表:

问题现象可能原因解决方案
表前缀不生效MyBatis-Plus拦截器冲突禁用MP的SQL解析器
历史表未创建history-level配置错误设置为full或audit
流程定义加载失败字符集不匹配检查MySQL的utf8mb4配置

2. 多租户模式适配改造

2.1 租户ID自动注入

创建自定义的ActivityTenantIdHandler实现TenantIdHandler接口:

public class ActivityTenantIdHandler implements TenantIdHandler { @Override public String getCurrentTenantId() { // 从Jeecg-Boot的Token中提取租户ID return TokenUtils.getTenantId(); } }

在配置类中注册处理器:

@Bean public SpringProcessEngineConfiguration processEngineConfiguration( DataSource dataSource, PlatformTransactionManager transactionManager) { SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration(); config.setTenantIdHandler(new ActivityTenantIdHandler()); // 其他配置... return config; }

2.2 流程实例隔离方案

针对单租户需求,需要重写以下关键类:

  1. CustomUserEntityManager:对接Jeecg用户体系
  2. CustomGroupEntityManager:处理部门映射
  3. CustomRuntimeService:封装流程启动逻辑

关键改造点代码示例:

public class CustomRuntimeService extends RuntimeServiceImpl { @Override public ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables) { variables.put("tenantId", TenantContext.getTenant()); return super.startProcessInstanceByKey( processDefinitionKey + "_" + TenantContext.getTenant(), businessKey, variables ); } }

3. 前后端深度集成

3.1 前端页面嵌入方案

src/views/modules下新建流程管理模块:

<template> <div class="jeecg-container"> <a-tabs> <a-tab-pane key="1" tab="流程设计"> <iframe :src="modelerUrl" style="width:100%;height:calc(100vh - 180px)" /> </a-tab-pane> </a-tabs> </div> </template> <script> export default { data() { return { modelerUrl: `${window._CONFIG['domianURL']}/activiti/modeler.html?token=${this.$store.getters.token}` } } } </script>

提示:需要配置Nginx解决跨域问题:

location /activiti { proxy_pass http://localhost:8080/activiti; add_header 'Access-Control-Allow-Origin' $http_origin; add_header 'Access-Control-Allow-Credentials' 'true'; }

3.2 接口安全改造

SecurityConfig中添加白名单:

@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers( "/activiti/**", "/modeler.html", "/editor-app/**" ).permitAll() // 其他配置... }

Token传递拦截器示例:

public class ActivitiTokenInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getParameter("token"); if(StringUtils.isNotBlank(token)){ TokenUtils.setToken(token); } return true; } }

4. 业务场景实战案例

4.1 请假流程完整实现

  1. 流程定义设计

    • 使用BPMN设计包含【提交】【部门审批】【HR备案】三个节点
    • 设置表单属性:
      <activiti:formProperty id="leaveDays" name="请假天数" type="long" required="true"/>
  2. 业务表关联

    @TableName("oa_leave") public class LeaveApply extends BaseEntity { @TableField("process_instance_id") private String processInstanceId; // 其他字段... }
  3. 流程启动控制器

    @PostMapping("/start") public Result<?> startProcess(@RequestBody LeaveApply leave) { // 业务数据入库 leaveService.save(leave); // 启动流程 runtimeService.startProcessInstanceByKey( "leave_process", leave.getId().toString(), Map.of("applyUser", getCurrentUsername(), "days", leave.getDays()) ); return Result.ok(); }

4.2 审批节点自动分配

实现动态任务分配策略:

public class LeaveTaskAssignee implements TaskAssigneeCalculator { @Override public String calculateAssignee(DelegateTask task) { String eventName = task.getEventName(); if ("create".equals(eventName)) { // 部门审批环节自动分配 if ("dept_approve".equals(task.getTaskDefinitionKey())) { return userService.getDeptManager( TaskUtils.getVariable(task, "applyUser") ); } } return null; } }

在流程定义中引用:

<userTask id="dept_approve" name="部门审批"> <extensionElements> <activiti:taskListener event="create" class="com.jeecg.activiti.LeaveTaskAssignee"/> </extensionElements> </userTask>

5. 性能优化与生产建议

5.1 数据库连接池配置

推荐使用HikariCP并调整以下参数:

spring.datasource.hikari.maximum-pool-size=20 spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.idle-timeout=30000 spring.activiti.async-executor-activate=true

5.2 历史数据归档策略

创建定时任务清理历史数据:

@Scheduled(cron = "0 0 2 * * ?") public void archiveHistoricData() { historyService.createHistoricProcessInstanceQuery() .finished() .list() .forEach(instance -> { // 归档到MongoDB mongoTemplate.save(instance, "historic_process"); // 删除关系型数据库记录 historyService.deleteHistoricProcessInstance(instance.getId()); }); }

5.3 缓存优化方案

自定义流程定义缓存:

@Bean public ProcessDefinitionCache processDefinitionCache() { return new CustomProcessDefinitionCache() { @Override protected ProcessDefinitionEntity getProcessDefinition(String processDefinitionId) { // 结合Redis实现二级缓存 String redisKey = "activiti:pd:" + processDefinitionId; ProcessDefinitionEntity pd = redisTemplate.opsForValue().get(redisKey); if(pd == null) { pd = super.getProcessDefinition(processDefinitionId); redisTemplate.opsForValue().set( redisKey, pd, 1, TimeUnit.HOURS ); } return pd; } }; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/29 19:16:02

UnityLive2DExtractor:快速提取Live2D资源的终极指南

UnityLive2DExtractor&#xff1a;快速提取Live2D资源的终极指南 【免费下载链接】UnityLive2DExtractor Unity Live2D Cubism 3 Extractor 项目地址: https://gitcode.com/gh_mirrors/un/UnityLive2DExtractor 想要从Unity游戏中提取精美的Live2D角色模型吗&#xff1f…

作者头像 李华
网站建设 2026/5/29 19:16:00

IEEE论文排版进阶:5个LaTeX‘黑魔法’让你的图表公式更专业

IEEE论文排版进阶&#xff1a;5个LaTeX‘黑魔法’让你的图表公式更专业当你的LaTeX论文初稿已经成型&#xff0c;那些隐藏在宏包深处的排版技巧才是让审稿人眼前一亮的秘密武器。本文不是基础教程&#xff0c;而是为那些追求出版级精度的研究者准备的视觉优化手册。1. 参考文献…

作者头像 李华
网站建设 2026/5/29 19:12:12

xrdp远程连接Ubuntu花屏?可能是你的.xsession和startwm.sh在‘打架’

xrdp远程连接Ubuntu花屏问题深度解析&#xff1a;会话管理与启动脚本的冲突解决当你满怀期待地通过xrdp远程连接到Ubuntu系统&#xff0c;准备开始高效工作时&#xff0c;屏幕上却出现令人沮丧的花屏或黑屏现象——这种体验想必不少技术爱好者都曾遭遇过。不同于常规的安装教程…

作者头像 李华
网站建设 2026/5/29 19:07:11

CPT Markets:经纪商服务质量与用户支持评估

外汇服务平台的价值&#xff0c;往往体现在细节之中。清晰的信息展示、顺畅的账户流程、及时的风险提示和相对完整的服务支持&#xff0c;都会影响用户对平台的长期印象。围绕CPT Markets进行评测&#xff0c;可以看到一个更偏综合服务的观察方向&#xff0c;而不是停留在单一功…

作者头像 李华