# 模板系统使用指南

## 概述

Apifox Flow 现在支持模板系统，允许您自定义生成的 TypeScript 代码的格式和结构。您可以使用内置模板或创建自己的自定义模板。

## 内置模板

### 1. Default 模板 (默认)
- **类型**: `default`
- **描述**: 使用传统的代码生成方式，不依赖模板引擎
- **特点**: 简单、快速、兼容性好

```bash
cargo run -- generate --template default
```

### 2. Advanced 模板
- **类型**: `advanced`
- **描述**: 生成高级 API 客户端，包含配置选项、超时处理、错误处理等
- **特点**: 
  - 支持超时配置
  - 支持重试机制
  - 更好的错误处理
  - 类型安全的配置接口

```bash
cargo run -- generate --template advanced
```

### 3. React 模板
- **类型**: `react`
- **描述**: 生成 React Hooks 和 API 客户端
- **特点**:
  - 自动生成 React Hooks
  - 状态管理 (loading, error, data)
  - 自动执行和手动刷新
  - TypeScript 类型支持

```bash
cargo run -- generate --template react
```

### 4. Oboss 模板
- **类型**: `oboss`
- **描述**: 生成函数式 API 调用，支持 Mock 版本
- **特点**:
  - 函数式导出，不使用类
  - 每个 API 方法都有正常版本和 Mock 版本
  - 使用 `@/lib/axios` 和 `@/lib/apifox` 作为 HTTP 客户端
  - 自动区分 body 参数和 query 参数
  - 支持 TypeScript 类型

```bash
cargo run -- generate --template oboss
```

## 自定义模板

### 创建自定义模板目录

1. 创建模板目录：
```bash
mkdir my_templates
```

2. 创建模板文件（使用 Handlebars 语法）：
```handlebars
// my_templates/api_client.hbs
// {{folder_name}} API 客户端
// Generated by apifox-flow, do not edit manually

export class {{class_name}} {
  private baseUrl: string;
  private headers: Record<string, string>;

  constructor(baseUrl: string = '{{default_base_url}}', headers: Record<string, string> = {}) {
    this.baseUrl = baseUrl;
    this.headers = { 'Content-Type': 'application/json', ...headers };
  }

{{#each methods}}
  // {{summary}}
  async {{method_name}}({{#if parameters}}params: { {{#each parameters}}{{name}}{{#unless required}}?{{/unless}}: {{type_}}{{#unless @last}}, {{/unless}}{{/each}} }}{{/if}}): Promise<{{response_type}}> {
    const response = await fetch(`${this.baseUrl}{{path}}`, {
      method: '{{http_method}}',
      headers: this.headers,{{#unless is_get}}
      body: JSON.stringify(params),{{/unless}}
    });
    return response.json();
  }

{{/each}}
}
```

3. 使用自定义模板：
```bash
cargo run -- generate --template-dir my_templates
```

## 模板变量

### 主要变量

| 变量名 | 类型 | 描述 |
|--------|------|------|
| `folder_name` | String | 文件夹名称 |
| `class_name` | String | 生成的类名 (PascalCase) |
| `safe_folder_name` | String | 安全的文件夹名称 (用于文件路径) |
| `methods` | Array | API 方法列表 |
| `types` | Array | 类型定义列表 |
| `imports` | Array | 导入语句列表 |
| `import_path` | String | 导入路径 |
| `default_base_url` | String | 默认基础 URL |

### API 方法变量

| 变量名 | 类型 | 描述 |
|--------|------|------|
| `summary` | String | API 方法描述 |
| `method_name` | String | 方法名 (camelCase) |
| `method_name_pascal` | String | 方法名 (PascalCase) |
| `http_method` | String | HTTP 方法 (GET, POST, etc.) |
| `path` | String | API 路径 |
| `parameters` | Array | 参数列表 |
| `response_type` | String | 响应类型 |
| `is_get` | Boolean | 是否为 GET 请求 |
| `has_body` | Boolean | 是否有 body 参数 |
| `has_query_params` | Boolean | 是否有 query 参数 |
| `http_method_lower` | String | HTTP 方法 (小写) |

### 参数变量

| 变量名 | 类型 | 描述 |
|--------|------|------|
| `name` | String | 参数名 |
| `type_` | String | 参数类型 |
| `required` | Boolean | 是否必需 |
| `is_body_param` | Boolean | 是否为 body 参数 |
| `is_query_param` | Boolean | 是否为 query 参数 |

### 类型定义变量

| 变量名 | 类型 | 描述 |
|--------|------|------|
| `name` | String | 类型名 |
| `is_enum` | Boolean | 是否为枚举 |
| `is_interface` | Boolean | 是否为接口 |
| `properties` | Array | 属性列表 |
| `enum_values` | Array | 枚举值列表 |
| `type_` | String | 类型定义 |

## 模板文件命名

模板文件必须使用 `.hbs` 扩展名，并且文件名对应生成的输出文件：

- `api_client.hbs` → `api.ts`
- `types.hbs` → `types.ts`
- `index.hbs` → `index.ts`
- `main_index.hbs` → 主目录的 `index.ts`
- `react_hooks.hbs` → `hooks.ts` (仅 React 模板)

## 自定义 Helper 函数

模板系统支持自定义 Helper 函数：

### 内置 Helper

- `{{to_pascal_case "string"}}` - 转换为 PascalCase
- `{{to_camel_case "string"}}` - 转换为 camelCase

### 使用示例

```handlebars
// 生成类名
export class {{to_pascal_case safe_folder_name}}ApiClient {
  // ...
}

// 生成方法名
async {{to_camel_case method_name}}() {
  // ...
}
```

## 条件渲染

使用 Handlebars 条件语句：

```handlebars
{{#if parameters}}
// 有参数的方法
async {{method_name}}(params: { {{#each parameters}}{{name}}: {{type_}}{{#unless @last}}, {{/unless}}{{/each}} }): Promise<{{response_type}}> {
{{else}}
// 无参数的方法
async {{method_name}}(): Promise<{{response_type}}> {
{{/if}}
```

## 循环渲染

使用 Handlebars 循环语句：

```handlebars
{{#each methods}}
// {{summary}}
async {{method_name}}(): Promise<{{response_type}}> {
  // 方法实现
}
{{/each}}
```

## 完整示例

### 1. 使用内置模板

```bash
# 使用高级模板生成所有代码
cargo run -- generate --template advanced --output advanced_api

# 使用 React 模板生成特定文件夹
cargo run -- generate --folder "Customer Service" --template react --output react_api
```

### 2. 使用自定义模板

```bash
# 使用自定义模板目录
cargo run -- generate --template-dir my_custom_templates --output custom_api

# 结合文件夹和自定义模板
cargo run -- generate --folder "Lucky Draw" --template-dir my_templates --output lucky_draw_api
```

### 3. 模板目录结构示例

```
my_templates/
├── api_client.hbs      # API 客户端模板
├── types.hbs           # 类型定义模板
├── index.hbs           # 索引文件模板
├── main_index.hbs      # 主索引模板
└── react_hooks.hbs     # React Hooks 模板 (可选)
```

## 最佳实践

1. **模板文件命名**: 使用描述性的文件名，便于维护
2. **变量命名**: 使用清晰的变量名，避免与 Handlebars 内置变量冲突
3. **错误处理**: 在模板中包含适当的错误处理逻辑
4. **类型安全**: 确保生成的代码具有良好的 TypeScript 类型支持
5. **文档注释**: 在模板中包含适当的注释和文档

## 故障排除

### 常见问题

1. **变量未找到错误**: 检查变量名是否正确，确保在模板上下文中存在
2. **模板文件未加载**: 确保模板文件使用 `.hbs` 扩展名
3. **语法错误**: 检查 Handlebars 语法是否正确
4. **路径问题**: 确保模板目录路径正确

### 调试技巧

1. 使用简单的测试模板验证变量是否正确传递
2. 检查生成的代码是否符合预期
3. 使用 `--template default` 作为对比基准
4. 逐步构建复杂模板，从简单开始

## 扩展功能

模板系统支持以下扩展功能：

- 自定义 Helper 函数
- 条件渲染
- 循环渲染
- 嵌套模板
- 部分模板 (partials)
- 模板继承

通过模板系统，您可以完全控制生成的 TypeScript 代码的结构和格式，满足各种不同的项目需求。
