Skip to content

规范 04 · 引擎核心操作

方法语义契约。引擎一次执行旅程的时序与设计动机见 设计原理 03 · 执行引擎

启动流程

text
startProcessInstanceById(defineId, operator, args) → ProcessInstance

语义

  1. 加载流程定义,解析为 ProcessModel
  2. 创建 ProcessInstance(state=10)
  3. 保存实例到仓库
  4. 执行 start 节点 → 遍历输出边 → 创建第一个任务(发起申请节点,actor=发起人)
  5. 任务的 actor 根据 assignee / assignmentHandler 解析
  6. 保存任务和参与者记录

startAndExecute 契约(调用方约定,引擎不内置)

text
startAndExecute(defineId, operator, args) → ProcessInstance
  1. 调用 startProcessInstanceById
  2. 获取所有进行中任务,逐个自动完成(submitType=0 APPLY)
  3. 流程由此推进到第一个真正的审批节点

引擎不自动执行第一个任务——这是调用方的职责(mldong 框架模式), 四版 demo 的 /wf/processInstance/startAndExecute 端点均遵循此契约。

完成任务

text
executeProcessTask(taskId, operator, args) → ProcessInstance

语义

  1. 加载任务 → 校验权限(actor 包含 operator;flow.admin / flow.auto 恒放行,见下)
  2. 任务状态 10→20,记录操作人和完成时间
  3. 执行当前节点 → 遍历输出边 → 创建下一批任务
  4. 若下一节点为 end → 实例状态 10→20(完成)
  5. 若下一节点为 task → 创建新任务(解析 actor)
  6. 若下一节点为 decision → 评估表达式 → 选择分支
  7. 若下一节点为 fork → 并行创建多条路径的任务
  8. 保存变更

系统代执行(flow.auto / flow.admin)

v1.0.1(集成反馈④):对齐 mldong 框架 boot2/boot3 语义。

  • 权限放行operator = "flow.auto"(自动执行,发起即提交)或 "flow.admin" (超级管理员)时,任务权限校验直接通过,无需在参与者列表内(忽略大小写)。
  • 变量注入跳过flow.auto / flow.admin 不是真实用户——引擎执行时不调用 UserProvider 注入 u_* 变量,流程变量保持既有值。需要 u_* 反映实际执行人时, 由调用方(如 startAndExecute)在 args 中显式携带。
  • 发起即提交(startAndExecute):启动流程后,调用方获取 doing 任务,以 flow.auto 逐个自动完成(submitType=APPLY),把流程推进到第一个真正的审批节点——apply 节点 参与者为发起人(applicant),由 flow.auto 代执行,语义等价于发起人亲自提交。

驳回

text
executeAndJumpToEnd(taskId, operator, args) → ProcessInstance

语义

  1. 校验权限
  2. 任务状态 10→20
  3. 实例状态 10→45(已拒绝)
  4. 废弃其他进行中的任务(状态 →99)

退回发起人(mldong 框架契约):业务上"驳回后让发起人改单重提"不使用 executeAndJumpToEnd(那是拒绝,实例直接 45),而是 submitType=6(ROLLBACK_TO_OPERATOR)executeAndJumpToFirstTaskNode——第一个任务节点重执行且参与者强制为发起人, 发起人收到新待办,实例保持 10 进行中。四版 demo 的 /wf/processTask/execute 遵循此行为 (submitType 全枚举见 设计原理 06 §3-4)。

跳转

text
executeAndJumpTask(taskId, operator, args, targetTaskName) → ProcessInstance

语义

  1. 校验权限
  2. 任务状态 10→20
  3. 在已完成的节点中找到 targetTaskName,重新执行其输出边
  4. 废弃当前未完成的任务

会签

会签在普通任务基础上增加:

  • 并行会签:为每个 actor 创建独立任务,全部完成才驱动下一步
  • 串行会签:一次只创建一个任务,完成后创建下一个 actor 的任务
  • 按比例会签:完成率达到阈值即驱动下一步

会签的 actor 存储在流程变量中:{COUNTERSIGN_PREFIX}_{taskName}_operatorList

三种模式的引擎实现细节见 设计原理 03 §6

流程变量约定

引擎自动注入以下变量(前缀 u_ 表示用户信息):

变量名来源说明
u_userIdIUserProvider当前操作人 ID
u_realNameIUserProvider当前操作人姓名
u_deptIdIUserProvider部门 ID
u_deptNameIUserProvider部门名称
u_postIdIUserProvider岗位 ID
u_postNameIUserProvider岗位名称
autoGenTitle引擎自动生成${realName}的${displayName}-${时间}
BUSINESS_NO业务方传入业务流水号
submitType操作时传入全枚举 0=发起 1=同意 2=拒绝 3=退回上一步 4=跳转 5=重新提交 6=退回发起人 20=会签拒绝(见 设计原理 06 §3-4

聚合根方法清单(跨语言契约)

四版实现遵循统一 DDD 结构:聚合根封装业务规则,引擎只做编排。 设计论证见 设计原理 02 · 领域模型

ProcessInstance(聚合根)

行为说明
create工厂——创建流程实例(state=10)
completeTask(task, operator, vars)完成任务(子实体状态转换 + 实例变量合并)
abandonTask(task)废弃单个任务
abandonAllDoing()废弃所有进行中任务
finish()流程完成(state 10→20)
reject()驳回(state 10→45)
addVariable(vars)追加流程变量
createTask(...)创建任务(子实体工厂)
getDoingTasks() / getDoneTasks()查询
isAllTasksFinished()join 合并判断

ProcessTask(子实体)

行为说明
finish(operator, vars)完成任务(10→20,记录操作人/完成时间)
abandon()废弃(10→99)
isAllowed(operator)参与者权限判断
isDoing() / isFinished()状态判断

各语言实现位置

语言聚合根引擎(薄编排)
Javadomain/ProcessInstance.java + domain/ProcessTask.javacore/JeeflowEngineImpl.java
Gomodel/instance.goengine/engine_impl.go
Node.jssrc/model.ts(class)src/engine.ts
Pythonjeeflow/model.py(dataclass + 方法)jeeflow/engine.py

引擎保留:流程遍历(executeNode)、决策求值、参与者解析、仓储调用。 任务状态转换/创建等业务规则一律收敛到聚合根。

jeeflow · 轻量级多语言工作流引擎