# 三标识决策卡（**仅企业版 BOS**）

> **适用范围**：**金蝶AI星空企业版 / 标准版**（C# / IronPython / 企业版 OpenAPI 字段口径）。  
> **不适用**：金蝶AI苍穹 / 星瀚 / **旗舰版**（Cosmic 族，`ok-cosmic`）。  
> **通用契约**（访问位 + 生命周期 + API 面）：[api-surface-contract.md](api-surface-contract.md)

**企业版**混用三层必出 Bug。先定**访问位**，再选层；三列只认元数据。

| 真源 | 路径 |
|------|------|
| 本卡 | 企业版字段分层规则 |
| 通用契约 | [api-surface-contract.md](api-surface-contract.md) |
| 取证 | [metadata-db-query.md](metadata-db-query.md) |

---

## 铁律（企业版 · 任意字段）

1. **先定访问位，再写字符串**（与业务字段名无关）  
   - View / FieldKey / GetValue / SetValue / OpenAPI FieldKeys / `FieldKeys.Add` → **Key**  
   - `billObj` / `entry` / `entity` / `DataEntity` / `DynamicObject[...]` → **PropertyName**  
   - SQL / KSQL → **FieldName**

2. **三列唯一真相**  
   - 只读连库 FKERNELXML，在同一字段块内读 Key / PropertyName / FieldName。  
   - 或 BOS 设计器三列。  
   - **没有**「默认同形 / 默认去 F」换算。

3. **禁止混层**  
   - 不用 Key 当数据包索引、不用 FieldName 当 GetValue、不用 PropertyName 当 FieldKeys。  
   - 无三列证据不得写字段字符串（除非显式假设）。

4. **缺三列**：有库先查；无库标假设。

---

## 纠错表（口述 / 同事说法）

| 说法 | 判定 |
|------|------|
| GetValue / SetValue 用 **Key** | 对 |
| `billObj` / `entry` / `entity` 索引用 **PropertyName** | 对 |
| GetValue 用 PropertyName（如 `"Qty"`） | **错**（除非元数据证明 Key 就是该串） |
| 数据包用 Key（如 `entry["FQty"]`） | **错**（除非元数据证明 PropertyName 就是该串） |
| 口算去掉 F 换层 | **错** |

---

## 名称

| 名称 | 英文 | 用在哪 |
|------|------|--------|
| 标识 | Key | 控件、GetValue/SetValue、FieldKeys |
| 实体属性名 | PropertyName | 数据包索引 |
| 字段名 | FieldName | SQL 列 |

示例仅说明「三者可以不同」：Key=`FQty`，PropertyName=`Qty`，FieldName=`FQTY`。**其它字段同样按访问位选层。**

---

## 30 秒决策

```
├─ 控件 / Field.Key / GetValue / SetValue / FieldKeys → Key
├─ billObj / entry / entity / DataEntity → PropertyName
├─ SQL → FieldName
└─ 不确定 → 连库或设计器，禁止猜
```

---

## 代码示例

```csharp
// Key 访问位
this.Model.SetValue("FQty", qty, row);
if (e.Field.Key == "FQty") { }
e.FieldKeys.Add("FQty");

// PropertyName 访问位（操作插件 / 转换 / 数据包）
entry["Qty"] = qty;
var mat = entry["MaterialId"] as DynamicObject;
string billNo = Convert.ToString(bill["BillNo"]);
decimal amt = Convert.ToDecimal(entity["Amount"] ?? 0);

// FieldName 访问位
// SELECT FQTY, FMATERIALID FROM T_SAL_ORDERENTRY
```

---

## 旗舰 / 苍穹 / 星瀚（不套本卡）

- 字段：Cosmic field key；**不要**强制企业版三列。  
- entityId：元数据标识，禁止物理表名。  
- 跨族：禁止 `Kingdee.BOS` 与 `kd.bos` 混用。

---

## 编码前检查

- [ ] 产品线是企业版  
- [ ] 每个字段字符串已归访问位  
- [ ] 三列来自元数据或已标假设  
- [ ] GetValue 用 Key，数据包索引用 PropertyName  
