# JRSoft Subway Protocol - C# 模型集成指南

## 概述

本协议包设计为与 `jrsoft-subway-csharp-model` 生成的 TypeScript 类型配合使用。当前包含的命令类型（`ExampleCommand`）仅为示例，实际使用时应从 C# 模型包导入真实的命令类型。

## 集成步骤

### 1. 安装 C# 模型包

首先，需要将 C# 模型包添加为依赖：

```bash
# 如果 C# 模型包已发布到 npm
npm install @jrsoft/csharp-model

# 或者使用本地链接（开发时）
cd ../jrsoft-subway-csharp-model
npm link
cd ../jrsoft-subway-protocol
npm link @jrsoft/csharp-model
```

### 2. 更新 package.json

在 `package.json` 中添加依赖：

```json
{
  "dependencies": {
    "@jrsoft/csharp-model": "^1.0.0"
  }
}
```

或者对于本地开发：

```json
{
  "dependencies": {
    "@jrsoft/csharp-model": "file:../jrsoft-subway-csharp-model"
  }
}
```

### 3. 更新 command-types.ts

将示例命令替换为真实的 C# 生成的命令：

```typescript
// src/command-types.ts

import { OperationType, CommandType } from './index';

// 导入 C# 生成的命令类型
import { 
  LedSwitchCommand as CSharpLedSwitchCommand,
  LedSwitchParameters,
  BlockPlayCommand as CSharpBlockPlayCommand,
  BlockPlayParameters,
  // ... 更多命令
} from '@jrsoft/csharp-model/typescript-schemas';

// 适配命令接口（处理字段名差异，如 deviceID -> deviceId）
export interface LedSwitchCommand extends Omit<CSharpLedSwitchCommand, 'deviceID'> {
  commandType: CommandType;
  deviceId: number | number[] | string;  // 重命名并支持批量
}

export interface BlockPlayCommand extends Omit<CSharpBlockPlayCommand, 'deviceID'> {
  commandType: CommandType;
  deviceId: number | number[] | string;
}

// 导出所有命令的联合类型
export type SpecificCommand = 
  | LedSwitchCommand
  | BlockPlayCommand
  // ... 更多命令
  ;

// 命令映射
export interface CommandTypeMap {
  'LedSwitch': LedSwitchCommand;
  'BlockPlay': BlockPlayCommand;
  // ... 更多映射
}
```

### 4. 更新 command-factory.ts

为每个真实命令添加工厂方法：

```typescript
// src/command-factory.ts

export class TypedCommandFactory {
  static createLedSwitchCommand(
    requestRef: string,
    targetClientId: string,
    deviceId: number | number[] | string,
    switchState: 'ON' | 'OFF',
    operationType: OperationType = OperationType.WRITE,
    options?: CommandOptions
  ): CommandMessage {
    return this.createTypedCommandMessage(
      requestRef,
      targetClientId,
      'LedSwitch',
      {
        commandType: CommandType.SIMPLE,
        deviceType: 'pillar',
        deviceId,
        operationType,
        parameters: { switch: switchState }
      },
      options
    );
  }

  // ... 更多命令工厂方法
}
```

## 字段映射说明

C# 生成的类型和协议要求的类型之间存在一些差异：

1. **字段名称差异**
   - C# 使用 `deviceID`（大写 ID）
   - 协议使用 `deviceId`（小写 id）

2. **额外字段**
   - 协议需要 `commandType` 字段（SIMPLE/BATCH/COMPLEX）
   - C# 生成的类型可能不包含此字段

3. **批量操作支持**
   - 协议的 `deviceId` 支持 `number | number[] | string`
   - C# 可能只定义了 `number`

## 开发建议

1. **使用 TypeScript 接口扩展**
   ```typescript
   interface ProtocolCommand extends CSharpCommand {
     commandType: CommandType;
     // 其他协议特定字段
   }
   ```

2. **创建适配器函数**
   ```typescript
   function adaptCSharpCommand(cmd: CSharpCommand): ProtocolCommand {
     return {
       ...cmd,
       commandType: CommandType.SIMPLE,
       deviceId: cmd.deviceID, // 字段重命名
     };
   }
   ```

3. **验证器更新**
   - 确保验证器能处理 C# 生成的命令结构
   - 添加特定命令的验证逻辑

## 注意事项

1. **版本同步**：确保 C# 模型包和协议包版本兼容
2. **类型安全**：使用 TypeScript 的严格模式确保类型正确
3. **测试覆盖**：为每个集成的命令添加单元测试
4. **文档更新**：集成新命令时更新相关文档

## 示例项目结构

```
jrsoft-subway/
├── jrsoft-subway-protocol/          # 协议定义
│   ├── src/
│   │   ├── index.ts                # 核心协议
│   │   ├── command-types.ts        # 命令类型（导入 C# 类型）
│   │   └── command-factory.ts      # 命令工厂
│   └── package.json
├── jrsoft-subway-csharp-model/      # C# 模型
│   ├── typescript-schemas/         # 生成的 TS 类型
│   │   ├── LedSwitchCommand.generated.ts
│   │   └── ...
│   └── package.json
└── jrsoft-subway-gateway/           # 使用协议的服务
    └── package.json                # 依赖 protocol 包
```