跳到主内容

v0.2.30 · 生产在用 · 零 moo-system 依赖

流程交给用户画,
环节交给引擎跑

流程定义存库并整图版本化,实例 morph 挂到任意业务单上跑 —— 用户在设计器里画流程,业务单照着走,而不是把流转写死在代码里。

One engine, seven tables

7张表,无 EAV
5我的流程视图
0运行态通用 CRUD
10–12Laravel 版本

PHP 8.2+ / Laravel 10–12 · 命名空间 Mooeen\Process · 结构由 scaffold YAML 生成

Engine vs lifecycle

环节属于引擎,生命周期属于业务

同样叫「流转」,生态里其实分工两层:一层管代码里声明的业务生命周期,一层管用户画出来的审批流程。两者零 composer 依赖,唯一接缝是 host 胶水里的事件桥。

① 声明式内核

moo-flow

状态机内核。host 写一份 FlowDefinition 声明「状态字段 + 一组 Transition」,受理、拒绝、完成、评价全走同一执行器。

纯逻辑库 · 无路由无迁移

② 通用引擎 · 本页

moo-process

流程定义存库、整图版本化、实例挂任意业务单。节点分办理与审批,参与人按组织规则解析,用户画什么就跑什么。

依赖 moo-scaffold 与 moo-contract

③ 审批应用 · 配套

moo-process-application

以动态表单提交作为流程业务主体:审批申请发起、状态投影与实例详情扩展。扩展包单向依赖引擎,引擎不反向认识它。

v0.1.17 · 产品包

接缝只有一处:本包发领域事件 → host listener 调 FlowExecutor::apply。所以「审批走到某一步,业务单状态跟着变」这件事是可选的加法,而不是引擎里写死的耦合。

Data model

七张表,一条在途实例

定义与整图快照分离,每次发布新建不可变版本;实例锁定发起时的版本,同定义同业务单最多一条在途,靠数据库生成列唯一索引保证。

一次流转的四个动作

  1. 1发布定义 —— 新建不可变版本,实例锁定发起时的版本。
  2. 2发起实例 —— morph 挂业务单,按定义范围复检发起资格。
  3. 3生成待办 —— 一批任务精确标识一次节点激活,并行任务按分支隔离。
  4. 4留痕 —— 人工动作与系统事件统一入表,append-only。
表(前缀 moo_process_)职责
definitions流程身份:名称、适用业务、启停、发起范围、当前发布版本指针
versions不可变版本快照:节点 + 连线整图 JSON,append-only
delegations审批代理:全部或指定流程范围 + 生效期,不改写待办候选人
instances运行实例:morph 挂单 + 发起快照 + 锁定版本 + 表单成果
tasks待办:节点快照、候选人、实际操作人、截止与升级配置
logs留痕:人工 / 系统统一入表,按待办反查有专用索引
receipts生命周期回执:消费者 + 日志 + 事件唯一,重放不重复投递

刻意不建的表:notifications(用 host 既有通知体系)、audit_logs(行为审计用 moo-trail)、timers(超时靠扫描任务表,不另存定时器)、EAV 变量表(发起快照进实例 JSON)。少四张表,就少四处会漂移的口径。

Capability

设计、预检、执行、留痕,四段都齐

不是「有节点就算流程引擎」:发布前的预检、在途版本的隔离、参与人的组织解析、审批动作的边角情况,都写进了同一套规则里。

流程定义与版本

定义和整图快照分离;每次发布新建不可变版本,在途实例仍跑旧版本,历史版本与会话不自动改写。

版本化动态表单

表单 JSON 随流程版本冻结;开始 / 办理 / 审批节点各自声明 all / selected / none 填写范围,实例按节点累计结构化成果。

发起范围

按全部在职人员、指定人员、岗位、部门(可含下级)授权;列表先过滤,事务内执行前再复检一次。

条件与网关

字段类型决定运算符与控件;枚举用编码、引用用系统 ID。预检、发布、试运行共用同一套校验。

试运行

用当前设计图和真实业务单只读计算:发起资格、业务快照、预计分支与首批处理人 —— 零实例、零待办、零通知。

执行与审批动作

办理、审批、快捷意见、驳回、转交、催办、前加签后加签与本人减签、或签、会签、依次、直属与逐级主管、排他网关、挂起安全网。

一级子流程

父流程节点引用同业务模型的另一条已发布定义;发布父版本时锁定子版本,父流程终止会级联终止在途子实例。

实例、待办与抄送

管理读面与个人关系读面分开,「我的流程」五视图、代理审批、独立评论与完整留痕;抄送与 cc 节点不建待办,超时默认只提醒。

Safety

运行态没有通用 CRUD

流程数据一旦能被直接增删改,留痕和状态机就都失去意义。所以引擎在这件事上是刻意收窄的。

01

写动作事务内锁行复检

办理、审批、转交都在事务里锁住当前待办再复检,竞态下不会重复推进。

02

个人与管理接口不混用

发起人撤回和管理员强制终止是两条独立契约,走不同入口与不同授权。

03

组织数据走公共契约

人员、部门、岗位经 moo-contract 的 OrgDirectory 读取,缺接线显式失败,不静默降级成空列表。

Extension

引擎不认识产品,产品来接引擎

扩展包单向依赖引擎,引擎不反向认识任何产品模型、表、路由或状态 —— 这是它能被不同业务复用的前提。

产品接入点

  • DefinitionProfileRegistry —— 声明某类流程要预置什么
  • SubjectContractRegistry —— 业务单怎么被引擎读懂
  • SubjectFormDataBridge —— 表单数据怎么进出
  • InstanceDetailContributor / InstanceDocumentContributor —— 详情页与文书由谁补

Host 责任

  • 组织数据:由 System 或 Host 提供 OrgDirectory 实现
  • 业务归属、业务字段、展示名称:窄契约或事件桥
  • 通知文案与渠道:用 Host 既有通知体系
  • 业务状态如何随审批变化:listener 里调 FlowExecutor

What it needs

用起来要满足的条件

  • · 必须先接 org 契约(OrgDirectory 的实现),否则参与人解析直接失败。
  • · 流程定义由用户在宿主后台的设计器里画,引擎不自带一套前端设计器。
  • · 结构性挂起(图本身有问题)需要修图后重新发起,不会自动恢复。
  • · 升级要 Host、Admin 与常驻 worker 一起升,禁止新旧引擎混跑。

What it is not

刻意不承诺的事

  • · 不是开箱即用的审批产品;审批应用是单独的 moo-process-application。
  • · 不管业务政策:谁能发起、字段怎么填、通知发给谁,都由 host 定义。
  • · 不存通知、审计与定时器,这三件事各自有更合适的包。
  • · 源码非开源,按商业授权提供;接入与升级以实际发布版本为准。

One sentence

把「审批流程」从写死在代码里的分支,变成用户能画、版本可回溯、在途不串味的一份定义。