流程架构的解耦与进化设计
一、业务痛点:流程架构的耦合困境
在之前所有涉及流程相关的业务系统操作,始终会面临一个困境:随着业务复杂度攀升,流程图像不断膨胀的蛛网 —— 新增一个审批节点可能要修改整张图的关联路径,调整一个分支条件要牵动上下游多个节点,每次改动后都需要全流程回归测试。
原因是之前的流程服务始终是把“图”和流程引擎做为了一个整体,这种 “图即流程、流程即图” 的设计,看似直观,在业务复杂后则陷入了 “业务流转逻辑” 与 “流程执行逻辑” 深度耦合之中。
实际的业务当中,流程的核心是 “流转逻辑” 的顺畅执行,流程图仅为业务系统驱动下的可视化呈现,且实际上流程引擎常用的节点功能是有限的,无需为了每次的节点变动都去调整整体结构。
二、破局思路:三元解耦架构
核心设计理念:**“流程引擎做执行(循环 + 节点类型),业务系统做决策(流转规则)”,**将传统 “整体图” 拆解为三个独立模块,实现解耦:
1. 节点类型收敛:聚焦核心执行单元
流程引擎仅定义 4 种核心节点类型,所有业务节点均归类其中:
- 开始节点:初始化流程上下文,触发首次流转
- 普通节点:单角色审批、数据校验等常规业务执行
- 会签节点:多角色并行审批,汇总意见后流转
- 结束节点:终止流程,输出结果
价值:引擎无需关心节点的 “业务含义”(如 “成本审核”“合同签约”),仅按类型执行标准逻辑。
2. 动态规则外置:将 “图的边” 交给业务系统
原流程图中 “节点间流转路径”(图的 “边”)转化为业务系统可配置的流转规则:
- 业务系统根据当前节点、业务数据(合同金额、租户类型等)计算下一跳节点的 ID 和类型
- 流转规则支持配置化(JSON、数据库配置等)
价值:业务规则与流程执行解耦,新增节点或调整路径时,仅需修改业务系统规则,无需变动流程引擎核心逻辑。
3. 循环执行内聚:引擎的 “永动闭环”
流程引擎通过循环逻辑实现 “执行 - 获取下一跳 - 再执行” 的闭环,直至触发结束节点。
价值:无论业务流程多复杂,引擎循环逻辑保持不变;新增节点仅需实现对应类型的execute方法,彻底摆脱 “改图即改引擎” 的困境。
三、设计思想:平衡通用与个性化
以营销合同业务为原型,构建满足 “公共→部分公用→个性化” 需求的通用流程,遵循三大原则:
“配置定义流程、层级实现复用、动态适配场景”
1. 层级架构设计
(1)层级划分逻辑
明确三级节点定位,清晰界定职责边界:
- PUB(全系统通用):全系统共享节点(如流程起点、终点)
- IND(产业专属):特定产业内复用节点(如成本产业专属审核节点)
- TEN(租户定制):单个租户个性化节点(如某租户专属初审节点)
(2)层级覆盖机制
支持下层节点覆盖上层节点的下跳规则(如租户层覆盖产业层),需配置:
- 覆盖条件:适用产业(
applyIndustries)、适用租户(applyTenants) - 开关控制:
enable字段(是否启用覆盖)
(3)层级优先级
定义流程下跳时的层级查找顺序(如layerPriorityOrder: ["TEN", "IND", "PUB"]),确保个性化规则优先生效。
2. 动态下跳规则
(1)条件规则引擎
基于业务数据的条件判断(如合同金额 > 50 万),通过 EL 表达式(elExpression)实现灵活校验。
(2)规则优先级
同一层级内的多条规则按priority字段排序(值越大优先级越高),高优先级规则优先匹配。
(3)白名单限制
通过layerWhitelist控制各层级允许跳转的节点范围,防止非法节点接入,保障流程安全。
(4)默认兜底机制
无匹配规则时,通过defaultNextNodeByLayer指定各层级默认下跳节点,避免流程中断。
3. 节点适用范围管控
(1)可见性控制
通过applyScope定义节点可使用的产业(industries)和租户(tenants),确保节点仅在授权范围内生效(如租户节点仅对特定租户可见)。
(2)版本管理
支持节点多版本(如V1.0),通过ResourceLoaderUtil.findHighestVersionByNodeId自动识别最高版本,默认加载。
4. 业务执行逻辑
(1)处理器绑定
每个节点通过businessHandler指定业务处理类(如合同创建、审核逻辑),实现流程节点与业务代码解耦。
(2)人员分配
支持自定义 EL 表达式解析人员分配逻辑,灵活适配业务场景。
5. 扩展特性
(1)非核心属性配置
通过extendConfig定义超时时间(timeout)、通知渠道(notifyChannel)等附加特性,扩展流程能力。
(2)节点类型标识
通过nodeType区分节点角色(CREATE:起点;NORMAL:中间节点;END:终点),辅助流程生命周期管理。
四、JSON 配置规范(核心中枢)
JSON 配置需严格遵循层级特性和功能需求,关键字段设计如下:
1. 基础标识字段(所有节点必选)
{"nodeId": "PUB_CREATE", // 节点唯一ID,前缀标识层级(PUB_/IND_/TEN_)"nodeName": "提交交接单据", // 节点名称"version": "V1.0", // 版本号"description": "所有租户通用的提交节点", // 描述"nodeType": "CREATE", // 节点类型(CREATE/NORMAL/END)"layerAttr": "PUB", // 层级属性(PUB/IND/TEN)"industryCode": "ALL", // 所属产业(PUB填ALL,IND/TEN填具体产业)"tenantId": "ALL" // 所属租户(PUB/IND填ALL,TEN填具体租户ID)
}
2. 动态下跳配置(dynamicNextConfig,核心字段)
"dynamicNextConfig": {"layerPriorityOrder": ["TEN", "IND", "PUB"], // 层级查找优先级"layerWhitelist": { // 各层级允许跳转的节点白名单"PUB": ["PUB_END"],"IND": [],"TEN": ["TEN_001_REGION_CHECK"]},"conditionRules": [ // 条件规则列表{"elExpression": "${contractAmount > 500000}", // EL表达式判断条件"targetNodeId": "PUB_MARKETING_SUPERVISORY_LEADER_CHECK", // 目标节点ID"targetNodeLayer": "PUB", // 目标节点层级"priority": 9, // 规则优先级(值越大越优先)"effectiveLayers": ["PUB"] // 规则生效的层级范围}],"defaultNextNodeByLayer": { // 各层级默认下跳节点"PUB": "PUB_CONTRACT_ADMINISTRATOR_CHECK","IND": "","TEN": ""}
}
3. 层级覆盖配置(layerOverrideControl,可选)
用于下层节点覆盖上层节点的规则:
"layerOverrideControl": [{"targetNodeId": "TEN_NR100046_FIRST_CHECK", // 覆盖后跳转的目标节点"applyIndustries": "COST", // 适用产业"applyTenants": ["NR100046"], // 适用租户"enable": true // 是否启用覆盖}
]
4. 适用范围与扩展配置
"applyScope": { // 节点可见范围"industries": ["ALL"], // 适用产业列表"tenants": ["ALL"] // 适用租户列表
},
"extendConfig": { // 扩展属性"timeout": 24, // 超时时间(小时)"notifyChannel": "SMS" // 通知渠道(短信/邮件等)
}
五、不同层级 JSON 的设计差异
| 层级 | 核心配置差异 | 适用场景 |
|---|---|---|
| PUB | industryCode: "ALL"、tenantId: "ALL",applyScope覆盖所有产业和租户 | 通用节点(流程起点、终点、跨产业审核) |
| IND | industryCode: 具体产业(如COST)、tenantId: "ALL",applyScope限制在特定产业 | 产业专属节点(如成本核算节点) |
| TEN | industryCode和tenantId为具体值,applyScope仅对该租户生效 | 租户个性化定制(如租户专属初审节点) |
六、流程架构与拓扑图的关联分析
流程架构设计吸收了拓扑图(Topology Graph)“节点 - 连接关系” 的核心抽象思想。
拓扑图的 “结构抽象” 是解决流程耦合的 “核心钥匙”—— 通过 “节点收敛 + 规则外置” 拆解传统流程图的耦合关系;而业务流程的 “动态执行、通用与个性化平衡” 需求,是设计的 “最终目标”—— 通过 “循环引擎、层级覆盖、业务绑定” 将静态拓扑转化为可落地的业务系统。二者结合实现了 “结构稳定、业务灵活” 的流程架构。
七、流程引擎总体流程图
┌─────────────────────────────────────────────────────────────────────────┐
│ 起始节点:PUB_CREATE(PUB层,V1.0) │
│ 层级优先级配置:[TEN, IND, PUB](高优先级层级优先匹配) │
└───────────────────┬─────────────────────────────────────────────────────┘││ 触发层级覆盖(租户NR100046+产业COST)▼
┌─────────────────────────────────────────────────────────────────────┐
│ TEN_NR100046_FIRST_CHECK(TEN层,V1.0) │
│ 白名单(允许跳转的层级节点): │
│ - TEN层:[TEN_001_REGION_CHECK] │
│ - IND层:[IND_ECOM_LOGISTICS] │
│ - PUB层:[PUB_FIN_CHECK, PUB_END] │
└───────────┬───────────────────────┬─────────────────────────────────┘│ ││ 条件1:金额>20万(TEN层规则匹配)│ (跨层级跳PUB层,需在PUB层白名单内)▼ │
┌───────────────────────┐ │ 条件2:合同类型=紧急(TEN层规则匹配)
│ PUB_END(PUB层) │ │ (跨层级跳PUB层,校验通过)
└───────────────────────┘ ▼┌───────────────────────┐│ PUB_FIN_CHECK(PUB层) │└───────────────────────┘│ 未触发覆盖(其他租户/产业)▼
┌─────────────────────────────────────────────────────────────────────┐
│ IND_INDUSTRIAL_UNIT_DEPARTMENTAL_COST_ACCOUNTING_CHECK(IND层,V1.0)│
│ 白名单:PUB层=[PUB_CONTRACT_MANAGEMENT_DEPARTMENT_CHECK, │
│ PUB_MARKETING_MANAGER_CHECK] │
└───────────┬───────────────────────┬─────────────────────────────────┘│ ││ 条件:金额>50万(IND层规则匹配)│ (跨层级跳PUB层,校验白名单通过)▼ │ 无匹配规则(走IND层默认节点)
┌───────────────────────────┐ │ (跨层级跳PUB层,默认节点在白名单内)
│ PUB_MARKETING_MANAGER_CHECK(PUB层)│ ▼
└───────────┬───────────────┘ ┌───────────────────────────────────┐│ │ PUB_CONTRACT_MANAGEMENT_DEPARTMENT_CHECK(PUB层)││ └───────────────────────────────────┘│ 条件:金额>50万(PUB层规则,按优先级)▼
┌───────────────────────────┐
│ PUB_MARKETING_SUPERVISORY_LEADER_CHECK(PUB层)│
└───────────┬───────────────┘│ 无匹配规则(走PUB层默认节点)│ (跨层级跳IND层,需IND层节点在PUB层白名单?不,此处为PUB层跳IND层,实际需IND层允许被引用)▼
┌─────────────────────────────────────────────────────────────────────┐
│ IND_INDUSTRIAL_UNIT_DEPARTMENTAL_COST_ACCOUNTING_CHECK(IND层) │
│ (形成跨层级循环,需再次按层级优先级匹配下跳) │
└─────────────────────────────────────────────────────────────────────┘
层级互跳核心规则说明:
-
跨层级跳转前提:
目标节点必须在当前节点的对应层级白名单中(如 IND 层节点跳 PUB 层,需 PUB 层目标节点在 IND 层的
layerWhitelist.PUB列表内),否则触发ProcessException(见LayerValidateUtil.validateWhitelist)。 -
层级优先级控制流向:
按
layerPriorityOrder(如[TEN, IND, PUB])依次检查各层级的规则和默认节点,高优先级层级(如 TEN)的匹配结果会覆盖低优先级层级(如 IND/PUB)。 -
典型跨层级场景:
- TEN 层 → PUB 层:TEN_NR100046_FIRST_CHECK 跳 PUB_END(白名单允许 + 规则匹配);
- IND 层 → PUB 层:IND 节点按规则跳 PUB_MARKETING_MANAGER_CHECK(白名单校验通过);
- PUB 层 → IND 层:PUB_INDUSTRIAL_SUPERVISORY_LEADER_CHECK 默认跳 IND 节点(需 IND 节点在 PUB 层白名单或层级校验允许)。
-
禁止非法跨层级:
若目标节点层级与当前处理层级不匹配(如 IND 层节点跳 TEN 层但未在白名单),
LayerValidateUtil.validateTargetLayer会抛出异常,阻断跳转。
