# jlflow **Repository Path**: carro/jlflow ## Basic Information - **Project Name**: jlflow - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-19 - **Last Updated**: 2026-07-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # JLFlow 微流程引擎 > 轻量级、零 Spring 依赖的微流程引擎:纯 Java + JDBC + 内置 UI(HTML + Vue3 + LogicFlow),开箱即用。 JLFlow 是一个面向中小型业务的轻量微流程引擎。它不绑定 Spring、不依赖 MyBatis、不引入 JPA,仅通过原生 JDBC + Servlet API 提供完整流程能力:部署、版本快照、实例运行、任务办理、撤回、驳回、委托、加签减签、超时自动审批、流程图可视化编辑与监控。引擎通过 SPI 与 Listener 钩子与宿主解耦,可无缝接入 SpringBoot / SpringMVC / 普通 Java 三类工程。 - 仓库地址:https://gitee.com/carro/jlflow - 引擎版本:1.0.0 - groupId:`site.jlopen.jlflow` --- ## 特性 - **零 Spring 依赖**:核心包 `jlflow-engine-core` 仅依赖 `slf4j-api`,不引入 Spring / MyBatis / JPA,可在任意 Java 工程使用。 - **内置可视化 UI**:`jlflow-engine-ui` 提供 LogicFlow 流程图设计器 + 管理后台(部署 / 实例 / 任务 / 日志 / 委托 / 超时规则),开箱即用。 - **雪花 ID(BIGINT)**:所有主键统一使用 `BIGINT` 雪花 ID(Java 中为 `Long`),便于跨服务传递与排序。 - **多租户**:通过 `tenant_id` 字段 + `AuthContext` 线程上下文实现逻辑隔离,可按需开关。 - **SPI 扩展点**:`IdentityProvider` / `ExpressionEvaluator` / `JsonSerializer` 三个 SPI,宿主可替换默认实现。 - **Listener 钩子**:`InstanceListener` / `TaskListener` / `RouteListener` / `ErrorListener`,覆盖实例生命周期、任务办理、路由计算、异常告警等关键节点。 - **版本快照机制**:发布即生成不可变版本(`jl_flow_deploy_version`),实例运行时再生成运行时快照(`jl_flow_instance_version`),支持已发布流程热升级不影响存量实例。 - **高级场景**:撤回(withdraw)、委托(delegate)、加签减签(counter sign / reduce sign)、超时自动审批(auto approve / reject / remind)、驳回回退(reject to node)等开箱即用。 - **REST API + 内置 UI**:基于 Servlet 实现,宿主只需声明依赖即可在 Web 容器中自动挂载到 `/jlflow` 路径。 --- ## 工程模块 JLFlow 采用 Maven 多模块组织,共 4 个子模块: | 模块 | artifactId | 说明 | | --- | --- | --- | | 核心引擎 | `jlflow-engine-core` | 引擎核心:API、Engine、Repository、JDBC、SPI、Listener,零 Spring 依赖 | | Spring 适配 | `jlflow-engine-spring` | SpringBoot/SpringMVC 适配包:读 `application.yml` + 自动注入 + DataSource 自动检测 | | 内置 UI | `jlflow-engine-ui` | 静态资源包:HTML + Vue3 + LogicFlow 流程图设计器与管理后台 | | 示例工程 | `jlflow-engine-samples` | 示例聚合模块(含 `jlflow-sample-springboot`) | 依赖关系: ``` jlflow-engine-core ← jlflow-engine-spring ← jlflow-engine-samples ← jlflow-engine-ui ← ``` --- ## 快速开始 只需 3 步即可在 SpringBoot 工程中接入 JLFlow: ### 第 1 步:引入依赖 ```xml site.jlopen.jlflow jlflow-engine-spring 1.0.0 site.jlopen.jlflow jlflow-engine-ui 1.0.0 com.mysql mysql-connector-j com.zaxxer HikariCP com.google.code.gson gson ``` ### 第 2 步:配置数据源与引擎 在 `application.yml` 中: ```yaml jlflow: enabled: true datasource: mode: self # self / auto / external url: jdbc:mysql://127.0.0.1:3306/jlflow?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 max-pool-size: 10 min-idle: 2 connection-timeout: 30000 ui: enabled: true context-path: /jlflow api: enabled: true context-path: /jlflow/api schedule: enabled: true timeout-scan-interval: 60 # 超时扫描间隔(秒) ``` 并执行建表脚本:`jlflow-engine-core/src/main/resources/sql/jlflow-mysql.sql` ### 第 3 步:启动应用 启动 SpringBoot 应用后: - 内置 UI 入口:`http://localhost:8080/jlflow` - REST API 根路径:`http://localhost:8080/jlflow/api` 在 UI 中点击「部署管理」→「新建部署」→ 进入流程图编辑器设计并发布,再发起实例即可。 --- ## 接入方式 ### 方式一:SpringBoot 引入 `jlflow-engine-spring`,自动配置 `JLFlowAutoConfiguration` 会扫描 `jlflow.*` 配置并自动启动引擎与 UI。无需任何 Java 代码。 ### 方式二:SpringMVC(传统 Spring) 引入 `jlflow-engine-core` + `jlflow-engine-ui`,在 Spring 配置类中手动构造: ```java @Configuration public class JlflowConfig { @Bean(destroyMethod = "shutdown") public JLFlowEngine jlFlowEngine(DataSource dataSource) { JLFlowConfig config = ConfigLoader.load(); // 读 classpath:jlflow.properties JLFlowEngine engine = JLFlowEngine.create(dataSource, config); engine.start(); return engine; } } ``` ### 方式三:常规 Java(非 Spring) ```java // 1. 加载配置 JLFlowConfig config = ConfigLoader.load(); // 2. 创建并启动引擎 JLFlowEngine engine = JLFlowEngine.create(config); engine.start(); // 3. 使用 API JLFlowApis apis = engine.apis(); apis.deploy().create(deployDto); apis.instance().start(startDto); apis.task().complete(completeDto); // 4. 应用关闭时 engine.shutdown(); ``` 非 Web 环境不加载内置 UI,仅使用核心 API。 --- ## 配置项说明 所有配置以 `jlflow.*` 为前缀,支持 `application.yml` / `application.properties` / `jlflow.properties` / JVM 参数 `-Djlflow.xxx` / 环境变量 `JLFLOW_XXX` 五种来源。 | 配置项 | 默认值 | 说明 | | --- | --- | --- | | `jlflow.enabled` | `true` | 引擎总开关 | | `jlflow.id-generator` | `snowflake` | ID 生成器(仅 snowflake) | | `jlflow.auto-create-table` | `false` | 是否自动建表(建议生产环境手动执行 SQL) | | `jlflow.table.prefix` | `jl_flow_` | 表前缀 | | `jlflow.tenant.enabled` | `false` | 是否启用多租户 | | `jlflow.tenant.default` | `_DEFAULT_` | 默认租户 ID | | `jlflow.tenant.resolver` | `threadlocal` | 租户解析器(threadlocal / header) | | `jlflow.datasource.mode` | `self` | 数据源模式:`self` 自建 / `auto` 自动检测 / `external` 外部注入 | | `jlflow.datasource.url` | - | JDBC URL(self 模式必填) | | `jlflow.datasource.driver-class-name` | - | JDBC Driver 类名 | | `jlflow.datasource.username` | - | 数据库用户名 | | `jlflow.datasource.password` | - | 数据库密码 | | `jlflow.datasource.max-pool-size` | `10` | 最大连接数 | | `jlflow.datasource.min-idle` | `2` | 最小空闲连接 | | `jlflow.datasource.connection-timeout` | `30000` | 连接超时(毫秒) | | `jlflow.ui.enabled` | `true` | 是否启用内置 UI | | `jlflow.ui.context-path` | `/jlflow` | UI 上下文路径 | | `jlflow.ui.auth.enabled` | `false` | 是否启用 UI Basic 认证 | | `jlflow.ui.auth.username` | `admin` | UI 认证用户名 | | `jlflow.ui.auth.password` | `jlflow123` | UI 认证密码 | | `jlflow.api.enabled` | `true` | 是否启用 REST API | | `jlflow.api.context-path` | `/jlflow/api` | API 上下文路径 | | `jlflow.schedule.enabled` | `true` | 是否启用超时扫描调度 | | `jlflow.schedule.timeout-scan-interval` | `60` | 超时扫描间隔(秒) | | `jlflow.router.strict-mode` | `false` | 路由严格模式:true 时未命中任何出边将抛异常 | --- ## 数据库表结构 JLFlow 共 14 张表,全部使用 `BIGINT` 雪花 ID 主键,引擎 `InnoDB`,字符集 `utf8mb4`。 | 序号 | 表名 | 说明 | 主键 | 含租户 | | --- | --- | --- | --- | --- | | 1 | `jl_flow_deploy` | 流程部署主表 | `deploy_id` | ✅ | | 2 | `jl_flow_deploy_version` | 部署版本快照(含 graph_json LONGTEXT) | `version_id` | ❌ | | 3 | `jl_flow_node` | 节点定义 | `node_id` | ❌ | | 4 | `jl_flow_edge` | 连线定义 | `edge_id` | ❌ | | 5 | `jl_flow_agent` | 节点经办规则 | `agent_id` | ❌ | | 6 | `jl_flow_agent_link` | 经办绑定(候选人/黑名单) | `link_id` | ❌ | | 7 | `jl_flow_instance` | 流程实例 | `instance_id` | ✅ | | 8 | `jl_flow_instance_version` | 实例运行时版本快照(含 graph_snapshot LONGTEXT) | `version_id` | ❌ | | 9 | `jl_flow_task` | 任务 | `task_id` | ✅ | | 10 | `jl_flow_task_assign` | 任务经办人 | `assign_id` | ❌ | | 11 | `jl_flow_log` | 运行日志 | `log_id` | ✅ | | 12 | `jl_flow_delegate` | 委托关系 | `delegate_id` | ✅ | | 13 | `jl_flow_counter_sign` | 加签记录 | `counter_sign_id` | ✅ | | 14 | `jl_flow_timeout_rule` | 超时规则 | `rule_id` | ✅ | DDL 脚本:[jlflow-engine-core/src/main/resources/sql/jlflow-mysql.sql](./jlflow-engine-core/src/main/resources/sql/jlflow-mysql.sql) --- ## SPI 扩展点 引擎通过 `site.jlopen.jlflow.spi.SpiRegistry` 管理三类 SPI,宿主可在启动前注入自定义实现。 ### 1. IdentityProvider(身份/组织) ```java public interface IdentityProvider { List userList(); List sectorsList(); List userInSectors(String deployCode, String instanceKey, String taskCode, String sectorId); JLFlowUser sectorLeader(String sectorId, String leaderType); List blackList(); JLFlowUser directLeader(String userId); } ``` 用于办理人解析、加签选人、委托代理、回退目标选择等场景。宿主需实现该接口以接入本地用户/组织数据。 ### 2. ExpressionEvaluator(表达式求值) ```java public interface ExpressionEvaluator { Object evaluate(String expression, Map params); boolean validate(String expression); } ``` 用于连线条件、跳转策略、办理人脚本等场景。默认实现 `DefaultExpressionEvaluator` 支持简单 `${var}` 占位与等值/比较运算,可替换为 SpEL / Aviator / QLExpress 等。 ### 3. JsonSerializer(JSON 序列化) ```java public interface JsonSerializer { String toJson(Object obj); T fromJson(String json, Class type); T fromJson(String json, Type type); } ``` 用于持久化流程变量、任务参数、流程图快照等。默认实现基于 Gson,可替换为 Jackson / Fastjson 等。 --- ## Listener 钩子 引擎在关键节点提供 4 类监听器,所有方法均默认空实现,宿主按需覆写。 ### 1. InstanceListener(实例生命周期) `beforeStart` → `afterStart` → `afterFinish` / `afterStop` / `afterSuspend` / `afterWithdraw` ### 2. TaskListener(任务生命周期) `afterCreate` → `injectVariables` → `beforeComplete` → `afterComplete` / `beforeReject` → `afterReject` / `onError` / `afterWithdraw` / `afterCounterSign` / `afterDelegate` ### 3. RouteListener(路由计算) `beforeRoute` → `afterRoute(nextNodeIds)` / `onNoMatch(ctx)` 兜底 ### 4. ErrorListener(异常告警) `onError(ctx)`:引擎运行过程中产生未捕获异常时触发,可在此实现告警、日志、补偿等逻辑。 注册方式: ```java SpiRegistry spi = new SpiRegistry(); spi.addListener(myInstanceListener, "leave_process"); // 仅对 leave_process 部署生效 spi.addListener(myTaskListener); // 全局生效 Engine engine = Engine.build(dataSource, spi, config); ``` --- ## 高级场景 ### 撤回(Withdraw) 发起人或上一步办理人可在后续任务未办理前撤回,引擎自动回退到撤回发起节点。 ```java apis.withdraw().withdraw(new WithdrawDTO(instanceId, taskId, userId, "撤回原因")); ``` ### 委托(Delegate) A 长期委托 B 代办某流程或全部流程的任务,引擎在分配任务时自动转给 B,并标记 `assign_type=1`。 ```java apis.delegate().create(new DelegateDTO("userA", "userB", "leave_process", startTime, endTime)); ``` ### 加签 / 减签(Counter Sign) 支持 4 种加签类型:前加签、后加签、并加签、减签。 ```java apis.counterSign().add(new CounterSignDTO(taskId, signType, signUserIds, operatorUserId)); ``` ### 超时自动审批 为节点配置超时规则,到期后引擎自动执行「自动通过 / 自动驳回 / 催办提醒」。 ```java apis.timeoutRule().create(new TimeoutRuleDTO(deployId, nodeId, 60, 1, 5, true)); // 含义:60 分钟超时,动作=自动通过,提前 5 分钟催办 ``` --- ## 内置 UI `jlflow-engine-ui` 提供基于 HTML + Vue3 + LogicFlow 的可视化界面,启动后访问 `http://host:port/jlflow` 即可使用,包含以下页面: | 页面 | 路径 | 说明 | | --- | --- | --- | | 首页 | `/jlflow/index.html` | 控制台入口 | | 部署管理 | `/jlflow/pages/deploy.html` | 创建/发布/停用流程部署 | | 流程图编辑器 | `/jlflow/pages/graph-editor.html` | 基于 LogicFlow 的可视化设计器 | | 实例管理 | `/jlflow/pages/instance.html` | 查看/挂起/终止实例 | | 任务管理 | `/jlflow/pages/task.html` | 待办/已办/办理/驳回 | | 运行日志 | `/jlflow/pages/log.html` | 实例/任务日志查询 | | 委托管理 | `/jlflow/pages/delegate.html` | 委托关系配置 | | 超时规则 | `/jlflow/pages/timeout-rule.html` | 节点超时规则配置 | UI 默认无需认证,生产环境建议开启 Basic 认证或前置网关鉴权。 --- ## 版本与路线图 | 版本 | 状态 | 关键特性 | | --- | --- | --- | | 1.0.0 | ✅ 已发布 | 部署/实例/任务/撤回/驳回/委托/加签/超时/UI/SPI | | 1.1.0 | 🚧 规划中 | 子流程、并行网关、条件分支增强 | | 1.2.0 | 📋 规划中 | PostgreSQL 支持、分布式调度、流程实例归档 | --- ## 开源协议 [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) --- ## 仓库地址 - Gitee:https://gitee.com/carro/jlflow