changelog-filename-gate / validate (push) Successful in 2s
新增 GET /mp/product/ai-recommend 免登录开放接口,供 AI 推荐 调用。支持多维筛选(关键词/目的地/天数/季节/标签/报价/出发 日期/人数/资源类型等),排除私人定制 CUSTOM。 Co-Authored-By: Claude <noreply@anthropic.com>
9.6 KiB
9.6 KiB
schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
| schema | ticket | title | consumer | author | change_type | backend_status | gateway_status | frontend_status | frontend_owner | frontend_ref | target_release | verified_at | status_note | updated_at | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hl-changelog/v2 | 6207 | AI 推荐产品多维筛选开放接口(免登录,排除私人定制) | mp | wx(GIT) | 新增接口 | deployed | verified | pending | mmg | 2026-08-23 | GET /mp/product/ai-recommend 免登录开放接口,AI 推荐用。默认返回 PUBLISHED + CORE/GROUP(排除 CUSTOM 私人定制),支持多维筛选。后端/网关已测试服验证,前端待消费。 | 2026-08-23 | dev-v3 |
【新增接口·小程序端】AI 推荐产品多维筛选开放接口(#6207)
PR: #6220 | 服务: hl-mp-service / hl-product-service-v2 / hl-gateway | 作者: wx | 更新时间: 2026-08-23
免登录开放接口,供 AI 做产品推荐调用。除私人定制(CUSTOM)以外的全部已上架(PUBLISHED)产品,多维筛选,全部条件可选可组合。
一、背景
AI 做产品推荐需要一个查询接口:能筛选除私人定制以外的全部已上架产品,条件越多越好(目的地、天数、报价范围、团期、包含资源、人数、季节等),不需要登录。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | AI推荐产品查询 | GET | /mp/product/ai-recommend |
🆕 新增 | 免登录,多维筛选,分页 |
网关白名单已放行(
JwtAuthFilterSKIP_URLS),无 token 可直接调用。
三、接口详情
1. AI推荐产品查询 GET /mp/product/ai-recommend
BFF 透传至 product-service GET /internal/mp/product/ai-query。pageSize 最大 50。
数据范围(硬性):
product.status = PUBLISHED(已上架)product_type IN (CORE, GROUP)(排除 CUSTOM 私人定制)
入参(全部可选,可任意组合)
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| keyword | Query | String | 否 | ≤100 字符 | 关键词/目的地(匹配产品名/副标题) |
| productType | Query | String | 否 | CORE/GROUP | 产品类型(默认 CORE+GROUP,传单一值可收窄) |
| category | Query | String | 否 | family/honeymoon/photography/experience/driving | 产品分类 |
| lineId | Query | Long | 否 | - | 产品线ID |
| minDays | Query | Integer | 否 | ≥1 | 最短天数 |
| maxDays | Query | Integer | 否 | ≥1 | 最长天数 |
| seasons | Query | String | 否 | spring/summer/autumn/winter,逗号分隔多值 | 季节 |
| tags | Query | String | 否 | 逗号分隔多值 | 产品标签 |
| minPrice | Query | BigDecimal | 否 | - | 最低起步价 |
| maxPrice | Query | BigDecimal | 否 | - | 最高起步价 |
| startDate | Query | String | 否 | yyyy-MM-dd | 出发日期起始 |
| endDate | Query | String | 否 | yyyy-MM-dd | 出发日期结束 |
| partySize | Query | Integer | 否 | ≥1 | 人数(仅与 startDate+endDate 组合时生效,过滤「订不下」的产品) |
| resourceType | Query | String | 否 | SCENIC/ACTIVITY/RESTAURANT/SERVICE/CUSTOM | 包含资源类型 |
| resourceKeyword | Query | String | 否 | - | 包含资源关键词 |
| orderBy | Query | String | 否 | sort/price_asc/price_desc/newest | 排序 |
| page | Query | Integer | 否 | 默认1,≥1 | 页码 |
| pageSize | Query | Integer | 否 | 默认10,1~50 | 每页条数(最大 50,>50 返 400) |
seasons/tags 传法:逗号分隔多值,如
seasons=summer,winter、tags=亲子,摄影。
出参 Result<PageResult<MpProductAiQueryItemVO>>
| 字段 | 类型 | 说明 |
|---|---|---|
| records[].productId | String | 产品ID(雪花,字符串防精度丢失) |
| records[].productNo | String | 产品编号 |
| records[].productType | String | CORE/GROUP |
| records[].name | String | 产品名称 |
| records[].subtitle | String | 副标题 |
| records[].introduction | String | 产品简介 |
| records[].category | String | 产品分类 |
| records[].tripDays / tripNights | Integer | 天数 / 晚数 |
| records[].coverImageUrl | String | 封面图 |
| records[].carouselImages | String[] | 轮播图 |
| records[].tags / seasons | String[] | 标签 / 季节 |
| records[].lineId | String | 产品线ID |
| records[].lineName | String | 产品线名称 |
| records[].startPrice | String | 起步价(字符串) |
| records[].startPriceLabel | String | ¥3980起/人 |
| records[].paymentType | String | FULL / DEPOSIT |
| records[].status | String | PUBLISHED |
| records[].sortOrder | Integer | 排序号 |
| records[].earliestBookingDate | String | 最早可订日期 yyyy-MM-dd |
| records[].availableDateSummary | String | 可订日期摘要(如 2026-09-11 起) |
| records[].availabilitySummary | String | 余位摘要(GROUP: 8个班期可报名,余位充足(2026-09-11 ~ 2026-10-30);CORE: 9天可订(2026-08-23 ~ 2026-08-31)) |
| records[].matchedDestinations | String[] | 匹配到的目的地/途经点摘要 |
| total | Integer | 总条数 |
| page / pageSize | Integer | 页码 / 每页条数 |
请求示例
GET /mp/product/ai-recommend?productType=GROUP&seasons=summer&minPrice=0&maxPrice=20000&page=1&pageSize=5
响应示例(测试服实测)
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"productId": "2056947670512971778",
"productNo": "G260423004",
"productType": "GROUP",
"name": "测试小蒙马-多档-固定金额",
"subtitle": "",
"introduction": "测试产品简介",
"category": "photography",
"tripDays": 5,
"tripNights": 4,
"coverImageUrl": "https://hlgl-test.oss-cn-beijing.aliyuncs.com/...",
"tags": ["小蒙马"],
"seasons": ["summer"],
"lineId": "2001",
"lineName": "测试产品线",
"startPrice": "8800.00",
"startPriceLabel": "¥8800起/人",
"paymentType": "FULL",
"status": "PUBLISHED",
"sortOrder": 0,
"earliestBookingDate": "2026-09-11",
"availableDateSummary": "2026-09-11 起",
"availabilitySummary": "8个班期可报名,余位充足(2026-09-11 ~ 2026-10-30)"
}
],
"total": 5,
"page": 1,
"pageSize": 5
},
"success": true
}
空数据响应(无匹配条件)
{
"code": 200,
"message": "成功",
"data": { "records": [], "total": 0, "page": 1, "pageSize": 5 },
"success": true
}
错误响应(参数防御)
{
"code": 400,
"message": "每页条数不能大于50",
"data": null,
"success": false
}
四、契约约束与正确调用方式
筛选语义(后端为准)
- 所有条件 AND 组合:同时传多个条件时,返回同时满足全部条件的产品。
- seasons / tags 多值取 OR:
seasons=summer,winter表示「夏季 或 冬季」。 - 报价范围按起步价过滤:起步价 = GROUP 未来班期最低成人价 或 CORE 价格日历未来最低价,
minPrice/maxPrice作用于该值。 - 人数(partySize)过滤语义:仅当同时传了出发日期范围(startDate/endDate 至少一个)+ partySize 才生效——过滤「订不下」的产品:
- GROUP:看日期范围内是否有余位 ≥ partySize 的可报名班期(ENROLLING/NEARLY_FULL)
- CORE:看日期范围内是否有库存(dailyStock - sold)≥ partySize 的日期
- 只传 partySize 不传日期 → 不触发人数过滤。
- 目的地关键词:匹配产品名/副标题 或 途经点名称 或 行程节点名称(任一处命中即算)。
- 日期倒置自动修正:startDate 晚于 endDate 时后端自动交换,不报错。
✅ 正确 / ⚠️ 注意
| 场景 | 行为 |
|---|---|
| ✅ 无条件调用 | 返回全部在售(CORE+GROUP 且 PUBLISHED)分页 |
✅ seasons=summer,winter |
夏季或冬季的产品 |
✅ minPrice=1000&maxPrice=5000 |
起步价在区间内的产品 |
✅ startDate=2026-09-01&endDate=2026-10-01&partySize=2 |
该日期范围内能订下 2 人的产品 |
⚠️ pageSize=999 |
400 拒绝(上限 50) |
⚠️ 只传 partySize 不传日期 |
人数条件不生效 |
五、测试环境已验证(2026-08-23)
GET /mp/product/ai-recommend?page=1&pageSize=5 → 200 total=22 ✓
GET /mp/product/ai-recommend?keyword=草原&page=1&pageSize=5 → 200 total=13 ✓
GET /mp/product/ai-recommend?productType=GROUP&page=1&pageSize=3 → 200 total=6 ✓
GET /mp/product/ai-recommend?category=family&page=1&pageSize=5 → 200 total=12 ✓
GET /mp/product/ai-recommend?seasons=summer,winter&page=1&pageSize=5 → 200 total=19 ✓
GET /mp/product/ai-recommend?minPrice=1000&maxPrice=5000&page=1&pageSize=3 → 200 ✓
GET /mp/product/ai-recommend?orderBy=price_asc&page=1&pageSize=5 → 200 ✓(第一条约 2980 便宜档)
GET /mp/product/ai-recommend?productType=GROUP&seasons=summer&minPrice=0&maxPrice=20000 → 200 total=5 ✓
GET /mp/product/ai-recommend?startDate=2026-08-24&endDate=2026-10-22 → 200 total=14 ✓
GET /mp/product/ai-recommend?pageSize=999 → 400 每页条数不能大于50 ✓
GET /mp/product/ai-recommend?category=driving&seasons=winter&keyword=不存在xyz → 200 empty ✓
免登录(无 token)经网关调用全部返回 200。
六、相关历史
- 关联 Issue: wx/HL#6207
- 关联 PR: wx/HL#6220