跳到正文

大型后台管理系统如何把业务操作做可靠(13):低代码表单与审批流程的执行边界

大型后台管理系统如何把业务操作做可靠

  1. 把业务规则写进订单和退款模型
  2. 并发编辑、草稿合并与搜索乱序
  3. 让报表说清统计口径与数据进度
  4. 退款超时后的幂等与对账
  5. 可恢复的导入导出任务
  6. 批量操作的预览、执行与恢复
  7. 多租户授权、撤权与审计
  8. 旧页面、接口和审批模板如何一起演进
  9. 沿真实操作验收可靠性与性能
  10. 设计规范和组件库如何落到日常开发
  11. 脚手架、接口契约与前后端联调
  12. 构建产物、持续交付与灰度回退
  13. 低代码表单与审批流程的执行边界(当前)
  14. 功能投放、权限与灰度人群
  15. 桌面、移动端与宿主能力适配
  16. 多个前端应用如何集成与独立交付
  17. 复杂编辑器的状态、命令与协作

运营在低代码平台给退款表单增加了「退货凭证」,还把金额超过 500 元的审批改成两级。发布后,昨天已经进入审批的一笔退款仍然需要展示当时的输入、找到正确审批人,并按约定继续处理。

表单配置和流程定义分别版本化

表单描述字段、校验和展示。审批定义描述状态、节点、分支、候选人和允许的动作。二者可以引用彼此的版本,各自保留发布历史。实例创建时固定表单与流程版本,并保存关键输入及用于审批的依据。下方是示例实例的最小关联。

{
  "caseId": "A42",
  "formVersion": "refund-form-v3",
  "workflowVersion": "refund-approval-v5",
  "resourceId": "R17",
  "taskId": "T2",
  "taskVersion": 4,
  "state": "awaiting_finance"
}

低代码表单的条件可用受限的声明式表达式。把字段、函数、类型和执行成本限制在约定范围,发布前检查缺失字段、循环依赖、无效跳转及越权连接器。浏览器负责即时提示,服务端依据已发布定义验证提交。客户扩展代码要有独立授权和隔离,配置提供者不自动获得执行任意代码或访问全库的能力。Formily 对复杂表单的分析

旧审批单沿用创建时的表单和流程版本,新单使用新版本

每次审批针对一个有版本的待办

接收审批时,服务端读取任务并检查当前候选人或受托人、任务版本和流程状态。完成任务、写入决定和创建下一节点应位于同一可靠边界。重复点击只得到已有决定。两个审批人并行操作时,流程应区分任一人同意、所有人同意或按比例同意,并记录拒绝、转交和超时如何改变后续节点。

退款的资金写入由交易服务完成。审批成功可以可靠投递执行命令,退款本身还有独立状态。如果支付渠道超时,审批页可以显示「已批准,退款结果待确认」,并链接到退款结果查询。

用一笔退款推演流程节点

假设 620 元退款需要门店主管和财务先后审批。提交时保存退款金额、订单和证据引用,创建主管待办。主管同意后,记录决定并完成当前待办,再创建财务待办。财务同意后,流程可以进入已批准,交易任务进入已受理。两者通过关联 ID 串起来。页面在退款待确认时仍展示审批已经完成。

当前任务 收到的动作 状态变化
主管审批 同意 完成主管待办,生成财务待办
主管审批 驳回 保存意见,结束本次审批或退回草稿
财务审批 同意 保存最终决定,产生退款执行任务
已完成任务 重复提交同一决定 返回已有决定
已转交任务 旧处理人提交 重新检查候选人和任务版本

在同一事务边界验证待办的主体与版本,然后写入决定、任务结果和下一节点或待投递记录。如果两个财务打开的是同一任务,只有符合版本的决定能完成任务。审批意见和关联证据也属于这次决定,后续有变更要保留变更记录。

让低代码规则在发布前可以解释

以「超过 500 元需要财务审批」为例,规则表达式应声明依赖的金额字段和单位。发布前用 499.99、500 和 500.01 元验证三种结果。字段在新表单中改名时,流程编译或校验应能指出缺少输入。条件不可计算时按事先约定拒绝提交或进入人工复核,不应默认跳过审批节点。

迁移在途实例时先挑选少量样例。已经完成主管审批、尚未生成财务待办的实例,和财务待办已有人领取的实例需要分别判断。若新定义改变了审批依据,要让业务方明确是否接受原决定。迁移清单保存原节点、目标节点、数据转换、失败原因和恢复方式。验证完成后再扩大范围。

发布前演练在途实例

新版本通常先用于新实例。在途迁移需要说明旧节点如何映射到新节点、已做的决定是否仍然有效、字段能否无损转换。遇到无法映射的等待节点,可继续运行旧版本,或按业务规则撤回后重走审批。发布前用一组实例预演影响,检查旧任务如何完成和恢复。流程引擎的迁移文档也把活动节点映射作为需要明确处理的步骤。Camunda 流程实例迁移

设计编辑器、发布器和执行器的职责

配置编辑器允许负责人保存未完成草稿。发布器接收一组明确的表单与流程版本,校验字段、节点、权限和外部引用,产生不可变的发布版本。执行器只读取已发布定义和当前实例状态。这样编辑器中临时改掉一个字段名时,运行中的审批不受草稿影响。

审批操作也需要区分「页面可以看到按钮」和「任务此刻可以完成」。下面是简化伪代码。读取待办时得到任务版本,提交时按当前候选人和任务状态再次判断。

completeTask(actor, taskId, expectedVersion, decisionId, decision):
  transaction:
    task = loadTaskForUpdate(actor.tenant, taskId)
    requireActorCanReadTask(actor, task)
    if sameRecordedDecision(task, decisionId, decision):
      return recordedResult(task)
    requireCurrentAssigneeAndVersion(actor, task, expectedVersion)
    appendDecision(task, decision)
    advanceWorkflow(task, decision)
    writeRequiredOutboxEntries(task)

如果流程已经拒绝,另一个候选人晚到的同意应得到明确冲突。若提交成功但响应丢失,重放原决定要得到原结果。审批同意和资金实际到账之间应保留独立状态,回访旧单据时可以按各自的 ID 查到历史和当前结果。

总结

配置化后台需要分别管理表单定义、流程定义和执行中的实例。版本记录能还原当时的审批依据,当前权限和交易约束则继续控制每一次实际执行。