主题
API 文档总览
探字星球 Mock API 文档(32 个 RESTful 端点,6 大模块)。所有端点由 mockjs 拦截 axios 请求实现,模拟网络延迟 50-100ms,数据持久化到 localStorage。
统一约定
响应格式
typescript
interface ApiResponse<T = unknown> {
code: number // 0 = 成功,非 0 = 失败
msg: string // "ok" 或错误描述
data: T // 业务数据
}错误码
| code | 含义 | 触发场景 |
|---|---|---|
| 0 | 成功 | 正常请求 |
| 400 | 参数错误 | 必填缺失、参数无效 |
| 404 | 资源不存在 | 路径参数对应的资源未找到 |
| 423 | 已锁定 | 商店密码连续错误 5 次后锁定 30 分钟 |
网络与持久化
- 网络延迟:
Mock.setup({ timeout: "50-100" })(mock/index.ts) - 持久化:每 10 秒自动保存 + 页面关闭时
beforeunload保存 - 存储位置:localStorage 多键结构(
tzxq_user_profile/tzxq_user_settings/tzxq_game_progress等 9 键),旧版单一键tzxq_mock_db自动迁移
API 调用链
页面 → Pinia Store → api-service.ts → axios → Mock 拦截 → mock/modules/* → mock/data/* → localStorage源码入口:
web/src/services/api-service.ts(axios 封装 + 响应拦截器)web/src/mock/index.ts(Mock 入口,注册所有模块)web/src/mock/utils.ts(success()/fail()/paginate()/parsePagination())
6 大模块 32 端点
| 模块 | 端点数 | 文档 | Mock 文件 |
|---|---|---|---|
| user | 9 | user.md | mock/modules/user/profile.ts(2)+ exp-points.ts(5)+ badges.ts(2) |
| character | 4 | character.md | mock/modules/character/list.ts |
| game | 7 | game.md | mock/modules/game/config.ts(3)+ progress.ts(2)+ powerups.ts(2) |
| achievement | 2 | achievement.md | mock/modules/achievement/level.ts + badges.ts |
| shop | 9 | shop.md | mock/modules/shop/rewards.ts(5)+ redeem.ts(2)+ password.ts(2) |
| planet | 1 | planet.md | mock/modules/planet/list.ts |
| 合计 | 32 | — | — |
⚠️ AP7:路由注册顺序约束
关键约束:
GET /api/v1/characters/categories必须在GET /api/v1/characters/:char之前注册,否则categories会被通用模式/:char误匹配为单字名称。
源码位置:web/src/mock/modules/character/list.ts
typescript
// 第 14 行:GET /characters(列表)
Mock.mock(/\/api\/v1\/characters(\?.*)?$/, "get", ...);
// 第 42 行:GET /characters/categories(必须在 /:char 之前)
Mock.mock(/\/api\/v1\/characters\/categories(\?.*)?$/, "get", ...);
// 第 47 行:GET /characters/categories/:id/chars
Mock.mock(/\/api\/v1\/characters\/categories\/([^/?]+)\/chars(\?.*)?$/, "get", ...);
// 第 62 行:GET /characters/:char(必须在 /categories 之后)
Mock.mock(/\/api\/v1\/characters\/([^/?]+)$/, "get", ...);类似约束也存在于 game/config.ts:GET /games/data 必须在 GET /games/:id 之前(通过 if (gameId === "data") 提前拦截)。