# 【行为变更·管理后台】早鸟优惠——同一产品禁止两个"会对同一订单同时生效"的早鸟计划(人数阶梯保留)

> 服务:hl-order-service-v2(8094) + hl-order-service-v3(8086) | 分支:dev-v3 | PR:#4097 | 工单:#4094
> 已部署测试服并经网关 9443 真 admin token 端到端实测通过(2026-06-20):冲突 create 返 585010;人数不重叠的阶梯档 create 正常 200。

## ⚠️ 关键说明

1. **早鸟新增"防同订单冲突"校验**:一个产品仍可挂多个早鸟计划当**人数阶梯**(满5减100/满10减300,下单按人数命中最优一档,此能力**保留不变**)。新增的限制是:**禁止同一产品出现两个"会对同一笔订单同时生效"的早鸟**——即两个计划都启用、且**生效日期窗重叠、且人数区间重叠**时拒绝。
2. **触发入口**:新建(create)、编辑(update,本计划处启用态时)、启用(toggle 启用)三处。命中冲突时**保存/启用失败**,返回业务码:
   - order-v2(线上购买/报价端):**`code=585010`**「产品(ID=X)已存在生效时间与人数区间重叠的早鸟计划(planId=Y),不能重复创建或启用」
   - order-v3:**`code=581610`**(同义消息)
3. **前端需留意**:早鸟计划配置页保存/启用**不再恒成功**,命中冲突会返上面的业务码(HTTP 仍 200,`success=false`)。请按 `success===true` 判定成功,失败时把后端 `message` 直接 toast 出来(消息已是可读中文,无需前端拼文案)。
4. **不算冲突、照旧放过的情况**:① 人数区间不重叠(如满1-4 与 满5-9,这就是阶梯);② 生效日期窗不重叠(不同档期);③ 对方计划已禁用;④ 编辑时与自己不算冲突。

## 1. 各场景行为对照

| 场景(同一产品) | 旧 | 新 |
|---|---|---|
| 新建早鸟,产品已有启用且日期+人数都重叠的计划 | 允许,运行时被动按 priority 选一个(有按错价风险) | **拒绝**,返 585010/581610 |
| 新建早鸟,人数区间不重叠(阶梯档) | 允许 | 允许(阶梯能力保留) |
| 新建早鸟,日期窗不重叠(不同档期) | 允许 | 允许 |
| 编辑/启用计划致与他计划"同订单同时生效" | 允许 | **拒绝** |
| 禁用计划 | 允许 | 允许(不校验,禁用只会减少生效计划) |

## 2. 端到端实测记录(测试服,网关 9443 真 admin token)

```text
TEST1 冲突:产品 2056938821550747650 已有启用计划(min1+/2026-05-01~06-30)
  POST /admin/order/early-bird {minPeople:2,maxPeople:10,startDate:2026-06-01,endDate:2026-06-15,productIds:[...]}
  → code=585010 success=false   ✅ 按预期拒绝
TEST2 阶梯:产品 2047268852147875842 已有启用计划(min6+)
  POST /admin/order/early-bird {minPeople:1,maxPeople:5,startDate:2026-07-01,endDate:2026-07-31,productIds:[...]}
  → code=200 success=true       ✅ 人数不重叠的阶梯档照旧放过(实测后已删除临时数据)
```

## 3. 后端内部变更(备查)

1. `EarlyBirdPlanService`(v2/v3)新增 `validateNoActiveConflict`,在 create/update/toggle 三入口接线。冲突判定 = 同产品(排除自身)的另一启用计划,日期窗重叠 且 人数区间重叠(minPeople 空按 1、maxPeople 空按无上限)。
2. `EarlyBirdPlanMapper`(v2/v3)新增 `selectEnabledByIds`(LambdaQueryWrapperX)。
3. 新错误码:v2 `OrderEarlyBirdErrorCode.PRODUCT_HAS_CONFLICTING_PLAN=585010`、v3 `EarlyBirdErrorCode.PRODUCT_HAS_CONFLICTING_PLAN=581610`。
4. 未动数据库/匹配算法(`doFindBestMatch`)/网关路由;纯配置端 Java 校验。
