跳转至

10-流程引擎 bams-flow

📄 创建: ZCode AI 2026-08-14 · 修改: JimWb 2026-08-14

https://doc.xpku.com/raw/tech/backend/bams-sdk/10-bams-flow.md

bams-flow(31 个类)是 BAMS 体系统一的流程能力集成模块(2026-08-03 随 Apex 2.0 迁入 SDK),整合两套独立的开源引擎:LiteFlow(规则编排/轻量流程)和 Warm-Flow(审批工作流)。


一、模块定位

两套引擎完全独立、互不调用,只是打包在同一模块、共享开关:

维度 LiteFlow Warm-Flow
定位 业务规则编排 / 轻量 Chain 执行 审批工作流(人工审批流)
引擎 liteflow-spring-boot-starter + liteflow-rule-db-redis warm-flow-mybatis-plus-sb3-starter
规则存储 sys_liteflow 表 + Redis Rule-DB Warm-Flow 自身的表
SDK 叠加能力 深:多工厂/多模板/不可变版本/版本化执行器/人工确认节点/Redis 实例仓库 浅:纯薄封装,一对一委托
开关 bams.flow.lite-flow-enabled bams.flow.warm-flow-enabled
典型用途 巡检/派工/验收的规则判断(含人工确认分支) 人工审批流程定义、发起、通过/驳回

易混淆点:LiteFlow 的"人工确认节点"(BamsHumanConfirmationNode)是规则编排内的布尔分支判断,不是 Warm-Flow 的审批节点。两者各管各的"人工"语义。


二、配置与启动

自动装配

FlowAutoConfiguration 通过 SPI 文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 注册。引入依赖即生效,不强制加注解。

@EnableBamsFlow(可选)

cn.cnbm.bams.flow.config.EnableBamsFlow —— 纯标记注解,@ImportAutoConfiguration(FlowAutoConfiguration.class)。若宿主已扫描到 FlowAutoConfiguration(默认情况),可不加。

配置项

bams:
  flow:
    enabled: true                  # 模块总开关(默认 true)
    warm-flow-enabled: true        # Warm-Flow 开关(默认 true)
    lite-flow-enabled: true        # LiteFlow 开关(默认 true)
    key: 'bams:liteflow:instance:' # 版本化业务实例 Redis Key 前缀

# LiteFlow Rule-DB(可选,默认不启用)
liteflow:
  rule-db:
    enabled: true                  # 必须显式开
    application-name: my-app       # 不配则取 spring.application.name,兜底 "admin"
    redis:
      address: 127.0.0.1:6379
      key-prefix: bams-liteflow

三、Warm-Flow 审批流(薄封装)

cn.cnbm.bams.flow.warm.service.BamsWarmFlowService / BamsWarmFlowServiceImpl

对 Warm-Flow 三大原生服务(DefService/InsService/TaskService)的薄封装,便于后续统一加日志/审计/权限校验。

流程定义管理

方法签名 功能
importJson(String defJson) 导入 JSON 流程定义
importDefinition(InputStream) 导入 XML 流程定义
publish(Long definitionId) 发布流程定义
unPublish(Long definitionId) 取消发布

流程实例与流转

方法签名 功能
Instance start(String businessId, FlowParams) 按业务主键发起实例
Task pass(Long taskId, String message, Map variable) 审批通过
Task reject(Long taskId, String message, Map variable) 驳回
Task skip(Long taskId, FlowParams) 通用流转(通过/驳回由 skipType 决定)
skipByInsId(Long instanceId, FlowParams) 按实例流转

原生服务访问

方法 说明
getDefService() 复杂场景直连 DefService
getInsService() 直连 InsService
getTaskService() 直连 TaskService

使用示例

@Autowired
private BamsWarmFlowService warmFlowService;

// 1. 定义流程
warmFlowService.importJson(defJson);
warmFlowService.publish(definitionId);

// 2. 发起 + 审批
Instance ins = warmFlowService.start(businessId, flowParams);
warmFlowService.pass(taskId, "同意", Map.of());
warmFlowService.reject(taskId, "驳回", null);

四、LiteFlow 规则编排(深度封装)

4.1 流程定义实体

cn.cnbm.bams.flow.lite.entity.SysLiteFlow(表 sys_liteflow

字段 说明
appCode 应用编码
corpCode 工厂编码
templateCode 业务模板编码(如 inspection)
version 不可变版本(如 v1)
xmlContent LiteFlow EL XML 原文
status DRAFT / PUBLISHED / ACTIVE / DISABLED
publisher 发布人

4.2 模板版本服务

BamsLiteFlowTemplateService

方法 功能
currentVersion(corpCode, templateCode) 取当前 ACTIVE 版本(XML 模式返回 "legacy")
versionedChain(baseChainId, corp, template, version) 生成不可变版本化 chain ID

chain ID 规则(分隔符 __ 双下划线):

场景 chain ID
XML 模式(无 Rule-DB) baseChainId
有版本无 template baseChainId__version
有版本有 template 无 corp baseChainId__template__version
完整 baseChainId__corp__template__version

4.3 ACTIVE 模板激活

BamsLiteFlowActiveTemplateService

  • findActive / requiredActive(app, corp, template):按四字段查 ACTIVE 模板
  • activateById(id) / activateVersion(...):事务内先把同作用域其他 ACTIVE 降级为 PUBLISHED,再设目标为 ACTIVE
  • 保证同一业务作用域只有一个 ACTIVE 版本

4.4 规则发布

BamsLiteFlowRulePublisherService

  • publishXml(...):解析 XML(强制禁用 DOCTYPE 和外部实体),遍历 <chain> 元素,经 versionedChain 生成 chain ID 后发布到 Redis Rule-DB
  • expectedVersion=0:Redis 中该 chain 版本必须不存在(不可变,不允许就地更新,必须换新 vN)

4.5 SysLiteFlowService(CRUD 入口)

extends ServiceExtImpl<SysLiteFlowMapper, SysLiteFlow>

方法 功能
publish(id) 从 DB 读模板 → 校验 XML → 发布到 Redis → 状态置 PUBLISHED
activate(id) @Transactional,激活模板
initialize(id) 仅允许 v1,先 publish 再 activate

4.6 版本化执行器(核心机制)

cn.cnbm.bams.flow.lite.runtime.BamsVersionedLiteFlowExecutor / Impl

多工厂、多模板、固定版本执行器。execute(request, context) 分三步:

1. 解析版本 resolveVersion
   ├─ 首次执行(instanceId 为空)→ 取当前 ACTIVE 版本
   └─ 后续执行(instanceId 非空)→ 从 Redis 恢复固定版本
      └─ validateOwnership 校验实例归属(全部字段匹配)

2. 执行规则
   ├─ versionedChain 算 chainId
   ├─ chainService.find(chainId)
   ├─ liteFlowService.execute(chainId, context)
   └─ 校验 response.isSuccess() + requestId 非空

3. 建实例
   └─ 首次用 executionRequestId 作 businessInstanceId
      结果携带 BamsLiteFlowInstance 元数据

关键保证:规则模板修改不影响已启动的实例,实例一旦绑定版本就锁定。

4.7 Request / Result

BamsVersionedFlowRequest(record):

字段 说明
id 业务对象主键
instanceId 已绑定的(首次传 null)
corpCode 公司编码
templateCode 业务模板编码
baseChainId 基础 chain ID
actionName 用于异常/日志提示
optionalChain chain 不存在时是否跳过(false 则抛异常)

BamsVersionedFlowResult(record):

字段 说明
executed 是否执行了
chainId 执行的 chain ID
version 版本
executionRequestId 请求 ID
instance 实例元数据(跳过时为 null)

4.8 实例仓库(Redis)

RedisBamsLiteFlowInstanceRepository

  • Key = flowProperties.requiredInstancePrefix() + templateCode + ":" + instanceId
  • find(templateCode, instanceId):读 JSON 反序列化
  • save(instance):序列化写入(后续动作不得重新选版本)

业务提交成功后才调 save,首次建立、后续沿用 instanceId。

4.9 人工确认节点

cn.cnbm.bams.flow.lite.node.BamsHumanConfirmationNode

固定组件 ID flowHumanConfirmation(Bean 名注册)。读上下文的 getHumanConfirmed() 决定 Chain 走向。

BamsHumanConfirmationContext(接口):

public interface BamsHumanConfirmationContext {
    Boolean getHumanConfirmed();  // true=通过, false=驳回, null=未处理
}

业务上下文实现此接口即可使用人工确认节点:

public class MyFlowContext implements BamsHumanConfirmationContext {
    private Boolean humanConfirmed;
    @Override
    public Boolean getHumanConfirmed() { return humanConfirmed; }
}

XML 中使用:

<chain name="inspection_flow">
    IF(flowHumanConfirmation, then(approveNode), then(rejectNode))
</chain>

4.10 类型化节点基类

BamsTypedNodeComponent<C> —— 类型化普通节点基类,context() 方法从 getRequestData() 取上下文并做类型校验。


五、典型用法

Warm-Flow 审批流

@Autowired
private BamsWarmFlowService warmFlowService;

// 定义
warmFlowService.importJson(defJson);
warmFlowService.publish(definitionId);

// 发起
Instance ins = warmFlowService.start(businessId, flowParams);

// 审批
warmFlowService.pass(taskId, "同意", Map.of());
warmFlowService.reject(taskId, "材料不全,请补充", null);

LiteFlow 规则编排(Rule-DB 版本化)

// 1. 在 sys_liteflow 表维护 DRAFT 模板记录
//    (appCode, corpCode, templateCode, version, xmlContent)

// 2. 发布
sysLiteFlowService.initialize(id);   // 仅 v1,发布后立即激活
// 或
sysLiteFlowService.publish(id);      // 发布为 PUBLISHED
sysLiteFlowService.activate(id);     // 激活为 ACTIVE

// 3. 业务节点(宿主自行声明)
@Component("approveNode")
public class ApproveNode extends BamsTypedNodeComponent<MyContext> {
    public ApproveNode() { super(MyContext.class); }
    @Override
    public void process() {
        MyContext ctx = context();
        // 审批逻辑
    }
}

// 4. 执行
@Autowired
private BamsVersionedLiteFlowExecutor executor;

BamsVersionedFlowRequest request = new BamsVersionedFlowRequest(
    businessId,           // id
    null,                 // instanceId(首次 null)
    corpCode,             // corpCode
    "inspection",         // templateCode
    "inspection_flow",    // baseChainId
    "巡检流程",            // actionName
    false                 // optionalChain
);

MyContext context = new MyContext();
BamsVersionedFlowResult result = executor.execute(request, context);

// 5. 业务提交成功后存实例
if (result.executed() && result.instance() != null) {
    instanceRepository.save(result.instance());
}

LiteFlow 规则编排(无 Rule-DB / 本地 XML)

不走 Rule-DB 时,直接注入 BamsLiteFlowService

@Autowired
private BamsLiteFlowService liteFlowService;

// chainId 不带版本后缀(currentVersion 返回 "legacy")
Object result = liteFlowService.execute("myChain", paramMap);

六、配置类清单

说明
EnableBamsFlow 启动注解(可选)
FlowAutoConfiguration 自动配置,三层条件装配(WarmFlow/LiteFlow/RuleDb)
BamsFlowProperties bams.flow.* 配置(enabled/warmFlowEnabled/liteFlowEnabled/key)
LiteFlowRuleDbProperties liteflow.rule-db.* 配置(applicationName + Redis 连接)

相关文档