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:
@@ -22,6 +22,8 @@
|
||||
|
||||
`key` 固定使用玩法路线 ID(即 `WanfaRoute.id`,例如 `family-water`),但 `DetailRecord` 不建立数据库外键。详情页通过 `/pages/detail/index?routeId={key}` 定位内容;详情记录删除不会跨领域级联删除路线或其他数据。
|
||||
|
||||
所有 JSON 响应遵循 [三端统一 API 响应契约](./api-response-contract.md),成功业务对象位于 `data`,失败时 `data` 为 `null`。
|
||||
|
||||
## 与 `detailPresentation.ts` 的关系
|
||||
|
||||
`detailPresentation.ts` 是前台展示适配器,不是持久化模型:
|
||||
@@ -54,7 +56,7 @@ API 前缀为 `/api/admin`,除登录接口外均需要后台 JWT。
|
||||
- 创建和编辑返回最新详情对象;排序接口返回排序后的 `items`。
|
||||
- ID 由后端生成并作为非空字符串返回;`key` 由调用方提供并保持稳定。
|
||||
- 空列表返回 `[]`,不能返回 `null` 或省略字段。
|
||||
- 失败响应沿用 Admin API 约定,包含 `message`、`code` 和可选的 `details`。
|
||||
- 成功结果放入 `data`;失败返回数字 `code`、`msg`、`data: null`,可选 `errorCode` 和 `details`。
|
||||
|
||||
## 数据类型
|
||||
|
||||
@@ -141,26 +143,30 @@ Authorization: Bearer <admin-jwt>
|
||||
|
||||
```json
|
||||
{
|
||||
"details": [
|
||||
{
|
||||
"id": "detail-001",
|
||||
"key": "classic-panorama",
|
||||
"eyebrow": "玩法推荐",
|
||||
"duration": "5天4晚",
|
||||
"title": "经典贵州全景",
|
||||
"subtitle": "贵州·瀑布、苗寨、古城与山地风光",
|
||||
"intro": "沿着贵州山地的自然纹理深入探索。",
|
||||
"highlights": ["核心景观串联", "小团出行,按同行人节奏调整"],
|
||||
"included": ["行程内用车与接送服务"],
|
||||
"excluded": ["往返大交通及个人消费"],
|
||||
"notes": ["贵州多山多雨,请准备防滑鞋和轻便雨具。"],
|
||||
"gallery": ["https://example.test/assets/detail-01.jpg"],
|
||||
"isActive": true,
|
||||
"sortOrder": 0,
|
||||
"createdAt": "2026-01-01T00:00:00Z",
|
||||
"updatedAt": "2026-01-01T00:00:00Z"
|
||||
}
|
||||
]
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"details": [
|
||||
{
|
||||
"id": "detail-001",
|
||||
"key": "classic-panorama",
|
||||
"eyebrow": "玩法推荐",
|
||||
"duration": "5天4晚",
|
||||
"title": "经典贵州全景",
|
||||
"subtitle": "贵州·瀑布、苗寨、古城与山地风光",
|
||||
"intro": "沿着贵州山地的自然纹理深入探索。",
|
||||
"highlights": ["核心景观串联", "小团出行,按同行人节奏调整"],
|
||||
"included": ["行程内用车与接送服务"],
|
||||
"excluded": ["往返大交通及个人消费"],
|
||||
"notes": ["贵州多山多雨,请准备防滑鞋和轻便雨具。"],
|
||||
"gallery": ["https://example.test/assets/detail-01.jpg"],
|
||||
"isActive": true,
|
||||
"sortOrder": 0,
|
||||
"createdAt": "2026-01-01T00:00:00Z",
|
||||
"updatedAt": "2026-01-01T00:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -171,7 +177,7 @@ GET /api/admin/details/{detailId}
|
||||
Authorization: Bearer <admin-jwt>
|
||||
```
|
||||
|
||||
成功返回单个 `DetailRecord`。记录不存在返回 `404 DETAIL_NOT_FOUND`。
|
||||
成功返回 `data` 内的单个 `DetailRecord`。记录不存在返回 `404`,业务码为 `DETAIL_NOT_FOUND`。
|
||||
|
||||
### 新增详情
|
||||
|
||||
@@ -181,7 +187,7 @@ Authorization: Bearer <admin-jwt>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
请求体为 `DetailCreate`。成功返回 `201` 和新建的 `DetailRecord`;未传 `sortOrder` 时追加到当前列表末尾。
|
||||
请求体为 `DetailCreate`。成功返回 `201` 和 `data` 内新建的 `DetailRecord`;未传 `sortOrder` 时追加到当前列表末尾。
|
||||
|
||||
### 编辑详情
|
||||
|
||||
@@ -191,7 +197,7 @@ Authorization: Bearer <admin-jwt>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
请求体为 `DetailPatch`,只更新提交的字段。修改 `key` 时仍须保证全局唯一。成功返回更新后的 `DetailRecord`;记录不存在返回 `404 DETAIL_NOT_FOUND`,`key` 冲突返回 `409 DETAIL_KEY_EXISTS`。
|
||||
请求体为 `DetailPatch`,只更新提交的字段。修改 `key` 时仍须保证全局唯一。成功返回 `data` 内更新后的 `DetailRecord`;记录不存在返回 `404`,业务码为 `DETAIL_NOT_FOUND`,`key` 冲突返回 `409`,业务码为 `DETAIL_KEY_EXISTS`。
|
||||
|
||||
### 删除详情
|
||||
|
||||
@@ -203,7 +209,11 @@ Authorization: Bearer <admin-jwt>
|
||||
成功返回:
|
||||
|
||||
```json
|
||||
{ "id": "detail-001" }
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": { "id": "detail-001" }
|
||||
}
|
||||
```
|
||||
|
||||
删除后应重新规范化剩余记录的 `sortOrder`,从 `0` 开始连续编号。详情记录没有 Product、订单或线索外键,因此删除不触发跨领域级联操作。
|
||||
@@ -225,7 +235,11 @@ Content-Type: application/json
|
||||
成功返回:
|
||||
|
||||
```json
|
||||
{ "items": [] }
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": { "items": [] }
|
||||
}
|
||||
```
|
||||
|
||||
其中 `items` 为更新 `sortOrder` 后的 `DetailRecord[]`。缺少 ID、包含未知 ID 或出现重复 ID 时返回 `400 DETAIL_REORDER_INVALID`。
|
||||
|
||||
Reference in New Issue
Block a user