Skip to content

规范 02 · 流程定义配置项完整参考(属性字典)

流程定义 = LogicFlow JSON。同一份 JSON 在所有语言实现(Java/Go/Python/Node/PHP/Rust)中 必须产生一致的执行结果。

本文档是流程定义所有配置项的权威参考(事实来源:Java 参考实现的 ModelParser / NodeParser 系列解析器,六语言行为对齐):

  • "引擎"列:✅ = 引擎已实现(解析并影响行为);「前端」= 仅设计器/发起页使用,引擎忽略
  • 未列出的 properties 键 = 引擎不识别,原样存入节点扩展属性 ext (任务变量可回显,不参与执行)
  • 前端设计器属性面板字段与本表的关系见 用户指南 11 · 流程设计器

1. JSON 结构总览

json5
{
  // ── 顶层(引擎解析)──
  "name": "leave",            // 流程编码(唯一,deploy 版本管理键)
  "displayName": "请假审批",   // 流程显示名称
  "type": "approval",         // 流程类型
  "expireTime": "2026-12-31", // 流程期望完成时间
  "relTableName": "biz_leave",// 关联业务表名(bizData 回显)
  "persistMode": "ARCHIVE",   // 业务落表模式(persist)
  "postInterceptors": ["..."],// 流程级后置拦截器
  "preInterceptors": ["..."], // 流程级前置拦截器
  "instanceUrl": "...",       // 实例详情 URL(预留)
  "instanceNoClass": "...",   // 业务号生成类(预留)
  // ── LogicFlow 图 ──
  "nodes": [ /* 见 §3 */ ],
  "edges": [ /* 见 §9 */ ]
}

节点(LogicFlow 标准字段)

json5
{
  "id": "apply",          // 节点唯一编码 → 任务名 taskName(全流程唯一)
  "type": "snaker:task",  // 节点类型(接受带/不带前缀两种写法,见 §3)
  "x": 250, "y": 200,     // 画布坐标(设计器布局,引擎不参与执行)
  "text": { "value": "发起申请" },  // 显示名称 displayName(引擎读取位置)
  "properties": { /* 引擎扩展属性,见 §4~§8 */ }
}

兼容:type 接受 snaker:tasktask 两种写法(设计器导出带前缀,手动编写可省略)。

2. 顶层属性(流程级)

字段类型引擎说明
namestring流程编码(唯一)——deploy 版本管理键(同 name 从 0 递增);bizData 表名回落
displayNamestring流程显示名称
typestring流程类型(listByType 分组键)
expireTimestring流程期望完成时间
relTableNamestring关联业务表名——bizData 回显定位表;缺省回落 name
persistModestring业务落表模式:ARCHIVE(缺省,流程结束归档)/ SYNC(发起 INSERT → 节点 UPDATE → 定稿),见 指南 08 persist
preInterceptorsstring[]流程级前置拦截器注册名(逗号分隔/数组)
postInterceptorsstring[]流程级后置拦截器注册名——persist 的办理节点权限判定路径,必须配置
instanceUrlstring预留实例详情 URL(前端用)
instanceNoClassstring预留业务号生成类(前端/集成方用)
selectUserOnInitiateint前端发起时选择处理人(0/1)
enableCcActorsint前端发起页抄送开关(0/1)
enableApplyReasonint前端发起页申请理由开关(0/1)
enableAttachmentint前端发起页附件开关(0/1)
enableFieldPermint前端字段权限开关(0/1)

3. 节点公共属性(全部节点通用)

字段引擎说明
id节点唯一编码 → 任务名 taskName
type节点类型(8 种,见下)
text.value显示名称 displayName
properties.name唯一编码(钉钉模式设计器写入,与 id 对应)
preInterceptors节点前置拦截器注册名(逗号分隔多注册名)
postInterceptors节点后置拦截器注册名(persist 模型级执行后触发)
x / y / layout布局画布坐标/布局(引擎不参与执行)

节点类型总览

type(兼容写法)说明必填 properties
snaker:start / start开始-
snaker:end / end结束(全流程只能有一个-
snaker:task / task任务节点assigneeassignmentHandler
snaker:decision / decision条件分支出边 expr
snaker:fork / fork并行分支-
snaker:join / join并行合并-
snaker:custom / custom自定义节点clazz
snaker:subprocess / subprocess子流程form

发起申请节点约定(mldong 框架契约):start 后第一个任务节点必须是"发起申请"节点, assignee = "applicant"(引擎解析为流程发起人)。引擎不自动执行该节点,由调用方 (startAndExecute)启动后自动完成,流程推进到真正的审批节点。

4. 任务节点 properties 完整字典(snaker:task)

字段类型引擎说明
assigneestring固定参与者:逗号分隔多人;applicant = 发起人;token 优先按流程变量 key 解析(见 参与者解析
assignmentHandlerstring动态参与者注册名(内置清单见 指南 07
formstring表单标识 → formKey(发起页/办理页表单定位)
taskTypeint0=主办 1=协办
performTypeint/string0=普通参与(多人任一完成即可)1=会签(每人独立任务);兼容字符串 '1'/'ALL'/'COUNTERSIGN'
countersignTypestring会签模式:PARALLEL(并行,全部完成推进)/ SEQUENTIAL(串行,依次流转)/ RATIO(阈值完成,配合 countersignCompletionCondition
countersignCompletionConditionstring会签完成条件表达式(如 #nrOfCompletedInstances>=2);特殊值 ONE_VOTE_VETO(忽略大小写)= 开启一票否决,见 §4.2
candidateUsersstring⚠️候选人 userId 列表(逗号分隔)——不生成 actor,供 candidatePage 选人
candidateGroupsstring⚠️候选角色标识(逗号分隔)
candidateHandlerstring⚠️动态候选人处理注册名
reminderTimestring提醒时间(如 10:00
reminderRepeatstring重复提醒间隔
expireTimestring期望完成时间
autoExecutestring自动执行配置
callbackstring回调处理注册名(任务完成回调)
preInterceptorsstring[]前置拦截器
postInterceptorsstring[]后置拦截器(persist 写库/权限判定)
fieldobject字段权限声明(见 §4.1)
其他任意键anyext不识别 → 存入节点扩展属性 ext(任务变量回显,不参与执行)

4.1 字段权限(field,SYNC persist 用)

  • 声明位置:任务节点 properties.field
  • 键格式(双兼容):PERMISSION_{表单字段全名}(含 f_ 前缀,前端 vben5-wf 约定,优先) 与 PERMISSION_{去前缀名}(旧格式)
  • 值:1=只读 / 2=可编辑 / 3=隐藏(缺省=可编辑)
  • 办理入口过滤:按任务节点权限过滤后再入流程变量——上游只读不可被下游绕过
  • 状态列:优先 {节点ID}_{状态码} 列,无则 {节点ID}

4.2 会签(countersign)行为

模式行为推进条件
PARALLEL每个参与者一个独立任务全部完成
SEQUENTIAL一次一个任务,完成后流转给下一个参与者全部完成
RATIO每人一个任务完成数满足 countersignCompletionCondition
一票否决(ONE_VOTE_VETOcountersignCompletionCondition 设为 ONE_VOTE_VETO(忽略大小写)时,任一成员 submitType=20 会签不同意 → 节点立即推进否决者提交即合并

会签推进/否决后的残留处理:节点合并(merged)推进下一节点时,该节点仍 DOING 的会签任务一律废弃(taskState=99),不留孤儿待办——并行会签下其余成员的待办即被清空(对齐 mldong 内置引擎 abandonProcessTask 行为)。

会签拒绝(submitType=20)的默认语义 = 软拒绝:未配置 ONE_VOTE_VETO 时,否决者任务正常完成、countersignDisagreeFlag=1 记录为流程变量(供下游节点作参考),流程不阻断,按常规模式(全部完成 / 表达式)等待推进——会签意见默认只作参考、不阻断流程。

5. 决策节点 properties(snaker:decision)

字段位置引擎说明
expr节点节点级默认表达式(可选)
handleClass节点自定义决策器处理类注册名
expr出边分支条件表达式——决策出边必填(首条满足者胜)
text.value出边分支标签(钉钉模式渲染在线上)

决策路由规则:引擎按出边顺序求值,第一条 expr 为真的边获胜; 无 expr 的出边作为默认分支(兜底)。表达式语法见 指南 02 §5

6. 自定义节点 properties(snaker:custom)

字段引擎说明
clazz处理器类路径(必填)
methodName方法名
args参数变量(逗号分隔的变量 key)
val返回值写入的变量 key

7. 子流程节点 properties(snaker:subprocess)

字段引擎说明
form子流程表单标识
version子流程版本号

8. 开始 / 结束 / 并行节点

  • snaker:start / snaker:end:无专属属性(仅公共属性)
  • snaker:fork / snaker:join:无专属属性——fork 出边建议写 text.value 分支标签

9. 边属性(edges)

json5
{
  "id": "e1",
  "sourceNodeId": "start",     // 起点节点 id
  "targetNodeId": "apply",     // 终点节点 id
  "properties": { "expr": "amount > 1000" },  // 决策分支条件
  "text": { "value": "金额>1000" }            // 分支标签(决策/fork 边建议必填)
}
字段引擎说明
sourceNodeId / targetNodeId起止节点
properties.expr决策出边条件表达式
text.value分支标签(钉钉模式渲染在线上,决策/fork 边建议必填)

10. 完整示例(标准骨架)

json
{
  "name": "leave",
  "displayName": "请假审批",
  "type": "approval",
  "relTableName": "biz_leave",
  "persistMode": "SYNC",
  "nodes": [
    { "id": "start", "type": "snaker:start", "x": 100, "y": 200, "properties": {}, "text": { "value": "开始" } },
    { "id": "apply", "type": "snaker:task", "x": 250, "y": 200,
      "properties": { "form": "apply-form", "assignee": "applicant", "taskType": 0, "performType": 0 },
      "text": { "value": "发起申请" } },
    { "id": "leader", "type": "snaker:task", "x": 400, "y": 200,
      "properties": { "form": "leave-form", "assignee": "leader", "taskType": 0, "performType": 0,
        "postInterceptors": ["jeeflowPersistPostInterceptor"] },
      "text": { "value": "组长审批" } },
    { "id": "decision1", "type": "snaker:decision", "x": 550, "y": 200, "properties": {}, "text": { "value": "金额判断" } },
    { "id": "end", "type": "snaker:end", "x": 700, "y": 200, "properties": {}, "text": { "value": "结束" } }
  ],
  "edges": [
    { "id": "e1", "sourceNodeId": "start", "targetNodeId": "apply", "properties": {} },
    { "id": "e2", "sourceNodeId": "apply", "targetNodeId": "leader", "properties": {} },
    { "id": "e3", "sourceNodeId": "leader", "targetNodeId": "decision1", "properties": {} },
    { "id": "e4", "sourceNodeId": "decision1", "targetNodeId": "end",
      "properties": { "expr": "amount > 1000" }, "text": { "value": "金额>1000" } },
    { "id": "e5", "sourceNodeId": "decision1", "targetNodeId": "end",
      "properties": {}, "text": { "value": "默认" } }
  ]
}

11. 常见错误对照

错误现象修复
多个 end 节点分支各自结束汇合到同一个 end
申请节点缺 assignee启动后无任务"assignee": "applicant"
决策出边缺 expr走默认分支(第一条无 expr 边)每条出边补 expr
决策/fork 边缺 text线上无标签text.value
节点 id 重复任务名冲突保证 id 全流程唯一
custom 写 customClass解析不出 clazz,节点不执行clazz(旧文档字段名,引擎不识别)
属性拼写错误静默进 ext,行为不生效对照本表逐键核对

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