---
schema: "hl-changelog/v2"
ticket: "5664"
title: "派单多司机时微信预览按司机分 tab（新增批量渲染端点）"
consumer: "admin"
author: "wx"
change_type: "新增接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "implemented"
frontend_owner: "mmg"
frontend_ref: "91530f73"
target_release: ""
verified_at: ""
status_note: "后端完成：PR #5668 合并 dev-v3（d4ebd435be62cbe377ba712e8f0aed2b41e75a56）并部署 TEST，网关验证双槽位分司机渲染+单项容错+单渲染回归全通过。待前端预览区接入 render-batch 按司机分 tab。"
updated_at: "2026-08-08"
base: "dev-v3"
generated: "2026-08-07T18:45:00+08:00"
---

# 派单多司机时微信预览按司机分 tab（#5664）

## 需求

派单选了多个司机（多槽位）时，微信消息预览按司机分 tab 切换——每个司机一个预览（车辆/行程/链接），分别查看+发送。实证：26-6318 派 2 司机（孙晓三、斯琴）预览只有 1 个。

## 根因

预览端点 `POST /admin/fleet/message-templates/{templateId}/render` 请求 VO 只接受**单个** driverId/vehicleId，多槽位只返回 1 个预览。

## 新增接口

### `POST /admin/fleet/message-templates/{templateId}/render-batch`

批量渲染同一模板，多槽位按司机返回预览列表。

**请求**：
```json
{
  "items": [
    {"orderId": 123, "vehicleId": 456, "driverId": 789, "assignmentGroupId": null,
     "serviceDates": null, "chargeableServiceDates": null, "vehicleFeeWaiverReason": null},
    {"orderId": 123, "vehicleId": 457, "driverId": 790}
  ]
}
```
- `items`：1~20 项，每项 = 单槽位预览入参（字段同单渲染 render 端点）。
- 1 项时等价单渲染（单司机场景不变，前端可继续用 render 或 render-batch 单项）。

**响应**：
```json
{
  "items": [
    {"index": 0, "driverId": 789, "vehicleId": 456, "assignmentGroupId": null,
     "success": true,
     "renderedBody": "师傅您好，HL20260807... 车辆 蒙A-G8888 别克GL8 ...",
     "variablesUsed": ["driver.name", "vehicle.plate", "..."],
     "errorCode": null, "errorMessage": null},
    {"index": 1, "driverId": 790, "vehicleId": 457, "success": true, "renderedBody": "...车辆 蒙A-H7777 丰田汉兰达..."}
  ]
}
```
- `items` 与请求同序；每项独立 `success`。
- 单项渲染抛业务异常 → 该项 `success=false` + `errorCode`/`errorMessage`，**不阻断其他槽位**；单项司机/车辆取数异常沿用单渲染容错兜空口径（字段空串、仍 success=true）。
- 模板不存在 → 整批 **600801**（与单渲染一致）；白名单外占位符 **600800**。

## 前端交接

1. **多槽位/多司机预览**：预览区对每槽位构造一个 item（该槽位 driverId/vehicleId/assignmentGroupId/serviceDates 等），调 `render-batch` 一次取回全部预览，按司机/槽位分 **tab** 展示各项 `renderedBody`。
2. **发送**：按选中 tab（司机）取对应 `renderedBody` 发送；单项 `success=false` 的 tab 展示 `errorMessage` 并禁用发送。
3. **单司机**：1 项即可（无 tab 或单 tab），行为与现状不变；现有 `render` 端点保留兼容（本单未改）。
4. tab 标签建议用司机姓名/车牌（renderedBody 内含，或前端用槽位上下文）。

## 验证

- MessageTemplateRenderServiceTest **20/20**（新增 4：多司机各自渲染/模板不存在 600801/单项取数异常兜空不阻断/单项业务异常 success=false 不阻断）；dev-v3 全量 verify 3265/0F/0E。
- 网关实证（TEST，change_notify 模板）：双槽位 render-batch → 2 预览各自车辆正确渲染（蒙A-G8888 别克GL8 / 蒙A-H7777 丰田汉兰达）；单项不存在车辆槽位兜空不阻断；单渲染 render 回归正常。
