From 95406b96e7d58cd6d0cf2259db69300f877f0e36 Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Thu, 7 May 2026 11:22:56 +0800 Subject: [PATCH] =?UTF-8?q?fix(mp-product):=20=E4=BB=B7=E6=A0=BC=E6=97=A5?= =?UTF-8?q?=E5=8E=86=E6=8E=A5=E5=8F=A3=E6=8E=A5=E6=94=B6=20startDate/endDa?= =?UTF-8?q?te=20=E6=97=B6=E6=8A=9B=20500=20(PR=20#1778,=20Closes=20#1776)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../07_fix_mp_price_calendar_null_500.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 changelogs/2026-05/07_fix_mp_price_calendar_null_500.md diff --git a/changelogs/2026-05/07_fix_mp_price_calendar_null_500.md b/changelogs/2026-05/07_fix_mp_price_calendar_null_500.md new file mode 100644 index 0000000..dc75bf0 --- /dev/null +++ b/changelogs/2026-05/07_fix_mp_price_calendar_null_500.md @@ -0,0 +1,65 @@ +# fix(mp-product): 价格日历接口接收 startDate/endDate 时抛 500 + +**PR**: [#1778](https://git.1814.love:8443/wx/HL/pulls/1778) **Issue**: [#1776](https://git.1814.love:8443/wx/HL/issues/1776) **合并**: 2026-05-07 + +通知对象: @mmg(小程序前端,建议小修一处) + +--- + +## 后端修了什么 + +`GET /mp/product/{id}/price-calendar` 接口当传 `?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD` 时报 500: + +``` +DateTimeParseException: Text 'null-01' could not be parsed at index 0 +``` + +根因:`MpPriceCalendarReqVO` 原本只声明 `month` 字段。前端 `packages/order/supplement/supplement.js:531` 传的是 `{startDate, endDate}` → Spring 没字段绑定 → `req.getMonth()=null` → `LocalDate.parse("null-01")` 抛异常。 + +PR #1778 补的: + +- VO 加 `startDate`/`endDate` 字段(与 `month` 二选一,向前兼容) +- Service 抽 `resolveMonthRange()` 私有方法:`startDate+endDate` 同月优先 → `month` 兜底 → 全空/格式错抛 `BusinessException` +- 加 2 个 ErrorCode: + - `410108 PRICE_CALENDAR_PARAM_MISSING` 参数缺失或格式错误 + - `410109 PRICE_CALENDAR_DATE_RANGE_CROSS_MONTH` startDate/endDate 跨月 +- 缓存 key 仍 `yyyy-MM` 月级粒度(`startDate=2026-07-01&endDate=2026-07-31` 与 `month=2026-07` 命中同一 cacheKey,无碎片) +- 单测加 5 场景全过:onlyMonth / sameMonth / crossMonth / allBlank / invalidFormat + +## 行为对照 + +| 请求 | 修复前 | 修复后 | +|------|--------|--------| +| `?month=2026-07` | 200 | 200(不变) | +| `?startDate=2026-07-01&endDate=2026-07-31` | **500 DateTimeParseException** | **200**(与 month=2026-07 字段级 IDENTICAL) | +| `?startDate=2026-07-01&endDate=2026-08-15` | 500 | 200 + Result.code=410109 跨月业务错 | +| 无参数 | 500 | 200 + Result.code=410108 参数缺失业务错 | + +## 前端建议(可选,@mmg) + +后端已完整兼容 `startDate/endDate`,**前端不修也能用**。 + +但 `month` 是默认契约(detail.js / confirm.js 都用 month),建议小程序 `packages/order/supplement/supplement.js:531` 也改成传 `{month}`,与其他两处统一: + +```js +// 当前(OK 但不一致) +const data = await productApi.getPriceCalendar(this.data.product.id, { startDate, endDate }); + +// 建议(与 detail.js / confirm.js 一致) +const month = startDate ? startDate.substring(0, 7) : formatTime(new Date(), 'YYYY-MM'); +const data = await productApi.getPriceCalendar(this.data.product.id, { month }); +``` + +非紧急,看你方便。 + +## 调用方对照(仓库 grep 全 3 处) + +- `packages/product/core/detail/detail.js:1319` 传 `{month}` ✅ +- `packages/order/confirm/confirm.js:526` 传 `{month, tierSeq}` ✅ +- `packages/order/supplement/supplement.js:531` 传 `{startDate, endDate}` ✅(后端已兼容,建议改 month 但不强制) + +## 验证 + +- 单测 67/67 全过 +- 本地 product-v2:8083 直连 round-trip 4 场景全通过(含字段级 IDENTICAL 等价性证据) +- 测试服部署后会再次 round-trip 一次