文件
hl-api-changelog/changelogs-v2/2026-09/06_frontend_团期看板展开行子订单列表恒空-前端缺陷-管理后台.md
2026-09-06 19:24:54 +08:00

17 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 团期看板展开行子订单列表恒空 admin wx(GIT) 前端缺陷 not_required not_required verified mmg 7d652bdc 2026-09-06 后端 GB-ADM-003 已在测试服 dev-v3 网关实测返回 1 条活跃子订单;纯前端门控 bug:store.currentGroupBatchId 只在详情页 fetchDetail 赋值,看板展开走的 fetchBatchOrders 不赋值,PeriodRow 子订单列表恒空。首选按 groupBatchId 键缓存(PeriodRow 原注释的设计),并把 ordersError 显示出来。 2026-09-06 dev-v3

团期订单:看板展开行子订单列表恒空(前端缺陷)

⚠️ 关键变化

现象:管理后台「团期订单」看板,产品「冻干粉发短信给」班期 2026-10-01「没,那你」这一行显示「已订房 1/8 · 剩 7 · 应收 5850.00 · 已收 5850.00」,点击展开却显示「本期暂无子订单。」,也没有加载态。

根因(hl-ui gitea/v2.1 提交 e78ba5be):src/stores/orderV2Batch.js:147-166 fetchBatchOrders(groupBatchId) 请求成功后只写 batchOrders,不写 currentGroupBatchId;该字段全文件唯一赋值点是 :129-131 fetchDetail()(团期详情页才调)。而 src/views/order-v2/batch/components/PeriodRow.vue:233-235 的子订单列表和 :236-238 的加载态都门控于 String(store.currentGroupBatchId) === groupBatchId.value。看板页展开只走 onToggle → store.fetchBatchOrders(:240-245),currentGroupBatchId 保持初始 '',门控永远不等 → orders 恒 [] → SubOrderTable.vue:4-7 v-if="!subs.length" 渲染「本期暂无子订单。」。只有在同一 SPA 会话里先进过该团期的详情页(fetchDetail 把 currentGroupBatchId 设成它)再回看板展开同一行,才碰巧显示正确;刷新页面后直接展开必现。

结论:后端零改动(GB-ADM-001 / GB-ADM-003 实测正确)。前端修法首选按 groupBatchId 键缓存子订单(PeriodRow.vue:232 原注释「按 groupBatchId 缓存」就是这个设计,现实现漂移成了借用详情页的 currentGroupBatchId 单值门控);同时把 store.ordersError 显示出来,否则接口 4xx/5xx 时也会伪装成「暂无子订单」。

行上的「1/8」「5850」和「房/导/摄」橙色芯片都是当时那条被挡住的活跃子订单 HL20260906093733163 的真实状态,不是看板算错:已订房按「1 单 = 1 房」持久计数器算(order_group_batch.enrolled_rooms),产品侧「线下占位房数」不参与已订房/剩余;橙 = 进行中(batchLifecycle.js:64-70 DOING → doing),不是「配置完了」。导/摄「零指派却橙」的后端口径已另立 #7204 修正。补充说明:这条子订单本是 2026-09-06 01:37 已取消的测试单,14 时许被团期房务会话为 #7149 实测用 SQL 临时改成「定制中 / 已付订金」,18:51 已复原为已取消——因此该班期现在已订房回到 0/8、展开区显示「本期暂无子订单」是正确的;复现本缺陷请换任一有活跃子订单的团期(见复现步骤)。


一、背景

复现步骤

页面:管理后台 192.168.100.219:9527/order-v2/batch(hl-ui 团期看板,src/views/order-v2/batch/index.vue)。

  1. 刷新页面(确保本会话没进过任何团期详情页)
  2. 产品页签选任一行头 orderCount>0 的团期(2026-09-06 18:55 测试库可用:「测试小蒙马-多档-固定金额」的 12-20 出团「#7158验收班期」、12-27 出团「#7178验收班期」,各 1 个活跃子订单;wx 截图用的「冻干粉发短信给」10-01「没,那你」行当时也是 1 单,但那单已于 18:51 复原为已取消,现在该行是真的没有子订单)
  3. 点击行左侧展开箭头
  4. 结果:展开区显示「本期暂无子订单。」,无加载态(而 GET /v3/admin/order/group-batch/{该行 groupBatchId}/orders 返回 ≥1 条)
  5. 对照:先点「进入团期」进详情页再返回看板展开同一行 → 显示子订单(这是 bug 的偶然绕过路径,不是修复)

调用链

  1. PeriodRow.vue:240-245 onToggle() → store.fetchBatchOrders(groupBatchId)
  2. src/stores/orderV2Batch.js:147-166 fetchBatchOrders → src/api/orderV2GroupBatch.js getGroupBatchOrders(id, {includeTravelers: true, includeNeeds: true, includeCancelled: false}) → GET /v3/admin/order/group-batch/{groupBatchId}/orders
  3. hl-gateway 路由 /v3/admin/** → lb://hl-order-service-v3
  4. hl-order-service-v3 GroupBatchQueryController.listSubOrders(order/groupbatch/controller/admin/GroupBatchQueryController.java:96-)→ GroupBatchQueryService.listSubOrders(:253-,缺省剔除 CANCELLED)→ 返回 1 条
  5. store 把结果写进 batchOrders(:157),不写 currentGroupBatchId
  6. PeriodRow.vue:233-235 orders = currentGroupBatchId === groupBatchId ? batchOrders : [] → []
  7. SubOrderTable.vue:4-7 空态

地面真相(测试服 dev-v3 e9a8dd27,2026-09-06 网关实测)

属性 值
产品 冻干粉发短信给 productId=2044306857534636034(GROUP)
班期 product 侧 productBatchId=2052935476557328386(2026-10-01 出团、10-03 返团)
团期主订单 groupBatchId=2096412454643802114,batchStatus=RESOURCE_PREPARING,maxRooms=8,enrolledRooms=1,enrolledPeople=2,orderCount=1
活跃子订单 orderId=2096412454488612866 orderNo=HL20260906093733163:orderStatus=CUSTOMIZING,payStatus=DEPOSIT_PAID,paidAmount=5850.00,1 成人 1 儿童,order_main.room_count=1
同班期其余 13 单 全部 CANCELLED(includeCancelled=true 时返回 14 条)
备注 以上是 wx 截图时段(2026-09-06 17:20 前后网关实测)的状态。该单 09:37 建、01:37(UTC 09-05 17:37)已取消,14 时许被团期房务会话为 #7149 实测用 SQL 临时改成 CUSTOMIZING / DEPOSIT_PAID / 5850 并改写房务需求(roomCount=2 KING,specialNeeds 含「#7149 网关实测」),18:51 已复原为 CANCELLED / UNPAID / 0.00;复原后该班期 enrolledRooms=0、无活跃子订单。它与产品侧「线下占位房数=0」无关

二、变更接口清单

# 接口 方法 网关路径 前端函数 变更 说明
1 团期子订单列表 GB-ADM-003 GET /v3/admin/order/group-batch/{groupBatchId}/orders getGroupBatchOrders() 复用不改 后端已实测返回 1 条,前端未渲染

三、接口详情

1. 团期子订单列表 GET /v3/admin/order/group-batch/{groupBatchId}/orders

VO: 无请求 VO(路径参数 + 三个可选 query)→ Result<List<GroupBatchOrderItemRespVO>>

使用场景

看板行展开(PeriodRow.onToggle)与团期详情名单页拉该团期的子订单摘要;缺省只返活跃集(orderStatus != CANCELLED)。

入参

字段 位置 类型 必填 约束 说明
groupBatchId path Long(JSON 字符串) 是 团期主订单 ID 不是 product 侧 productBatchId
includeTravelers query Boolean 否 缺省 false true 时附 travelers[](证件号一律不返回)
includeNeeds query Boolean 否 缺省 false true 时附 roomCount / roomType / specialNeeds
includeCancelled query Boolean 否 缺省 false true 时含已取消子订单

出参 Result<List<GroupBatchOrderItemRespVO>>

字段 类型 说明
data[].orderId String(Long) 子订单 ID
data[].orderNo String 订单编号
data[].customerName String 客户姓名
data[].contactPhone String 联系人手机号(脱敏,前 3 后 4)
data[].adultCount / childCount / youngChildCount / babyCount Integer 成人 / 儿童 / 幼童 / 婴儿数
data[].participantCount Integer 出行人总数(四项之和)
data[].orderStatus String 订单状态码:PENDING_PAY / CUSTOMIZING / PENDING_DEPARTURE / TRAVELLING / COMPLETED / CANCELLED
data[].orderStatusName String 订单状态中文名
data[].payStatus String UNPAID / DEPOSIT_PAID / FULLY_PAID
data[].paidAmount String(BigDecimal) 已支付金额(订金 + 尾款)
data[].totalPrice String(BigDecimal) 本户应收 = orderAmount + 增项 − 优惠(下限 0);取消单返 0
data[].balanceAmount String(BigDecimal) 待支付尾款 = 应收 − 已退 − 已付(≥0)
data[].estimatedCost String(BigDecimal) 下单时点预估成本快照,可为 null
data[].contractStatus String GENERATING / SIGNED / VOIDED / RESIGNING / FAILED;无合同 null
data[].insuranceStatus String INSURING / INSURED / CANCELLED / FAILED;无保险 null
data[].hotelRequirementStatus String 房需求提报状态 PENDING / SUBMITTED / REJECTED(实测也会透出需求状态机原值如 PENDING_REVIEW)
data[].vehicleRequirementStatus String 车需求提报状态 PENDING / SUBMITTED / REJECTED
data[].roomCount Integer 房数(includeNeeds=true;来源 order_hotel_requirement.days,缺省 ceil(人数/2))——与 order_main.room_count 是两个字段,看板「已订房」用的是后者
data[].roomType String 房型文本(includeNeeds=true)
data[].specialNeeds String 特殊需求(includeNeeds=true;缺需求行回落 customer_remark)
data[].tierCode String 档位码,如 1A1C
data[].tierName String 档位名,如 1成人1儿童
data[].travelerInfoComplete Boolean 出行人资料是否齐全
data[].travelers[] Array includeTravelers=true 时返回:name / type(ADULT/CHILD/YOUNG_CHILD/BABY) / age / birthdayInTrip
data[].consultantName String 定制师姓名(创单时固化)

请求示例

GET /v3/admin/order/group-batch/2096412454643802114/orders?includeTravelers=true&includeNeeds=true HTTP/1.1
Host: api.test.1814.love:9443
Authorization: Bearer <token>

响应示例

实测响应(2026-09-06,travelers[] 略):

{
  "code": 200,
  "message": "成功",
  "data": [
    {
      "orderId": "2096412454488612866",
      "orderNo": "HL20260906093733163",
      "customerName": "测试团期指引",
      "adultCount": 1,
      "childCount": 1,
      "youngChildCount": 0,
      "babyCount": 0,
      "participantCount": 2,
      "orderStatus": "CUSTOMIZING",
      "orderStatusName": "定制中",
      "payStatus": "DEPOSIT_PAID",
      "paidAmount": "5850.00",
      "totalPrice": "5850.00",
      "balanceAmount": "0.00",
      "estimatedCost": null,
      "contractStatus": null,
      "insuranceStatus": null,
      "hotelRequirementStatus": "PENDING_REVIEW",
      "vehicleRequirementStatus": "PENDING",
      "roomCount": 2,
      "roomType": "KING",
      "specialNeeds": "#7149 网关实测 AC-1 招募中",
      "tierCode": "1A1C",
      "tierName": "1成人1儿童",
      "travelerInfoComplete": false,
      "consultantName": "admin"
    }
  ],
  "success": true
}

空数据 / 降级响应

该团期没有活跃子订单时 data 为空数组(不是 null);前端只有在 code=200 && data.length===0 时才应显示「本期暂无子订单」,请求失败或异常码一律显示错误态。

{
  "code": 200,
  "message": "成功",
  "data": [],
  "success": true
}

错误响应

{
  "code": 589500,
  "message": "团期不存在",
  "data": null,
  "success": false
}

其他:589507 无操作权限(非团期管理员 / 非本定制师名下)。HTTP 始终 200,按 code 判断。

业务边界

  • 缺省剔除 CANCELLED;includeCancelled=true 才含已取消单
  • 路径参数是 order 侧 groupBatchId,看板行 VO 里的 groupBatchId 字段直接可用;不要传 productBatchId
  • roomCount(房务需求)与看板「已订房」(order_main.room_count 计数器,1 单 = 1 房)口径不同,不要互相校验

四、前端修复要点与自测清单

修复要点

  1. 首选(方案 B)按 groupBatchId 键缓存:orderV2Batch.js 把 batchOrders(单值数组)改成按 ID 的 map(如 ordersByBatch = ref({})),fetchBatchOrders 写 ordersByBatch.value[id] = list;PeriodRow.vue:233-238 的 orders / ordersLoading 直接读 store.ordersByBatch[groupBatchId.value],去掉对 currentGroupBatchId 的依赖(该字段语义上只服务详情页)。多行同时展开互不覆盖;PeriodRow.vue:232 原注释「按 groupBatchId 缓存」即此设计。保留旧的 batchOrders 导出(:202 一带)直到 grep 确认详情页 / ChipDetailModal.vue 没有直接读它。
  2. 治标(方案 A):只在 fetchBatchOrders 请求前写 currentGroupBatchId.value = id。一行改动,但 currentGroupBatchId 是单值:keep-alive(index.vue:170-172)下先展开 X 行、进 Y 详情再返回,X 行会退回空态;多行同时展开互相覆盖。不推荐单独采用。
  3. 错误态:PeriodRow.vue 目前不渲染 store.ordersError(orderV2Batch.js:159-162 失败时置 batchOrders=[]),接口失败会伪装成「暂无子订单」;展开区应区分「加载中 / 加载失败(可重试)/ 暂无子订单」,且行上 orderCount>0(GB-ADM-001 有该字段)而列表为空时显示「加载失败」而非「暂无」。
  4. 让橙色芯片可自证:SubOrderTable.vue:10-19 表头只有联系人 / 人数 / 房型·间数 / 电话 / 应收 / 毛利 / 资料,GB-ADM-003 已返回的 hotelRequirementStatus / vehicleRequirementStatus 没有展示;建议加「房需求 / 车需求」状态列,或在芯片上加 tooltip 文案「进行中:N 户待审核」(数据来自 GB-ADM-090~095 逐户明细),否则运营看到橙色仍不知道它对应哪户的什么状态。芯片图例建议:灰=未开始、橙=进行中、绿=已完成、红=异常。
  5. 顺手核对:ChipDetailModal.vue(index.vue:174 引入)是否也依赖 currentGroupBatchId;详情页离开时是否需要清空 currentGroupBatchId。

自测清单

  1. 刷新看板页,直接展开任一 orderCount>0 的行(如「测试小蒙马-多档-固定金额 · #7158验收班期」)→ 出现与 GB-ADM-003 返回条数一致的子订单
  2. 先展开 A 行再展开 B 行 → 各自显示各自的子订单,收起再展开不串行
  3. 展开瞬间出现加载态
  4. 断网或把接口改成 500 → 展开区显示「加载失败」而非「本期暂无子订单」
  5. 进详情页再返回看板展开 → 仍正确(keep-alive 场景)
  6. 真正没有活跃子订单的团期(如把该单取消后)→ 显示「本期暂无子订单」

五、验证证据

网关实测(测试服 2026-09-06 17:20 前后,登录后切 ADMIN 角色;该单 18:51 已复原为已取消,下表是截图时段的证据)

请求 结果
GET /v3/admin/order/group-batch/2096412454643802114/orders 200 / code 200,1 条(HL20260906093733163)
GET .../orders?includeTravelers=true&includeNeeds=true(前端缺省参数) 200 / code 200,1 条,含 roomCount=2 / roomType=KING
GET .../orders?includeCancelled=true 200 / code 200,14 条(1 活跃 + 13 CANCELLED)
GET /v3/admin/order/group-batch/2096412454643802114 enrolledRooms=1、enrolledPeople=2、remainRooms=7、maxRooms=8
GET /v3/admin/order/group-batch/board?productId=2044306857534636034 该行 enrolledRooms=1、orderCount=1、groupBatchId=2096412454643802114

DB 落库(只读)

hl_order_service_v3.order_main 中 product_batch_id=2052935476557328386 共 14 行:13 行 order_status=CANCELLED,1 行 CUSTOMIZING(pay_status=DEPOSIT_PAID、paid_amount=5850.00、room_count=1、group_batch_id=2096412454643802114);order_group_batch 该团期 enrolled_rooms=1、enrolled_people=2。


六、影响与不影响范围

  • 影响:hl-ui src/stores/orderV2Batch.js、src/views/order-v2/batch/components/PeriodRow.vue、SubOrderTable.vue(可选加列);团期详情页若直接读 store.batchOrders 需同步改用新缓存
  • 不影响:后端 GB-ADM-001 / GB-ADM-003 契约与实现;网关;小程序;订单列表页

七、关联

  • 后端工单 #7204:导/摄芯片零指派却 DOING(橙)的聚合口径修正(wx 2026-09-06 拍板:零指派灰 / 部分指派橙 / 全部指派绿)——与本缺陷无依赖,但同一现场
  • 后端团期看板三单:#7188(「第N期」序号透出)、#7189(看板以产品全班期为基底 + 班期范围筛选)、#7190(「出行完毕」状态)——均不改 GB-ADM-003
  • 同日前端缺陷:06_frontend_团期产品新建订单向导创单漏传productBatchId-前端缺陷-管理后台.md(已由 mmg 修复 03a985b6)