# API 接口文档

## 概述

留言板 API 服务提供 RESTful 风格的 HTTP 接口，用于留言的提交、查询、回复和统计。

| 项目 | 值 |
|------|-----|
| Base URL | `https://your-domain.com/api.php` |
| 数据格式 | JSON (UTF-8) |
| 认证方式 | `api_key` 参数 |
| 请求方式 | GET / POST |

---

## 认证方式

所有接口均需携带有效的 `api_key` 进行身份认证。密钥在后台「API 管理」中生成。

### 方式一：URL 参数（推荐用于 GET 请求）

```
GET /api.php?action=verify&api_key=YOUR_API_KEY
```

### 方式二：JSON Body（推荐用于 POST 请求）

```json
{
  "api_key": "YOUR_API_KEY",
  "nickname": "张三",
  "content": "留言内容"
}
```

---

## 通用响应格式

所有接口统一返回以下 JSON 结构：

```json
{
  "code": 200,
  "msg": "成功",
  "data": {}
}
```

| 字段 | 类型 | 说明 |
|------|------|------|
| `code` | int | 状态码，200 表示成功 |
| `msg` | string | 提示信息 |
| `data` | object/array/null | 业务数据，部分接口无此字段 |

---

## 错误码

| 状态码 | 说明 |
|--------|------|
| 200 | 请求成功 |
| 400 | 参数错误（缺少必填参数或格式不正确） |
| 401 | 缺少 api_key |
| 403 | 密钥无效 / 已禁用 / 域名受限 |
| 404 | 资源不存在 |
| 405 | 请求方法不允许 |
| 429 | 请求过于频繁（IP 限流） |

---

## 接口列表

### 1. 验证 API Key

测试 API Key 是否有效。

```
GET /api.php?action=verify&api_key=YOUR_KEY
```

**参数**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| api_key | string | 是 | API 密钥 |

**响应示例**

```json
{
  "code": 200,
  "msg": "API Key 有效",
  "data": {
    "name": "我的博客调用"
  }
}
```

---

### 2. 提交留言

提交一条新留言，系统会自动进行敏感词过滤、垃圾检测和 IP 限流。

```
POST /api.php?action=post&api_key=YOUR_KEY
```

**请求参数 (JSON Body)**

| 参数 | 类型 | 必填 | 限制 | 说明 |
|------|------|------|------|------|
| nickname | string | 是 | ≤ 30 字符 | 留言者昵称 |
| content | string | 是 | ≤ 500 字符 | 留言内容 |
| email | string | 否 | 有效邮箱格式 | 留言者邮箱，填写后有人回复时会收到邮件通知 |

**调用示例 (cURL)**

```bash
curl -X POST "https://your-domain.com/api.php?action=post&api_key=YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"nickname":"张三","content":"这是一条测试留言","email":"user@example.com"}'
```

**调用示例 (JavaScript)**

```js
fetch('https://your-domain.com/api.php?action=post&api_key=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    nickname: '张三',
    content: '这是一条测试留言',
    email: 'user@example.com'
  })
})
.then(r => r.json())
.then(d => console.log(d));
```

**响应示例**

```json
{
  "code": 200,
  "msg": "留言提交成功，等待审核",
  "data": {
    "id": 42
  }
}
```

---

### 3. 回复留言

以访客身份回复某条留言，支持多轮互动。回复同样经过敏感词过滤。

```
POST /api.php?action=reply&api_key=YOUR_KEY
```

**请求参数 (JSON Body)**

| 参数 | 类型 | 必填 | 限制 | 说明 |
|------|------|------|------|------|
| message_id | int | 是 | - | 要回复的留言 ID |
| nickname | string | 是 | ≤ 30 字符 | 回复者昵称 |
| content | string | 是 | ≤ 500 字符 | 回复内容 |
| email | string | 否 | 有效邮箱格式 | 回复者邮箱（暂不发送邮件通知） |

**调用示例 (JavaScript)**

```js
fetch('https://your-domain.com/api.php?action=reply&api_key=YOUR_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    message_id: 42,
    nickname: '李四',
    content: '我觉得你说的很对！'
  })
})
.then(r => r.json())
.then(d => console.log(d));
```

**响应示例**

```json
{
  "code": 200,
  "msg": "回复成功",
  "data": {
    "id": 15
  }
}
```

---

### 4. 获取留言列表

分页获取已审核通过的留言列表，每条留言包含其所有回复（管理员回复和用户回复）。

```
GET /api.php?action=list&api_key=YOUR_KEY&page=1&per_page=10
```

**请求参数**

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| page | int | 否 | 1 | 页码 |
| per_page | int | 否 | 10 | 每页数量，最大 50 |

**响应示例**

```json
{
  "code": 200,
  "data": {
    "total": 100,
    "page": 1,
    "per_page": 10,
    "total_pages": 10,
    "messages": [
      {
        "id": 42,
        "nickname": "张三",
        "content": "这是一条留言",
        "city": "中国 广东 深圳",
        "device_info": "手机 | Android 13 | Chrome 120",
        "created_at": "2026-07-11 10:30:00",
        "replies": [
          {
            "id": 1,
            "nickname": "管理员",
            "content": "感谢留言！",
            "is_admin": 1,
            "created_at": "2026-07-11 11:00:00"
          },
          {
            "id": 2,
            "nickname": "李四",
            "content": "我也觉得很好",
            "is_admin": 0,
            "created_at": "2026-07-11 12:00:00"
          }
        ]
      }
    ]
  }
}
```

**返回字段说明**

| 字段 | 类型 | 说明 |
|------|------|------|
| total | int | 留言总数 |
| page | int | 当前页码 |
| per_page | int | 每页数量 |
| total_pages | int | 总页数 |
| messages | array | 留言列表 |
| messages[].id | int | 留言 ID |
| messages[].nickname | string | 昵称 |
| messages[].content | string | 留言内容 |
| messages[].city | string | IP 归属地 |
| messages[].device_info | string | 设备信息 |
| messages[].created_at | string | 发布时间 |
| messages[].replies | array | 该留言的所有回复列表 |
| replies[].id | int | 回复 ID |
| replies[].nickname | string | 回复者昵称 |
| replies[].content | string | 回复内容 |
| replies[].is_admin | int | 是否为管理员回复（1=是，0=否） |
| replies[].created_at | string | 回复时间 |

---

### 5. 获取留言详情

获取单条留言的详细信息，包含该留言的所有回复（管理员回复和用户回复）。

```
GET /api.php?action=detail&api_key=YOUR_KEY&id=42
```

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | int | 是 | 留言 ID |

**响应示例**

```json
{
  "code": 200,
  "msg": "成功",
  "data": {
    "id": 42,
    "nickname": "张三",
    "content": "这是一条留言",
    "city": "中国 广东 深圳",
    "device_info": "手机 | Android 13 | Chrome 120",
    "created_at": "2026-07-11 10:30:00",
    "replies": [
      {
        "id": 1,
        "nickname": "管理员",
        "content": "感谢留言！",
        "is_admin": 1,
        "created_at": "2026-07-11 11:00:00"
      },
      {
        "id": 2,
        "nickname": "李四",
        "content": "有道理",
        "is_admin": 0,
        "created_at": "2026-07-11 12:00:00"
      }
    ]
  }
}
```

**返回字段说明**

| 字段 | 类型 | 说明 |
|------|------|------|
| id | int | 留言 ID |
| nickname | string | 昵称 |
| content | string | 留言内容 |
| city | string | IP 归属地 |
| device_info | string | 设备信息 |
| created_at | string | 发布时间 |
| replies | array | 该留言的所有回复列表 |
| replies[].id | int | 回复 ID |
| replies[].nickname | string | 回复者昵称 |
| replies[].content | string | 回复内容 |
| replies[].is_admin | int | 是否为管理员回复（1=是，0=否） |
| replies[].created_at | string | 回复时间 |

---

### 6. 获取留言统计

获取留言总数和今日新增数量。

```
GET /api.php?action=count&api_key=YOUR_KEY
```

**无额外参数**

**响应示例**

```json
{
  "code": 200,
  "data": {
    "total": 100,
    "today": 5
  }
}
```

---

## 使用场景

| 场景 | 说明 |
|------|------|
| 博客评论 | 在博客侧边栏嵌入最新留言 |
| 网页嵌入 | 任意网页通过 JS 调用显示留言 |
| 移动端 | App / 小程序通过 API 对接 |
| CMS 集成 | 配合其他内容管理系统使用 |

---

## 注意事项

- **妥善保管 API Key**，不要暴露在前端公开代码中
- **域名白名单** — 设置后仅允许指定域名调用 API，支持通配符 `*.example.com`
- 留言会自动进行**敏感词过滤**和**垃圾检测**
- 同一 IP 在指定时间内只能提交一次留言（限流）
- 昵称最长 30 字符，留言内容最长 500 字符
- 建议在**服务端**调用 API，避免 API Key 泄露
- 所有时间字段均为服务器本地时间（`YYYY-MM-DD HH:MM:SS` 格式）
- **邮件通知**：留言者提交 `email` 字段后，当有人回复该留言时，系统会自动发送邮件通知留言者（需在后台配置 SMTP 邮件服务）
