hl-api-changelog/changelogs-v2/2026-07/78_车务派车看板与矩阵SSE实时刷新-前端待处理-管理后台.md
2026-07-21 18:22:27 +08:00

7.5 KiB

【前端待处理·管理后台】车务派车看板与矩阵 SSE 实时刷新

目标前端

问题与后端结论

2026-07-21 复现订单详情新增用车需求后,fleet-service 已生成未派车占位,但已打开的派车看板和矩阵派单不会实时刷新;多个车务管理员同时在线时,其他人的页面也无法感知变化。

根因是原管理后台 SSE 只接入消息、聊天、在线状态和房务抢单池信令,没有车务派单数据变更事件,也没有看板/矩阵的刷新订阅。

后端已补充以下链路:

  1. fleet-service 在用车需求展开事务真正提交后发布 REQUIREMENT_EXPANDED 事件,避免页面刷新早于未派占位落库。
  2. fleet-service 调 user-service 内部广播接口。
  3. user-service 经 Redis Pub/Sub 把信令分发到所有实例。
  4. 每个实例只向当前连接角色为 VEHICLE_MANAGER 的 SSE 连接发送 fleet-dispatch-changed
  5. 信令不绑定单个 adminId,因此多个车务管理员、多个浏览器标签和多个 user-service Pod 均可收到。

后端代码和定向测试已完成;测试环境是否已部署须以前后端发布记录为准。前端不得在后端未部署时把“收不到新事件”误判为页面监听实现失败。

SSE 契约

继续复用现有管理后台 SSE 连接,不新增浏览器请求接口:

GET /ws/admin-msg/stream?token=<accessToken>
Accept: text/event-stream

新增具名事件:

event: fleet-dispatch-changed
data: {"type":"FLEET_DISPATCH","targetRoleKey":"VEHICLE_MANAGER","fleetEvent":"REQUIREMENT_EXPANDED","orderId":"2079494135466643457","requirementId":"..."}

字段说明:

字段 类型 当前值/说明
type String 固定 FLEET_DISPATCH
targetRoleKey String 固定 VEHICLE_MANAGER
fleetEvent String 当前为 REQUIREMENT_EXPANDED
orderId String/Long 变更涉及的订单 ID;仅作定位提示,按字符串处理
requirementId String/Long 变更涉及的用车需求 ID;仅作定位提示,按字符串处理
  • 前端不得对雪花 ID 使用 Number();如需比较,统一 String(value) 后比较。
  • 本事件是“数据已变化”的轻量信令,不携带看板或矩阵业务正文。
  • 收到事件后必须重拉现有权威查询接口,不能根据信令自行拼装订单、派车组或矩阵占用条。
  • 后端只向当前角色为 VEHICLE_MANAGER 的连接投递。SUPER_ADMIN 只有切换并以车务管理员当前角色重新建立 SSE 后才会收到。

前端接入要求

1. 全局 SSE 接收

src/composables/useAdminMessageSSE.js 增加具名事件监听:

es.addEventListener('fleet-dispatch-changed', handleFleetDispatchSignal)

解析 JSON 后转入独立的车务派单信令总线。不要复用聊天信令或房务 lastGrabPoolSignal,避免模块语义互相污染。

建议在现有总线文件中新增:

export const lastFleetDispatchSignal = ref(null)

export function pushFleetDispatchSignal(signal) {
  if (!signal) return
  lastFleetDispatchSignal.value = { ...signal, _seq: Date.now() }
}

连续事件必须保证每次都能触发订阅;实现可沿用现有 _gseq 自增模式,不强制使用 Date.now()

2. 派车看板刷新

目标页面:src/views/fleet/board/index.vue

  • 订阅 lastFleetDispatchSignal
  • 页面处于挂载状态并收到 REQUIREMENT_EXPANDED 后调用现有 fetchBoard()
  • 保留当前筛选条件、分页/视图模式和搜索输入,不得重置用户工作区。
  • 多条短时间信令可做 100300ms 合并刷新,避免重复并发请求。
  • 沿用现有请求序号/取消机制,迟到响应不得覆盖较新的看板数据。

3. 矩阵派单刷新

目标页面:

  • src/views/fleet/matrix/index.vue
  • src/views/fleet/matrix/solo/index.vue(如独立挂载数据上下文)
  • src/views/fleet/matrix/composables/useFleetMatrixData.js

处理要求:

  • 收到信令后调用现有 fetchMatrix(requestFilters.value) 或等价的当前筛选刷新入口。
  • 同步刷新未派订单池、顶部统计和矩阵占用数据;不能只刷新车辆行而保留旧未派数量。
  • 保留当前年月、车队、车型和其他筛选条件。
  • 若派单弹窗正在提交,不得关闭弹窗或清空用户输入;提交结束后以最后一次权威查询结果收敛页面。
  • 矩阵分窗复用主页面数据组件时只订阅一次,避免同一事件发起重复请求。

4. 断线重连对账

Redis Pub/Sub 和 SSE 均不提供历史事件重放。断线期间可能漏过 fleet-dispatch-changed,因此:

  • SSE 重新收到 connected 后,若派车看板或矩阵当前已打开,应主动重拉一次当前页面数据。
  • 不要仅依赖实时事件维持页面正确性。
  • 仍按现有 SSE 生命周期要求保证全局只有一条连接,不得为看板和矩阵各自新建 EventSource

不影响范围

  • 不修改派车看板、矩阵派单现有查询接口及响应结构。
  • 不修改现有 messageunread-countim-chatim-chat-readpresencegrab-pool-changed 事件。
  • 不要求前端调用 /internal/sse/fleet-dispatch/broadcast;该路径仅供服务间 Feign 使用,管理后台不得直接访问。
  • 本次只覆盖用车需求展开后实时刷新。后续其他派单动作如扩展新的 fleetEvent,将另行补充契约。

验收清单

  • 以车务管理员 A 打开 /fleet/board,车务管理员 B 或定制师新增用车需求后,A 的看板无需手动刷新即可出现新未派订单。
  • 以车务管理员 A 打开 /fleet/matrix,新增用车需求后未派订单池、顶部统计和矩阵数据自动更新。
  • 两个不同车务管理员同时在线并分别打开看板/矩阵,两边均收到同一变更并刷新。
  • 同一车务管理员两个浏览器标签同时在线,两个标签均能刷新且互不关闭 SSE。
  • 当前角色为 SUPER_ADMIN 且未切换车务角色时不接收本事件。
  • SUPER_ADMIN 切换为 VEHICLE_MANAGER 并重建 SSE 后可以接收。
  • 收到信令时保留看板和矩阵当前筛选条件,不跳回默认月份或清空搜索项。
  • 短时间连续提交用车需求不会产生请求风暴或旧响应覆盖新数据。
  • SSE 断线期间新增需求,连接恢复并收到 connected 后页面主动对账并显示最新数据。
  • Network 中只存在一条 /ws/admin-msg/stream 长连接,没有为车务页面新增独立 SSE。

后端验证记录

  • fleet-serviceAssignmentServiceTest 239 项通过。
  • fleet-service车务派单 AFTER_COMMIT 通知测试 2 项通过。
  • user-serviceAdminSseServiceTest 37 项通过,覆盖两个车务同时接收、非车务角色隔离。
  • user-service车务广播与内部接口测试 3 项通过。
  • hl-fleet-servicehl-user-service 模块级 mvn -DskipTests package 均通过。

发布说明

  • 本文是前端接入与联调通知,不代表已修改或发布 mmg/hl-ui
  • 前端完成后应在 mmg/hl-ui 走自身 Issue、分支、PR、测试和发布流程。
  • 联调材料不得包含 access token、带 token 的完整 SSE URL、Cookie 或真实管理员身份信息。