> **前置条件** — 执行前请先确认已完成认证（参见 [`../../shb-shared/SKILL.md`](../../shb-shared/SKILL.md)）。输出措辞禁令、id 复用规则、传参优先级见本 skill 的 [`SKILL.md`](../SKILL.md)。

# shb-cli warehouse material field（字段定义查询与唯一性预检）

云仓物料的字段定义查询（`material field list`）与字段唯一性预检（`material field check`，只读）。两者都是只读命令，常作为创建/编辑物料的前置步骤被 [`shb-warehouse-material-create.md`](shb-warehouse-material-create.md) / [`shb-warehouse-material-update.md`](shb-warehouse-material-update.md) 引用。

## 查询字段定义

```bash
shb-cli warehouse material field list
```

返回物料新增/编辑表单的字段定义（`MaterialFormFieldVO` 列表），用于了解租户自定义字段配置，不代表列表页展示字段（列表页默认展示字段见 [`shb-warehouse-material-search.md`](shb-warehouse-material-search.md)）。

- 每个字段带 `fieldName`/`displayName`/`formType`/`isSystem`/`isNull` 等元数据。
- `isNull=0` 表示必填——**系统字段和租户自定义字段都可能被配成必填，不要只检查系统字段**。
- `isSystem=1` 为系统字段，`isSystem=0` 为租户自定义字段（写入时走 `--custom-fields`，见 create/update 文档）。

## 向用户转述字段信息的完整措辞规范

用户问「能改哪些字段」「有哪些字段」「哪些必填」时：先跑 `material field list` 拿数据（这是**纯后台内部步骤**），但回答里**只出现每个字段的中文展示名**：

- **禁止**在中文名后面加英文字段名注释，如「物料名称（`name`）」「终端销售价（`salePrice`）」——括号里的 `name`/`salePrice` 是接口字段名，属于内部实现，一个都不能出现。
- **禁止**向用户解释 `isNull`、`isSystem`、`formType`、"系统字段/自定义字段" 这类元数据机制；哪些必填直接用中文说「其中 xx、xx 是必填的」即可。
- **不要把快捷 flag 列表当作"可修改字段"的答案**——flag 只是命令入口，不等于该租户的完整字段集合（自定义字段就不在 flag 里），且「快捷 flag」「`--sale-price`」同样不能出现在回复里。
- 据字段定义判断本次创建/编辑还缺哪些必填值后，直接用中文向用户开口要（如「请提供单位」「这个物料的供应商是？」），**绝不复述"我看到字段配置是…"这类判断过程**——用户只看到你"要什么"。匹配不到中文展示名的字段宁可不展示，也不要把英文 key 抛给用户。

正例：「可以修改：物料名称、物料属性、单位、规格、说明、类别、终端销售价、押金控制价、是否期效管理、保质期，以及物料分组、产品线等扩展信息。其中物料名称、单位是必填的。要改哪个物料的哪些内容？」
反例（禁止）：「物料名称（`name`）、终端销售价（`salePrice`）… 字段 `isNull=0` 的为必填字段」——泄漏了接口字段名和元数据机制。

## 字段唯一性预检

创建/编辑前预检 `sn`（或其他唯一性字段）是否会冲突，避免直接提交后被后端拒绝再回退：

```bash
shb-cli warehouse material field check --field-name sn --field-value M-2001

# 编辑时排除自身
shb-cli warehouse material field check --field-name sn --field-value M-2001 --id <当前物料id>
```

- 返回布尔值：`true` = 无冲突（可用），`false` = 已被占用。
- `fieldName` 传 `sn` 走数据库唯一性查询，传其他字段名走该字段的自定义唯一性查询（需该字段本身配置了唯一性校验）。
- 这是只读预检，不需要 `--yes`，不产生任何数据变更。
