Files
nanami-web/API.md
2026-05-15 19:17:31 +08:00

545 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Nanami Web · Public API
Bilingual (zh / en) public REST API for the Nanami Turtle WoW platform.
> 标注:🆕 新增 · ✏️ 有变动 · 🌐 支持多语言
- **Base URL生产环境** `https://nanami.rucky.cn`
- **Base URL直连 IP** `http://120.77.146.152:3000`
- **Content-Type** `application/json`
- **认证:** 公共读接口无需认证POST/PUT/DELETE 写接口需要管理员 session不属于公共 API 范围)
---
## 🎮 WoW 客户端版本
平台当前只对外提供 Turtle WoW **1.18** 版本。每个 `Release` / `SoftwareVersion` 仍保留 `wowVersion` 字段用于标识历史数据和数据库约束,但公共网页、后台、下载和更新接口都会固定使用 `1.18`
### 版本解析
- `wow` / `wowVersion` 查询参数可以省略;即使传入其他历史值,也会回落到 `1.18`
- 浏览器 Cookie 不再参与 wow 版本选择
- 列表接口不再支持 `?wow=all` 返回所有历史版本
### 响应字段
- 单条对象上含 `wowVersion`,当前对外返回值为 `"1.18"`
- 列表型响应顶层含 `wowVersion` 字段,回显当前固定过滤值
### 启动器自更新建议
启动器调用 `/api/software/check-update` 时无需传 wow 频道;服务端始终返回 1.18 通道。
```bash
curl 'https://nanami.rucky.cn/api/software/check-update?slug=nanami-launcher&versionCode=1010'
```
---
## 🌐 国际化i18n
所有公共读接口都支持中英双语,通过查询参数选择语言。
### 语言协商
| 来源 | 示例 | 优先级 |
|------|------|--------|
| 查询参数 `lang` | `?lang=en``?lang=zh` | 1最高 |
| 查询参数 `locale` | `?locale=en` | 2`lang` 别名) |
| `Accept-Language` 请求头 | `Accept-Language: en-US,en;q=0.9` | 3 |
| 默认 | — | `zh` |
合法值:`zh``en`。其他值会被忽略,回退到默认。
### 响应字段约定
每条可翻译的文本字段,会同时返回三个键:
| 键名 | 含义 |
|------|------|
| `name` / `summary` / `description` / `changelog` / `title` / `content` | 「规范字段」,按当前 lang 解析后的值 |
| `*Zh`(如 `nameZh` | 原始中文 |
| `*En`(如 `nameEn` | 原始英文 |
响应顶层附带 `lang` 字段,回显本次实际响应使用的语言,便于客户端确认协商结果。
### 回退规则
请求 `lang=en` 时若 `*En` 字段为空,则规范字段回退到中文(保证客户端永远拿到非空内容)。`*Zh` / `*En` 始终是数据库存储的原始值(其中之一可能为空)。
### 兼容性
- **未传 `lang` 的旧客户端不受影响**`name``summary``changelog` 等字段仍是中文,行为与改造前一致
- 新增的 `*Zh` / `*En` 字段是增量字段,旧客户端可以安全忽略
---
## 1. 检查更新 ✏️ 🌐 🎮
```
GET /api/software/check-update?slug={slug}&versionCode={n}&wow={wow}&lang={lang}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| slug | string | ✅ | 软件标识,例如 `nanami-launcher``nanami-launcher-patch` |
| versionCode | number | ❌ | 当前客户端版本号(整数),缺省为 0 |
| wow | string | ❌ | 固定为 `1.18`;可省略 |
| lang | string | ❌ | `zh` / `en`,缺省 `zh` |
**响应示例wow=1.18, lang=en**
```json
{
"hasUpdate": true,
"forceUpdate": false,
"lang": "en",
"wowVersion": "1.18",
"latest": {
"version": "1.0.15",
"versionCode": 1015,
"changelog": "Added Memorial Box feature\n…",
"changelogZh": "添加骨灰盒功能\n…",
"changelogEn": "Added Memorial Box feature\n…",
"downloadUrl": "https://nanami.rucky.cn/api/software/download/abc123?source=launcher",
"fileSize": 0,
"minVersion": null,
"wowVersion": "1.18",
"createdAt": "2026-04-28T14:40:30.844Z"
}
}
```
`forceUpdate=true` 仅当存在更新且最新版被标记为强制更新。下载 URL 自动带 `source=launcher`,启动器更新下载会单独计数。
---
## 2. 下载文件 ✏️
```
GET /api/software/download/{versionId}?source={source}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| versionId | string | ✅ | 路径参数,版本记录 ID |
| source | string | ❌ | 下载来源标记,`launcher` 表示客户端自更新 |
**响应:**
- 本地文件:`Content-Type: application/octet-stream`,二进制流
- 外链文件HTTP 302 跳转
`source=launcher` 时,下载量计入「启动器更新下载」单独计数器。该参数已由 `check-update` 自动附加,启动器无需关心。
---
## 3. 获取最新启动器(网页用) 🌐
```
GET /api/software/latest?info=1&track=1&lang={lang}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| info | string | ❌ | 传 `1` 返回 JSON 元数据;不传则直接返回二进制文件 |
| track | string | ❌ | 仅 `info=1` 时生效,传 `1` 同时累加下载计数 |
| lang | string | ❌ | `zh` / `en`,仅 `info=1` 时影响 changelog 字段 |
**响应示例info=1, lang=en**
```json
{
"available": true,
"version": "1.0.15",
"versionCode": 1015,
"changelog": "Added Memorial Box feature\n…",
"changelogZh": "添加骨灰盒功能\n…",
"changelogEn": "Added Memorial Box feature\n…",
"fileSize": 0,
"createdAt": "2026-04-28T14:40:30.844Z",
"downloadUrl": "/api/software/download/abc123",
"downloadType": "url",
"lang": "en"
}
```
---
## 4. 启动器友好直链 🆕 🎮
```
GET /download/launcher?wow={wow}
```
外部网页可直接 `<a href>` 引用这个地址下载最新版启动器,等价于 `GET /api/software/latest`(无 `info=1`):本地文件直返,外链 302 跳转。
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| wow | string | ❌ | 固定为 `1.18`;可省略 |
⚠️ **第三方链接安全**:这条 URL 是公开嵌入用的,不读用户 cookie始终下载 1.18 通道。
```html
<a href="https://nanami.rucky.cn/download/launcher">下载 Nanami 启动器(默认 WoW 1.18</a>
<a href="https://nanami.rucky.cn/download/launcher?wow=1.18">下载 Nanami 启动器WoW 1.18</a>
```
---
## 5. 上报心跳(在线状态) 🆕
```
POST /api/launcher/heartbeat
Content-Type: application/json
```
**请求体:**
```json
{
"deviceId": "unique-machine-id",
"os": "Windows",
"osVersion": "10.0.19045",
"appVersion": "1.3.0"
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| deviceId | string | ✅ | 设备唯一标识,建议机器码或 UUID 并持久化 |
| os | string | ❌ | 操作系统,例如 `Windows` |
| osVersion | string | ❌ | 系统版本号 |
| appVersion | string | ❌ | 启动器版本 |
**响应:** `{ "ok": true }`
实现建议:启动时发送一次心跳,之后每 60 秒一次;超过 3 分钟未心跳视为离线。
---
## 6. 历史更新日志 ✏️ 🌐 🎮
```
GET /api/software/changelog?slug={slug}&wow={wow}&lang={lang}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| slug | string | ✅ | 软件标识 |
| wow | string | ❌ | 固定为 `1.18`;可省略 |
| lang | string | ❌ | `zh` / `en` |
**响应示例wow=1.18, lang=en**
```json
{
"name": "Nanami Launcher",
"nameZh": "Nanami 启动器",
"nameEn": "Nanami Launcher",
"slug": "nanami-launcher",
"lang": "en",
"wowVersion": "1.18",
"versions": [
{
"version": "1.0.15",
"versionCode": 1015,
"changelog": "Added Memorial Box feature\n…",
"changelogZh": "添加骨灰盒功能\n…",
"changelogEn": "Added Memorial Box feature\n…",
"fileSize": 0,
"isLatest": true,
"forceUpdate": false,
"wowVersion": "1.18",
"createdAt": "2026-04-28T14:40:30.844Z"
}
]
}
```
---
## 7. 软件列表 / 详情 🆕 🌐
### `GET /api/software?lang={lang}`
返回全部软件包及其当前最新版本。
**响应示例:**
```json
[
{
"id": "...",
"slug": "nanami-launcher",
"name": "Nanami Launcher",
"nameZh": "Nanami 启动器",
"nameEn": "Nanami Launcher",
"description": "Nanami addon launcher…",
"descriptionZh": "Nanami 插件启动器…",
"descriptionEn": "Nanami addon launcher…",
"createdAt": "...",
"updatedAt": "...",
"versions": [{ "version": "1.0.15", "isLatest": true, "...": "..." }],
"_count": { "versions": 48 },
"lang": "en"
}
]
```
### `GET /api/software/{idOrSlug}?lang={lang}`
返回单个软件包及其全部历史版本versions 按 versionCode 倒序)。
---
## 8. 插件列表 / 详情 🆕 🌐 🎮
### `GET /api/addons`
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| lang | string | ❌ | `zh` / `en` |
| wow | string | ❌ | 固定为 `1.18`;可省略 |
| published | string | ❌ | 默认 `true`;传 `false` 包括草稿 |
| category | string | ❌ | 按分类过滤 |
| search | string | ❌ | 名称 / 简介模糊匹配,中英都搜 |
**响应示例:**
```json
[
{
"id": "...",
"slug": "nanami-ui",
"name": "Nanami-UI",
"nameZh": "Nanami-UI",
"nameEn": "Nanami-UI",
"summary": "All-in-one UI replacement…",
"summaryZh": "一款为乌龟服精心打造的全功能界面…",
"summaryEn": "All-in-one UI replacement…",
"description": "# Nanami-UI\n…",
"descriptionZh": "# Nanami-UI\n…",
"descriptionEn": "# Nanami-UI\n…",
"iconUrl": "/uploads/...",
"category": "ui",
"published": true,
"totalDownloads": 1234,
"releases": [
{
"id": "...",
"version": "0.9.14",
"changelog": "See the launcher changelog for details.",
"changelogZh": "详见启动器更新日志",
"changelogEn": "See the launcher changelog for details.",
"downloadType": "local",
"filePath": "/uploads/...",
"isLatest": true
}
],
"screenshots": [],
"_count": { "releases": 5 },
"lang": "en"
}
]
```
### `GET /api/addons/{idOrSlug}?lang={lang}`
返回单个插件及其所有 releases按 createdAt 倒序)。
---
## 9. 插件版本Releases 🆕 🌐 🎮
### `GET /api/releases?addonId={id}&wow={wow}&lang={lang}`
列出 release。
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| addonId | string | ❌ | 限定某个插件;缺省返回全平台所有插件的 release |
| wow | string | ❌ | 固定为 `1.18`;可省略 |
| lang | string | ❌ | `zh` / `en` |
**响应示例:**
```json
[
{
"id": "...",
"version": "1.2.5",
"changelog": "2026.04.03 update:\n…",
"changelogZh": "2026.04.03更新:\n…",
"changelogEn": "2026.04.03 update:\n…",
"downloadType": "local",
"filePath": "/uploads/...",
"externalUrl": null,
"gameVersion": "1.18.1",
"downloadCount": 0,
"isLatest": true,
"createdAt": "...",
"addon": {
"id": "...",
"slug": "instancejournal",
"name": "InstanceJournal",
"nameZh": "InstanceJournal",
"nameEn": "InstanceJournal"
},
"lang": "en"
}
]
```
### `GET /api/download/{releaseId}`
直接下载 release 文件(本地文件返二进制,外链 302 跳转),同时累加 release 下载量。
---
## 10. 公告文章 🆕 🌐
### `GET /api/articles`
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| lang | string | ❌ | `zh` / `en` |
| published | string | ❌ | 默认 `true` |
| limit | number | ❌ | 限制条数 |
**响应:**
```json
[
{
"id": "...",
"slug": "shutdown-announcement",
"title": "Server shutdown",
"titleZh": "关服公告",
"titleEn": "Server shutdown",
"summary": "...",
"summaryZh": "...",
"summaryEn": "...",
"content": "Markdown content…",
"contentZh": "Markdown 内容…",
"contentEn": "Markdown content…",
"coverImage": "/uploads/…",
"published": true,
"createdAt": "...",
"updatedAt": "...",
"lang": "en"
}
]
```
### `GET /api/articles/{idOrSlug}?lang={lang}`
返回单篇文章。字段同上。
---
## 11. 站点资源 🌐
### `GET /api/banners?enabled=1`
首页 Hero Banner 图。无可翻译文本,`lang` 参数不影响响应。
```json
[{ "id": "...", "imageUrl": "/uploads/...", "sortOrder": 0, "enabled": true }]
```
### `GET /api/gallery?enabled=1&lang={lang}`
截图画廊。`title` 字段双语。
```json
[
{
"id": "...",
"imageUrl": "/uploads/...",
"title": "Nameplate showcase",
"titleZh": "姓名版展示",
"titleEn": "Nameplate showcase",
"sortOrder": 0,
"enabled": true
}
]
```
---
## 12. 服务器时间
```
GET /api/server-time
```
```json
{ "serverTime": "2026-04-29T08:00:00.000Z", "epochMs": 1798156800000 }
```
供客户端校时与首页倒计时使用。
---
## 错误处理
所有失败响应都返回统一结构:
```json
{ "error": "Slug already exists" }
```
| HTTP | 含义 |
|------|------|
| 400 | 参数缺失或格式错误 |
| 401 | 未授权(写接口) |
| 404 | 资源不存在 |
| 409 | 冲突(如 slug 重复) |
| 500 | 服务端错误 |
---
## 接口一览
| 方法 | 路径 | 状态 | 多语言 | WoW 过滤 | 用途 |
|------|------|------|--------|----------|------|
| GET | `/api/software/check-update` | ✏️ | ✅ | ✅ | 启动器自更新检查 |
| GET | `/api/software/download/{id}` | ✏️ | ❌ | ❌ | 下载启动器文件(按 versionId 精确) |
| GET | `/api/software/latest` | ✏️ | ✅ | ✅ | 最新启动器信息 / 下载(网页用) |
| GET | `/download/launcher` | 🆕 | ❌ | ✅ | 友好直链:始终下载 1.18 最新 |
| POST | `/api/launcher/heartbeat` | — | ❌ | ❌ | 上报启动器在线状态 |
| GET | `/api/software/changelog` | ✏️ | ✅ | ✅ | 启动器历史 changelog |
| GET | `/api/software` | 🆕 | ✅ | ✅ | 软件列表 |
| GET | `/api/software/{idOrSlug}` | 🆕 | ✅ | ✅ | 单个软件 + 全部版本 |
| GET | `/api/addons` | 🆕 | ✅ | ✅ | 插件列表 |
| GET | `/api/addons/{idOrSlug}` | 🆕 | ✅ | ✅ | 单个插件 + 所有 release |
| GET | `/api/releases` | 🆕 | ✅ | ✅ | 插件版本列表 |
| GET | `/api/download/{id}` | — | ❌ | ❌ | 下载插件 release 文件(按 releaseId |
| GET | `/api/articles` | 🆕 | ✅ | ❌ | 公告列表 |
| GET | `/api/articles/{idOrSlug}` | 🆕 | ✅ | ❌ | 单篇公告 |
| GET | `/api/banners` | 🆕 | ❌ | ❌ | Hero Banner 图 |
| GET | `/api/gallery` | 🆕 | ✅ | ❌ | 截图画廊 |
| GET | `/api/server-time` | — | — | ❌ | 服务器时间 |
---
## 调用示例
```bash
# 1.18 启动器最新版(英文 changelog
curl 'https://nanami.rucky.cn/api/software/latest?info=1&lang=en&wow=1.18'
# 1.18 启动器全部历史 changelog中文
curl 'https://nanami.rucky.cn/api/software/changelog?slug=nanami-launcher&wow=1.18&lang=zh'
# 1.18 客户端的 UI 类插件(英文)
curl 'https://nanami.rucky.cn/api/addons?lang=en&category=ui'
# 1.18 启动器友好直链
curl -L -o nanami-launcher-1.18.exe 'https://nanami.rucky.cn/download/launcher?wow=1.18'
# 通过 Accept-Language 协商语言
curl -H 'Accept-Language: en-US,en;q=0.9' 'https://nanami.rucky.cn/api/articles'
```