文件
hl-api-changelog/changelogs-v2/2026-09/28_8469_团期导摄芯片状态改按团期名册计算-修改接口-管理后台.md
T

1124 行
48 KiB
Markdown
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
---
schema: "hl-changelog/v2"
ticket: "8469"
title: "团期看板导/摄芯片状态改按团期名册计算,合同/保险芯片门控随之变化"
consumer: "admin"
author: "jw(GIT)"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "implemented"
frontend_owner: "mmg"
frontend_ref: "17afce4236ba8157f66f0aa0ffb181e9da60ae35"
target_release: "v2.1"
verified_at: "2026-09-29"
status_note: "PR #8489 已合入 dev-v3(2c87b0618),TEST 的 hl-order-service-v3 运行 dev-v3 2c87b0618;经网关 api.test.1814.love 用真实 admin token 实测 AC-1~AC-6、AC-9 通过(验收脚本 22/22)。5 个接口结构、字段名、枚举值集不变,颜色渲染逻辑不用改;导/摄计数单位由户变为名册位,看板悬停 0/0 与导/摄页签、芯片弹层的按户文案需前端核对(见第四节交接清单),故 frontend_status 记 pending。前端已交付(导/摄汇总行随 #8468 已删;chipStatsTip total=0 改显「无需」),详见 hl-admin v2.1 提交 17afce42。"
updated_at: "2026-09-28"
base: "dev-v3"
---
# 团期看板:导/摄芯片状态改按团期名册计算(管理后台)
> **服务**: hl-order-service-v3(团期看板列表、团期芯片明细)
> **PR**: #8489(合入 dev-v3 为 `2c87b0618`)
> **Issue**: #8469
> **日期**: 2026-09-28
> **影响范围**: 团期看板每行「导 / 摄」芯片颜色与悬停计数、「合同 / 保险」芯片颜色;团期详情「配导游」「配摄影」页签的状态标签与计数;看板点导 / 摄 / 合同 / 保险芯片弹出的明细
---
## ⚠️ 关键变化
1. **导 / 摄芯片改按团期名册算,不再按户**:看板列表的 `records[].chips.guide` / `chips.photo` 与芯片明细 `GET .../chips/guide`、`GET .../chips/photo` 的 `aggregateStatus` 同一口径——团期名册里这一位有人就是 `DONE`;名册没人时,只有「团期已成团、未返团、且团期标记为整团不需要」才是 `DONE`,其余都是 `TODO`。流团恒 `TODO`、已返团恒 `DONE` 两条硬规则不变。完整判定表见六.5。
2. **导 / 摄不再出现 `DOING`**(改前「部分户已指派」是 `DOING`),也不会出现 `ERROR`;`chipStats.guide.error` / `chipStats.photo.error` 恒为 0。
3. **导 / 摄计数单位变了:从「户」变成「名册的这一位」**。`chipStats.guide/photo` 的 `total/done` 与明细的 `totalCount/doneCount` 只有三种取值:名册有人 `total=1, done=1`;成团后整团不需要且名册没人 `total=0, done=0`;其余 `total=1, done=0`。不要再按户数展示,也不要与 `orderCount` 比较。
4. **合同 / 保险芯片的起点随之变化**:「房 / 车 / 导 / 摄四项全部 `DONE` 前,合同 / 保险恒 `TODO`」这条规则现在吃新的导 / 摄结果。整团不需要导摄、或名册已配齐的团不再被导 / 摄卡住;合同 / 保险自身的 `totalCount`、`doneCount`、`chipStats` 与逐户 `items` 不变。
5. **接口结构、字段名、枚举值集全部不变**,颜色映射(`TODO` 灰 / `DOING` 橙 / `DONE` 绿 / `ERROR` 红)照旧。前端要核对的只有按户文案与 0/0 悬停(见第四节「前端交接清单」)。
---
## 一、背景
团期详情导游 / 摄影页签的状态标签、看板导 / 摄芯片颜色和悬停「已完成 done/total」原来都按户算:只统计需要导游 / 摄影的子订单(户),再看每户有没有指派。子订单都「无需」时计入户数为 0,状态就一直是「待开始」,即使团期名册里已经派了人;合同、保险芯片又要等房车导摄四项齐了才开始,于是一起卡住。
测试服实例:团期 `2101506167098511362`(jw测试1期,物料准备中,12 户都无需配导游,名册导游位 2 名领队、摄影位 1 人),改前导游页签显示「待开始 · 共 0 户计入 · 已完成 0 户」,合同芯片 `TODO`(10/12 已签署)、保险芯片 `TODO`(12/12 已出单)。
jw 2026-09-28 定案口径(出自工单 D1~D8,按源码最终实现表述):
| # | 口径 |
|---|---|
| D1 | 团期名册本位(导游位 / 摄影位)有人 → 完成;没人 → 待开始(成团前后的细分见 D5、D6) |
| D2 | 两条硬规则不变:团期已流团 → 待开始;已返团(出行完毕 / 核单中 / 已结算)→ 完成 |
| D3 | 看板列表、团期详情页签、芯片明细接口三处同一口径、同一取值 |
| D4 | 合同 / 保险「房车导摄四项全部完成前恒待开始」,导 / 摄两项改吃 D1 的结果 |
| D5 | 招募中只看名册:有人 → 完成,没人 → 待开始;团期上的「需要导游 / 需要摄影」标记在招募中还没写入(成团时才由子订单汇总写入),不参与判断 |
| D6 | 已成团未返团(资源准备中 / 物料准备中 / 待出发 / 出行中):名册有人 → 完成;名册没人时,团期标记为「不需要」→ 完成,「需要」→ 待开始 |
| D7 | 计数:名册有人 1/1,没人 0/1(done/total);成团后整团不需要且名册没人 → 0/0 |
| D8 | 导游位默认 = 导游 `GUIDE` + 领队 `LEADER`,摄影位 = 摄影 `PHOTOGRAPHER`(与团期人员配置、芯片明细 `staffList` 同一口径);导 / 摄不再有「进行中」,失败数恒 0 |
---
## 二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 团期分页列表(看板,GB-ADM-001) | GET | `/v3/admin/order/group-batch` | 修改:出参取值语义变化 | `records[].chips.guide/photo`、`records[].chipStats.guide/photo` 改按团期名册;`chips.contract/insurance` 门控随之变化;带与不带 `productId` 两条路一致 |
| 2 | 配导游芯片明细(GB-ADM-092) | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/guide` | 修改:出参取值语义变化 | `aggregateStatus`、`totalCount`、`doneCount` 改按团期名册;`items` 仍恒 `[]`,`staffList` 不变 |
| 3 | 配摄影芯片明细(GB-ADM-093) | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/photo` | 修改:出参取值语义变化 | 同 2 |
| 4 | 合同芯片明细(GB-ADM-094) | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/contract` | 修改:出参取值语义变化 | `aggregateStatus` 受新导 / 摄结果门控;`totalCount`、`doneCount`、`items` 不变 |
| 5 | 保险芯片明细(GB-ADM-095) | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/insurance` | 修改:出参取值语义变化 | 同 4 |
---
## 三、接口详情
### 1. 团期分页列表(看板) `GET /v3/admin/order/group-batch`
**VO**: `GroupBatchPageItemRespVO`(`records[]` 元素;芯片字段在内嵌的 `Chips` 与 `ChipStatsMap` / `ChipStats`)
#### 使用场景
团期看板每行的六芯片:颜色取 `records[].chips.X`,悬停「已完成 done/total」取 `records[].chipStats.X`。本单只改其中 `guide`、`photo` 两项的取值,以及 `contract`、`insurance` 两项何时离开 `TODO`。不带 `productId`(全部团期,按建团时间分页)与带 `productId`(产品全班期基底,含未建团的班期行)两条路同一口径。
#### 入参
全部为既有参数,本单未改。
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| productId | Query | Long | 否 | - | 按产品筛选;有值时以产品全班期为基底,含未建团的班期行(`groupBatchId` 为 `null`) |
| batchStatus | Query | String | 否 | 团期九态之一(见六.5) | 团期状态精确筛选 |
| opsStage | Query | String | 否 | `RECRUIT` / `CONFIGURE` / `CONFIRM` / `TRIP` / `REVIEW` / `SETTLE` / `DISBANDED`;非法值忽略 | 看板桶筛选 |
| scope | Query | String | 否 | `ONGOING` / `FINISHED` / `ALL`;非法值忽略 | 班期范围;带 `productId` 时缺省 `ONGOING`,不带时缺省 `ALL` |
| month | Query | String | 否 | `yyyy-MM` | 出发月份 |
| departFrom / departTo | Query | String | 否 | `yyyy-MM-dd`,含当日;非法值忽略 | 出团日期区间 |
| deadlineFrom / deadlineTo | Query | String | 否 | `yyyy-MM-dd` | 报名截止日区间 |
| keyword | Query | String | 否 | - | 班期编号 / 班期名称模糊匹配 |
| sortBy / sortOrder | Query | String | 否 | `departDate` / `enrollDeadline` / `createTime`;`asc` / `desc` | 排序;非白名单值回落默认排序,不报错 |
| pageNo | Query | Integer | 否 | 缺省或小于 1 时按 1 | 页码 |
| pageSize | Query | Integer | 否 | 缺省 20,最大 100(超出截断) | 每页条数 |
#### 出参 `Result<PageResult<GroupBatchPageItemRespVO>>`
| 字段 | 类型 | 说明 |
|------|------|------|
| data.records[].chips.guide / chips.photo | String | **取值变化**:只会是 `TODO` 或 `DONE`,按团期名册判定(判定表见六.5);不再出现 `DOING`、`ERROR` |
| data.records[].chipStats.guide / chipStats.photo | Object | **取值变化**:`{ total, done, error }`,单位是「名册的这一位」:名册有人 `total=1, done=1`;成团后整团不需要且名册没人 `total=0, done=0`;其余 `total=1, done=0`;`error` 恒 0 |
| data.records[].chips.contract / chips.insurance | String | **门控变化**:房 / 车 / 导 / 摄四项全部 `DONE` 前恒 `TODO`,其中导 / 摄取上面的新结果;四项齐后按逐户合同 / 保险状态汇总,汇总规则不变 |
| data.records[].chipStats.contract / chipStats.insurance | Object | 不变:户数,按真实数据统计,不受门控影响 |
| data.records[].chips.hotel / vehicle、chipStats.hotel / vehicle | - | 不变 |
| data.records[] 其余字段、data.total / page / pageSize | - | 不变 |
#### 请求示例
```http
GET /v3/admin/order/group-batch?scope=ALL&pageNo=1&pageSize=100
Authorization: Bearer <admin token>
```
无请求体。按产品看板:`GET /v3/admin/order/group-batch?productId=2101499109901778946&scope=ALL&pageNo=1&pageSize=100`。
#### 响应示例
2026-09-28 18:34 测试服实测(不带 `productId`;本页共 13 行,这里只保留实例团期一行,字段均为原值):
```json
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"groupBatchId": "2101506167098511362",
"productBatchId": "2101502082564407299",
"productId": "2101499109901778946",
"productName": "jw测试产品",
"batchNo": "Q202609272101502082564407298",
"batchName": "jw测试1期",
"batchLabel": "1",
"batchStatus": "MATERIAL_PREPARING",
"batchStatusName": "物料准备中",
"stage": "CONFIRM",
"stageName": "确认",
"tripSubStatus": null,
"tripSubStatusName": null,
"opsStage": "CONFIRM",
"opsStageName": "确认",
"minGroupPeople": 6,
"minToForm": 6,
"maxRooms": 12,
"maxParticipants": 24,
"enrolledPeople": 24,
"enrolledRooms": 12,
"remainRooms": 0,
"remainParticipants": 0,
"orderCount": 12,
"enrollDeadline": "2026-09-26",
"departDate": "2026-09-27",
"endDate": "2026-10-03",
"daysToDepart": -1,
"receivableAmount": "156760.00",
"receivedAmount": "47940.00",
"unpaidAmount": "108820.00",
"chips": {
"hotel": "DONE",
"vehicle": "DONE",
"guide": "DONE",
"photo": "DONE",
"contract": "DOING",
"insurance": "DONE"
},
"chipStats": {
"hotel": {
"total": 12,
"done": 12,
"error": 0
},
"vehicle": {
"total": 12,
"done": 12,
"error": 0
},
"guide": {
"total": 1,
"done": 1,
"error": 0
},
"photo": {
"total": 1,
"done": 1,
"error": 0
},
"contract": {
"total": 12,
"done": 10,
"error": 0
},
"insurance": {
"total": 12,
"done": 12,
"error": 0
}
},
"productBatchStatus": null,
"productBatchStatusLabel": null,
"productBatchStatusName": null,
"productBatchRemoved": null
}
],
"total": 13,
"page": 1,
"pageSize": 100
},
"traceId": null,
"success": true
}
```
改前(同一请求,18:00 实测)这一行的芯片部分:
```json
{
"groupBatchId": "2101506167098511362",
"batchStatus": "MATERIAL_PREPARING",
"chips": {
"hotel": "DONE",
"vehicle": "DONE",
"guide": "TODO",
"photo": "TODO",
"contract": "TODO",
"insurance": "TODO"
},
"chipStats": {
"hotel": {
"total": 12,
"done": 12,
"error": 0
},
"vehicle": {
"total": 12,
"done": 12,
"error": 0
},
"guide": {
"total": 0,
"done": 0,
"error": 0
},
"photo": {
"total": 0,
"done": 0,
"error": 0
},
"contract": {
"total": 12,
"done": 10,
"error": 0
},
"insurance": {
"total": 12,
"done": 12,
"error": 0
}
}
}
```
#### 空数据 / 降级响应
- 本页没有团期时 `records: []`,不做芯片计算。
- 带 `productId` 时,未建团的班期行(`groupBatchId` 为 `null`)导 / 摄恒 `TODO`、`total=1, done=0`(改前为 `total=0, done=0`);房 / 车 / 合同 / 保险计数仍为 0。实测片段(同一产品另一期):
```json
{
"groupBatchId": null,
"productBatchId": "2101502082795143171",
"batchName": "jw测试2期",
"batchStatus": "RECRUITING",
"orderCount": 0,
"chips": {
"hotel": "TODO",
"vehicle": "TODO",
"guide": "TODO",
"photo": "TODO",
"contract": "TODO",
"insurance": "TODO"
},
"chipStats": {
"hotel": {
"total": 0,
"done": 0,
"error": 0
},
"vehicle": {
"total": 0,
"done": 0,
"error": 0
},
"guide": {
"total": 1,
"done": 0,
"error": 0
},
"photo": {
"total": 1,
"done": 0,
"error": 0
},
"contract": {
"total": 0,
"done": 0,
"error": 0
},
"insurance": {
"total": 0,
"done": 0,
"error": 0
}
}
}
```
- 团期里没有活跃子订单时:房 / 车 / 合同 / 保险计数为 0(不变);导 / 摄仍按名册与团期标记判定,例如成团后整团不需要且名册没人为 `DONE`、`total=0, done=0`。
#### 错误响应
错误码未改动。角色未授予 `group-batch:list`:
```json
{
"code": 589507,
"message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)",
"data": null,
"success": false
}
```
未登录由网关拦截,HTTP 200、业务码 401(测试服实测文案「缺少有效的 Authorization 头」)。
#### 业务边界
- 判权未改:`group-batch:list`,无权限 589507。
- 导 / 摄只看团期名册、团期状态与团期「需要导游 / 需要摄影」标记,不看任何一户子订单的需要标记或指派情况。
- 流团(`batchStatus=CANCELLED`):六芯片恒 `TODO`;导 / 摄计数照实,名册有人时会出现 `chips.guide=TODO` 而 `chipStats.guide` 为 `total=1, done=1`,属正常。
- 已返团(`TRIP_FINISHED` / `REVIEWING` / `SETTLED`):导 / 摄恒 `DONE`;名册没人且团期需要时计数为 `total=1, done=0`,属正常。
- 颜色一律以 `chips.X` 为准,`chipStats` 只用来解释(与 #7250 口径相同)。
- 名册增删人员后,下一次请求即按新名册计算。
- 本接口只读。
### 2. 配导游芯片明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/guide`
**VO**: `GroupBatchChipDetailVO`
#### 使用场景
团期详情「配导游」页签的状态标签与计数、看板点导游芯片弹出的明细。本接口 `aggregateStatus` 与看板同一行 `chips.guide` 同值,`doneCount` / `totalCount` 与 `chipStats.guide.done` / `chipStats.guide.total` 同值。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| groupBatchId | Path | Long | 是 | 运营团期 ID | 路由上的团期 ID(既有,未改) |
#### 出参 `Result<GroupBatchChipDetailVO>`
| 字段 | 类型 | 说明 |
|------|------|------|
| batchId / groupBatchId | String | 团期 ID(`batchId` 已废弃,同值;不变) |
| chipLabel | String | 「配导游」(不变) |
| aggregateStatus / aggregateStatusName | String | **取值变化**:只会是 `TODO`「待开始」或 `DONE`「已完成」,按团期名册判定(判定表见六.5);改前按户,可为 `DOING`「进行中」 |
| totalCount | Integer | **取值变化**:名册导游位有人为 1;没人时,成团后整团不需要为 0,其余为 1。改前是需要导游的户数 |
| doneCount | Integer | **取值变化**:名册导游位有人为 1,否则 0。改前是已指派导游的户数 |
| staffList | Object[] | 不变:本团导游位已配置人员;元素字段 `staffId`、`staffRole`、`staffRoleName`、`staffName`、`staffPhone`(脱敏)、`reporterRank`、`reporterRankName`、`source`、`sourceName`;未配置为 `[]` |
| items | Object[] | 不变:恒为 `[]`(#8468 起) |
#### 请求示例
```http
GET /v3/admin/order/group-batch/2101506167098511362/chips/guide
Authorization: Bearer <admin token>
```
无请求体。
#### 响应示例
2026-09-28 18:34 测试服实测,实例团期(12 户都无需配导游,名册导游位 2 名领队)。改前同一请求 `aggregateStatus` 为 `TODO`「待开始」、`totalCount=0`、`doneCount=0`,其余字段相同。
```json
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2101506167098511362",
"groupBatchId": "2101506167098511362",
"chipLabel": "配导游",
"aggregateStatus": "DONE",
"aggregateStatusName": "已完成",
"totalCount": 1,
"doneCount": 1,
"staffList": [
{
"staffId": "1011",
"staffRole": "LEADER",
"staffRoleName": "领队",
"staffName": "巴特尔",
"staffPhone": "139****1011",
"reporterRank": "PRIMARY",
"reporterRankName": "主报账人",
"source": null,
"sourceName": null
},
{
"staffId": "1008",
"staffRole": "LEADER",
"staffRoleName": "领队",
"staffName": "萨仁高娃",
"staffPhone": "139****1008",
"reporterRank": "NONE",
"reporterRankName": "非报账人",
"source": null,
"sourceName": null
}
],
"items": []
},
"traceId": null,
"success": true
}
```
#### 空数据 / 降级响应
名册导游位没人时 `staffList: []`、`items: []`,状态与计数看团期状态和团期标记。三种实测:
成团后整团不需要、名册没人(团期 `2100856430494973953`,资源准备中)→ `DONE`,`totalCount=0`、`doneCount=0`:
```json
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2100856430494973953",
"groupBatchId": "2100856430494973953",
"chipLabel": "配导游",
"aggregateStatus": "DONE",
"aggregateStatusName": "已完成",
"totalCount": 0,
"doneCount": 0,
"staffList": [],
"items": []
},
"traceId": null,
"success": true
}
```
成团后团期需要导游、名册没人(造数团期 H,资源准备中)→ `TODO`,`totalCount=1`、`doneCount=0`(`data` 部分):
```json
{
"batchId": "2104511888882868226",
"groupBatchId": "2104511888882868226",
"chipLabel": "配导游",
"aggregateStatus": "TODO",
"aggregateStatusName": "待开始",
"totalCount": 1,
"doneCount": 0,
"staffList": [],
"items": []
}
```
流团后名册仍有人(同一团期 H 流团后)→ 恒 `TODO`,计数照实 `totalCount=1`、`doneCount=1`(`data` 部分):
```json
{
"batchId": "2104511888882868226",
"groupBatchId": "2104511888882868226",
"chipLabel": "配导游",
"aggregateStatus": "TODO",
"aggregateStatusName": "待开始",
"totalCount": 1,
"doneCount": 1,
"staffList": [
{
"staffId": "1002",
"staffRole": "GUIDE",
"staffRoleName": "导游",
"staffName": "李雪梅",
"staffPhone": "138****1002",
"reporterRank": "NONE",
"reporterRankName": "非报账人",
"source": null,
"sourceName": null
}
],
"items": []
}
```
#### 错误响应
错误码未改动:团期不存在 589500,无权限 589507。未登录(测试服实测,网关返回 HTTP 200、业务码 401):
```json
{
"code": 401,
"message": "缺少有效的 Authorization 头",
"data": null,
"traceId": "8f16889e7bc64740",
"success": false
}
```
#### 业务边界
- 判权未改:`group-batch:view`,无权限 589507;团期不存在 589500。
- 导游位收哪些角色以配置位字典为准,默认导游 `GUIDE` + 领队 `LEADER`;与 `staffList` 同一口径,所以 `staffList` 非空 ⇔ `doneCount=1`。
- 招募中不看团期标记:名册没人一律 `TODO`、`totalCount=1`、`doneCount=0`。
- 流团恒 `TODO`(计数照实,可能 1/1);已返团恒 `DONE`(计数照实,可能 0/1 或 0/0);成团后才流团的团期名册没人时计数为 `totalCount=1`、`doneCount=0`,不是 0/0。
- `items` 恒 `[]`,不要用逐户数据推导本芯片状态。
- 本接口只读。
### 3. 配摄影芯片明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/photo`
**VO**: `GroupBatchChipDetailVO`
#### 使用场景
团期详情「配摄影」页签的状态标签与计数、看板点摄影芯片弹出的明细。本接口 `aggregateStatus` 与看板同一行 `chips.photo` 同值,`doneCount` / `totalCount` 与 `chipStats.photo.done` / `chipStats.photo.total` 同值。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| groupBatchId | Path | Long | 是 | 运营团期 ID | 路由上的团期 ID(既有,未改) |
#### 出参 `Result<GroupBatchChipDetailVO>`
| 字段 | 类型 | 说明 |
|------|------|------|
| batchId / groupBatchId | String | 团期 ID(`batchId` 已废弃,同值;不变) |
| chipLabel | String | 「配摄影」(不变) |
| aggregateStatus / aggregateStatusName | String | **取值变化**:只会是 `TODO`「待开始」或 `DONE`「已完成」,按团期名册判定(判定表见六.5);改前按户,可为 `DOING`「进行中」 |
| totalCount | Integer | **取值变化**:名册摄影位有人为 1;没人时,成团后整团不需要为 0,其余为 1。改前是需要摄影的户数 |
| doneCount | Integer | **取值变化**:名册摄影位有人为 1,否则 0。改前是已指派摄影的户数 |
| staffList | Object[] | 不变:本团摄影位已配置人员;元素字段同接口 2(`staffId`、`staffRole`、`staffRoleName`、`staffName`、`staffPhone`(脱敏)、`reporterRank`、`reporterRankName`、`source`、`sourceName`);未配置为 `[]` |
| items | Object[] | 不变:恒为 `[]`(#8468 起) |
#### 请求示例
```http
GET /v3/admin/order/group-batch/2101506167098511362/chips/photo
Authorization: Bearer <admin token>
```
无请求体。
#### 响应示例
2026-09-28 18:34 测试服实测,实例团期(12 户都无需配摄影,名册摄影位 1 人)。改前同一请求 `aggregateStatus` 为 `TODO`「待开始」、`totalCount=0`、`doneCount=0`,其余字段相同。
```json
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2101506167098511362",
"groupBatchId": "2101506167098511362",
"chipLabel": "配摄影",
"aggregateStatus": "DONE",
"aggregateStatusName": "已完成",
"totalCount": 1,
"doneCount": 1,
"staffList": [
{
"staffId": "1003",
"staffRole": "PHOTOGRAPHER",
"staffRoleName": "摄影",
"staffName": "王强",
"staffPhone": "138****1003",
"reporterRank": "NONE",
"reporterRankName": "非报账人",
"source": null,
"sourceName": null
}
],
"items": []
},
"traceId": null,
"success": true
}
```
#### 空数据 / 降级响应
名册摄影位没人时 `staffList: []`、`items: []`。招募中团期摄影位没人(团期 `2104491315645538305`,团期标记在招募中为 0,也不算「不需要」)→ `TODO`,`totalCount=1`、`doneCount=0`:
```json
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2104491315645538305",
"groupBatchId": "2104491315645538305",
"chipLabel": "配摄影",
"aggregateStatus": "TODO",
"aggregateStatusName": "待开始",
"totalCount": 1,
"doneCount": 0,
"staffList": [],
"items": []
},
"traceId": null,
"success": true
}
```
成团后整团不需要且名册没人时为 `DONE`、`totalCount=0`、`doneCount=0`(与接口 2 同形)。
#### 错误响应
错误码未改动:团期不存在 589500,无权限 589507。
```json
{
"code": 589500,
"message": "团期不存在",
"data": null,
"success": false
}
```
#### 业务边界
- 判权未改:`group-batch:view`,无权限 589507;未登录由网关返回业务码 401。
- 摄影位收哪些角色以配置位字典为准,默认只收摄影 `PHOTOGRAPHER`;与 `staffList` 同一口径,所以 `staffList` 非空 ⇔ `doneCount=1`。
- 招募中不看团期标记:名册没人一律 `TODO`、`totalCount=1`、`doneCount=0`。
- 流团恒 `TODO`(计数照实);已返团恒 `DONE`(计数照实)。
- `items` 恒 `[]`,不要用逐户数据推导本芯片状态。
- 本接口只读。
### 4. 合同芯片明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/contract`
**VO**: `GroupBatchChipDetailVO`(逐户项 `GroupBatchChipItemRespVO`)
#### 使用场景
看板点合同芯片弹出的逐户合同明细,以及团期详情里的合同芯片面板。本接口 `aggregateStatus` 与看板同一行 `chips.contract` 同值。本单只改「何时离开 `TODO`」,逐户内容与计数不变。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| groupBatchId | Path | Long | 是 | 运营团期 ID | 路由上的团期 ID(既有,未改) |
#### 出参 `Result<GroupBatchChipDetailVO>`
| 字段 | 类型 | 说明 |
|------|------|------|
| batchId / groupBatchId | String | 团期 ID(`batchId` 已废弃,同值;不变) |
| chipLabel | String | 「合同」(不变) |
| aggregateStatus / aggregateStatusName | String | **门控变化**:房 / 车 / 导 / 摄四项未全部 `DONE` 时恒 `TODO`「待开始」,其中导 / 摄改用团期名册结果;四项齐后按逐户合同状态汇总(汇总规则不变):有作废中 / 已作废 → `ERROR`;全部已签署 → `DONE`;有待出具 / 已生成 / 已上报 / 已上传 / 签署中 → `DOING`;否则 `TODO` |
| totalCount | Integer | 不变:活跃子订单数(合同每户都计入) |
| doneCount | Integer | 不变:已签署户数 |
| staffList | - | 不变:恒 `null` |
| items | Object[] | 不变:逐户合同状态;元素字段 `orderId`、`orderNo`、`teamNo`、`contactName`(已废弃)/ `customerName`、`peopleCount`、`status`、`statusText`(已废弃)/ `statusName`、`needsIt`(恒 true)、`updateTime`、`claimerId`、`claimerName`、`claimerSource`、`staffs`(恒 `null`) |
#### 请求示例
```http
GET /v3/admin/order/group-batch/2101506167098511362/chips/contract
Authorization: Bearer <admin token>
```
无请求体。
#### 响应示例
2026-09-28 18:34 测试服实测,实例团期(房 / 车 12/12 已完成,导 / 摄按名册已完成,四项齐;10/12 已签署)。`items` 共 12 户,这里只保留前 2 户,其余字段原值。改前同一请求 `aggregateStatus` 为 `TODO`「待开始」(被按户的导 / 摄卡住),计数与 `items` 相同。
```json
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2101506167098511362",
"groupBatchId": "2101506167098511362",
"chipLabel": "合同",
"aggregateStatus": "DOING",
"aggregateStatusName": "进行中",
"totalCount": 12,
"doneCount": 10,
"staffList": null,
"items": [
{
"orderId": "2101506167043985410",
"orderNo": "HL20260920105808925",
"teamNo": "26-3627",
"contactName": "张建国",
"customerName": "张建国",
"peopleCount": 6,
"status": "SIGNED",
"statusText": "已签署",
"statusName": "已签署",
"needsIt": true,
"updateTime": null,
"claimerId": "1001",
"claimerName": "admin",
"claimerSource": "BATCH",
"staffs": null
},
{
"orderId": "2101507276118626306",
"orderNo": "HL20260920110233355",
"teamNo": "26-0750",
"contactName": "王志强",
"customerName": "王志强",
"peopleCount": 2,
"status": "SIGNED",
"statusText": "已签署",
"statusName": "已签署",
"needsIt": true,
"updateTime": null,
"claimerId": "1001",
"claimerName": "admin",
"claimerSource": "BATCH",
"staffs": null
}
]
},
"traceId": null,
"success": true
}
```
#### 空数据 / 降级响应
- 团期没有活跃子订单:`totalCount=0`、`doneCount=0`、`items: []`、`aggregateStatus` 为 `TODO`(不变)。
- 导 / 摄仍未齐时恒 `TODO`。实测:造数团期 H 已配导游、未配摄影,合同芯片 `TODO`:
```json
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2104511888882868226",
"groupBatchId": "2104511888882868226",
"chipLabel": "合同",
"aggregateStatus": "TODO",
"aggregateStatusName": "待开始",
"totalCount": 1,
"doneCount": 0,
"staffList": null,
"items": [
{
"orderId": "2104511888652181506",
"orderNo": "HL20260928180148673",
"teamNo": null,
"contactName": "巴图孟和",
"customerName": "巴图孟和",
"peopleCount": 2,
"status": null,
"statusText": "无合同",
"statusName": "无合同",
"needsIt": true,
"updateTime": null,
"claimerId": null,
"claimerName": null,
"claimerSource": null,
"staffs": null
}
]
},
"traceId": null,
"success": true
}
```
#### 错误响应
错误码未改动:团期不存在 589500,无权限 589507。
```json
{
"code": 589507,
"message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)",
"data": null,
"success": false
}
```
#### 业务边界
- 判权未改:`group-batch:view`,无权限 589507;团期不存在 589500;未登录由网关返回业务码 401。
- 门控只影响 `aggregateStatus`:门控期间 `totalCount`、`doneCount`、`items` 照实,可能出现 `doneCount=totalCount` 而 `aggregateStatus=TODO`,属正常。
- 流团恒 `TODO`;已返团时房 / 车 / 导 / 摄恒 `DONE`,合同按逐户汇总(不变)。
- 整团不需要导摄的团(成团后、名册没人、团期标记为不需要)不再因导 / 摄卡在 `TODO`,只要房 / 车也已 `DONE` 即按逐户合同状态显示。
- 本接口只读。
### 5. 保险芯片明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/insurance`
**VO**: `GroupBatchChipDetailVO`(逐户项 `GroupBatchChipItemRespVO`)
#### 使用场景
看板点保险芯片弹出的逐户保险明细,以及团期详情里的保险芯片面板。本接口 `aggregateStatus` 与看板同一行 `chips.insurance` 同值。本单只改「何时离开 `TODO`」,逐户内容与计数不变。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| groupBatchId | Path | Long | 是 | 运营团期 ID | 路由上的团期 ID(既有,未改) |
#### 出参 `Result<GroupBatchChipDetailVO>`
| 字段 | 类型 | 说明 |
|------|------|------|
| batchId / groupBatchId | String | 团期 ID(`batchId` 已废弃,同值;不变) |
| chipLabel | String | 「保险」(不变) |
| aggregateStatus / aggregateStatusName | String | **门控变化**:房 / 车 / 导 / 摄四项未全部 `DONE` 时恒 `TODO`「待开始」,其中导 / 摄改用团期名册结果;四项齐后按逐户保险状态汇总(汇总规则不变):有已取消 / 出单失败 → `ERROR`;全部已出单 → `DONE`;有出单中 → `DOING`;否则 `TODO` |
| totalCount | Integer | 不变:活跃子订单数(保险每户都计入) |
| doneCount | Integer | 不变:已出单户数 |
| staffList | - | 不变:恒 `null` |
| items | Object[] | 不变:逐户保险状态;元素字段同接口 4 |
#### 请求示例
```http
GET /v3/admin/order/group-batch/2101506167098511362/chips/insurance
Authorization: Bearer <admin token>
```
无请求体。
#### 响应示例
2026-09-28 18:34 测试服实测,实例团期(四项齐,12/12 已出单)。`items` 共 12 户,这里只保留前 2 户,其余字段原值。改前同一请求 `aggregateStatus` 为 `TODO`「待开始」,计数与 `items` 相同。
```json
{
"code": 200,
"message": "成功",
"data": {
"batchId": "2101506167098511362",
"groupBatchId": "2101506167098511362",
"chipLabel": "保险",
"aggregateStatus": "DONE",
"aggregateStatusName": "已完成",
"totalCount": 12,
"doneCount": 12,
"staffList": null,
"items": [
{
"orderId": "2101506167043985410",
"orderNo": "HL20260920105808925",
"teamNo": "26-3627",
"contactName": "张建国",
"customerName": "张建国",
"peopleCount": 6,
"status": "INSURED",
"statusText": "已出单",
"statusName": "已出单",
"needsIt": true,
"updateTime": null,
"claimerId": "1001",
"claimerName": "admin",
"claimerSource": "BATCH",
"staffs": null
},
{
"orderId": "2101507276118626306",
"orderNo": "HL20260920110233355",
"teamNo": "26-0750",
"contactName": "王志强",
"customerName": "王志强",
"peopleCount": 2,
"status": "INSURED",
"statusText": "已出单",
"statusName": "已出单",
"needsIt": true,
"updateTime": null,
"claimerId": "1001",
"claimerName": "admin",
"claimerSource": "BATCH",
"staffs": null
}
]
},
"traceId": null,
"success": true
}
```
#### 空数据 / 降级响应
- 团期没有活跃子订单:`totalCount=0`、`doneCount=0`、`items: []`、`aggregateStatus` 为 `TODO`(不变)。
- 房 / 车 / 导 / 摄未齐时恒 `TODO`,计数照实(与接口 4 同形)。
#### 错误响应
错误码未改动:团期不存在 589500,无权限 589507。
```json
{
"code": 589500,
"message": "团期不存在",
"data": null,
"success": false
}
```
#### 业务边界
- 判权未改:`group-batch:view`,无权限 589507;团期不存在 589500;未登录由网关返回业务码 401。
- 门控只影响 `aggregateStatus`:门控期间计数与 `items` 照实,可能出现 `doneCount=totalCount` 而 `aggregateStatus=TODO`,属正常(实例团期改前即 12/12 却 `TODO`)。
- 流团恒 `TODO`;已返团时按逐户汇总(不变)。
- 本接口只读。
---
## 四、契约约束与正确调用方式
> 5 个接口均为 GET、入参未改;本节写取值的正确读法。
### ✅ 正确 / ❌ 错误读法对照
| 场景 | 读法 |
|------|------|
| ✅ 芯片颜色 | 列表取 `chips.X`,明细取 `aggregateStatus`;四值映射不变 |
| ✅ 导 / 摄「名册有没有人」 | 明细 `staffList` 是否非空,或 `doneCount=1` / `chipStats.X.done=1`(三者恒一致) |
| ✅ 识别「整团不需要」 | 导 / 摄 `total=0`(明细 `totalCount=0`):此时状态必为 `DONE`,含义是已成团(含已返团)、团期标记为不需要、名册没人 |
| ❌ 把导 / 摄计数当户数 | 「共 N 户计入 · 已完成 N 户」对导 / 摄不成立,两个数只会是 0 或 1 |
| ❌ 用逐户数据推导导 / 摄状态 | 导 / 摄 `items` 恒 `[]`;子订单上的需要导游 / 摄影标记不参与判定 |
| ❌ 用 `chipStats` 推颜色 | 流团时 `TODO` 可与 1/1 并存,已返团时 `DONE` 可与 0/1 并存,合同 / 保险门控期间 `TODO` 可与 12/12 并存 |
### 前端交接清单
1. **颜色**:不用改。`chips.guide/photo` 只会出现 `TODO` / `DONE`,合同 / 保险仍是四值。
2. **看板悬停**(hl-ui `src/views/order-v2/batch/_shared/batchLifecycle.js` 的 `chipStatsTip`):导 / 摄会显示「已完成 1/1」「已完成 0/1」「已完成 0/0」,数字是名册这一位,不是户数。0/0 时芯片为绿色(整团不需要),当前会原样显示「已完成 0/0」——这是本契约的正常取值;若要更直观,可对导 / 摄 `total=0`(此时必为 `DONE`)改显示「无需」。
3. **导 / 摄页签与芯片弹层汇总行**(hl-ui `src/views/order-v2/batch/detail/components/ChipItemsPanel.vue`、`src/views/order-v2/batch/components/ChipDetailModal.vue` 的「共 {totalCount} 户计入 · 已完成 {doneCount} 户」):对导 / 摄这两个数不再是户数。若按 #8468 交接清单第 6 项已对导 / 摄去掉该行,无需再动;若仍在,请对导 / 摄隐藏该行或改为按名册展示(如「已配置 N 人」取 `staffList.length`,`totalCount=0` 显示「无需」)。状态标签照用 `aggregateStatus`。房 / 车 / 合同 / 保险的汇总行不变。
4. **合同 / 保险**:不用改。整团不需要导摄或名册已配齐的团,合同 / 保险芯片会比改前更早离开 `TODO`,属预期。
5. 不需要新增请求或字段。
---
## 五、数据库行为
本单 5 个接口均为只读查询,零写入;不含数据迁移,不改存量数据。
---
## 六、边界行为
- 未登录 → 网关拦截,HTTP 200、业务码 401(既有,测试服实测)。
- 无权限 → 589507(列表 `group-batch:list`,明细 `group-batch:view`,既有)。
- 团期不存在 → 589500(芯片明细,既有)。
- 未建团的班期行(仅带 `productId` 的列表)→ 导 / 摄 `TODO`、`total=1, done=0`;该行没有 `groupBatchId`,调不到芯片明细。
- 团期状态缺失(历史脏数据)→ 导 / 摄名册有人 `DONE`(1/1),否则 `TODO`(0/1)。
- 成团后才流团 → 恒 `TODO`;名册没人时计数 0/1,不是 0/0。
- 导 / 摄从不出现 `DOING`、`ERROR`;`chipStats.guide/photo.error` 恒 0。
- 向后兼容:结构不变,旧前端不改也能按新值正确着色;只是导 / 摄的按户文案不再准确(见第四节)。
---
## 六.5、枚举 / 数据字典
### 芯片聚合态(常量定义于 `com.hulalv.order.groupbatch.helper.GroupBatchChipResolver`)
**所属字段**: `GroupBatchPageItemRespVO.Chips.*`、`GroupBatchChipDetailVO.aggregateStatus` | **类型**: `String`
| 值 | 中文 | 说明 |
|----|------|------|
| `TODO` | 待开始 | 导 / 摄:见下方判定表;合同 / 保险:四项未齐时恒为此值 |
| `DOING` | 进行中 | 导 / 摄本单起不再出现;房 / 车 / 合同 / 保险规则不变 |
| `DONE` | 已完成 | 导 / 摄:见下方判定表 |
| `ERROR` | 异常 | 导 / 摄从不出现;房 / 车 / 合同 / 保险规则不变 |
### 导 / 摄判定表(按优先级从上往下,命中即止;计数写作 done/total)
| 团期状态 | 名册本位 | 团期「需要」标记 | 状态 | 计数 |
|----------|----------|------------------|------|------|
| 流团 `CANCELLED` | 有人 | 不看 | `TODO` | 1/1 |
| 流团 `CANCELLED` | 没人 | 不看 | `TODO` | 0/1 |
| 已返团 `TRIP_FINISHED` / `REVIEWING` / `SETTLED` | 有人 | 不看 | `DONE` | 1/1 |
| 已返团 | 没人 | 需要 | `DONE` | 0/1 |
| 已返团 | 没人 | 不需要 | `DONE` | 0/0 |
| 任意其他状态(含招募中) | 有人 | 不看 | `DONE` | 1/1 |
| 已成团未返团 `RESOURCE_PREPARING` / `MATERIAL_PREPARING` / `PENDING_DEPARTURE` / `TRAVELLING` | 没人 | 不需要 | `DONE` | 0/0 |
| 已成团未返团 | 没人 | 需要 | `TODO` | 0/1 |
| 招募中 `RECRUITING` | 没人 | 不看 | `TODO` | 0/1 |
| 未建团的班期行(仅带 `productId` 的列表) | 没人 | 无 | `TODO` | 0/1 |
### batchStatus(`com.hulalv.order.groupbatch.enums.GroupBatchStatus`)
**所属字段**: `GroupBatchPageItemRespVO.batchStatus` | **类型**: `String`
| 值 | 中文 | 导 / 摄判定分组 |
|----|------|------|
| `RECRUITING` | 招募中 | 招募中:只看名册 |
| `RESOURCE_PREPARING` | 资源准备中 | 已成团未返团 |
| `MATERIAL_PREPARING` | 物料准备中 | 已成团未返团 |
| `PENDING_DEPARTURE` | 待出发 | 已成团未返团 |
| `TRAVELLING` | 出行中 | 已成团未返团 |
| `TRIP_FINISHED` | 出行完毕 | 已返团 |
| `REVIEWING` | 核单中 | 已返团 |
| `SETTLED` | 已结算 | 已返团 |
| `CANCELLED` | 已取消(流团) | 流团 |
### 配置位成员(`com.hulalv.order.assignment.constants.GroupBatchStaffSlot`)
**所属字段**: 决定 `staffList` 与导 / 摄「名册本位有没有人」 | **类型**: `String`(`staffRole`)
| 配置位 | 默认成员 | 说明 |
|--------|----------|------|
| 导游位 | `GUIDE` 导游、`LEADER` 领队 | 以配置位字典为准,字典读不到时用默认成员 |
| 摄影位 | `PHOTOGRAPHER` 摄影 | 同上 |
| - | 司机、其他 | 不属于任何配置位,不算导 / 摄有人 |
---
## 六.6、修改前后对比
### 字段级对比
| 字段 | 改前 | 改后 |
|------|------|------|
| `chips.guide` / `chips.photo`,导 / 摄明细 `aggregateStatus` | 按户(#7204):无计入户 `TODO`;计入户零指派 `TODO`;部分指派 `DOING`;全部指派 `DONE` | 按团期名册:只有 `TODO` / `DONE`,判定见六.5 |
| `chipStats.guide/photo.total`,导 / 摄明细 `totalCount` | 需要导游 / 摄影的户数 | 名册这一位:1;成团后整团不需要且名册没人时为 0 |
| `chipStats.guide/photo.done`,导 / 摄明细 `doneCount` | 已指派的户数 | 名册有人 1,否则 0 |
| `chipStats.guide/photo.error` | 恒 0 | 恒 0(不变) |
| `chips.contract/insurance`,合同 / 保险明细 `aggregateStatus` | 四项齐判定用按户的导 / 摄结果 | 用按名册的导 / 摄结果 |
### 行为级对比(测试服部署前后同一批只读请求;计数写作 done/total)
| 场景 | 改前 | 改后 |
|------|------|------|
| 实例团期 `2101506167098511362`(物料准备中,12 户都无需导摄,名册导游位 2 人、摄影位 1 人)导 / 摄 | `TODO` 0/0 | `DONE` 1/1 |
| 同上 · 合同 | `TODO` 10/12 | `DOING` 10/12 |
| 同上 · 保险 | `TODO` 12/12 | `DONE` 12/12 |
| 招募中团期 `2104491315645538305`(导游位有人、摄影位没人) | 导 / 摄 `TODO` 0/0 | 导游 `DONE` 1/1,摄影 `TODO` 0/1 |
| 成团后整团不需要、名册空的团期(部署前后都在列表里的 8 个) | 导 / 摄 `TODO` 0/0 | 导 / 摄 `DONE` 0/0 |
| 带 `productId` 的未建团班期行(实例产品下 15 行) | 导 / 摄 `TODO` 0/0 | 导 / 摄 `TODO` 0/1 |
| 团期 `2104490621953794050`(2 户都需要导摄且已指派,名册导游位、摄影位各 1 人) | 导 / 摄 `DONE` 2/2(户) | 导 / 摄 `DONE` 1/1(名册位) |
| 部分户已指派 | 导 / 摄 `DOING` | 不再出现;名册有人即 `DONE` |
| 房 / 车芯片(看板 11 行) | - | 部署前后逐字段一致 |
---
## 六.7、影响评估
- **是否破坏向后兼容**: 否。结构、字段名、枚举值集不变;但导 / 摄计数的含义由户数变为名册位,按户展示的文案会不准确(见第四节交接清单第 2、3 项)。
- **前端是否必须同步上线**: 否。颜色随新值自然变化;文案核对不影响功能。
- **前端 workaround 清理点**: 若前端为导 / 摄 `DOING`「部分户已指派」写过专门的图例或提示,可删;导 / 摄汇总行里的「户」字样可删。
---
## 七、不影响范围
- **仅影响**: 看板列表 `chips` / `chipStats` 的导、摄两项取值与合同、保险两项的门控;导、摄、合同、保险四个芯片明细的 `aggregateStatus` 与导 / 摄计数。
- **零影响**:
- 配房、配车芯片明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/hotel`、`GET /v3/admin/order/group-batch/{groupBatchId}/chips/vehicle`,以及看板 `chips.hotel/vehicle`、`chipStats.hotel/vehicle`(测试服部署前后逐字段一致)
- 合同 / 保险芯片的 `totalCount`、`doneCount`、`chipStats`、逐户 `items`
- 团期详情 `GET /v3/admin/order/group-batch/{groupBatchId}` 的进度条 `progressStepper`(#8478,按确认门就绪标记计算)及其余字段
- 合并层看板 `GET /v3/admin/order/group-batch/board`
- 团期人员配置(保存 / 名册 / 更换 / 删除 / 候选)接口
- 子订单上的需要导游 / 摄影标记与订单侧人员指派数据(不再参与芯片判定,数据本身不变)
---
## 八、测试环境已验证
- **环境**:TEST,`hl-order-service-v3` 运行 dev-v3 `2c87b0618`(PR #8489 合入,2026-09-28 18:33 双实例滚动完成)。
- **方式**:经网关 `https://api.test.1814.love`,真实 admin token;构建身份探针命中(实例团期导游芯片由 `TODO` 0/0 变为 `DONE` 1/1)。手机号均为接口脱敏值。
- **部署前后对照**:同一批只读请求,证据为会话证据 accept8469/PROBE-before.json 与 accept8469/PROBE-after.json,结果见六.6 行为级对比。
- **造数**:团期 H「11月20日海拉尔-满洲里3日团」(团期 ID `2104511888882868226`,1 张订单,成团前只对这张单置需要导游 / 摄影),验收后已流团、订单已取消;其余团期只读。
| AC | 检验点 | 结果 | 证据 |
|----|--------|------|------|
| 1 | 实例团期导 / 摄:明细 `DONE` 1/1;看板不带 `productId`、带 `productId` 两条路同为 `DONE` 1/1,三处一致 | ✅ | 会话证据 accept8469/AC-1.json |
| 2 | 招募中团期:导游位有人 `DONE` 1/1、摄影位没人 `TODO` 0/1(团期标记为 0 也不算不需要),看板与明细一致;实例产品下 15 个未建团行导 / 摄均 `TODO` 0/1 | ✅ | 会话证据 accept8469/AC-2.json、accept8469/PROBE-after.json |
| 3 | 成团后整团不需要、名册空的 9 个团期看板导 / 摄均 `DONE` 0/0,抽样明细一致;团期 H(资源准备中,团期需要导摄、名册空)导 / 摄 `TODO` 0/1,看板与明细一致 | ✅ | 会话证据 accept8469/AC-3.json |
| 4 | 团期 H 流团后名册仍有 2 人,导 / 摄恒 `TODO`(计数 1/1 照实);测试服没有已返团团期可取证,已返团三态由单测矩阵覆盖(出行完毕 / 核单中 / 已结算 × 有人 / 没人需要 / 没人不需要) | ✅ | 会话证据 accept8469/AC-4.json |
| 5 | 团期 H 配导游后导游 `DONE` 1/1、摄影仍 `TODO` 0/1、合同 `TODO`;再配摄影后摄影 `DONE` 1/1;实例团期四项齐后合同 `TODO` → `DOING` 10/12、保险 `TODO` → `DONE` 12/12 | ✅ | 会话证据 accept8469/AC-5.json |
| 6 | 看板 11 行房 / 车 `chips` 与 `chipStats` 部署前后逐字段一致 | ✅ | 会话证据 accept8469/PROBE-before.json、accept8469/PROBE-after.json |
| 9 | 无 token 调导游芯片明细 → HTTP 200、业务码 401 | ✅ | 会话证据 accept8469/AC-9.json |
验收脚本 22/22 通过(会话证据 accept8469/VERIFY-summary.json)。
---
## 九、相关历史 PR
| PR | Issue | 说明 | 是否仍有效 |
|----|-------|------|------------|
| #7207 | #7204 | 导 / 摄芯片按户:零指派 `TODO`、部分指派 `DOING`、全部指派 `DONE` | ❌ 已被本单取代 |
| #7254 | #7250 | 六芯片透出 `chipStats` 计数 | ✅ 字段有效;导 / 摄计数单位本单改为名册位 |
| #7856 | #7853 | 导 / 摄芯片明细带出 `staffList` | ✅ 有效(内容不变) |
| #8475 | #8468 | 导 / 摄明细 `items` 恒 `[]`;该文所写「导 / 摄聚合态与计数仍按户」一句已被本单取代 | ⚠️ `items` 口径有效,聚合口径以本文为准 |
| #8480 | #8478 | 团期详情进度条 `progressStepper` | ✅ 有效,本单不改 |
| **#8489** | **#8469** | 本单:导 / 摄芯片改按团期名册,合同 / 保险门控随之变化 | ✅ 最新 |
---
## 十、相关文档
- 工单 #8469: https://git.1814.love/wx/HL/issues/8469
- 拆出本单的 #8468(导 / 摄明细去掉逐户人员): https://git.1814.love/wx/HL/issues/8468
- 改前口径 #7204: https://git.1814.love/wx/HL/issues/7204
---
## 关联 / 联系人
### 链接
- **Issue**: [#8469](https://git.1814.love/wx/HL/issues/8469)
- **PR**: [#8489](https://git.1814.love/wx/HL/pulls/8489)
- **Merge commit**: [2c87b0618](https://git.1814.love/wx/HL/commit/2c87b0618)
### 联系人
- **后端负责人**: @jw