diff --git a/changelogs-v2/2026-09/28_8478_团期详情新增分叉进度条并替代确认缺项横幅-修改接口-管理后台.md b/changelogs-v2/2026-09/28_8478_团期详情新增分叉进度条并替代确认缺项横幅-修改接口-管理后台.md new file mode 100644 index 00000000..b2d67658 --- /dev/null +++ b/changelogs-v2/2026-09/28_8478_团期详情新增分叉进度条并替代确认缺项横幅-修改接口-管理后台.md @@ -0,0 +1,401 @@ +--- +schema: "hl-changelog/v2" +ticket: "8478" +title: "团期详情新增分叉进度条 progressStepper,配置段拆配房、配车、配导游、配摄影、配物资五条分支" +consumer: "admin" +author: "jw(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "PR #8480 已合入 dev-v3(49777861b),TEST 的 hl-order-service-v3 运行 dev-v3 49777861b;经网关 api.test.1814.love 用真实 admin token 实测招募、配置、确认、出行三态、核单、结算、已流团各状态,以及整团免车与无需导摄,全部通过。前端需接:详情页头用 progressStepper 画分叉进度条替换直线步骤条,页头加「未设置主报账人」标签,去掉「团期尚不满足确认条件」横幅、查看需求「仍有子订单需求缺失」提示块、总览「资源与单据」卡片(见第四节前端交接清单),故 frontend_status 记 pending。" +updated_at: "2026-09-28" +base: "dev-v3" +--- + +# 团期详情:新增分叉进度条 progressStepper(管理后台) + +> **服务**: hl-order-service-v3(端口 8086) +> **PR**: #8480(合入 dev-v3 为 `49777861b`) +> **Issue**: #8478 +> **日期**: 2026-09-28 +> **影响范围**: 团期详情页页头进度条、确认缺项提示、查看需求提示块、总览「资源与单据」卡片 + +--- + +## ⚠️ 关键变化 + +1. **团期详情新增 `progressStepper`**:6 个主节点(招募 / 配置 / 确认 / 出行 / 核单 / 结算),「配置」节点下带 5 条分支(配房 / 配车 / 配导游 / 配摄影 / 配物资),字段名与订单详情的 `progressStepper` 一致,订单详情的分叉图组件可以直接复用。 +2. **分支有四种状态**:`WAITING` 待开始 / `UNMET` 未配齐(物资为「未确认」)/ `WAIVED` 无需或整团免车 / `DONE` 已完成(物资为「已确认」)。「无需」「整团免车」由后端判定,前端**不要**再用 `hotelReady` 等五个布尔自己拼。 +3. **已流团时 `progressStepper` 是空数组 `[]`**(不是 null),前端照旧显示「已流团」标签。 +4. **主报账人两个字段只改了说明**:`primaryReporterId` / `primaryReporterName` 早已有值(团期人员配置里 `reporter_rank=PRIMARY` 的人,未设置为 null)。原 swagger 写的「P10 未落,暂返 null」已过时,取值没有变化。 +5. **前端要配合的改造**见第四节「前端交接清单」:用进度条替换页头的「团期尚不满足确认条件」横幅,页头加「未设置主报账人」标签,去掉查看需求的「仍有子订单需求缺失」提示块和总览「资源与单据」卡片。 + +--- + +## 一、背景 + +团期详情页现有两块缺项提示内容重复且很长: + +- 页头「团期尚不满足确认条件」横幅(#8410):12 户的团就逐户列 12 行。 +- 「查看需求」页签的「仍有子订单需求缺失,暂不能整团确认」提示块。 + +逐户缺项在「查看需求」表格的「需求审核」「需求状态」两列里已经有了。jw 2026-09-28 定案: + +- 两块提示都去掉; +- 团级五项改成和订单详情一样的分叉进度条; +- 导游 / 摄影不需要、或整团免车时,要显示「无需」「整团免车」; +- 「未设置主报账人」放在页头状态标签左侧,主报账人**不**作为分支。 + +「无需」的来源散在三处,前端只靠现有字段判不准,所以由后端统一派生: + +| 分支 | 「无需」怎么来 | 前端自己判会踩的坑 | +|------|--------|--------| +| 导游 / 摄影 | 团期 `needs_guide` / `needs_photographer` | 这两列**只在成团时写入,招募阶段恒为 0**,直接用会把招募团显示成「无需」 | +| 车 | 团级用车需求上的「整团免车」声明(成团后声明,可撤销) | 团期详情原本没有这个信息 | +| 房、物资 | 没有免除 | — | + +另外,总览「资源与单据」卡片读的是 `detail.chips`,但团期详情从来没有返回过 `chips`,那 6 张卡一直显示灰色「待办」,本次一并让前端去掉。 + +--- + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 团期详情 | GET | `/v3/admin/order/group-batch/{groupBatchId}` | 出参新增字段 | 新增 `progressStepper`;更正 `primaryReporterId` / `primaryReporterName` 的说明(取值不变) | + +--- + +## 三、接口详情 + +### 1. 团期详情 `GET /v3/admin/order/group-batch/{groupBatchId}` + +**VO**: `GroupBatchDetailRespVO`(新增嵌套 `GroupBatchProgressNodeVO`、`GroupBatchProgressSubFlowVO`) + +#### 使用场景 + +团期详情页进入时调用(A2,GB-ADM-002),已有调用点不变。本次新增的 `progressStepper` 供页头画分叉进度条,替换现在的直线步骤条和「团期尚不满足确认条件」横幅。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| groupBatchId | Path | String | ✅ | 团期主键(雪花 ID,按字符串传) | 团期 ID | + +#### 出参 `Result` + +以下只列本次新增或改了说明的字段,其余字段与改前完全一致。 + +| 字段 | 类型 | 说明 | +|------|------|------| +| progressStepper | Array | 团期进度条。非流团时恒为 6 个主节点,按 `step` 1~6 排列;已流团、或 `batchStatus` 为空 / 认不出时为空数组 `[]` | +| progressStepper[].step | Integer | 节点序号 1~6 | +| progressStepper[].code | String | 节点编码:`RECRUIT` / `CONFIGURE` / `CONFIRM` / `TRIP` / `REVIEW` / `SETTLE`,与详情已有的 `stage` 是同一套取值 | +| progressStepper[].name | String | 节点名称:招募 / 配置 / 确认 / 出行 / 核单 / 结算 | +| progressStepper[].status | String | 节点状态:`DONE` 已过 / `PROCESSING` 进行中 / `WAITING` 未到。已结算团的结算节点是 `DONE` | +| progressStepper[].label | String | 当前节点的标签:招募中 / 配置中 / 已确认 / 待出发、出行中、已返团(出行节点取出行子状态)/ 核单中 / 已结算;非当前节点为 null | +| progressStepper[].isCurrent | Boolean | 是否当前节点,恰有一个为 true,其 `code` 等于同一响应的 `stage` | +| progressStepper[].subFlows | Array | 分支列表。只有 `CONFIGURE` 节点有值(固定 5 条),其余节点为 null | +| progressStepper[].subFlows[].code | String | 分支编码,固定顺序:`HOTEL` / `VEHICLE` / `GUIDE` / `PHOTOGRAPHER` / `MATERIAL` | +| progressStepper[].subFlows[].name | String | 分支名称:配房 / 配车 / 配导游 / 配摄影 / 配物资 | +| progressStepper[].subFlows[].status | String | 分支状态:`WAITING` / `UNMET` / `WAIVED` / `DONE`,判定规则见第六.5 节 | +| progressStepper[].subFlows[].statusName | String | 状态名:待开始 / 未配齐(物资为未确认)/ 无需、整团免车 / 已完成(物资为已确认) | +| progressStepper[].subFlows[].displayText | String | 可直接展示的文案,「名称·状态名」,如 `配车·整团免车` | +| primaryReporterId | String | **说明更正,取值不变**:团期人员配置里 `reporter_rank=PRIMARY` 那个人的 staffId;团期未设置主报账人时为 null | +| primaryReporterName | String | **说明更正,取值不变**:同一个人的姓名(配置时的快照);未设置时为 null | + +#### 请求示例 + +```http +GET /v3/admin/order/group-batch/2104327837991518210 +Authorization: Bearer +``` + +#### 响应示例 + +TEST 实测:整团免车团,配置阶段。其余字段省略。 + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "groupBatchId": "2104327837991518210", + "batchStatus": "RESOURCE_PREPARING", + "stage": "CONFIGURE", + "hotelReady": false, + "vehicleReady": true, + "guideReady": true, + "photographerReady": true, + "materialConfirmed": false, + "primaryReporterId": null, + "primaryReporterName": null, + "progressStepper": [ + { "step": 1, "code": "RECRUIT", "name": "招募", "status": "DONE", "label": null, "isCurrent": false, "subFlows": null }, + { + "step": 2, "code": "CONFIGURE", "name": "配置", "status": "PROCESSING", "label": "配置中", "isCurrent": true, + "subFlows": [ + { "code": "HOTEL", "name": "配房", "status": "UNMET", "statusName": "未配齐", "displayText": "配房·未配齐" }, + { "code": "VEHICLE", "name": "配车", "status": "WAIVED", "statusName": "整团免车", "displayText": "配车·整团免车" }, + { "code": "GUIDE", "name": "配导游", "status": "WAIVED", "statusName": "无需", "displayText": "配导游·无需" }, + { "code": "PHOTOGRAPHER", "name": "配摄影", "status": "WAIVED", "statusName": "无需", "displayText": "配摄影·无需" }, + { "code": "MATERIAL", "name": "配物资", "status": "UNMET", "statusName": "未确认", "displayText": "配物资·未确认" } + ] + }, + { "step": 3, "code": "CONFIRM", "name": "确认", "status": "WAITING", "label": null, "isCurrent": false, "subFlows": null }, + { "step": 4, "code": "TRIP", "name": "出行", "status": "WAITING", "label": null, "isCurrent": false, "subFlows": null }, + { "step": 5, "code": "REVIEW", "name": "核单", "status": "WAITING", "label": null, "isCurrent": false, "subFlows": null }, + { "step": 6, "code": "SETTLE", "name": "结算", "status": "WAITING", "label": null, "isCurrent": false, "subFlows": null } + ] + } +} +``` + +招募阶段的团,5 条分支都是 `{"status": "WAITING", "statusName": "待开始"}`,`RECRUIT` 为当前节点,label「招募中」。 + +#### 空数据 / 降级响应 + +已流团(`batchStatus=CANCELLED`),或 `batchStatus` 为空 / 认不出时,`progressStepper` 为空数组,详情其余字段照常返回: + +```json +{ + "code": 200, + "success": true, + "data": { "batchStatus": "CANCELLED", "stage": "DISBANDED", "stageName": "已流团", "progressStepper": [] } +} +``` + +#### 错误响应 + +与改前一致,本次没有新增错误码。 + +```json +{ "code": 589500, "message": "团期不存在", "data": null, "success": false } +``` + +```json +{ "code": 401, "message": "缺少有效的 Authorization 头", "data": null } +``` + +| 场景 | 返回 | +|------|------| +| 团期不存在 / 已删除 | `589500 团期不存在` | +| 未带或带了无效 token | 网关约定:HTTP 200,响应体 `code: 401` | + +#### 业务边界 + +- 判权、入参、其余出参都与改前一致;本次只加了一个字段。 +- `progressStepper` **只供展示**。确认按钮能不能点,仍以确认预检 `GET .../confirm-check` 的 `ready` 为准;阶段判断仍以 `batchStatus` 为准。 +- 配置阶段(`RESOURCE_PREPARING`)里,分支为 `UNMET` 的项,就是确认预检 `batchItems` 里同一项 `passed=false`(两边读同一组标记,TEST 上 9 个配置阶段团逐项核对一致)。招募阶段分支一律显示「待开始」,预检这时 `statusConfirmable=false`,两者不做一一对应。 +- 分支状态是实时派生的:管理员确认物资、配齐房车、声明或撤销整团免车后,重新拉一次详情就会变。 +- 只读:接口不写库。只有「非招募、非流团、车已就绪」时才多查一次本库,判断整团免车声明。 + +--- + +## 四、契约约束与正确调用方式 + +本接口是 GET,没有请求体。下表是消费出参的正确方式。 + +### ✅ 正确 / ❌ 错误用法对照 + +| 场景 | 做法 | +|------|------| +| ✅ 画进度条 | 按数组顺序(即 `step`)画 6 个节点,带 `subFlows` 的节点画成分叉 | +| ✅ 分支文案 | 直接用 `displayText`,或 `name + "·" + statusName` | +| ✅ 分支颜色 | 按 `status` 四值分:`DONE` 完成色、`WAIVED` 完成色的弱化版(建议灰色勾)、`UNMET` 警示色(橙)、`WAITING` 灰 | +| ✅ 已流团 | `progressStepper` 为 `[]` 时不画进度条,显示「已流团」标签 | +| ❌ 用 `hotelReady` 等五个布尔自己拼分支 | 判不出「无需」「整团免车」,招募团还会被误判 | +| ❌ 写死订单进度条的节点编码(`PROFILE` / `RESOURCE` / `DEPART`) | 团期节点编码是 `RECRUIT` / `CONFIGURE` / `CONFIRM` / `TRIP` / `REVIEW` / `SETTLE` | +| ❌ 用 `progressStepper` 判断能否确认 | 能否确认只看 `confirm-check` 的 `ready` | + +### 前端交接清单 + +行号按 hl-ui `origin/v2.1@501c4258`。 + +1. **分叉进度条**:通用化 `src/views/order-v2/detail/components/ForkStepBar.vue`,只加可选参数,订单页行为不变。 + - 节点从传入数组读:首节点、带 `subFlows` 的分叉节点、其后各节点,不再写死订单的节点编码;首节点文字可配(团期为「招募」)。 + - 支持 5 条分支的高度。现在 3 条及以上是 132px,5 条时间隔约 23px 会重叠,建议约 200px。 + - 新增 `UNMET` 橙色样式和 `WAIVED` 样式;补 `MATERIAL` 图标。 + - 用它替换 `batch/detail/components/BatchHero.vue` 的直线步骤条 `batch-hero__steps`,数据直接取 `detail.progressStepper`;为 `[]` 时照旧显示「已流团」标签。 + - 点击分支跳到对应页签(配房 / 配车 / 配导游 / 配摄影 / 物资),用 `index.vue` 现有的 `onGotoChip`。 +2. **页头主报账人提示**:`BatchHero.vue` 右上 `batch-hero__stat` 里、状态标签左边,`!detail.primaryReporterId && detail.batchStatus !== 'CANCELLED'` 时显示橙色标签「未设置主报账人」,点击打开现有的 `ReporterRankModal`(`index.vue` 的 `reporterShow`)。主报账人**不**作为分支。 +3. **删掉页头横幅**:`batch/detail/index.vue:94-126` 的「团期尚不满足确认条件」`n-alert` 与 `showConfirmCheckBanner`。**保留** `loadConfirmCheck` 预检(确认按钮置灰靠它);`index.vue:951` 的提示「请核对下方缺项清单」改为不指向已删除的清单。 +4. **删掉查看需求提示块**:`RequirementTab.vue:97-133`「仍有子订单需求缺失,暂不能整团确认」。「豁免户」「接送机缺口」两块提示、头部「预检:缺失 x 户」小字、表格「需求审核」「需求状态」两列都保留。 +5. **删掉总览「资源与单据」卡片**:`batch/detail/components/OverviewTab.vue:56-79`。详情从未返回 `chips`,这 6 张卡一直是灰色「待办」。 +6. **设完主报账人后重新预检**:`index.vue:842` 的 `onReporterSaved` 目前只重拉详情,要补调 `loadConfirmCheck()`;否则设完主报账人,确认按钮仍按旧预检结果置灰,要刷新页面才恢复。 +7. **单测同步**:`batch/detail/__tests__/index.spec.js:271-355` 里对横幅的断言,以及 `RequirementTab` / `OverviewTab` 相关断言。 +8. **可选**:去掉横幅后,逐户的「未付订金」「合同模板未设置」在「查看需求」里看不到(前者在财务页签能看到)。如果想在确认按钮置灰时告诉用户原因,可以给按钮加悬停提示,内容直接用预检的 `gateMessage`,不需要新接口。 + +--- + +## 五、数据库行为 + +本接口只读,零写入、零 DDL。数据来源都是既有列: + +| 读什么 | 来源 | +|--------|------| +| 节点 | `order_group_batch.batch_status` | +| 分支标记 | `order_group_batch` 的 `hotel_ready` / `vehicle_ready` / `guide_ready` / `photographer_ready` / `material_confirmed` | +| 导摄是否需要 | `order_group_batch.needs_guide` / `needs_photographer` | +| 整团免车 | `order_group_vehicle_requirement`(活跃且已确认)+ `order_group_vehicle_group`(零分组) | + +--- + +## 六、边界行为 + +- 未登录 / 无效 token → 网关返回 `code: 401`(HTTP 200)。 +- 团期不存在 → `589500`。 +- 已流团、`batchStatus` 为空或认不出 → `progressStepper=[]`,详情其余字段照常返回,不报 500。 +- 招募阶段 → 5 条分支都是「待开始」。`needs_*` 这时恒为 0,但不会显示「无需」。 +- 标记为 false 时,即使该项不需要(`needs_*=0`),也显示 `UNMET`,与确认门判定一致。 +- 已结算 → 6 个节点全是 `DONE`,结算节点 `isCurrent=true`、label「已结算」。 + +--- + +## 六.5、枚举 / 数据字典 + +### progressStepper[].code(`GroupBatchStageBuckets.Bucket`) + +**所属字段**: `GroupBatchProgressNodeVO.code` | **类型**: `String` + +| 值 | 中文 | 对应九态 `batchStatus` | +|----|------|------| +| `RECRUIT` | 招募 | RECRUITING | +| `CONFIGURE` | 配置 | RESOURCE_PREPARING | +| `CONFIRM` | 确认 | MATERIAL_PREPARING | +| `TRIP` | 出行 | PENDING_DEPARTURE / TRAVELLING / TRIP_FINISHED | +| `REVIEW` | 核单 | REVIEWING | +| `SETTLE` | 结算 | SETTLED | + +### progressStepper[].status(`GroupBatchProgressStepper` 常量) + +**所属字段**: `GroupBatchProgressNodeVO.status` | **类型**: `String` + +| 值 | 中文 | 说明 | +|----|------|------| +| `DONE` | 已过 | 当前节点之前的节点;已结算团的结算节点 | +| `PROCESSING` | 进行中 | 当前节点(已结算除外) | +| `WAITING` | 未到 | 当前节点之后的节点 | + +### progressStepper[].subFlows[].code(`GroupBatchProgressStepper.Branch`) + +**所属字段**: `GroupBatchProgressSubFlowVO.code` | **类型**: `String` + +| 值 | 中文 | 读哪个标记 | 能否免除 | +|----|------|------|------| +| `HOTEL` | 配房 | `hotelReady` | 否 | +| `VEHICLE` | 配车 | `vehicleReady` | 整团免车 | +| `GUIDE` | 配导游 | `guideReady` | 团期不需要导游 | +| `PHOTOGRAPHER` | 配摄影 | `photographerReady` | 团期不需要摄影 | +| `MATERIAL` | 配物资 | `materialConfirmed` | 否 | + +### progressStepper[].subFlows[].status(`GroupBatchProgressStepper` 常量) + +**所属字段**: `GroupBatchProgressSubFlowVO.status` | **类型**: `String` + +按优先级从上往下判: + +| 值 | 中文(statusName) | 条件 | +|----|------|------| +| `WAITING` | 待开始 | 团期在招募阶段 | +| `UNMET` | 未配齐(物资:未确认) | 对应标记不为 true | +| `WAIVED` | 无需 / 整团免车 | 导游、摄影:标记为 true 且团期不需要;车:标记为 true 且整团免车声明成立 | +| `DONE` | 已完成(物资:已确认) | 其余标记为 true 的情况 | + +--- + +## 六.6、修改前后对比 + +### 字段级对比 + +| 字段 | 改前 | 改后 | +|------|------|------| +| `progressStepper` | 无 | 新增,见第三节 | +| `primaryReporterId` 的 swagger 说明 | 主报账人 staffId(P10 未落,暂返 null) | 取团期人员配置里 reporter_rank=PRIMARY 的人;未设置为 null(取值与改前相同) | +| `primaryReporterName` 的 swagger 说明 | 主报账人姓名(P10 未落,暂返 null) | 同一个人的姓名快照;未设置为 null(取值与改前相同) | + +### 行为级对比 + +| 行为 | 改前 | 改后 | +|------|------|------| +| 团级五项的展示依据 | 前端读 5 个布尔,或读 confirm-check 的 batchItems | 读 `progressStepper` 的分支,含「无需」「整团免车」 | +| 已流团 | 无进度条字段 | `progressStepper=[]` | +| 其余字段 | — | 不变 | + +--- + +## 六.7、影响评估 + +- **是否破坏向后兼容**: 否。纯新增字段,其余字段取值不变。 +- **前端是否必须同步上线**: 否。不接新字段时页面行为与改前一致;按第四节清单改造后生效。 +- **前端 workaround 清理点**: 页头「团期尚不满足确认条件」横幅、查看需求「仍有子订单需求缺失」提示块、总览「资源与单据」卡片(该卡依赖从未返回过的 `chips`),按第四节清单去掉。 + +--- + +## 七、不影响范围 + +- **仅影响**: 团期详情接口出参(新增一个字段)。 +- **零影响**: + - 确认预检 `GET /v3/admin/order/group-batch/{groupBatchId}/confirm-check` 与确认 `POST .../confirm` 的判定和出参 + - 团期列表、看板(`chips` 与统计口径不变) + - 订单详情的 `progressStepper`(团期用独立的 VO,字段名一致,互不影响) + - 数据库表结构与存量数据 + +--- + +## 八、测试环境已验证 + +TEST 的 hl-order-service-v3 运行 dev-v3 `49777861b`,部署后连调 6 次都返回 `progressStepper`,两个实例都已生效。经网关用真实 admin token 实测: + +``` +GET /v3/admin/order/group-batch/2101506167098511362 → 200,6 节点,CONFIGURE 当前「配置中」,5 条分支 ✓ +GET /v3/admin/order/group-batch/2104327837991518210 → 200,配车「整团免车」,导摄「无需」 ✓ +GET /v3/admin/order/group-batch/2101014943498219522 → 200,配车有分组,DONE「已完成」 ✓ +GET .../{9 个配置阶段团}/confirm-check 与详情逐项比对 → 分支 UNMET ⇔ passed=false,全部一致 ✓ +自造团 招募 → 5 条「待开始」(needs 为 0 也不显示无需)✓ +自造团 成团后 → 房车未配齐、导摄无需、物资未确认 ✓ +自造团 确认 / 待出发 / 出行中 / 已返团 / 核单 / 已结算 → 当前节点与 label 正确,code = stage ✓ +自造团 已流团 → progressStepper = [] ✓ +自造团 guide_ready=0 且 needs_guide=0 → UNMET(未配齐优先于无需)✓ +不带 Authorization → code 401 ✓ +团期不存在 1999999999999999999 → 589500 ✓ +``` + +自造团(团期 `2104485658041147393`、订单 `2104485657902735361`、班期 `2104485617050230787`)验完已取消并清理。 + +--- + +## 九、相关历史 PR + +| PR | Issue | 说明 | 是否仍有效 | +|----|-------|------|------------| +| — | #8410 | 团期确认只读预检 confirm-check,前端据此加了页头「团期尚不满足确认条件」横幅 | ✅ 接口有效;横幅按本单第四节去掉 | +| — | #8271 | 团期六节点定案,详情 `stage` 字段 | ✅ 有效,`progressStepper[].code` 与之同源 | +| — | #7441 | 整团免车声明 | ✅ 有效,配车分支「整团免车」据此判定 | +| **本 PR #8480** | **#8478** | 新增 `progressStepper` | ✅ 最新 | + +--- + +## 十、相关文档 + +- 关联 Issue: [wx/HL#8478](https://git.1814.love/wx/HL/issues/8478)(正文「前端范围」与本文第四节一致) +- 关联 PR: [wx/HL#8480](https://git.1814.love/wx/HL/pulls/8480) +- 订单详情分叉进度条组件:hl-ui `src/views/order-v2/detail/components/ForkStepBar.vue` + +## 关联 / 联系人 + +### 链接 + +- **Issue**: [#8478](https://git.1814.love/wx/HL/issues/8478) +- **PR**: [#8480](https://git.1814.love/wx/HL/pulls/8480) +- **Merge commit**: [49777861b](https://git.1814.love/wx/HL/commit/49777861bd967a9a50b7372351b585cff5da0c58) + +### 联系人 + +- **后端负责人**: @jw