工作流引擎的委托代批:一张单,两个办理人

一、一个场景:李四出差了,单子归谁批

孙倩递了一张请假单:10 月 14 日到 15 日休年假。单子走「含驳回流程」,审批链是 上级审批(李四)→ 经理审批(王五)。

李四这几天在外地出差。出发前,他在「我的委托」里配了一条:· 全部流程 · 委托给张三 · 10/13 ~ 10/16 · 启用。

当晚,单子流转到上级审批节点:

  • 李四的待办里有这张单;
  • 张三的待办里也有这张单;
  • 张三看完,写下「行程已知会,同意」提交,单子流转到经理审批;
  • 审批记录里,上级审批这一步的办理人:张三。

这就是「委托代批」:配一条委托记录,之后所有"本该给某人"的审批单,在建任务那一刻自动把被委托人一并写进参与者------原人保留,两人任一可办。

看着只是"一张表 + 一个查询",但要在八种语言的引擎里做成同一套行为,需要钉死的语义有十来条。这篇按 配置 → 判据 → 并入 → 记录 → 跨语言 → 迁移 的顺序,把它完整讲一遍。以下所有截图和读数,都来自本机起的一套演示(Python 后端 + jeeflow-ui 组件包)。

二、委托不是转办:并入不替换、不接力、不扩名册

第一条设计决定:命中委托 = 把被委托人追加进参与者集合。不是替换,不是换人。

动作 效果 什么时候用
委托代批 追加被委托人;原人保留 出差 / 休假期间
转办 换人,摘掉原办理人 这张单交给别人
加签 追加一个参与者 加一个会签 / 知会人

三条细节同样是设计的一部分:

不接力。 A 委托了 B、B 又委托了 C------C 不会收到 A 的单。委托只对"建单那一刻的原始参与者"生效,被委托人自己的委托不再往外展开,从根上避免环状委托。演示里有个天然样本:孙倩自己配了"委托周明",她发起的单,发起节点的参与者是「孙倩、周明」------周明的委托人吴婷没有出现。

不扩名册。 串行会签的每一步都是独立建任务:代理人只进当一步任务的参与者,不会去动会签的投票名册。

只对新单生效。 参与者是任务落库时的一次性快照;改委托只影响之后新建的单,已经建出来的单不变------待办、已办、详情读的都是同一张参与者表,查询侧不用再维护第二套算法。

三、什么时候算人:建单那一刻,一条判定链

委托的判定时机是固定的:任务参与者解析完成之后、落库之前,引擎对每个参与者查一次生效委托,命中就追加。

覆盖范围是全部建单路径,而不是只有"发起":发起、办理推进、串行会签的每一步、跳转、回退------每一次建任务都会重算一遍。单子是在流转中不断产生新任务的,只在发起处挂钩会漏掉后面每一步。

判定本身是一条单链:

  • 看这个人名下、当前流程作用域有没有委托行;
  • 有:取最新一条(按 id),对这条做四项判据;
  • 判否(没有记录、或这条没通过判据):再看全部流程作用域的最新一条------精确判否、全局兜底;
  • 命中:把被委托人追加进参与者。

判据四项:

  1. 时间窗:开始时间 ≤ 现在 ≤ 结束时间,两头允许留空(留空 = 该侧不限);
  2. 启用 :只认 enabled == 1(白名单式判定,"2"、空值、脏值一律不算启用,第五节细说);
  3. 自委托:被委托人 ≠ 授权人(自己委托给自己,不生效);
  4. 作用域 :流程名留空 = 全部流程兜底;填了流程名,就按流程模型名匹配(比如 leave)。

流程名的匹配口径:以流程模型名 为准(流程 JSON 里的 name 字段,即 ProcessModel.name),模型未带时回落到流程定义表里的名字;判空前先 trim。所以配 leave 命中的是"流程模型名 = leave"的那支流程,而不是定义表里的显示名。

每个节点的参与者,各算各的委托:演示里「经理审批」节点的参与者,也自动并进了王五自己的委托人赵六。

四、取哪一条:先取最新,再裁决

同一个作用域下可以存在多条记录,取行顺序本身就是设计的一部分:

同一作用域,先按 id 取最新一条,再对这条做裁决;判否不回头找更旧的。

用起来就是一句话:你最后改的那条,就是生效的那条。

  • 出差改期:直接把窗口往后改,改完即生效;
  • 提前回岗:把这条停用,新单立即不再并人------不会"翻回"更早的记录;
  • 委托期间到了:窗口自会兜住(窗外的新单不并人),记录留着不影响。

本机实测(同一张单、同一个节点,只看上级审批的参与者是谁):

最新一条委托的样子 上级审批参与者
窗内 + 启用 + 委托张三 李四、张三
窗内 + 停用 仅李四
窗内 + 自委托(改委托给自己) 仅李四
窗内 + enabled=2 仅李四

取哪一条落到 SQL 层就一句:

sql 复制代码
WHERE operator = ? [AND process_name = ?]
ORDER BY id DESC LIMIT 1

判据不写进 SQL(不写 enabled 条件、不写时间窗),先取出最新一条,再交四项判据裁决------这样"停用 / 改期立即生效"才有保证。

还有一条工程口径:同一份规范对内存仓储和 SQL 仓储同时生效,同一个引擎的两种仓储实现必须给出同一个答案(本地单测没连库时跑内存仓,行为也不能漂)。

五、enabled 的两个侧面:读侧白名单,写侧归一

enabled 这个字段值得单说,因为它在"读"和"写"两侧的职责不同,而且是分开定的:

  • 读侧 :只有整数 1 生效。0、2、NULL、脏值一律不生效------白名单式判定,不做"非 0 即真"的宽松解析。
  • 写侧 :processSurrogate/save 不传 → 落 1;传了但不可解析成整数("abc"、"1x"、空串)→ 落 0 ,并且保存/建单必须成功、不报错。

写侧的动机很朴实:一条委托录入走偏,结果应该是"存下来了但没启用",而不是"保存接口 500"。一个字段的格式问题,不该把整个动作打断。

六、谁能看到谁的委托:归属不变式

「我的委托」只属于自己。这条在两层上保证:

  • 门面层 :分页自动带上"授权人 = 当前用户"的归属条件。集成方注入登录人;缺省 / 空值时按契约归一(演示环境缺省为 user1)。
  • 仓储层 :绕过门面直连仓储时,归属条件为空或缺失 → 返回空页,绝不允许退化成"全库台账"。

把这条放在引擎与仓储两层,而不是交给每个宿主自己做:换集成方式、直连 SPI,归属保证都还在。

七、八个引擎,同一套答案

上面的语义不是某一家的实现细节,而是统一规范里的一节:spec/06 §4.5「委托代理」。八种语言的引擎(Java / Go / Python / Node / PHP / Rust / MoonBit / C#)按同一套行为实现。

跨栈验收里,委托占了三个用例格:两组取行判据(时间窗 / 启用 / 自委托 / 取最新)+ 一组归属不变式;13 套集成后端联同 MoonBit 插件形态,跑的是同一组夹具。

在手边的四个后端上做了个只读抽查(同一个请求:查李四名下的委托分页):

后端 返回的行 返回范围
Python 1 条 只含李四的行
Java 1 条 只含李四的行
Go 1 条 只含李四的行
Node 1 条 只含李四的行

换哪个语言的后端,委托的语义不变------这是 jeeflow 八语言联邦一贯的目标。

八、如果你从 mldong 内置版迁过来:三条方向差异

jeeflow 的委托语义与 mldong 框架内置工作流模块 有三处方向不同。两版都自洽,规范以 jeeflow 为准;迁移前,把自己环境里的委托配置对照下面三条普查一遍即可------重点关注三类配置:"全部流程"与"某流程"并存 、最近停用或改期过 、历史上有"委托给自己"的行。

判据点 内置版 jeeflow 迁移时留意
作用域优先级 全部流程优先 精确优先,判否回落 接管人可能不同
择优顺序 先过滤再取最新 先取最新再裁决 停用后是否落回旧记录
自委托 未单独过滤 自委托不生效 先清理自委托历史行

九、回到使用:一份小小的对照清单

  • 出差 / 休假用委托 (加人,原人保留);某张单子不想管,用转办(换人)。
  • 只针对某类流程:填流程名(流程模型名);全都要管:留空。
  • 改期:直接改原记录的窗口;提前回岗:停用(或删除)该条。
  • 代理人办完的单,审批记录记的是代理人的名字------谁办的,记谁。

参考资料(发布版保留纯文本链接)

相关推荐
高频因子挖掘机1 小时前
量化回测为什么不能随便选前复权?从收益率计算到成交价格的三个误区
后端·github·api
高频因子挖掘机3 小时前
回测收益为什么可能不真实?从时间戳、数据可用性到未来函数检查
后端·github·api
Joy T6 小时前
Agent 确定性上下文设计:从 Prompt 参数注入到能力分层
java·开发语言·微服务·架构·prompt·agent context
微订校园外卖平台9 小时前
同城外卖小程序开发:校园外卖系统四端架构与订单链路拆解
架构·外卖系统·本地生活·微订
m0_587383009 小时前
广州 24 小时自助健身房解决方案技术实现与实战指南
java·spring·小程序·架构·需求分析
牛战士coding10 小时前
AI Agent 如何接入真实业务系统?订单助手三层架构完整拆解
人工智能·架构
收放扳机10 小时前
PCB收放板设备机械手架构选型参考——三轴/四轴/六轴/蜘蛛手对比
人工智能·科技·架构·自动化·制造·pcb工艺
九卷10 小时前
企业级Agent系统整体技术架构介绍
ai·架构·大模型·llm·agent·智能体
行百里er11 小时前
Redis 完结篇——Redis 热点问题在 Spring Boot 项目中实战
redis·后端