From a9fafb8a146969765f36a25691ea2bfbc7f572de Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Sat, 18 Jul 2026 11:43:16 +0800 Subject: [PATCH] =?UTF-8?q?docs(fleet):=20=E5=8F=91=E5=B8=83=E8=BD=A6?= =?UTF-8?q?=E5=8A=A1=E8=AF=BB=E6=A8=A1=E5=9E=8B=E5=89=8D=E7=AB=AF=E5=A5=91?= =?UTF-8?q?=E7=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...¦åŠ¡çœ‹æ¿è¯¦æƒ…候选与矩阵读模型统一-管ç†åŽå°.md | 775 ++++++++++++++++++ 1 file changed, 775 insertions(+) create mode 100644 changelogs-v2/2026-07/60_4936_车务看æ¿è¯¦æƒ…候选与矩阵读模型统一-管ç†åŽå°.md diff --git a/changelogs-v2/2026-07/60_4936_车务看æ¿è¯¦æƒ…候选与矩阵读模型统一-管ç†åŽå°.md b/changelogs-v2/2026-07/60_4936_车务看æ¿è¯¦æƒ…候选与矩阵读模型统一-管ç†åŽå°.md new file mode 100644 index 0000000..73a4598 --- /dev/null +++ b/changelogs-v2/2026-07/60_4936_车务看æ¿è¯¦æƒ…候选与矩阵读模型统一-管ç†åŽå°.md @@ -0,0 +1,775 @@ +# ã€å‰ç«¯å¯¹æŽ¥Â·ç®¡ç†åŽå°ã€‘车务看æ¿ã€è¯¦æƒ…ã€å€™é€‰ä¸ŽçŸ©é˜µè¯»æ¨¡åž‹ç»Ÿä¸€ + +> Issue: [wx/HL#4936](https://git.1814.love:8443/wx/HL/issues/4936) +> +> PR: [wx/HL#5031](https://git.1814.love:8443/wx/HL/pulls/5031)ã€[wx/HL#5032](https://git.1814.love:8443/wx/HL/pulls/5032)ã€[wx/HL#5034](https://git.1814.love:8443/wx/HL/pulls/5034) +> +> æœåŠ¡: `hl-fleet-service` / `hl-order-service-v3` +> +> 日期: 2026-07-18 +> +> å½±å“范围: 车务派å•çœ‹æ¿æ±‡æ€»ä¸Žåˆ—è¡¨ã€æ´¾å•详情ã€è½¦è¾†/叿œºå€™é€‰ã€çŸ©é˜µæœˆè§†å›¾ã€ç›¸é‚»è®¢å•衔接风险 + +## 一ã€å¯¹æŽ¥ç»“论 + +1. æ´¾å•看æ¿ç»§ç»­ä½¿ç”¨åˆ†é¡µæŽ¥å£ï¼Œ`pageSize` 最大 100;没有新增“ä¸åˆ†é¡µå…¨é‡æŽ¥å£â€ã€‚ +2. `/summary` 与 `/orders` 共用日期ã€è½¦åž‹ã€å¸æœºã€è”系人ã€å›¢å·ã€å®šåˆ¶å¸ˆå’Œ `keyword` 筛选;汇总忽略 `status/statuses/page/pageSize`,返回åŒä¸€ç­›é€‰èŒƒå›´å†…的全部状æ€åˆ†é¢ã€‚`pendingCount/pendingUrgentCount/todayDepartCount/holdingTimeoutCount` åŒæ ·éšè¿™äº›è®¢å•筛选å˜åŒ–ï¼›`idleVehicleCount/idleDriverCount` 是ä¸éšè®¢å•筛选å˜åŒ–çš„å…¨å±€èµ„æºæŒ‡æ ‡ã€‚ +3. æ´¾å•列表ã€è¯¦æƒ…和矩阵å‡ä»¥**当å‰è®¢å• + 当剿œ‰æ•ˆç”¨è½¦éœ€æ±‚ + 当剿œ‰æ•ˆæ´¾è½¦ç»„**为准,历å²éœ€æ±‚å’ŒåŽ†å²æ´¾å•ä¸èƒ½è¦†ç›–当剿•°æ®ã€‚ +4. è¯¦æƒ…ä¸€æ¬¡è¿”å›žé€æ—¥è¡Œç¨‹ã€å¤§äº¤é€šã€å½“å‰éœ€æ±‚ã€å…¨éƒ¨æœ‰æ•ˆæ´¾è½¦ç»„ã€ç”Ÿå‘½å‘¨æœŸã€å‡­è¯å’Œæ“作记录。 +5. å€™é€‰è½¦è¾†å’Œå¸æœºåˆ†åˆ«åˆ†é¡µï¼Œå…è®¸å…ˆé€‰è½¦æˆ–å…ˆé€‰å¸æœºï¼›è¿”回完整闭区间å¯ç”¨æ—¶é—´çª—ã€ç»“构化å¯ç”¨æ€§åŽŸå› ã€å†²çªå’Œå¸¸é©»å…³ç³»ã€‚ +6. 矩阵按整月查询,但åŒä¸€è·¨æœˆæ´¾è½¦ç»„先补é½å®Œæ•´ç»„å†è£å‰ªæ˜¾ç¤ºï¼›ä¸ä¼šå› åªæŸ¥åˆ°æœˆå†…一天而丢失真实起止日期。 +7. 矩阵相邻订å•衔接风险由åŽç«¯è¿”回 `status/statusLabel/style/reasonCode/reasonMessage`,å‰ç«¯ä¸å¾—自行根æ®é¢œè‰²æˆ–æ—¶é—´é‡æ–°æŽ¨å¯¼ã€‚ +8. **大交通å…许ä¸å¡«å†™ã€‚** 无大交通时ä»å¯æäº¤ç”¨è½¦éœ€æ±‚ã€æŸ¥è¯¢å€™é€‰ã€é¢„检和派车;å‰ç«¯åªèƒ½æ˜¾ç¤ºæç¤ºï¼Œä¸å¾—ç¦ç”¨æ´¾è½¦æŒ‰é’®ã€‚ +9. 所有雪花 ID 凿Œ‰å­—符串处ç†ï¼Œç¦æ­¢è½¬ä¸º JavaScript `Number`。 +10. 本次未修改 `hl-ui`,å‰ç«¯åªæŒ‰æœ¬æ–‡å®ŒæˆæŽ¥å£å¯¹æŽ¥ã€‚ + +## äºŒã€æŽ¥å£æ¸…å• + +| # | æŽ¥å£ | 方法 | 路径 | 用途 | +|---|---|---|---|---| +| 1 | çœ‹æ¿æ±‡æ€» | GET | `/admin/fleet/board/summary` | åŒç­›é€‰çжæ€è®¡æ•°ã€æ€¥å•æ•°ã€èµ„æºæ•°ã€å®šåˆ¶å¸ˆé€‰é¡¹ | +| 2 | 看æ¿åˆ—表 | GET | `/admin/fleet/board/orders` | 分页å¡ç‰‡ã€ç»Ÿä¸€ç­›é€‰ã€å½“å‰çжæ€å’Œæ“作能力 | +| 3 | 看æ¿è¯¦æƒ… | GET | `/admin/fleet/board/orders/{orderId}` | 当å‰è®¢å•ã€å½“å‰éœ€æ±‚ã€è¡Œç¨‹ã€å¤§äº¤é€šã€æ´¾è½¦ç»„和日志 | +| 4 | 出行人脱æ•列表 | GET | `/admin/fleet/board/orders/{orderId}/travelers` | é»˜è®¤è„±æ•æŸ¥çœ‹å‡ºè¡Œäºº | +| 5 | 出行人明文查询 | POST | `/admin/fleet/board/orders/{orderId}/travelers/plain` | 有æƒé™ä¸”有审计ç†ç”±æ—¶æŸ¥çœ‹æ˜Žæ–‡ | +| 6 | æ´¾å•候选 | POST | `/admin/fleet/assignments/candidates` | è½¦è¾†å’Œå¸æœºç‹¬ç«‹åˆ†é¡µã€å†²çªã€å¯ç”¨æ—¶é—´çª—ã€å¸¸é©»å…³ç³» | +| 7 | 矩阵月视图 | GET | `/admin/fleet/matrix/grid` | è½¦è¾†æœˆåŽ†ã€æ´¾è½¦æ®µã€å¹¶è¡Œè½¦è¾†ã€å¤§äº¤é€šå’Œè¡”接风险 | + +## 三ã€çœ‹æ¿æ±‡æ€»ä¸Žåˆ—表公共筛选 + +### 3.1 æŸ¥è¯¢å‚æ•° + +| 傿•° | 类型 | å¿…å¡« | 说明 | +|---|---|---|---| +| `statuses` | `string[]` | å¦ | 多状æ€ä»»ä¸€å‘½ä¸­ï¼›æ”¯æŒé‡å¤ query 傿•°æˆ–逗å·åˆ†éš”。 | +| `status` | `string` | å¦ | å•状æ€/逗å·åˆ†éš”别å,与 `statuses` åˆå¹¶ã€‚ | +| `startDayFrom` | `date` | å¦ | 日期区间起,与当å‰è¡Œç¨‹é—­åŒºé—´åšé‡å åŒ¹é…。 | +| `startDate` | `date` | å¦ | `startDayFrom` 别åï¼›å‰è€…未传时生效。 | +| `startDayTo` | `date` | å¦ | 日期区间止,与当å‰è¡Œç¨‹é—­åŒºé—´åšé‡å åŒ¹é…。 | +| `endDate` | `date` | å¦ | `startDayTo` 别åï¼›å‰è€…未传时生效。 | +| `vehicleTypeKeys` | `string[]` | å¦ | 车型大类:`suv/mpv/bus/sedan`,任一命中。 | +| `typeKeys` | `string[]` | å¦ | `vehicleTypeKeys` 别å。 | +| `driverName` | `string` | å¦ | 当å‰å¸æœºå§“忍¡ç³ŠåŒ¹é…。 | +| `keyword` | `string` | å¦ | 叿œºã€è”系人/客户ã€å›¢å·ã€è®¢å•å·ã€å½“å‰è´Ÿè´£å®šåˆ¶å¸ˆå±•示å任一包å«å³å‘½ä¸­ã€‚定制师展示å为ä¼ä¸šå¾®ä¿¡æ˜µç§°ä¼˜å…ˆã€ç”¨æˆ·å兜底;order-v3 é™çº§æ—¶å›žé€€æ´¾å•快照,åªåŒ¹é…åŽç«¯æœ€ç»ˆè§£æžå‡ºçš„一个展示å。 | +| `contactName` | `string` | å¦ | è”系人/å®¢æˆ·åæ¨¡ç³ŠåŒ¹é…。 | +| `contactKeyword` | `string` | å¦ | `contactName` 别å。 | +| `teamNo` | `string` | å¦ | 团å·åŒ…å«åŒ¹é…,例如 `7218` å¯å‘½ä¸­ `26-7218`。 | +| `consultantId` | `string` | å¦ | 当å‰è´Ÿè´£å®šåˆ¶å¸ˆç®¡ç†å‘˜ ID 精确匹é…。 | +| `plannerName` | `string` | å¦ | å®šåˆ¶å¸ˆæ˜¾ç¤ºåæ¨¡ç³ŠåŒ¹é…兼容傿•°ã€‚ | +| `consultantName` | `string` | å¦ | `plannerName` 别å。 | +| `variant` | `string` | å¦ | `list` 默认;`grid` ä¸ºå…¼å®¹å€¼ï¼Œå…¶ä»–å€¼è¿”å›žå‚æ•°é”™è¯¯ã€‚ | +| `page` | `int` | åˆ—è¡¨å¦ | 默认 1;汇总忽略。 | +| `pageSize` | `int` | åˆ—è¡¨å¦ | 默认 20ã€æœ€å¤§ 100;汇总忽略。 | + +状æ€å€¼ï¼š + +```text +unassigned / unassigned_urgent / holding / holding_urgent / +assigned / change_requested / completed / canceled +``` + +状æ€å«ä¹‰ç”±åŽç«¯ `statusOptions` 返回。`holding` 是“车务已排车ã€å¸æœºå°šæœªå®Œæˆç¡®è®¤é“¾è·¯â€ï¼Œä¸æ˜¯â€œè½¦åŠ¡æ­£åœ¨æµè§ˆè¯¦æƒ…â€ã€‚ + +### 3.2 汇总请求示例 + +```http +GET /admin/fleet/board/summary?startDate=2026-07-01&endDate=2026-07-31&typeKeys=suv&keyword=王 +Authorization: Bearer +``` + +### 3.3 汇总å“应示例 + +```json +{ + "code": 200, + "message": "æˆåŠŸ", + "success": true, + "data": { + "pendingCount": 3, + "pendingUrgentCount": 1, + "todayDepartCount": 1, + "idleVehicleCount": 9, + "idleDriverCount": 5, + "holdingTimeoutCount": 1, + "statusCounts": { + "unassigned": 3, + "holding": 1, + "assigned": 2, + "changeRequested": 0, + "completed": 4, + "canceled": 1, + "unassignedUrgent": 1, + "holdingUrgent": 1 + }, + "statusOptions": [ + { + "value": "unassigned", + "label": "待派车", + "count": 3, + "urgentCount": 1 + }, + { + "value": "holding", + "label": "排车中", + "count": 1, + "urgentCount": 1 + }, + { + "value": "assigned", + "label": "已派车", + "count": 2, + "urgentCount": 0 + } + ], + "consultantOptions": [ + { + "value": "2000000000000000001", + "label": "ä¼ä¸šå¾®ä¿¡æ˜µç§°" + } + ] + } +} +``` + +一致性规则: + +```text +åŒä¸€ç»„éžçжæ€ç­›é€‰æ¡ä»¶ä¸‹ï¼š +summary.statusOptions[value=X].count + == orders?statuses=X 返回的 data.total +``` + +`idleVehicleCount/idleDriverCount` 是当å‰ç‰©ç†èµ„æºæŒ‡æ ‡ï¼Œä¸å—è®¢å•æ–‡å­—筛选影å“;其他订å•状æ€è®¡æ•°ä½¿ç”¨åŒä¸€ç­›é€‰åŽçš„记录集。 + +### 3.4 列表请求示例 + +```http +GET /admin/fleet/board/orders?page=1&pageSize=20&statuses=unassigned,holding&keyword=7218&consultantId=2000000000000000001 +Authorization: Bearer +``` + +### 3.5 列表å“应示例 + +```json +{ + "code": 200, + "message": "æˆåŠŸ", + "success": true, + "data": { + "page": 1, + "pageSize": 20, + "total": 1, + "records": [ + { + "id": "HL202607180001", + "orderNo": "HL202607180001", + "orderId": "2000000000000000101", + "teamNo": "26-7218", + "assignmentId": "2000000000000000201", + "assignmentGroupId": "2000000000000000201", + "fleetItemIndex": 0, + "customerName": "测试è”系人", + "contactName": "测试è”系人", + "productName": "测试产å“", + "headcount": 4, + "adultCount": 3, + "childCount": 1, + "youngChildCount": 0, + "babyCount": 0, + "startDate": "2026-07-20", + "endDate": "2026-07-22", + "days": 3, + "pickupAt": null, + "dropoffAt": null, + "isHailarPickup": false, + "isHailarDropoff": false, + "consultantId": "2000000000000000001", + "plannerName": "ä¼ä¸šå¾®ä¿¡æ˜µç§°", + "consultantName": "ä¼ä¸šå¾®ä¿¡æ˜µç§°", + "consultantDisplayName": "ä¼ä¸šå¾®ä¿¡æ˜µç§°", + "specialTags": ["ä¸­æ–‡å¸æœº", "大行æŽç©ºé—´"], + "requirementRemark": "无大交通,按行程安排车辆", + "requiredVehicles": [ + { + "vehicleType": "suv", + "categoryLabel": "SUV系列", + "seats": 7, + "count": 1 + } + ], + "assignmentStatus": "unassigned", + "assignmentStatusLabel": "待派车", + "lifecycleStageCode": "requirement_pending", + "lifecycleStageLabel": "待车务派车", + "currentStep": 1, + "availableActionCodes": ["ASSIGN", "REJECT_REQUIREMENT"], + "urgentBadge": null, + "canAssign": true, + "canRejectRequirement": true + } + ] + } +} +``` + +### 3.6 列表字段绑定规则 + +| 字段 | å‰ç«¯è§„则 | +|---|---| +| `teamNo` | 展示当å‰å›¢å·ï¼›ç©ºå€¼ä¸å›žé€€æ‹¼é€ ã€‚ | +| `contactName` | å¡ç‰‡è”系人。 | +| `consultantDisplayName` | 定制师展示å,ä¼ä¸šå¾®ä¿¡æ˜µç§°ä¼˜å…ˆã€ç”¨æˆ·å兜底。 | +| `startDate/endDate/days` | 当å‰è®¢å•档期,闭区间å«é¦–尾。 | +| `specialTags/requirementRemark` | 当剿œ‰æ•ˆç”¨è½¦éœ€æ±‚,ä¸å¾—混入历å²éœ€æ±‚。 | +| `assignmentStatusLabel/lifecycleStageLabel` | 直接展示,å‰ç«¯ä¸ç»´æŠ¤ç‹¬ç«‹ä¸­æ–‡æ˜ å°„。 | +| `availableActionCodes/canAssign/canRejectRequirement` | 决定æ“作入å£ï¼›æ€¥å•æ ·å¼ä¸å¾—éšè—按钮。 | + +列表按派车组èšåˆï¼›åº•å±‚ä¸€å¤©ä¸€æ¡æ´¾è½¦åˆ‡ç‰‡ä¸ä¼šæŠŠåŒä¸€æ´¾è½¦ç»„é‡å¤æˆå¤šå¼ å¡ç‰‡ã€‚紧急待处ç†åœ¨å‰ã€æ™®é€šè¿›è¡Œä¸­æ¬¡ä¹‹ã€ç»ˆæ€æ²‰åº•,åŒä¼˜å…ˆçº§ä»¥ç¨³å®š ID 兜底;å‰ç«¯ä¸å¾—二次排åºã€‚ + +## å››ã€æ´¾å•详情 + +### 4.1 请求 + +```http +GET /admin/fleet/board/orders/2000000000000000101 +Authorization: Bearer +``` + +è·¯å¾„å‚æ•°æ˜¯æ•°å­—è®¢å• IDï¼ŒæŒ‰å­—ç¬¦ä¸²ä¼ é€’ï¼Œä¸æ˜¯è®¢å•å·ã€‚ + +### 4.2 å“应示例 + +```json +{ + "code": 200, + "message": "æˆåŠŸ", + "success": true, + "data": { + "id": "HL202607180001", + "orderNo": "HL202607180001", + "teamNo": "26-7218", + "customerName": "测试è”系人", + "headcount": 4, + "adultCount": 3, + "childCount": 1, + "youngChildCount": 0, + "babyCount": 0, + "startDate": "2026-07-20", + "endDate": "2026-07-22", + "pickupAt": null, + "dropoffAt": null, + "productName": "测试产å“", + "consultantId": "2000000000000000001", + "plannerName": "ä¼ä¸šå¾®ä¿¡æ˜µç§°", + "consultantName": "ä¼ä¸šå¾®ä¿¡æ˜µç§°", + "consultantDisplayName": "ä¼ä¸šå¾®ä¿¡æ˜µç§°", + "specialTags": ["ä¸­æ–‡å¸æœº", "大行æŽç©ºé—´"], + "requirementRemark": "无大交通,按行程安排车辆", + "itinerary": { + "theme": "è‰åŽŸä¸‰æ—¥", + "route": "海拉尔 → é¢å°”å¤çº³ → 满洲里", + "days": [ + { + "dayNumber": 1, + "date": "2026-07-20", + "title": "抵达海拉尔", + "detail": "市区行程" + }, + { + "dayNumber": 2, + "date": "2026-07-21", + "title": "é¢å°”å¤çº³", + "detail": "è‰åŽŸè¡Œç¨‹" + }, + { + "dayNumber": 3, + "date": "2026-07-22", + "title": "满洲里", + "detail": "返程" + } + ] + }, + "transport": { + "transferTimeHint": "æš‚æ— æŽ¥é€æœºæ—¶é—´", + "arrive": null, + "depart": null, + "batches": [], + "pickupRequired": null + }, + "currentAssignment": { + "id": "2000000000000000201", + "assignmentGroupId": "2000000000000000201", + "fleetItemIndex": 0, + "requiredVehicleType": "suv", + "requiredSeats": 7, + "startDate": "2026-07-20", + "endDate": "2026-07-22", + "vehicleId": "2000000000000000301", + "vehiclePlate": "è’™A·TEST1", + "driverId": "2000000000000000401", + "driverName": "æµ‹è¯•å¸æœº", + "baseAssignmentStatus": "assigned", + "assignmentStatus": "assigned", + "lifecycleStageCode": "confirmed", + "lifecycleStageLabel": "已确认执行", + "currentStep": 4, + "availableActionCodes": ["CANCEL", "CHANGE_DRIVER", "COMPLETE_EARLY"], + "protocolPrice": "1300.00", + "driverConfirmationEvidenceFileIds": [] + }, + "activeAssignments": [ + { + "assignmentGroupId": "2000000000000000201", + "fleetItemIndex": 0, + "startDate": "2026-07-20", + "endDate": "2026-07-22", + "vehiclePlate": "è’™A·TEST1", + "driverName": "æµ‹è¯•å¸æœº", + "assignmentStatus": "assigned" + } + ], + "operationLog": { + "records": [], + "total": 0, + "summary": {"totalCount": 0} + }, + "relatedDetailReady": true + } +} +``` + +### 4.3 当å‰éœ€æ±‚和派车组隔离 + +- `currentAssignment` 是最新一个有效派车组的兼容字段。 +- `activeAssignments` æ‰æ˜¯å½“å‰éœ€æ±‚下全部有效派车组;一å•多车时必须渲染完整数组。 +- 历å²éœ€æ±‚ã€å·²å–消组和旧订å•å¿«ç…§ä¸èƒ½è¿›å…¥å½“å‰éœ€æ±‚详情。 +- `baseAssignmentStatus` 是è½åº“基础æ€ï¼›`assignmentStatus` æ˜¯å½“å‰æœ‰æ•ˆçжæ€ï¼Œå‰ç«¯å±•示åŽè€…。 + +### 4.4 逿—¥è¡Œç¨‹è§„则 + +- `itinerary.days` æ¥è‡ª `order_itinerary_day`,一天一æ¡äº‹å®žæ•°æ®ã€‚ +- 返回日期必须ä½äºŽå½“å‰ `[startDate,endDate]`,按 `dayNumber` 稳定排åºã€‚ +- æ”¹æœŸåŽæŒ‰å½“å‰è®¢å•档期对é½ï¼›è¶Šç•Œã€æ—§ç‰ˆæœ¬å’Œéžæ³•æ—¥åºæ•°æ®ä¸è¿”回。 +- 无有效行程时返回 `days=[]`,å‰ç«¯æ˜¾ç¤ºç©ºæ€ï¼Œä¸å¾—生æˆå‡è¡Œç¨‹ã€‚ + +### 4.5 大交通规则 + +æœ‰æ•°æ®æ—¶ï¼š + +- 到达接客使用大交通 `arriveTime`。 +- 返程é€å®¢ä½¿ç”¨å¤§äº¤é€š `departTime`。 +- 分批接é€å®Œæ•´è¿”回 `batches`。 + +æ— æ•°æ®æ—¶å›ºå®šè¿”回: + +```json +{ + "transport": { + "transferTimeHint": "æš‚æ— æŽ¥é€æœºæ—¶é—´", + "arrive": null, + "depart": null, + "batches": [], + "pickupRequired": null + } +} +``` + +**空大交通是正常业务状æ€ï¼Œä¸æ˜¯å‚æ•°é”™è¯¯ï¼Œä¹Ÿä¸æ˜¯æ´¾è½¦é˜»æ–­æ¡ä»¶ã€‚** `pickupAt/dropoffAt` åŒæ ·å…许为 `null`。 + +## 五ã€è½¦è¾†ä¸Žå¸æœºå€™é€‰ + +### 5.1 请求 + +```http +POST /admin/fleet/assignments/candidates +Authorization: Bearer +Content-Type: application/json +``` + +```json +{ + "orderId": "2000000000000000101", + "requirementId": "2000000000000000501", + "fleetItemIndex": 0, + "startDate": "2026-07-20", + "endDate": "2026-07-22", + "headcount": 4, + "selectedVehicleId": null, + "selectedDriverId": null, + "excludeAssignmentId": null, + "vehicleKeyword": "GL8", + "driverKeyword": "å¼ ", + "vehiclePage": 1, + "vehiclePageSize": 20, + "driverPage": 1, + "driverPageSize": 20 +} +``` + +`pickupAt/dropoffAt` æœªå‡ºçŽ°æ˜¯åˆæ³•è¯·æ±‚ï¼›æœ‰åŸŽå¸‚ä¿¡æ¯æ—¶å¯é¢å¤–传入,供城市衔接判断使用。 + +### 5.2 è¯·æ±‚å‚æ•° + +| 傿•° | 类型 | å¿…å¡« | 说明 | +|---|---|---|---| +| `orderId` | `string` | 改派时是 | 当å‰è®¢å• ID。 | +| `requirementId` | `string` | 改派时是 | 当剿œ‰æ•ˆç”¨è½¦éœ€æ±‚ ID。 | +| `fleetItemIndex` | `int` | å¦ | 当å‰è½¦åž‹é¡¹åºå·ï¼Œä»Ž 0 开始。 | +| `startDate/endDate` | `date` | 是 | 请求用车闭区间。 | +| `pickupAt/dropoffAt` | `string` | å¦ | 城市衔接辅助信æ¯ï¼›ç©ºå€¼ä¸é˜»æ–­å€™é€‰å’Œæ´¾è½¦ã€‚ | +| `headcount` | `int` | å¦ | 乘客人数,ä¸å«å¸æœºã€‚车辆乘客容é‡=`seats-1`。 | +| `selectedVehicleId` | `string` | å¦ | 已选车辆,支æŒå…ˆé€‰è½¦ã€‚ | +| `selectedDriverId` | `string` | å¦ | 已选叿œºï¼Œæ”¯æŒå…ˆé€‰å¸æœºã€‚ | +| `excludeAssignmentId` | `string` | å¦ | æ”¹æ´¾æ—¶æŽ’é™¤å½“å‰æ´¾å•,且必须属于当å‰è®¢å•和需求。 | +| `vehicleKeyword` | `string` | å¦ | 车牌或车型。 | +| `driverKeyword` | `string` | å¦ | 叿œºå§“åæˆ–完整手机å·ã€‚ | +| `vehiclePage/driverPage` | `int` | 是 | å„自分页页ç ï¼Œé»˜è®¤ 1。 | +| `vehiclePageSize/driverPageSize` | `int` | 是 | å„自æ¯é¡µæ¡æ•°ï¼Œæœ€å¤§ 100。 | + +### 5.3 å“应示例 + +```json +{ + "code": 200, + "message": "æˆåŠŸ", + "success": true, + "data": { + "vehicles": { + "records": [ + { + "vehicleId": "2000000000000000301", + "plate": "è’™A·TEST1", + "modelName": "测试车型", + "seats": 7, + "passengerCapacity": 6, + "seatsEnough": true, + "fleet": "own", + "selected": false, + "available": true, + "availabilityReasonCode": "AVAILABLE", + "availabilityReasonMessage": "所选æœåŠ¡æ—¥æœŸå†…å¯ç”¨", + "availabilityWindows": [ + {"startDate": "2026-07-20", "endDate": "2026-07-22"} + ], + "residentMatch": false, + "crossResident": false, + "requiresCrossResidentConfirmation": false, + "relationMessage": null, + "conflicts": [] + } + ], + "total": 1, + "page": 1, + "pageSize": 20 + }, + "drivers": { + "records": [ + { + "driverId": "2000000000000000401", + "name": "æµ‹è¯•å¸æœº", + "maskedPhone": "138****0000", + "years": 8, + "season": "active", + "completedOrderCount": 12, + "rating": 5.0, + "ratingDefaulted": true, + "selected": false, + "available": true, + "availabilityReasonCode": "CITY_JUNCTION_SHAREABLE", + "availabilityReasonMessage": "仅存在å¯è¡”接的åŒåŸŽè¾¹ç•Œå ç”¨", + "availabilityWindows": [ + {"startDate": "2026-07-20", "endDate": "2026-07-22"} + ], + "residentMatch": false, + "crossResident": false, + "requiresCrossResidentConfirmation": false, + "conflicts": [] + } + ], + "total": 1, + "page": 1, + "pageSize": 20 + }, + "selectedRelation": null + } +} +``` + +### 5.4 候选判定规则 + +| `availabilityReasonCode` | å«ä¹‰ | `available` | +|---|---|---| +| `AVAILABLE` | 整个请求闭区间无阻塞å ç”¨ | `true` | +| `CITY_JUNCTION_SHAREABLE` | åªæœ‰æ»¡è¶³è§„则的城市边界衔接 | `true` | +| `ASSIGNMENT_CONFLICT` | è¯·æ±‚åŒºé—´å†…å­˜åœ¨é˜»å¡žæ´¾å• | `false` | + +- `availabilityWindows` 是请求区间内的实际å¯ç”¨**闭区间**,冲çªä¼šåˆ‡åˆ†æ—¶é—´çª—。 +- è½¦è¾†å’Œå¸æœºéƒ½å¿…须覆盖完整请求区间æ‰å¯ç›´æŽ¥é€‰ä¸­ã€‚ +- 叿œºæ— è¯„价时返回 `rating=5.0` 且 `ratingDefaulted=true`;有真实评价时为 `false`。 +- è½¦è¾†æ€»åº§ä½æ•°åŒ…å«å¸æœºï¼Œ`passengerCapacity=seats-1`ï¼›å‰ç«¯ä¸å¾—æŠŠå¸æœºåº§ä½å†æ¬¡ç»™ä¹˜å®¢ã€‚ +- `selectedRelation` åœ¨è½¦è¾†å’Œå¸æœºéƒ½å·²é€‰æ—¶è¿”回常驻关系。跨常驻组åˆå¿…须显示åŽç«¯æç¤ºå¹¶æ˜¾å¼ç¡®è®¤ã€‚ + +## å…­ã€çŸ©é˜µæœˆè§†å›¾ + +### 6.1 请求 + +```http +GET /admin/fleet/matrix/grid?year=2026&month=7&season=active&fleets=own,coopA&typeKeys=suv&status=all +Authorization: Bearer +``` + +### 6.2 è¯·æ±‚å‚æ•° + +| 傿•° | 类型 | å¿…å¡« | 说明 | +|---|---|---|---| +| `year` | `int` | 是 | 查询年份。 | +| `month` | `int` | 是 | 1-12,越界返回车务月份错误。 | +| `season` | `string` | å¦ | `active` é»˜è®¤ï¼›ä¹Ÿæ”¯æŒ `pending/archived/blacklist`。 | +| `fleets` | `string[]` | å¦ | `own/coopA/coopB` 多选。 | +| `typeKeys` | `string[]` | å¦ | `suv/mpv/bus/sedan` 多选。 | +| `status` | `string` | å¦ | `all` 默认ã€`unassigned`ã€`assigned`。 | + +### 6.3 å“应示例 + +```json +{ + "code": 200, + "message": "æˆåŠŸ", + "success": true, + "data": { + "year": 2026, + "month": 7, + "daysInMonth": 31, + "todayDay": 18, + "weekendDays": [4, 5, 11, 12, 18, 19, 25, 26], + "fleetCount": {"own": 5, "coopA": 4, "coopB": 3}, + "statusCounts": { + "totalAssignments": 21, + "unassignedAssignments": 10, + "assignedAssignments": 11, + "totalOrders": 16, + "unassignedOrders": 5, + "partialOrders": 2, + "assignedOrders": 11 + }, + "unassignedWindowCount": 5, + "vehicles": [ + { + "id": "2000000000000000301", + "plate": "è’™A·TEST1", + "modelName": "测试车型", + "seats": 7, + "fleet": "own", + "primaryDriverName": "æµ‹è¯•å¸æœº", + "primaryDriverPhone": "138****0000", + "assignments": [ + { + "id": "2000000000000000201", + "assignmentGroupId": "2000000000000000201", + "orderNumericId": "2000000000000000101", + "orderNo": "HL202607180001", + "teamNo": "26-7218", + "consultantId": "2000000000000000001", + "consultantName": "ä¼ä¸šå¾®ä¿¡æ˜µç§°", + "customerName": "测试è”系人", + "headcount": 4, + "adultCount": 3, + "childCount": 1, + "startDay": 20, + "endDay": 22, + "startDate": "2026-07-20", + "endDate": "2026-07-22", + "clippedHead": false, + "clippedTail": false, + "vehicleCategory": "suv", + "categoryLabel": "SUV系列", + "assignmentStatus": "assigned", + "protocolPrice": "1300.00", + "vehicleSpecialTags": ["ä¸­æ–‡å¸æœº"], + "vehicleRequirementRemark": "按行程安排", + "pickupTransports": [], + "dropoffTransports": [], + "parallelAssignments": [ + { + "assignmentGroupId": "2000000000000000201", + "fleetItemIndex": 0, + "vehicleCategory": "suv", + "categoryLabel": "SUV系列", + "requiredSeats": 7, + "startDate": "2026-07-20", + "endDate": "2026-07-22", + "vehicleId": "2000000000000000301", + "vehiclePlate": "è’™A·TEST1", + "driverId": "2000000000000000401", + "driverName": "æµ‹è¯•å¸æœº", + "assignmentStatus": "assigned", + "protocolPrice": "1300.00" + } + ] + } + ], + "connections": [ + { + "fromAssignmentGroupId": "2000000000000000201", + "toAssignmentGroupId": "2000000000000000202", + "fromEndDate": "2026-07-22", + "toStartDate": "2026-07-23", + "previousDepartureTime": null, + "nextArrivalTime": null, + "previousCity": null, + "nextCity": null, + "connectionMinutes": null, + "thresholdMinutes": 120, + "status": "MISSING_TIME", + "statusLabel": "ç¼ºå°‘æŽ¥é€æ—¶é—´", + "style": "RED_DASHED", + "reasonCode": "PREVIOUS_REQUIRED_DEPARTURE_MISSING", + "reasonMessage": "å‰ä¸€è®¢å•缺少必需é€å®¢æ‰¹æ¬¡" + } + ] + } + ] + } +} +``` + +### 6.4 æ´¾å•统计å£å¾„ + +- `totalAssignments` æ˜¯æ´¾è½¦è¡Œæ•°ï¼Œä¸æ˜¯è®¢å•数。 +- `totalOrders` 是去é‡è®¢å•数。 +- 一å•åŒæ—¶å­˜åœ¨å·²æ´¾å’Œæœªæ´¾é¡¹æ—¶è®¡å…¥ `partialOrders`,也计入 `unassignedOrders`。 +- `unassignedWindowCount` æ˜¯å«æœªæ´¾é¡¹çš„去é‡è®¢å•数,ä¸ç­‰äºŽæœªæ´¾é€æ—¥åˆ‡ç‰‡æ¡æ•°ã€‚ +- 跨月派车组使用完整原始 `startDate/endDate`,仅 `startDay/endDay` è£å‰ªåˆ°å½“剿œˆï¼›`clippedHead/clippedTail` 告诉å‰ç«¯æ˜¯å¦è·¨æœˆç»­æŽ¥ã€‚ + +### 6.5 相邻订å•è¡”æŽ¥å››æ€ + +| `status` | `style` | å«ä¹‰ | +|---|---|---| +| `MISSING_TIME` | `RED_DASHED` | ç¼ºå°‘å¿…éœ€å¤§äº¤é€šã€æ—¶åˆ»æˆ–城市,无法完æˆè¡”接判断。 | +| `DIFFERENT_CITY` | `DARK_RED` | å‰åŽè®¢å•城市ä¸åŒã€‚ | +| `SAME_CITY_TOO_SHORT` | `LIGHT_RED` | åŒåŸŽä½†é—´éš”å°äºŽé…置阈值。 | +| `SAME_CITY_OK` | `GREEN` | åŒåŸŽä¸”间隔达到é…置阈值。 | + +原因ç ï¼š + +```text +PREVIOUS_REQUIRED_DEPARTURE_MISSING +NEXT_REQUIRED_ARRIVAL_MISSING +PREVIOUS_DEPARTURE_TIME_MISSING +NEXT_ARRIVAL_TIME_MISSING +PREVIOUS_DEPARTURE_CITY_MISSING +NEXT_ARRIVAL_CITY_MISSING +DIFFERENT_CITY +SAME_CITY_INTERVAL_TOO_SHORT +SAME_CITY_INTERVAL_SUFFICIENT +``` + +åŒåŸŽæœ€å°è¡”æŽ¥é˜ˆå€¼è¯»å– Nacos é…置,默认 120 分钟;æ°å¥½ç­‰äºŽé˜ˆå€¼å±žäºŽ `SAME_CITY_OK`。 + +注æ„:`MISSING_TIME` 是矩阵风险æç¤ºï¼Œä¸è¡¨ç¤ºè®¢å•ä¸èƒ½æ´¾è½¦ã€‚用户未填写大交通时ä»å…è®¸å®Œæˆæ´¾è½¦ã€‚ + +## 七ã€å‡ºè¡Œäººæƒé™ä¸Žå®¡è®¡ + +### 7.1 脱æ•列表 + +```http +GET /admin/fleet/board/orders/2000000000000000101/travelers +Authorization: Bearer +``` + +默认返回姓åã€å¹´é¾„类型和脱æ•è¯ä»¶/手机å·ï¼›å‰ç«¯æ—¥å¸¸æ´¾è½¦åªä½¿ç”¨æ­¤æŽ¥å£ã€‚ + +### 7.2 明文查询 + +```http +POST /admin/fleet/board/orders/2000000000000000101/travelers/plain +Authorization: Bearer +Content-Type: application/json +``` + +```json +{ + "reason": "叿œºå‡ºå‘剿 ¸å¯¹æŽ¥å®¢äººä¿¡æ¯" +} +``` + +明文接å£å¿…é¡»ç»è¿‡æƒé™æ ¡éªŒå¹¶è®°å½•æ“作人ã€è®¢å•ã€ç†ç”±å’Œæ—¶é—´ã€‚å‰ç«¯ä¸å¾—ç¼“å­˜ã€æ—¥å¿—æ‰“å°æˆ–二次æŒä¹…化明文个人信æ¯ã€‚ + +## å…«ã€å‰ç«¯å¿…é¡»å¤„ç† + +1. 看æ¿ä½¿ç”¨åˆ†é¡µæŽ¥å£ï¼Œåˆ†é¡µå™¨è¯»å– `data.total/page/pageSize`。 +2. 状æ€é¡¹ã€çжæ€ä¸­æ–‡ã€æ€¥å•æ•°è¯»å– `summary.statusOptions`,ä¸ç»´æŠ¤ç‹¬ç«‹æžšä¸¾å’Œç‹¬ç«‹è®¡æ•°ã€‚ +3. 汇总请求必须æºå¸¦ä¸Žåˆ—表相åŒçš„éžçжæ€ç­›é€‰ï¼›ä¸è¦æŠŠå½“å‰çжæ€ç­›é€‰ä¼ æˆæ±‡æ€»ç»Ÿè®¡èŒƒå›´ã€‚ +4. å¡ç‰‡å±•示 `teamNo/contactName/headcount/consultantDisplayName/startDate/endDate/specialTags/requirementRemark`。 +5. 定制师选择值传 `consultantId`;显示使用åŽç«¯è¿”回的ä¼ä¸šå¾®ä¿¡ä¼˜å…ˆå称。 +6. 统一文本框传 `keyword`,å¯åŒæ—¶åŒ¹é…叿œºã€è”系人ã€å›¢å·ã€è®¢å•å·å’Œå½“å‰å®šåˆ¶å¸ˆå±•示å;定制师按ä¼ä¸šå¾®ä¿¡æ˜µç§°ä¼˜å…ˆã€ç”¨æˆ·å兜底,å‰ç«¯ä¸å¾—自行并行匹é…多个å称别å。 +7. æ“作按钮使用 `availableActionCodes/canAssign/canRejectRequirement`,ä¸èƒ½æŒ‰é¢œè‰²æˆ–å‰ç«¯çжæ€çŒœæµ‹ã€‚ +8. è¯¦æƒ…å¤šè½¦è¯»å– `activeAssignments`ï¼›`currentAssignment` åªæ˜¯å…¼å®¹çš„æœ€æ–°ä¸€ç»„。 +9. `transport.transferTimeHint="æš‚æ— æŽ¥é€æœºæ—¶é—´"` 时显示æç¤ºï¼Œä½†ä¿æŒæ´¾è½¦å…¥å£å¯ç”¨ã€‚ +10. 候选资æºåˆ†åˆ«è¯»å– `vehicles/drivers` 分页;显示åŽç«¯åŽŸå› å’Œå¸¸é©»å…³ç³»æç¤ºã€‚ +11. 矩阵直接使用 `connections[].status/style/reasonCode/reasonMessage`ï¼›å¤§çº¢ã€æ·¡çº¢ã€è™šçº¿çº¢å’Œç»¿è‰²è¯­ä¹‰ä¸èƒ½è‡ªè¡Œäº¤æ¢ã€‚ +12. 所有雪花 ID 当字符串处ç†ã€‚ + +## ä¹ã€å…¼å®¹æ€§ä¸Žä¸å½±å“范围 + +- ä¿ç•™ `status/startDate/endDate/typeKeys/contactKeyword/consultantName` 等兼容别å。 +- 䏿–°å¢žå‰ç«¯å†…部接å£ï¼Œä¸æ”¹å˜çŽ°æœ‰æ´¾è½¦å†™æŽ¥å£ã€‚ +- ä¸è¦æ±‚å¡«å†™å¤§äº¤é€šï¼Œä¹Ÿä¸æŠŠç©ºå¤§äº¤é€šæ”¹æˆæ ¡éªŒé”™è¯¯ã€‚ +- 䏿”¹å˜â€œä¸€å¤©ä¸€æ¡æ´¾è½¦åˆ‡ç‰‡â€çš„æ•°æ®åº“事实模型;本轮åªä¿®æ­£è¯»æ¨¡åž‹èšåˆã€‚ +- ä¸å¤„ç†å›¢æœŸé…车。 +- ä¸ä¿®æ”¹ `hl-ui`。 + +## åã€éªŒè¯è¯æ® + +### 10.1 代ç ä¸Žæµ‹è¯• + +```text +hl-fleet-service å®šå‘æµ‹è¯•:253/253 通过 +hl-fleet-service å…¨é‡ verify:1799/1799 通过 +hl-order-service-v3 相关契约测试:30/30 通过 +独立代ç è¯„审:无 P0/P1 阻断项 +OpenAPI è¯´æ˜Žå®šå‘æ ¡éªŒï¼šspotless:check + compile 通过 +``` + +Order-v3 免釿µ‹è¯•中 4 项环境/åŸºçº¿å¤±è´¥å·²åœ¨åŒæäº¤å¹²å‡€åŸºçº¿å¤çŽ°ï¼š3 项为 H2 缺少 `payment_manual_receipt`,1 项为既有本地缓存架构门ç¦ï¼›ä¸ç”±æœ¬æ¬¡è½¦åŠ¡æ”¹åŠ¨å¼•å…¥ã€‚ + +### 10.2 部署 + +```text +hl-order-service-v3:Deploy Panel 任务 22ec81e8,8086/8186 åŒå®žä¾‹æˆåŠŸ +hl-fleet-service:Deploy Panel 任务 68487f94,8087/8187 åŒå®žä¾‹æˆåŠŸ +hl-fleet-service OpenAPI å£å¾„补充:Deploy Panel 任务 249594e3,8087/8187 åŒå®žä¾‹æˆåŠŸ +``` + +部署åŽå·²é€šè¿‡ç½‘关读å–车务 OpenAPI,确认线上文档明确区分“åŒä¸€è®¢å•筛选范围内的状æ€è®¡æ•°â€ä¸Žâ€œä¸éšè®¢å•筛选å˜åŒ–çš„å…¨å±€ç©ºé—²èµ„æºæ•°â€ï¼Œå¹¶åŒ…å«ç»Ÿä¸€å…³é”®è¯å¯¹å½“å‰å®šåˆ¶å¸ˆå±•示å的匹é…规则。 + +### 10.3 真实网关 API + +使用独立车务和定制师测试账å·ï¼Œç» `https://api.test.1814.love:9443` 完æˆçœŸå®žè®¢å•å…¨æµç¨‹å›žå½’;未使用 `admin`ã€`wx` 或 Mock æ•°æ®ã€‚ + +```text +最终回归:161/161 通过,失败 0 +è¦†ç›–ï¼šçœ‹æ¿æ±‡æ€»/列表/详情ã€ç»Ÿä¸€ç­›é€‰ã€å®šåˆ¶å¸ˆã€è„±æ•/明文出行人ã€å€™é€‰è½¦è¾†/叿œºã€ + 常驻与跨常驻ã€é¢„æ£€ã€æ´¾è½¦ã€å¸æœºç¡®è®¤ã€å–消/æ¢å¤/改派/æå‰å®Œç»“ã€çŸ©é˜µã€ä»·æ ¼ã€ + 车辆/叿œºã€å¯¹è´¦ã€æ¨¡æ¿ï¼Œä»¥åŠæ— å¤§äº¤é€šè®¢å•完整派车链路。 +``` + +无大交通真实场景é¢å¤–断言: + +```text +- 新建真实订å•å¹¶è¡¥é½ 2 å出行人 +- ä¸åˆ›å»ºä»»ä½•大交通计划 +- æˆåŠŸæäº¤æœ‰æ•ˆç”¨è½¦éœ€æ±‚ +- 详情:arrive=nullã€depart=nullã€batches=[]ã€transferTimeHint=æš‚æ— æŽ¥é€æœºæ—¶é—´ +- 候选查询æˆåŠŸï¼ŒpickupAt/dropoffAt å‡çœç•¥ +- 派车预检æˆåŠŸï¼Œconflict=false +- ç›´æ´¾æˆåŠŸå¹¶è¿›å…¥å·²æ´¾è½¦çŠ¶æ€ +- DBï¼šæ´¾è½¦ç»„é€æ—¥ 6 æ¡ï¼Œpickup_at/dropoff_at 6 æ¡å‡ä¸ºç©º +``` + +## å一ã€ç›¸å…³æ–‡æ¡£ + +- 看æ¿å­—段ã€ç»Ÿè®¡ã€è¡Œç¨‹å’Œä¿é™©äº‹åŠ¡ï¼š`57_4882_车务派å•看æ¿å½“å‰è®¢å•字段统计行程与ä¿é™©äº‹åŠ¡æ”¶å£-管ç†åŽå°.md` +- 需求级最终完æˆå›žè°ƒï¼š`59_4935_车务需求级派å•完æˆå›žè°ƒä¸Žæ»šåЍå‘布契约-管ç†åŽå°.md` +- æéœ€æ±‚和派å•基础契约:`53_4871_车务æéœ€æ±‚æ´¾å•看æ¿é—­çŽ¯å¥‘çº¦-管ç†åŽå°.md` +- 团å·ä¸Žå®šåˆ¶å¸ˆç­›é€‰ï¼š`54_4876_æ´¾å•看æ¿å›¢å·ä¸Žå®šåˆ¶å¸ˆä¸‹æ‹‰ç­›é€‰-管ç†åŽå°.md`