# API 参考文档

## 基本信息

- **基础 URL**: `http://localhost:3000`
- **认证方式**: JWT Bearer 令牌
- **Content-Type**: `application/json`

## 认证 API

### 用户注册

```http
POST /auth/register
Content-Type: application/json

{
  "username": "string",
  "password": "string"
}
```

**响应**:

```json
{
  "message": "用户创建成功",
  "user": {
    "id": "string",
    "username": "string",
    "isAdmin": false
  }
}
```

### 用户登录

```http
POST /auth/login
Content-Type: application/json

{
  "username": "string", 
  "password": "string"
}
```

**响应**:

```json
{
  "access_token": "jwt_token_string",
  "user": {
    "id": "string",
    "username": "string",
    "isAdmin": false
  }
}
```

### 密码修改

```http
POST /auth/change-password
Authorization: Bearer <token>
Content-Type: application/json

{
  "currentPassword": "string",
  "newPassword": "string"
}
```

## 模型配置 API

### 获取模型列表

```http
GET /model-configs
Authorization: Bearer <token>
```

**响应**:

```json
[
  {
    "id": "string",
    "name": "string",
    "provider": "openai|gemini",
    "modelId": "string",
    "baseUrl": "string",
    "type": "llm|embedding|rerank",
    "supportsVision": boolean
  }
]
```

### 创建模型配置

```http
POST /model-configs
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "string",
  "provider": "openai|gemini", 
  "modelId": "string",
  "baseUrl": "string",
  "apiKey": "string",
  "type": "llm|embedding|rerank",
  "supportsVision": boolean
}
```

### 更新模型配置

```http
PUT /model-configs/:id
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "string",
  "apiKey": "string",
  // ... 其他字段
}
```

### 删除模型配置

```http
DELETE /model-configs/:id
Authorization: Bearer <token>
```

## 知识库 API

### 文件上传

```http
POST /upload
Authorization: Bearer <token>
Content-Type: multipart/form-data

{
  "file": File,
  "chunkSize": number,
  "chunkOverlap": number,
  "embeddingModelId": "string",
  "mode": "fast|precise"  // 处理模式
}
```

**响应**:

```json
{
  "id": "string",
  "name": "string",
  "originalName": "string",
  "size": number,
  "mimetype": "string",
  "status": "pending|indexing|completed|failed"
}
```

### 获取文件列表

```http
GET /knowledge-bases
Authorization: Bearer <token>
```

**响应**:

```json
[
  {
    "id": "string",
    "name": "string", 
    "originalName": "string",
    "size": number,
    "mimetype": "string",
    "status": "pending|indexing|completed|failed",
    "createdAt": "datetime"
  }
]
```

### 删除文件

```http
DELETE /knowledge-bases/:id
Authorization: Bearer <token>
```

### 清空知识库

```http
DELETE /knowledge-bases/clear
Authorization: Bearer <token>
```

## 聊天 API

### 流式聊天

```http
POST /chat/stream
Authorization: Bearer <token>
Content-Type: application/json

{
  "message": "string",
  "history": [
    {
      "role": "user|assistant",
      "content": "string"
    }
  ],
  "userLanguage": "zh|en|ja"
}
```

**响应**: Server-Sent Events (SSE)

```
data: {"type": "content", "data": "正在搜索知识库..."}

data: {"type": "content", "data": "找到相关信息..."}

data: {"type": "content", "data": "回答内容片段"}

data: {"type": "sources", "data": [
  {
    "fileName": "string",
    "content": "string", 
    "score": number,
    "chunkIndex": number
  }
]}

data: [DONE]
```

## 用户设置 API

### 获取用户设置

```http
GET /user-settings
Authorization: Bearer <token>
```

**响应**:

```json
{
  "selectedLLMId": "string",
  "selectedEmbeddingId": "string", 
  "selectedRerankId": "string",
  "temperature": number,
  "maxTokens": number,
  "topK": number,
  "enableRerank": boolean,
  "similarityThreshold": number,
  "enableFullTextSearch": boolean,
  "language": "zh|en|ja"
}
```

### 更新用户设置

```http
PUT /user-settings
Authorization: Bearer <token>
Content-Type: application/json

{
  "selectedLLMId": "string",
  "temperature": number,
  "maxTokens": number,
  // ... 其他设置字段
}
```

## 视觉管道 API

### 获取推荐模式

```http
GET /api/vision/recommend-mode?file=xxx&size=xxx
Authorization: Bearer <token>
```

**响应**:

```json
{
  "recommendedMode": "precise",
  "reason": "由于文件较大，推荐使用高精度模式",
  "estimatedCost": 0.5,
  "estimatedTime": 60,
  "warnings": ["处理时间可能会较长", "会产生API使用费用"]
}
```

### LibreOffice 转换服务

```http
POST /libreoffice/convert
Content-Type: multipart/form-data

{
  "file": File
}
```

**响应**:

```json
{
  "pdf_path": "/uploads/document.pdf",
  "converted": true,
  "original": "document.docx",
  "file_size": 102400
}
```

### 健康检查

```http
GET /libreoffice/health
```

**响应**:

```json
{
  "status": "healthy",
  "service": "libreoffice-converter",
  "version": "1.0.0",
  "uptime": 3600.5
}
```

## 用户管理 API（管理员专用）

### 获取用户列表

```http
GET /users
Authorization: Bearer <admin_token>
```

### 创建用户

```http
POST /users
Authorization: Bearer <admin_token>
Content-Type: application/json

{
  "username": "string",
  "password": "string",
  "isAdmin": boolean
}
```

### 删除用户

```http
DELETE /users/:id
Authorization: Bearer <admin_token>
```

## 错误响应格式

```json
{
  "statusCode": number,
  "message": "string",
  "error": "string"
}
```

## 状态码说明

- `200` - 成功
- `201` - 创建成功
- `400` - 请求参数无效
- `401` - 认证错误 / 令牌无效
- `403` - 权限不足
- `404` - 资源未找到
- `409` - 资源冲突
- `500` - 服务器内部错误

## 实现示例

### JavaScript/TypeScript

```javascript
// 登录
const loginResponse = await fetch('/auth/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    username: 'user',
    password: 'password'
  })
});

const { access_token } = await loginResponse.json();

// 获取文件列表
const filesResponse = await fetch('/knowledge-bases', {
  headers: {
    'Authorization': `Bearer ${access_token}`
  }
});

const files = await filesResponse.json();

// 流式聊天
const chatResponse = await fetch('/chat/stream', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${access_token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    message: '你好',
    history: [],
    userLanguage: 'ja'
  })
});

const reader = chatResponse.body.getReader();
// SSE 流的处理...
```

---

# 开放API功能实现总结

## 概述

本项目已实现完整的开放API功能，支持外部系统通过API Key进行认证和访问。

## 后端实现

### API控制器

#### 基础API控制器 (`ApiController`)

| 端点 | 方法 | 描述 | 认证方式 |
|------|------|------|----------|
| `/health` | GET | 健康检查 | 无 |
| `/chat` | POST | 简单聊天接口 | JWT |

#### V1版本开放API控制器 (`ApiV1Controller`)

| 端点 | 方法 | 描述 | 认证方式 |
|------|------|------|----------|
| `/api/v1/chat` | POST | RAG聊天（支持流式SSE和JSON响应） | API Key |
| `/api/v1/search` | POST | 知识库混合搜索 | API Key |
| `/api/v1/knowledge-bases` | GET | 列出知识库文件 | API Key |
| `/api/v1/knowledge-bases/upload` | POST | 上传文件到知识库 | API Key |
| `/api/v1/knowledge-bases/:id` | DELETE | 删除知识库文件 | API Key |
| `/api/v1/knowledge-bases/:id` | GET | 获取单个文件详情 | API Key |

### API Key认证机制

**文件位置**: `server/src/auth/api-key.guard.ts`

支持两种方式传递API Key：
- `Authorization: Bearer kb_xxx` 头
- `x-api-key` 头

**API Key格式**: `kb_` + 64位十六进制字符串

### API Key数据模型

**文件位置**: `server/src/auth/entities/api-key.entity.ts`

```typescript
@Entity('api_keys')
export class ApiKey {
    id: string;           // UUID主键
    userId: string;       // 关联用户ID
    key: string;          // API Key值（唯一）
    createdAt: Date;      // 创建时间
}
```

### API Key管理服务

**文件位置**: `server/src/user/user.service.ts`

| 方法 | 描述 |
|------|------|
| `findByApiKey(apiKey)` | 通过API Key查找用户 |
| `getOrCreateApiKey(userId)` | 获取或创建用户的API Key |
| `regenerateApiKey(userId)` | 重新生成API Key |

## 前端实现

### 登录支持

**文件位置**: `web/src/pages/auth/Login.tsx`

支持两种登录方式：
- 用户名/密码登录
- API Key直接登录

### API客户端

**文件位置**: `web/services/apiClient.ts`

- 自动在请求头中添加 `x-api-key`
- 支持多租户切换（`x-tenant-id`）

### 认证上下文

**文件位置**: `web/src/contexts/AuthContext.tsx`

- 管理API Key状态
- 持久化存储到 `localStorage`

## 功能特点

| 特性 | 状态 | 说明 |
|------|------|------|
| API Key认证 | ✅ 已实现 | 支持Bearer Token和x-api-key两种方式 |
| 多租户隔离 | ✅ 已实现 | 每个API Key关联到特定用户和租户 |
| RAG聊天（流式） | ✅ 已实现 | 支持SSE流式响应 |
| 知识库搜索 | ✅ 已实现 | 支持向量搜索和全文搜索的混合搜索 |
| 文件上传/管理 | ✅ 已实现 | 支持文件上传、列表查询和删除 |
| 前端API Key登录 | ✅ 已实现 | 支持直接使用API Key登录 |

## 使用示例

### 使用API Key进行认证

```javascript
// 使用x-api-key头
const response = await fetch('/api/v1/chat', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'kb_your_api_key_here'
  },
  body: JSON.stringify({
    message: '你好',
    stream: false
  })
});

// 或使用Authorization头
const response = await fetch('/api/v1/chat', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer kb_your_api_key_here'
  },
  body: JSON.stringify({
    message: '你好',
    stream: true
  })
});
```

### 上传文件到知识库

```javascript
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('mode', 'fast');
formData.append('chunkSize', '1000');
formData.append('chunkOverlap', '200');

const response = await fetch('/api/v1/knowledge-bases/upload', {
  method: 'POST',
  headers: {
    'x-api-key': 'kb_your_api_key_here'
  },
  body: formData
});
```

## 已完成功能

| 功能 | 状态 | 说明 |
|------|------|------|
| API Key管理界面 | ✅ 已实现 | 设置页面提供API Key的查看/复制/重新生成功能 |
| API使用示例 | ✅ 已实现 | 设置页面提供cURL示例和认证说明 |
| 多租户隔离 | ✅ 已实现 | 每个API Key关联到特定用户和租户 |

## 相关文件清单

### 后端文件
- `server/src/api/api.controller.ts` - 基础API控制器
- `server/src/api/api-v1.controller.ts` - V1版本开放API控制器
- `server/src/api/api.service.ts` - API服务
- `server/src/api/api.module.ts` - API模块
- `server/src/auth/api-key.guard.ts` - API Key认证守卫
- `server/src/auth/entities/api-key.entity.ts` - API Key实体
- `server/src/user/user.service.ts` - 用户服务（包含API Key管理）
- `server/src/user/user.controller.ts` - 用户控制器（API Key相关接口）

### 前端文件
- `web/src/pages/auth/Login.tsx` - 登录页面（支持API Key登录）
- `web/src/contexts/AuthContext.tsx` - 认证上下文
- `web/services/apiClient.ts` - API客户端
- `web/components/views/SettingsView.tsx` - 设置页面（API Key管理界面）
- `web/services/apiKeyService.ts` - API Key服务
