# 工作流框架调研文档
> 支付系统人工审批流技术选型参考
—
## 目录
1. [Spring State Machine 简介](#1-spring-state-machine-简介)
2. [LiteFlow 简介](#2-liteflow-简介)
3. [自定义审批流方案(推荐)](#3-自定义审批流方案推荐)
4. [方案对比与选型建议](#4-方案对比与选型建议)
—
## 1. Spring State Machine 简介
Spring State Machine 是 Spring 官方出的状态机框架,基于 Spring Framework,用于构建状态机应用。
### 核心概念
**State (状态) + Event (事件) + Transition (转换)**
– **State**: 状态,如 PENDING、APPROVED
– **Event**: 事件,如 SUBMIT、APPROVE
– **Transition**: 状态转换,A –Event–> B
– **Guard**: 条件判断,决定是否能转换
– **Action**: 转换时执行的动作
– **StateMachine**: 状态机实例
### 三种持久化方式
| 方式 | 说明 |
|——|——|
| Ephemeral | 内存,重启丢失(测试用) |
| StateMachinePersist | 自定义持久化(Redis、DB) |
| JpaPersistingStateMachineListener | JPA 持久化(官方推荐) |
### 快速示例
**依赖:**
“`xml
“`
**1. 定义状态和事件:**
“`java
public enum PaymentState {
PENDING, RISK_CHECK, MANUAL_REVIEW, APPROVED, REJECTED
}
public enum PaymentEvent {
SUBMIT, RISK_PASS, RISK_REJECT, NEED_MANUAL, APPROVE, REJECT
}
“`
**2. 配置状态机:**
“`java
@Configuration
@EnableStateMachine
public class PaymentStateConfig extends StateMachineConfigurerAdapter
@Override
public void configure(StateMachineStateConfigurer
states
.withStates()
.initial(PaymentState.PENDING)
.state(PaymentState.RISK_CHECK)
.state(PaymentState.MANUAL_REVIEW)
.end(PaymentState.APPROVED)
.end(PaymentState.REJECTED);
}
@Override
public void configure(StateMachineTransitionConfigurer
transitions
.withExternal().source(PaymentState.PENDING).target(PaymentState.RISK_CHECK)
.event(PaymentEvent.SUBMIT)
.action(ctx -> log.info(“提交风控”))
.and()
.withExternal().source(PaymentState.RISK_CHECK).target(PaymentState.APPROVED)
.event(PaymentEvent.RISK_PASS)
.and()
.withExternal().source(PaymentState.RISK_CHECK).target(PaymentState.MANUAL_REVIEW)
.event(PaymentEvent.NEED_MANUAL)
.and()
.withExternal().source(PaymentState.RISK_CHECK).target(PaymentState.REJECTED)
.event(PaymentEvent.RISK_REJECT)
.and()
.withExternal().source(PaymentState.MANUAL_REVIEW).target(PaymentState.APPROVED)
.event(PaymentEvent.APPROVE)
.and()
.withExternal().source(PaymentState.MANUAL_REVIEW).target(PaymentState.REJECTED)
.event(PaymentEvent.REJECT);
}
}
“`
**3. 使用状态机:**
“`java
@Service
@RequiredArgsConstructor
public class PaymentService {
private final StateMachine
public void submitPayment(Long paymentId) {
stateMachine.start();
Message
.withPayload(PaymentEvent.SUBMIT)
.setHeader(“paymentId”, paymentId)
.build();
stateMachine.sendEvent(message);
log.info(“当前状态: {}”, stateMachine.getState().getId());
}
public void riskCheckComplete(Long paymentId, boolean pass) {
PaymentEvent event = pass ? PaymentEvent.RISK_PASS : PaymentEvent.RISK_REJECT;
stateMachine.sendEvent(event);
}
}
“`
### 注意事项
| 问题 | 说明 |
|——|——|
| 性能 | 单机单实例,高并发建议用 Redis 分布式锁 |
| 持久化 | 默认内存,需自行实现 StateMachinePersist 持久化 |
| 重试 | 内置 RetryInterceptor,需额外配置 |
| 调试 | 提供 @WithStateMachine 测试支持 |
### vs 自定义状态机
| 维度 | 自定义 | Spring State Machine |
|——|——–|———————|
| 代码量 | 少 | 中 |
| 可视化状态图 | ❌ | ✅(Spring State Machine Visualizer) |
| 持久化 | 自行实现 | 内置支持(需配置) |
| Guard/Action | 自行实现 | 内置 |
| 学习成本 | 低 | 中 |
—
## 2. LiteFlow 简介
LiteFlow 是国产的规则引擎框架(由 Yomahub 出品),主打轻量 + 高性能,适用于复杂业务规则路由,而非传统审批流。
### 定位
| 维度 | 说明 |
|——|——|
| 定位 | 规则引擎 / 流程编排 |
| 适用场景 | 规则路由、决策树、业务规则编排 |
| 不擅长 | 需要人工审批、多实例协作的长流程 |
| 许可证 | Apache 2.0(免费) |
### 核心概念
**Chain (链) = Node (节点) + Node (节点) + Node (节点)**
– **SWITCH(x)**: 条件分支,类似 if/else
– **WHEN(并行)**: 多节点并行执行
– **THEN(串行)**: 依次执行
– **BREAK**: 终止流程
### 快速示例
**依赖:**
“`xml
“`
**1. 定义流程规则(flow.xml):**
“`xml
THEN(
“riskCheckNode”,
SWITCH($payment.getType())
.CASE(“NORMAL”, “normalPayNode”)
.CASE(“HIGH_RISK”, “highRiskPayNode”)
.CASE(“VIP”, “vipPayNode”),
“notifyNode”
);
“`
**2. 定义节点(Java):**
“`java
@Component
public class RiskCheckNode extends NodeComponent {
@Override
public void process() {
Payment payment = this.getContextData(Payment.class);
if (blacklistService.isBlacklisted(payment.getUserId())) {
this.setNextNodeId(“rejectNode”);
return;
}
int riskScore = riskService.calculateScore(payment);
payment.setRiskScore(riskScore);
if (riskScore > 80) {
this.setNextNodeId(“highRiskPayNode”);
}
}
}
“`
**3. 执行流程:**
“`java
@Service
@RequiredArgsConstructor
public class PaymentService {
private final FlowExecutor flowExecutor;
public PaymentResult routePayment(Payment payment) {
DefaultContext context = new DefaultContext();
context.set(“payment”, payment);
LiteFlowResponse response = flowExecutor.execute2Resp(
“paymentRoute”, context
);
if (response.isSuccess()) {
return (PaymentResult) response.getContextData(“result”);
} else {
throw new PaymentException(“路由失败”);
}
}
}
“`
### vs Spring State Machine
| 维度 | LiteFlow | Spring State Machine |
|——|———-|———————|
| 设计目标 | 规则路由编排 | 状态机 |
| 配置方式 | XML/YML(可视化友好) | Java 代码 |
| 适用场景 | 规则引擎、路由决策 | 状态流转、审批流 |
| 人工干预 | ❌ 不支持 | ✅ 支持任务领取 |
| 并行执行 | ✅ WHEN 原生支持 | ⚠️ 需额外配置 |
| 性能 | 高(无状态设计) | 中 |
| 状态持久化 | ❌ 无内置 | ✅ 可配置 |
### 典型使用场景
– **支付路由**: 根据金额、用户类型、风控分数选择不同支付通道
– **风控决策**: 多规则并行检查,最终决策
– **营销规则**: 优惠券、折扣、满减等规则编排
– **订单处理**: 根据订单类型、地区、商品类型走不同处理流程
### 总结
**LiteFlow = 规则引擎 ≠ 审批流引擎**
如果你的需求是根据条件选择不同的处理逻辑(路由、决策、规则编排),LiteFlow 非常合适。
如果你的需求是需要人工审批、多步骤流转、任务管理,Spring State Machine 或自定义状态机更合适。
—
## 3. 自定义审批流方案(推荐)
针对人工审批 + 多步骤流转场景的自定义轻量级解决方案。
### 设计思路
“`
┌──────────────────────────────────────────────────────┐
│ 审批流核心模型 │
│ │
│ WorkflowDef (流程定义) │
│ │ │
│ ├──► WorkflowStep (步骤定义) │
│ │ │ │
│ │ └──► 1. 步骤顺序 │
│ │ └──► 2. 审批者类型(角色/用户) │
│ │ └──► 3. 通过条件 │
│ │ │
│ WorkflowInstance (流程实例) ← 业务表关联 │
│ │ │
│ ├──► Task (待办任务) ← 人工审批入口 │
│ │ │
│ └──► TaskHistory (审批历史) ← 审计记录 │
└──────────────────────────────────────────────────────┘
“`
### 核心表结构
“`sql
— 流程定义表
CREATE TABLE workflow_def (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
workflow_code VARCHAR(64) NOT NULL UNIQUE, — ‘merchant_audit’
name VARCHAR(128), — ‘商户审核流程’
version INT DEFAULT 1,
status TINYINT DEFAULT 1, — 1启用 0禁用
created_at DATETIME,
updated_at DATETIME
);
— 步骤定义表
CREATE TABLE workflow_step (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
workflow_def_id BIGINT NOT NULL,
step_code VARCHAR(64), — ‘risk_check’
step_name VARCHAR(128), — ‘风控审核’
step_order INT NOT NULL, — 顺序
approver_type VARCHAR(32), — ‘ROLE’ / ‘USER’ / ‘EXPR’
approver_value VARCHAR(256), — ‘risk_team’ / ‘user_123’ / ‘${initiator}’
pass_condition VARCHAR(64), — ‘ALL_PASS’ / ‘ONE_PASS’
created_at DATETIME
);
— 流程实例表(绑定业务)
CREATE TABLE workflow_instance (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
workflow_def_id BIGINT NOT NULL,
biz_type VARCHAR(64), — ‘merchant’
biz_id BIGINT NOT NULL, — merchant_audit.id
initiator VARCHAR(64), — 发起人
current_step INT DEFAULT 1, — 当前步骤
status VARCHAR(32), — RUNNING / APPROVED / REJECTED
created_at DATETIME,
updated_at DATETIME
);
— 待办任务表
CREATE TABLE workflow_task (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
instance_id BIGINT NOT NULL,
step_code VARCHAR(64),
assignee VARCHAR(64), — 审批人
status VARCHAR(32), — PENDING / COMPLETED / REJECTED
result VARCHAR(32), — PASS / REJECT
comment TEXT, — 审批意见
created_at DATETIME,
completed_at DATETIME
);
— 审批历史表
CREATE TABLE workflow_history (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
instance_id BIGINT NOT NULL,
step_code VARCHAR(64),
operator VARCHAR(64),
action VARCHAR(32), — SUBMIT / APPROVE / REJECT
comment TEXT,
created_at DATETIME
);
“`
### 核心代码
**流程状态枚举:**
“`java
public enum WorkflowStatus {
PENDING, // 待审批
RUNNING, // 审批中
PASSED, // 审批通过
REJECTED, // 审批拒绝
CANCELLED // 已取消
}
“`
**流程服务:**
“`java
@Service
@Slf4j
public class WorkflowService {
@Autowired private WorkflowDefMapper workflowDefMapper;
@Autowired private WorkflowStepMapper stepMapper;
@Autowired private WorkflowInstanceMapper instanceMapper;
@Autowired private WorkflowTaskMapper taskMapper;
@Autowired private WorkflowHistoryMapper historyMapper;
/** 启动流程 */
public Long startWorkflow(String workflowCode, String bizType, Long bizId, String initiator) {
// 1. 获取流程定义
WorkflowDef def = workflowDefMapper.findByCode(workflowCode);
List
// 2. 创建流程实例
WorkflowInstance instance = new WorkflowInstance();
instance.setWorkflowDefId(def.getId());
instance.setBizType(bizType);
instance.setBizId(bizId);
instance.setInitiator(initiator);
instance.setCurrentStep(1);
instance.setStatus(WorkflowStatus.RUNNING.name());
instanceMapper.insert(instance);
// 3. 创建第一个任务
createTask(instance, steps.get(0), initiator);
// 4. 记录历史
saveHistory(instance, null, “SUBMIT”, initiator);
log.info(“启动流程实例: {}, 业务: {}:{}”, workflowCode, bizType, bizId);
return instance.getId();
}
/** 审批任务 */
public void approve(Long taskId, String operator, String result, String comment) {
WorkflowTask task = taskMapper.findById(taskId);
WorkflowInstance instance = instanceMapper.findById(task.getInstanceId());
List
// 1. 完成当前任务
task.setStatus(“COMPLETED”);
task.setResult(result);
task.setComment(comment);
task.setCompletedAt(LocalDateTime.now());
taskMapper.update(task);
// 2. 记录历史
saveHistory(instance, task.getStepCode(), result, operator);
// 3. 判断是否通过
WorkflowStep currentStep = steps.get(instance.getCurrentStep() – 1);
boolean stepPass = “PASS”.equals(result);
if (!stepPass) {
// 步骤未通过,流程结束
instance.setStatus(WorkflowStatus.REJECTED.name());
instanceMapper.update(instance);
log.info(“流程拒绝: {}”, instance.getId());
return;
}
// 4. 检查是否还有下一步
int nextStepIndex = instance.getCurrentStep();
if (nextStepIndex >= steps.size()) {
// 流程完成
instance.setStatus(WorkflowStatus.PASSED.name());
instanceMapper.update(instance);
log.info(“流程通过: {}”, instance.getId());
return;
}
// 5. 进入下一步
instance.setCurrentStep(nextStepIndex + 1);
instanceMapper.update(instance);
// 6. 创建下一步任务
WorkflowStep nextStep = steps.get(nextStepIndex);
String nextAssignee = resolveAssignee(nextStep, instance);
createTask(instance, nextStep, nextAssignee);
log.info(“流程流转至步骤: {}, 任务分配给: {}”, nextStep.getStepCode(), nextAssignee);
}
/** 查询待办任务 */
public List
return taskMapper.findPendingByAssignee(assignee);
}
private void createTask(WorkflowInstance instance, WorkflowStep step, String assignee) {
WorkflowTask task = new WorkflowTask();
task.setInstanceId(instance.getId());
task.setStepCode(step.getStepCode());
task.setAssignee(assignee);
task.setStatus(“PENDING”);
task.setCreatedAt(LocalDateTime.now());
taskMapper.insert(task);
}
private String resolveAssignee(WorkflowStep step, WorkflowInstance instance) {
if (“INITIATOR”.equals(step.getApproverValue())) {
return instance.getInitiator();
}
if (“EXPR”.equals(step.getApproverType())) {
// 动态表达式,如 ${initiator} 或 ${amount > 10000 ? ‘admin’ : ‘user’}
return evaluateExpression(step.getApproverValue(), instance);
}
return step.getApproverValue();
}
private void saveHistory(WorkflowInstance instance, String stepCode, String action, String operator) {
WorkflowHistory history = new WorkflowHistory();
history.setInstanceId(instance.getId());
history.setStepCode(stepCode);
history.setAction(action);
history.setOperator(operator);
history.setCreatedAt(LocalDateTime.now());
historyMapper.insert(history);
}
}
“`
**使用示例:**
“`java
@Service
@RequiredArgsConstructor
public class MerchantAuditService {
private final WorkflowService workflowService;
/** 商户提交审核 */
public void submitAudit(MerchantAudit audit) {
auditService.save(audit);
workflowService.startWorkflow(“merchant_audit”, “merchant_audit”, audit.getId(), audit.getApplicant());
}
/** 审批通过 */
public void approve(Long taskId, String operator) {
workflowService.approve(taskId, operator, “PASS”, “同意”);
}
/** 审批拒绝 */
public void reject(Long taskId, String operator, String reason) {
workflowService.approve(taskId, operator, “REJECT”, reason);
}
/** 查询待审批列表 */
public List
return workflowService.getPendingTasks(operator);
}
}
“`
### 优点
| 优点 | 说明 |
|——|——|
| **零依赖** | 仅 MySQL,无额外框架 |
| **完全可控** | 代码即文档,可自行扩展 |
| **轻量** | 核心代码 < 300 行 |
| **灵活** | 可加会签、知会、加签、委托等 |
| **可观测** | 完整的审批历史记录 |
### 可扩展功能
| 功能 | 难度 | 说明 |
|------|------|------|
| 会签(多人审批) | ⭐⭐ | 同一任务分配多人,需全部通过 |
| 知会(非审批人) | ⭐ | 只通知,不阻塞流程 |
| 加签 | ⭐⭐ | 审批中追加审批人 |
| 委托 | ⭐ | 将任务转给他人 |
| 催办 | ⭐ | 定时提醒未审批任务 |
| 驳回 | ⭐⭐ | 驳回到指定步骤 |
---
## 4. 方案对比与选型建议
### 方案对比
| 方案 | 人工审批 | 多步骤 | 复杂度 | 推荐场景 | 推荐度 |
|------|:--------:|:------:|--------|----------|:------:|
| **自定义状态机 + 任务表** | ✅ | ✅ | 低 | 简单流程(≤5状态) | ⭐⭐⭐⭐⭐ |
| **Spring State Machine** | ✅ | ✅ | 中 | 中等流程,有持久化需求 | ⭐⭐⭐ |
| **LiteFlow** | ❌ | ⚠️ | 中 | 规则路由、决策树 | ⭐⭐ |
| **Camunda 7** | ✅ | ✅ | 高 | 复杂企业流程 | ⭐⭐ |
| **Activiti** | ✅ | ✅ | 高 | 复杂企业流程 | ⭐ |
### 针对支付系统的建议
针对支付系统(风控审核、入账确认)场景,推荐使用自定义审批流方案:
| 场景 | 推荐方案 |
|------|----------|
| 商户审核(简单多级审批) | 自定义状态机 + 审批任务表 |
| 订单状态流转 | 枚举 + 状态机 |
| 需要持久化/重启恢复 | Spring State Machine + JPA |
| 费率/限额规则路由 | LiteFlow |
### 下一步
如需进一步集成到项目中,可提供以下支持:
- [ ] 完整的数据库表结构(SQL 脚本)
- [ ] Mapper、Service、Controller 代码生成
- [ ] 工作流定义配置(风控审核、人工复核等)
- [ ] REST API 接口设计
---
*文档生成时间: 2026-04-30*




