文件
jw-beauty/docs/dev/05-API接口文档.md
T
Guoguo 0feb900a1d docs: complete developer documentation (5 guides + index)
- 01-快速开始: local setup for all 3 modules, common issues
- 02-配置说明: all env vars, WeChat/Pay/DB/COS config details
- 03-架构说明: system overview, directory structure, data flows
- 04-部署指南: Tencent Cloud SCF/COS deployment, launch checklist
- 05-API接口文档: all 42 endpoints with params and response format
- README index with audience guide and quick links
2026-05-18 08:11:30 -07:00

1298 行
31 KiB
Markdown
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
# API 接口文档
本文档列出 jw-beauty 后端所有 API 接口,供前端开发和调试参考。
**Base URL**: `https://api.vsai.net.cn`
---
## 通用约定
### 认证方式
需要认证的接口在请求头中携带 JWT:
```
Authorization: Bearer <token>
```
- `requireUser`:需要用户 Token(通过 `/auth/login` 获取)
- `requireAdmin`:需要管理员 Token(通过 `/admin/login` 获取)
### 响应格式
所有接口返回统一 JSON 结构:
```json
{
"code": 0,
"message": "success",
"data": {}
}
```
| code | 含义 |
|------|------|
| 0 | 成功 |
| 1001 | Token 无效或过期 |
| 1002 | 管理员未授权 |
| 1004 | 用户不存在 |
| 1005 | 设备/记录不存在 |
| 1006 | 设备未绑定 |
| 2001 | 参数错误或业务限制 |
| 3001 | 服务端错误 |
### 公共请求头
| Header | 说明 |
|--------|------|
| `Authorization` | Bearer Token |
| `Content-Type` | `application/json`(除文件上传外) |
| `X-Device-Id` | 设备标识(可选) |
| `X-App-Version` | 应用版本号(可选) |
| `X-Platform` | 平台标识(可选) |
### 分页参数
支持分页的列表接口统一使用:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `page` | number | 1 | 页码(从 1 开始) |
| `page_size` | number | 20 | 每页条数(最大 100 |
### Rate Limiting
| 路径 | 限制 |
|------|------|
| `POST /api/v1/auth/login` | 15 分钟内最多 10 次 |
| `POST /api/v1/admin/login` | 15 分钟内最多 5 次 |
| `POST /api/v1/user/avatar` | 15 分钟内最多 20 次 |
| `POST /api/v1/user/phone` | 15 分钟内最多 20 次 |
---
## 健康检查
### `GET /health`
| 项目 | 说明 |
|------|------|
| Auth | 无 |
| 说明 | 健康检查,用于部署验证和监控 |
**响应示例**
```json
{ "code": 0, "message": "success", "data": { "status": "ok" } }
```
---
## 1. 认证模块
### 1.1 `POST /api/v1/auth/login`
| 项目 | 说明 |
|------|------|
| Auth | 无 |
| 说明 | 微信小程序登录。维护模式下拒绝登录。新用户自动注册。 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `code` | string | 是 | `wx.login()` 返回的临时登录凭证 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `token` | string | JWT Token |
| `user_id` | string | 用户 ID |
| `is_new_user` | boolean | 是否新注册用户 |
| `user_info` | object | 用户基本信息 |
| `user_info.nickname` | string | 昵称 |
| `user_info.avatar` | string | 头像 URL |
| `user_info.phone` | string | 手机号 |
| `user_info.gender` | number | 性别(0=未知) |
| `expires_in` | number | Token 有效期(秒),固定 604800(7天) |
**响应示例**
```json
{
"code": 0,
"message": "success",
"data": {
"token": "eyJhbGci...",
"user_id": "1",
"is_new_user": false,
"user_info": {
"user_id": "1",
"nickname": "用户1",
"avatar": "",
"phone": "",
"gender": 0
},
"expires_in": 604800
}
}
```
---
### 1.2 `POST /api/v1/auth/refresh`
| 项目 | 说明 |
|------|------|
| Auth | Bearer Token(可过期不超过 1 天) |
| 说明 | 刷新用户 Token。Token 未过期且剩余有效期超过 7 天时原样返回。 |
**请求 Body**:无
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `token` | string | 新 Token(或原 Token |
| `expires_in` | number | 有效期(秒) |
---
## 2. 用户模块
### 2.1 `GET /api/v1/user/profile`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 获取当前用户资料 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `user_id` | string | 用户 ID |
| `nickname` | string | 昵称 |
| `avatar` | string | 头像 URL |
| `phone` | string | 手机号 |
| `gender` | number | 性别 |
| `bind_time` | null | 保留字段 |
| `device_count` | number | 已绑定设备数量 |
---
### 2.2 `PUT /api/v1/user/profile`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 更新用户资料 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `nickname` | string | 否 | 昵称 |
| `avatar` | string | 否 | 头像 URL(也接受 `avatar_url` |
| `gender` | number | 否 | 性别 |
**响应 `data`**
```json
{ "message": "success" }
```
---
### 2.3 `POST /api/v1/user/avatar`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| Content-Type | `multipart/form-data` |
| 说明 | 上传头像图片到 COS。限制 2MB,仅支持 jpg/png/gif/webp。 |
**请求**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `file` | file | 是 | 图片文件 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `avatar` | string | COS CDN 头像 URL |
---
### 2.4 `POST /api/v1/user/phone`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 微信手机号授权绑定 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `code` | string | 是 | 微信 `getPhoneNumber` 返回的 code |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `phone` | string | 完整手机号(带区号) |
| `pure_phone_number` | string | 不带区号的手机号 |
| `country_code` | string | 国家区号 |
---
## 3. 设备模块
### 3.1 `POST /api/v1/device/bind`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 申请绑定设备。每个用户同时只能绑定一台设备。设备绑定功能可通过系统设置关闭。 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_id` | string | 是 | 设备 ID(产品码) |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `device_id` | string | 设备 ID |
| `bind_token` | string | 绑定令牌(16 字符 hex),用于确认绑定 |
| `subscription` | object | 当前订阅状态 |
| `subscription.plan` | string | 订阅计划(none/trial/monthly/yearly |
| `subscription.remaining_days` | number | 剩余天数 |
---
### 3.2 `POST /api/v1/device/bind/confirm`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 确认绑定设备(蓝牙握手成功后调用) |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_id` | string | 是 | 设备 ID |
| `bind_token` | string | 是 | 绑定令牌 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `message` | string | "success" |
| `subscription` | object | 当前订阅状态 |
---
### 3.3 `POST /api/v1/device/mock-bind`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 环境 | 仅非 production 环境可用 |
| 说明 | 模拟绑定设备,跳过蓝牙确认流程。用于开发调试。 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_id` | string | 是 | 设备 ID |
**响应 `data`**
```json
{ "message": "success", "device_id": "DEV001" }
```
---
### 3.4 `POST /api/v1/device/unbind`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 解绑设备 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_id` | string | 否 | 指定设备 ID,不传则解绑当前设备 |
**响应 `data`**
```json
{ "message": "success" }
```
---
### 3.5 `GET /api/v1/device/list`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 获取当前用户的设备列表 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `devices` | array | 设备列表 |
| `total` | number | 设备数量 |
---
### 3.6 `GET /api/v1/device/:device_id`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 获取已绑定设备详情。只能查看自己绑定的设备。 |
**路径参数**
| 参数 | 说明 |
|------|------|
| `device_id` | 设备 ID |
**响应 `data`**:设备详情对象(含 device_id, device_name, firmware_version, battery, temperature 等)
---
### 3.7 `GET /api/v1/device/command/pending`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 拉取设备待执行的远程指令。拉取后指令标记为已推送。 |
**Query 参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_id` | string | 是 | 设备 ID |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `commands` | array | 指令列表 |
| `commands[].seq` | number | 指令序号(command_id |
| `commands[].opcode` | number | 操作码 |
| `commands[].payload` | object | 指令参数 |
---
### 3.8 `POST /api/v1/device/command/result`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 上报指令执行结果 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `command_id``seq` | number | 是 | 指令 ID |
| `success` | boolean | 否 | 是否成功,默认 true |
**响应 `data`**
```json
{ "message": "success" }
```
---
### 3.9 `POST /api/v1/device/event`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 上报设备事件(错误、温度异常等) |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_id` | string | 是 | 设备 ID |
| `event_type` | string | 否 | 事件类型,默认 `device_error` |
| `error_code` | number | 否 | 错误码 |
| `temperature` | number | 否 | 温度 |
**响应 `data`**
```json
{ "message": "ok" }
```
---
## 4. 订阅模块
### 4.1 `GET /api/v1/subscription/plans`
| 项目 | 说明 |
|------|------|
| Auth | 无 |
| 说明 | 获取可用订阅计划列表。价格和试用天数从系统设置读取。 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `plans` | array | 计划列表 |
| `plans[].key` | string | 计划标识(monthly/yearly/trial |
| `plans[].name` | string | 名称(月卡/年卡/试用) |
| `plans[].price` | number | 价格(分) |
| `plans[].days` | number | 有效天数 |
**响应示例**
```json
{
"code": 0,
"message": "success",
"data": {
"plans": [
{ "key": "monthly", "name": "月卡", "price": 99, "days": 30 },
{ "key": "yearly", "name": "年卡", "price": 899, "days": 365 },
{ "key": "trial", "name": "试用", "price": 0, "days": 7 }
]
}
}
```
---
### 4.2 `GET /api/v1/subscription`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 获取当前用户的订阅状态 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `status` | string | `active` / `expired` / `inactive` |
| `plan` | string | 计划(none/trial/monthly/yearly |
| `start_time` | string | 开始时间(无订阅时无此字段) |
| `expire_time` | string | 到期时间(无订阅时无此字段) |
| `remaining_days` | number | 剩余天数 |
| `trial_used` | boolean | 是否已使用过试用 |
---
### 4.3 `POST /api/v1/subscription/purchase`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 创建购买订单。当前返回订单号和占位支付参数,支付集成待完成。 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `plan``plan_type` | string | 是 | 计划标识(trial/monthly/yearly |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `order_id` | string | 订单号 |
| `payment_params` | object | 支付参数(当前为空对象) |
| `plan` | string | 计划标识 |
| `amount` | number | 金额 |
---
### 4.4 `POST /api/v1/subscription/mock-purchase`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 环境 | 仅非 production 环境可用 |
| 说明 | 模拟购买订阅,直接激活。不支持 trial 计划(trial 请用 `/subscription/trial`)。 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `plan``plan_type` | string | 是 | `monthly``yearly` |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `status` | string | `active` |
| `plan` | string | 计划标识 |
| `remaining_days` | number | 剩余天数 |
---
### 4.5 `POST /api/v1/subscription/trial`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 激活试用订阅。每个用户仅可使用一次。已有有效订阅时不可激活。 |
**请求 Body**:无
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `status` | string | `active` |
| `plan` | string | `trial` |
| `remaining_days` | number | 试用天数(默认 7 |
---
### 4.6 `POST /api/v1/subscription/verify`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 管理员手动激活订阅(临时方案,支付集成前使用) |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `user_id` | number | 是 | 用户 ID |
| `plan``plan_type` | string | 否 | 计划,默认 `monthly` |
| `order_id` | string | 否 | 订单号,不传则自动生成 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `status` | string | `active` |
| `plan` | string | 计划标识 |
| `remaining_days` | number | 剩余天数 |
---
## 5. 护理模块
### 5.1 `GET /api/v1/treatment/history`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 获取当前用户的护理记录列表,支持分页 |
**Query 参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `page` | number | 否 | 页码,默认 1 |
| `page_size` | number | 否 | 每页条数,默认 20 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `total` | number | 总记录数 |
| `page` | number | 当前页码 |
| `page_size` | number | 每页条数 |
| `records` | array | 护理记录列表 |
---
### 5.2 `POST /api/v1/treatment/sync`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 同步护理记录。设备必须已绑定。同时更新设备的电量和温度。 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_id` | string | 是 | 设备 ID |
| `session_id` | string | 否 | 会话 ID,不传自动生成 |
| `start_time` | string | 否 | 开始时间 |
| `end_time` | string | 否 | 结束时间 |
| `regions` | string/array | 否 | 护理区域(数组会用逗号拼接) |
| `total_duration_ms` | number | 否 | 总时长(毫秒) |
| `mode` | number | 否 | 护理模式 |
| `avg_pd` | number | 否 | 平均光密度 |
| `battery` | number | 否 | 电量 |
| `temperature` | number | 否 | 温度 |
| `wavelength` | number | 否 | 波长 |
| `brightness` | number | 否 | 亮度 |
| `pd_values` | object | 否 | PD 传感器数据 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `record_id` | string | 会话 IDsession_id |
---
### 5.3 `GET /api/v1/treatment/:record_id`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 获取单条护理记录详情。只能查看自己的记录。 |
**路径参数**
| 参数 | 说明 |
|------|------|
| `record_id` | 会话 IDsession_id |
**响应 `data`**:护理记录完整对象
---
## 6. 固件模块
### 6.1 `GET /api/v1/firmware/latest`
| 项目 | 说明 |
|------|------|
| Auth | requireUser |
| 说明 | 检查固件更新。返回最新固件信息和有时效的 COS 签名下载 URL。 |
**Query 参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `current_version` | string | 否 | 当前固件版本号 |
**响应 `data`**(有更新):
| 字段 | 类型 | 说明 |
|------|------|------|
| `has_update` | boolean | `true` |
| `version` | string | 最新版本号 |
| `size_bytes` | number | 文件大小(字节) |
| `sha256` | string | 文件 SHA256 校验值 |
| `download_url` | string | 签名下载 URL(有效期 600 秒) |
**响应 `data`**(无更新):
```json
{ "has_update": false }
```
---
## 7. 管理后台模块
所有管理后台接口路径前缀为 `/api/v1/admin`,需要 `requireAdmin` 认证。
### 7.1 认证
#### `POST /api/v1/admin/login`
| 项目 | 说明 |
|------|------|
| Auth | 无 |
| 说明 | 管理员登录。支持 bcrypt 和旧版 salt 哈希两种密码格式(旧格式自动升级)。 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `username` | string | 是 | 用户名 |
| `password` | string | 是 | 密码 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `token` | string | 管理员 JWT Token |
| `admin_id` | string | 管理员 ID |
| `username` | string | 用户名 |
| `real_name` | string | 真实姓名 |
| `role` | string | 角色 |
---
#### `POST /api/v1/admin/password`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 修改管理员密码。新密码最少 6 位。 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `old_password` | string | 是 | 原密码 |
| `new_password` | string | 是 | 新密码(>=6 位) |
**响应 `data`**
```json
{ "message": "success" }
```
---
### 7.2 仪表盘
#### `GET /api/v1/admin/dashboard`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 获取后台首页统计数据 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `device_count` | number | 设备总数 |
| `user_count` | number | 用户总数 |
| `treatment_count` | number | 护理记录总数 |
| `subscription_count` | number | 订阅总数 |
| `sub_stats` | object | 订阅统计详情 |
---
### 7.3 设备管理
#### `GET /api/v1/admin/devices`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 设备列表,支持关键词搜索和分页 |
**Query 参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `keyword` | string | 否 | 搜索关键词(设备 ID/名称) |
| `page` | number | 否 | 页码 |
| `page_size` | number | 否 | 每页条数 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `records` | array | 设备列表 |
| `total` | number | 总数 |
---
#### `POST /api/v1/admin/devices`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 预生成单个产品码(设备) |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_id` | string | 是 | 设备 ID |
| `product_id` | string | 否 | 产品型号,默认 `HOX_LIGHT_MASK` |
| `device_secret` | string | 否 | 设备密钥 |
| `device_name` | string | 否 | 设备名称,默认"光子美容仪" |
| `firmware_version` | string | 否 | 固件版本,默认 `1.0.0` |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `device_id` | string | 已创建的设备 ID |
---
#### `POST /api/v1/admin/devices/batch`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 批量预生成产品码,单次最多 500 个 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_ids` | string[] | 是 | 设备 ID 数组(1-500 个) |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `created` | number | 成功创建数量 |
| `failed` | number | 失败数量 |
---
#### `GET /api/v1/admin/devices/:device_id`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 获取设备详情,含绑定历史和最近护理记录 |
**响应 `data`**:设备信息 + `binding_history`(绑定历史数组)+ `recent_treatments`(最近护理数组)
---
#### `POST /api/v1/admin/devices/:device_id/unbind`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 后台强制解绑设备 |
**响应 `data`**
```json
{ "message": "success" }
```
---
#### `POST /api/v1/admin/devices/:device_id/command`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 向设备推送远程指令 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `opcode` | number | 是 | 操作码 |
| 其他 | any | 否 | 指令参数(整个 body 存入 payload |
**响应 `data`**
```json
{ "message": "queued", "command": { ... } }
```
---
#### `GET /api/v1/admin/devices/:device_id/commands`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 获取设备的指令历史,支持分页 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `records` | array | 指令列表 |
| `total` | number | 总数 |
---
### 7.4 用户管理
#### `GET /api/v1/admin/users`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 用户列表,支持关键词搜索和分页 |
**Query 参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `keyword` | string | 否 | 搜索关键词 |
| `page` | number | 否 | 页码 |
| `page_size` | number | 否 | 每页条数 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `records` | array | 用户列表 |
| `total` | number | 总数 |
---
#### `GET /api/v1/admin/users/:user_id`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 获取用户详情(含订阅、设备等关联信息) |
**响应 `data`**:用户详情对象
---
#### `POST /api/v1/admin/users/:user_id/unbind`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 后台解绑用户的设备 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `device_id` | string | 否 | 指定设备 ID,不传则解绑该用户所有设备 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `message` | string | "success" |
| `affected_rows` | number | 受影响行数 |
---
#### `POST /api/v1/admin/users/:user_id/deactivate`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 注销用户。同时解绑该用户的所有设备。 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `message` | string | "success" |
| `unbound_rows` | number | 解绑的设备数 |
---
### 7.5 订阅管理
#### `GET /api/v1/admin/subscriptions`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 订阅列表,支持按状态筛选和分页 |
**Query 参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `tab` | string | 否 | 筛选标签(如 active/expired |
| `page` | number | 否 | 页码 |
| `page_size` | number | 否 | 每页条数 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `records` | array | 订阅列表 |
| `total` | number | 总数 |
| `stats` | object | 订阅统计 |
---
#### `POST /api/v1/admin/subscriptions`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 为指定用户创建订阅 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `user_id` | number | 是 | 用户 ID |
| `plan` | string | 否 | 计划,默认 `monthly` |
| `amount` | number | 否 | 金额,默认 0 |
| `order_id` | string | 否 | 订单号,自动生成 |
| `days` | number | 否 | 有效天数,默认 30 |
**响应 `data`**
```json
{ "message": "success" }
```
---
#### `POST /api/v1/admin/subscriptions/cancel`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 取消指定订阅 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `subscription_id` | number | 是 | 订阅 ID |
**响应 `data`**
```json
{ "message": "success" }
```
---
### 7.6 护理记录
#### `GET /api/v1/admin/records`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 护理记录列表,支持多条件筛选和分页 |
**Query 参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `keyword` | string | 否 | 搜索关键词 |
| `user_id` | number | 否 | 按用户筛选 |
| `date_from` | string | 否 | 起始日期 |
| `date_to` | string | 否 | 截止日期 |
| `page` | number | 否 | 页码 |
| `page_size` | number | 否 | 每页条数 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `records` | array | 护理记录列表 |
| `total` | number | 总数 |
---
### 7.7 操作日志
#### `GET /api/v1/admin/logs`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 操作日志列表,支持按类型和设备筛选 |
**Query 参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `type` | string | 否 | 日志类型(action 字段) |
| `device_id` | string | 否 | 按设备筛选 |
| `page` | number | 否 | 页码 |
| `page_size` | number | 否 | 每页条数 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `records` | array | 日志列表 |
| `total` | number | 总数 |
---
### 7.8 系统设置
#### `GET /api/v1/admin/settings`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 获取所有系统设置 |
**响应 `data`**KV 对象,包含以下设置项:
| Key | 类型 | 默认值 | 说明 |
|-----|------|--------|------|
| `system_name` | string | "光子美容仪后台" | 系统名称 |
| `admin_email` | string | - | 管理员邮箱 |
| `timezone` | string | - | 时区 |
| `monthly_price` | number | 99 | 月卡价格 |
| `yearly_price` | number | 899 | 年卡价格 |
| `trial_days` | number | 7 | 试用天数 |
| `enable_register` | boolean | true | 是否允许注册 |
| `enable_binding` | boolean | true | 是否允许设备绑定 |
| `enable_free_mode` | boolean | true | 是否启用自由模式 |
| `enable_smart_mode` | boolean | - | 是否启用智能模式 |
| `maintenance_mode` | boolean | false | 维护模式(开启后拒绝用户登录) |
---
#### `POST /api/v1/admin/settings`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 更新系统设置。仅接受白名单内的 key。更新后自动清除设置缓存。 |
**请求 Body**:KV 对象,key 为上表中允许的设置项名。
**请求示例**
```json
{
"monthly_price": 129,
"trial_days": 14,
"maintenance_mode": false
}
```
**响应 `data`**
```json
{ "message": "success" }
```
---
### 7.9 固件管理
#### `GET /api/v1/admin/firmware`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 获取所有固件版本列表 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `records` | array | 固件列表 |
| `total` | number | 总数 |
---
#### `POST /api/v1/admin/firmware`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 登记新固件版本(固件文件需先上传到 COS) |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `version` | string | 是 | 版本号 |
| `cos_key` | string | 是 | COS 对象 Key |
| `device_type` | string | 否 | 设备类型 |
| `size_bytes` | number | 否 | 文件大小 |
| `sha256` | string | 否 | SHA256 校验值 |
| `status` | number | 否 | 状态(0=禁用, 1=启用),默认 1 |
**响应 `data`**
| 字段 | 类型 | 说明 |
|------|------|------|
| `firmware_id` | number | 固件记录 ID |
---
#### `POST /api/v1/admin/firmware/:firmware_id/status`
| 项目 | 说明 |
|------|------|
| Auth | requireAdmin |
| 说明 | 更新固件启用/禁用状态 |
**请求 Body**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `status` | number | 是 | 0=禁用, 1=启用 |
**响应 `data`**
```json
{ "message": "success" }
```
---
## 接口速查索引
| # | Method | Path | Auth | 说明 |
|---|--------|------|------|------|
| - | GET | `/health` | 无 | 健康检查 |
| 1.1 | POST | `/api/v1/auth/login` | 无 | 微信登录 |
| 1.2 | POST | `/api/v1/auth/refresh` | Bearer | Token 刷新 |
| 2.1 | GET | `/api/v1/user/profile` | User | 获取资料 |
| 2.2 | PUT | `/api/v1/user/profile` | User | 更新资料 |
| 2.3 | POST | `/api/v1/user/avatar` | User | 上传头像 |
| 2.4 | POST | `/api/v1/user/phone` | User | 绑定手机号 |
| 3.1 | POST | `/api/v1/device/bind` | User | 申请绑定设备 |
| 3.2 | POST | `/api/v1/device/bind/confirm` | User | 确认绑定 |
| 3.3 | POST | `/api/v1/device/mock-bind` | User | 模拟绑定(非生产) |
| 3.4 | POST | `/api/v1/device/unbind` | User | 解绑设备 |
| 3.5 | GET | `/api/v1/device/list` | User | 设备列表 |
| 3.6 | GET | `/api/v1/device/:device_id` | User | 设备详情 |
| 3.7 | GET | `/api/v1/device/command/pending` | User | 拉取待执行指令 |
| 3.8 | POST | `/api/v1/device/command/result` | User | 上报指令结果 |
| 3.9 | POST | `/api/v1/device/event` | User | 上报设备事件 |
| 4.1 | GET | `/api/v1/subscription/plans` | 无 | 订阅计划列表 |
| 4.2 | GET | `/api/v1/subscription` | User | 订阅状态 |
| 4.3 | POST | `/api/v1/subscription/purchase` | User | 创建购买订单 |
| 4.4 | POST | `/api/v1/subscription/mock-purchase` | User | 模拟购买(非生产) |
| 4.5 | POST | `/api/v1/subscription/trial` | User | 激活试用 |
| 4.6 | POST | `/api/v1/subscription/verify` | Admin | 手动激活订阅 |
| 5.1 | GET | `/api/v1/treatment/history` | User | 护理记录列表 |
| 5.2 | POST | `/api/v1/treatment/sync` | User | 同步护理记录 |
| 5.3 | GET | `/api/v1/treatment/:record_id` | User | 护理记录详情 |
| 6.1 | GET | `/api/v1/firmware/latest` | User | 检查固件更新 |
| 7.1 | POST | `/api/v1/admin/login` | 无 | 管理员登录 |
| 7.1 | POST | `/api/v1/admin/password` | Admin | 修改密码 |
| 7.2 | GET | `/api/v1/admin/dashboard` | Admin | 仪表盘统计 |
| 7.3 | GET | `/api/v1/admin/devices` | Admin | 设备列表 |
| 7.3 | POST | `/api/v1/admin/devices` | Admin | 创建设备 |
| 7.3 | POST | `/api/v1/admin/devices/batch` | Admin | 批量创建设备 |
| 7.3 | GET | `/api/v1/admin/devices/:id` | Admin | 设备详情 |
| 7.3 | POST | `/api/v1/admin/devices/:id/unbind` | Admin | 强制解绑 |
| 7.3 | POST | `/api/v1/admin/devices/:id/command` | Admin | 推送指令 |
| 7.3 | GET | `/api/v1/admin/devices/:id/commands` | Admin | 指令历史 |
| 7.4 | GET | `/api/v1/admin/users` | Admin | 用户列表 |
| 7.4 | GET | `/api/v1/admin/users/:id` | Admin | 用户详情 |
| 7.4 | POST | `/api/v1/admin/users/:id/unbind` | Admin | 解绑用户设备 |
| 7.4 | POST | `/api/v1/admin/users/:id/deactivate` | Admin | 注销用户 |
| 7.5 | GET | `/api/v1/admin/subscriptions` | Admin | 订阅列表 |
| 7.5 | POST | `/api/v1/admin/subscriptions` | Admin | 创建订阅 |
| 7.5 | POST | `/api/v1/admin/subscriptions/cancel` | Admin | 取消订阅 |
| 7.6 | GET | `/api/v1/admin/records` | Admin | 护理记录列表 |
| 7.7 | GET | `/api/v1/admin/logs` | Admin | 操作日志 |
| 7.8 | GET | `/api/v1/admin/settings` | Admin | 获取设置 |
| 7.8 | POST | `/api/v1/admin/settings` | Admin | 更新设置 |
| 7.9 | GET | `/api/v1/admin/firmware` | Admin | 固件列表 |
| 7.9 | POST | `/api/v1/admin/firmware` | Admin | 登记固件 |
| 7.9 | POST | `/api/v1/admin/firmware/:id/status` | Admin | 更新固件状态 |