docs(changelog): 小程序用车详情 vehicleCount 由车·日数订正为车辆台数(#8143)
changelog-filename-gate / validate (push) Failing after 2s
changelog-filename-gate / validate (push) Failing after 2s
同一个订单同一个字段,返回的数字会变小(3 天 2 辆车由 6 变成 2)。 字段名/类型/其余字段全不变,前端把它当「车辆数」展示则无需改动。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,275 @@
|
|||||||
|
---
|
||||||
|
schema: "hl-changelog/v2"
|
||||||
|
ticket: "8143"
|
||||||
|
title: "用车详情 vehicleCount 由「车·日数」订正为「车辆台数」"
|
||||||
|
consumer: "mp"
|
||||||
|
author: "jw(GIT)"
|
||||||
|
change_type: "修改接口"
|
||||||
|
backend_status: "deployed"
|
||||||
|
gateway_status: "verified"
|
||||||
|
frontend_status: "pending"
|
||||||
|
frontend_owner: ""
|
||||||
|
frontend_ref: ""
|
||||||
|
target_release: ""
|
||||||
|
verified_at: "2026-09-22"
|
||||||
|
status_note: "路径/方法/入参/出参字段名全不变,唯一变化是 vehicleCount 的【值】——同一个订单同一个字段,数字会变小(3 天 2 辆车由 6 变成 2)。前端把它当「车辆数」展示则无需改动、显示自动变正确;若有基于该值的派生计算需复核。"
|
||||||
|
updated_at: "2026-09-22"
|
||||||
|
base: "dev-v3"
|
||||||
|
---
|
||||||
|
|
||||||
|
# 小程序用车详情: vehicleCount 由「车·日数」订正为「车辆台数」
|
||||||
|
|
||||||
|
> **服务**: hl-mp-service (端口 8085/8185)
|
||||||
|
> **PR**: #8172
|
||||||
|
> **Issue**: #8143
|
||||||
|
> **日期**: 2026-09-22
|
||||||
|
> **影响范围**: 小程序订单详情页「服务包含」→「用车详情」弹窗的车辆数字段
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ 关键变化
|
||||||
|
|
||||||
|
`GET /mp/order/:orderId/vehicle` 的 `vehicleCount`,**契约一直声明是「车辆数」,实际下发的却是派车明细行数(车·日数)**。3 天 2 辆车的订单下发 `6`。本次订正为按车辆去重的台数,**同一个订单、同一个字段,返回的数字会变小**。
|
||||||
|
|
||||||
|
字段名、类型、其余所有字段均不变。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、背景
|
||||||
|
|
||||||
|
v2 时代派车列表一车一行,行数即台数,两者恒等;v3 起派车明细的行粒度变成「一车一日」,取列表长度这个表达式的含义随之漂移成「车·日数」,而字段声明没跟着改。上游把这个数存在用车需求表的 `assignment_used_vehicle_day_count` 列里——**列名就是它真正的口径**。
|
||||||
|
|
||||||
|
该字段直接展示给客人,失败形态是静默的:无异常、无错误码,照常返回 200。
|
||||||
|
|
||||||
|
测试库实证(只读统计):
|
||||||
|
|
||||||
|
| 维度 | 读数 |
|
||||||
|
|------|------|
|
||||||
|
| (订单, 用车需求) 组合总数 | 165 |
|
||||||
|
| 行数 ≠ 去重台数的组合 | **123(74.5%)** |
|
||||||
|
| 最极端样本 | 订单 `2091418470443810817`:1 辆车连开 6 天,下发 `6` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、变更接口清单
|
||||||
|
|
||||||
|
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||||
|
|---|------|------|------|----------|------|
|
||||||
|
| 1 | 用车详情 | GET | `/mp/order/:orderId/vehicle` | 出参字段值语义订正 | `vehicleCount` 改为按车辆去重的台数;字段名/类型/其余字段全不变 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、接口详情
|
||||||
|
|
||||||
|
### 1. 用车详情 `GET /mp/order/:orderId/vehicle`
|
||||||
|
|
||||||
|
**VO**: `MpVehicleDetailVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
小程序订单详情页「服务包含」列表中「用车」条目的点击弹窗。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
**零变化**。
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|------|------|------|------|------|------|
|
||||||
|
| `orderId` | path | Long | 是 | 雪花 ID,**按字符串传** | 订单 ID |
|
||||||
|
|
||||||
|
无查询参数、无请求体。登录态由网关注入 `X-User-Id`,前端不传。
|
||||||
|
|
||||||
|
#### 出参 `Result<MpVehicleDetailVO>`
|
||||||
|
|
||||||
|
字段名、类型、字段个数**全部不变**。唯一变化是 `vehicleCount` 的取值口径:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `vehicleCount` | Integer | **本次改动**。改前=派车明细行数(车·日数);改后=按车辆去重的台数 |
|
||||||
|
| `vehicleType` / `plateNumber` / `driverName` / `driverPhone` / `seatCount` | String / Integer | 不变,仍取第一辆车 |
|
||||||
|
| `matched` | Boolean | 不变 |
|
||||||
|
| `coverUrl` / `vehicleCategory` / `driverYearsRequired` / `features` | - | 不变,自 #7306 B-7 起恒 null |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /mp/order/2091418470443810817/vehicle
|
||||||
|
Authorization: Bearer <user token>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
改前(测试环境实测):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":200,"message":"成功","data":{
|
||||||
|
"vehicleType":"suv","vehicleCount":6,"coverUrl":null,
|
||||||
|
"plateNumber":"蒙A-E2E01","driverName":"阿拉坦","driverPhone":"135****5019",
|
||||||
|
"matched":true,"seatCount":5,
|
||||||
|
"vehicleCategory":null,"driverYearsRequired":null,"features":null},
|
||||||
|
"success":true}
|
||||||
|
```
|
||||||
|
|
||||||
|
改后(**仅 `vehicleCount` 变化**):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":200,"message":"成功","data":{
|
||||||
|
"vehicleType":"suv","vehicleCount":1,"coverUrl":null,
|
||||||
|
"plateNumber":"蒙A-E2E01","driverName":"阿拉坦","driverPhone":"135****5019",
|
||||||
|
"matched":true,"seatCount":5,
|
||||||
|
"vehicleCategory":null,"driverYearsRequired":null,"features":null},
|
||||||
|
"success":true}
|
||||||
|
```
|
||||||
|
|
||||||
|
该订单实际就是 1 辆车(蒙A-E2E01)连开 6 天。
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
未配车时仍返回 `matched=false` 的成功响应,`vehicleCount` 不下发。**该路径零变化**(改前改后响应逐字段一致,已实测)。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
**不新增、不改动**,既有行为逐字保持:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":581008,"message":"无权查看此订单","data":null,"success":false}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"code":581007,"message":"订单不存在","data":null,"success":false}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- **「当日无需用车」的日行不计入台数**。车务可把行程中某一天明确标记为不用车,这种日行没有车辆、车牌与司机,它不占一个台数。
|
||||||
|
- 因此「3 天全都不用车」算出的是 `0` 而不是 `1`——多条无车日行不会被折叠成一台。
|
||||||
|
- **多车订单仍只显示第一辆车**的车型/车牌/司机/座位数,本次未改展示形态。
|
||||||
|
- 该字段与用车天数无关,不能用它反推行程长度。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、契约约束与正确调用方式
|
||||||
|
|
||||||
|
本次不改变任何请求约束,调用方式与改前完全一致。
|
||||||
|
|
||||||
|
| 场景 | 调用 |
|
||||||
|
|------|------|
|
||||||
|
| ✅ 查本人订单用车详情 | `GET /mp/order/2091418470443810817/vehicle` + 本人登录态 → 200 |
|
||||||
|
| ❌ 查他人订单 | 同上路径 + 他人登录态 → `581008`(既有行为,未改) |
|
||||||
|
| ❌ 订单不存在 | → `581007`(既有行为,未改) |
|
||||||
|
|
||||||
|
**读取 `vehicleCount` 的正确姿势**:把它当「这趟行程一共用了几辆车」。它**不是**用车天数,也不是「车辆数 × 天数」。若需要用车天数,当前接口不提供,请另提需求。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、数据库行为
|
||||||
|
|
||||||
|
无。本接口是只读链路,无事务、无锁、无写入。本次改动不涉及表结构、不涉及 Flyway。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、边界行为
|
||||||
|
|
||||||
|
- 未登录 → 401(网关拦截),不变
|
||||||
|
- 订单不存在 / 非本人订单 → `581007` / `581008`,不变
|
||||||
|
- 未配车 → `matched=false` 的 200 响应,`vehicleCount` 不下发,不变
|
||||||
|
- 行程中某天标记「无需用车」→ 该天不计入台数
|
||||||
|
- 整趟都没有实际车辆 → `vehicleCount=0`(不会折成 1)
|
||||||
|
- 上游派单包取不到 → 透传上游错误码,不变
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六.6、修改前后对比
|
||||||
|
|
||||||
|
### 字段级对比
|
||||||
|
|
||||||
|
| 字段 | 改前 | 改后 |
|
||||||
|
|------|------|------|
|
||||||
|
| `vehicleCount` | 派车明细行数(车·日数) | 按 `vehicleId` 去重的车辆台数 |
|
||||||
|
| 其余 10 个字段 | — | 逐字段不变(实测前后对照唯一差异就是 `vehicleCount`) |
|
||||||
|
|
||||||
|
### 行为级对比
|
||||||
|
|
||||||
|
| 订单 | 服务天数 | 实际车辆台数 | 明细行数 | 改前下发 | 改后下发 |
|
||||||
|
|------|----------|--------------|----------|----------|----------|
|
||||||
|
| `2091418470443810817` | 6 | 1 | 6 | 6 | **1** |
|
||||||
|
| `2089611106451398658` | 3 | 1 | 3 | 3 | **1** |
|
||||||
|
| `2087156782022393857` | 3 | 2 | 6 | 6 | **2** |
|
||||||
|
| `2087156855368187906` | 3(含 1 天不用车) | 2 | 3 | 3 | **2** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六.7、影响评估
|
||||||
|
|
||||||
|
- **是否破坏向后兼容**: 否。字段名、类型、字段个数均不变,仅值变小。
|
||||||
|
- **前端是否必须同步上线**: 否。前端把该值当「车辆数」展示(与字段声明一致)则无需任何改动,显示会自动变正确。
|
||||||
|
- **前端 workaround 清理点**: 若前端曾为绕开这个错误值做过除以天数之类的换算,可以撤掉。若有基于该值的派生计算(按数量估算车辆费用、用它反推行程天数),**需复核**——它此前拿到的是车·日数。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、不影响范围
|
||||||
|
|
||||||
|
- **仅影响**: 小程序「用车详情」弹窗的 `vehicleCount` 一个字段的值。
|
||||||
|
- **零影响**:
|
||||||
|
- **多车订单的展示形态未改** —— 车型/车牌/司机/座位数仍只显示第一辆,第二辆车与后续日期的司机在客人端仍然看不到(本单只订正计数,展示形态需前端配合改弹窗,另行立单)
|
||||||
|
- 同一弹窗的其余 10 个字段(实测前后逐字段一致)
|
||||||
|
- 领队详情 `GET /mp/order/:orderId/guide`
|
||||||
|
- 行前看板 `team.driver`(该字段恒 null,原型暂不展示)
|
||||||
|
- `hl-order-service-v3`:**零改动**
|
||||||
|
- 数据库:无表变更、无 Flyway、无存量迁移
|
||||||
|
- 错误码:不新增
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、测试环境已验证
|
||||||
|
|
||||||
|
构建身份(取证时 `deploy-status.sh`):`hl-mp-service` = `86967e224` / 分支 `dev-v3` / BEHIND `0/N` / STATE `ok`;`hl-order-service-v3` = `c4a1f1fb6` / BEHIND `2/N`(落后提交未触及该服务)。
|
||||||
|
|
||||||
|
真实网关(`api.test.1814.love:9443`)实测:
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /mp/order/2091418470443810817/vehicle 改前 → 200 vehicleCount=6 ✓
|
||||||
|
GET /mp/order/2091418470443810817/vehicle 改后 → 200 vehicleCount=1 ✓(库:6 行 / 1 台车 / 6 天)
|
||||||
|
GET /mp/order/2089611106451398658/vehicle 改前 → 200 vehicleCount=3 ✓
|
||||||
|
GET /mp/order/2089611106451398658/vehicle 改后 → 200 vehicleCount=1 ✓(库:3 行 / 1 台车 / 3 天)
|
||||||
|
GET /mp/order/2086637109266862081/vehicle 改前后 → 200 matched=false 逐字段一致 ✓(未配车路径零回归)
|
||||||
|
```
|
||||||
|
|
||||||
|
含「当日无需用车」日行的订单(另一条上游分支):
|
||||||
|
|
||||||
|
```
|
||||||
|
order 2087156782022393857 → vehicleCount=2 ✓(库:6 行 / 2 台车 / 3 天)
|
||||||
|
order 2087156855368187906 → vehicleCount=2 ✓(库:3 行 = 2 实车 + 1 天无需用车;null 行未计入)
|
||||||
|
```
|
||||||
|
|
||||||
|
单元测试:`hl-mp-service` 整模块 `Tests run: 1058, Failures: 0, Errors: 0, Skipped: 0`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、相关历史 PR
|
||||||
|
|
||||||
|
| PR | Issue | 说明 | 是否仍有效 |
|
||||||
|
|----|-------|------|------------|
|
||||||
|
| — | #7306 | B-7 规格 4 字段 v3 无源降级恒 null | ✅ 有效(本次未改) |
|
||||||
|
| — | #7067 | 派车明细行粒度改为「assignmentId + serviceDate」日行 | ✅ 有效(本缺陷的成因) |
|
||||||
|
| **本 PR #8172** | **#8143** | `vehicleCount` 订正为车辆台数 | ✅ 最新 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、相关文档
|
||||||
|
|
||||||
|
- 关联 Issue: [wx/HL#8143](https://git.1814.love:8443/wx/HL/issues/8143)
|
||||||
|
- 关联 PR: [wx/HL#8172](https://git.1814.love:8443/wx/HL/pulls/8172)
|
||||||
|
|
||||||
|
## 关联 / 联系人
|
||||||
|
|
||||||
|
### 链接
|
||||||
|
|
||||||
|
- **Issue**: [#8143](https://git.1814.love:8443/wx/HL/issues/8143)
|
||||||
|
- **PR**: [#8172](https://git.1814.love:8443/wx/HL/pulls/8172)
|
||||||
|
- **Merge commit**: [86967e224](https://git.1814.love:8443/wx/HL/commit/86967e224)
|
||||||
|
|
||||||
|
### 联系人
|
||||||
|
|
||||||
|
- **后端负责人**: @jw
|
||||||
|
- **前端消费方**: hl-mini(mmg)
|
||||||
在新工单中引用
屏蔽一个用户