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

# PaaS 表单字段定义(字段类型目录)

表单字段定义的权威参考:字段元数据含义、**字段类型(`formType`)目录**、以及各类型在写操作(`form save`/`create`/`finish-content`)里 value 该怎么传。搜索/详情格式化输出、创建或编辑记录前确认字段 key/类型/是否必填,都查这里。

- 只是查"表单有哪些字段、字段 key 是什么" → 本文档。
- 查"当前流程节点哪些字段可填/必填/隐藏"(带 `revisable` 判定) → 见本文档「当前节点可填写字段」一节。
- 拿字段 key 去改数据的完整 payload → [`shb-paas-update.md`](shb-paas-update.md);建记录 → [`shb-paas-create.md`](shb-paas-create.md)。

## 查询字段定义

```bash
# 表单自身的全部字段定义(改数据前查 key/类型用这个)
shb-cli paas template fields --template-biz-id <template-biz-id>

# 某条记录在当前流程节点的字段(含 revisable 可填判定)——判定见下「当前节点可填写字段」
shb-cli paas template node-fields --content-biz-id <content-biz-id>

# 下拉/级联等选项字段的选项解析
shb-cli paas template select-info --data '<json>'

# 可用的产品子表字段
shb-cli paas template product-fields
```

## 当前节点"可填写字段"怎么判断(用户问"这个节点能填哪些字段")

用户问"当前节点可填写的字段有哪些 / 这一步要填什么",走 `template node-fields --content-biz-id <content-biz-id>`(可选 `--node-instance-id <id>` 指定节点,不传默认取当前节点),再**按下列字段过滤**——不要把整个返回列表原样丢给用户:

| 返回字段 | 含义 | 判断口径 |
|---------|------|---------|
| `revisable` | 是否可填写/可编辑 | **`1`=可填写**;`0`=只读(展示但不可改);`null`=非输入型元素(分组标题等结构项),直接跳过 |
| `isNull` | 是否可为空 | `1`=选填(可为空);`0`=**必填** |
| `isHidden` | 是否隐藏字段 | `1`=隐藏(页面不展示);`0`=显示 |

**"当前节点可填写的字段" = `revisable == 1`**。在此基础上:

- 想只给用户看**要填的**:再排除 `isHidden == 1`(隐藏项用户填不到)。
- 区分必填/选填:`isNull == 0` 是必填,`isNull == 1` 是选填——回复里可标注"(必填)"。
- 展示时用 `displayName`(中文名),**不要暴露 `fieldName` 的 key**(见 [`SKILL.md`](../SKILL.md) 输出卫生规则);`revisable` 为 `null` 的项(分组标题等)不是字段,别列进去。

> 典型口径:「当前节点可填写的字段:客户(必填)、其他位置、……」——即筛 `revisable==1 && isHidden!=1`,必填项来自 `isNull==0`。

## 字段元数据含义

`template fields` 每个字段对象常用的 key(取自实测返回):

| key | 含义 | 判断口径 |
|-----|------|---------|
| `fieldName` | 字段 key(形如 `field_xxx`,系统字段是固定英文名如 `serialNumber`) | payload/`--fields` 里用它;**绝不展示给用户** |
| `displayName` | 字段中文文案 | 给用户看用这个 |
| `formType` | **字段类型**,决定 value 怎么传 | 见下「字段类型目录」 |
| `isSystem` | 是否系统内置字段 | `1`=系统字段(key 固定、多为内置语义);`0`=自定义字段 |
| `isNull` | 是否可为空 | `1`=选填;`0`=**必填** |
| `isHidden` | 是否隐藏 | `1`=隐藏(页面不展示) |
| `isVisible` / `isAppShow` | 是否可见 / App 端是否展示 | 展示控制 |
| `isSearch` | 是否可作为搜索条件 | `1`=可用于筛选(见 search 文档) |
| `isChildForm` / `subFormFieldList` | 是否子表字段 / 子表内字段定义 | `subForm` 类型的下级字段在 `subFormFieldList` 里 |
| `setting` | 字段配置(选项、校验、关联等) | 复合控件的选项/关联规则在这里,**内部读取判断用,不照搬进回复** |
| `orderId` | 排序 | — |

> 编辑流程中的记录时,字段能不能写还要看当前节点权限:先 `template node-fields` 按 `revisable==1` 过滤(判定见本文档「当前节点可填写字段」),`fields` 只告诉你字段"存在",不代表当前节点"可写"。

## 字段类型目录(`formType`)

按用途分组(取自实测表单的真实类型);**方括号内是 `formType` 原值**,给用户只说中文名。

### 文本 / 数值 / 计算
| formType | 中文 | 说明 |
|----------|------|------|
| `text` | 单行文本 | 普通短文本 |
| `textarea` | 多行文本 | 长文本 |
| `richText` | 富文本 | 带格式,value 为富文本内容 |
| `number` | 数字 | 数值 |
| `currency` | 金额 | 货币数值 |
| `currencyCode` | 结算币种 | 币种(系统字段) |
| `formula` | 计算公式 | **只读**,由其它字段算出,不要写它 |
| `serialNumber` | 编号 | 单据编号(系统字段),如 `THH...`,系统生成,不要写 |
| `phone` | 电话 | 电话号码 |
| `jsCodeBlock` | 代码块 | 脚本/计算展示型,一般不直接填 |

### 选择 / 日期
| formType | 中文 | 说明 |
|----------|------|------|
| `select` | 下拉(单/多选) | 选项值来自 `setting`,value 传选项值数组 |
| `cascader` | 多级菜单(级联) | 级联选项 |
| `tag` | 标签 / 部门 | 标签或部门 |
| `date` | 日期 | 日期 |
| `datetime` | 日期时间 | 日期+时间(如 `CREATE_TIME` 创建时间,系统字段只读) |

### 人员 / 客户 / 位置 / 产品
| formType | 中文 | 说明 |
|----------|------|------|
| `user` | 人员 | 选人,value 为人员对象数组 |
| `customer` | 客户 | 关联客户(系统字段) |
| `linkman` | 客户联系人 | 关联联系人(系统字段) |
| `customerAddress` | 客户地址 | 关联客户地址(系统字段) |
| `address` | 地址 | 自填地址 |
| `location` | 定位 | 地理位置(系统字段) |
| `product` | 产品 | 关联产品(系统字段) |

### 附件 / 富媒体
| formType | 中文 | 说明 |
|----------|------|------|
| `attachment` | 附件 | 文件/图片,删除已有附件用 `form save` 的 `deletefiles`(见 update 文档) |

### 物流 / 库存 / 物料(多为系统字段)
| formType | 中文 | 说明 |
|----------|------|------|
| `logistics` | 物流组件 | 物流单号+承运公司对象 |
| `sparepart` | 备件 | 备件明细 |
| `materialOrder` | 物料清单 | 物料清单 |
| `outWarehouse` | 物料出库 | 出库单据 |
| `outStock` | 出库申请单 | 出库申请 |
| `lackStock` | 缺货申请单 | 缺货申请 |
| `outDataSource` | 出库仓库 / 外部数据源 | 外部数据源关联 |
| `connector` | 连接器 | 外部系统连接器 |

### 支付
| formType | 中文 | 说明 |
|----------|------|------|
| `pay` | 支付 | 支付信息(注意:提交类流程节点可能校验支付状态) |

### 结构 / 子表(注意:不是数据字段)
| formType | 中文 | 说明 |
|----------|------|------|
| `separator` | 分组标题 / 分隔符 | **布局元素,不是可填字段**——列"可填字段"时跳过,不要写进 payload |
| `subForm` | 子表单 | 一对多的子表,行数据格式见下「子表」 |

## value 怎么传(写操作)

**关键规则:`formValueList` 里每个字段的 `value` 都是「JSON 字符串」**(字符串里再包一层 JSON),不是裸值。实测口径:

| 类型 | value(JSON 字符串)形态 | 例 |
|------|------------------------|----|
| 文本/多行/富文本/编号 | JSON 字符串包一个字符串 | `"\"大方发\""` |
| 数字/金额/公式 | JSON 字符串包数值字符串 | `"\"1111\""` |
| 单选/多选/级联/标签 | 选项值数组的字符串 | `"[\"2\"]"` |
| 人员/客户/联系人/产品/地址/物流/备件等复合 | 对象数组的字符串 | `"[{\"no\":\"233\",\"company\":{\"id\":3,\"name\":\"安迅物流\"}}]"` |

- **不要凭空构造复合控件的对象结构**:改之前先 `paas form get --content-biz-id <id>`(raw JSON,见 [`shb-paas-detail.md`](shb-paas-detail.md))读到该字段当前 value 的真实形态,照它的结构改值。
- `formula` / `serialNumber` / `createTime` 这类系统生成或计算字段**不要写**。
- 具体保存 payload(`formValueList` / `isSubForm` / `deletefiles`)见 [`shb-paas-update.md`](shb-paas-update.md);建记录见 [`shb-paas-create.md`](shb-paas-create.md)。

### 子表(`subForm`)

子表字段的下级字段定义在该字段的 `subFormFieldList` 里;写入时用 `isSubForm: 1` + `subFormContentFormList`,**行级**由 `subFormContentBizId` 区分(有=改已有行,无=新增行)。完整结构见 [`shb-paas-update.md`](shb-paas-update.md)「子表行编辑」。

## ⚠️ 字段定义写操作(加字段 / 全量替换)

改的是**表单结构**(字段定义本身),不是某条记录的数据值。属写操作,执行前必须确认用户明确要求(见 [`SKILL.md`](../SKILL.md) 权限/安全表)。

```bash
shb-cli paas template add-fields --data '<json>' --dry-run                     # 增量加字段(安全,推荐)
shb-cli paas template add-fields --data '<json>' --confirm-write
shb-cli paas template save-fields --data '<json>' --yes --replace-all-fields   # ⚠️ 全量替换,遗漏字段会被删
```

- **优先 `add-fields`(增量)**:只新增字段,不动既有字段,安全。先 `--dry-run` 再 `--confirm-write`。
- **`save-fields` 是全量替换**(对应设计器整体保存):payload 里**遗漏的既有字段会被逻辑删除**——这也是唯一的"删字段"途径(见 [`shb-paas-delete.md`](shb-paas-delete.md))。必须先 `template fields` 取全量现状、去掉/改动后整体提交,且带 `--yes --replace-all-fields`,逐字段向用户核对。
- 改结构前先 `template check-state --template-biz-id <id>` 确认表单未被在途流程锁定。
- 新字段的 `formType` 取值见上「字段类型目录」;payload 用 `--data '<json>'` 内联优先,`--file` 仅本地已有现成文件时用。

## 注意

- **输出卫生**:向用户展示或询问字段一律用 `displayName`(中文名),`fieldName`(key)与 `formType`(类型原值)仅供内部拼 payload;`setting` 里的配置和判断过程都不要复述给用户(见 [`SKILL.md`](../SKILL.md) 输出卫生规则)。
- `template fields` 返回的是**表单结构**层的字段定义,与某条记录的**数据值**是两回事(值查 `form get`,见 detail 文档)。
- 字段返回为当前用户在当前租户下的可见范围。
- headless 模式仅允许单条命令:先跑 `template fields`/`form get` 读结果,再把 key 和现值填进下一条,不要用管道 `|` / `$()` / `;`。
