feat: add hotel and vehicle option site modules

Add full support for hotel group and vehicle option site management features:
- Define SQLAlchemy models and alembic migration for the new database tables
- Add default sample content entries in content.py
- Extend admin and public API routes to support the new modules
- Update seed script to populate default hotel and vehicle data
- Update all relevant documentation and test cases
This commit is contained in:
duanshuwen
2026-07-03 20:26:44 +08:00
parent 72d388a047
commit 201e835eab
13 changed files with 426 additions and 34 deletions

View File

@@ -1,4 +1,4 @@
# WonderQ-Admin-UI Admin API 接口需求
# WonderQ-Admin-UI Admin API 接口需求
本文档用于指导 `WonderQ-Admin` 后端按当前 `WonderQ-Admin-UI` 管理端完成 Admin API 对接。接口需求来源于前端 `src/api.ts``src/App.tsx` 的实际类型、请求封装和页面调用。
@@ -34,7 +34,7 @@ Content-Type: application/json
| `POST /api/admin/products` | 新建商品 | 已覆盖 | 返回完整 Product |
| `PATCH /api/admin/products/{id}` | 编辑商品 | 已覆盖 | 返回完整 Product |
| `GET /api/admin/destinations` | 商品目的地下拉、目的地页 | 已覆盖 | 需要返回别名和商品数 |
| `GET /api/admin/site-config` | 首页/目的地/活动结构维护 | 已覆盖 | 需要包含未启用内容已保存的 `routeSections` |
| `GET /api/admin/site-config` | 首页/目的地/活动结构维护 | 已覆盖 | 需要包含未启用内容已保存的 `routeSections``hotelGroups``vehicleOptions``ctaBanners` |
| `PATCH /api/admin/site-config/{module}/{item_id}` | 模块内容编辑 | 已覆盖 | 模块名需保持一致 |
| `GET /api/admin/leads` | 需求线索页 | 已覆盖 | UI 当前不传筛选参数 |
| `PATCH /api/admin/leads/{id}/status` | 线索状态流转 | 已覆盖 | UI 更新后会重新拉列表 |
@@ -58,7 +58,7 @@ type LeadStatus = "new" | "assigned" | "contacted" | "planning" | "won" | "inval
### SiteModule
```ts
type SiteModule = "heroSlides" | "destinations" | "map" | "themes" | "campaigns" | "routeSections" | "ctaBanners";
type SiteModule = "heroSlides" | "destinations" | "map" | "themes" | "campaigns" | "routeSections" | "hotelGroups" | "vehicleOptions" | "ctaBanners";
```
## 公共数据结构
@@ -209,6 +209,26 @@ type SiteConfig = {
isActive: boolean;
sortOrder: number;
}>;
hotelGroups: Array<{
id: string;
title: string;
description?: string | null;
image?: string | null;
isActive: boolean;
sortOrder: number;
createdAt?: string;
updatedAt?: string;
}>;
vehicleOptions: Array<{
id: string;
title: string;
description?: string | null;
image?: string | null;
isActive: boolean;
sortOrder: number;
createdAt?: string;
updatedAt?: string;
}>;
ctaBanners: Array<{
id: string;
alt: string;
@@ -216,6 +236,7 @@ type SiteConfig = {
targetType: string;
targetValue?: string | null;
isActive: boolean;
sortOrder: number;
}>;
};
```
@@ -259,7 +280,9 @@ type SiteItemPatch = {
| `themes` | `label``image``targetType``targetValue``isActive` |
| `campaigns` | `title``description``coverImage``priceAmount``priceUnit``tags``status` |
| `routeSections` | `title``subtitle``productIds``isActive``sortOrder` |
| `ctaBanners` | `alt``image``targetType``targetValue``isActive` |
| `hotelGroups` | `title``description``image``isActive``sortOrder` |
| `vehicleOptions` | `title``description``image``isActive``sortOrder` |
| `ctaBanners` | `alt`(服务标题)、`image``targetType``targetValue``isActive``sortOrder` |
## 接口明细
@@ -409,10 +432,10 @@ GET /api/admin/site-config
要求:
- 返回 `heroSlides``destinations``map``themes``campaigns``routeSections``ctaBanners` 个模块。
- 返回 `heroSlides``destinations``map``themes``campaigns``routeSections``hotelGroups``vehicleOptions``ctaBanners` 个模块。
- Admin API 需要返回未启用内容Public API 才按发布/启用状态过滤。
- 各模块按 `sortOrder` 升序。
- `routeSections` 返回当前已保存的子分组,包含未启用分组和后台配置的全部 `productIds`;无数据时返回空数组。
- `routeSections` 返回当前已保存的子分组,包含未启用分组和后台配置的全部 `productIds`;无数据时返回空数组。`hotelGroups``vehicleOptions` 返回全部后台卡片,包含停用项;无数据时返回空数组。
### 更新站点配置项
@@ -424,7 +447,7 @@ PATCH /api/admin/site-config/{module}/{item_id}
| 参数 | 类型 | 说明 |
| --- | --- | --- |
| `module` | `SiteModule` | 只能为 `heroSlides``destinations``map``themes``campaigns``routeSections``ctaBanners` |
| `module` | `SiteModule` | 只能为 `heroSlides``destinations``map``themes``campaigns``routeSections``hotelGroups``vehicleOptions``ctaBanners` |
| `item_id` | `string` | 对应模块内容项 ID |
请求体:`SiteItemPatch`
@@ -460,6 +483,46 @@ PATCH /api/admin/site-config/routeSections/reorder
- `DELETE /api/admin/site-config/routeSections/{section_id}` 只删除分组配置并解除关联,不删除商品本体;删除后后端重新整理剩余分组 `sortOrder`
- `PATCH /api/admin/site-config/routeSections/reorder``itemIds` 必须完整覆盖当前全部分组 ID不能缺失、重复或包含未知 ID。
- `GET /api/public/site-config` 只返回启用分组,且 `productIds` 只包含已发布商品;未发布、归档或不存在的商品不进入 Public 响应。
#### 特色酒店和万趣用车 `hotelGroups` / `vehicleOptions`
`hotelGroups` 是首页“特色酒店”卡片配置,`vehicleOptions` 是首页“万趣用车”卡片配置。两者只维护首页模块卡片,不维护商品本体或商品关联。
```http
POST /api/admin/site-config/hotelGroups
PATCH /api/admin/site-config/hotelGroups/{item_id}
DELETE /api/admin/site-config/hotelGroups/{item_id}
PATCH /api/admin/site-config/hotelGroups/reorder
POST /api/admin/site-config/vehicleOptions
PATCH /api/admin/site-config/vehicleOptions/{item_id}
DELETE /api/admin/site-config/vehicleOptions/{item_id}
PATCH /api/admin/site-config/vehicleOptions/reorder
```
字段规则:
- 新增请求至少包含 `title`,可包含 `description``image``isActive``sortOrder`
- 更新请求可包含 `title``description``image``isActive``sortOrder`
- 删除只删除首页卡片配置,不删除商品、目的地或素材库资源;删除后后端重新整理剩余项 `sortOrder`
- `PATCH /reorder``itemIds` 必须完整覆盖当前同模块全部配置项 ID不能缺失、重复或包含未知 ID。
- `GET /api/public/site-config` 只返回启用卡片,并按 `sortOrder` 升序MiniAPP 在字段缺失或空数组时使用本地内容兜底。
#### 更多服务 `ctaBanners`
`ctaBanners` 对应首页“更多服务”模块,维护权益、服务管家、目的地和需求入口等服务卡片。管理端按顶部轮播相同的配置方式提供新增、编辑、删除和排序;`alt` 是前台卡片标题,`image` 是卡片背景图。
```http
POST /api/admin/site-config/ctaBanners
PATCH /api/admin/site-config/ctaBanners/{item_id}
DELETE /api/admin/site-config/ctaBanners/{item_id}
PATCH /api/admin/site-config/ctaBanners/reorder
```
字段规则:
- 新增请求至少包含 `alt`,可包含 `image``targetType``targetValue``isActive``sortOrder`
- 更新请求可包含 `alt``image``targetType``targetValue``isActive``sortOrder`
- 删除只删除首页更多服务卡片配置,不删除素材库资源;删除后后端重新整理剩余项 `sortOrder`
- `GET /api/public/site-config` 只返回启用卡片,并按 `sortOrder` 升序。
### 线索列表
```http
@@ -544,6 +607,8 @@ POST /api/admin/reset-guizhou-content
themes: number;
ctaBanners: number;
routeSections?: number;
hotelGroups?: number;
vehicleOptions?: number;
products: number;
}
```