11 KiB
schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
| schema | ticket | title | consumer | author | change_type | backend_status | gateway_status | frontend_status | frontend_owner | frontend_ref | target_release | verified_at | status_note | updated_at | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hl-changelog/v2 | frontend | 查看需求 Tab:整团级操作收进顶部操作条 + 子订单行新增「需求详情」弹窗 | admin | wx(GIT) | 前端优化 | not_required | not_required | verified | mmg | f713b1c65c061a18754c5bc759d1c50c3dd5eb3e | v2.1 | 2026-09-23 | 2026-09-23 wx 对「查看需求」Tab 提三点:①「新增正式行程用车需求」按钮应该在顶部操作条这里;②该按钮独立成一张卡片操作不方便;③要一个按钮点开弹窗看用房/用车需求详情;并总结「这个 Tab 操作整体不方便,整理优化下」。本条是给 mmg 的 UI 重排规格。后端零改动:四项改动用到的端点与字段全部已在 dev-v3 上线并被本 Tab 现有代码调用,无新增端点、无出入参变化、无网关路由变化、无 DDL。字段清单逐项对 origin/dev-v3 的 VO 源码核过(GroupHotelHouseholdsRespVO / GroupVehicleHouseholdsRespVO / GroupBatchRoomPlanDetailRespVO)。 | 2026-09-23 mmg 交付:五区块卡头全撤,顶部操作条(刷新一个顶六个/新增编辑正式需求平铺,整团级缺失时 primary ghost/撤回免车受控重开收更多下拉,判定经 ops-state 上抛);预检条目可点(户级滚动定位名单行+高亮,车侧整团级直开编辑弹窗);名单表加需求详情弹窗(两 tab 只读复用 households 快照零新请求,分房段按需拉 room-plans 过滤本户);五卡自绘折叠分区默认只展开两汇总(n-collapse 懒挂载不满足 eager fetch);scroll-x 钉死列宽合计 1568;顺带修 A 段遗留 doConfirm stale refs ReferenceError;7 spec 99 例全绿 | 2026-09-23 | dev-v3 |
查看需求 Tab:操作重排 + 逐户需求详情弹窗
服务: hl-order-service-v3(后端零改动) 页面: 管理后台 → 团期订单 → 团期详情 → 「查看需求」Tab 文件:
src/views/order-v2/batch/detail/components/RequirementTab.vue及其子组件 日期: 2026-09-23 影响范围: 仅前台渲染与交互编排;无端点、无出入参、无网关路由、无 DDL 变化
一、现状与问题(对 origin/v2.1 = 61a549bd 实读)
这个 Tab 现在是「一条操作条 + 一张子订单表 + 五张平铺卡片」的结构:
| 位置 | 承载的整团级操作 |
|---|---|
RequirementTab.vue:29-51 .requirement-tab__ops |
刷新预检 / 打回选中户(N) / 整团确认需求 |
GroupVehicleRequirementSection.vue 的 #header-extra |
新增(编辑)正式行程用车需求 / 整份撤回·撤回免车 / 声明整团免车 / 受控重开配车窗口 |
| 五张卡片各自的卡头 | 各自一个「刷新」 |
三个具体问题:
- 整团级操作散在三处,其中一处还在第四屏。
- 阻断项和解除阻断的按钮离得最远。顶部预检提示条会打出「团期 xxx 尚未形成正式用车需求」,而消除它的那个按钮在下方「正式用车需求」卡片的卡头里——看见问题的地方和能动手的地方隔了四张卡片。
- 一户的需求被劈在两张卡片里。「用房 · 子订单订房记录」和「用车 · 子订单需求记录」各自按户列一遍,要看清某一户到底报了什么,得在两张卡片之间上下翻。子订单表里的那一行才是「这一户」,但那行点不开。
二、要做的四件事
1. 整团级操作全部收进顶部操作条
.requirement-tab__ops 改为(从左到右):
[刷新] [打回选中户(N)] [新增正式行程用车需求] [更多 ▾] ………… [整团确认需求]
新增正式行程用车需求平铺(wx 明确指定放这里)。文案沿用现有逻辑:有需求时显示「编辑正式需求」,无需求时显示「新增正式行程用车需求」。更多 ▾收三个低频且互斥的:整份撤回/撤回免车(二者v-if/v-else-if互斥)、声明整团免车、受控重开配车窗口。收进下拉的理由是这四个按钮的出现与否随状态变化,平铺会让操作条宽度随状态跳动;下拉让操作条形状恒定。- 按钮层级:
整团确认需求保持type="primary",是这个页面的终点。新增正式行程用车需求用默认样式,但当预检提示条里出现「尚未形成正式用车需求」这一条时,把它切成type="primary" ghost—— 此刻它才是「现在该点的那个」。 - 卡片保留,只清空卡头。
GroupVehicleRequirementSection这张卡片继续展示正式用车需求的内容(车队、座位、状态),只把#header-extra里那四个按钮搬走。
实现上父子已经通着:RequirementTab.vue:155-168 已持有 ref="vehicleReqRef",把 canEdit / isWaived / canWithdraw / canReopen 四个 computed 与四个动作的入口方法 defineExpose 出来即可,不需要新增 props 或提升状态。
2. 预检提示条的每一条做成可点
这是「操作不方便」最直接的来源,优先级最高。
| 提示条里的条目 | 点击后 |
|---|---|
HL2026xxxx 定制师张三 — 未提交房需求 |
滚动到子订单表对应行并高亮(orderId 已在 missing 项里) |
团期 21008xxxx 尚未形成正式用车需求 |
直接打开 GroupVehicleRequirementEditModal,即操作条上那个「新增正式行程用车需求」 |
把「看见问题」和「动手解决」接在一起,用户就不必自己在页面里找对应入口。
3. 子订单表操作列新增「需求详情」→ 弹窗
在现有「进入」旁边加一个「需求详情」。点开一个 n-modal(或右侧 n-drawer),两个 Tab:用房 / 用车,只读。
关键点:这个弹窗的价值是「按户聚合」,不是「多给字段」。
两张列表卡片其实已经把下面这些字段渲染出来了(RoomHouseholdsSection.vue / VehicleHouseholdsSection.vue 实读确认),弹窗做的是把同一户散在两处的内容收到一屏。
用房 Tab
数据来自本 Tab 已加载的 GET /v3/admin/order/group-batch/{groupBatchId}/requirement/hotel-households,按 orderId 过滤,不发新请求。
- 头部:
customerName/teamNo/orderNo/participantCount/consultantName - 状态:
statusName,外加countedInSummary的显式标识(计入汇总 / 未计入汇总) - 配房需求:
remark - 特殊标签:
specialTags[] - 打回留痕:
returnRemark+returnedAt(有值才显示) - 逐晚表,来自
days[]:
| 列 | 取值 | 既有约定(沿用,勿改) |
|---|---|---|
| 第 N 天 | dayNumber |
|
| 入住日 | stayDate |
|
| 自行预订 | customerSelfBooked |
为 true 时该晚不该被当成缺口 |
| 酒店 | hotels[].hotelName |
为 null 显「未知酒店」,行不隐藏(间数仍有效) |
| 地点 | hotels[].district |
用 district 不用 city,契约实测 city 几乎恒为同一地级市,区分不出地点 |
| 房型 | rooms[].roomTypeName |
回落链:roomTypeName → roomCategoryName → roomCategory → 「未知房型」 |
| 间数 | rooms[].roomCount |
用车 Tab
数据来自 GET .../requirement/vehicle-households,同样按 orderId 过滤复用已加载数据。逐条渲染 requirements[]:
kindName(行程用车 / 接送机)+statusNameserviceDates[]headcount/totalSeatCount(含驾驶位)/remainingPassengerSeats(负数标「缺口」,沿用现有红色样式)fleet[]车队明细pickupRequired/dropoffRequired—— 仅 TRANSFER 有意义,TRAVEL 恒为 null,TRAVEL 下整行不渲染specialTags[]/remarkreturnRemark+returnedAt(有值才显示)
可选第二段:这一户「已经配成什么样」
如果要让弹窗从「他报了什么」延伸到「我们给他配了什么」,GET /v3/admin/order/group-batch/{groupBatchId}/room-plans(H12 整团配房明细,只读、不含金额)已经有分房层,按 orderId 过滤即可:
days[].plans[].allocations[] → orderId / orderNo / roomCount / roomGroupNo(家庭分组 F{N}) / 入住人数 / allocSource(AUTO|MANUAL)
外层还带 hotelName / roomTypeName / planStatus(PENDING|CONFIRMED)/ replaceReason。这是弹窗里唯一需要多发一个请求的部分,按需加载即可。
4. 刷新收敛成一个,明细卡片默认折叠
- 顶部操作条那个
刷新预检改名刷新,一次刷预检 + 五个区块;撤掉五张卡片各自的刷新按钮。用户心智里这个页面只有一个「刷新」。 - 五张卡片(用房·汇总 / 用房·子订单订房记录 / 用车·汇总 / 正式用车需求 / 用车·子订单需求记录)改
n-collapse,默认只展开两张「汇总」。明细按需展开,首屏留给操作条、预检提示条和子订单表。
三、数据来源汇总(零新接口)
| 用途 | 端点 | 本 Tab 现状 |
|---|---|---|
| 子订单表 | GET /v3/admin/order/group-batch/{id}/orders |
已调 |
| 预检 | GET .../requirement/confirm-check |
已调 |
| 用房逐户(弹窗用房 Tab) | GET .../requirement/hotel-households |
已调,字段够 |
| 用车逐户(弹窗用车 Tab) | GET .../requirement/vehicle-households |
已调,字段够 |
| 整团确认 / 打回 | POST .../requirement/confirm、.../requirement/reject |
已调 |
| 正式用车需求 读/存/撤回/免车/重开 | GET·PUT .../vehicle-requirement、.../withdraw、.../waive、.../reopen |
已调 |
| 弹窗「已配成什么样」(可选段) | GET .../room-plans |
本 Tab 未调,端点已上线(H12) |
四、业务边界
- 本条只覆盖「查看需求」Tab。「配房明细」Tab(
RoomPlansTab.vue)的结构不在本次重排范围内。 - 需求侧的房间粒度只到「房型 × 间数」。
GroupHotelHouseholdsRespVO的最细一层是HouseholdRoomItem{roomTypeId, roomTypeName, roomCategory, roomCategoryName, roomCount},弹窗的用房 Tab 给不出「哪一间」。 - 「谁住哪一间」这层数据全系统没有。配房侧能到「哪一户的哪个家庭分组 F{N}、几个人、住哪家酒店哪个房型的几间」(上面第二段那个可选来源),但出行人姓名与房间的绑定不存在——
GET .../room-plans的接口说明里明写了不返回出行人姓名与联系方式。要做到姓名级,是一次真正的新增能力,不是取数问题。 - 用车侧被打回的户可能在弹窗里无行可渲染。
VehicleHouseholdsSection.vue:210的注释写着「打回行失活不在列表(与用房侧『列出打回户灰显』刻意不同)」。【需确认】这一条我只读到注释、没有实测接口返回,实现时以vehicle-households的实际返回为准;若确实不返,弹窗用车 Tab 对被打回的户要给一个明确空态文案,不要显示成「这户没报用车需求」。 受控重开配车窗口进下拉后仍受既有约束:DISPATCHED 定稿后要重配须先开窗拿令牌,PENDING_RECONFIRM 下续开/取当前令牌同走这个入口(后端幂等返回既有令牌,809203兜他人窗口)。挪位置不改变这套行为。整团免车是合法逃生口不是异常态。顶部那个本团整团免车的n-tag(checkResult?.vehicleWaived === true)要保留在操作条附近,免车时车侧校验整体跳过,别让它看起来像出错了。