---
name: kd-enterprise-csharp
description: >
  在已有金蝶AI星空企业版/标准版 .NET 插件工程中实现或修改 C# BOS 插件。
  Use when: 用户要写/改 AbstractBillPlugIn、List、Operation、Convert、报表、校验器、定时任务、WebAPI 等 C# 插件；
  或验证 Kingdee.BOS 事件/字段/FormId。
  Do not use when: Cosmic Java（ok-cosmic）、IronPython（kd-enterprise-python-plugin）、空目录建工程、与 BOS 无关的 .NET 应用。
---

# 企业版 C# BOS 插件

**.NET Framework 4.x 类库 + `Kingdee.BOS.*`。认工程结构，再写代码。**  
不做空目录脚手架（对齐旗舰：`ok-cosmic` 假定工程已在，只写插件）。

## When / Do not

**Use when**

- 目录里**已有** `.csproj` / `.sln` 的企业版/标准版 **C# 插件**工程
- 写/改表单、动态表单、列表、操作、转换、报表、校验、调度、WebAPI 等
- 报表/账表加列、扩展取数、继承原报表插件（默认本 skill，不走 openapi）

**Do not use when**

- Cosmic Java → `ok-cosmic`
- IronPython → `kd-enterprise-python-plugin`
- **空目录 / 无 csproj**：不要 `dotnet new` 臆造工程；请用户用 VS 建好类库（或打开已有插件工程）后再来
- 纯 C# 非 BOS 业务系统

## 工程结构识别（编码前必做）

从 cwd 向上找 `.sln` / `.csproj`，记录：

| 信号 | 含义 |
|------|------|
| `OutputType` = Library + `TargetFrameworkVersion` v4.5+ | 标准 **BOS 插件类库**（主路径） |
| `ProjectTypeGuids` 含 WPF + Library | **客制化控件**工程（如 `Kingdee.LF.Client.Plugin` 形态） |
| `Reference`/`HintPath` 含 `Kingdee.BOS*`、可选 `Libs\` | 金蝶程序集已挂上 |
| 已有 `Abstract*PlugIn` / `*Service` 类 | 对齐命名空间、风格、注册习惯 |

**失败**：找不到 csproj，或完全无 `Kingdee.BOS` 引用 → **停写业务插件**；说明需先有 VS 类库工程并引用金蝶 DLL，不要在空文件夹生成整套工程。

可选：`kcode init --enterprise` 只写产品画像/协作配置，**不替代** .NET 工程。

## Input / Output

**Input**

| 字段 | 说明 |
|------|------|
| projectPath | 已识别的 csproj/源码路径与程序集引用 |
| pluginType | 基类类型（见资产表） |
| formId / entity / op | FormId、entity key、操作编码 |
| fields | 字段 key（已验证） |
| event | 目标事件 |

**Output**

| 字段 | 说明 |
|------|------|
| files | 修改/新增的 `.cs` 路径（落在现有工程内） |
| registration | BOS 注册说明 |
| facts | FormId/字段/事件已确认项 |
| verify | 编译/数据中心验证 |

## Steps

```
- [ ] 1. plan：识别工程结构；无 csproj 则停
- [ ] 2. **通用契约**：读 `skills/_shared/api-surface-contract.md`
        · 生命周期位 → 基类/事件族（enterprise-plugin-shape）
        · 每个字段 → 访问位 → Key | PropertyName | FieldName
        · API ⊆ 当前类型 assets 手册/Template（禁止面外方法）
- [ ] 3. 确认 pluginType + 事件 + FormId；字段按 metadata-db-query：有连接则只读 SQL+LLM 解析；**无连接则先问用户**；跳过查库则标 assumption- [ ] 4. 打开对应 assets 手册+骨架；snippets 仅作面内示例
- [ ] 5. 报表加列：先找现有 AbstractSysReportPlugIn / SysReportBaseService
- [ ] 6. 写码：Kingdee.BOS.*；操作插件数据包索引=PropertyName；无 View 主路径
- [ ] 7. 禁止：循环查库/save、拼接 SQL、跨族 API、面外方法、表单挂操作事务、混层
- [ ] 8. verify：构建（若可）+ 注释 lifecycle / access / assumption
```

**失败策略**

| 失败 | 动作 |
|------|------|
| 无工程/无 csproj | 停止 |
| 无库连接信息 | **向用户索取**主机/库名/只读认证（metadata-db-query §1） |
| FormId/字段无法确认 | 连库解析；用户拒绝则 assumption || 不知 Key 还是 PropertyName | **访问位矩阵**（api-surface-contract §2），禁止口算 |
| 方法名不确定 | **只抄**当前类型 assets 手册/Template/同仓，禁止编 API |
| 基类/事件不明 | 生命周期矩阵（api-surface-contract §3） |
| 编译失败 | 按错误修，不换臆造 API |
| 误走 OpenAPI | 插件二开回到本 skill |




## 资产（模板）

| 类型 | 手册 | 骨架 |
|------|------|------|
| 表单 | [FormPlugin.md](assets/FormPlugin.md) | [FormPluginTemplate.cs](assets/FormPluginTemplate.cs) |
| 列表 | [ListPlugin.md](assets/ListPlugin.md) | [ListPluginTemplate.cs](assets/ListPluginTemplate.cs) |
| 操作 | [OperationPlugin.md](assets/OperationPlugin.md) | [OperationPluginTemplate.cs](assets/OperationPluginTemplate.cs) |
| 转换 | [ConvertPlugin.md](assets/ConvertPlugin.md) | [ConvertPluginTemplate.cs](assets/ConvertPluginTemplate.cs) |
| 报表表单 | [ReportFormPlugin.md](assets/ReportFormPlugin.md) | [SysReportFormTemplate.cs](assets/SysReportFormTemplate.cs) |
| 报表取数 | [ReportServicePlugin.md](assets/ReportServicePlugin.md) | [SysReportServiceTemplate.cs](assets/SysReportServiceTemplate.cs) |
| 动态表单 | [DynamicFormPlugin.md](assets/DynamicFormPlugin.md) | [DynamicFormPluginTemplate.cs](assets/DynamicFormPluginTemplate.cs) |
| 校验 | [ValidatorPlugin.md](assets/ValidatorPlugin.md) | [ValidatorPluginTemplate.cs](assets/ValidatorPluginTemplate.cs) |
| 调度 | [ScheduleService.md](assets/ScheduleService.md) | [ScheduleServiceTemplate.cs](assets/ScheduleServiceTemplate.cs) |
| WebAPI | [WebApiService.md](assets/WebApiService.md) | [WebApiServiceTemplate.cs](assets/WebApiServiceTemplate.cs) |

三标识（企业版必读）：[skills/_shared/three-identifiers.md](../_shared/three-identifiers.md)  
通用契约：[skills/_shared/api-surface-contract.md](../_shared/api-surface-contract.md)  
形态选型：[skills/_shared/enterprise-plugin-shape.md](../_shared/enterprise-plugin-shape.md)  
snippets：`assets/snippets/*.cs`（面内示例，非场景穷举）


## BOS 规则（可执行）

- 表单/列表：`this.View` / Model；操作/报表/转换：**无** View 主路径
- UI 消息：仅手册中的 `ShowMessage` / `ShowWarnningMessage` / `ShowErrMessage`
- 服务侧：抛 `KDException` / `KDBusinessException`
- **访问位**：GetValue/SetValue/FieldKeys → Key；任意 `entity`/`entry`/`DataEntity` 索引 → PropertyName；SQL → FieldName
- **生命周期**：先归位再选基类（api-surface-contract §3）
- **API 面**：只使用当前类型 assets 手册中的成员




- TFM：.NET Framework 4.x；C# 以**当前 csproj** 为准

## 渐进披露

| 需要时 | 文件 |
|--------|------|
| **三标识何时用哪个** | [../_shared/three-identifiers.md](../_shared/three-identifiers.md) |
| C# 语言层怎么用（先读 INDEX） | [references/lang-csharp/INDEX.md](references/lang-csharp/INDEX.md) |
| 企业版主题 rules | `rules/kd-enterprise-*`（索引 `kd-enterprise-index`） |
| 查询/事务示例 | assets/snippets |

**勿默认读取**：`lang-csharp/csharp-scripts.md`、`lang-csharp/refs/**`。

## 工具

| 场景 | 工具 |
|------|------|
| 工程/引用 | 搜 `*.csproj` / `Kingdee.BOS` |
| 字段/FormId | Agent 引导只读 SQL + LLM 解析（`metadata-db-query.md`，非 MCP）；无连接先问用户 |
| API 签名 | IL 反编译 / 项目引用 |
| 构建 | `msbuild` / `dotnet build` |
| 审查 | `review` |

## 验证

- 工程结构已识别；`.cs` 落在现有工程；注册点、已确认事实、测试步骤与结果
