Files
WonderQ-Admin/docs/miniapp-public-api.md
duanshuwen a47b4b5dd0 feat: Add WonderQ-MiniAPP Public API documentation
- Introduced a comprehensive API contract for the WonderQ-MiniAPP, detailing endpoints for site configuration, product listings, and lead submissions.
- Defined data types for various entities including HeroSlide, Destination, Theme, CtaBanner, PublicProduct, and more.
- Specified request and response formats, including error handling guidelines.

chore: Update requirements to include python-multipart

- Added python-multipart dependency to requirements.txt for handling file uploads.

test: Implement API contract tests

- Created test suite for API contracts, validating serializers and endpoints for public products and leads.
- Included tests for destination and product serializers, ensuring correct data handling and validation.

test: Add configuration tests for OSS settings

- Implemented tests to verify that OSS settings are correctly loaded from environment variables.
2026-07-01 16:55:00 +08:00

12 KiB
Raw Permalink Blame History

WonderQ-MiniAPP Public API 对接文档

最后更新2026-06-30

本文档定义 WonderQ-MiniAPP 前台 H5/小程序对接 WonderQ-Admin 后端所需的 Public API 契约。当前 MiniAPP 主动调用站点配置、产品列表和线索提交 3 个接口;后端已存在的健康检查、产品详情和目的地列表接口建议继续保留,供后续前台按需接入。

基础约定

  • 基础地址由 MiniAPP 环境变量 VITE_API_BASE_URL 控制;为空时前台按同源 /api 请求。
  • Public API 不要求前台登录认证。
  • 请求和响应均使用 JSON字符集为 UTF-8。
  • 图片字段应返回可被 H5 和微信小程序访问的 URL现有前台兼容 /assets/... 形式。
  • 列表字段建议返回空数组,不建议返回 nullMiniAPP 对站点配置和产品列表有本地兜底内容。
  • 错误响应需提供可展示信息,兼容 { "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 是否启用

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例如 overviewitineraryservicenoticepricemanager
label string Tab 展示文案
title string | null 分区标题
blocks ProductDetailBlock[] 内容块

ProductDetailBlock 支持两种结构:

{ "type": "text", "text": "文本内容" }
{ "type": "image", "url": "/assets/example.jpg", "alt": "图片说明" }

接口清单

GET /health

用于服务健康检查。

响应示例

{
  "ok": true,
  "service": "miniapp-api"
}

GET /api/public/site-config

用于首页轮播、目的地、主题入口和底部 CTA 配置。MiniAPP 启动时会和产品列表并行请求该接口;接口不可用或关键数组为空时,前台会回退本地静态内容。

响应字段

字段 类型 说明
heroSlides HeroSlide[] 首页顶部轮播
destinations Destination[] 首页目的地入口
themes Theme[] 主题甄选入口
ctaBanners CtaBanner[] 底部 CTA Banner
campaigns unknown[] 后端现有扩展字段,可保留
routeSections Array<{ id: string; title: string; productIds: string[] }> 后端现有扩展字段,可保留

响应示例

{
  "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": "小七孔" }]
    }
  ],
  "themes": [],
  "ctaBanners": []
}

GET /api/public/products

用于首页产品分区、搜索结果、活动页、目的地页、详情推荐和预订入口。当前 MiniAPP 一次拉取列表后在前端做搜索、筛选和推荐。

Query 参数

参数 类型 必填 默认值 说明
keyword string 关键词搜索,建议匹配产品标题、副标题、标签、目的地名称和目的地别名
destinationId string 按目的地 ID 筛选
status string published 产品状态
take number 48 返回数量,后端当前限制 1-100

响应字段

字段 类型 说明
items PublicProduct[] 产品列表

响应示例

{
  "items": [
    {
      "id": "8a6e7c4f-0000-4000-9000-000000000001",
      "sourceId": 101,
      "title": "黄果树瀑布小包团",
      "subtitle": "错峰入园,私家车接送",
      "destination": { "id": "dest-anshun", "name": "黄果树" },
      "priceAmount": 398000,
      "priceUnit": "起/人",
      "tags": ["贵州", "黄果树", "小包团"],
      "coverImage": "/assets/guizhou/huangguoshu.jpg",
      "summary": "适合首次到贵州的经典线路。",
      "images": [
        {
          "id": "img-1",
          "url": "/assets/guizhou/huangguoshu.jpg",
          "alt": "黄果树瀑布",
          "sortOrder": 0
        }
      ],
      "detailSections": [
        {
          "key": "overview",
          "label": "行程概述",
          "title": "小包团专属概览",
          "blocks": [{ "type": "text", "text": "按同行人、预算和体力强度重排行程。" }]
        }
      ],
      "status": "published"
    }
  ]
}

GET /api/public/products/{product_id}

后端已存在,建议保留给 MiniAPP 后续详情页按需拉取。当前 MiniAPP 主要通过产品列表缓存进入详情。

Path 参数

参数 类型 说明
product_id string 产品 UUID如果传入纯数字后端按 sourceId 查询

成功响应

返回单个 PublicProduct

异常响应

状态码 说明
404 产品不存在

示例:

{
  "detail": "线路不存在"
}

GET /api/public/destinations

后端已存在,建议保留给 MiniAPP 后续目的地页独立拉取。当前 MiniAPP 首页目的地来自 site-config.destinations

响应示例

{
  "items": [
    {
      "id": "dest-libo",
      "name": "荔波小七孔",
      "slug": "libo-xiaoqikong",
      "region": "黔南",
      "image": "/assets/guizhou/libo-xiaoqikong.jpg",
      "isHot": true,
      "sortOrder": 0,
      "isActive": true,
      "aliases": [{ "id": "alias-1", "alias": "小七孔" }]
    }
  ]
}

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 产品预订咨询页

请求示例

{
  "destination": "荔波小七孔",
  "phone": "187 8617 4929",
  "travelDate": "2027-01-01",
  "peopleCount": 2,
  "note": "咨询线路:黄果树瀑布小包团;方案偏好:经典人文",
  "sourcePage": "product_consult",
  "sourceProductId": "8a6e7c4f-0000-4000-9000-000000000001"
}

成功响应

状态码:201

{
  "id": "lead-uuid",
  "status": "new"
}

常见异常

状态码 场景
422 请求体校验失败,例如 phone 为空、peopleCount 小于等于 0、note 超长
500 服务端异常,响应不得暴露内部细节

MiniAPP 当前依赖说明

  • site-configproducts 会在应用启动时并行请求任一请求失败时MiniAPP 会回退到本地静态内容。
  • products.items 为空时MiniAPP 会使用本地产品兜底数据。
  • 产品搜索当前主要在前端执行,依赖 titletagsdestination.namesummary
  • 产品详情页当前使用已加载的产品列表数据;后续可改为进入详情页时请求 GET /api/public/products/{product_id}
  • 收藏、浏览历史和最近咨询记录由 MiniAPP 本地存储处理,不需要后端接口。
  • 企业微信客服由 MiniAPP 环境变量控制,不属于 WonderQ-Admin Public API文档和接口不得写入真实链接或企业 ID。

后端验证建议

  • GET /health 增加或保留健康检查测试。
  • GET /api/public/site-config 验证返回 JSON 包含 heroSlidesdestinationsthemesctaBanners 数组字段。
  • GET /api/public/products 验证响应结构为 { items: [...] },并覆盖 keyworddestinationIdstatustake 参数。
  • GET /api/public/products/{product_id} 验证 UUID、数字 sourceId 和 404 场景。
  • GET /api/public/destinations 验证只返回启用目的地及别名字段。
  • POST /api/public/leads 验证成功创建、phone 规范化、必填校验、人数/预算边界和备注长度限制。