---
name: kd-flagship-plugin
description: 苍穹/旗舰版插件开发强制规范。生命周期/元数据操作/禁用规则。
alwaysApply: false
---

# 苍穹插件开发规范

## 生命周期（先读强制）

- 【强制】**禁止**在 `initialize()` 中注册控件事件或设置控件可见性（含 `registerListener` 调用、`setVisible`/`setEnable`）。  
  - 事件 → **`registerListener`**  
  - 界面显隐/启用 → **`afterBindData`**（及用户事件回调）  
  - `initialize` **不是**「注册监听/改 UI」的合法时机
- 【推荐】**禁止**在 `beforeBindData` / `afterBindData` 中随意修改数据对象（`setValue`/分录增删）。这两个事件新建和查看单据都会执行，修改字段值会导致存储值与界面不一致。
- 【推荐】**禁止**循环调用 `view.updateView()`，应循环结束后对修改的数据局部刷新

## UI 控件状态（强制区分）

- 【强制】**不存在** `setReadOnly(...)` / `IDataModel.setReadOnly` → 用 `getView().setEnable(false, "fieldKey")`（可多 key）禁用/启用控件
- 【强制】**`setEnable` / `setVisible` 是合法平台 API**，用于插件控制控件可用与可见；**不要**把「用 setEnable」判成错误
- 【推荐】界面状态优先放在 `afterBindData`（及用户事件回调），**不要**在 `initialize` 里 setEnable/setVisible
- 【推荐】`beforeBindData`/`afterBindData` **改数据包**与 **改控件状态** 分开：前者慎用；后者在 afterBindData 做状态是推荐路径

## 分录 API（存在/幻觉）

- 【强制】**不存在**：`getEntryCount` / `addRow` / `deleteRow` / `getEntry()`（无参）
- 【强制】**存在（合法族）**：`getEntryRowCount(entryKey)`、`createNewEntryRow(entryKey[, dyn])`、`deleteEntryRow(entryKey, rowIndex)`、`getEntryRowEntity(entryKey, rowIndex)`、`getEntryEntity(entryKey)`
- 不要把「官方某重载要 DynamicObject」说成「单参 createNewEntryRow 整个 API 不存在」

## 元数据操作
- 【强制】实体元数据是单例对象，**禁止**在缓存中获取后直接修改 → 必须先 `Clone`
- 【禁止】直接修改 `BusinessInfo` / `LayoutInfo`（运行时一份元数据所有代码共享，修改不可控）
- 【强制】引用对象创建或赋值必须保证对象类型一致
  - 正例：用 `prop.getComplexType().createInstance()` 创建基础资料
  - 反例：用 `EntityMetadataCache.getDataEntityType("bd_customer").createInstance()` 类型不一致

## 禁用规则
- 【强制】**禁止**禁用标准产品插件
- 【强制】**禁止**删除预置的反写规则（不使用时可以禁用，但不可删除）
- 【强制】**禁止**修改标准产品数据库视图和存储过程
- 【强制】**禁止**对已启动工作流的单据调用标准审核/反审核接口
- 【强制】**禁止**对已启动工作流的单据数据进行物理删除

## 其他
- 【推荐】跨应用：转换规则/转换插件在源单所在应用，反写规则/反写插件在目标单所在应用
- 【推荐】如果需要事务控制或权限控制，必须在操作插件中完成
- 【推荐】不使用废弃的接口方法
