From 85621d5e16e628a2505f2127ad63e4c52ebdef61 Mon Sep 17 00:00:00 2001 From: lc Date: Wed, 23 Sep 2026 15:59:53 +0800 Subject: [PATCH] =?UTF-8?q?docs(order-v3):=20#8230=20=E5=9B=A2=E6=9C=9F?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=94=AF=E6=8C=81=E7=94=A8=E9=A4=90=EF=BC=8C?= =?UTF-8?q?=E7=94=9F=E6=88=90/=E4=BF=9D=E5=AD=98/=E9=87=8D=E7=BD=AE/?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2/=E5=A5=97=E7=94=A8=E6=A8=A1=E7=89=88?= =?UTF-8?q?=E5=8F=AF=E5=8F=AA=E4=BC=A0=E5=9B=A2=E6=9C=9FID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 (1M context) --- ...餐按团期ID生成保存查询与套用-修改接口-管理后台.md | 507 ++++++++++++++++++ 1 file changed, 507 insertions(+) create mode 100644 changelogs-v2/2026-09/23_8230_团期订单支持用餐按团期ID生成保存查询与套用-修改接口-管理后台.md diff --git a/changelogs-v2/2026-09/23_8230_团期订单支持用餐按团期ID生成保存查询与套用-修改接口-管理后台.md b/changelogs-v2/2026-09/23_8230_团期订单支持用餐按团期ID生成保存查询与套用-修改接口-管理后台.md new file mode 100644 index 00000000..1b6c6435 --- /dev/null +++ b/changelogs-v2/2026-09/23_8230_团期订单支持用餐按团期ID生成保存查询与套用-修改接口-管理后台.md @@ -0,0 +1,507 @@ +--- +schema: "hl-changelog/v2" +ticket: "8230" +title: "团期订单支持用餐:生成、保存、重置、查询、套用模版可只传团期ID" +consumer: "admin" +author: "lc(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "已部署 TEST 并经 Gateway 实测通过。用餐的查询、生成、保存、重置、套用模版 5 个接口加入团期维度:orderId 与 groupBatchId 必须且只能传一个,都传或都不传返回 400。只传 groupBatchId 时读写的是团期自己的用餐行(行上团期ID有值、订单ID为空);按订单读写的行此后团期ID为空,按团期查不到子订单的行。团期的出发/返回日期取团期出团日期 depart_date / 结束日期 end_date。" +updated_at: "2026-09-23" +base: "dev-v3" +--- + +# order-v3: 团期订单支持用餐,5 个用餐接口可只传团期ID + +> **服务**: hl-order-service-v3 +> **PR**: #8251 +> **Issue**: #8230 +> **日期**: 2026-09-23 +> **影响范围**: 管理后台用餐信息的查询、生成、保存、重置与套用模版(订单、团期两种维度) + +--- + +## ⚠️ 关键变化 + +- 🔁 **二选一(破坏性)**:查询、生成、保存、重置、套用模版这 5 个接口,`orderId` 与 `groupBatchId` **必须且只能传一个**。都传返回 `400`「订单ID和团期ID只能传一个」;都不传返回 `400`「订单ID和团期ID必须传一个」。查询接口的 `batchNo` 不算数,**只传 `batchNo` 视为两个都没传**,同样 400。 +- 🔁 **订单行不再带团期**:按订单生成、保存、重置、套用出来的行,行上 `groupBatchId`、`batchNo` 一律为空。以前挂团订单的行会顺带写团期ID / 团期编号,现在不写。 +- 🔁 **保存不再用 `orderId` + `groupBatchId` 一起传**:以前保存时可以同时传两者并校验订单是否属于该团期(589601),现在同时传直接 400,589601 不再出现。 +- 🆕 **团期维度**:只传 `groupBatchId` 时读写的是**团期自己的用餐行**,行上 `groupBatchId` 有值、`orderId` 为空;按团期查询**只返回团期自己的行,不含团里子订单的行**。 +- ℹ️ **3.1 用 `orderId` + `batchNo` 组合此后查不到数据**:订单行上已不存团期编号,这个组合固定返回空列表。 + +--- + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|---|---|---|---|---| +| 1 | 查询用餐信息列表(3.1) | GET | `/v3/admin/order/meal-info/list` | 修改 | `orderId` / `groupBatchId` 二选一;只传团期ID只返回团期自己的行,顶层汇总按团期填 | +| 2 | 生成用餐信息(3.2) | POST | `/v3/admin/order/meal-info/generate` | 修改 | 新增 `groupBatchId`,二选一;团期按团期产品当前行程生成 | +| 3 | 保存用餐信息(整单,3.3) | POST | `/v3/admin/order/meal-info/save` | 修改 | `orderId` 不再必填,二选一;只传团期ID保存团期行 | +| 4 | 重置用餐信息(3.4) | POST | `/v3/admin/order/meal-info/reset` | 修改 | 新增 `groupBatchId`,二选一;团期删掉自己的行后重新生成 | +| 5 | 套用用餐模版(4.3) | POST | `/v3/admin/order/meal-template/apply` | 修改 | 新增 `groupBatchId`,二选一;同一个模版可套到团期 | + +出参字段一个都没增减。模版查询、存为模版、删除模版不变(模版不分订单、团期)。没有新增错误码。 + +--- + +## 三、接口详情 + +### 1. 查询用餐信息列表 `GET /v3/admin/order/meal-info/list` + +**VO**: `OrderMealInfoListReqVO` → `OrderMealInfoListRespVO` + +#### 使用场景 + +按订单或按团期取用餐行及顶层汇总。两种维度用同一个接口,由传 `orderId` 还是 `groupBatchId` 区分。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| orderId | Query | String | 二选一 | 正数 | 按订单查。**与 `groupBatchId` 必须且只能传一个** | +| groupBatchId | Query | String | 二选一 | 正数 | 按团期查,只返回团期自己的行 | +| batchNo | Query | String | 否 | — | 不参与二选一;只传它按都没传处理(400);与 `orderId` 组合固定查不到数据 | +| 其余筛选 | Query | — | 否 | — | `mealType`、`mealDateStart/End`、`dayNumber`、`settleType`、`keyword`、`limit` 不变 | + +#### 出参字段表 + +| 字段 | 类型 | 说明 | +|------|------|------| +| orderId | String | 按订单查为订单ID;按团期查为 `null` | +| groupBatchId / batchNo | String | 按订单查:**仍回显订单所属团期**(不挂团为 `null`);按团期查:该团期 | +| departDate / returnDate | String | 按订单查:订单出发/返回日期;按团期查:团期出团日期 `depart_date` / 结束日期 `end_date` | +| personCount | Integer | 按订单查:订单人数;按团期查:团期报名人数 | +| orderEditable | Boolean | 按团期查恒为 `true` | +| generated | Boolean | 按团期查:该团期有没有自己的行 | +| items[].orderId / items[].groupBatchId | String | 订单行:`orderId` 有值、`groupBatchId` 为 `null`;团期行:`groupBatchId` 有值、`orderId` 为 `null` | +| items[].batchNo | String | 新写入的行一律为 `null` | + +#### 请求示例 + +```http +GET /v3/admin/order/meal-info/list?groupBatchId=2101996448340238338 +``` + +#### 响应示例 + +```json +{ + "code": 200, + "success": true, + "data": { + "orderId": null, + "groupBatchId": "2101996448340238338", + "batchNo": "Q202611042099750379129368577", + "departDate": "2026-11-04", + "returnDate": "2026-11-08", + "personCount": 4, + "orderEditable": true, + "generated": true, + "totalAmount": 0.00, + "items": [ + { "mealInfoId": "…", "orderId": null, "groupBatchId": "2101996448340238338", "batchNo": null, + "mealType": "LUNCH", "mealDate": "2026-11-04", "dayNumber": 1, "amount": 0.00 } + ] + } +} +``` + +按订单查(订单挂在该团期下)时顶层 `groupBatchId` 仍是 `"2101996448340238338"`,但 `items[].groupBatchId` 为 `null`。 + +#### 空数据 / 降级响应 + +- 团期还没有自己的行:`items: []`、`generated: false`,顶层汇总照常填。 +- 团期里子订单有用餐行、团期自己没有:按团期查仍是 `items: []`。 +- `orderId` + `batchNo`:`items: []`。 + +#### 错误响应 + +```json +{ "code": 400, "message": "订单ID和团期ID只能传一个", "success": false, "data": null } +``` + +都不传(含只传 `batchNo`):`400`「订单ID和团期ID必须传一个」。按团期查没有团期查看权限:`589507`。订单维度的错误码不变。 + +#### 业务边界 + +- 二选一在入参校验阶段判断,先于任何权限、存在性判断。 +- 按团期查只按团期ID取行,不含团里子订单的行;按订单查只返回该订单的行。 +- 顶层 `groupBatchId` 是订单汇总回显,不代表行上存了团期ID。 + +### 2. 生成用餐信息 `POST /v3/admin/order/meal-info/generate` + +**VO**: `OrderMealInfoGenerateReqVO` → `OrderMealInfoListRespVO` + +#### 使用场景 + +订单或团期还没有用餐行时,按产品行程生成空行。团期传 `groupBatchId`。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| orderId | Body | String | 二选一 | 正数 | 按订单产品快照生成(不变) | +| groupBatchId | Body | String | 二选一 | 正数 | **新增**。按团期产品当前行程生成团期行 | + +#### 出参字段表 + +| 字段 | 类型 | 说明 | +|------|------|------| +| 全部字段 | — | 与查询接口同维度的返回一致(团期维度见接口 1) | +| items[].dayNumber | Integer | 团期:第 d 天用餐日期 = `depart_date` + d − 1,天数到 `end_date` | + +#### 请求示例 + +```json +{ "groupBatchId": "2101996448340238338" } +``` + +#### 响应示例 + +```json +{ + "code": 200, + "success": true, + "data": { + "orderId": null, "groupBatchId": "2101996448340238338", + "departDate": "2026-11-04", "returnDate": "2026-11-08", "personCount": 4, "generated": true, + "items": [ + { "orderId": null, "groupBatchId": "2101996448340238338", "mealType": "LUNCH", "mealDate": "2026-11-04", "dayNumber": 1, "amount": 0.00 }, + { "orderId": null, "groupBatchId": "2101996448340238338", "mealType": "DINNER", "mealDate": "2026-11-04", "dayNumber": 1, "amount": 0.00 } + ] + } +} +``` + +#### 空数据 / 降级响应 + +- 团期已有自己的行:不再生成,直接返回现有行(幂等)。 +- 团期 `depart_date` 或 `end_date` 为空:不生成,`code` 200,`message` 带 589602 文案。 +- 行程里含(酒店)/ 自理的餐、行程没有的天不生成;团期产品取不到行程时生成 0 行。 + +#### 错误响应 + +```json +{ "code": 400, "message": "订单ID和团期ID必须传一个", "success": false, "data": null } +``` + +都传:`400`「订单ID和团期ID只能传一个」。团期:无团期管理权限 `589507`、团期不存在 `589500`、`end_date` 早于 `depart_date` `589612`。 + +#### 业务边界 + +- 团期生成的每天每餐取团期产品**当前**行程,不是某张子订单下单时的快照。 +- 团期不按团期状态拦截。 +- 按订单生成的行 `groupBatchId` 为空。 + +### 3. 保存用餐信息(整单) `POST /v3/admin/order/meal-info/save` + +**VO**: `OrderMealInfoBatchSaveReqVO` → `OrderMealInfoListRespVO` + +#### 使用场景 + +一次提交某张订单或某个团期保存后应有的全部行:带行ID覆盖、不带新增、原来有而这次没传的软删。团期**只传 `groupBatchId`**,不要同时传 `orderId`。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| orderId | Body | String | 二选一 | 正数 | **不再必填**。按订单保存 | +| groupBatchId | Body | String | 二选一 | 正数 | **含义变化**:以前是「订单所属团期一致校验」,现在只传它表示按团期保存 | +| items[] | Body | Array | 是 | — | 保存后应有的全部行,字段不变;空数组表示一行都不留 | + +#### 出参字段表 + +| 字段 | 类型 | 说明 | +|------|------|------| +| 全部字段 | — | 与查询接口同维度的返回一致 | +| items[].dayNumber | Integer | 团期行 = 用餐日期 − `depart_date` + 1;`depart_date` 为空时为 `null` | + +#### 请求示例 + +```json +{ + "groupBatchId": "2101996448340238338", + "items": [ + { "mealType": "LUNCH", "mealDate": "2026-11-05", "restaurantName": "…", "dishName": "…", + "unitPrice": 45.00, "tableCount": 0, "personCount": 4, "freePersonCount": 0, + "freeAmount": 0, "otherCost": 0, "amount": 180.00, "settleType": "sign", "settleTypeName": "签单" } + ] +} +``` + +#### 响应示例 + +```json +{ + "code": 200, + "success": true, + "data": { + "orderId": null, "groupBatchId": "2101996448340238338", "departDate": "2026-11-04", + "totalAmount": 180.00, + "items": [ + { "mealInfoId": "…", "orderId": null, "groupBatchId": "2101996448340238338", "batchNo": null, + "mealType": "LUNCH", "mealDate": "2026-11-05", "dayNumber": 2, "amount": 180.00 } + ] + } +} +``` + +#### 空数据 / 降级响应 + +- 团期传 `items: []`:该团期自己的行全部软删,返回 `items: []`,不影响子订单的行。 + +#### 错误响应 + +```json +{ "code": 400, "message": "订单ID和团期ID只能传一个", "success": false, "data": null } +``` + +都不传:`400`「订单ID和团期ID必须传一个」。团期:无团期管理权限 `589507`、团期不存在 `589500`、带的行ID不是本团期自己的行 `589611`、行查不到或已删 `589606`、金额对不上 `589613`。`589601` 不再返回。 + +#### 业务边界 + +- 团期保存只动团期自己的行,软删范围也只在团期自己的行里。 +- 按订单保存新增的行 `groupBatchId` 为空。 +- 任一行校验失败整批不写。 + +### 4. 重置用餐信息 `POST /v3/admin/order/meal-info/reset` + +**VO**: `OrderMealInfoResetReqVO` → `OrderMealInfoListRespVO` + +#### 使用场景 + +删掉某张订单或某个团期自己的全部行,再按生成规则重新生成空行。团期传 `groupBatchId`。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| orderId | Body | String | 二选一 | 正数 | 按订单重置(不变) | +| groupBatchId | Body | String | 二选一 | 正数 | **新增**。按团期重置 | + +#### 出参字段表 + +| 字段 | 类型 | 说明 | +|------|------|------| +| 全部字段 | — | 与接口 2 生成的返回一致 | + +#### 请求示例 + +```json +{ "groupBatchId": "2101996448340238338" } +``` + +#### 响应示例 + +```json +{ + "code": 200, + "success": true, + "data": { + "orderId": null, "groupBatchId": "2101996448340238338", "generated": true, + "items": [ + { "mealInfoId": "…(新行ID)", "orderId": null, "groupBatchId": "2101996448340238338", "mealType": "LUNCH", "mealDate": "2026-11-04", "dayNumber": 1, "amount": 0.00 } + ] + } +} +``` + +#### 空数据 / 降级响应 + +- 团期 `depart_date` 或 `end_date` 为空:原有团期行照样删掉、不生成,`code` 200,`message` 带 589602 文案。 + +#### 错误响应 + +```json +{ "code": 589612, "message": "返回日期早于出发日期,无法生成用餐信息", "success": false, "data": null } +``` + +`end_date` 早于 `depart_date` 时原有行不删。二选一 400、`589507`、`589500` 同接口 2。 + +#### 业务边界 + +- 团期重置只删团期自己的行,子订单的行不动;删和生成一起成功或一起失败。 +- 重置后行ID全部换新。 + +### 5. 套用用餐模版 `POST /v3/admin/order/meal-template/apply` + +**VO**: `MealTemplateApplyReqVO` → `OrderMealInfoListRespVO` + +#### 使用场景 + +把一个模版按出发日铺开,接在现有行后面返回(只读,不写库),确认后再用接口 3 保存。模版不分订单、团期,同一个模版两边都能套。套到团期传 `groupBatchId`。 + +#### 入参字段表 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------|------| +| orderId | Body | String | 二选一 | 正数 | **不再必填**。套到订单 | +| groupBatchId | Body | String | 二选一 | 正数 | **新增**。套到团期 | +| templateId | Body | String | 是 | — | 模版ID(不变) | + +#### 出参字段表 + +| 字段 | 类型 | 说明 | +|------|------|------| +| items[] | Array | 前段是现有行(团期:团期自己的行),后段是模版行(`mealInfoId` 为 `null`) | +| items[].mealDate | String | 团期:模版第 d 日 = `depart_date` + d − 1 | +| items[].personCount | Integer | 团期按人的模版行 = 团期报名人数;按桌为 0 | +| items[].orderId / groupBatchId | String | 套到团期:模版行 `groupBatchId` 有值、`orderId` 为 `null`;套到订单:模版行 `groupBatchId` 为 `null` | +| 其余字段 | — | 与 #8125 相同 | + +#### 请求示例 + +```json +{ "groupBatchId": "2101996448340238338", "templateId": "2102035945748684802" } +``` + +#### 响应示例 + +```json +{ + "code": 200, + "success": true, + "data": { + "orderId": null, "groupBatchId": "2101996448340238338", "departDate": "2026-11-04", "personCount": 4, + "items": [ + { "mealInfoId": "…", "orderId": null, "groupBatchId": "2101996448340238338", "mealType": "LUNCH", "mealDate": "2026-11-05", "dayNumber": 2 }, + { "mealInfoId": null, "orderId": null, "groupBatchId": "2101996448340238338", "mealType": "DINNER", "mealDate": "2026-11-06", "dayNumber": 3, "personCount": 4, "priceUnit": "person" } + ] + } +} +``` + +#### 空数据 / 降级响应 + +- 团期 `depart_date` 为空:只返回团期现有行,`code` 200,`message` 带 589602 文案。 +- 模版没有行:只返回现有行。 + +#### 错误响应 + +```json +{ "code": 400, "message": "订单ID和团期ID只能传一个", "success": false, "data": null } +``` + +都不传:`400`「订单ID和团期ID必须传一个」。团期:无团期管理权限 `589507`、团期不存在 `589500`。 + +#### 业务边界 + +- 套用不写库;保存时把返回的 `items` 原样用接口 3 提交,**套到团期的就只传 `groupBatchId` 提交**。 +- 团期套用的现有行只取团期自己的行,不含子订单的行。 + +--- + +## 四、契约约束与正确调用方式 + +| 场景 | payload | +|------|---------| +| ✅ 团期生成 / 重置 | `{ "groupBatchId": "…" }` | +| ✅ 团期保存 | `{ "groupBatchId": "…", "items": [...] }` | +| ✅ 团期套用 | `{ "groupBatchId": "…", "templateId": "…" }` | +| ✅ 团期查询 | `?groupBatchId=…` | +| ✅ 订单维度 | 只传 `orderId`,其余同改动前 | +| ❌ 两个都传 | `{ "orderId": "…", "groupBatchId": "…" }` → 400「订单ID和团期ID只能传一个」 | +| ❌ 两个都不传 | `{}` / 只传 `batchNo` → 400「订单ID和团期ID必须传一个」 | + +- 挂团订单保存时**不要再带 `groupBatchId`**(以前可带作一致校验,现在会 400)。 +- 团期的出发 / 返回日期、第几天都以后端返回为准(取团期 `depart_date` / `end_date`)。 + +--- + +## 五、数据库行为 + +- 只传 `groupBatchId` 写入的行:团期ID有值,订单ID、团期编号为空。 +- 只传 `orderId` 写入的行:订单ID有值,团期ID、团期编号为空。 +- 团期保存、重置的软删范围只在团期自己的行;子订单的行不受影响。 +- 套用模版不写库。存量数据无需迁移。 + +--- + +## 六、边界行为 + +- 二选一 400 先于权限、存在性判断,库里零写入。 +- 团期写(生成 / 保存 / 重置 / 套用)要团期管理权限,查询要团期查看权限,不足 `589507`;团期不存在 `589500`;不按团期状态拦截。 +- 团期 `depart_date` / `end_date` 为空:生成、重置、套用返回 `code` 200,`message` 为「订单出发或返回日期为空,无法生成用餐信息」(沿用 589602 文案),查询照常。 +- `orderId` + `batchNo` 查询:固定空列表。 + +--- + +## 六.6、修改前后对比 + +### 字段级对比 + +| 字段 | 改动前 | 改动后 | +|---|---|---| +| 3.2 / 3.4 / 4.3 入参 `groupBatchId` | 无 | 新增,与 `orderId` 二选一 | +| 3.3 / 4.3 入参 `orderId` | 必填 | 与 `groupBatchId` 二选一 | +| 3.3 入参 `groupBatchId` | 与订单所属团期一致校验(589601) | 只传它表示按团期保存;与 `orderId` 同传 400 | +| 订单行 `items[].groupBatchId` / `batchNo` | 挂团订单有值 | `null` | + +### 行为级对比 + +| 行为 | 改动前 | 改动后 | +|---|---|---| +| 3.1 只传团期ID | 连同团里子订单的行一起返回,汇总为 null | 只返回团期自己的行,汇总按团期填 | +| 3.1 都不传 | 查没挂订单也没挂团期的行 | 400 | +| 3.1 `orderId` + `batchNo` | 按订单 + 团期编号筛 | 空列表 | +| 3.3 都传 | 按订单保存 | 400 | + +## 六.7、影响评估 + +- **是否破坏向后兼容**: 是。都传、都不传、只传 `batchNo` 由成功变为 400;订单行不再带团期ID +- **前端是否必须同步上线**: 是。挂团订单保存不能再带 `groupBatchId`;团期用餐走只传 `groupBatchId` +- **前端 workaround 清理点**: 挂团订单保存时附带 `groupBatchId` 的处理;依赖订单行 `groupBatchId` / `batchNo` 判断归属的处理 + +## 七、不影响范围 + +- **仅影响**: 上述 5 个用餐接口 +- **零影响**: 模版查询、存为模版、删除模版;金额公式;订单维度的权限与错误码(589601 除外) + +--- + +## 八、测试环境已验证 + +部署提交 `b86e635c7`(含合并提交 `6ae15b3ed`),Deploy Panel 任务 `23cffa4a`;经 Gateway(`https://api.test.1814.love`)用真实 TEST 身份(SUPER_ADMIN)由固定脚本实测 73 项全部通过。团期 `2101996448340238338`(团期编号 `Q202611042099750379129368577`,出团 2026-11-04、结束 2026-11-08、报名 4 人),子订单 `2101996448319266818`: + +``` +只传 groupBatchId 调 3.2 生成 → 12 行,与团期产品当前行程逐天逐餐一致;第 1 天(自理/含营地/含特色餐)只有午、晚 ✓ +生成的行 → groupBatchId=团期、orderId=null、batchNo=null;mealDate=2026-11-04+d−1 ✓ +再调 3.2 → 行数、行ID不变(幂等)✓ +改一行后调 3.4 重置 → 原行全部软删,重新生成与首次逐行一致 ✓ +同一个模版只传 groupBatchId / 只传 orderId 调 4.3 → 两边都能套;团期模版行第 d 日落 2026-11-04+d−1、按人行人数=4、orderId=null ✓ +只传 groupBatchId 调 3.3 保存 2 行 → groupBatchId 有值、orderId=null;dayNumber:11-05→2、11-06→3 ✓ +再保存改一行、少传一行 → 改的变了(105.00),少传的软删 ✓ +子订单按订单保存 1 行后 3.1 按订单查回 → 行上 groupBatchId=null;顶层仍回显所属团期 ✓ +只传 groupBatchId 调 3.1 → 查不到子订单那行,只有团期保存的行 ✓ +3.1/3.2/3.3/3.4/4.3 都传 → 400「订单ID和团期ID只能传一个」(5/5)✓ +3.1/3.2/3.3/3.4/4.3 都不传、3.1 只传 batchNo → 400「订单ID和团期ID必须传一个」(6/6),零写入 ✓ +只传 groupBatchId 调 3.1 → departDate=2026-11-04、returnDate=2026-11-08,与团期详情一致 ✓ +团期不存在 / 带子订单行ID / 带不存在行ID / 金额不符 → 589500 / 589611 / 589606 / 589613,零写入 ✓ +``` + +--- + +## 十、相关文档 + +- 关联 Issue: [wx/HL#8230](https://git.1814.love:8443/wx/HL/issues/8230) +- 关联 PR: [wx/HL#8251](https://git.1814.love:8443/wx/HL/pulls/8251) +- 前置变更: [#8125 套用模版改为在现有行后追加](21_8125_用餐第几天按订单出发日算与套用模版改为在现有行后追加-修改接口-管理后台.md) + +## 关联 / 联系人 + +### 链接 + +- **Issue**: [#8230](https://git.1814.love:8443/wx/HL/issues/8230) +- **PR**: [wx/HL#8251](https://git.1814.love:8443/wx/HL/pulls/8251) +- **Merge commit**: [6ae15b3ed](https://git.1814.love:8443/wx/HL/commit/6ae15b3edaa58cea64c07fce4056fef8a02b551c) + +### 联系人 + +- 后端: @lc