--- schema: "hl-changelog/v2" ticket: "frontend" title: "团期看板对齐后端契约待办汇总(第N期 / 班期范围 scope / 出行完毕页签 / 未建团行交互 / 芯片计数)" consumer: "admin" author: "wx(GIT)" change_type: "前端优化" backend_status: "deployed" gateway_status: "verified" frontend_status: "verified" frontend_owner: "mmg" frontend_ref: "2eb27845" target_release: "" verified_at: "2026-09-08" status_note: "本篇是 #7188/#7189/#7190 三单的前端待办汇总(行标题第N期 batchLabel / 班期范围 scope 筛选三处同传 / 出行完毕 TRIP_FINISHED 页签 / 未建团行 groupBatchId=null 分支),含精确 file:line 与期望代码。第 5 项芯片计数 tooltip 依赖后端 #7250 chipStats,后端代码已合入 dev-v3(PR #7254),其 changelog 07_7250_* 已于 2026-09-07 通过测试服 AC-1~AC-9 实测后发布(commit 16e0133),依赖已解除,本条可派发;c39fb8a 已修正其文案口径(done=已完成数非待配、error>0≠红因后端有覆盖规则、精确待配需点明细)。2026-09-07 复审后二次修正约/保异常文案:原「{error} 户合同已作废」「{error} 户投保失败」以偏概全(后端合同 error 含作废中+已作废两态、保险 error 含已取消+投保失败两态),改为「{error} 户合同异常」「{error} 户保险异常」,精确原因走明细接口 GB-ADM-094(约)/GB-ADM-095(保);房/车「已打回」两个失败态语义一致,保持不变。前端已识别,按「先完成任务清单」排在 #7067 U2-U7 之后统一派发,本条保持 pending。" updated_at: "2026-09-07" base: "dev-v3" --- # 团期看板:对齐后端契约的前端待办汇总(前端优化) ## ⚠️ 关键变化 后端 #7188 / #7189 / #7190 已上线且实测通过,但 hl-ui 尚未消费新字段与新参数,现场表现为三个「看起来像 bug」的现象。本篇把待办逐条列清,**后端零改动**(第 5 项例外,依赖后端 #7250)。 | # | 现象 | 根因 | 后端已给什么 | |---|---|---|---| | 1 | 行标题只有「没,那你」,没有「第7期」 | 前端没读 `batchLabel` | 分页 / 看板 / 详情三处都返 `batchLabel`(实测 10-01 期 `"7"`、12-01 期 `"8"`) | | 2 | 产品页签写「8 期」,看板「全部期」只有 2 行 | 前端不传 `scope`,后端在传 productId 时缺省按「未结束」过滤 | `scope=ONGOING / FINISHED / ALL` 四端点同名同义 | | 3 | 状态页签缺「出行完毕」 | 前端页签表硬编码 7 个 | 统计条固定返 8 键,含 `TRIP_FINISHED` | | 4 | 未建团行点进去会报错 | 前端未按 `groupBatchId=null` 分支渲染 | 分页项 `groupBatchId` 可为 null,另有 `productBatchRemoved` 标孤儿行 | | 5 | 芯片整格红,看不出哪户出了问题 | 现契约只给一个状态字符串 | 待后端 #7250 透出 `chipStats` 计数 | **已修无需再动**:「展开行子订单列表恒空」(changelog `06_frontend_团期看板展开行子订单列表恒空-前端缺陷-管理后台.md`)在 `gitea/v2.1` 20eb2a19 已修复——`src/stores/orderV2Batch.js:44` 的 `ordersByBatch` 按 groupBatchId 键缓存已落地(`:166-173` 写入),`PeriodRow.vue:248-249` 注释也已说明不再依赖 `currentGroupBatchId`。 **桶中文文案不改**:沿用前端现有「待审核 / 已审核 / 流团」,与 #7190 changelog 写明的「前端页签文案沿用现有」一致;新增的第八个页签用「出行完毕」。 --- ## 一、背景 wx 2026-09-06 至 09-07 在测试服(管理后台「团期订单」看板,产品「冻干粉发短信给」productId=2044306857534636034)逐项核对,四个现象经 BUG 分析员对 origin/dev-v3 源码与网关实测取证,结论是三条前端未跟进、一条是测试数据(详见第六节)。 后端三单的接口契约分别在: - `changelogs-v2/2026-09/06_7188_团期看板列表详情透出第N期batchLabel-修改接口-管理后台.md` - `changelogs-v2/2026-09/07_7189_团期看板产品全班期基底与scope范围筛选-修改接口-管理后台.md` - `changelogs-v2/2026-09/06_7190_团期状态新增出行完毕TRIP_FINISHED看板八桶-修改接口-管理后台.md` 本篇只写「前端该改哪里、改成什么样」,字段语义与请求参数以上述三份为准。 --- ## 二、逐条待办 ### 1. 行标题与详情头显示「第N期」 **现状**(ref `gitea/v2.1` 20eb2a19) - `src/views/order-v2/batch/components/PeriodRow.vue:179-184`:`title` computed 依次取 `batchName / groupBatchName / name / periodName`,不含 `batchLabel`。 - `src/views/order-v2/batch/detail/components/BatchHero.vue:74-75`:同样只取 `batchName` 系列。 - 全仓 `batchLabel` 只在 `views/order-v2/new/components/Step3Confirm.vue`、`views/product/edit/components/steps/BatchPricingStep.vue`、`views/product/line/components/BatchPanel.vue` 命中,看板与团期详情零命中。 **期望** ```js const title = computed(() => { const name = props.row.batchName || props.row.groupBatchName || props.row.name || props.row.periodName || '团期' return props.row.batchLabel ? `第${props.row.batchLabel}期 ${name}` : name }) ``` `batchLabel` 是数字字符串(`"7"`),**不要**当数字做算术或当排序键;存量团期在下一次该班期下单刷新快照前可能为 null,必须兜底成只显名称。详情头同规则。 ### 2. 新增「班期范围」筛选,三处请求同传 scope **现状** - `src/stores/orderV2Batch.js:76` `fetchSummary` 与 `:93` `fetchBatchPage` 都不传 `scope`;看板相关文件全仓 `scope` 零命中(其它命中在房务日历、待办、订单调整快照,与本处无关)。 - 结果:传 productId 时后端按缺省 `ONGOING` 只回未结束班期,产品 2044306857534636034 的 8 期里只剩 10-01 与 12-01,而左侧产品页签的 `batchCount` 是 product 侧全部班期数(8),同屏两个口径。 **期望** - 筛选区加「班期范围」下拉:未结束 / 已结束 / 全部,对应 `scope=ONGOING / FINISHED / ALL`,**默认「未结束」**。 - 列表、统计条、导出**同一组参数同传** `productId / scope / month / keyword`(列表另加 `opsStage / pageNo / pageSize`)。统计条不传 scope 会与列表对不上账。 - 用户点后段桶页签(`TRIP_FINISHED` / `AUDITING` / `CHECKED`)时,若当前 scope 不是 ALL,**自动切成 ALL** 再请求(可给一句提示)。后端严格取 scope 与 opsStage 的交集,这三个桶的返团日必然已过,默认「未结束」下交集恒空。 实测对照(2026-09-07,产品 2044306857534636034): | 请求 | total | |---|---| | 不传 scope(等于 ONGOING) | 2 | | `scope=FINISHED` | 6 | | `scope=ALL` | 8 | ### 3. 状态页签补「出行完毕」 **现状** - `src/views/order-v2/batch/_shared/batchLifecycle.js:13` `OPS_STAGES` 只有 7 键;`:24-31` `OPS_STAT_TABS` 逐项硬写;`BATCH_STATUS_TO_OPS` 缺 `TRIP_FINISHED`。 - 全仓 `TRIP_FINISHED` 与「出行完毕」零命中。 **期望** - 三张表都补 `TRIP_FINISHED`,位置在 `TRAVELLING` 与 `AUDITING` 之间(与后端 `GroupBatchStageBuckets.Bucket` 声明顺序一致),标签「出行完毕」。 - 统计条按**键名**读 `buckets.TRIP_FINISHED`,不要按数组索引取值。 - 其余七个桶的中文**不改**,沿用现有文案。 后端统计条实测返回(`GET /v3/admin/order/group-batch/summary?productId=2044306857534636034`): ```json { "code": 200, "message": "成功", "data": { "total": 2, "buckets": { "RECRUIT": 1, "FORMED": 1, "PENDING_TRIP": 0, "TRAVELLING": 0, "TRIP_FINISHED": 0, "AUDITING": 0, "CHECKED": 0, "DISBANDED": 0 }, "subOrderCount": 55 }, "success": true } ``` ### 4. 未建团行与孤儿行的交互 **现状**:#7189 起分页在传 productId 时返回三类行,前端尚未区分。 **期望** - `groupBatchId === null`(未建团行,产品建了班期但还没人下单):不渲染展开箭头、不请求子订单、不显示任何团期操作,只放「新增子订单」,跳 `/order-v2/new?productId={productId}&productBatchId={productBatchId}`。对这类行调团期详情、子订单或团期操作,后端会返 589500「团期不存在」。 - `productBatchRemoved === true`(孤儿行,产品侧班期已删但团期仍有活跃子订单):行尾标「班期已删」灰标签,仍可展开看子订单。 - 未建团行的 `chips` 六项固定为 `TODO`,不要当成「有待办」去提醒;它只是零户占位。 ### 5. 芯片红色可解释(依赖后端 #7250) **现状**:芯片只返回一个状态字符串,规则是「只要有一户被打回就整格 ERROR(红)」,优先于「进行中」。现场产品 2044306857534636034 的 10-01 期 55 户活跃单里有 1 户处于「驳回给定制师」,房芯片就整格红,运营看不出是 1 户还是 55 户出问题。 **期望**:wx 2026-09-07 拍板「口径不改,透出计数」。后端 #7250 将在看板列表额外返回 `chipStats.{hotel|vehicle|guide|photo|contract|insurance} = {done, total, error}`(附加对象,`chips` 字符串不变,老前端不受影响)。前端在芯片上加悬停提示:「**已完成 {done}/{total}**」,`error` 大于 0 时追加异常说明——房/车「{error} 户已打回」、约「{error} 户**合同异常**」、保「{error} 户**保险异常**」(或统一「{error} 户异常」)。 > **约/保为什么只写「异常」不写具体原因**(2026-09-07 复审二次修正):后端 `CONTRACT_FAILED = {VOIDING 作废中, VOIDED 已作废}`、`INSURANCE_FAILED = {CANCELLED 已取消, FAILED 投保失败}`,每个都是**两态**。原口径写「合同已作废」「投保失败」会把正在作废的说成已作废、把主动退保的说成投保失败,以偏概全。要精确原因请点进对应芯片明细接口:**约 = GB-ADM-094**(`GET .../chips/contract`)、**保 = GB-ADM-095**(`GET .../chips/insurance`),明细里逐户给 `status` + `statusText`。 注意三点:`done` 是**已完成**户数,不是待办户数,不要写成「{done}/{total} 待配」;这三个数**推不出精确的待配户数**(现场 55 户里 48 户待房务配、1 户配房中、2 户待审核、3 户未开始、1 户打回,仅凭 done=0 / total=55 / error=1 推不出 48),要精确分布请点进该芯片对应的逐户明细(GB-ADM-090~095,房 090 / 车 091 / 导 092 / 摄 093 / 约 094 / 保 095);`error > 0` **不等于**芯片一定是红色——团期已流团、已返团(出行完毕 / 核团中 / 已结算)、或房车导摄未全部完成这三种情况下后端有状态覆盖规则,`error` 仍是真实户数而颜色分别是灰 / 绿 / 灰,颜色请一律以 `chips.X` 为准。字段名与例外矩阵以后端 changelog 为准:`changelogs-v2/2026-09/07_7250_团期看板芯片透出chipStats计数-修改接口-管理后台.md`(PR #7254 已合入 dev-v3 `47c9a6d29`;该篇已于 2026-09-07 通过测试服 AC-1~AC-9 实测并发布,commit `16e0133`)。**依赖已解除,本项可开工。** --- ## 三、契约约束与正确调用方式 > 本篇不新增接口。以下是消费规则速查,字段详情见三份后端 changelog。 | 场景 | 正确做法 | |---|---| | 看板默认加载 | 列表与统计条都带 `productId`,都不传 scope(等于 ONGOING),或都显式传 `scope=ONGOING` | | 用户切范围 | 列表、统计条、导出三处**同时**带新的 `scope` | | 点后段桶页签 | 先把 scope 切成 ALL 再请求,否则必然空列表 | | 未建团行 | 只放「新增子订单」,深链带 `productId` 与 `productBatchId` | | 页签「N 期」徽标 | 直接用 `products` 接口的 `batchCount`,不要用列表 total 反推(默认范围不含已结束期) | | 行标题 | `batchLabel ? 第{batchLabel}期 {batchName} : batchName`,null 必须兜底 | | 剩余房 / 剩余名额 | `null` 表示**不限**,不要按 0 判满员 | --- ## 四、验证方式 改完后在测试服(产品「冻干粉发短信给」)逐条核对: 1. 范围切「全部」,10-01 行标题为「第7期 没,那你」,12-01 行为「第8期 QA-7189-1201」;进详情页头部同样带期号。 2. 默认进入时范围显示「未结束」,Network 里列表与统计条都带 `scope=ONGOING`,两边 total 都是 2;切「全部」后都变 8,与页签「8 期」一致;导出请求带同一个 scope。 3. 在「未结束」下点「出行完毕」,请求变成 `opsStage=TRIP_FINISHED&scope=ALL`,范围下拉自动跳到「全部」。 4. 状态页签共 8 个,顺序为 招募中 / 已成团 / 待出行 / 出行中 / 出行完毕 / 待审核 / 已审核 / 流团;`scope=ALL` 时招募中 7、已成团 1、其余 0。 5. 12-01 期那行没有展开箭头、没有团期操作,只有「新增子订单」,点击跳 `/order-v2/new?productId=2044306857534636034&productBatchId=2096631555760807938`。 --- ## 五、不影响范围 - 后端接口零改动(第 5 项待 #7250)。 - 小程序、H5 不涉及。 - 团期详情页除头部标题外的其它区域不涉及。 - 已修好的「展开行子订单恒空」不要重复改。 --- ## 六、附:现场四问题的排查结论 | 现象 | 结论 | |---|---| | 行标题没有「第7期」 | 前端未跟进(后端三接口都已返 `batchLabel="7"`) | | 「全部期」只剩 2 期 | 前端未跟进(后端默认 `scope=ONGOING` 是 2026-09-06 拍板口径,`scope=ALL` 实测回 8 期) | | 缺「出行完毕」页签 | 前端未跟进(后端固定返 8 桶) | | 房芯片红但「没配房」 | **不是 bug**:红色代表「有户需人工介入」,该团期 55 户里 1 户处于「驳回给定制师」(#7210 验收 AC-22 并发打回的造数单 HL20260907014318542),规则是任一户被打回即整格红,优先于「进行中」。另核对「已订房 54/80 剩 26」三个数字自洽(54+26=80),没有人数与户数混用 | --- ## 联系人 - **后端负责人**: @wx - **前端负责人**: @mmg