Appearance
规范 06 · 统一门面(JeeflowFacade)完整接口文档
面向"接口即 POST + JSON body"的框架风格:集成方只实现一个转发 controller, 把 body JSON 转成 Map 传入门面,所有流程能力通过
action路由。本文档是前端接入的唯一依据:不管后端是 mldong 系列(boot2/boot3/boot4)、 FastAPI、NestJS、GoFrame,还是任意其他框架(如若依),只要实现了统一门面转发层, 前端即可按本文档的
action+ 参数 + 返回结构直接对接。 设计动机(为什么需要门面、与 boot2/boot3 端点的关系)见 设计原理 07 · 管理扩展与门面。
1. 入口契约
text
Map<String,Object> flow(String action, Map<String,Object> args)action:boot2/boot3 端点路径的短名(见第 3 节 action 清单)args:业务参数 Map(含分页、过滤、表单数据、operator 等)- 返回统一结构(对齐 mldong
CommonResult):
json
{ "code": 0, "msg": "成功", "data": { ... } }code=0成功;code!=0失败,msg为失败原因(引擎内统一99999999)- 门面内部异常会被捕获转成
{code: 99999999, msg: 异常信息},不会向上抛 - 未知 action 返回
{code: 99999999, msg: "未知 action: xxx"}
HTTP 约定
- 所有 action 均走 POST,路径形如
/wf/{action}(各集成框架示例见集成指南) - body 为 JSON 对象(
Content-Type: application/json) - 登录鉴权由集成方框架层完成(token/会话),门面本身不感知登录态
2. 全局约定
2.1 统一响应
| code | 含义 |
|---|---|
| 0 | 成功 |
| 99999999 | 业务失败(msg 为原因) |
| 其他 | 集成方框架层错误(未登录 401、无权限 403 等,由框架自身返回) |
2.2 分页结构(page 类 action 的 data)
json
{
"pageNum": 1,
"pageSize": 10,
"recordCount": 25,
"totalPage": 3,
"rows": [ ... ]
}pageNum从 1 起;pageSize默认 10- 查询参数:
pageNum/pageSize/orderBy(如"t.create_time desc") - 过滤参数:
m_前缀三段式m_{别名}_{操作符}_{列名},别名省略时默认主表t, 列名 camelCase 自动转 snake_case,操作符大写:
| 形式 | 示例 | 含义 |
|---|---|---|
m_{op}_{column} | m_EQ_taskName=leaveApply | 主表 t.task_name = 'leaveApply' |
m_{alias}_{op}_{column} | m_t_LIKE_displayName=请假 | t.display_name LIKE '%请假%' |
m_pd_{op}_{column} | m_pd_LIKE_name=simple | 实例列表按流程定义搜:pd.name LIKE '%simple%'(别名 pd → 关联的流程定义表,白名单列 pd.name / pd.display_name / pd.version) |
| 操作符 | EQ LIKE GT LT GE LE IN … | 标准 SQL 语义 |
实例列表(
processInstance/page)支持m_pd_*别名按流程定义维度过滤(前端"编码"搜索走m_pd_LIKE_name,"名称"搜索走m_pd_LIKE_displayName);任务列表走m_t_*(t= 任务表)。 六语言内存/持久仓储都须解析pd./t.别名到对应行键(PHP 内存仓储此前只剥别名按裸键取、 与 camelCase 行键失配,已补齐对齐 Java in-memory 的pd.*/t.*白名单映射;Rust 在 facadeparse_m_params解析m_{alias}_{op}_{col})。
2.3 id 字符串契约(重要)
- 引擎 id(流程定义/实例/任务/设计 id)为雪花算法 64 位整数,JS 中超过
2^53会丢精度 - 六语言出口一律保证 id 为字符串:Java 集成层
ToStringSerializer、Node 全链路 string、 Go/Python 出口stringifyIDs、PHP 出口字符串化 转换、Rust facade 出口stringify_ids(递归处理嵌套对象/数组) - 嵌套对象同样适用:列表/嵌套行(
processDesign/detail的his[]、processInstance/detail的tasks[]/activeTaskList[]等)的id/*Id键 与顶层同契约(教训:Python dataclass 列表曾绕过出口 hook 以 int 外泄) - 前端一律把 id 当字符串处理(不做数值运算、不 parseInt);提交时传字符串或数字均可 (引擎统一 toLong 容错)
- Java 宿主集成硬要求:jeeflow-java starter 只向引擎内部 JSON(bizData/ext 存储)注入
Long→ToStringSerializer,不向宿主 Web 层注入。宿主必须自行配置全局Long.class/long字符串序列化(mldong-boot2/3/4 的WebMvcConfig已配; 其他宿主如裸 Spring Boot 需自查,否则雪花 id 以 JSON number 下发丢精度)
2.4 时间格式
- 一律
yyyy-MM-dd HH:mm:ss(如2026-08-06 10:30:00) - 空值返回
null
2.5 operator 约定(操作人)
门面不感知登录态,
args.operator显式传入(demo 风格默认user1)集成方必须覆盖:从登录上下文注入当前用户 id(如
body["operator"] = current_user.id)涉及"我的"语义的 action(
processInstance/page、todoList、doneList、ccList) 依赖 operator 过滤,字段口径已写死(对齐 javaJeeflowFacade,各语言仓储按此实现,不许偏宽/偏窄):action 过滤列 语义 processInstance/paget.operator EQ operator我发起的实例(实例 operator 即发起人) processTask/todoListactor_ids contains operator 我参与(未办结) processTask/doneListt.operator EQ operator我办理的——不含发起人 create_user,"我发起但非我办理"不算我的已办processInstance/ccListcc.actor_id EQ operator抄送给我的(抄送行接收人)
2.6 鉴权与权限码
- 引擎不依赖任何鉴权框架,只通过
IActionPermissionProviderSPI 提供 「action → 权限码」映射元数据,校验由集成方框架层完成(如StpUtil.checkPermissionOr) - 默认映射规则:
wf:{action.replace('/', ':')},例如processDefine/page→wf:processDefine:page - 部分 action 为 OR 语义(任一持有即可):
processDefine/detail→wf:processDefine:detail或wf:processDesign:listByType;processTask/candidatePage→wf:processTask:execute或wf:processTask:candidatePage - 无注解的只读/轻量 action 登录即可访问(放行):
processInstance/detail、highLight、approvalRecord、bizData、processTask/detail、addCandidate、latest、getAssigneeTextData、processInstance/stats/overview、stats/trend、stats/group(统计只读,全部登录用户可访问)等 - 集成方惯例:超级管理员(如 mldong
superAdmin)放行一切权限 - 集成方校验示例:
java
private void checkPermission(String action) {
LoginUser loginUser = LoginUserHolder.me();
if (loginUser != null && loginUser.isSuperAdmin()) return; // 超管万能
IActionPermissionProvider provider = ServiceContext.find(IActionPermissionProvider.class);
String[] codes = provider == null ? null : provider.permissionCodes(action);
if (codes != null && codes.length > 0) {
StpUtil.checkPermissionOr(codes);
}
}2.7 表单数据约定
| 前缀 | 位置 | 含义 |
|---|---|---|
f_ | 发起参数 / 实例变量 | 发起表单字段(f_amount、f_reason…) |
tf_ | 任务执行参数 / 任务变量 | 任务表单字段(tf_approvalComment 审批意见、tf_approvalAttachment 审批附件、tf_nextNodeOperator 下一节点执行人、tf_ccActors 抄送人) |
- 实例/任务行中
ext字段 = 对应变量 JSON 对象;taskFormData= 带tf_前缀的字段 (同时输出带前缀 + 去前缀两个副本,前端可直接取值) - 发起时
f_nextNodeOperator:发起人预指派的下一节点执行人(执行时自动转tf_nextNodeOperator)
2.8 submitType(执行类型,processTask/execute 用)
| code | 枚举 | 语义 | 引擎方法 |
|---|---|---|---|
| 0 | APPLY | 发起申请 | executeProcessTask |
| 1 | AGREE | 同意 | executeProcessTask |
| 2 | REJECT | 拒绝(流程直接结束) | executeAndJumpToEnd |
| 3 | ROLLBACK | 退回上一步 | executeAndJumpTask(target=null) |
| 4 | JUMP | 跳转到指定节点(需 taskName) | executeAndJumpTask(target=taskName) |
| 5 | RE_APPLY | 重新提交(业务方语义,透传) | executeProcessTask |
| 6 | ROLLBACK_TO_OPERATOR | 退回发起人 | executeAndJumpToFirstTaskNode |
| 20 | COUNTERSIGN_DISAGREE | 会签拒绝:门面自动置 countersignDisagreeFlag=1。默认软拒绝(该成员任务正常完成、flag 记录为流程变量供下游参考、流程不阻断);仅当节点 countersignCompletionCondition=ONE_VOTE_VETO 时才一票否决直接推进整单 | executeProcessTask |
2.9 状态枚举
任务状态 taskState
| code | 含义 |
|---|---|
| 10 | DOING 进行中 |
| 20 | FINISHED 已完成 |
| 30 | WITHDRAW 已撤回 |
| 40 | INTERRUPT 强行终止 |
| 50 | PENDING 挂起 |
| 99 | ABANDON 已废弃 |
实例状态 state(同上枚举,30 撤回 / 40 终止)
参与方式 performType
| code | 含义 |
|---|---|
| 0 | NORMAL 普通参与(多人任一完成即可) |
| 1 | COUNTERSIGN 会签(每人独立任务,全部完成才驱动下一步) |
兼容性:Java
codeOf语义接受字符串'1'/'ALL'/'COUNTERSIGN'表示会签, 前端提交字符串或数字均可。
定义状态 state(processDefine):1 启用 / 0 停用(upAndDown 切换)
设计部署状态 isDeployed(processDesign):1 已部署 / 0 未部署
2.10 抄送(CC)
- 发起抄送:
startAndExecute参数带f_ccActors(用户 id 数组)→ 自动创建抄送实例 - 任务中抄送:
execute参数带tf_ccActors(用户 id 数组) - 手动抄送:
processInstance/createCCInstance(抄送人可在ccList查看)
3. action 清单(40+ 个)
| 分组 | action | 需要扩展仓储 |
|---|---|---|
| 流程定义 | processDefine/page detail startAndExecute deploy redeploy remove upAndDown | 否 |
| 流程实例 | processInstance/page detail startAndExecute withdraw bizData | bizData 需 persist |
| 流程任务 | processTask/todoList doneList execute detail jumpAbleTaskNameList candidatePage surrogate addCandidate latest | 否 |
| 流程设计 | processDesign/page detail save update updateDefine remove deploy redeploy listByType | 是(IProcessExtRepository) |
| 委托代理 | processSurrogate/page save update detail remove | 是 |
| 视图端点 | processDefine/getLastByName processInstance/highLight approvalRecord getAssigneeTextData createCCInstance updateCCStatus ccList | createCCInstance/updateCCStatus/ccList 需抄送表 |
| 统计 | processInstance/stats/overview stats/trend stats/group | 否(纯查询,全语言同批) |
未配置
IProcessExtRepository时,processDesign/*、processSurrogate/*报错; 未注册metaTableReader(jeeflow-persist)时bizData明确报错。
4. action 详解
通用:每个 action 的 body 均可带
operator(见 2.5);所有返回包在{code, msg, data}内。左侧菜单已按接口名列出全部 action(4.1~4.6 分组),点击直达。
4.1 流程定义 processDefine/*
processDefine/page — 流程定义分页
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| pageNum/pageSize/orderBy/m_* | 否 | - | 分页与过滤(2.2) |
data → 分页结构,rows 行字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 定义 id |
| name | string | 流程标识名(唯一,deploy 版本管理键) |
| displayName | string | 显示名 |
| type | string | 流程类型(如 approval/leave) |
| state | int | 1 启用 / 0 停用 |
| version | int | 版本号(同 name 从 0 递增) |
| createTime/createUser/updateTime/updateUser | - | 审计字段 |
processDefine/detail — 定义详情
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 定义 id |
data:
| 字段 | 类型 | 说明 |
|---|---|---|
| id/name/displayName/type/state/version | - | 同 page 行 |
| jsonObject | object | 流程 JSON 图(LogicFlow 模型,前端渲染流程图/表单依赖) |
processDefine/startAndExecute — 发起并执行(自动完成申请节点)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processDefineId | 是 | string | 定义 id |
| operator | 是 | string | 发起人 |
| f_* | 否 | any | 发起表单数据(业务字段) |
| f_nextNodeOperator | 否 | string | 预指派的下一步执行人 |
| f_ccActors | 否 | string[] | 发起抄送人 |
语义:启动实例 → 自动完成申请节点(assignee=applicant 映射为发起人)→ 流转到第一个审批节点。 data → { "processInstanceId": "..." }
processDefine/deploy — 发布流程定义
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| (流程 JSON 顶层展开) | 是 | object | 流程 JSON 字段直接平铺请求体(name/displayName/type/nodes/edges…)——vben5 前端约定 |
| content | 兼容 | string|object | 引擎兼容写法:整体塞进 content 字段(字符串或对象均可) |
语义:入参 JSON → ModelParser 解析出 name/displayName/type → 按 name 查最新 define: 存在则 version+1 插新记录,不存在则新记录(version 从 0 起)。 data → { "processDefineId": "..." }
processDefine/redeploy — 重新发布(原地替换内容)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processDefineId | 是 | string | 定义 id |
| (流程 JSON 顶层展开) | 是 | object | 同 deploy:流程 JSON 平铺请求体 |
| content | 兼容 | string|object | 引擎兼容写法 |
data → null(成功空)
processDefine/remove — 删除定义
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 二选一 | string | 单删 |
| ids | 二选一 | string[] | 批量删 |
data → null
processDefine/upAndDown — 启停定义
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 二选一 | string | 单个启停 |
| ids | 二选一 | string[] | 批量启停 |
| state | 是 | int | 1 启用 / 0 停用 |
| opType | 是 | int | 与 state 同义(boot3 前端惯例,二者取一) |
data → null
4.2 流程实例 processInstance/*
processInstance/page — 我发起的实例分页
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| operator | 是 | string | 过滤"我发起"(t.operator = operator,实例发起人;见 §2.5 口径表) |
| pageNum/pageSize/orderBy/m_* | 否 | - | 分页与过滤 |
data → 分页结构,rows 行字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 实例 id |
| parentId | string|null | 子流程的父实例 id |
| processDefineId | string | 定义 id |
| state | int | 实例状态(2.9) |
| businessNo | string | 业务编号 |
| operator | string | 发起人 id |
| processDefineName/processDefineDisplayName/processDefineVersion | - | 定义冗余 |
| displayName/version | - | 定义显示名/版本(简写冗余) |
| variable | object | 实例变量 JSON |
| ext | object | 实例变量(含 f_* 表单数据) |
| createTime/createUser/updateTime/updateUser/expireTime | - | 审计/到期 |
processInstance/detail — 实例详情
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 实例 id |
data:
| 字段 | 类型 | 说明 |
|---|---|---|
| id/parentId/processDefineId/state/parentNodeName/businessNo/operator | - | 同 page 行 |
| variables | object | 实例变量全量 |
| formData | object | f_* 表单字段(带前缀+去前缀副本) |
| displayName/name/version | - | 定义信息 |
| jsonObject | object | 流程 JSON 图 |
| tasks | task[] | 全量任务列表,每行含 ext(含 isFirstTaskNode:进行中且为申请节点 → 前端可"重新提交") |
| activeTaskList | task[] | 仅 DOING 的任务(tasks 的子集) |
task 行结构(详情/列表通用,见 4.3 taskVo)。
processInstance/startAndExecute — 同 processDefine/startAndExecute
processInstance/withdraw — 撤回
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 实例 id |
| operator | 是 | string | 撤回人 |
语义:仅发起人/当前处理人可撤回;实例与全部进行中任务置为 WITHDRAW(30)(级联持久化)。 data → null
processInstance/bizData — 业务数据回显(需 jeeflow-persist)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processInstanceId | 是 | string | 实例 id(id 亦可) |
语义:按流程定义顶层 relTableName(缺省回落 name)定位业务表, MetaTableReader.readByProcessInstance 读取该实例的业务数据。 data → 业务行对象(结构由业务表决定)。
processInstance/stats/overview — 指标卡统计
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| start / end | 否 | string | yyyy-MM-dd HH:mm:ss,按实例 create_time 限定;空 = 不限该边界 |
| stateIn | 否 | int[] | 限定统计的实例状态;缺省 [10,20,30,40,45,50](剔除 99 废弃) |
权限:登录即可(2.6 放行清单),不配权限码。
data(全局口径,不带 operator 过滤;个人视角数字仍走 todoList/doneList 等分页接口的 recordCount):
| 字段 | 类型 | 口径 |
|---|---|---|
| total / inProgress / completed / rejected / withdrawn / suspended | int | 实例按 state 计数(10/20/45/30/50) |
| todayNew | int | create_time 在服务器当日的实例数(恒按当天,不受 start/end 影响) |
| avgDurationSeconds | int | 已完成(state=20)实例平均时长(秒):MAX(task.finish_time) - instance.create_time |
| rejectRate | float | rejected / max(1, completed + rejected) |
| pendingTaskCount | int | 全系统进行中任务数(task_state=10,不受 stateIn 影响) |
| overdueTaskCount | int | 逾期未办任务数(task_state=10 AND expire_time IS NOT NULL AND expire_time < now) |
| countersignRate | float | 会签占比:perform_type=1 的已完成任务 / 全部已完成任务 |
| onTimeRate | float | 及时办结率:finish_time <= expire_time 的已完成任务 / expire_time 非空的已完成任务 |
expire_time未填充的数据源:overdueTaskCount=0、onTimeRate=0(非错误,前端隐藏对应卡)。 全部指标只用纯列,不读variableJSON(v1.1 决策:不做 JSON 提取,六语言零方言分叉)。
processInstance/stats/trend — 时间趋势
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| start / end | 是 | string | yyyy-MM-dd HH:mm:ss |
| granularity | 是 | string | hour / day / week / month |
data → 数组(连续桶,无数据桶补 0,按 start→end 枚举;hour 建议跨度 ≤31 天,超限不报错):
jsonc
[{ "bucket": "2026-08-01", "started": 12, "finished": 8 }]started:实例create_time落在该桶(发起量);finished:任务finish_time落在该桶且task_state=20(办结量)bucket格式:hour=yyyy-MM-dd HH:00、day=yyyy-MM-dd、week=yyyy-'W'ww(ISO 周)、month=yyyy-MM- 两序列来源不同表,各自分桶后按 bucket 对齐合并(非 join)
processInstance/stats/group — 维度分组
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| dimension | 是 | string | 枚举见下表(9 个,全纯列) |
| start / end | 否 | string | 按创建/完成时间限定;stuckNode/stuckApprover 为实时快照,忽略 start/end |
| limit | 否 | int | 默认 10,按 count 降序取 Top N |
data → 数组(按 count 降序):
jsonc
[{ "key": "leaveApply", "label": "请假流程", "count": 42, "avgDurationSeconds": 57600 }]| dimension | 分组键 | 说明 |
|---|---|---|
state | instance.state | 状态分布;label 可空,前端走字典 wf_process_instance_state |
define | join define(key=编码 name,label=display_name) | 流程 Top N;含 avgDurationSeconds |
category | define.type | 流程分类分布 |
approver | task.operator(task_state=20) | 审批人历史办结量;key=用户 id,label 可空(前端查用户表) |
applicant | instance.operator | 发起人分布 |
node | task.display_name(task_state=20) | 节点平均耗时(avg=finish_time - create_time 均值) |
stuckNode | task.display_name(task_state=10) | 当前积压节点(实时快照,count=在办任务数) |
stuckApprover | task_actor.actor_id(join task_state=10 任务) | 当前积压人(实时快照;进行中任务 operator 无值,必须走 actor 表;会签每 actor 一行,count=该人在办任务数) |
durationBucket | 完成实例时长分桶 | key 固定 sameDay / 1to3d / 3to7d / over7d 四桶(无数据补 0) |
- 不支持的
dimension值返回code!=0明确错误(不静默空数组) - 语义区分:
approver(历史办结)vsstuckApprover(当前在办);node(历史耗时)vsstuckNode(当前在办) - 出参中一切 id 为字符串(2.3)
4.3 流程任务 processTask/*
taskVo(任务详情/列表通用行)字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 任务 id |
| processInstanceId | string | 实例 id |
| taskName | string | 节点名(模型节点 id) |
| displayName | string | 节点显示名 |
| taskType | string | 任务类型(task/start 等) |
| performType | int | 0 普通 / 1 会签 |
| taskState | int | 状态(2.9) |
| operator | string | 当前操作人 id |
| formKey | string | 表单 key |
| taskParentId | string | 父任务 id(会签/子流程) |
| taskActorIdList | string[] | 参与人列表 |
| taskFormData | object | tf_* 任务表单数据(带前缀+去前缀副本) |
processTask/todoList — 我的待办
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| operator | 是 | string | 过滤"我的待办" |
| pageNum/pageSize/m_* | 否 | - | 分页过滤 |
data → 分页结构,rows = taskRow(在 taskVo 基础上增加): finishTime/expireTime/variable/createTime/createUser/updateTime/updateUser、 processDefineName/processDefineDisplayName/version、 instanceVariable/instanceCreateTime、instanceExt(实例变量)、 ext(任务变量,为空时回退实例变量)、taskFormData。
processTask/doneList — 我已办
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| operator | 是 | string | 过滤"我已办"(t.operator = operator,任务办理人;不含发起人 create_user,"我发起但非我办理"不算我的已办;见 §2.5 口径表) |
| pageNum/pageSize/m_* | 否 | - | 分页过滤 |
data → 分页结构,rows 同 todoList。
processTask/execute — 执行任务(核心)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processTaskId | 是 | string | 任务 id |
| operator | 是 | string | 执行人 |
| submitType | 是 | int | 2.8 执行类型(默认 1 AGREE) |
| taskName | 条件必填 | string | submitType=4 JUMP 时目标节点名(jumpAbleTaskNameList 获取) |
| tf_* | 否 | any | 任务表单数据(审批意见 tf_approvalComment、附件 tf_approvalAttachment、抄送 tf_ccActors、预指派 tf_nextNodeOperator) |
| countersignDisagreeFlag | 否 | int | 会签拒绝(submitType=20)时 1 = 已记录该成员反对(门面自动注入;仅当节点 countersignCompletionCondition=ONE_VOTE_VETO 才直接推进整单,否则软拒绝不阻断) |
分发逻辑见 2.8 表。data → null
processTask/detail — 任务详情
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 任务 id |
| operator | 是 | string | 判断 executable |
data = taskVo 基础上增加:
| 字段 | 类型 | 说明 |
|---|---|---|
| executable | boolean | 当前 operator 是否可执行 |
| ext | object | 任务变量对象(为空时回退实例变量),必含 isFirstTaskNode |
| jsonObject | object | 流程 JSON 图(前端渲染表单) |
| taskModel | object | {name, displayName, type, form?, ext?} 节点模型信息;ext = 节点 properties.field 原样透传(含 PERMISSION_* 字段权限,前端 initPermission 依据,与 boot2 setTaskModel 一致);form = 节点表单 key |
ext.isFirstTaskNode(六语言必出):当且仅当该任务taskName为流程 JSON 中第一个snaker:task节点 id(首任务节点)且任务处于 DOING 时为true,否则false。语义与processInstance/detail的tasks[]/activeTaskList[]行的ext.isFirstTaskNode一致——前端process-task/detail.vue:61双兜底record.isFirstTaskNode || record.ext?.isFirstTaskNode,据此在详情抽屉对首任务节点 DOING 时开放"重新提交"。task detail 与 instance detail 两条出口都须提供(此前仅 instance detail 提供,task detail 缺,已补齐对齐)。
processTask/jumpAbleTaskNameList — 可跳转节点列表
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processInstanceId | 是 | string | 实例 id |
data → [{ "label": "节点显示名", "value": "节点名" }](已走过的非会签节点)
processTask/candidatePage — 候选处理人
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processTaskId | 是 | string | 任务 id(id 亦可) |
模型候选命中(节点配置
candidateUsers等)→ 分页 rows,行契约(六语言统一):键 必有 说明 id是 行主键,取 src. id→ src.userId→ actorId(字符串化),供前端valueField:'id'取值realName是 显示名,取 src. realName,缺省回落iduserId兼容 src 含 userId时保留(对齐旧消费方)userName可选 src 含时透传 deptName可选 src 含时透传(IUserProvider.getUser 子路径可得) 用户信息映射优先级:IUserSearchProvider.findById → IUserProvider.getUser(realName/deptName 可得时透传)→ 兜底
{id: actorId, realName: actorId}。无模型候选 → 走 IUserSearchProvider 用户分页搜索(需集成方注入,query 透传 m_* 条件); 未注入明确报错
processTask/surrogate — 转办/加人
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processTaskId | 是 | string | 任务 id |
| actorIds | 是 | string[]|string | 新增参与人(数组或逗号分隔字符串) |
语义:为任务追加参与人(普通任务追加后任一完成即可;会签任务追加为额外会签任务)。 data → null
processTask/addCandidate — 同 surrogate
processTask/latest — 实例当前进行中任务
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processInstanceId | 是 | string | 实例 id |
data → taskVo(第一个 DOING 任务)或 null
4.4 流程设计 processDesign/*(需 IProcessExtRepository)
设计稿(草稿)≠ 定义(发布产物):save/updateDefine 存草稿快照(历史表), deploy 才生成流程定义。设计稿内容变更后 isDeployed 自动置 0(防误用旧定义)。
processDesign/page — 设计分页
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| pageNum/pageSize/m_* | 否 | - | 分页过滤 |
data → 分页结构,rows 行字段:id, name, displayName, type, icon, isDeployed, remark, createTime, createUser, updateTime, updateUser(时间字段格式 yyyy-MM-dd HH:mm:ss,见 §2.4)
processDesign/detail — 设计详情
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 设计 id |
data:id, name, displayName, type, icon, isDeployed, remark + jsonObject(最新设计稿内容,缺失基本信息时从设计表补齐 name/displayName/type/processDesignId)
his(历史快照列表)
processDesign/save — 新建/保存设计(含草稿内容)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 否 | string | 有 = 更新基本信息;无 = 新建 |
| name/displayName | 新建必填 | string | 名称 |
| type | 否 | string | 类型(默认 approval) |
| icon/remark | 否 | string | 图标/备注 |
| content | 否 | string|object | 设计稿 JSON(有则存历史快照,并置未部署) |
data → { "id": "设计 id" }
processDesign/update — 只改基本信息(不写快照)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 设计 id |
| name/displayName/type/icon/remark | 否 | string | 仅传要改的字段 |
data → null
processDesign/updateDefine — 保存设计稿(设计器保存)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processDesignId | 是 | string | 设计 id |
| (设计稿 JSON 顶层展开) | 是 | object | 设计稿 JSON 字段平铺请求体(name/displayName/type/nodes/edges…)——vben5 前端约定 |
| content | 兼容 | string|object | 引擎兼容写法:整体塞进 content 字段 |
语义:快照入库(与最新相同则不重复存)+ 同步 name/displayName/type + 置未部署。 data → null
processDesign/remove — 删除设计
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 二选一 | string | 单删 |
| ids | 二选一 | string[] | 批量删 |
data → null
processDesign/deploy — 设计发布(生成流程定义)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 设计 id |
语义:取最新快照 → 生成流程定义(版本管理同 deploy)→ 设计置已部署。 data → { "processDefineId": "..." }
processDesign/redeploy — 设计重新发布(原地替换定义)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 设计 id |
语义:取最新快照 → 按 name 找最新定义:有则原地替换内容(version 不变),无则新建。 data → { "processDefineId": "..." }
processDesign/listByType — 按类型分组(发起申请页数据源)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| - | - | - | 无参数 |
data → { type: [item, ...] },item:
| 字段 | 类型 | 说明 |
|---|---|---|
| processDesignId | string | 设计 id |
| name/displayName/icon/remark | string | 设计信息 |
| processDefineId | string|null | 该 name 最新已发布定义 id(未发布为 null) |
| processDefineState | int|null | 定义状态,六语言必出:取该 name 最新定义的 state(1 启用 / 0 禁用,未发布为 null)。前端"发起申请"卡片以 items[].processDefineState !== 0 控制发起按钮可用性——定义被 upAndDown 禁用(state=0)时不可发起,该键是发起流程的硬依赖 |
| jsonObject | object | 最新设计稿(设计器回显) |
分组序契约(2026-08-31 补)
- map 形态遍历序不作保证:
data为 map({ type: [items] })时,六语言引擎用不同分组容器 (javaLinkedHashMap/ gomap/ pythondict/ nodeobject/ phparray/ rustserde_json::Map=BTreeMap), map 的 key 遍历序由各语言容器与原生序列化行为偶然决定,引擎不作契约保证(六引擎本体各自确定, 但序语义实为四种:id 首现 / 数字升序 / type·字典序 / 种子序)。消费端(集成层)把 map 转有序数组时, 必须按下述契约序自行排序,不得依赖引擎 map 遍历序。 - 有序数组分组序 = type 数值优先升序:type 可解析为整数时按数值升序;不可解析为整数时按字符串升序; 数值型 type 排在前、非数值型 type 排在后。例:
["1","2","6"]→1 > 2 > 6;["1","a","10"]→1 > 10 > a。 该序由集成层 map→array 转换处保证(八套集成层统一实现),前端不再排序(vben 保持不排序、依赖本契约; App 保留既有sortGroupsByType作展示兜底,与本契约一致)。 - 组内 items 序 = 引擎行序,保持现状:jdbc 路径均为
ORDER BY id DESC(最新设计在前),六语言一致、稳定,契约保持。
4.5 委托代理 processSurrogate/*(需 IProcessExtRepository)
processSurrogate/page — 委托分页
data → 分页结构,rows 行字段:id, processName, operator(授权人), surrogate(被委托人), startTime, endTime, enabled(1启用/0停用), createTime, createUser, updateTime, updateUser
processSurrogate/save — 新建委托
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processName | 是 | string | 委托的流程名(空 = 全部流程) |
| surrogate | 是 | string | 被委托人 id |
| startTime/endTime | 是 | string | 生效时间段(yyyy-MM-dd HH:mm:ss) |
| enabled | 否 | int | 1 启用 / 0 停用(默认 1) |
data → { "id": "..." }
新建时授权人(operator)默认取操作人。编辑走独立的
processSurrogate/update。
processSurrogate/update — 更新委托
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 委托 id |
| processName | 是 | string | 委托的流程名(空 = 全部流程) |
| surrogate | 是 | string | 被委托人 id |
| startTime/endTime | 是 | string | 生效时间段(yyyy-MM-dd HH:mm:ss) |
| enabled | 否 | int | 1 启用 / 0 停用(默认 1) |
data → { "id": "..." };id 不存在报 99999999(msg 委托记录不存在)。
授权人(operator)在请求缺省时保留原值——前端编辑表单不带 operator,若按 save 语义取操作人会把授权人改掉。
processSurrogate/detail — 委托详情
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 委托 id |
data → 单条委托行:id, processName, operator(授权人), surrogate(被委托人), startTime, endTime, enabled, createTime, createUser, updateTime, updateUser (时间字段格式化 yyyy-MM-dd HH:mm:ss);id 不存在报 99999999(msg 委托记录不存在)。
processSurrogate/remove — 删除委托
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| ids | 二选一 | string[] | 批量删(前端 IdsParam 惯例,行内删除也发长度 1 的数组) |
| id | 二选一 | string | 单删(兼容形态) |
data → null
ids与id均缺失或为空数组时报99999999,不得返回成功(:PHP 曾把空串绑进DELETE ... WHERE id = '',删 0 行仍回code=0,前端提示"删除成功"而记录仍在)。 本条与processDefine/remove、processDesign/remove的批量语义同源,见 §7「批量入参」。
4.6 视图端点
processDefine/getLastByName — 按名取最新定义
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processDefineName | 是 | string | 流程名 |
data → {id, name, displayName, type, state, version};不存在报错。
processInstance/highLight — 流程图高亮(含节点成员进度)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 实例 id |
data:
| 字段 | 类型 | 说明 |
|---|---|---|
| activeNodeNames | string[] | 活跃节点(进行中任务节点) |
| historyNodeNames | string[] | 历史节点(已完成 + 模型路径补全) |
| historyEdgeNames | string[] | 历史边(决策分支已求值过滤,未走的分支不高亮) |
| nodeProgress | object | 节点成员进度 {节点名: {members: [...], type?}} |
nodeProgress 成员结构:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 用户 id |
| name | string | 用户姓名(IUserProvider SPI 解析,查不到为空串,前端降级显示 id) |
| done | boolean(仅命中) | 该成员已完成 |
| active | boolean(仅命中) | 该成员进行中(当前位) |
type:会签节点带 PARALLEL / SEQUENTIAL;动态参与人(无静态成员)节点不返回。
processInstance/approvalRecord — 审批记录
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 实例 id |
data → rows:
| 字段 | 类型 | 说明 |
|---|---|---|
| taskName/displayName | string | 节点 |
| taskType | string | 任务类型 |
| performType | int | 0 普通 / 1 会签 |
| taskState | int | 任务状态 |
| operator | string | 处理人 id |
| finishTime | string | 完成时间 |
| variable | object | 任务变量(含审批意见等) |
| ext | object | 同 variable(冗余兼容) |
processInstance/getAssigneeTextData — 当前处理人(发起页"我的待处理"徽标)
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| id | 是 | string | 实例 id |
| includeNodeName | 否 | boolean | label 是否带节点名(默认 true) |
data → [{ "value": "用户id", "label": "节点显示名:用户id" }]
processInstance/createCCInstance — 手动抄送
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processInstanceId | 是 | string | 实例 id |
| actorIds | 是 | string[] | 抄送人数组(非空) |
| operator | 是 | string | 操作人 |
data → null
processInstance/updateCCStatus — 抄送已读
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| processInstanceId | 是 | string | 实例 id |
| operator | 是 | string | 抄送人(标记自己已读) |
data → null
processInstance/ccList — 抄送我的
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| operator | 是 | string | 过滤"抄送我的"(cc.actor_id = operator,抄送行接收人;见 §2.5 口径表) |
| pageNum/pageSize/m_* | 否 | - | 分页过滤 |
data → 分页结构,rows 同 processInstance/page 行结构。
5. 请求/响应示例
发起请假流程
json
// POST /wf/processInstance/startAndExecute
{
"processDefineId": "1864123456789012480",
"operator": "zhangwei",
"f_reason": "年假回乡",
"f_days": 5,
"f_startDate": "2026-08-10",
"f_nextNodeOperator": "lina",
"f_ccActors": ["chenjing"]
}json
// 200
{ "code": 0, "msg": "成功", "data": { "processInstanceId": "1864123456789012999" } }待办列表
json
// POST /wf/processTask/todoList
{ "operator": "lina", "pageNum": 1, "pageSize": 10 }json
// 200
{
"code": 0, "msg": "成功",
"data": {
"pageNum": 1, "pageSize": 10, "recordCount": 1, "totalPage": 1,
"rows": [{
"id": "1864123456789013111",
"processInstanceId": "1864123456789012999",
"taskName": "node_1", "displayName": "部门审批",
"taskType": "task", "performType": 0, "taskState": 10,
"operator": "lina", "formKey": null, "taskParentId": null,
"ext": { "tf_approvalComment": null, "f_reason": "年假回乡" },
"taskFormData": { "tf_approvalComment": null, "approvalComment": null },
"processDefineName": "leave", "processDefineDisplayName": "请假流程", "version": 0,
"createTime": "2026-08-06 09:30:00"
}]
}
}审批
json
// POST /wf/processTask/execute
{
"processTaskId": "1864123456789013111",
"operator": "lina",
"submitType": 1,
"tf_approvalComment": "同意,注意行程安全",
"tf_nextNodeOperator": "wangqiang",
"tf_ccActors": ["zhaomin"]
}json
// 200
{ "code": 0, "msg": "成功", "data": null }跳转(submitType=4)
json
// POST /wf/processTask/jumpAbleTaskNameList
{ "processInstanceId": "1864123456789012999" }
// → data: [{"label":"部门审批","value":"node_1"},{"label":"总经理审批","value":"node_2"}]
// POST /wf/processTask/execute
{ "processTaskId": "1864123456789013111", "operator": "lina", "submitType": 4, "taskName": "node_2" }错误示例
json
// HTTP 200,以 body code 判断业务成败
{ "code": 99999999, "msg": "流程定义不存在", "data": null }6. 集成方需要实现的 SPI
| SPI | 必选 | 说明 |
|---|---|---|
| IProcessRepository | 是 | 流程定义/实例/任务/抄送仓储(引擎提供 JDBC 默认实现) |
| IProcessExtRepository | 设计/委托 action 必选 | 设计稿、委托仓储 |
| IUserProvider | 否(建议) | 用户信息解析(nodeProgress 姓名、候选映射);未注册姓名降级为 id |
| IUserSearchProvider | candidatePage 用户搜索 | 用户分页搜索 + 单用户查询 |
| IActionPermissionProvider | 否(引擎内置默认) | action → 权限码映射 |
| metaTableReader | bizData | 业务数据读取(jeeflow-persist 提供) |
各语言注入位置:Java 构造器/ServiceContext;Go facade.New 参数/字段;Python/Node 构造参数。
7. 六语言行为对齐说明
| 关注点 | 约定 |
|---|---|
| id 出口 | 一律字符串(Node 全链路 string;Go/Python stringifyIDs;Java 集成层 ToStringSerializer;PHP 出口字符串化;Rust facade stringify_ids) |
| performType | 接受数字或字符串 '1'/'ALL'/'COUNTERSIGN' |
| 时间 | yyyy-MM-dd HH:mm:ss 字符串 |
| 分页 | {pageNum, pageSize, recordCount, totalPage, rows} |
| 批量入参 | 删除/启停类 action(processDefine/remove upAndDown、processDesign/remove、processSurrogate/remove)统一 {ids} 数组优先、单 {id} 兼容——前端按 mldong IdsParam 惯例只发 ids;ids/id 缺失或空数组一律报错,禁止静默成功 |
| 响应 | {code, msg, data} |
| 撤回 | 实例 + 全部进行中任务同步置 WITHDRAW(级联持久化) |
| 发起抄送 | f_ccActors;任务抄送 tf_ccActors |
| 动态参与人 | 未配置静态候选时,nodeProgress 不返回该节点(成员未知) |