hl-api-changelog/changelogs-v2/2026-06/20_4076_早鸟优惠计划管理CRUD接口-新增接口-管理后台.md

14 KiB

早鸟优惠计划管理 CRUD 接口(管理后台)

  • 端类型:管理后台
  • 变更类型:新增接口
  • 日期2026-06-20
  • PR#4076
  • 负责人yst腰苏图

接口背景

早鸟优惠Early Bird Discount是订单 v3 新增的优惠机制,允许管理员为指定产品配置日期区间 x 人数区间 x 折扣方式三维优惠计划。下单时系统自动匹配最优方案并应用优惠。

本次PR #4076新增管理后台侧 CRUD 6 个接口,供管理员对早鸟计划进行增删改查、启停操作。


变更清单

# 方法 路径 说明
1 GET /v3/admin/order/early-bird/list 早鸟计划分页列表
2 GET /v3/admin/order/early-bird/{planId} 早鸟计划详情
3 POST /v3/admin/order/early-bird 创建早鸟计划
4 PUT /v3/admin/order/early-bird/{planId} 修改早鸟计划(不影响已下单订单)
5 DELETE /v3/admin/order/early-bird/{planId} 删除早鸟计划
6 PUT /v3/admin/order/early-bird/{planId}/toggle 启用 / 禁用早鸟计划

全部为新增接口,无前版存量接口被替换。

接口详情

项目 说明
认证 需要管理后台 JWT TokenAuthorization: Bearer token
Base URL /v3/admin/order/early-bird
幂等性 POST 创建非幂等同参数可重复创建多个计划;PUT 修改按 planId 幂等覆盖
限流 无独立限流规则,走全局网关限流
内容类型 请求体 Content-Type: application/json;GET 请求均为 Query 参数

接口入参

4.1 GET /v3/admin/order/early-bird/list — 分页列表

参数 类型 必填 说明
pageNo Integer 页码,从 1 开始
pageSize Integer 每页条数,建议 10 / 20

4.2 GET /v3/admin/order/early-bird/{planId} — 详情

路径参数 planIdLong早鸟计划 ID。

4.3 POST /v3/admin/order/early-bird — 创建

请求体EarlyBirdPlanSaveReqVO

字段 类型 必填 校验规则 说明
planName String NotBlank 计划名称
remark String 优惠描述
discountType String 枚举三选一 折扣方式,默认 AMOUNT_TOTAL见枚举节
discountAmount BigDecimal 条件必填 AMOUNT_PER_PERSON 或 AMOUNT_TOTAL 时必填 优惠金额(元)
discountPercent BigDecimal 条件必填 PERCENT 时必填,值区间 (0, 100) 开区间 折扣率,80=8折非立减百分比
priority Integer >=0,默认 0 优先级,同区间多命中时大者优先
minPeople Integer >=1 最低适用人数(含)
maxPeople Integer >=1 且 >=minPeople 最高适用人数(含),不填=不限
startDate LocalDate yyyy-MM-dd 生效开始日期
endDate LocalDate yyyy-MM-dd,需 >=startDate 生效结束日期
productIds List 关联产品 ID 列表,空=不限产品
applicableTravelerTypes List 枚举值见下 适用人群 code 列表,空=后端自动填充成人+儿童+小童(排婴儿)

4.4 PUT /v3/admin/order/early-bird/{planId} — 修改

路径参数 planIdLong。请求体与 4.3 完全一致,全字段覆盖更新。修改不影响已下单订单中已匹配的早鸟优惠。

4.5 DELETE /v3/admin/order/early-bird/{planId} — 删除

路径参数 planIdLong。无请求体。

4.6 PUT /v3/admin/order/early-bird/{planId}/toggle — 启用 / 禁用

参数 类型 位置 说明
planId Long Path 早鸟计划 ID
enabled Boolean Query true=启用;false=禁用

禁用后该计划不再参与下单时自动匹配。

出参字段

所有接口返回 Result 包装,成功 code=200。列表接口返回 Result<PageResult>,创建/详情返回 Result,修改/删除/toggle 返回 Result。

EarlyBirdPlanVO 字段表

字段 类型 说明
planId Long字符串序列化 计划 ID,雪花 ID,前端用字符串接收防精度丢失
planName String 计划名称
remark String 优惠描述,可为 null
discountType String 折扣方式枚举 code
discountAmount BigDecimal 优惠金额,PERCENT 类型时为 null
discountPercent BigDecimal 折扣率0~100,非 PERCENT 时为 null;80=8折
priority Integer 优先级
minPeople Integer 最低适用人数(含)
maxPeople Integer 最高适用人数,null=不限
peopleRangeText String 后端拼好的人数区间文案,如 3-5 人 / 3 人及以上
discountText String 后端拼好的折扣说明,如 每人立减 100 元 / 整单立减 500 元 / 8 折优惠
startDate LocalDateyyyy-MM-dd 生效开始日期
endDate LocalDateyyyy-MM-dd 生效结束日期
enabled Boolean 是否启用
applicableTravelerTypes List 适用人群 code 列表;配置为空时后端回填 [ADULT, CHILD, YOUNG_CHILD]
applicableTravelerTypesText String 后端拼好的适用人群文案,如 成人/儿童/小童
productIds List 关联产品 ID 列表,空=不限产品
productNames List 关联产品名称,下标与 productIds 对齐;产品已删除时填 产品[ID]已删除
products List<{productId:Long, name:String}> 关联产品结构化列表
createTime LocalDateTime 创建时间
updateTime LocalDateTime 最后更新时间

枚举 / 数据字典

discountType — 折扣方式

code 中文 计算说明
AMOUNT_PER_PERSON 每人立减 优惠金额 = discountAmount x 计费人数
AMOUNT_TOTAL 整单立减(默认) 优惠金额 = discountAmount
PERCENT 按比例打折 优惠金额 = 总价 x (100 - discountPercent) / 100

discountPercent 语义值为折扣率,80 表示 8折,不是打 8 折的优惠百分比。立减额 = 总价 x (100 - 80) / 100 = 总价 x 0.2。

applicableTravelerTypes — 适用人群

code 中文 人数匹配规则
ADULT 成人 计入人数
CHILD 儿童 计入人数
YOUNG_CHILD 小童 计入人数
BABY 婴儿 默认不计入人数,需显式配置才计入

人数匹配口径:命中方案的 applicableTravelerTypes 中包含哪几类,就统计哪几类的人数判断是否满足 minPeople/maxPeople 区间。默认配置排除婴儿。


错误码

早鸟模块错误码段位581600 – 581699

错误码 说明 触发场景
581600 早鸟计划不存在 planId 查不到对应记录
581601 早鸟计划已禁用 对已禁用计划执行不允许操作
581602 当前日期不在有效期内 当前日期早于 startDate 或晚于 endDate
581603 人数不满足最低人数要求({0} 计费人数 < minPeople,{0} 为最低人数阈值
581604 人数超过最高人数限制({0} 计费人数 > maxPeople,{0} 为最高人数阈值
581605 PERCENT 时折扣率不能为空 discountType=PERCENT 但 discountPercent 未传
581606 {0} 类型时优惠金额不能为空 立减类型但 discountAmount 未传,{0} 为类型名
581607 最高人数不能小于最低人数 maxPeople < minPeople
581608 结束日期不能早于开始日期 endDate < startDate
581609 适用人群包含非法取值:{0} applicableTravelerTypes 有不在枚举范围的 code
581610 产品已存在生效时间与人数区间重叠的早鸟计划,不能重复创建或启用 同产品同时间段同人数区间已有启用计划

示例

8.1 典型成功 — 创建早鸟计划(整单立减)

POST /v3/admin/order/early-bird,Content-Type: application/json

请求体:

{
  "planName": "暑期早鸟立减300",
  "remark": "7月出发整单立减300元",
  "discountType": "AMOUNT_TOTAL",
  "discountAmount": 300,
  "priority": 10,
  "minPeople": 2,
  "maxPeople": 6,
  "startDate": "2026-07-01",
  "endDate": "2026-07-31",
  "productIds": [1900000000001, 1900000000002],
  "applicableTravelerTypes": ["ADULT", "CHILD", "YOUNG_CHILD"]
}

响应:

{
  "code": 200,
  "msg": "success",
  "data": {
    "planId": "1920000000001234",
    "planName": "暑期早鸟立减300",
    "remark": "7月出发整单立减300元",
    "discountType": "AMOUNT_TOTAL",
    "discountAmount": 300.00,
    "discountPercent": null,
    "priority": 10,
    "minPeople": 2,
    "maxPeople": 6,
    "peopleRangeText": "2-6 人",
    "discountText": "整单立减 300 元",
    "startDate": "2026-07-01",
    "endDate": "2026-07-31",
    "enabled": true,
    "applicableTravelerTypes": ["ADULT", "CHILD", "YOUNG_CHILD"],
    "applicableTravelerTypesText": "成人/儿童/小童",
    "productIds": [1900000000001, 1900000000002],
    "productNames": ["云南大理亲子7日游", "丽江雪山5日徒步"],
    "products": [
      {"productId": 1900000000001, "name": "云南大理亲子7日游"},
      {"productId": 1900000000002, "name": "丽江雪山5日徒步"}
    ],
    "createTime": "2026-06-20T10:00:00",
    "updateTime": "2026-06-20T10:00:00"
  }
}

8.2 边界情况 — 折扣率类计划(不限人数、不限产品)

maxPeople 不传=不限;productIds 不传=不限产品;applicableTravelerTypes 不传=后端回填默认值。

请求体:

{
  "planName": "年底全产品9折",
  "discountType": "PERCENT",
  "discountPercent": 90,
  "minPeople": 1,
  "startDate": "2026-12-01",
  "endDate": "2026-12-31"
}

响应:

{
  "code": 200,
  "msg": "success",
  "data": {
    "planId": "1920000000001235",
    "planName": "年底全产品9折",
    "remark": null,
    "discountType": "PERCENT",
    "discountAmount": null,
    "discountPercent": 90.00,
    "priority": 0,
    "minPeople": 1,
    "maxPeople": null,
    "peopleRangeText": "1 人及以上",
    "discountText": "9 折优惠",
    "startDate": "2026-12-01",
    "endDate": "2026-12-31",
    "enabled": true,
    "applicableTravelerTypes": ["ADULT", "CHILD", "YOUNG_CHILD"],
    "applicableTravelerTypesText": "成人/儿童/小童",
    "productIds": [],
    "productNames": [],
    "products": [],
    "createTime": "2026-06-20T11:00:00",
    "updateTime": "2026-06-20T11:00:00"
  }
}

8.3 业务失败 — 产品时间区间人数区间重叠581610

该产品+时间段+人数区间已有另一启用计划。请求体:

{
  "planName": "冲突测试计划",
  "discountType": "AMOUNT_TOTAL",
  "discountAmount": 100,
  "minPeople": 2,
  "maxPeople": 5,
  "startDate": "2026-07-01",
  "endDate": "2026-07-15",
  "productIds": [1900000000001]
}

响应:

{
  "code": 581610,
  "msg": "产品已存在生效时间与人数区间重叠的早鸟计划,不能重复创建或启用",
  "data": null
}

业务边界

适用场景:管理员新建/修改/删除早鸟优惠配置;对已有计划快速启停;查询当前所有早鸟计划状态。

不适用场景:小程序用户侧查看早鸟优惠(走 internal Feign 接口);下单时自动匹配优惠(订单服务内部逻辑,前端无需干预);修改不追溯已下单订单中已应用的优惠金额。

特殊边界

  • 同一产品在同一时间段+人数区间内只允许存在一个启用状态的计划581610;禁用状态不参与冲突检测
  • discountPercent=80 表示 8折,不是优惠 80%;前端展示需转换为 X折格式
  • planId 为雪花 ID,JSON 已序列化为字符串,前端用字符串类型接收
  • applicableTravelerTypes 传空或不传,后端自动填充默认值 [ADULT, CHILD, YOUNG_CHILD] 并持久化

修改前后对比

新增接口,无前版对比。


影响评估 / 回滚

新增接口,不影响存量功能,无需回滚策略。如需下线,在网关层屏蔽 /v3/admin/order/early-bird 前缀即可。


注意事项

  1. discountPercent 语义陷阱80=8折,不是立减 80%。前端展示请转换为 X折,勿直接显示 80%。
  2. planId 雪花 ID 序列化:响应中已序列化为字符串;调用修改/删除/toggle 时路径参数直接传字符串即可。
  3. applicableTravelerTypes 回填:创建时不传或传空,后端自动填充默认值并持久化;详情/列表返回实际存储值(不再是空数组)。
  4. toggle 启用触发重叠校验581610将已禁用计划重新启用时,若同时间+人数区间已有其他启用计划,会拒绝启用。
  5. PUT 修改是全字段覆盖,不支持 PATCH 语义,未传的选填字段会被重置为 null/默认值。
  6. productNames/products 降级关联产品已删除时,productNames 对应位置返回 产品[ID]已删除,前端按需降级处理。

关联 / 联系人

项目 内容
PR #4076 早鸟优惠管理后台 CRUD
后端负责人 yst腰苏图
变更服务 hl-order-service-v3