首页
/ 【保姆级教程】从零构建企业级工作流引擎:FlowLong飞龙实战指南

【保姆级教程】从零构建企业级工作流引擎:FlowLong飞龙实战指南

2026-02-04 04:05:52作者:翟江哲Frasier

🔥 为什么选择FlowLong?破解中国特色审批痛点

你是否还在为这些工作流难题抓狂?

  • 复杂分支条件配置如同天书
  • 会签/或签/票签等中国式审批难以实现
  • 流程驳回策略混乱导致业务中断
  • 与Spring Boot/Solon框架集成困难重重

本文将带你30分钟上手FlowLong,掌握:

  • ✅ 10分钟环境搭建与项目初始化
  • ✅ 20分钟实现请假审批全流程
  • ✅ 3大核心API与10+企业级功能实战
  • ✅ 避坑指南与性能优化技巧

📋 目录导航(建议收藏)

章节 核心内容 难度 预计时间
1. 引擎架构解析 核心组件与工作原理 ⭐⭐⭐ 8分钟
2. 环境搭建 Spring Boot集成实战 10分钟
3. 快速入门 请假流程完整案例 ⭐⭐ 15分钟
4. 核心功能 分支/会签/驳回深度解析 ⭐⭐⭐ 20分钟
5. 高级特性 事件监听与定时任务 ⭐⭐⭐⭐ 18分钟
6. 生产部署 性能调优与最佳实践 ⭐⭐⭐⭐ 14分钟

1. 引擎架构解析:5大核心组件驱动业务流程

1.1 架构概览

flowchart TD
    A[流程引擎 FlowLongEngine] --> B[核心服务层]
    B --> C1[ProcessService 流程定义]
    B --> C2[RuntimeService 实例运行]
    B --> C3[TaskService 任务管理]
    B --> C4[QueryService 数据查询]
    D[持久层] --> D1[MyBatis-Plus DAO]
    D --> D2[多数据库支持]
    E[扩展点] --> E1[事件监听]
    E --> E2[任务拦截器]
    E --> E3[自定义处理器]
    B --> D
    B --> E

1.2 核心服务功能对比

服务接口 主要职责 核心方法 典型场景
ProcessService 流程部署与管理 deployByResource() 发布新流程定义
RuntimeService 实例生命周期 startInstanceById() 启动请假流程
TaskService 任务操作 complete()/reject() 审批/驳回任务
QueryService 数据查询 getTasksByInstanceId() 待办任务列表

2. 环境搭建:Spring Boot集成(10分钟搞定)

2.1 依赖配置(pom.xml)

<dependency>
    <groupId>com.aizuda</groupId>
    <artifactId>flowlong-spring-boot-starter</artifactId>
    <version>最新版本</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

2.2 数据库初始化

-- 执行官方SQL脚本
source /data/web/disk1/git_repo/aizuda/flowlong/db/flowlong-mysql.sql

2.3 配置文件(application.yml)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/flowlong?useSSL=false
    username: root
    password: 123456

flowlong:
  banner: true  # 显示启动Logo
  remind:
    initial-delay: 60000  # 提醒任务初始延迟
    period: 300000        # 提醒检查周期(5分钟)
  eventing:
    task: true  # 启用任务事件监听

2.4 启动类配置

@SpringBootApplication
@MapperScan("com.aizuda.bpm.mybatisplus.mapper")
public class FlowLongApplication {
    public static void main(String[] args) {
        SpringApplication.run(FlowLongApplication.class, args);
    }
}

3. 快速入门:3步实现请假审批流程

3.1 流程定义(process.json)

{
  "id": "leave-process",
  "name": "请假流程",
  "nodes": [
    {
      "nodeKey": "start",
      "nodeName": "开始",
      "nodeType": "startEvent",
      "nextNodeKeys": ["approve"]
    },
    {
      "nodeKey": "approve",
      "nodeName": "经理审批",
      "nodeType": "taskNode",
      "assignType": 1,
      "assignee": "manager001",
      "nextNodeKeys": ["end"],
      "rejectStrategy": 1  // 驳回策略:1-退回发起人
    },
    {
      "nodeKey": "end",
      "nodeName": "结束",
      "nodeType": "endEvent"
    }
  ]
}

3.2 部署与启动流程

@RestController
@RequestMapping("/process")
@AllArgsConstructor
public class LeaveController {
    private final FlowLongEngine flowLongEngine;
    
    // 部署流程
    @PostMapping("/deploy")
    public Long deploy() {
        FlowCreator creator = FlowCreator.of("admin", "系统管理员");
        return flowLongEngine.processService()
                   .deployByResource("process.json", creator, false);
    }
    
    // 启动流程实例
    @PostMapping("/start")
    public FlwInstance start() {
        FlowCreator creator = FlowCreator.of("user001", "张三");
        Map<String, Object> args = new HashMap<>();
        args.put("days", 3);  // 请假天数
        args.put("reason", "病假");
        
        return flowLongEngine.startInstanceByProcessKey("leave-process", null, creator, args, false, null)
                   .orElseThrow(() -> new RuntimeException("流程启动失败"));
    }
}

3.3 任务审批与查询

// 审批任务
@PostMapping("/approve/{taskId}")
public boolean approve(@PathVariable Long taskId) {
    FlowCreator approver = FlowCreator.of("manager001", "王经理");
    Map<String, Object> args = new HashMap<>();
    args.put("comment", "同意请假");
    return flowLongEngine.taskService().complete(taskId, approver, args);
}

// 查询待办任务
@GetMapping("/tasks")
public List<FlwTask> getTasks(@RequestParam String userId) {
    return flowLongEngine.queryService()
               .getActiveTasksByUserId(userId)
               .orElse(Collections.emptyList());
}

4. 核心功能实战:解锁中国特色审批

4.1 条件分支:3种分支类型对比

flowchart LR
    A[开始] --> B{请假天数}
    B -- <3天 --> C[主管审批]
    B -- ≥3天 --> D[经理审批]
    B -- ≥7天 --> E[CEO审批]
    C & D & E --> F[结束]

实现代码

{
  "nodeKey": "condition",
  "nodeName": "条件分支",
  "nodeType": "conditionNode",
  "conditions": [
    {
      "expression": "${days < 3}",
      "nextNodeKey": "supervisor"
    },
    {
      "expression": "${days >= 3 && days < 7}",
      "nextNodeKey": "manager"
    }
  ],
  "defaultNextNodeKey": "ceo"
}

4.2 会签管理:4种会签模式全解析

会签类型 特点 适用场景 实现参数
顺序会签 依次审批 层级审批 performType:1
并行会签 同时审批 多人评审 performType:2
或签 一人通过即可 知会类审批 performType:3
票签 权重投票 委员会决策 performType:4, passWeight:60

票签实现示例

{
  "nodeKey": "vote",
  "nodeName": "委员会投票",
  "nodeType": "taskNode",
  "performType": 4,  // 票签模式
  "passWeight": 60,  // 60%权重通过
  "assignees": [
    {"userId": "member1", "weight": 30},
    {"userId": "member2", "weight": 30},
    {"userId": "member3", "weight": 40}
  ]
}

4.3 驳回策略:3种经典场景配置

flowchart TD
    A[当前任务] -->|驳回| B{策略选择}
    B --> C[退回上一步]
    B --> D[退回发起人]
    B --> E[指定节点]
    C --> F[重新审批]
    D --> G[修改申请]
    E --> H[特定节点处理]

配置示例

{
  "nodeKey": "managerApproval",
  "rejectStrategy": 2,  // 2-退回发起人
  "rejectStart": 1      // 1-继续执行,2-回到上节点
}

5. 高级特性:事件监听与定时任务

5.1 任务事件监听

@Configuration
public class TaskEventListenerConfig {
    @Bean
    public TaskListener taskListener() {
        return new TaskListener() {
            @Override
            public void create(TaskEvent event) {
                FlwTask task = event.getFlwTask();
                // 发送邮件通知
                sendEmail(task.getAssignee(), "新任务提醒", task.getTaskName());
            }
            
            @Override
            public void complete(TaskEvent event) {
                // 记录审批日志
                log.info("任务完成: {} by {}", event.getFlwTask().getId(), event.getOperator());
            }
        };
    }
}

5.2 定时任务与自动提醒

flowlong:
  remind:
    initial-delay: 60000      # 1分钟后开始执行
    period: 300000            # 每5分钟检查一次
    max-remind-count: 3       # 最多提醒3次

自定义提醒实现

@Component
public class SmsTaskReminder implements TaskReminder {
    @Override
    public void remind(FlwTask task, int remindCount) {
        String phone = getUserPhone(task.getAssignee());
        String content = String.format("您有任务[%s]已逾期,请及时处理(第%d次提醒)", 
                          task.getTaskName(), remindCount);
        smsService.send(phone, content);
    }
}

6. 生产部署:性能优化与最佳实践

6.1 数据库优化

优化项 配置建议 性能提升
索引优化 为instance_id/task_key创建复合索引 5-10倍查询提速
分表策略 历史任务表按月份分表 降低锁竞争
连接池配置 hikari.maximum-pool-size=20 避免连接耗尽

6.2 缓存配置

@Bean
public FlowCache redisFlowCache(RedisTemplate<String, Object> redisTemplate) {
    return new RedisFlowCache(redisTemplate)
               .setProcessModelExpire(3600)  // 流程模型缓存1小时
               .setInstanceDataExpire(1800); // 实例数据缓存30分钟
}

6.3 避坑指南

  1. 流程部署重复问题

    // 部署时设置repeat=false避免重复部署
    processService.deployByResource("process.json", creator, false);
    
  2. 并发任务处理

    // 使用分布式锁确保任务唯一处理
    @Bean
    public JobLock redisJobLock(RedissonClient redissonClient) {
        return new RedissonJobLock(redissonClient);
    }
    
  3. 长流程性能问题

    // 开启流程实例状态缓存
    flowlong:
      cache:
        instance-state: true
    

🚀 快速启动项目(3行命令)

# 克隆仓库
git clone https://gitcode.com/aizuda/flowlong.git

# 进入示例项目
cd flowlong/flowlong-spring-boot-example

# 启动应用
mvn spring-boot:run

📚 资源获取

🔖 结语与下期预告

通过本文你已掌握FlowLong核心功能,下期我们将深入:

  • 流程设计器集成实战
  • 多租户与权限控制
  • 企业版高级功能解析

如果觉得本文有帮助,请点赞收藏关注,你的支持是我们持续更新的动力!

版权声明:本文基于FlowLong开源项目创作,使用需遵守Apache-2.0协议,转载请注明出处。

登录后查看全文
热门项目推荐
相关项目推荐