feat(api): 实现三端统一的JSON API响应契约
- 新增`api_response.py`统一响应封装工具类,提供标准成功/错误响应构造方法 - 重构WonderQ-Admin全局异常处理器,将所有异常转换为标准响应格式 - 修改所有公共和管理端接口的返回逻辑,统一使用`code`(与HTTP状态码一致)、`msg`和`data`的三层结构 - 新增`api-response-contract.md`文档,定义完整的三端统一JSON响应规范 - 更新所有领域API文档,明确业务数据需位于`data`字段内,补充响应格式说明 - 为WonderQ-MiniAPP和WonderQ-Admin-UI新增响应解析逻辑和类型定义,自动完成协议校验和错误处理 - 更新所有测试用例,适配新的响应结构确保接口符合契约要求 - 新增`module-config-api.md`模块配置API文档,补充站点模块配置的接口约定 - 更新项目README文档,调整文档分类顺序将响应契约置于首位
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
|
||||
当前实现:`WonderQ-Admin` 通过迁移 `0015_wanfa` 创建 `WanfaCategory`、`WanfaRoute` 表并导入稳定初始 ID;`WonderQ-Admin-UI` 已接入分类和路线的查询、新增、编辑、删除及排序操作。
|
||||
|
||||
所有 JSON 响应遵循 [三端统一 API 响应契约](./api-response-contract.md),成功业务对象位于 `data`,失败时 `data` 为 `null`。
|
||||
|
||||
路线接口只维护分类和路线摘要字段。路线详情不写入 `WanfaRoute`,由独立 `DetailRecord` 通过 `docs/detail-api.md` 管理,详情记录的 `key` 等于路线 ID。首页玩法推荐和玩法页路线点击后统一跳转 `/pages/detail/index?routeId={route.id}`;无关联路线时才回退到需求页。
|
||||
|
||||
## 领域边界
|
||||
@@ -51,7 +53,7 @@ API 前缀为 `/api/admin`,除登录接口外均需要后台 JWT。
|
||||
- ID 由后端生成并作为非空字符串返回。初始化迁移时应优先保留 `playData.ts` 中已有的稳定 ID。
|
||||
- 分类和路线的数组顺序就是管理端和前台的展示顺序,接口不要求前端依赖 `sortOrder` 字段。
|
||||
- 空集合返回 `[]`,不能返回 `null` 或省略字段。
|
||||
- 失败响应沿用 Admin API 约定,包含 `message`、`code` 和可选的 `details`。
|
||||
- 成功结果放入 `data`;失败返回数字 `code`、`msg`、`data: null`,可选 `errorCode` 和 `details`。
|
||||
- 被首页玩法推荐关联的分类不能直接删除;需先调用首页内容域的移除关联接口,否则返回 `409 WANFA_CATEGORY_RECOMMENDED`。
|
||||
|
||||
## 数据类型
|
||||
@@ -130,22 +132,26 @@ Authorization: Bearer <admin-jwt>
|
||||
|
||||
```json
|
||||
{
|
||||
"categories": [
|
||||
{
|
||||
"id": "family-route",
|
||||
"label": "亲子路线",
|
||||
"routes": [
|
||||
{
|
||||
"id": "family-water",
|
||||
"title": "亲子玩水",
|
||||
"subtitle": "贵州·轻松节奏与自然课堂",
|
||||
"image": "https://example.test/assets/family-water.jpg",
|
||||
"routeCount": 4,
|
||||
"demandKeyword": "亲子玩水"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"categories": [
|
||||
{
|
||||
"id": "family-route",
|
||||
"label": "亲子路线",
|
||||
"routes": [
|
||||
{
|
||||
"id": "family-water",
|
||||
"title": "亲子玩水",
|
||||
"subtitle": "贵州·轻松节奏与自然课堂",
|
||||
"image": "https://example.test/assets/family-water.jpg",
|
||||
"routeCount": 4,
|
||||
"demandKeyword": "亲子玩水"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -163,7 +169,7 @@ Content-Type: application/json
|
||||
{ "label": "亲子路线" }
|
||||
```
|
||||
|
||||
成功返回 `201` 和新分类对象,初始 `routes` 为 `[]`,并追加到分类列表末尾。
|
||||
成功返回 `201` 和 `data` 内的新分类对象,初始 `routes` 为 `[]`,并追加到分类列表末尾。
|
||||
|
||||
### 编辑分类
|
||||
|
||||
@@ -179,7 +185,7 @@ Content-Type: application/json
|
||||
{ "label": "家庭路线" }
|
||||
```
|
||||
|
||||
成功返回更新后的 `WanfaCategory`。不存在的分类返回 `404 WANFA_CATEGORY_NOT_FOUND`。
|
||||
成功返回 `data` 内的更新后 `WanfaCategory`。不存在的分类返回 `404`,业务码为 `WANFA_CATEGORY_NOT_FOUND`。
|
||||
|
||||
### 删除分类
|
||||
|
||||
@@ -188,10 +194,14 @@ DELETE /api/admin/wanfa/categories/{categoryId}
|
||||
Authorization: Bearer <admin-jwt>
|
||||
```
|
||||
|
||||
为避免误删路线,分类仍包含路线时不得级联删除,应返回 `409 WANFA_CATEGORY_NOT_EMPTY`。删除前由 Admin UI 提示先移除分类内路线。删除成功返回:
|
||||
为避免误删路线,分类仍包含路线时不得级联删除,应返回 `409`,业务码为 `WANFA_CATEGORY_NOT_EMPTY`。删除前由 Admin UI 提示先移除分类内路线。删除成功返回:
|
||||
|
||||
```json
|
||||
{ "id": "family-route" }
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": { "id": "family-route" }
|
||||
}
|
||||
```
|
||||
|
||||
### 分类排序
|
||||
@@ -211,10 +221,14 @@ Content-Type: application/json
|
||||
成功返回:
|
||||
|
||||
```json
|
||||
{ "items": [] }
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": { "items": [] }
|
||||
}
|
||||
```
|
||||
|
||||
其中 `items` 为排序后的 `WanfaCategory[]`。缺少 ID、包含未知 ID 或出现重复 ID 时返回 `400 WANFA_CATEGORY_REORDER_INVALID`。
|
||||
其中 `items` 为排序后的 `WanfaCategory[]`。缺少 ID、包含未知 ID 或出现重复 ID 时返回 `400`,业务码为 `WANFA_CATEGORY_REORDER_INVALID`。
|
||||
|
||||
### 新增路线
|
||||
|
||||
@@ -236,7 +250,7 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
成功返回 `201` 和新建的 `WanfaRoute`,并追加到对应分类路线末尾。分类不存在返回 `404 WANFA_CATEGORY_NOT_FOUND`。
|
||||
成功返回 `201` 和 `data` 内新建的 `WanfaRoute`,并追加到对应分类路线末尾。分类不存在返回 `404`,业务码为 `WANFA_CATEGORY_NOT_FOUND`。
|
||||
|
||||
### 编辑路线
|
||||
|
||||
@@ -246,7 +260,7 @@ Authorization: Bearer <admin-jwt>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
请求体为 `WanfaRoutePatch`,只更新提交的字段。成功返回更新后的 `WanfaRoute`;分类或路线不存在时分别返回 `404 WANFA_CATEGORY_NOT_FOUND` 或 `404 WANFA_ROUTE_NOT_FOUND`。
|
||||
请求体为 `WanfaRoutePatch`,只更新提交的字段。成功返回 `data` 内更新后的 `WanfaRoute`;分类或路线不存在时分别返回 `404`,业务码为 `WANFA_CATEGORY_NOT_FOUND` 或 `WANFA_ROUTE_NOT_FOUND`。
|
||||
|
||||
### 删除路线
|
||||
|
||||
@@ -255,7 +269,7 @@ DELETE /api/admin/wanfa/categories/{categoryId}/routes/{routeId}
|
||||
Authorization: Bearer <admin-jwt>
|
||||
```
|
||||
|
||||
成功返回 `{ "id": "..." }`。删除后,分类内路线保持原有相对顺序。
|
||||
成功返回 `data: { "id": "..." }`。删除后,分类内路线保持原有相对顺序。
|
||||
|
||||
### 分类内路线排序
|
||||
|
||||
@@ -274,10 +288,14 @@ Content-Type: application/json
|
||||
成功返回排序后的路线:
|
||||
|
||||
```json
|
||||
{ "items": [] }
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": { "items": [] }
|
||||
}
|
||||
```
|
||||
|
||||
分类不存在返回 `404 WANFA_CATEGORY_NOT_FOUND`;路线 ID 不完整、重复或不属于该分类时返回 `400 WANFA_ROUTE_REORDER_INVALID`。
|
||||
分类不存在返回 `404`,业务码为 `WANFA_CATEGORY_NOT_FOUND`;路线 ID 不完整、重复或不属于该分类时返回 `400`,业务码为 `WANFA_ROUTE_REORDER_INVALID`。
|
||||
|
||||
## 当前本地数据映射
|
||||
|
||||
|
||||
Reference in New Issue
Block a user