hl-api-changelog/changelogs/2026-04/2026-04-19_early-bird-plan-product-unique.md

2.9 KiB

refactor: 早鸟计划保存强制"一产品一早鸟"唯一约束

服务: hl-order-service-v2 PR: #929 Issue: #917 日期: 2026-04-19 前端是否需要改动: 建议改动错误展示(新增约束冲突错误,需前端友好展示)


一、背景

一个产品同时只能绑定一个早鸟优惠计划(业务规则)。之前 DB 无唯一约束,Service 也不校验,运营可重复绑定同一产品到多个计划,导致 matchPlan 命中不确定。

本次从 Service 层 + DB 索引 两道防线强制约束。

二、变更接口

方法 路径 变更类型
POST /admin/order/early-bird 新增业务约束校验
PUT /admin/order/early-bird/{id} 同上

三、新增约束行为

保存前校验:请求体 productIds 中任意产品已被其他早鸟计划绑定 → 直接返回 code=500 + 明细消息(BusinessException,HTTP 200 + body.code=500

编辑时会自动排除当前计划 ID,即编辑同一计划仍使用原产品不算冲突。

四、错误响应示例

冲突场景

POST /admin/order/early-bird
{
  "planName": "五一早鸟",
  "discountAmount": 100.00,
  "minPeople": 2,
  "startDate": "2026-05-01",
  "endDate": "2026-05-15",
  "productIds": [2045345825172639746, 2045345825172639747]
}

// 响应(产品 2045345825172639746 已被其他计划绑定)
{
  "code": 500,
  "message": "以下产品已绑定其他早鸟计划,不能重复绑定:游牧的森林-短途版(产品ID=2045345825172639746, 已关联计划ID=2045586012523864065)",
  "data": null,
  "success": false
}
  • 多个冲突会用 ; 分隔列出
  • 消息含产品名Feign 失败时退化为 "产品[ID]" 占位)+ 产品 ID + 占用的计划 ID

编辑同一计划的产品(不算冲突)

PUT /admin/order/early-bird/2045586012523864065
{
  "planName": "默认早鸟优惠",
  "productIds": [2045345825172639746]   // 同一计划原本就绑的产品
}
// 响应: 200 OK

五、前端改动建议

  1. 错误提示展示:后端返回的错误消息已自带产品名/ID/冲突计划 ID,前端直接用 message 字段展示即可
  2. 可选优化:前端在选择 "适用产品" 时,可先调 GET /admin/order/early-bird 列表接口收集已占用的产品 ID,在下拉框禁用或标灰提示"已被计划 XX 占用"
  3. 编辑时:保持原绑定的产品不算冲突,前端无需特殊处理

六、兼容性

  • 之前一个产品绑多个计划的脏数据在生产环境由运维按 sql/migrations/20260419_917_early_bird_product_unique.sql 清洗(默认保留最早一条)
  • 本地 / 测试环境已完成 DDL 迁移,本地 DB 若存在重复数据请运行脚本中【审计】+【清洗】SQL 后再拉代码

七、关联

  • 后端 changelog: 2026-04-19_early-bird-product-unique-ddl.md(含 DDL 迁移细节)