hl-api-changelog/changelogs-v2/2026-06/18_新建订单出发日期选择器需限制可售日期-前端待修-管理后台.md

6.8 KiB

新建订单「出发日期」选择器需限制为可售日期(前端待修) — 前端待修 — 管理后台

变更类型:🐛 前端 UX 缺陷(无后端代码变更、零 DDL;后端所需接口已存在且测试服可用,本文档给出对接方式) 端类型:管理后台(新建订单向导 → 第 3 步「基本信息」→「出发日期」选择器) 日期2026-06-18 服务hl-product-service-v2价格日历查询接口,已上线;hl-order-service-v3创单服务端兜底,已上线 责任端:前端 hl-uimmg


⚠️ 关键说明

现象:新建订单第 3 步的「出发日期」选择器是一个不受限的普通日期控件,任意日期都可选(截图里日历停在 2026 年 11 月 且全部可点)。

应有行为:只允许选择该产品 + 该档位下的可售日期(与产品卡「最近可出发」、小程序端下单日历口径一致)。

根因 = 前端未把日期选择器与已有的「价格日历」接口打通,不是后端缺接口:

  1. 限制可选范围所需的接口已存在且测试服可用GET /admin/product/item/{productId}/pricing-calendar,逐日返回 sellable(是否可售,后端算好)。前端在第 3 步已持有 productId(第 2 步选品)+ tierSeq(第 2 步选档),直接调它把非可售日期置灰即可(详见 §2
  2. 后端已在服务端兜底:即便选了非可售日期提交,创单也会被拦下、不会落库(详见 §3。所以这是纯前端的「提前拦截 / 体验」问题——当前用户能选到注定失败的日期,提交后才报错,且报错文案误导(见 §3

实测样本(测试服 9443 + 真实 admin token产品「游牧的森林-短途版」(productId=2045345825172639746,CORE 类型) 可售日仅 2026-06-18~2026-06-30 共 13 天;其余 78 天(含整个 11 月)sellable=false。截图里 11 月全部可选属错误,应整月禁选。


1. 复现

  1. 新建订单 → 选主题「游牧的森林」→ 选产品「游牧的森林-短途版」→ 选档位「轻奢」。
  2. 第 3 步「基本信息」点「出发日期」,日历弹出。
  3. 现状:所有日期都能点(截图停在 2026-11,全月可选
  4. 期望:只有 2026-06-18~2026-06-30 可点,其余置灰;最好默认定位到「最近可出发」所在月2026-06而不是空月份。

2. 修复方式:用 pricing-calendar 给选择器置灰

GET /admin/product/item/{productId}/pricing-calendar

参数 位置 必填 说明
productId path 第 2 步选中的产品 ID
month query yyyy-MM;不传返回全部已配日历
tierSeq query 档位序号,仅 CORE/CUSTOM 生效;传第 2 步选中的档位(不同档位可售日可能不同)

响应 data{ productType, items[] }items[] 子项关键字段:

字段 类型 说明
date LocalDate(yyyy-MM-dd) 日期
sellable Boolean 是否可售(置灰判据:sellable !== true 即禁选)
adultPrice String 成人价(金额=带引号字符串)
childPrice / infantPrice / toddlerDiscount String 各人群价/优惠
stock / sold Integer 库存上限 / 已售stock=null 表示不限)
tierSeq / priceType Integer / String 档位序号 / 价格类型

前端对接建议

  1. 进入第 3 步(或用户在日历翻月)时,按 productId + tierSeq 拉日历(可不传 month 一次性取全部,数据量小)。
  2. itemssellable === truedate 构造「可选日期集合」,其余日期一律 disabled;列表里没有的日期也按不可选处理。
  3. 默认打开月份用产品卡已有的「最近可出发」(nextSaleDate) 所在月,避免落到空月份。
  4. 用户在第 2 步改了档位再回到第 3 步时,需按新 tierSeq 重新拉取。
# 拉「游牧的森林-短途版」轻奢档(tierSeq=1)的可售日历
curl -k "https://api.test.1814.love:9443/admin/product/item/2045345825172639746/pricing-calendar?tierSeq=1" \
  -H "Authorization: Bearer <adminToken>"

实测返回(节选,已上线测试服):

{
  "code": 200,
  "success": true,
  "data": {
    "productType": "CORE",
    "items": [
      { "date": "2026-06-18", "adultPrice": "3.00", "childPrice": "3.00", "sellable": true,  "tierSeq": 1, "priceType": "NORMAL", "stock": null, "sold": 0 },
      { "date": "2026-06-30", "adultPrice": "3.00", "sellable": true,  "tierSeq": 1 },
      { "date": "2026-11-15", "sellable": false, "tierSeq": 1 }
    ]
  }
}

本例中 sellable=true 仅 13 天(2026-06-18~2026-06-30),其余(含 11 月全月)sellable=false


3. 后端服务端兜底(已生效,前端可放心)

创单接口 POST /v3/admin/order 已对出发日期做服务端校验,非可售日期 / 过去日期都进不去(实测,均未落库):

提交的出发日期 结果 code message
2026-06-20(可售) 通过报价、正常创单 200
2026-11-15(不可售) 被拦截,不落库 581041 所选出发日期不可售或未配置价格,请重新选择出发日期
2026-06-01(早于今天) 被拦截,不落库 581011 出发日期不能早于今天

已优化PR #4008,已合 dev-v3 + 部署测试服双实例实测):非可售日期之前误报 581014「拉取产品信息失败,请稍后重试」(像系统故障),现已改为 581041「所选出发日期不可售或未配置价格,请重新选择出发日期」,前端可直接透传该 message 给用户。581014 现仅表示真正的产品服务不可达。前端按 §2 限制好选择器后,正常路径不会触发 581041,它是用户绕过限制时的兜底提示。


4. 实测确认

  • 价格日历接口 GET /admin/product/item/2045345825172639746/pricing-calendar?tierSeq=1200data.items 共 91 条,sellable=true 13 条(2026-06-18~2026-06-30)✓
  • 创单非可售日期 2026-11-15:被拦截 581041「所选出发日期不可售或未配置价格…」PR #4008 优化后),无新增订单 ✓
  • 创单过去日期 2026-06-01:被拦截 581011
  • 均经测试服网关 9443 + 真实 admin token 验证。

备注

  • 本文为前端缺陷通知 + 现有接口对接说明,无后端代码变更、零 DDL、无新增/改动接口。
  • pricing-calendar 接口为产品管理「价格日历」长期已上线端点,CORE/CUSTOM 走 product_price_calendar 逐日价、GROUP 走 group_tour_batch 班期(按出发日),前端按 data.productType 区分渲染。
  • 小程序端下单日历亦是同口径(按可售日置灰),管理后台对齐即可。