审批工作流
受众:开发者 摘要:审批 / 复核 / 工单状态机 starter,用于统一状态动作、权限校验、附件、审计和超时处理计划。
spring-open-starter-approval-workflow 提供一个轻量同步状态机。它不保存业务表,也不执行 Admin 审批动作;业务模块定义流程和动作,调用 starter 执行动作校验,再把返回的状态、审计记录和超时计划保存到自己的实体或任务中。spring-open-core-approval-workflow 负责后台只读运维台,读取 ApprovalWorkflowCatalog 的流程目录快照和 ApprovalInbox 的跨模块待办摘要,不直接暴露业务审批实例表。
适用场景
| 场景 | 推荐 |
|---|---|
| 内容安全复核、CMS 内容审核、商城售后审批 | 使用审批工作流 |
| 提现、结算、广告投放、商户入驻等人工复核 | 使用审批工作流 |
| 只是一串同步规则,当前规则决定是否继续 | 使用 责任链 |
| 固定步骤编排,没有人工状态流转 | 使用 管道 |
| 方法外层审计、指标、鉴权增强 | 使用 钩子 |
快速接入
1. 引入 Starter
<dependency>
<groupId>com.springopen</groupId>
<artifactId>spring-open-starter-approval-workflow</artifactId>
</dependency>如果业务需要审批工作流能力,请显式引入 spring-open-starter-approval-workflow;框架不再提供 all-in-one starter 兜底。
2. 定义流程
@Bean
ApprovalWorkflowDefinition contentReviewWorkflow() {
return ApprovalWorkflowDefinition.builder()
.workflow("content.review")
.name("内容审核")
.description("内容提交、通过、驳回和超时自动处理")
.action(ApprovalActionDefinition.builder()
.code("submit")
.fromStatus("draft")
.toStatus("pending")
.requiredPermission("cms:content:update")
.timeout(Duration.ofHours(24))
.timeoutAction("auto-approve")
.build())
.action(ApprovalActionDefinition.builder()
.code("approve")
.fromStatus("pending")
.toStatus("approved")
.requiredPermission("cms:content:review")
.build())
.action(ApprovalActionDefinition.builder()
.code("reject")
.fromStatus("pending")
.toStatus("rejected")
.requiredPermission("cms:content:review")
.remarkRequired(true)
.build())
.build();
}workflow 和 action.code 必须稳定。它们会进入审计、配置、任务和后续 Admin 展示。
3. 执行动作
ApprovalActionResult result = ApprovalWorkflow.execute(ApprovalActionRequest.builder()
.workflow("content.review")
.subject(ApprovalSubject.builder()
.type("cms-content")
.id(contentId.toString())
.title(title)
.ownerId(authorId.toString())
.build())
.currentStatus(currentReviewStatus)
.action("approve")
.operatorId(currentUserId.toString())
.operatorPermission("cms:content:review")
.remark("内容合规")
.traceId(traceId)
.build());
content.setReviewStatus(result.getAfterStatus());
contentLogRepository.save(result.getAuditRecord());
if (result.getTimeoutPlan() != null) {
reviewTimeoutTaskRepository.save(result.getTimeoutPlan());
}业务模块仍负责事务、实体保存、日志落库、通知和调度任务。starter 返回的是可落库快照,不替业务模块持久化。
已接入试点
| 业务 | 流程编码 | 说明 |
|---|---|---|
| CMS 内容审核 | cms.content.review | CMS 定义提交、通过、驳回、自动通过和自动驳回动作,starter 校验状态、权限、驳回备注和超时计划,CMS 保存内容状态与操作日志。 |
| Content Safety 复核 | content-safety.review | Content Safety 复核任务校验人工通过 / 拒绝 / 关闭和超时自动处理动作,驳回必须填写备注;Content Safety 只保存检测日志审计字段,不直接修改业务对象状态。 |
| Money 用户余额提现 | money.balance.withdraw | 提现审核通过、人工拒绝、进入处理、标记已打款、失败和取消动作先经审批工作流校验;拒绝必须填写备注,外部 payout / Web3 广播前会先校验 approved -> processing,原有冻结释放、出账流水和 txHash 校验仍由 Money Service 负责。 |
| Money Web3 支付结算复核 | money.web3.payment-settlement.review | Web3 支付结算复核日志记录、超时自动通过 / 驳回、自动重试和手动执行结算先经审批工作流校验;工作流只校验动作、来源状态和权限快照,复核指纹、链上确认、订单条件更新、支付流水幂等、Outbox 和补偿仍由 Web3 Service 负责。 |
| Mall 售后审批 | mall.after-sale.review | 售后通过、驳回、关闭、退货签收、标记退款成功和超时自动处理先经审批工作流校验;人工驳回必须填写说明,真实退款、余额流水和优惠券返还仍由 Mall 售后 Service 负责。 |
| Mall 商户入驻 | mall.merchant.review | 商户提交、审核通过和驳回先经审批工作流校验;驳回必须填写说明,商户启停、店铺归属和角色模板仍由 Mall Service 负责。 |
| Advertising 素材审核 | advertising.creative.review | 广告素材提审、审核通过和驳回先经审批工作流校验;内容安全预检、素材版本、审核日志和公开展示状态仍由 Advertising Service 负责。 |
| Advertising 投放启停 | advertising.creative.delivery | 广告素材启用和暂停先经审批工作流校验,确保只在合法素材状态之间切换;预算扣费、结算和报表仍由 Advertising Service 负责。 |
Contract
| 类型 | 说明 |
|---|---|
ApprovalWorkflow.execute(request) | Facade 短入口 |
ApprovalWorkflowManager.execute(request) | Spring Bean 入口 |
ApprovalWorkflowCatalog.list() | 已注册流程的只读目录快照,供 Admin 运维页、文档导出和 smoke 检查展示 |
ApprovalInbox.snapshot(query) | 跨模块待处理事项只读聚合快照,供 Admin 运维页或 smoke 检查展示 |
ApprovalInboxContributor | 业务模块贡献待处理摘要和待办项目的 SPI |
ApprovalWorkflowDescriptor | 流程只读描述,包含流程编码、展示名、说明、动作数量、超时动作数量和动作清单 |
ApprovalActionDescriptor | 动作只读描述,包含来源状态、目标状态、权限、备注要求和超时计划摘要 |
ApprovalWorkflowDefinition | 流程定义 |
ApprovalActionDefinition | 动作定义,包含来源状态、目标状态、权限、备注和超时计划 |
ApprovalActionRequest | 动作请求 |
ApprovalActionResult | 动作结果 |
ApprovalAuditRecord | 审计快照 |
ApprovalTimeoutPlan | 超时自动处理计划 |
ApprovalAttachment | 附件引用 |
ApprovalSubject | 被审批业务对象引用 |
后台运维入口
spring-open-core-approval-workflow 默认随应用装配,提供只读后台运维入口:
| 项目 | 值 |
|---|---|
| Admin API | GET /api/v1/admin/approval-workflow/operations |
| Admin 页面 | /approval-workflow/operations |
| 菜单 code | approval-workflow |
| 权限 | approval-workflow:view |
该页面展示:
- 当前启动期已注册的 workflow、动作、权限、备注要求和超时计划摘要。
- 各业务模块通过
ApprovalInboxContributor贡献的待办来源、待处理数量和最近待办摘要。 - runbook 提示,提醒管理员回到 owning module 的页面执行审批动作。
该入口只读,不执行审批、不创建通用审批实例表、不绕过业务模块权限。处理动作仍必须回到 CMS / Blog / Forum / Money / Mall / Advertising 等业务模块自己的后台 API 和 Service。
边界
- 不保存数据库,不生成迁移。
- 不接管业务实体状态字段。
- 不直接发送通知。
- 不直接创建 Scheduler 任务,只返回
ApprovalTimeoutPlan。 - 不做页面权限判断;动作权限只校验调用方传入的权限集合。
- 不代替 Chain / Pipeline。审批工作流关心“状态动作能不能执行、执行后状态是什么”。
ApprovalWorkflowCatalog只展示启动期流程定义,不展示待办数量、审批实例详情或业务敏感字段。ApprovalInbox只聚合各业务模块贡献的待处理摘要和跳转入口,不保存通用审批实例表,不执行审批动作,不替代业务模块的审核 / 复核 / 举报处理 API。spring-open-core-approval-workflow只把上述两个只读 contract 暴露到 Admin 运维台,不新增业务状态机,也不接管业务模块补偿逻辑。
统一待办聚合
业务模块可以实现 ApprovalInboxContributor,把自己的待审核内容、待处理举报或待复核记录贡献给统一待办快照:
| 业务来源 | source | 当前贡献内容 | 处理入口 |
|---|---|---|---|
| CMS | cms | reviewStatus=pending 的内容 | /cms/moderation?reviewStatus=pending |
| Blog | blog | 草稿 / 内容安全降级草稿组成的待审文章摘要 | /blog/articles?status=0 |
| Forum | forum | 待处理举报 | /forum/reports?status=0 |
待办聚合只负责读取、排序、汇总和限制返回数量。处理动作仍回到各业务模块自己的后台页面和 Service,避免通用 starter 反向持有业务状态。
配置
spring:
open:
approval-workflow:
enabled: true| 配置 | 默认值 | 说明 |
|---|---|---|
spring.open.approval-workflow.enabled | true | 是否启用审批工作流自动配置 |
后续接入建议
内容类低风险试点已经覆盖 CMS 内容审核和 Content Safety 复核;资金类首个试点已覆盖 Money 用户余额提现;交易类试点已覆盖 Mall 售后审批,广告素材审核 / 投放启停和 Mall 商户入驻也已作为高风险业务接入样板。后续再接新的高风险流程时,先明确业务状态字段、权限快照、审计落库、补偿 / 回滚和 Admin 操作入口,再逐个业务流程迁移。