> **前置条件** — 执行任何命令前先确认已认证；未认证见 [`../../shb-shared/SKILL.md`](../../shb-shared/SKILL.md)。

# shb-cli paas form search

PaaS 表单内容查询：按表单（模块/页面）查记录、筛选、拉全量。

> **命令、flag、参数名、JSON/接口字段名，以及取数过程（分页、全量、选列、截断重试）只供后台执行,绝不出现在给用户的回复里**——不解释、不转述、不当理由。回复只给业务结果与真实数量。

## Contents

- 表单定位（名称 → `templateBizId`）
- 查询方式（快捷 flag / `--data` / `--file`）
- 输出：始终投影，`--fields` 选列
- 搜索字段与高级条件（`conditions` / `systemConditions`）
- 按创建时间过滤 （`between`）
- 获取全量（`--all`）
- 典型场景
- 回复用户规则

## 表单定位

`form search` 必须有 `templateBizId`（即表单 id）。用户只给名称/标题/业务描述时，先按 [`shb-paas-form.md`](shb-paas-form.md) 用 `paas app forms` 定位（候选不唯一先向用户确认，不要臆造 id）。

拿到表单后查字段定义，把用户说的“客户/创建人/下拉”等展示名映射成真实字段 key：

```bash
shb-cli paas template fields --template-biz-id <template-biz-id>
```

## 查询方式

**优先级：快捷 flag ＞ `--data` ＞ `--file`**。常规筛选用快捷 flag；复杂/完整 body 用 `--data` 内联；`--file` 仅在本地已有现成 JSON 文件时用。

```bash
# 快捷 flag(CLI 会按 PC 列表页口径自动构造最小查询 payload)
shb-cli paas form search --template-biz-id <id>
shb-cli paas form search --template-biz-id <id> --keyword <关键字>
shb-cli paas form search --template-biz-id <id> --keyword <关键字> --search-condition serialNumber,customerName   # 指定参与关键字搜索的字段
shb-cli paas form search --template-biz-id <id> --status 1          # 流程状态
shb-cli paas form search --template-biz-id <id> --create-view 1     # 创建视角
shb-cli paas form search --template-biz-id <id> --page-num 1 --page-size 100

# 完整 / 复杂 JSON body
shb-cli paas form search --data '{"templateBizId":"<id>","pageNum":1,"pageSize":100}'
shb-cli paas form search --file ./form-search.json
```

## 输出：始终投影，`--fields` 选列

`form search` **始终返回投影后的少量可读列**（字段文案与值都转成可读内容）——无论 `--data` 多复杂、`-o json|raw|table` 选哪种编码都一样。**没有裸出整张接口响应的开关**，整表深层结构（`esTaskList`/`formValueStr`/`wfButtonVO`）不会进上下文。`--format-data` 已废弃（投影是默认，加了不报错）。

投影结果结构：`columns`（key/文案/类型）、`rows`（用 `--fields` 控制列）、`page`（分页，含总数 `totalElements`）、`rawRows`（仅 `--include-raw` 时）。字段文案来自 `paas template fields`；展示给用户用字段中文名，不要抛英文 key。

```bash
shb-cli paas form search --template-biz-id <id> --fields serialNumber,bizId,createTime
shb-cli paas form search --template-biz-id <id> -o table
```

**选列铁律 —— `--fields` 是「取回哪些列进上下文」，不是「给用户显示哪些列」：**

- **一次取全**：查前先看 `paas template fields`，把这次可能用到的列一次性写进 `--fields`，只跑一次。投影后每格很小，多取几列远比重跑便宜。
- **改显示不重查**：用户要多显示/少显示某列，若该列已取回，**直接在已取回数据上重新排版**，不要为改显示列重跑 `form search`。
- **只有新列没取过才重查**：沿用同样筛选条件，`--page-size` 收小，只取需对照的少数记录。
- `--include-raw` 会把每条原始行塞进 `rawRows`，**体量明显变大，默认不加，禁止用于数数/筛选**。

## 搜索字段与高级条件

| 字段 | 类型 | 说明 |
|------|------|------|
| `templateBizId` | string | 表单 id，快捷 flag 模式必填 |
| `keyword` | string | 关键字搜索 |
| `pageNum` / `pageSize` | int | 页码**从 1 开始**；`pageSize` CLI 默认 10|
| `status` | int/string | 流程状态：1 进行中、2 已完成、3 已取消 |
| `createView` | int/string | 创建视角：1 我创建的、2 我负责的 |
| `tagId` / `labelQuery` | string/object | 标签 / 智能标签 |
| `conditions` | array | 自定义字段高级条件 |
| `systemConditions` | array | 系统字段高级条件（如创建时间，见下节） |
| `customStatusSearchList` | array | 自定义状态高级条件 |
| `sorts` / `searchCondition` | array | 排序 / 参与关键字搜索的字段 |

复杂筛选、排序、标签/状态组合走 `--data '<json>'` 内联。

**`conditions` / `systemConditions` 的 `Condition` 结构规则**（不要臆造字段名）：

- 字段 key 用 `property`（不是 `fieldName`）。
- operator 用后端小写枚举：`eq`、`not_eq`、`like`、`not_like`、`array_eq`、`array_in`、`object_in`、`between`、`empty`、`not_empty` 等；不要用 `EQ`/`CONTAINS` 这类 UI 文案。
- 客户/产品/人员/地址/下拉多选等对象或数组字段不能传普通字符串，按类型带 `key` + `value`/`inValue`。
- `between`（区间）不用 `value`，用 `betweenValue1`（下界）+ `betweenValue2`（上界），详见下节。
- 不确定字段类型/operator/真实 key 时先查 `paas template fields`。
- **过滤失效即停手**：加条件后总数与不加时完全一样 = 条件没生效（多为格式/字段名不对）。**立即停止核对格式，不要换数组/字符串/大小写/property 反复重试同一条件**；改用确切写法或向用户说明。

```json
{
  "conditions": [
    {"property": "field_customer", "operator": "array_eq", "key": "id", "value": "customer-biz-id"},
    {"property": "field_textarea", "operator": "like", "value": "关键字"},
    {"property": "field_select", "operator": "eq", "value": "选项值"}
  ]
}
```

按“客户手机号/名称”查表单时，先用客户能力把手机号或名称解析成客户 ID，客户字段条件只传 ID：`{"property":"客户字段key","operator":"array_eq","key":"id","value":"客户ID"}`。不要把手机号直接放进客户字段，也不要写成 `operator:"eq"`。

## 按创建时间过滤

按**创建时间**筛选：系统字段条件 `createTime` + `between`，下界 `betweenValue1`、上界 `betweenValue2`，**值都是 epoch 毫秒时间戳数字（不是字符串、不是 ISO）**：

```bash
shb-cli paas form search --data '{
  "templateBizId": "<id>",
  "systemConditions": [
    {"property": "createTime", "operator": "between", "betweenValue1": <起始毫秒>, "betweenValue2": <结束毫秒>}
  ],
  "pageNum": 1, "pageSize": 100
}'
```

- **「最近 N 天」算毫秒**：用环境可用的时间能力（时间工具或系统时间）取当前毫秒 `now`；`betweenValue2 = now`，`betweenValue1 = now - N*86400000`。
- **只想知道区间内总数**：`pageSize:1` 只取 `page.totalElements`（即区间内条数），不用拉整表，输出极小；确需明细时才去掉 `pageSize:1`、加 `--fields serialNumber,bizId,createTime`。
- **只认这一种写法**：`property` 用 `createTime`；`between` 用 `betweenValue1/2`。给 `between` 传 `value` 数组会 400、传字符串或 ISO 会被静默忽略，顶层 `createTimeStart`/`startTime` 接口不认。加时间条件后 `totalElements` 若与不加时相同 = 没生效 → 停手核对，勿反复试（见上节「过滤失效即停手」）。
- 备选等价写法：两条 `createTime` 条件 `ge`（下界）+ `le`（上界），`value` 为**毫秒字符串**；仍首选上面的 `between`。

## 获取全量

```bash
shb-cli paas form search --template-biz-id <id> --all --fields serialNumber,bizId,createTime
```

- 必须配 `--fields <少数列>` 收窄；不要加 `--include-raw`。
- `--all` 已遍历所有页，不要再补跑分页；同一条件最多执行一次。
- 输出被截断就改分页叠加，不要反复重试 `--all`。
- **只想数数不要用 `--all`**：见下节「统计 / 聚合计数」。

## 统计 / 聚合计数

> ✅ **首选：只要总数/分布，不要拉全量明细。**
> 用户只问"有多少数据/多少条/记录数"，或要按某个维度（`status`/`createView`/自定义下拉字段等）做分布统计时，**不需要把记录拉回来自己数**——`pageSize:1` 只取 `page.totalElements`（第一次调用就带总数，输出极小），逐个取值单独查一次后汇总即可。**这样零截断风险、也不占上下文**，远优于把成百上千条明细全拉进来再数。
> 只有确需**逐条明细字段**（如逐单列出、按非接口字段二次加工）时，才走「获取全量」/分页叠加拉明细；能用计数搞定的，绝不拉明细。

```bash
# 单一总数：整表或加了筛选条件后有多少条
shb-cli paas form search --template-biz-id <id> --page-size 1

# 按状态分布：逐个取值单独查一次，只取总数（page.totalElements），模型读取后汇总
shb-cli paas form search --template-biz-id <id> --status 1 --page-size 1   # 进行中
shb-cli paas form search --template-biz-id <id> --status 2 --page-size 1   # 已完成
shb-cli paas form search --template-biz-id <id> --status 3 --page-size 1   # 已取消
```

- 自定义下拉/单选字段等维度的分布，用 `conditions` 逐个取值单独查一次（同上，`pageSize:1`），不要一次性拉全量再在上下文里分组计数。
- **不要用 `for` 循环或 `;` 串联多条命令**——headless 模式下 shell 仅允许单条 shb-cli 命令，逐维度分别调用。

## 典型场景

```bash
# 关键字查询
shb-cli paas form search --template-biz-id <id> --keyword "<关键字>" --fields serialNumber,bizId,createTime

# 进行中的表单
shb-cli paas form search --template-biz-id <id> --status 1 --fields serialNumber,bizId,customStatus,createTime

# 复杂高级搜索（--data 放完整 FormContentQuery：conditions/systemConditions/labelQuery/sorts…）
shb-cli paas form search --data '<json>' --fields serialNumber,bizId,createTime
```

## 回复用户规则

- 不回显命令、flag、JSON 字段名、分页/取数过程或内部字段名。
- 状态值转业务文案（如 `1` → “进行中”）。
- 自定义字段用字段定义里的中文 `displayName`；匹配不到中文名的字段不要把英文 key 抛给用户。
- 只给业务结论、数量和必要明细。
