> **前置条件** — 执行以下任何命令前，请先确认已完成认证。如未认证，参见 [`../../shb-shared/SKILL.md`](../../shb-shared/SKILL.md)。

# shb-cli paas flow

**流程是什么**:表单开启流程后,每条数据记录(`content-biz-id`)按流程图的节点逐步流转;每个节点上有若干按钮(提交/同意/驳回/回退等),点按钮即推进流程。本文档覆盖:流程定义查看、流转状态追踪、按钮查询、审批推进、催办/撤回/会签/转交、流程部署与版本管理。

## 命令速查(先选对命令)

| 想做什么 | 用哪条命令 |
|---------|-----------|
| 看流程定义(节点/连线长什么样) | `flow get` |
| 看某条记录流转到哪个节点、谁处理过 | `flow log` / `flow log-progress` |
| 看某条记录当前节点能点哪些按钮 | `flow buttons` |
| 推进流程(点按钮/审批) | 优先 `form finish-content`(见 form 文档);`flow approve` 是同一动作的底层入口 |
| 给已保存的表单记录开启流程 | `flow start`(或 `form start-content` 一步完成保存+开启) |
| 催当前处理人办理 | `flow urge` |
| 把已流出的任务撤回给自己 | `flow back-to-me` |
| 给当前节点加会签人 | `flow countersign` |
| 把 A 的在办任务批量转给 B | `flow batch-transfer` |
| 暂停 / 恢复某条流程实例 | `flow pause` / `flow resume` |
| 修改并发布流程图 | `flow deploy`(新建) / `flow redeploy`(重发布) |
| 查看/启用流程版本 | `flow version list/current/enable/...` |

## 只读命令

```bash
# 流程定义:该表单的流程图(节点、连线、条件)
shb-cli paas flow get --app-id <app-id> --form-template-id <form-template-id>

# 流转日志:每个节点谁在什么时间做了什么,含当前节点(isCurrent: true)和 nodeInstanceId
shb-cli paas flow log --content-biz-id <content-biz-id>

# 进度视图:同上但按进度条口径,适合"走到哪一步了"
shb-cli paas flow log-progress --content-biz-id <content-biz-id>

# 纯表单日志(外链场景加 --outlink 1)
shb-cli paas flow log-pure-form --content-biz-id <content-biz-id>

# 当前节点可用按钮:返回每个按钮的 cnName(中文名)、enName、code,以及当前任务标识
shb-cli paas flow buttons --content-biz-id <content-biz-id>
```

> `--app-id` 与 `--form-template-id` 来自 `paas app forms` 结果里的 `appId` 与 `bizId`(bizId 即表单 id);`--content-biz-id` 是某条数据记录,来自 `paas form search` 结果。

### 关键取值来源(不要臆造,一律取自命令返回)

| payload 字段 | 从哪拿 |
|-------------|--------|
| `flowTaskId` | `flow buttons` 返回的 `currentaskId`(后端历史拼写,字段名就少个 t,不是笔误) |
| `nodeButtonName` | `flow buttons` 返回按钮的 `enName`(如 `submit`/`agree`) |
| `approveResult` | 按钮语义对应:1=同意/通过,4=回退,7=撤回给自己(spec 示例口径) |
| `nodeInstanceId` | 当前节点直接用 `flow buttons` 返回的 `currentNodeInstanceId`;历史节点从 `flow log` 的 `nodeLogList` 按节点取 |
| `processorInstanceId` | 流程实例 id,出现在流程日志/实例数据中 |

## ⚠️ 写操作 / 状态变更(执行前必须确认;先 `--dry-run` 预演,再 `--confirm-write`)

### 审批 / 推进

```bash
# 优先用 form finish-content(见 form 文档);flow approve 是底层等价入口
shb-cli paas flow approve --data '{
  "nodeButtonName": "agree",
  "flowTaskId": "<flow-task-id>",
  "approveResult": 1,
  "approveMessage": "同意",
  "remark": "同意",
  "formContentId": "<content-biz-id>",
  "formTemplateId": "<template-biz-id>",
  "module": "PAAS",
  "syncForm": true,
  "param": {},
  "formValue": {}
}' --confirm-write
```

### 开启流程

```bash
shb-cli paas flow start --app-id <app-id> --form-content-id <content-biz-id> --form-template-id <template-biz-id> --confirm-write
```

### 催办 / 撤回 / 会签 / 转交

```bash
# 催办:提醒当前节点处理人;pushTypes 是推送渠道
shb-cli paas flow urge --data '{"formContentId":"<content-biz-id>","formTemplateBizId":"<template-biz-id>","nodeInstanceId":"<node-instance-id>","pushTypes":[2],"sourceModule":"paas"}' --confirm-write

# 撤回给自己:把已流出的任务收回
shb-cli paas flow back-to-me --data '{"flowTaskId":"<flow-task-id>","nodeButtonName":"backToMe","approveResult":7,"approveMessage":"撤回","remark":"撤回"}' --confirm-write

# 会签:给当前节点追加处理人
shb-cli paas flow countersign --data '{"paasFlowNodeInstanceId":"<node-instance-id>","processorInstanceId":"<processor-instance-id>","userIdList":["<user-id>"]}' --confirm-write

# 批量转交:把 A 名下这些记录的任务转给 B
shb-cli paas flow batch-transfer --data '{"originUserId":"<origin-user-id>","transferUserId":"<transfer-user-id>","formContentIdList":["<content-biz-id>"]}' --confirm-write
```

### 暂停 / 恢复

```bash
shb-cli paas flow pause --data '{"processorInstanceId":"<processor-instance-id>"}' --confirm-write
shb-cli paas flow resume --data '{"processorInstanceId":"<processor-instance-id>"}' --confirm-write
```

### 部署 / 修改流程图(加节点、加审批节点走这里)

**没有"单独加一个节点"的细粒度命令**——流程图是整体提交的:`antvJson` 是完整流程图 JSON(设计器格式),`cells` 数组里是全部节点与连线(edge)。节点类型:`start-node`(发起)、`process-node`(流程节点)、`approve-node`(审批节点)、`end-node`(结束)。

要添加流程/审批节点:先 `flow get` 取现有 `attribute`(即 antvJson),在 `cells` 里加节点和连线后整图提交;**不要手工凭空构造整图**,节点 `data` 里的审批人/字段权限/按钮配置复杂,以现图为基础修改。

```bash
shb-cli paas flow deploy --data '{"formTemplateId":"<template-biz-id>","appId":"<app-id>","antvJson":"<流程图JSON字符串>","newCanvas":true}' --confirm-write
shb-cli paas flow redeploy --data '{"workflowTemplateId":"<workflow-template-id>","formTemplateId":"<template-biz-id>","appId":"<app-id>","antvJson":"<流程图JSON字符串>","newCanvas":true}' --confirm-write
```

## 版本管理

流程图每次部署产生一个版本,同一时间只有一个当前启用版本。**判断当前启用版本看 `status: 2`(实测口径:唯一 status=2 的版本即当前版本,新发起的流程走它);`enable` 字段所有版本都是 true,没有区分意义,不要用它判断。** 用户问"有什么版本/目前用什么版本"→ `version list` 一次调用即可:全部版本列表 + 其中 `status: 2` 那条就是当前版本;问"某条记录在走哪个版本"→ `version current`。

```bash
shb-cli paas flow version list --form-template-id <template-biz-id>              # 该表单全部流程版本
shb-cli paas flow version current --form-content-biz-id <content-biz-id>         # 某条记录正在走哪个版本
shb-cli paas flow version condition-new --form-template-id <template-biz-id>     # 流程条件可用的表达式
shb-cli paas flow version create --data '<json>' --confirm-write                  # ⚠️ 新建版本
shb-cli paas flow version edit --data '<json>' --confirm-write                    # ⚠️ 编辑未启用版本
shb-cli paas flow version enable --data '<json>' --confirm-write                  # ⚠️ 启用版本
```

删除流程版本(destructive)见 [`shb-paas-delete.md`](shb-paas-delete.md)。

## 典型链路

```bash
# 推进一条记录走一步:查按钮 → 用按钮参数推进 → 看日志确认
shb-cli paas flow buttons --content-biz-id <content-biz-id>
shb-cli paas form finish-content --data '<json,按钮字段来自上一步>' --dry-run
shb-cli paas form finish-content --data '<json>' --confirm-write
shb-cli paas flow log --content-biz-id <content-biz-id>
```

## 注意

- 所有写操作的 JSON 优先用 `--data '<json>'` 内联;`--file <path>` 仅本地已有现成文件时用。
- 排错顺序以 [`shb-paas-detail.md`](shb-paas-detail.md)「排错顺序」为准;流程版本问题再补 `flow version list`;流程报 `state invalid` 先 `template check-state` 看表单是否被禁用/锁定。
- `flow buttons` / `flow log` 接收的都是 `content-biz-id`(整条记录)。
- payload 字段值一律取自「关键取值来源」表中的命令返回,不要臆造;按钮相关字段(`flowTaskId`/`nodeButtonName`/`approveResult`)必须来自 `flow buttons`。
- headless 模式仅允许单条 shb-cli 命令:禁止管道 `|`、`$()` 命令替换、`;` 串联——先跑一条读结果,再把值填进下一条。
