feat: 新增客片案例与团队共创模块,重构玩法与配置
- 新增客片案例全流程功能,包含前台页面、管理端配置、后端API、数据库迁移与文档 - 新增团队共创详情页面与对应接口 - 重构玩法模块:将静态playData替换为动态API获取,拆分类型定义到playTypes.ts - 优化vite构建配置与环境变量处理,调整详情页操作栏文案 - 更新全量相关文档与配图,新增客片案例、团队共创API文档 - 新增测试用例,完善数据归一化逻辑 - 调整路由配置与环境变量示例文件
This commit is contained in:
@@ -11,7 +11,8 @@
|
||||
3. `wanfa-api.md`
|
||||
4. `concierge-api.md`
|
||||
5. `detail-api.md`
|
||||
6. `public-api.md`
|
||||
6. `team-building-api.md`
|
||||
7. `public-api.md`
|
||||
|
||||
管理前端开发:
|
||||
|
||||
@@ -21,13 +22,15 @@
|
||||
4. `wanfa-api.md`
|
||||
5. `concierge-api.md`
|
||||
6. `detail-api.md`
|
||||
7. `module-config-api.md`
|
||||
7. `team-building-api.md`
|
||||
8. `module-config-api.md`
|
||||
|
||||
MiniAPP 前台开发:
|
||||
|
||||
1. `integration-workflow.md`
|
||||
2. `public-api.md`
|
||||
3. `development-status.md`
|
||||
2. `team-building-api.md`
|
||||
3. `public-api.md`
|
||||
4. `development-status.md`
|
||||
|
||||
## 文档清单
|
||||
|
||||
@@ -40,10 +43,12 @@ MiniAPP 前台开发:
|
||||
| `backend-plan.md` | 当前 FastAPI 后端定位、业务模块、近期优先级和安全部署原则 | 后端 |
|
||||
| `admin-api-requirements.md` | Admin UI 必需的 Admin API 主契约 | 后端、管理前端 |
|
||||
| `module-config-api.md` | 页面模块配置 CRUD 的唯一细节契约 | 后端、管理前端 |
|
||||
| `home-api.md` | 首页体验、团队共创和极境视界内容的 Admin API 补充契约 | 后端、管理前端 |
|
||||
| `home-api.md` | 首页内容和玩法推荐关联的 Admin API 补充契约 | 后端、管理前端 |
|
||||
| `wild-archives-api.md` | 客片案例列表、详情和图片字段契约 | 三端 |
|
||||
| `wanfa-api.md` | 玩法分类和路线管理 API 的补充契约 | 后端、管理前端 |
|
||||
| `concierge-api.md` | 管家顾问资料管理 API 的补充契约 | 后端、管理前端 |
|
||||
| `detail-api.md` | 详情展示内容管理 API 的补充契约 | 后端、管理前端 |
|
||||
| `team-building-api.md` | 团队共创详情字段、CRUD 与 Public 详情接口契约 | 三端 |
|
||||
| `public-api.md` | MiniAPP 对接后端的 Public API 契约 | 后端、MiniAPP |
|
||||
|
||||
## 文档边界
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> 适用端:`WonderQ-Admin`、`WonderQ-Admin-UI`。
|
||||
>
|
||||
> 状态:待实现契约。本文件参考 `WonderQ-MiniAPP/src/pages/concierge/components/conciergeTypes.ts` 定义管家顾问资料,以及管理端需要的查询、维护和排序接口。它不是 MiniAPP Public API 文档。
|
||||
> 状态:已实现。本文档约定 `WonderQ-Admin`、`WonderQ-Admin-UI` 的管家管理接口,并记录 MiniAPP 使用的对应 Public API。
|
||||
|
||||
## 领域边界
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
- 订单、预订、商品和商品图片关联。
|
||||
- 管家页面 Hero 文案和服务原则内容。
|
||||
|
||||
当前 `WonderQ-MiniAPP/src/pages/concierge/index.vue` 中的 Hero、原则和顾问数据仍是本地静态内容;本契约落地后,Admin UI 维护顾问数据,MiniAPP 再通过独立的 Public API 消费已发布内容。
|
||||
当前 `WonderQ-MiniAPP/src/pages/concierge/index.vue` 中的 Hero 和服务原则仍是本地内容;顾问卡片由 Admin UI 维护,MiniAPP 通过独立的 Public API 消费已启用顾问。
|
||||
|
||||
## 接口清单
|
||||
|
||||
@@ -33,6 +33,12 @@ API 前缀为 `/api/admin`,除登录接口外均需要后台 JWT。
|
||||
| `DELETE` | `/api/admin/concierge/advisors/{advisorId}` | 删除管家顾问 |
|
||||
| `PATCH` | `/api/admin/concierge/advisors/reorder` | 调整管家顾问展示顺序 |
|
||||
|
||||
MiniAPP Public API:
|
||||
|
||||
| 方法 | 路径 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| `GET` | `/api/public/concierge/advisors` | 获取已启用的管家顾问展示数据 |
|
||||
|
||||
## 通用约定
|
||||
|
||||
- 请求和响应使用 JSON,字段使用 camelCase。
|
||||
@@ -227,6 +233,22 @@ Content-Type: application/json
|
||||
|
||||
其中 `items` 为更新 `sortOrder` 后的 `ConciergeAdvisorRecord[]`。缺少 ID、包含未知 ID 或出现重复 ID 时返回 `400 CONCIERGE_REORDER_INVALID`。
|
||||
|
||||
### MiniAPP Public API
|
||||
|
||||
```http
|
||||
GET /api/public/concierge/advisors
|
||||
```
|
||||
|
||||
无需鉴权。接口只返回 `isActive === true` 的顾问,按 `sortOrder` 升序排列,并移除 `id`、`sortOrder`、时间和其他管理字段:
|
||||
|
||||
```ts
|
||||
type PublicConciergeResponse = {
|
||||
advisors: ConciergeAdvisorContent[];
|
||||
};
|
||||
```
|
||||
|
||||
顾问列表为空时返回 `{ "advisors": [] }`。MiniAPP 应在请求期间展示 loading,失败时展示错误和重试入口,响应字段缺失时通过归一化函数过滤无效顾问。
|
||||
|
||||
## 图片与素材
|
||||
|
||||
Admin UI 使用现有素材上传接口获取图片 URL:
|
||||
@@ -292,7 +314,7 @@ const advisor: ConciergeAdvisor = {
|
||||
|
||||
## 后端落地边界
|
||||
|
||||
本契约落地时需要由 `WonderQ-Admin` 补充对应 ORM 模型、迁移、schema、路由、序列化和审计日志;由 `WonderQ-Admin-UI` 补充 API 类型、请求封装、管家列表、表单和排序交互。当前后端没有 `/api/admin/concierge/*` 路由,Admin UI 的管家入口仍是空态,MiniAPP 顾问数据仍在 `index.vue` 中静态定义。
|
||||
当前实现由 `WonderQ-Admin` 提供 ORM 模型、`0016_concierge_advisors` 迁移、schema、Admin/Public 路由、序列化和审计日志;由 `WonderQ-Admin-UI` 提供 API 类型、请求封装、管家列表、表单、图片上传、启停、排序和删除确认;由 `WonderQ-MiniAPP` 调用 Public API 并归一化顾问数据。Hero 和服务原则仍不在管家表中维护。
|
||||
|
||||
相关文档:
|
||||
|
||||
|
||||
131
docs/home-api.md
131
docs/home-api.md
@@ -2,15 +2,16 @@
|
||||
|
||||
> 适用端:`WonderQ-Admin`、`WonderQ-Admin-UI`。
|
||||
>
|
||||
> 状态:待实现契约。本文件参考 `WonderQ-MiniAPP/src/pages/home/components/homeExperienceData.ts`、`homeTeamBuildingData.ts` 和 `homeWildArchivesData.ts` 定义首页卡片内容,以及管理端需要的查询、维护和排序接口。它是首页内容的 Admin API 补充契约,不是 MiniAPP Public API 文档。
|
||||
> 状态:已实现。本文件约定首页内容的 Admin API,并记录 MiniAPP 使用的对应 Public API。首页玩法推荐不复制玩法文案,而是关联 `WanfaCategory`。
|
||||
|
||||
## 领域边界
|
||||
|
||||
首页内容管理只维护三类首页卡片:
|
||||
首页内容管理维护四类首页内容:
|
||||
|
||||
- 体验推荐:徽标、分类、标题、英文标题、封面和需求关键词。
|
||||
- 团队共创:标签、标题、描述、封面和需求关键词。
|
||||
- 极境视界:案例标题、封面和需求关键词。
|
||||
- 团队共创:标签、标题、描述、封面、需求关键词、详情副标题和详情正文段落。
|
||||
- 极境视界:案例标题、封面、详情图片和需求关键词;首页卡片可进入客片案例详情。
|
||||
- 玩法推荐:已关联的玩法分类、启用状态和首页展示顺序;分类名称及路线由玩法领域维护。
|
||||
|
||||
本领域不负责:
|
||||
|
||||
@@ -20,7 +21,7 @@
|
||||
|
||||
`demandKeyword` 只是点击卡片后预填需求页的普通字符串,不是商品 ID、路线 ID、订单 ID,也不建立数据库外键。
|
||||
|
||||
当前首页仍直接使用三个文件中的 mock 数组。Admin API 接入前,这些数组继续作为前台 fallback;本文件不代表接口已经在 `WonderQ-Admin` 或 `WonderQ-Admin-UI` 中实现。
|
||||
当前首页通过 `GET /api/public/home` 消费四类内容;三个卡片 mock 数组仍作为接口失败、空响应或字段缺失时的前台 fallback,玩法推荐无本地模拟数据时保持空态。Admin UI 通过本文件列出的 Admin API 维护正式数据。
|
||||
|
||||
## 接口清单
|
||||
|
||||
@@ -43,6 +44,20 @@ API 前缀为 `/api/admin`,除登录接口外均需要后台 JWT。
|
||||
| `PATCH` | `/api/admin/home/wild-archives/{archiveId}` | 编辑极境视界案例 |
|
||||
| `DELETE` | `/api/admin/home/wild-archives/{archiveId}` | 删除极境视界案例 |
|
||||
| `PATCH` | `/api/admin/home/wild-archives/reorder` | 调整极境视界案例顺序 |
|
||||
| `GET` | `/api/admin/home/play-recommendations` | 获取首页已关联的玩法分类 |
|
||||
| `POST` | `/api/admin/home/play-recommendations` | 关联一个玩法分类到首页 |
|
||||
| `PATCH` | `/api/admin/home/play-recommendations/{recommendationId}` | 修改关联的启用状态或玩法分类 |
|
||||
| `DELETE` | `/api/admin/home/play-recommendations/{recommendationId}` | 移除首页玩法分类关联,不删除玩法分类 |
|
||||
| `PATCH` | `/api/admin/home/play-recommendations/reorder` | 调整首页玩法推荐顺序 |
|
||||
|
||||
MiniAPP Public API:
|
||||
|
||||
| 方法 | 路径 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| `GET` | `/api/public/home` | 获取已启用的首页内容和玩法推荐 |
|
||||
| `GET` | `/api/public/home/team-buildings/{teamBuildingId}` | 获取单个团队共创详情 |
|
||||
| `GET` | `/api/public/home/wild-archives` | 获取客片案例更多列表 |
|
||||
| `GET` | `/api/public/home/wild-archives/{archiveId}` | 获取单个客片案例详情 |
|
||||
|
||||
## 通用约定
|
||||
|
||||
@@ -112,6 +127,8 @@ type HomeTeamBuilding = {
|
||||
description: string;
|
||||
image: string;
|
||||
demandKeyword: string;
|
||||
detailSubtitle: string;
|
||||
detailParagraphs: string[];
|
||||
};
|
||||
|
||||
type HomeTeamBuildingRecord = HomeTeamBuilding & {
|
||||
@@ -138,6 +155,7 @@ type HomeWildArchive = {
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
images: string[];
|
||||
demandKeyword: string;
|
||||
};
|
||||
|
||||
@@ -183,8 +201,11 @@ type HomeReorderRequest = {
|
||||
| 团队共创 | `description` | `string` | 是 | 卡片描述,去除首尾空白后不得为空。 |
|
||||
| 团队共创 | `image` | `string` | 是 | 可直接用于图片组件的封面 URL。 |
|
||||
| 团队共创 | `demandKeyword` | `string` | 是 | 点击后预填需求页的关键词。 |
|
||||
| 团队共创 | `detailSubtitle` | `string` | 是 | 详情页首屏副标题;旧数据回退为 `description`。 |
|
||||
| 团队共创 | `detailParagraphs` | `string[]` | 是 | 详情页正文段落;至少一段,旧数据回退为 `[description]`。 |
|
||||
| 极境视界 | `title` | `string` | 是 | 案例标题,去除首尾空白后不得为空。 |
|
||||
| 极境视界 | `image` | `string` | 是 | 案例图片 URL。 |
|
||||
| 极境视界 | `image` | `string` | 是 | 案例封面图片 URL。 |
|
||||
| 极境视界 | `images` | `string[]` | 是 | 案例详情图片 URL 列表,至少一张;第一张建议与封面一致。 |
|
||||
| 极境视界 | `demandKeyword` | `string` | 是 | 点击后预填需求页的关键词。 |
|
||||
| 全部资源 | `isActive` | `boolean` | 响应必填 | 是否进入已发布前台内容,创建默认 `true`。 |
|
||||
| 全部资源 | `sortOrder` | `number` | 响应必填 | 非负整数,数值越小越靠前。 |
|
||||
@@ -254,6 +275,57 @@ Content-Type: application/json
|
||||
|
||||
成功响应为 `{ "items": [] }`,其中 `items` 是更新 `sortOrder` 后的完整记录列表。缺少 ID、包含未知 ID 或出现重复 ID 时返回 `400 HOME_REORDER_INVALID`。
|
||||
|
||||
### MiniAPP Public API
|
||||
|
||||
```http
|
||||
GET /api/public/home
|
||||
```
|
||||
|
||||
无需鉴权。接口只返回 `isActive === true` 的记录,首页卡片和玩法推荐分别按 `sortOrder` 升序返回,并移除管理端状态、排序和审计时间字段:
|
||||
|
||||
```ts
|
||||
type PublicHomeResponse = {
|
||||
experiences: HomeExperience[];
|
||||
teamBuildings: HomeTeamBuilding[];
|
||||
wildArchives: HomeWildArchive[];
|
||||
playRecommendations: HomeWanfaRecommendation[];
|
||||
};
|
||||
|
||||
type HomeWanfaRecommendation = {
|
||||
id: string;
|
||||
categoryId: string;
|
||||
label: string;
|
||||
routes: WanfaRoute[];
|
||||
};
|
||||
|
||||
type WanfaRoute = {
|
||||
id: string;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
image: string;
|
||||
routeCount: number;
|
||||
demandKeyword: string;
|
||||
};
|
||||
```
|
||||
|
||||
四组列表始终返回数组;没有可用内容时返回空数组。玩法推荐只返回启用的关联记录,并展开关联分类当前的路线。MiniAPP 应在数据层归一化字段并保留对应 mock fallback,不在页面组件内直接请求接口。
|
||||
|
||||
### 玩法推荐关联
|
||||
|
||||
`POST /api/admin/home/play-recommendations` 请求体:
|
||||
|
||||
```ts
|
||||
type HomeWanfaRecommendationCreate = {
|
||||
categoryId: string;
|
||||
isActive?: boolean;
|
||||
sortOrder?: number;
|
||||
};
|
||||
|
||||
type HomeWanfaRecommendationPatch = Partial<HomeWanfaRecommendationCreate>;
|
||||
```
|
||||
|
||||
Admin 响应记录包含 `id`、`categoryId`、`categoryLabel`、`routeCount`、`isActive`、`sortOrder`、`createdAt` 和 `updatedAt`。同一个玩法分类只能关联一次;分类不存在或已关联时分别返回 `404` 或 `409 HOME_WANFA_CATEGORY_DUPLICATE`。移除关联不会删除 `WanfaCategory` 或其路线。被首页推荐关联的玩法分类不能直接删除,需先移除首页关联。
|
||||
|
||||
## 当前 fallback 与迁移映射
|
||||
|
||||
迁移初始数据时应保留以下稳定 ID、字段值和当前数组顺序:
|
||||
@@ -306,16 +378,17 @@ POST /api/admin/media-assets/upload
|
||||
|
||||
## Admin UI 对接要求
|
||||
|
||||
1. 进入首页内容管理时分别请求三个列表接口,按 `sortOrder` 渲染对应分组。
|
||||
1. 进入首页内容管理时请求三类首页卡片列表,并同时请求玩法分类和首页玩法推荐关联,按 `sortOrder` 渲染对应分组。
|
||||
2. 体验推荐表单维护 `badge`、`category`、`title`、`englishTitle`、`image` 和 `demandKeyword`。
|
||||
3. 团队共创表单维护 `tag`、`title`、`description`、`image` 和 `demandKeyword`。
|
||||
4. 极境视界表单维护 `title`、`image` 和 `demandKeyword`。
|
||||
5. 三类资源都提供启用/停用、编辑、删除和上移/下移操作;排序时提交完整 ID 列表。
|
||||
3. 团队共创表单维护 `tag`、`title`、`description`、`image`、`demandKeyword`、`detailSubtitle` 和 `detailParagraphs`;正文使用空行分隔多个段落。
|
||||
4. 极境视界表单维护 `title`、`image`、`images` 和 `demandKeyword`;详情图片按一行一个 URL 编辑。
|
||||
5. 三类首页卡片提供启用/停用、编辑、删除和上移/下移操作;玩法推荐提供启用/停用、移除和上移/下移操作;排序时提交完整 ID 列表。
|
||||
6. 每次变更成功后以接口返回的记录或列表更新本地状态,不直接假设本地修改已经保存。
|
||||
7. 删除前要求二次确认;删除成功后接受服务端返回的重新排序结果。
|
||||
8. 处理 `401`、`404`、`409`、`422` 和 `5xx`,保存、上传和排序进行中禁用重复提交。
|
||||
9. 不在首页表单中出现 Product ID、ProductImage ID、价格、库存、订单或预订字段。
|
||||
10. 预览点击行为使用 `demandKeyword`;该字段为空时禁止提交,而不是由前端猜测或拼接商品标识。
|
||||
11. 玩法推荐管理应先加载玩法分类,再加载首页关联;新增只能从未关联分类中选择,移除只取消关联,不能删除玩法分类。
|
||||
|
||||
建议的 Admin UI API 封装函数:
|
||||
|
||||
@@ -337,20 +410,51 @@ createHomeWildArchive(input: HomeWildArchiveCreate);
|
||||
updateHomeWildArchive(archiveId: string, input: HomeWildArchivePatch);
|
||||
deleteHomeWildArchive(archiveId: string);
|
||||
reorderHomeWildArchives(itemIds: string[]);
|
||||
|
||||
getHomeWanfaRecommendations();
|
||||
createHomeWanfaRecommendation(input: HomeWanfaRecommendationCreate);
|
||||
updateHomeWanfaRecommendation(recommendationId: string, input: HomeWanfaRecommendationPatch);
|
||||
deleteHomeWanfaRecommendation(recommendationId: string);
|
||||
reorderHomeWanfaRecommendations(itemIds: string[]);
|
||||
```
|
||||
|
||||
当前首页的“查看更多”按钮固定跳转需求关键词“极境视界”,不属于 `HomeWildArchive` 记录字段;如果未来需要后台配置该按钮,应另行增加首页 CTA 配置契约。
|
||||
当前首页的“查看更多”按钮跳转客片案例列表;首页案例卡片跳转 `/pages/wild-archives/detail?id={archiveId}`,不再跳转需求页。
|
||||
|
||||
## 前后台数据边界
|
||||
|
||||
- Admin API 返回启用和停用的完整记录,供管理端维护。
|
||||
- 未来 Public API 只返回已发布且启用的首页内容;Public API 的响应字段应与本契约的渲染字段兼容,但不应暴露 `createdAt`、`updatedAt` 等管理元数据。
|
||||
- MiniAPP 接入时再同步更新 `src/lib/types.ts`、`src/lib/data.ts`、首页组件和 `docs/public-api.md`;本次文档不改变现有 mock 消费路径。
|
||||
- MiniAPP 已在 `src/lib/api.ts`、`src/lib/types.ts` 和 `src/lib/store.ts` 接入 Public API;首页组件通过共享状态消费归一化后的四类内容,玩法推荐按关联分类展示。
|
||||
- 后端不得把 `demandKeyword` 解析成 Product 或订单关联;如需线路、详情或预订能力,应另立领域契约。
|
||||
|
||||
## 团队共创详情
|
||||
|
||||
团队共创首页卡片点击后跳转 MiniAPP `/pages/team-buildings/detail?id={teamBuildingId}`,详情页再按 ID 请求 Public API。首页接口只返回卡片摘要,不携带正文段落。
|
||||
|
||||
```http
|
||||
GET /api/public/home/team-buildings/{teamBuildingId}
|
||||
```
|
||||
|
||||
成功响应在首页摘要基础上增加详情字段:
|
||||
|
||||
```ts
|
||||
type PublicHomeTeamBuildingDetail = HomeTeamBuilding & {
|
||||
detailSubtitle: string;
|
||||
detailParagraphs: string[];
|
||||
};
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
- 仅返回 `isActive === true` 的团队共创;不存在或已停用返回 `404`。
|
||||
- `detailSubtitle` 为空时回退为 `description`。
|
||||
- `detailParagraphs` 为空时回退为 `[description]`。
|
||||
- MiniAPP 请求失败时按 `teamBuildingId` 使用本地模拟详情,并提示当前为模拟数据;找不到对应 fallback 时展示未找到状态。
|
||||
- 详情封面复用 `image` 字段,不新增独立 hero 图片或详情表。
|
||||
|
||||
## 后端落地边界
|
||||
|
||||
本契约落地时需要由 `WonderQ-Admin` 补充对应 ORM 模型、迁移、schema、路由、序列化和审计日志;由 `WonderQ-Admin-UI` 补充 API 类型、请求封装、首页内容列表、表单、图片上传和排序交互。当前后端没有 `/api/admin/home/*` 路由,Admin UI 也未接入这三类首页数据。
|
||||
当前实现由 `WonderQ-Admin` 提供三张首页内容表、`HomeWanfaRecommendation` 关联表、`0017_home_content`、`0018_home_wanfa_recommendations`、`0019_home_wild_archive_images` 与 `0020_home_team_building_details` 迁移、schema、Admin/Public 路由、序列化和审计日志;由 `WonderQ-Admin-UI` 提供首页玩法推荐入口、分类关联、启停、移除、排序、客片详情图片和团队共创详情维护;由 `WonderQ-MiniAPP` 调用 `/api/public/home`、团队共创详情和客片案例列表/详情接口。
|
||||
|
||||
相关文档:
|
||||
|
||||
@@ -359,4 +463,5 @@ reorderHomeWildArchives(itemIds: string[]);
|
||||
- [Public API 契约](./public-api.md)
|
||||
- [体验推荐数据](../WonderQ-MiniAPP/src/pages/home/components/homeExperienceData.ts)
|
||||
- [团队共创数据](../WonderQ-MiniAPP/src/pages/home/components/homeTeamBuildingData.ts)
|
||||
- [团队共创详情接口](./team-building-api.md)
|
||||
- [极境视界数据](../WonderQ-MiniAPP/src/pages/home/components/homeWildArchivesData.ts)
|
||||
|
||||
BIN
docs/images/2026-08-18_220929.png
Normal file
BIN
docs/images/2026-08-18_220929.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
BIN
docs/images/2026-08-18_221642.png
Normal file
BIN
docs/images/2026-08-18_221642.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 274 KiB |
BIN
docs/images/2e901149-1329-42d3-b335-3a2bafdcf8e6.png
Normal file
BIN
docs/images/2e901149-1329-42d3-b335-3a2bafdcf8e6.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -1,6 +1,6 @@
|
||||
# WonderQ MiniAPP Public API
|
||||
|
||||
本文档是 `WonderQ-MiniAPP` 当前使用的 Public API 契约。接口只提供站点内容、登录和出行需求提交能力。
|
||||
本文档是 `WonderQ-MiniAPP` 当前使用的 Public API 契约。接口提供站点内容、首页卡片、玩法展示、管家展示、登录和出行需求提交能力。
|
||||
|
||||
## 基础约定
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
| ------ | ------------------------------ | ------------ | ------------------ |
|
||||
| `GET` | `/health` | 否 | 服务健康检查 |
|
||||
| `GET` | `/api/public/site-config` | 否 | 获取启用的站点内容 |
|
||||
| `GET` | `/api/public/home` | 否 | 获取已启用的首页内容和玩法推荐 |
|
||||
| `GET` | `/api/public/home/team-buildings/{teamBuildingId}` | 否 | 获取团队共创详情 |
|
||||
| `GET` | `/api/public/home/wild-archives` | 否 | 获取客片案例更多列表 |
|
||||
| `GET` | `/api/public/home/wild-archives/{archiveId}` | 否 | 获取客片案例详情和图片 |
|
||||
| `GET` | `/api/public/wanfa/categories` | 否 | 获取玩法分类和路线 |
|
||||
| `GET` | `/api/public/concierge/advisors` | 否 | 获取已启用的管家顾问 |
|
||||
| `POST` | `/api/public/auth/phone-login` | 否 | 微信手机号登录 |
|
||||
| `GET` | `/api/public/auth/me` | Customer JWT | 获取当前客户 |
|
||||
| `POST` | `/api/public/leads` | 否 | 提交出行需求 |
|
||||
@@ -36,6 +42,153 @@ type SiteConfig = {
|
||||
|
||||
Public 响应只返回启用内容,其余模块按 `isActive` 过滤。
|
||||
|
||||
## 玩法展示
|
||||
|
||||
### `GET /api/public/wanfa/categories`
|
||||
|
||||
无需鉴权。接口按后台维护的分类和路线顺序返回 MiniAPP 玩法页所需的最小展示字段,不返回后台排序、审计和时间字段。
|
||||
|
||||
成功响应:
|
||||
|
||||
```ts
|
||||
type PublicWanfaResponse = {
|
||||
categories: PublicWanfaCategory[];
|
||||
};
|
||||
|
||||
type PublicWanfaCategory = {
|
||||
id: string;
|
||||
label: string;
|
||||
routes: PublicWanfaRoute[];
|
||||
};
|
||||
|
||||
type PublicWanfaRoute = {
|
||||
id: string;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
image: string;
|
||||
routeCount: number;
|
||||
demandKeyword: string;
|
||||
};
|
||||
```
|
||||
|
||||
MiniAPP 使用 `demandKeyword` 作为需求页预填关键词;接口失败或响应为空时,玩法页展示对应的错误、重试或空态,不再读取 `playData.ts` 模拟数据。
|
||||
|
||||
## 管家展示
|
||||
|
||||
### `GET /api/public/concierge/advisors`
|
||||
|
||||
无需鉴权。接口只返回后台启用的管家顾问,按后台维护顺序返回;不返回管理端 ID、启停状态、排序元数据和时间字段。
|
||||
|
||||
```ts
|
||||
type PublicConciergeDetail = {
|
||||
icon: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
type PublicConciergeAdvisor = {
|
||||
avatar: string;
|
||||
name: string;
|
||||
role: string;
|
||||
details: PublicConciergeDetail[];
|
||||
qrImage: string;
|
||||
};
|
||||
|
||||
type PublicConciergeResponse = {
|
||||
advisors: PublicConciergeAdvisor[];
|
||||
};
|
||||
```
|
||||
|
||||
成功响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"advisors": [
|
||||
{
|
||||
"avatar": "https://example.test/assets/advisor-avatar.jpg",
|
||||
"name": "示例顾问",
|
||||
"role": "SENIOR TRAVEL ADVISOR",
|
||||
"details": [{ "icon": "calendar", "label": "服务经验:8年" }],
|
||||
"qrImage": "https://example.test/assets/advisor-qr.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
无可用顾问时返回 `{ "advisors": [] }`。MiniAPP 应处理 loading、错误、重试和空态,不能依赖固定顾问姓名或本地模拟数组。
|
||||
|
||||
## 首页内容
|
||||
|
||||
### `GET /api/public/home`
|
||||
|
||||
无需鉴权。接口只返回后台启用的首页体验推荐、团队共创和极境视界内容,按后台排序返回,不暴露管理元数据。
|
||||
|
||||
```ts
|
||||
type PublicHomeResponse = {
|
||||
experiences: HomeExperience[];
|
||||
teamBuildings: HomeTeamBuilding[];
|
||||
wildArchives: HomeWildArchive[];
|
||||
playRecommendations: HomeWanfaRecommendation[];
|
||||
};
|
||||
|
||||
type HomeWanfaRecommendation = {
|
||||
id: string;
|
||||
categoryId: string;
|
||||
label: string;
|
||||
routes: WanfaRoute[];
|
||||
};
|
||||
|
||||
type WanfaRoute = {
|
||||
id: string;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
image: string;
|
||||
routeCount: number;
|
||||
demandKeyword: string;
|
||||
};
|
||||
|
||||
type HomeExperience = {
|
||||
id: string;
|
||||
badge: string;
|
||||
category: string;
|
||||
title: string;
|
||||
englishTitle: string;
|
||||
image: string;
|
||||
demandKeyword: string;
|
||||
};
|
||||
|
||||
type HomeTeamBuilding = {
|
||||
id: string;
|
||||
tag: string;
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
demandKeyword: string;
|
||||
};
|
||||
|
||||
type PublicHomeTeamBuildingDetail = HomeTeamBuilding & {
|
||||
detailSubtitle: string;
|
||||
detailParagraphs: string[];
|
||||
};
|
||||
|
||||
type HomeWildArchive = {
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
demandKeyword: string;
|
||||
photoCount: number;
|
||||
};
|
||||
```
|
||||
|
||||
无可用内容时,`experiences`、`teamBuildings`、`wildArchives` 和 `playRecommendations` 均返回空数组。玩法推荐由首页内容域关联玩法分类后生成,接口只返回启用的关联及分类当前路线;MiniAPP 接口失败或字段不完整时使用首页对应 fallback,玩法推荐缺省为空态。
|
||||
|
||||
客片案例更多列表使用 `GET /api/public/home/wild-archives`,返回同样的摘要字段;详情使用 `GET /api/public/home/wild-archives/{archiveId}`,在摘要字段基础上增加 `images: string[]`。首页卡片点击详情,`查看更多` 点击案例列表,不再跳转需求页。
|
||||
|
||||
### 团队共创详情
|
||||
|
||||
`GET /api/public/home/team-buildings/{teamBuildingId}` 无需鉴权,只返回启用的团队共创详情。响应包含首页摘要字段,以及 `detailSubtitle` 和 `detailParagraphs`。不存在或已停用返回 `404`。
|
||||
|
||||
详情页接口失败时,MiniAPP 按 ID 使用 `homeTeamBuildingData.ts` 中的网络图片和模拟正文 fallback,并显示接口不可用提示;首页 `/api/public/home` 不返回 `detailParagraphs`,避免首页请求携带长正文。
|
||||
|
||||
### 通用字段
|
||||
|
||||
站点模块通常包含 `id`、`createdAt`、`updatedAt`、`isActive` 和 `sortOrder`。客户端按 `sortOrder` 消费排序模块,不依赖固定 ID。
|
||||
|
||||
155
docs/team-building-api.md
Normal file
155
docs/team-building-api.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# 团队共创详情接口契约
|
||||
|
||||
> 适用端:`WonderQ-Admin`、`WonderQ-Admin-UI`、`WonderQ-MiniAPP`。
|
||||
> 目标:复用 `HomeTeamBuilding` 表,维护首页团队共创卡片和沉浸式详情页内容。
|
||||
|
||||
## 领域边界
|
||||
|
||||
- 团队共创卡片和详情共用一条 `HomeTeamBuilding` 记录。
|
||||
- 详情封面复用 `image`,不新增独立详情表或第二张 hero 图片。
|
||||
- `detailSubtitle` 是详情首屏副标题。
|
||||
- `detailParagraphs` 是按阅读顺序保存的正文段落数组。
|
||||
- Admin UI 使用正文 textarea 的“空行分隔段落”约定;后端保存前会清洗首尾空白和空段落。
|
||||
- 首页卡片仍保留 `demandKeyword`,但点击行为改为详情页;该字段仅作为其他需求入口的普通文案,不建立商品或订单外键。
|
||||
|
||||
## 数据类型
|
||||
|
||||
```ts
|
||||
type HomeTeamBuilding = {
|
||||
id: string;
|
||||
tag: string;
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
demandKeyword: string;
|
||||
detailSubtitle: string;
|
||||
detailParagraphs: string[];
|
||||
isActive: boolean;
|
||||
sortOrder: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
type HomeTeamBuildingCreate = {
|
||||
tag: string;
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
demandKeyword: string;
|
||||
detailSubtitle?: string;
|
||||
detailParagraphs?: string[];
|
||||
isActive?: boolean;
|
||||
sortOrder?: number;
|
||||
};
|
||||
|
||||
type HomeTeamBuildingPatch = Partial<HomeTeamBuildingCreate>;
|
||||
```
|
||||
|
||||
兼容规则:旧客户端不提交详情字段时,后端使用模型默认值;迁移 `0020_home_team_building_details` 会把已有记录的副标题回填为 `description`,正文回填为 `[description]`。Public 序列化时仍会对空值做相同 fallback。
|
||||
|
||||
## Admin API
|
||||
|
||||
前缀为 `/api/admin`,需要 `Authorization: Bearer <admin-jwt>`。既有列表、创建、编辑、删除和排序路径保持不变:
|
||||
|
||||
| 方法 | 路径 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| `GET` | `/api/admin/home/team-buildings` | 获取全部团队共创记录 |
|
||||
| `POST` | `/api/admin/home/team-buildings` | 新增团队共创记录 |
|
||||
| `PATCH` | `/api/admin/home/team-buildings/{teamBuildingId}` | 编辑团队共创记录和详情字段 |
|
||||
| `DELETE` | `/api/admin/home/team-buildings/{teamBuildingId}` | 删除团队共创记录 |
|
||||
| `PATCH` | `/api/admin/home/team-buildings/reorder` | 调整团队共创顺序 |
|
||||
|
||||
创建或编辑请求示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"tag": "户外挑战",
|
||||
"title": "山野挑战,共创极境",
|
||||
"description": "洞穴、瀑降与协作,适合 10-30 人。",
|
||||
"image": "https://example.test/assets/team-building.jpg",
|
||||
"demandKeyword": "户外团建",
|
||||
"detailSubtitle": "越过山丘,向来处去",
|
||||
"detailParagraphs": [
|
||||
"真正的贵州,从未被写进流水线的攻略里。",
|
||||
"把会议室换成山野,让团队重新认识彼此。"
|
||||
],
|
||||
"isActive": true
|
||||
}
|
||||
```
|
||||
|
||||
约束:
|
||||
|
||||
- 文本字段去除首尾空白后不得为空;详情副标题最大 160 字,正文最多 30 段。
|
||||
- `detailParagraphs` 保存时过滤空段落;编辑接口显式传空正文会返回 `422`。
|
||||
- 图片只接受 HTTP(S) URL;排序值为非负整数。
|
||||
- 列表接口返回启用和停用记录,按 `sortOrder` 升序;删除和排序继续写审计日志。
|
||||
- 迁移只新增两列,不改变旧字段和现有接口路径;本次实现不自动执行迁移。
|
||||
|
||||
## Public API
|
||||
|
||||
### 首页摘要
|
||||
|
||||
```http
|
||||
GET /api/public/home
|
||||
```
|
||||
|
||||
首页响应中的 `teamBuildings` 只返回卡片摘要:
|
||||
|
||||
```ts
|
||||
type PublicHomeTeamBuildingSummary = {
|
||||
id: string;
|
||||
tag: string;
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
demandKeyword: string;
|
||||
};
|
||||
```
|
||||
|
||||
### 详情
|
||||
|
||||
```http
|
||||
GET /api/public/home/team-buildings/{teamBuildingId}
|
||||
```
|
||||
|
||||
无需鉴权。成功响应:
|
||||
|
||||
```ts
|
||||
type PublicHomeTeamBuildingDetail = PublicHomeTeamBuildingSummary & {
|
||||
detailSubtitle: string;
|
||||
detailParagraphs: string[];
|
||||
};
|
||||
```
|
||||
|
||||
错误响应:
|
||||
|
||||
| 状态码 | 场景 |
|
||||
| --- | --- |
|
||||
| `404` | ID 不存在或团队共创已停用 |
|
||||
| `5xx` | 服务端异常;MiniAPP 进入本地 fallback |
|
||||
|
||||
响应中的 `detailSubtitle` 为空时返回 `description`;`detailParagraphs` 为空时返回 `[description]`。Public API 不返回管理端状态、排序和审计字段。
|
||||
|
||||
## MiniAPP 联调约定
|
||||
|
||||
1. 首页通过 `/api/public/home` 加载团队共创卡片。
|
||||
2. `openTeamBuilding(item)` 调用 `goTeamBuildingDetail(item.id)`,跳转 `/pages/team-buildings/detail?id={teamBuildingId}`。
|
||||
3. 详情页调用 `fetchPublicTeamBuildingDetail(teamBuildingId)`,成功后通过 `normalizeHomeTeamBuildingDetail` 归一化。
|
||||
4. 请求失败时按 ID 查找 `homeTeamBuildingFallback`;命中则展示模拟网络图片、标题、副标题和正文,并提示“接口暂不可用,当前展示模拟数据”。
|
||||
5. 无 ID、ID 不存在且无 fallback 时展示未找到状态,并提供返回首页操作。
|
||||
6. 页面必须覆盖 loading、接口失败、空正文和未找到状态;详情布局使用 TailwindCSS,不新增页面级自定义样式。
|
||||
|
||||
## 三端联调顺序
|
||||
|
||||
1. 在 `WonderQ-Admin` 执行 `python -m alembic upgrade head`,仅在确认目标数据库后执行。
|
||||
2. 启动后端并验证 `GET /health`。
|
||||
3. 在 Admin UI 创建或编辑团队共创,填写详情副标题和正文;正文 textarea 使用空行分段。
|
||||
4. 验证 Admin API 返回详情字段,Public 首页只返回摘要。
|
||||
5. 在 MiniAPP 首页点击团队共创卡片,确认 URL 携带正确 ID。
|
||||
6. 验证详情接口成功展示最新内容;停止后端后确认按 ID fallback 并显示提示。
|
||||
|
||||
## 变更文件
|
||||
|
||||
- 后端:`WonderQ-Admin/app/models.py`、`app/schemas.py`、`app/serializers.py`、`app/routers/public.py`、`alembic/versions/0020_home_team_building_details.py`。
|
||||
- 管理端:`WonderQ-Admin-UI/src/api.ts`、`src/pages/structure/HomeContentPage.tsx`、`src/components/admin/HomeContentEditor.tsx`、`src/components/admin/HomeContentCardRail.tsx`。
|
||||
- 前台:`WonderQ-MiniAPP/src/pages/home/components/homeTeamBuildingData.ts`、`src/lib/types.ts`、`src/lib/api.ts`、`src/lib/navigation.ts`、`src/pages/home/index.vue`、`src/pages/team-buildings/detail.vue`、`src/pages.json`。
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
> 适用端:`WonderQ-Admin`、`WonderQ-Admin-UI`。
|
||||
>
|
||||
> 状态:待实现契约。本文件参考 `WonderQ-MiniAPP/src/pages/play/components/playData.ts` 定义玩法分类和路线的数据结构,以及管理端需要的查询、维护和排序接口。它不是 MiniAPP Public API 文档。
|
||||
> 状态:已实现契约。本文件参考 `WonderQ-MiniAPP/src/pages/play/components/playData.ts` 定义玩法分类和路线的数据结构,以及管理端需要的查询、维护和排序接口。它不是 MiniAPP Public API 文档。
|
||||
|
||||
当前实现:`WonderQ-Admin` 通过迁移 `0015_wanfa` 创建 `WanfaCategory`、`WanfaRoute` 表并导入稳定初始 ID;`WonderQ-Admin-UI` 已接入分类和路线的查询、新增、编辑、删除及排序操作。
|
||||
|
||||
## 领域边界
|
||||
|
||||
@@ -11,6 +13,7 @@
|
||||
- 分类名称和展示顺序。
|
||||
- 路线标题、副标题、封面、路线数量和需求关键词。
|
||||
- 分类与路线的新增、编辑、删除和排序。
|
||||
- 首页玩法推荐与分类的关联由首页内容域维护,本域只提供可被关联的分类和路线数据。
|
||||
|
||||
玩法领域不负责:
|
||||
|
||||
@@ -47,6 +50,7 @@ API 前缀为 `/api/admin`,除登录接口外均需要后台 JWT。
|
||||
- 分类和路线的数组顺序就是管理端和前台的展示顺序,接口不要求前端依赖 `sortOrder` 字段。
|
||||
- 空集合返回 `[]`,不能返回 `null` 或省略字段。
|
||||
- 失败响应沿用 Admin API 约定,包含 `message`、`code` 和可选的 `details`。
|
||||
- 被首页玩法推荐关联的分类不能直接删除;需先调用首页内容域的移除关联接口,否则返回 `409 WANFA_CATEGORY_RECOMMENDED`。
|
||||
|
||||
## 数据类型
|
||||
|
||||
@@ -316,7 +320,7 @@ reorderWanfaRoutes(categoryId: string, itemIds: string[]);
|
||||
|
||||
## 后端落地边界
|
||||
|
||||
本契约落地时需要由 `WonderQ-Admin` 补充对应 ORM 模型、迁移、schema、路由、序列化和审计日志;由 `WonderQ-Admin-UI` 补充 API 类型、请求封装、表单和排序交互。接口实现前不要把 `playData.ts` 的静态数据误认为已存在的数据库或 API 数据。
|
||||
玩法数据由 `WonderQ-Admin` 的 `WanfaCategory`、`WanfaRoute` ORM 模型和 Admin API 负责持久化;`WonderQ-Admin-UI` 负责 API 类型、请求封装、表单、删除确认和排序交互。`playData.ts` 仅作为迁移初始数据来源,不能视为数据库或 API 数据。
|
||||
|
||||
相关文档:
|
||||
|
||||
|
||||
147
docs/wild-archives-api.md
Normal file
147
docs/wild-archives-api.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# 客片案例 API 契约
|
||||
|
||||
> 适用端:`WonderQ-Admin`、`WonderQ-Admin-UI`、`WonderQ-MiniAPP`。
|
||||
>
|
||||
> 目标:维护“极境视界”首页卡片,并提供客片案例更多列表和案例详情页面。
|
||||
|
||||
## 领域边界
|
||||
|
||||
客片案例是首页内容领域的一类展示内容,不属于商品、Product、ProductImage、订单或预订领域。
|
||||
|
||||
- `image` 是首页卡片封面。
|
||||
- `images` 是详情页纵向展示的图片 URL 列表。
|
||||
- `demandKeyword` 仅为兼容已有需求入口的普通文案,本次案例卡片和详情不跳转需求页。
|
||||
- 图片只保存 URL,不保存 base64,不建立商品图片关联。
|
||||
|
||||
## 数据类型
|
||||
|
||||
```ts
|
||||
type WildArchiveRecord = {
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
images: string[];
|
||||
demandKeyword: string;
|
||||
isActive: boolean;
|
||||
sortOrder: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
type PublicWildArchiveSummary = {
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
demandKeyword: string;
|
||||
photoCount: number;
|
||||
};
|
||||
|
||||
type PublicWildArchiveDetail = PublicWildArchiveSummary & {
|
||||
images: string[];
|
||||
};
|
||||
|
||||
type WildArchiveCreate = {
|
||||
title: string;
|
||||
image: string;
|
||||
images?: string[];
|
||||
demandKeyword: string;
|
||||
isActive?: boolean;
|
||||
sortOrder?: number;
|
||||
};
|
||||
|
||||
type WildArchivePatch = Partial<WildArchiveCreate>;
|
||||
```
|
||||
|
||||
`images` 未传时服务端兼容为 `[image]`;传入后至少包含一张合法 `http` 或 `https` 图片 URL,最多 30 张。`photoCount` 始终由服务端根据详情图片列表返回。
|
||||
|
||||
## Admin API
|
||||
|
||||
所有 Admin API 需要 `Authorization: Bearer <admin-jwt>`。
|
||||
|
||||
| 方法 | 路径 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| `GET` | `/api/admin/home/wild-archives` | 获取全部案例,包含启用和停用记录及详情图片 |
|
||||
| `POST` | `/api/admin/home/wild-archives` | 新增案例 |
|
||||
| `PATCH` | `/api/admin/home/wild-archives/{archiveId}` | 修改标题、封面、详情图片、需求关键词、启用状态或排序 |
|
||||
| `DELETE` | `/api/admin/home/wild-archives/{archiveId}` | 删除案例 |
|
||||
| `PATCH` | `/api/admin/home/wild-archives/reorder` | 按完整 ID 列表调整顺序 |
|
||||
|
||||
新增示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "石龙洞——客片案例",
|
||||
"image": "https://example.test/cover.jpg",
|
||||
"images": [
|
||||
"https://example.test/cover.jpg",
|
||||
"https://example.test/cave-1.jpg"
|
||||
],
|
||||
"demandKeyword": "地心探险",
|
||||
"isActive": true
|
||||
}
|
||||
```
|
||||
|
||||
Admin UI 的“极境视界”表单必须同时维护封面和详情图片,详情图片使用一行一个 URL;删除需要二次确认,排序提交完整 `itemIds`。
|
||||
|
||||
## Public API
|
||||
|
||||
### 获取更多列表
|
||||
|
||||
```http
|
||||
GET /api/public/home/wild-archives
|
||||
```
|
||||
|
||||
无需鉴权。只返回 `isActive === true` 的记录,按 `sortOrder` 升序:
|
||||
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": "shilong-cave",
|
||||
"title": "石龙洞——客片案例",
|
||||
"image": "https://example.test/cover.jpg",
|
||||
"demandKeyword": "地心探险",
|
||||
"photoCount": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 获取案例详情
|
||||
|
||||
```http
|
||||
GET /api/public/home/wild-archives/{archiveId}
|
||||
```
|
||||
|
||||
无需鉴权。停用或不存在的案例返回 `404`,成功返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "shilong-cave",
|
||||
"title": "石龙洞——客片案例",
|
||||
"image": "https://example.test/cover.jpg",
|
||||
"demandKeyword": "地心探险",
|
||||
"photoCount": 5,
|
||||
"images": [
|
||||
"https://example.test/cover.jpg",
|
||||
"https://example.test/cave-1.jpg"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## MiniAPP 页面约定
|
||||
|
||||
- `pages/wild-archives/index`:客片案例更多列表。
|
||||
- `pages/wild-archives/detail?id={archiveId}`:客片案例详情。
|
||||
- 首页“极境视界”卡片调用详情页;“查看更多”调用列表页。
|
||||
- 页面数据层优先调用 Public API;接口失败时列表和详情允许使用 `homeWildArchivesData.ts` 中的网络图片 mock 数据。
|
||||
- 详情页按 `images` 顺序纵向展示,保留图片原始比例;空列表时展示空态,不渲染破损图片。
|
||||
|
||||
## 迁移与验证
|
||||
|
||||
- 数据模型:`HomeWildArchive.images` 使用 JSONB 保存 URL 数组。
|
||||
- 迁移:`WonderQ-Admin/alembic/versions/0019_home_wild_archive_images.py`。
|
||||
- 迁移会将历史 `image` 自动转为第一张详情图片,保证旧数据可打开详情页。
|
||||
- 三端联调顺序:执行迁移 → 启动 Admin API → 配置 Admin UI 案例 → 访问 MiniAPP 列表和详情。
|
||||
|
||||
相关契约:[首页内容 API](./home-api.md)、[Public API](./public-api.md)。
|
||||
Reference in New Issue
Block a user