From b1ae9cba79b9daaa961b4ed2db76d91917806ff0 Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Mon, 28 Sep 2026 14:06:45 +0800 Subject: [PATCH] =?UTF-8?q?docs(changelog):=20#8457=20=E8=BD=A6=E5=8A=A1?= =?UTF-8?q?=E9=A6=96=E9=A1=B5=E6=96=B0=E5=A2=9E=E3=80=8C=E5=BE=85=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4=E6=8E=A5=E9=80=81=E5=8F=98=E6=9B=B4=E3=80=8D=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=8D=A1=EF=BC=88=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GET /admin/profile/dashboard 车务角色 pendingStatusCards 由两项扩为三项, 第三项 transfer_change_pending 为全局计数、count 可为 null(未知)。 测试服 d10aada4d 网关实测 2→3→2,团期订单不计入。 Refs #8457 Co-Authored-By: Claude Opus 5.5 (1M context) --- ...µ新增待确认接送变更状态卡-修改接口-管理后台.md | 298 ++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 changelogs-v2/2026-09/28_8457_车务首页新增待确认接送变更状态卡-修改接口-管理后台.md diff --git a/changelogs-v2/2026-09/28_8457_车务首页新增待确认接送变更状态卡-修改接口-管理后台.md b/changelogs-v2/2026-09/28_8457_车务首页新增待确认接送变更状态卡-修改接口-管理后台.md new file mode 100644 index 00000000..bf6d0f32 --- /dev/null +++ b/changelogs-v2/2026-09/28_8457_车务首页新增待确认接送变更状态卡-修改接口-管理后台.md @@ -0,0 +1,298 @@ +--- +schema: "hl-changelog/v2" +ticket: "8457" +title: "车务首页新增待确认接送变更状态卡" +consumer: "admin" +author: "wx(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "" +updated_at: "2026-09-28" +base: "dev-v3" +--- + +# hl-user-service: 车务首页新增待确认接送变更状态卡 + +**服务**: hl-user-service(计数由 hl-fleet-service 汇总,第三张卡的数据来自 hl-order-service-v3) +**PR**: #8471(已合入 `dev-v3`,squash `d10aada4d`) +**Issue**: #8457 +**日期**: 2026-09-28 +**影响范围**: 管理后台首页 `GET /admin/profile/dashboard`,仅车务管理员角色(`VEHICLE_MANAGER`)的响应 + +--- + +## ⚠️ 关键变化 + +- 车务角色响应里的 `pendingStatusCards` 由**固定两项**变为**固定三项**,新增第三项 `status=transfer_change_pending`、`statusLabel=待确认接送变更`。前两项的 `status`、`statusLabel`、顺序不变。 +- `pendingStatusCards[].count` 可以是 `null`:**只有第三项可能为 null**,表示「取不到、未知」;`0` 表示「确实没有」。前端对 `null` 和缺字段都按未知处理,显示「—」,不要显示成 0。 +- 第三项是**全局计数**,不受首页「近 7 天」窗口限制。守恒关系随之收窄:`unassigned` + `holding` 两项之和 == `pendingArrangeVehicle` == `upcomingTrips.length`,**第三项不参与**。不要把三张卡相加当作总数。 + +--- + +## 一、背景 + +大交通变更后需要车务确认的接送变更(#8435 引入的确认流程)此前只能在车务看板上逐单看到,车务首页没有入口,车务不知道还有多少单没确认。本单在车务首页加第三张状态卡,显示全部待确认接送变更的订单数,点卡片跳车务看板处理。 + +--- + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 管理后台首页仪表盘 | GET | `/admin/profile/dashboard` | 修改 | 车务角色响应的 `pendingStatusCards` 由两项扩为三项,`count` 可为 null | + +--- + +## 三、接口详情 + +### 1. 管理后台首页仪表盘 `GET /admin/profile/dashboard` + +**VO**: `无 ReqVO(Query 参数 period)→ LogisticsDashboardVO` + +声明返回类型为 `Result`,按登录角色返回不同的实现;车务管理员角色返回 `LogisticsDashboardVO`,本单只改这一个实现。 + +#### 使用场景 + +车务管理员登录后台进入首页,展示待安排车辆总数、三张未完成状态卡与近 7 天用车列表。第三张卡「待确认接送变更」点击后跳车务看板处理。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| period | Query | String | 否 | 默认 `today`;取值 `today` / `week` / `month` | 其他角色仪表盘的时间范围。车务角色不使用该参数,传什么都返回同样的结果 | + +无请求体。 + +#### 出参字段表 + +以下为车务角色 `data` 的全部字段;`pendingArrangeVehicle`、`upcomingTrips` 本单未改。 + +| 字段 | 类型 | 说明 | +|------|------|------| +| pendingArrangeVehicle | Integer | 待安排车辆数:行程开始日在今天起 7 天内(含今天)、存在待派车或待确认执行派车的订单数,按订单去重。本单未改 | +| pendingStatusCards | Array<Object> | 未完成状态卡,固定三项,顺序固定为待派车、待确认、待确认接送变更 | +| pendingStatusCards[].status | String | 状态键:`unassigned` / `holding` / `transfer_change_pending` | +| pendingStatusCards[].statusLabel | String | 展示文案:`待派车` / `待确认` / `待确认接送变更` | +| pendingStatusCards[].count | Integer \| null | 订单级计数,每单只计一次。前两项恒为整数;第三项为 null 表示未知,0 表示确实没有 | +| upcomingTrips | Array<Object> | 即将出行/用车(近 7 天)。本单未改 | + +#### 请求示例 + +```http +GET /admin/profile/dashboard +Authorization: Bearer <车务管理员登录 JWT> +``` + +无请求体。 + +#### 响应示例 + +测试服车务测试账号实测原文(2026-09-28 12:51:10): + +```json +{ + "code": 200, + "message": "成功", + "data": { + "pendingArrangeVehicle": 0, + "pendingStatusCards": [ + {"status": "unassigned", "statusLabel": "待派车", "count": 0}, + {"status": "holding", "statusLabel": "待确认", "count": 0}, + {"status": "transfer_change_pending", "statusLabel": "待确认接送变更", "count": 2} + ], + "upcomingTrips": [] + }, + "traceId": null, + "success": true +} +``` + +第三项与前两项口径不同(见「业务边界」),两者数值互不相关,前两项为 0 时第三项可以非 0。 + +#### 空数据 / 降级响应 + +- 没有任何待确认接送变更:第三项 `count=0`。 +- 取不到第三项计数(订单服务不可达、超时或返回失败):第三项 `count=null`;前两项、`pendingArrangeVehicle`、`upcomingTrips` 照常返回。 +- 取不到整份车务汇总(车务服务不可达或返回失败):仍返回三项,`count` 依次为 `0`、`0`、`null`;`pendingArrangeVehicle=0`,`upcomingTrips=[]`。 +- 车务服务未返回状态卡(旧版本车务服务):前两项由 `upcomingTrips` 推算,第三项 `count=null`。 +- 以上降级都返回 `code=200`、`success=true`,不报错;判断未知只看第三项 `count` 是否为 null 或缺字段。降级场景只有单测覆盖,测试服未造。 + +#### 错误响应 + +鉴权失败由网关统一拦截,HTTP 状态恒为 200,看 body 的 `code`。下例为同一网关对 `/admin/` 路径缺 `Authorization` 头时的实测原文(取自另一个 `/admin/` 端点,网关对所有 `/admin/` 路径返回同一形态): + +```json +{ + "code": 401, + "message": "缺少有效的 Authorization 头", + "data": null, + "traceId": "c34c4a77f4c449dc", + "success": false +} +``` + +| 错误码 | 触发条件 | +|---|---| +| 401 | 网关拦截:缺 `Authorization` 头(「缺少有效的 Authorization 头」)、Token 无效(「Token 无效」)、Token 已过期或被撤销(「Token 已过期或被撤销」) | +| 403 | 网关拦截:小程序用户 Token 访问管理端接口(「无权访问管理端接口」) | +| 200208 | 用户服务未取到登录管理员身份(「未认证」) | + +非车务角色调用不会报错,而是返回该角色自己的仪表盘,见「业务边界」。 + +#### 业务边界 + +- 三项顺序固定为 `unassigned`、`holding`、`transfer_change_pending`;前端按 `status` 取卡即可。 +- 前两项与第三项口径不同:前两项只看行程开始日在今天起 7 天内(含今天)的订单;第三项是全局计数,没有日期条件,也不受 `period` 影响。 +- 第三项只计非团期订单:已归入团期的订单改大交通不计入(团期接送变更不走车务确认);已删除订单不计入。 +- 第三项按订单计:一个订单无论改过几次大交通,只计 1 次;车务在看板上确认该订单的接送变更后,它立即不再计入。 +- `count=null` 与 `count=0` 含义不同:null 是「取不到」,0 是「确实没有」。 +- 只有车务管理员角色(`VEHICLE_MANAGER`)的响应带 `pendingStatusCards`。超管、管理员、定制师、房务、财务、物料等角色调用同一接口返回各自的仪表盘,不含这组字段。 + +--- + +## 四、契约约束与正确调用方式 + +| 场景 | 第三项 `count` | 前端展示 | +|------|------|------| +| 有待确认接送变更 | 正整数 | 显示数字 | +| 没有待确认接送变更 | `0` | 显示 0 | +| 取不到计数 | `null` 或缺字段 | 显示「—」,不显示 0 | + +- 按 `status` 取卡并匹配样式;遇到不认识的 `status` 不要报错。 +- 首张统计「待安排车辆」用 `pendingArrangeVehicle`,不要用三张状态卡相加代替。 +- 点第三张卡跳车务看板 `/fleet/board` 时要清空出发日期范围。车务看板默认只列今年 1 月 1 日至今日出发的订单(按行程开始日过滤),而第三项是全局计数,不清空日期会看不到出发日在今天之后的待确认订单。不加状态筛选,也不加「只看待确认」。 +- 车务确认接送变更走 #8435 的 `POST /admin/fleet/board/orders/{orderId}/transfer-change/confirm`;确认成功后重新拉一次首页即可看到计数减少。 + +--- + +## 五、数据库行为 + +无表结构变更,不写库。三张卡都是只读计数。 + +--- + +## 六、边界行为 + +- 第三项与首页 7 天窗口无关:行程开始日在几个月以后的订单只要有待确认接送变更,也会计入第三项,但不会出现在前两项和 `upcomingTrips` 里。 +- 前两项之和恒等于 `pendingArrangeVehicle`,也等于 `upcomingTrips.length`;这一关系对第三项不成立。 +- 第三项取不到时不影响前两项和其他字段。 + +### 向后兼容 + +响应结构只在 `pendingStatusCards` 数组末尾追加一项,前两项的键、文案、顺序不变;`pendingArrangeVehicle`、`upcomingTrips` 不变。新增的是 `count` 可为 null 这一取值,前端对数字做运算或格式化前要先判空。 + +--- + +## 六.5、枚举 / 数据字典 + +`pendingStatusCards[].status`: + +| status | statusLabel | 含义 | count 口径 | +|------|------|------|------| +| unassigned | 待派车 | 用车需求已展开但还没排车/司机 | 行程开始日在今天起 7 天内的订单数,整数 | +| holding | 待确认 | 已锁定车/司机,待车务确认执行 | 行程开始日在今天起 7 天内的订单数,整数 | +| transfer_change_pending | 待确认接送变更 | 客人改了大交通后接送需求有变化,待车务在看板确认(#8435) | 全局订单数(非团期、未删除),整数或 null | + +--- + +## 六.6、修改前后对比 + +| 项 | 修前 | 修后 | +|------|------|------| +| `pendingStatusCards` 项数 | 固定 2 项 | 固定 3 项 | +| 第三项 | 无 | `transfer_change_pending` / `待确认接送变更` | +| `count` 取值 | 恒为整数 | 前两项恒为整数;第三项为整数或 null | +| 守恒关系 | 两项之和 == `pendingArrangeVehicle` == `upcomingTrips` 唯一订单数 | `unassigned` + `holding` 两项之和 == `pendingArrangeVehicle` == `upcomingTrips.length`;第三项不参与 | + +测试服实测第三项读数(车务测试账号): + +| 时刻 | 操作 | 第三项 `count` | +|------|------|------| +| 12:51:10 | 基线 | 2 | +| 13:05:24 | 核心订单车务已派车后,客人改到达航班时间 | 3 | +| 13:05:54 | 车务在看板确认该订单的接送变更 | 2 | +| 13:10:38 → 13:10:57 | 团期订单改大交通前后 | 2 → 2 | + +--- + +## 六.7、影响评估 + +- **是否破坏向后兼容**: 否。只在数组末尾追加一项,`count` 新增 null 取值。 +- **前端是否必须同步上线**: 否。车务首页状态卡按数组循环渲染,第三张卡会自动出现(未配样式的键显示为灰色);但现有取值对 `count` 做了 `?? 0` 兜底,第三项为 null 时会显示成 0,与「确实没有」混淆。 +- **前端需要改的点**(依据工单 #8457「文档与交接」节,对照 hl-ui `v2.1` `1c555f544` 核对): + 1. 第三张卡 `count` 为 null 或缺字段时显示「—」,不显示 0(`VehicleDashboard.vue` 里 `count` 的 `?? 0` 兜底要改)。 + 2. 为 `transfer_change_pending` 补卡片样式(`STATUS_CARD_PRESENTATION`)。 + 3. 统计区由 3 张变 4 张(首张 `pendingArrangeVehicle` 加三张状态卡),栅格列数与骨架屏数量跟着调。 + 4. 点第三张卡跳 `/fleet/board` 并清空出发日期范围,不加状态筛选,也不加「只看待确认」。 + 5. 车务看板页目前不读任何路由参数(`openFleetBoard` 传的 `orderId` / `orderNo` / `statuses` 没有消费方),要支持读跳转参数来清空日期;参数名由前端定。 +- **前端 workaround 清理点**: 无。 + +--- + +## 七、不影响范围 + +- 超管、管理员、定制师、房务、财务、物料等角色的首页仪表盘。 +- `period` 参数的取值与含义。 +- 车务角色的 `pendingArrangeVehicle`、`upcomingTrips` 口径,以及前两张状态卡的口径。 +- 车务看板列表与详情接口、接送变更确认接口(#8435)。 +- 网关路由与鉴权规则(本单未改网关)。 + +--- + +## 八、测试环境已验证 + +部署:测试服 `hl-fleet-service`、`hl-order-service-v3`、`hl-user-service` 于 2026-09-28 12:19:44 至 12:22:27 先后滚到 `dev-v3 d10aada4d`(即本单合并提交),deploy-status 显示三者落后 0;`hl-gateway` 为 2026-09-27 部署的 `71def6dc5`,本单未改网关。 + +### 测试服网关实测(`GET /admin/profile/dashboard`,测试专用账号与自造夹具) + +| 场景 | 检验点 | 结果 | +|------|--------|------| +| 车务账号请求首页 | 返回三项、顺序固定,第三项 `count=2`,前两项与 `upcomingTrips` 为空 | ✅ 原文见响应示例 | +| 核心订单车务已派车后,客人改到达航班时间(该单接送服务日为 12 月) | 第三项 `count` 由 2 变 3,前两项仍为 0 | ✅ | +| 车务在看板确认该订单接送变更(确认接口返回 `outcome=BASELINE_REFRESHED`) | 第三项 `count` 回到 2 | ✅ | +| 团期订单改大交通 | 第三项 `count` 前后都是 2;该团期订单在车务看板详情里 `transferChange=null` | ✅ | +| 超管、管理员、定制师调用同一接口 | 响应均不含 `pendingStatusCards`;超管与管理员顶层键为 `overview`、`publishedProducts`、`ranking`、`todos`、`totalAdmins`、`totalMiniAppUsers`、`totalProducts`、`trend`、`upcomingTrips`,定制师为 `calendarEvents`、`customerStats`、`funnel`、`overview`、`productStats`、`ranking`、`reviewStats`、`shortcuts`、`todos`、`trend`、`upcomingTrips` | ✅ | + +### 单测覆盖(测试服未造「服务不可达」场景) + +| 场景 | 用例 | +|------|------| +| 订单服务返回计数:第三项带出该值 | `FleetDashboardSummaryServiceTest.getSummary_transferChangeCountAvailable_thirdCardCarriesCount` | +| 订单服务取不到:第三项 null,前两项不受影响 | `FleetDashboardSummaryServiceTest.getSummary_transferChangeCountNull_thirdCardNullOthersUnaffected` | +| 无未完成订单:三项齐全 | `FleetDashboardSummaryServiceTest.getSummary_noIncompleteOrders_returnsThreeCardsAllZero` | +| 订单服务返回 0 时给 0 不给 null;抛异常、返回失败、data 为 null、负数时给 null | `OrderQueryFacadeTest.countTransferChangePendingOrNull_*`(7 个) | +| 订单服务调用失败走降级时不伪装成 0 | `TransferChangePendingCountFeignFallbackFactoryTest.create_transportFailure_returnsFailedResultNotZero` | +| 车务服务不可达:三项 0 / 0 / null | `LogisticsDashboardServiceTest.getDashboard_allServicesFail_returnsAllZeros`、`FleetDashboardStatusCardsTest.degradedCards_fleetUnreachable_firstTwoZeroThirdNull`、`FleetDashboardSummaryFeignFallbackFactoryTest.fallback_returnsStableZeroStatusCards` | +| 车务服务返回失败:三项、第三项 null | `LogisticsDashboardServiceTest.getDashboard_fleetReturnsNonSuccess_degradesToThreeCardsThirdNull` | +| 透传保真:车务服务给 null 时输出 null,给 0 时输出 0 | `LogisticsDashboardServiceTest.getDashboard_fleetThirdCardNull_passesThroughNullNotZero`、`LogisticsDashboardServiceTest.getDashboard_fleetThirdCardZero_passesThroughZeroNotNull` | +| 旧版本车务服务未返回状态卡:前两项推算、第三项 null | `LogisticsDashboardServiceTest.getDashboard_legacyFleetResponse_derivesCardsFromUpcomingTrips` | +| 订单服务内部计数接口返回计数 | `OrderInternalForFleetControllerTest.countTransferChangePending_success_returnsCountAsData` | + +--- + +## 十、相关文档 + +- 工单 #8457: https://git.1814.love/wx/HL/issues/8457 +- 同族工单 #8435(大交通改变时接送需求车务确认与看板标记):https://git.1814.love/wx/HL/issues/8435 +- 同族 changelog:`changelogs-v2/2026-09/28_8435_大交通改变时接送需求车务确认与看板标记-新增接口-管理后台.md` +- 契约文档:`docs/order-v3/api/API-SPEC-FLEET-V1.5.html` §13.10 车务工作台摘要(版本历史 v1.5.105) + +--- + +## 关联 / 联系人 + +### 链接 + +- **Issue**: [#8457](https://git.1814.love/wx/HL/issues/8457) +- **PR**: [#8471](https://git.1814.love/wx/HL/pulls/8471) +- **Merge commit**: [d10aada4d](https://git.1814.love/wx/HL/commit/d10aada4d) + +### 联系人 + +- **后端负责人**: @wx