# 应用对接API文档

## 概述

本文档描述了验证平台应用对接API的详细说明，供第三方应用开发者集成使用。

**服务器地址**: `https://gendan.xyz`  
**API基础路径**: `/api/v1/app/{appKey}`

---

## 认证与加密

### 请求认证

- 公开接口：无需认证
- 需认证接口：请求头携带 `Authorization: Bearer {token}`
- Token通过登录接口获取

### 数据加密

平台支持AES和RC4两种加密方式，具体加密类型由应用配置决定。

#### AES加密

- 算法：AES-GCM
- 密钥长度：16/24/32字节（自动填充至32字节）
- 格式：Base64编码（nonce + ciphertext）

#### RC4加密

- 密钥长度：任意长度
- 格式：Base64编码

---

## API接口列表

### 1. 应用信息接口（公开）

#### 1.1 获取应用信息

**请求**
```
GET /api/v1/app/{appKey}/info
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "id": 1,
    "name": "应用名称",
    "description": "应用描述",
    "icon_url": "图标URL",
    "status": "active",
    "billing_type": "balance",
    "login_policy": "strict",
    "max_devices": 1,
    "multi_open_mode": "forbidden",
    "max_instances": 1,
    "enable_trial": false,
    "trial_balance": 0,
    "heartbeat_interval": 60,
    "heartbeat_timeout": 300
  }
}
```

#### 1.2 检查更新

**请求**
```
GET /api/v1/app/{appKey}/check-update?version=1.0.0
```

**参数说明**
- `version` (必填): 客户端当前版本号，必须存在于服务器版本列表中

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "has_update": true,
    "current_version": "1.0.0",
    "latest_version": "1.0.1",
    "download_url": "下载地址",
    "file_size": 1024000,
    "file_hash": "文件哈希",
    "entry_file": "入口文件",
    "update_notes": "更新说明",
    "update_strategy": "optional|forced",
    "update_type": "full|patch",
    "update_method": "auto|manual",
    "changelog": "更新日志",
    "files": [],
    "is_patch": false
  }
}
```

**错误响应**
```json
{
  "code": 400,
  "message": "请提供客户端版本号"
}
```

```json
{
  "code": 404,
  "message": "客户端版本不存在"
}
```

**更新判断逻辑**

基于版本ID（创建顺序）判断，与版本管理页面一致：

| has_update | update_strategy | 含义 |
|------------|-----------------|------|
| false | "" | 已是最新版本，无需更新 |
| true | optional | 有可选更新 |
| true | forced | 必须强制更新（存在更高ID的强制版本） |

**判断规则**
1. 如果存在 `ID > 客户端版本ID` 且 `update_strategy = "forced"` 的版本 → `has_update=true, update_strategy="forced"`
2. 如果存在 `ID > 客户端版本ID` 的版本（无强制更新） → `has_update=true, update_strategy="optional"`
3. 客户端版本ID已是最高 → `has_update=false`

**增量更新**
- 如果 `update_type` 为 `"patch"` 且存在以客户端版本为基础的增量包：
  - `is_patch`: true
  - `base_version`: 基础版本号
  - `patch_url`: 增量包下载地址
  - `patch_size`: 增量包大小
  - `patch_hash`: 增量包哈希

#### 1.3 获取公告列表

**请求**
```
GET /api/v1/app/{appKey}/announcements
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": [
    {
      "id": 1,
      "title": "公告标题",
      "content": "公告内容",
      "type": "info",
      "is_top": true,
      "created_at": "2024-01-01T00:00:00Z"
    }
  ]
}
```

---

### 2. 用户认证接口（公开）

#### 2.1 用户注册

**请求**
```
POST /api/v1/app/{appKey}/register
Content-Type: application/json

{
  "username": "用户名",
  "email": "邮箱（如需验证）",
  "email_code": "邮箱验证码（如需验证）",
  "phone": "手机号（如需短信验证）",
  "sms_code": "短信验证码（如需短信验证）",
  "password": "密码",
  "device_id": "设备ID",
  "device_name": "设备名称",
  "device_type": "android|ios|windows|mac|linux|web",
  "instance_id": "实例ID"
}
```

**响应**
```json
{
  "code": 200,
  "message": "注册成功",
  "data": {
    "user_id": 1
  }
}
```

#### 2.2 用户登录

**请求**
```
POST /api/v1/app/{appKey}/login
Content-Type: application/json

{
  "username": "用户名",
  "password": "密码",
  "device_id": "设备ID（必填）",
  "device_name": "设备名称",
  "device_type": "android|ios|windows|mac|linux|web",
  "instance_id": "实例ID"
}
```

**响应**
```json
{
  "code": 200,
  "message": "登录成功",
  "data": {
    "user_id": 1,
    "token": "JWT令牌"
  }
}
```

**错误响应**
```json
{
  "code": 403,
  "message": "设备绑定数量已达上限，请解绑后再试",
  "data": {
    "error_code": "DEVICE_LIMIT_EXCEEDED",
    "max_devices": 1,
    "device_count": 1,
    "devices": [
      {
        "id": 1,
        "device_id": "xxx",
        "device_name": "设备名",
        "device_type": "windows",
        "online_count": 0,
        "created_at": "2024-01-01T00:00:00Z"
      }
    ]
  }
}
```

#### 2.3 发送邮箱验证码

**请求**
```
POST /api/v1/app/{appKey}/send-email-code
Content-Type: application/json

{
  "email": "邮箱地址",
  "purpose": "register|reset_password"
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "message": "验证码已发送"
  }
}
```

#### 2.4 重置密码

**请求**
```
POST /api/v1/app/{appKey}/reset-password
Content-Type: application/json

{
  "email": "邮箱地址",
  "code": "验证码",
  "password": "新密码（至少6位）"
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "message": "密码重置成功"
  }
}
```

#### 2.5 修改密码

**请求**
```
POST /api/v1/app/{appKey}/change-password
Content-Type: application/json

{
  "username": "用户名",
  "old_password": "原密码",
  "new_password": "新密码（至少6位）"
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "message": "密码修改成功"
  }
}
```

---

### 3. 账户接口（需认证）

#### 3.1 获取账户信息

**请求**
```
POST /api/v1/app/{appKey}/account
Authorization: Bearer {token}
Content-Type: application/json

{
  "user_id": 1
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "user_id": 1,
    "username": "用户名",
    "balance": 100.0,
    "status": "active"
  }
}
```

#### 3.2 心跳上报

**请求**
```
POST /api/v1/app/{appKey}/heartbeat
Authorization: Bearer {token}
Content-Type: application/json

{
  "user_id": 1,
  "device_id": "设备ID",
  "instance_id": "实例ID"
}
```

**响应**
```json
{
  "code": 200,
  "message": "心跳成功",
  "data": {
    "message": "心跳成功",
    "balance": 99.0
  }
}
```

---

### 4. 充值接口（公开）

#### 4.1 卡密充值

**请求**
```
POST /api/v1/app/{appKey}/recharge
Content-Type: application/json

{
  "username": "用户名",
  "card_key": "卡密",
  "device_id": "设备ID"
}
```

**响应**
```json
{
  "code": 200,
  "message": "充值成功",
  "data": {
    "message": "充值成功",
    "value": 30.0
  }
}
```

#### 4.2 试用

**请求**
```
POST /api/v1/app/{appKey}/trial
Content-Type: application/json

{
  "user_id": 1
}
```

**响应**
```json
{
  "code": 200,
  "message": "试用成功",
  "data": {
    "message": "试用成功",
    "trial_balance": 10.0
  }
}
```

---

### 5. 设备管理接口（需认证）

#### 5.1 获取设备列表

**请求**
```
GET /api/v1/app/{appKey}/devices
Authorization: Bearer {token}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": [
    {
      "id": 1,
      "device_id": "设备ID",
      "device_name": "设备名称",
      "device_type": "windows",
      "status": "active",
      "online_sessions": 1,
      "created_at": "2024-01-01T00:00:00Z"
    }
  ]
}
```

#### 5.2 获取设备数量

**请求**
```
POST /api/v1/app/{appKey}/device-count
Authorization: Bearer {token}
Content-Type: application/json

{
  "user_id": 1
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "count": 1,
    "max_devices": 1,
    "remaining": 0
  }
}
```

#### 5.3 解绑设备（需认证）

**请求**
```
POST /api/v1/app/{appKey}/unbind-device
Authorization: Bearer {token}
Content-Type: application/json

{
  "user_id": 1,
  "device_id": "设备ID"
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "message": "解绑成功"
  }
}
```

#### 5.4 解绑设备（用户认证）

**请求**
```
POST /api/v1/app/{appKey}/unbind-device-with-auth
Content-Type: application/json

{
  "username": "用户名",
  "password": "密码",
  "device_id": "设备ID"
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "message": "解绑成功"
  }
}
```

#### 5.5 获取实例列表

**请求**
```
POST /api/v1/app/{appKey}/instances
Authorization: Bearer {token}
Content-Type: application/json

{
  "user_id": 1
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": [
    {
      "id": 1,
      "instance_id": "实例ID",
      "device_id": "设备ID",
      "device_name": "设备名称",
      "is_online": true,
      "last_heartbeat": "2024-01-01T00:00:00Z",
      "created_at": "2024-01-01T00:00:00Z"
    }
  ]
}
```

#### 5.6 强制下线实例

**请求**
```
POST /api/v1/app/{appKey}/instances/{instance_id}/offline
Authorization: Bearer {token}
Content-Type: application/json

{
  "user_id": 1
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "message": "已强制离线"
  }
}
```

---

### 6. 云端数据接口（需认证）

#### 6.1 获取云端常量列表

**请求**
```
GET /api/v1/app/{appKey}/constants
Authorization: Bearer {token}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "config_key": {
      "type": "string",
      "value": "配置值"
    },
    "file_key": {
      "type": "binary",
      "value": "/api/v1/app/{appKey}/constants/file_key/download",
      "file_name": "文件名",
      "file_size": 1024,
      "md5": "文件MD5",
      "mime_type": "application/octet-stream"
    }
  }
}
```

#### 6.2 获取单个云端常量

**请求**
```
GET /api/v1/app/{appKey}/constants/{key}
Authorization: Bearer {token}
```

#### 6.3 下载云端常量文件

**请求**
```
GET /api/v1/app/{appKey}/constants/{key}/download
Authorization: Bearer {token}
```

#### 6.4 获取云端变量列表

**请求**
```
GET /api/v1/app/{appKey}/variables
Authorization: Bearer {token}
```

#### 6.5 获取单个云端变量

**请求**
```
GET /api/v1/app/{appKey}/variables/{key}
Authorization: Bearer {token}
```

#### 6.6 下载云端变量文件

**请求**
```
GET /api/v1/app/{appKey}/variables/{key}/download
Authorization: Bearer {token}
```

#### 6.7 上传云端变量文件

**请求**
```
POST /api/v1/app/{appKey}/variables/{key}/upload
Authorization: Bearer {token}
Content-Type: multipart/form-data

file: 文件内容
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "message": "上传成功",
    "file_url": "文件URL",
    "file_size": 1024,
    "mime_type": "application/octet-stream",
    "original_name": "原文件名",
    "download_url": "下载URL"
  }
}
```

#### 6.8 更新云端变量

**请求**
```
POST /api/v1/app/{appKey}/variables
Authorization: Bearer {token}
Content-Type: application/json

{
  "variables": {
    "key1": "value1",
    "key2": "value2"
  }
}
```

#### 6.9 创建变量记录（Stream类型）

**请求**
```
POST /api/v1/app/{appKey}/variables/{key}/records
Authorization: Bearer {token}
Content-Type: application/json

{
  "field1": "value1",
  "field2": "value2"
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "id": 1,
    "created_at": "2024-01-01T00:00:00Z"
  }
}
```

#### 6.10 获取变量记录列表

**请求**
```
GET /api/v1/app/{appKey}/variables/{key}/records?page=1&page_size=20
Authorization: Bearer {token}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "records": [
      {
        "id": 1,
        "data": {"field": "value"},
        "created_at": "2024-01-01T00:00:00Z"
      }
    ],
    "total": 100,
    "page": 1,
    "page_size": 20,
    "total_pages": 5
  }
}
```

#### 6.11 删除变量记录

**请求**
```
DELETE /api/v1/app/{appKey}/variables/{key}/records/{record_id}
Authorization: Bearer {token}
```

---

### 7. 动态代码接口（需认证）

#### 7.1 执行动态代码

**请求**
```
POST /api/v1/app/{appKey}/dynamic-code/{key}/execute
Authorization: Bearer {token}
Content-Type: application/json

{
  "params": {
    "param1": "value1"
  },
  "user_id": 1
}
```

**响应**
```json
{
  "code": 200,
  "message": "success",
  "data": {
    "result": "执行结果",
    "execution_time": 10
  }
}
```

---

## 错误码说明

| 错误码 | 说明 |
|-------|------|
| 200 | 成功 |
| 400 | 参数错误 |
| 401 | 未授权/Token无效 |
| 403 | 禁止访问/余额不足/设备限制等 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |

## 特殊错误码

| 错误码 | 说明 |
|-------|------|
| DEVICE_LIMIT_EXCEEDED | 设备绑定数量已达上限 |
| IP_LIMIT_EXCEEDED | IP绑定数量已达上限 |
| MULTI_INSTANCE_LIMIT_EXCEEDED | 多开数量已达上限 |

---

## 集成流程

1. 调用 `/info` 获取应用配置信息
2. 调用 `/register` 或 `/login` 获取用户Token
3. 使用Token调用需认证的接口
4. 定期调用 `/heartbeat` 保持在线状态
5. 根据需要调用其他接口

---

## C++ SDK使用示例

```cpp
#include "verify_client.hpp"

int main() {
    // 创建客户端
    verify::Client client("https://gendan.xyz", "your_app_key");
    
    // 获取应用信息
    auto info = client.getAppInfo();
    
    // 用户登录
    auto loginResult = client.login("username", "password", "device_id");
    std::string token = loginResult["token"].asString();
    client.setToken(token);
    
    // 心跳
    client.heartbeat("user_id", "device_id", "instance_id");
    
    // 充值
    client.recharge("username", "card_key", "device_id");
    
    return 0;
}
```
