WonderQ-MiniAPP Public API 对接文档
最后更新:2026-07-02
本文档定义 WonderQ-MiniAPP 前台 H5/小程序对接 WonderQ-Admin 后端所需的 Public API 契约。当前 MiniAPP 主动调用站点配置、产品列表和线索提交 3 个接口;后端已存在的健康检查、产品详情和目的地列表接口建议继续保留,供后续前台按需接入。
基础约定
- 基础地址由 MiniAPP 环境变量
VITE_API_BASE_URL 控制;为空时前台按同源 /api 请求。
- Public API 不要求前台登录认证。
- 请求和响应均使用 JSON,字符集为 UTF-8。
- 图片字段应返回可被 H5 和微信小程序访问的 URL;现有前台兼容
/assets/... 形式。
- 列表字段建议返回空数组,不建议返回
null;MiniAPP 对站点配置和产品列表有本地兜底内容。
- 错误响应需提供可展示信息,兼容
{ "message": "..." } 或 FastAPI 默认 { "detail": "..." }。不要暴露内部异常、真实环境变量、Token、JWT secret、客服链接或企业 ID。
数据类型
HeroSlide
| 字段 |
类型 |
必填 |
说明 |
id |
string |
是 |
轮播图 ID |
title |
string |
是 |
主标题 |
kicker |
string | null |
否 |
辅助短文案 |
image |
string |
是 |
图片 URL |
targetType |
string | null |
否 |
点击目标类型 |
targetValue |
string | null |
否 |
点击目标值 |
isActive |
boolean |
否 |
是否启用 |
Destination
| 字段 |
类型 |
必填 |
说明 |
id |
string |
是 |
目的地 ID |
name |
string |
是 |
目的地名称 |
image |
string | null |
否 |
图片 URL |
isHot |
boolean |
否 |
是否热门 |
isActive |
boolean |
否 |
是否启用 |
aliases |
Array<{ id: string; alias: string }> |
否 |
搜索别名 |
Theme
| 字段 |
类型 |
必填 |
说明 |
id |
string |
是 |
主题 ID |
label |
string |
是 |
主题名称 |
image |
string |
是 |
图片 URL |
targetType |
string | null |
否 |
点击目标类型 |
targetValue |
string | null |
否 |
点击目标值 |
isActive |
boolean |
否 |
是否启用 |
CtaBanner
| 字段 |
类型 |
必填 |
说明 |
id |
string |
是 |
Banner ID |
alt |
string |
是 |
图片替代文案 |
image |
string |
是 |
图片 URL |
targetType |
string | null |
否 |
点击目标类型 |
targetValue |
string | null |
否 |
点击目标值 |
isActive |
boolean |
否 |
是否启用 |
Campaign
| 字段 |
类型 |
必填 |
说明 |
id |
string |
是 |
活动 ID |
slug |
string |
是 |
活动标识 |
title |
string |
是 |
活动标题 |
description |
string | null |
否 |
活动描述 |
coverImage |
string | null |
否 |
活动封面图 |
priceAmount |
number | null |
否 |
参考起价,单位按 priceUnit 展示 |
priceUnit |
string | null |
否 |
价格单位文案,默认 起/人 |
tags |
string[] |
否 |
活动卡片标签,最多 3 个 |
status |
string |
是 |
活动状态;Public API 只返回 published |
startsAt |
string | null |
否 |
活动开始时间 |
endsAt |
string | null |
否 |
活动结束时间 |
RouteSection
RouteSection 用于描述首页“精选线路”下的动态运营分组。后台可按任务新增、编辑、删除和排序分组;MiniAPP 不应依赖固定分组 ID,只按接口返回的分组顺序和 productIds 渲染。
| 字段 |
类型 |
必填 |
说明 |
id |
string |
是 |
后端生成的分组 ID,客户端只用于列表 key 和商品关联,不作为固定业务枚举 |
title |
string |
是 |
分组标题 |
subtitle |
string | null |
否 |
分组副文案 |
productIds |
string[] |
是 |
该分组包含的产品 ID;产品详情来自 /api/public/products.items |
isActive |
boolean |
否 |
是否启用;Public API 通常只返回启用分组 |
Public API 输出规则:
GET /api/public/site-config 只返回启用的 routeSections。
routeSections[].productIds 只包含已发布商品 ID;未发布、归档或不存在的商品不得出现在 Public 响应中。
- 动态分组按后台
sortOrder 升序返回,productIds 的顺序就是用户侧商品卡展示顺序。
- MiniAPP 会按
productIds 匹配 /api/public/products.items[].id;接口缺失、routeSections 为空或没有可匹配商品时回退 src/content.ts 的本地精选线路兜底内容。
PublicProduct
| 字段 |
类型 |
必填 |
说明 |
id |
string |
是 |
后端产品 UUID |
sourceId |
number | null |
否 |
历史采集产品 ID;前台可用于兼容旧数据 |
title |
string |
是 |
产品标题 |
subtitle |
string | null |
否 |
副标题 |
destination |
{ id: string; name: string } | null |
否 |
目的地信息 |
priceAmount |
number | null |
否 |
参考起价,单位按后端内容约定 |
priceUnit |
string | null |
否 |
价格单位文案 |
tags |
string[] |
否 |
标签列表 |
coverImage |
string | null |
否 |
封面图 URL |
summary |
string | null |
否 |
摘要 |
images |
Array<ProductImage> |
否 |
图集 |
detailSections |
ProductDetailSection[] | null |
否 |
产品详情分区 |
status |
string |
否 |
产品状态,前台主要消费 published 内容 |
ProductImage
| 字段 |
类型 |
必填 |
说明 |
id |
string |
否 |
图片 ID |
url |
string |
是 |
图片 URL |
alt |
string | null |
否 |
图片说明 |
sortOrder |
number |
是 |
排序值 |
ProductDetailSection
| 字段 |
类型 |
必填 |
说明 |
key |
string |
是 |
分区 key,例如 overview、itinerary、service、notice、price、manager |
label |
string |
是 |
Tab 展示文案 |
title |
string | null |
否 |
分区标题 |
blocks |
ProductDetailBlock[] |
是 |
内容块 |
ProductDetailBlock 支持两种结构:
接口清单
GET /health
用于服务健康检查。
响应示例
GET /api/public/site-config
用于首页轮播、目的地、主题入口和底部 CTA 配置。MiniAPP 启动时会和产品列表并行请求该接口;接口不可用或关键数组为空时,前台会回退本地静态内容。
响应字段
| 字段 |
类型 |
说明 |
heroSlides |
HeroSlide[] |
首页顶部轮播 |
destinations |
Destination[] |
首页目的地入口 |
map |
Array<{ id: string; image: string; isActive?: boolean }> |
贵州地图图片;MiniAPP 当前消费 map[0].image |
themes |
Theme[] |
主题甄选入口 |
ctaBanners |
CtaBanner[] |
底部 CTA Banner |
campaigns |
Campaign[] |
活动元信息,可用于“特价优惠”入口;当前不包含活动产品结果列表 |
routeSections |
RouteSection[] |
“精选线路”子分组定义 |
首页模块数据归属
| 首页模块 |
当前接口归属 |
说明 |
| 特价优惠 |
site-config.campaigns + /api/public/products |
当前 Public API 只返回活动元信息,不直接返回“特价优惠结果列表”。MiniAPP 若要展示活动线路,可按活动标题、标签或后续扩展的活动产品关联从 /api/public/products 中筛选。 |
| 精选线路 |
site-config.routeSections + /api/public/products |
routeSections 返回动态分组与 productIds;具体产品卡片数据由 /api/public/products.items 提供。后台可按任务新增、删除、停用和排序分组,用户侧不假设固定三组。 |
响应示例
{
"heroSlides": [
{
"id": "hero-1",
"title": "贵州小包团定制",
"kicker": "万趣,你的小包团首选",
"image": "/assets/guizhou/libo-xiaoqikong.jpg",
"targetType": "search",
"targetValue": "贵州",
"isActive": true
}
],
"destinations": [
{
"id": "dest-1",
"name": "荔波小七孔",
"image": "/assets/guizhou/libo-xiaoqikong.jpg",
"isHot": true,
"isActive": true,
"aliases": [{ "id": "alias-1", "alias": "小七孔" }]
}
],
"map": [
{
"id": "map-1",
"image": "/assets/guizhou/guizhou-map.jpg",
"isActive": true
}
],
"themes": [],
"ctaBanners": [],
"campaigns": [
{
"id": "campaign-1",
"slug": "classic-deal",
"title": "经典打卡特惠",
"description": "经典首游活动",
"coverImage": "/assets/guizhou/libo-xiaoqikong.jpg",
"priceAmount": 162500,
"priceUnit": "起/人",
"tags": ["臻藏旅位", "赛事庆典"],
"status": "published",
"startsAt": null,
"endsAt": null
}
],
"routeSections": [
{
"id": "route-section-001",
"title": "经典人文打卡线路",
"subtitle": "黄果树、荔波小七孔、千户苗寨、镇远古城、梵净山一次串联",
"productIds": ["8a6e7c4f-0000-4000-9000-000000000001"],
"isActive": true
},
{
"id": "route-section-002",
"title": "极限山野户外野咖线路",
"subtitle": "溶洞、峡谷、漂流、峰林骑行和山野咖啡组合",
"productIds": [],
"isActive": true
},
{
"id": "route-section-003",
"title": "人文+户外综合混搭线路",
"subtitle": "非遗村寨、古城夜游、自然轻探险和精品住宿同程安排",
"productIds": [],
"isActive": true
}
]
}
GET /api/public/products
用于首页产品分区、搜索结果、活动页、目的地页、详情推荐和预订入口。当前 MiniAPP 一次拉取列表后在前端做搜索、筛选和推荐。
Query 参数
| 参数 |
类型 |
必填 |
默认值 |
说明 |
keyword |
string |
否 |
无 |
关键词搜索,建议匹配产品标题、副标题、标签、目的地名称和目的地别名 |
destinationId |
string |
否 |
无 |
按目的地 ID 筛选 |
status |
string |
否 |
published |
产品状态 |
take |
number |
否 |
48 |
返回数量,后端当前限制 1-100 |
响应字段
| 字段 |
类型 |
说明 |
items |
PublicProduct[] |
产品列表 |
响应示例
GET /api/public/products/{product_id}
后端已存在,建议保留给 MiniAPP 后续详情页按需拉取。当前 MiniAPP 主要通过产品列表缓存进入详情。
Path 参数
| 参数 |
类型 |
说明 |
product_id |
string |
产品 UUID;如果传入纯数字,后端按 sourceId 查询 |
成功响应
返回单个 PublicProduct。
异常响应
示例:
GET /api/public/destinations
后端已存在,建议保留给 MiniAPP 后续目的地页独立拉取。当前 MiniAPP 首页目的地来自 site-config.destinations。
响应示例
POST /api/public/leads
用于首页快速定制、搜索页快速定制、需求页和预订咨询页提交线索。
请求字段
| 字段 |
类型 |
必填 |
说明 |
phone |
string |
是 |
联系方式。前台输入文案为“手机号 / 微信号”,后端当前会去除首尾空白并压缩连续空格 |
destination |
string |
否 |
目的地或玩法 |
travelDate |
string |
否 |
出行日期;MiniAPP 当前传 YYYY-MM-DD 字符串 |
peopleCount |
number |
否 |
出行人数,需大于 0 |
budgetMin |
number |
否 |
最低预算,需大于等于 0 |
budgetMax |
number |
否 |
最高预算,需大于等于 0 |
note |
string |
否 |
补充说明,后端当前限制最长 1000 字符 |
sourcePage |
string |
否 |
来源页面 |
sourceProductId |
string |
否 |
来源产品 UUID |
sourcePage 当前取值
| 值 |
来源 |
home_inline |
首页快速定制入口 |
search_inline |
搜索结果页快速定制入口 |
demand_page |
提交需求页 |
product_consult |
产品预订咨询页 |
请求示例
成功响应
状态码:201
常见异常
| 状态码 |
场景 |
422 |
请求体校验失败,例如 phone 为空、peopleCount 小于等于 0、note 超长 |
500 |
服务端异常,响应不得暴露内部细节 |
MiniAPP 当前依赖说明
site-config 与 products 会在应用启动时并行请求;任一请求失败时,MiniAPP 会回退到本地静态内容。
products.items 为空时,MiniAPP 会使用本地产品兜底数据。
- “精选线路”由
site-config.routeSections 定义动态分组标题、副文案和商品 ID 顺序,由 /api/public/products.items 提供产品详情;客户端不依赖固定分组 ID 或固定三组数量。
routeSections 缺失、为空或无法匹配到有效商品时,MiniAPP 使用 src/content.ts 的本地精选线路内容回退。
- “特价优惠”当前没有独立 Public 结果列表字段;
site-config.campaigns 只提供活动元信息,活动线路需通过产品标签/关键词筛选或后续扩展活动产品关联字段。
- 产品搜索当前主要在前端执行,依赖
title、tags、destination.name、summary。
- 产品详情页当前使用已加载的产品列表数据;后续可改为进入详情页时请求
GET /api/public/products/{product_id}。
- 收藏、浏览历史和最近咨询记录由 MiniAPP 本地存储处理,不需要后端接口。
- 企业微信客服由 MiniAPP 环境变量控制,不属于
WonderQ-Admin Public API;文档和接口不得写入真实链接或企业 ID。
后端验证建议
- 为
GET /health 增加或保留健康检查测试。
- 为
GET /api/public/site-config 验证返回 JSON 包含 heroSlides、destinations、map、themes、ctaBanners、campaigns、routeSections 数组字段。
- 为
GET /api/public/site-config 验证 routeSections 表达“精选线路”子分组;接口返回当前已配置且启用的分组,未配置时返回空数组并由 MiniAPP 本地内容兜底。
- 为
GET /api/public/site-config 验证 routeSections 只返回启用分组,且 productIds 不包含未发布商品。
- 为
GET /api/public/products 验证响应结构为 { items: [...] },并覆盖 keyword、destinationId、status、take 参数。
- 为
GET /api/public/products/{product_id} 验证 UUID、数字 sourceId 和 404 场景。
- 为
GET /api/public/destinations 验证只返回启用目的地及别名字段。
- 为
POST /api/public/leads 验证成功创建、phone 规范化、必填校验、人数/预算边界和备注长度限制。