From 6fce073bcb9699a34be10976d7e000959e8a1680 Mon Sep 17 00:00:00 2001 From: jw Date: Tue, 29 Sep 2026 17:38:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20#8497=20=E5=9B=A2=E6=9C=9F?= =?UTF-8?q?=E5=AD=98=E9=87=8F=E5=9B=A2=E5=8F=B7=E6=8D=A2=E5=8F=B7=E5=86=85?= =?UTF-8?q?=E9=83=A8=E5=9B=9E=E5=A1=AB=E4=B8=8E=E5=90=8C=E6=AD=A5=E7=AB=AF?= =?UTF-8?q?=E7=82=B9=EF=BC=88=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3=C2=B7?= =?UTF-8?q?=E5=86=85=E9=83=A8=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- ...›¢号换号内部回填与同步端点-新增接口-管理后台.md | 297 ++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 changelogs-v2/2026-09/29_8497_团期存量团号换号内部回填与同步端点-新增接口-管理后台.md diff --git a/changelogs-v2/2026-09/29_8497_团期存量团号换号内部回填与同步端点-新增接口-管理后台.md b/changelogs-v2/2026-09/29_8497_团期存量团号换号内部回填与同步端点-新增接口-管理后台.md new file mode 100644 index 00000000..a681808d --- /dev/null +++ b/changelogs-v2/2026-09/29_8497_团期存量团号换号内部回填与同步端点-新增接口-管理后台.md @@ -0,0 +1,297 @@ +--- +schema: "hl-changelog/v2" +ticket: "8497" +title: "团期团号改为 T+出发年份后两位-4位混淆号,新增存量换号的两个内部端点(产品回填 / order-v3 同步)" +consumer: "internal" +author: "jw(GIT)" +change_type: "新增接口" +backend_status: "deployed" +gateway_status: "not_required" +frontend_status: "not_required" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "两个新增接口都是 internal(网关不暴露、X-Internal-Token 校验),只给运维一次性执行存量换号用,前端无需对接。TEST 已于 2026-09-29 执行完毕:297 个在册班期换号、13 个团期与 61 行应付快照同步,重跑零变更。附带说明:团期团号 batchNo 的取值格式由 28 位旧号改为形如 T26-8867 的新号,所有返回 batchNo 的接口字段名与类型不变,仅取值变短,前端列宽可收窄。" +updated_at: "2026-09-29" +base: "dev-v3" +--- + +# 团期:团号改为 T26-8867 形态,新增存量换号的两个内部端点 + +> **服务**: hl-product-service-v2(端口 8083)、hl-order-service-v3(端口 8086,含 finance 模块) +> **PR**: #8514(新规则)、#8532(存量换号) +> **Issue**: #8497 +> **日期**: 2026-09-29 +> **影响范围**: 团期团号 batchNo 的取值格式;两个一次性内部端点 + +--- + +## ⚠️ 关键变化 + +- 团期团号(产品侧 `group_tour_batch.batch_no`,建团时原样抄进订单侧团期)由 28 位旧号 `Q + yyyyMMdd + 19 位雪花 ID`(如 `Q202611102104491287904428034`)改为 **`T` + 出发年份后两位 + `-` + 4 位混淆号**(如 `T26-8867`;一年超过 9999 个后为 5 位)。 +- 所有返回 `batchNo` 的既有接口(团期列表 / 详情、房务看板、车务派单、财务应收台账团行的 `orderNo` / `teamNo` 等)**字段名、类型、位置都不变**,只是取值变成新格式;存量在册班期已统一换成新号。 +- 团期子订单自己的订单号(`HL` + 年月日时分秒 + 3 位毫秒)与团号(`yy-NNNN`,如 `26-3821`)**不变**。 + +--- + +## 一、背景 + +jw 2026-09-29 定:团号要能念、能记,参照订单团号 `26-8867` 的思路改为 `T26-8867`(T=团),年份取出发日期。新建班期由 PR-1 起按新规则取号;存量在册班期的旧号由本次新增的两个内部端点一次性换掉,旧号存进产品库 `legacy_batch_no` 列备查(不进任何接口、不做按旧号搜索的兼容)。 + +--- + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 团期存量团号回填 | POST | `/internal/product/group-tour-batch/batch-no/backfill` | 新增 | 产品服务:在册班期旧号换成新号,dryRun 默认 true | +| 2 | 团期团号同步 | POST | `/v3/internal/order/group-batch/batch-no/sync` | 新增 | order-v3:订单侧团期与财务应付快照跟上产品侧新号,dryRun 默认 true | + +--- + +## 三、接口详情 + +### 1. 团期存量团号回填 `POST /internal/product/group-tour-batch/batch-no/backfill` + +**VO**: `GroupTourBatchNoBackfillRespVO` + +#### 使用场景 + +运维在部署后一次性执行:把产品库在册班期里不是新格式的团号逐行换成新号(与新建班期共用同一个取号器、同一张按年序号表),旧号写进 `legacy_batch_no`;班期名等于旧号的一并换成新号;班期名长得像旧号(复制产品抄来的)的改回自身团号。先 dryRun 看数,再 `dryRun=false` 正式执行,紧接着调用接口 2。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| X-Internal-Token | header | string | 是 | 服务间内部令牌 | 缺失或错误返回 403 | +| dryRun | query | boolean | 否 | 默认 true | true 只统计不修改;false 正式换号 | +| limit | query | integer | 否 | 大于等于 0;不传为不限 | 本轮最多换号行数,只限制换号,不限制改名 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| dryRun | boolean | 是否只统计 | +| limit | integer | 本轮换号上限,null 为不限 | +| scanned | integer | 扫描的在册班期数 | +| legacyCandidates | integer | 在册班期中不是新格式的行数 | +| converted | integer | 换号成功行数(dryRun 时为将会换号的行数) | +| renamed | integer | 名字改回自身团号的行数 | +| skipped | integer | 跳过行数(读后被并发改动 / 已删除,本行已回滚) | +| mappingTotal | integer | 换号映射总数 | +| mappings | array | 换号映射(最多返回前 N 条):batchId(string)、oldBatchNo、newBatchNo(dryRun 时为 null) | +| skippedItems | array | 跳过明细:batchId、phase(CONVERT / RENAME)、reason | + +#### 请求示例 + +```http +POST /internal/product/group-tour-batch/batch-no/backfill?dryRun=false HTTP/1.1 +Host: 192.168.100.236:8083 +X-Internal-Token: <内部令牌> +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "dryRun": false, + "limit": null, + "scanned": 301, + "legacyCandidates": 297, + "converted": 297, + "renamed": 5, + "skipped": 0, + "mappingTotal": 297, + "mappings": [ + { "batchId": "2046126055898431490", "oldBatchNo": "Q202602262046126055885848578", "newBatchNo": "T26-0906" } + ], + "skippedItems": [] + }, + "success": true +} +``` + +#### 空数据 / 降级响应 + +没有需要换号的班期时(例如重跑)返回 `converted=0`、`renamed=0`、`mappings=[]`,HTTP 200: + +```json +{ + "code": 200, + "message": "成功", + "data": { "dryRun": false, "limit": null, "scanned": 306, "legacyCandidates": 0, "converted": 0, "renamed": 0, "skipped": 0, "mappingTotal": 0, "mappings": [], "skippedItems": [] }, + "success": true +} +``` + +#### 错误响应 + +缺少或错误的内部令牌: + +```json +{ "code": 403, "msg": "内部接口禁止外部访问" } +``` + +`limit` 为负数: + +```json +{ "code": 400, "message": "数值超出允许范围,请修改后重试", "data": null, "success": false } +``` + +#### 业务边界 + +- 只处理在册班期,已删除的班期保留原号。 +- 每行一个独立事务;读后被并发改动的行回滚并计入 skipped,不影响后续行,序号不留空洞。 +- 回填过程中同时新建班期不会撞号(共用同一张按年序号表)。 +- 可重跑,已是新号的行不再处理。 + +### 2. 团期团号同步 `POST /v3/internal/order/group-batch/batch-no/sync` + +**VO**: `GroupBatchNoSyncRespVO` + +#### 使用场景 + +紧接接口 1 执行:逐个团期拉产品侧当前团号(在事务外调用产品服务),与订单侧团期不一致时,在同一事务里回写订单侧团期团号(名字等于旧号时一并改),并把财务应付明细与应付团头里等于旧号的团号换成新号。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| X-Internal-Token | header | string | 是 | 服务间内部令牌 | 缺失或错误返回 403 | +| dryRun | query | boolean | 否 | 默认 true | true 只统计不修改;false 正式同步 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| dryRun | boolean | 是否只统计 | +| scanned | integer | 扫描的未删除团期数 | +| synced | integer | 已同步团期数(dryRun 时为将会同步的数量) | +| skipped | integer | 与产品侧已一致而跳过的团期数 | +| failedCount | integer | 失败团期数(拉产品侧失败 / 产品侧团号为空 / 事务失败,均已回滚且不中断) | +| payableLineRows | integer | 应付明细改号影响行数合计(只作留痕) | +| payableTeamRows | integer | 应付团头改号影响行数合计(只作留痕) | +| syncedItems | array | 同步明细:groupBatchId(string)、oldBatchNo、newBatchNo、batchNameChanged | +| failed | array | 失败明细:groupBatchId、reason | + +#### 请求示例 + +```http +POST /v3/internal/order/group-batch/batch-no/sync?dryRun=false HTTP/1.1 +Host: 192.168.100.236:8086 +X-Internal-Token: <内部令牌> +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "dryRun": false, + "scanned": 17, + "synced": 13, + "skipped": 4, + "failedCount": 0, + "payableLineRows": 60, + "payableTeamRows": 1, + "syncedItems": [ + { "groupBatchId": "2101506167098511362", "oldBatchNo": "Q202609272101502082564407298", "newBatchNo": "T26-9802", "batchNameChanged": false } + ], + "failed": [] + }, + "success": true +} +``` + +#### 空数据 / 降级响应 + +全部团期已与产品侧一致时返回 `synced=0`、`syncedItems=[]`;单个团期拉取产品侧失败时计入 `failedCount` 与 `failed`,其余团期照常处理: + +```json +{ + "code": 200, + "message": "成功", + "data": { "dryRun": false, "scanned": 17, "synced": 0, "skipped": 17, "failedCount": 0, "payableLineRows": 0, "payableTeamRows": 0, "syncedItems": [], "failed": [] }, + "success": true +} +``` + +#### 错误响应 + +缺少或错误的内部令牌: + +```json +{ "code": 403, "msg": "内部接口禁止外部访问" } +``` + +#### 业务边界 + +- 不改团期子订单的订单号与团号。 +- 同一团期的团期表与应付快照在同一事务内一起改或一起回滚。 +- 新号若与已有应付团头冲突,该团期回滚并计入 failed,需人工处理。 +- 可重跑,已一致的团期跳过。 + +--- + +## 四、契约约束与正确调用方式 + +- 两个接口只供运维一次性执行,不经网关(网关对 `/internal/**`、`/v3/internal/**` 返回 403),需直连服务端口并带 `X-Internal-Token`。 +- 执行顺序固定:接口 1 dryRun → 接口 1 正式 → **紧接着**接口 2 dryRun → 接口 2 正式。两者之间有新订单进来不影响结果(下单时不改团号)。 +- 不传 `dryRun` 等同 dryRun=true,不会误改数据。 +- 既有接口里的 `batchNo` 字段名、类型不变,取值格式变为新号;调用方不要按 28 位长度或 `Q` 前缀解析团号。 + +--- + +## 五、数据库行为 + +- 接口 1:产品库班期的团号换成新号,旧号写入备查列;占用按出发年份计数的团号序号;不改已删除班期。 +- 接口 2:订单侧团期的团号(及等于旧号的班期名)与财务应付明细、应付团头上的团号改为新号;金额不变;不改订单主表。 +- 两个接口 dryRun 时只读不写。 + +--- + +## 六、边界行为 + +- 同一序号在不同年份后四位相同(如 `T26-0906`、`T27-0906`),靠年份段区分,属公式特性。 +- 号一经生成,出发日期改到别的年份也不改号。 +- 快照还原遇到旧格式的号会重新取号,避免换号后旧号回流。 + +--- + +## 七、不影响范围 + +- 团期子订单的订单号(`HL…`)与团号(`yy-NNNN`)。 +- 所有既有接口的路径、入参、出参字段与类型。 +- 前端:无需对接这两个内部接口;`batchNo` 列宽可按新格式收窄(可选)。 + +--- + +## 八、测试环境已验证 + +2026-09-29 在 TEST 直连服务端口执行(换号前后各存全量快照逐行比对): + +- 接口 1 dryRun:在册 301、旧格式 297、名字像旧号 5,序号表不变;正式:297 换号、5 改名、0 跳过,3.6 秒;执行期间并发新建 5 个班期全部成功且不撞号。 +- 接口 2 dryRun → 正式:扫描 17、同步 13、跳过 4、失败 0,应付明细改 60 行、应付团头改 1 行。 +- 重跑两接口零变更;无令牌 403;`limit=-1` 返回 400。 +- 换号后:在册班期无旧号、`legacy_batch_no` 与原号逐行一致;订单侧团期与产品侧逐行一致;全库团号列普查旧号 0;团期子订单订单号与团号 46 行逐行一致;应付台账按新号 `T26-9802` 查得应付 3120.00,与换号前一致。 + +--- + +## 十、相关文档 + +- 工单 #8497(含两轮 TEST 验收证据评论) +- PR #8514(新规则)、PR #8532(存量换号) +- 团期文档 `docs/group/数据模型.html`「新增事实三」已按新规则收口 + +--- + +## 关联 / 联系人 + +- 后端:jw +- 工单:https://git.1814.love/wx/HL/issues/8497