文件
hl-api-changelog/changelogs-v2/2026-09/06_7142_订单详情列表创单响应透出判团字段-修改接口-管理后台.md
T
2026-09-06 16:33:44 +08:00

510 行
18 KiB
Markdown
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
---
schema: "hl-changelog/v2"
ticket: "7142"
title: "订单详情/列表/创单响应透出 groupBatchId·productBatchId·groupOrder 判团字段"
consumer: "admin"
author: "wx(GIT)"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: ""
updated_at: "2026-09-06"
base: "dev-v3"
---
# 订单模块:判团字段透出(详情·列表·创单)
三个订单读接口响应透出判团字段 `groupBatchId` / `productBatchId` / `groupOrder`,供前端判断订单是否为团订单。关键口径:**判团只读 `groupBatchId`(非空=团订单)或 `groupOrder`**;`productBatchId` 仅供溯源,不参与判团。
## ⚠️ 关键变化
- **判团唯一口径** `groupBatchId` 非空或 `groupOrder = true` → 团订单;为空/false → 普通订单。
- **不要拿 `productBatchId` 反推团单**,该字段仅供产品侧班期溯源展示,产品侧可能有多个班期映射同一团期。
- 前一版 #7083 仅涉及订单主表冻结,本次全量透出给前端消费,与主表字段同源。
---
## 二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 订单详情 - 主单数据 | GET | `/v3/admin/order/{id}` | 响应新增字段 | data.main 新增 4 字段 |
| 2 | 订单分页列表 | GET | `/v3/admin/order` | 响应新增字段 | data.list[] 新增 2 字段 |
| 3 | 创建订单 | POST | `/v3/admin/order` | 响应新增字段 | data 新增 3 字段 |
---
## 三、接口详情
### 1. 订单详情 - 主单数据 `GET /v3/admin/order/{id}`
**VO**: `OrderMainVO`(响应位置:`data.main`)
#### 使用场景
打开订单详情页面时,读取订单主单数据及其判团标记,供前端决定显示团期相关内容(如「团期编号」、「团期名称」等)。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| `id` | Path | String | 是 | 正整数 ID | 订单 ID |
#### 出参 `Result<OrderDetailRespVO>`
| 字段 | 类型 | 说明 |
|------|------|------|
| `data.main.groupBatchId` | String/null | 运营团期主键(order_group_batch.group_batch_id);非空=团订单,为空=普通订单 |
| `data.main.productBatchId` | String/null | 产品侧班期 ID(product_v2.group_tour_batch.batch_id);仅供溯源,不参与判团 |
| `data.main.groupOrder` | Boolean | 派生值,= groupBatchId != null;直接用于前端判团 |
| `data.main.batchNo` | String/null | 团期编号(order_group_batch.batch_no);普通单为 null,团期软删也为 null |
| `data.main.batchName` | String/null | 团期名称(order_group_batch.batch_name);普通单为 null,团期软删也为 null |
#### 请求示例
```http
GET /v3/admin/order/2096414445365338113
Authorization: Bearer <token>
```
无请求体。
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"main": {
"id": "2096414445365338113",
"orderNo": "HL20260906094527867",
"orderStatus": "PENDING_PAY",
"orderStatusName": "待支付",
"flowStatus": "AWAITING_PAY",
"flowStatusName": "待补全信息",
"flowStep": 0,
"flowStepTotal": 6,
"totalAmount": "5850.00",
"depositAmount": "1000.00",
"departureDate": "2026-10-01",
"returnDate": "2026-10-03",
"groupBatchId": "2096412454643802114",
"productBatchId": "2052935476557328386",
"groupOrder": true,
"batchNo": "Q202610012052935476548939777",
"batchName": "10月1日长白山亲子团",
"progressStepper": []
},
"profile": {},
"resource": {},
"contract": {},
"insurance": {},
"refund": {},
"aftersale": {},
"financial": {}
}
}
```
#### 空数据 / 降级响应
普通订单时,`groupBatchId`、`productBatchId`、`batchNo`、`batchName` 均为 null;`groupOrder` 为 false。
#### 错误响应
```json
{
"code": 581007,
"message": "订单不存在",
"success": false,
"data": null
}
```
示例错误码:
- 581007:订单不存在
- 581045:房务角色无权查看订单详情(HTTP 200 code)
#### 业务边界
- 沿用订单详情权限校验;业务失败仍为 HTTP 200,需检查 code。
- 普通订单与团单在出参结构上无区别,仅字段值不同(null vs 有值)。
- 团期已软删时,`groupBatchId` 存在但对应记录不可查,`batchNo` / `batchName` 回退为 null。
- `productBatchId` 与 `groupBatchId` 无必然对应,前端不做交叉校验。
---
### 2. 订单分页列表 `GET /v3/admin/order`
别名接口:`GET /v3/admin/order/list`
**VO**: `OrderListItemRespVO`(响应位置:`data.list[]`)
#### 使用场景
订单列表页加载数据时,带上新增的判团标记,供前端快速判断每行是否为团订单,可用于条件展示「团期信息」列或其他团期特化功能。
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| `orderStatus` | Query | String | 否 | 枚举多值(逗号分隔) | 粗状态过滤(PENDING_PAY、CUSTOMIZING 等) |
| `flowStatus` | Query | String | 否 | 枚举多值(逗号分隔) | 细状态过滤(AWAITING_PAY、RESOURCE_PREPARING 等) |
| `tagNames` | Query | Array | 否 | - | 按标签过滤(多标签 OR 关系) |
| `keyword` | Query | String | 否 | - | 搜索关键字(团号/客户姓名/产品名/订单号 LIKE) |
| `departureDateFrom` | Query | String | 否 | yyyy-MM-dd | 出发日期范围起始 |
| `departureDateTo` | Query | String | 否 | yyyy-MM-dd | 出发日期范围结束 |
| `createSource` | Query | String | 否 | - | 来源过滤(CONSULTANT/MP/...) |
| `cancelled` | Query | Boolean | 否 | - | 是否含已取消订单(默认 false) |
| `consultantName` | Query | String | 否 | - | 定制师姓名 LIKE 模糊匹配 |
| `statusGroup` | Query | String | 否 | 枚举单值 | 按 Tab 分组(ALL/BEFORE_TRIP/ON_TRIP/SETTLEMENT/ABNORMAL/AFTERSALE) |
| `page` | Query | Integer | 是 | ≥1 | 页码 |
| `pageSize` | Query | Integer | 是 | ≤100 | 每页条数 |
#### 出参 `Result<Page<OrderListItemRespVO>>`
| 字段 | 类型 | 说明 |
|------|------|------|
| `data.list[].groupBatchId` | String/null | 运营团期主键(order_group_batch.group_batch_id);非空=团订单 |
| `data.list[].groupOrder` | Boolean | 派生值,= groupBatchId != null;直接用于前端判团 |
其他字段详见现有订单列表接口文档。
#### 请求示例
```http
GET /v3/admin/order?page=1&pageSize=20
Authorization: Bearer <token>
```
无请求体。
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"total": 150,
"list": [
{
"id": "2096414445365338113",
"orderNo": "HL20260906094527867",
"productName": "冻干粉发短信给",
"customerName": "张三",
"departureDate": "2026-10-01",
"orderStatus": "PENDING_PAY",
"flowStatus": "AWAITING_PAY",
"totalAmount": "5850.00",
"groupBatchId": "2096412454643802114",
"groupOrder": true
},
{
"id": "2096414445365338114",
"orderNo": "HL20260906094527868",
"productName": "其他产品",
"customerName": "李四",
"departureDate": "2026-10-02",
"orderStatus": "PENDING_DEPARTURE",
"flowStatus": "PENDING_DEPARTURE",
"totalAmount": "8000.00",
"groupBatchId": null,
"groupOrder": false
}
]
}
}
```
#### 空数据 / 降级响应
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"total": 0,
"list": []
}
}
```
#### 错误响应
```json
{
"code": 401,
"message": "未登录或登录已过期",
"success": false,
"data": null
}
```
#### 业务边界
- 分页字段 `page` / `pageSize` 沿用现有约束。
- 列表返回最新 50 条或 100 条时,两个新增字段保证同时返回,不存在部分返回的情况。
- `groupOrder` 是 `groupBatchId != null` 的派生布尔值,前端可二选一使用。
- 普通订单与团单混合返回,字段值直接对标订单属性。
---
### 3. 创建订单 `POST /v3/admin/order`
**VO**: `OrderCreateRespVO`(响应位置:`data`)
#### 使用场景
创建订单后,管理端「订单已创建」弹窗或后续流程需判断该单是否为团单,及时显示团期相关信息(如「团期编号」、「出发日期」等)。
#### 入参
沿用现有 `OrderCreateReqVO`,**请求体不变**(本单只改响应)。字段表:
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| `productId` | Body | String(Long) | ✅ | 正整数 | 产品 ID |
| `tierSeq` | Body | Integer | ✅ | ≥1 | 档位序号 |
| `departureDate` | Body | String(yyyy-MM-dd) | ✅ | 不早于今天 | 出发日期 |
| `adultCount` | Body | Integer | ✅ | ≥1 | 成人数 |
| `childCount` | Body | Integer | 否 | ≥0,默认 0 | 儿童数 |
| `youngChildCount` | Body | Integer | 否 | ≥0,默认 0 | 小童数 |
| `babyCount` | Body | Integer | 否 | ≥0,默认 0 | 婴儿数 |
| `customerName` | Body | String | ✅ | @NotBlank | 客户姓名 |
| `customerPhone` | Body | String | ✅ | ^1[3-9]\d{9}$ | 客户手机号 |
| `customerRemark` | Body | String | 否 | ≤500 | 备注 |
| `createSource` | Body | String | 否 | 默认 CONSULTANT | 创建来源 |
| `productBatchId` | Body | String(Long) | 否 | GROUP 必传、非 GROUP 禁传 | 团期 ID(见 #7135) |
| `roomCount` | Body | Integer | 否 | ≥1 | 房间数 |
| `tags` | Body | Array&lt;String&gt; | 否 | — | 订单标签 |
#### 出参 `Result<OrderCreateRespVO>`
| 字段 | 类型 | 说明 |
|------|------|------|
| `data.id` | String | 订单主键 |
| `data.orderNo` | String | 订单号 |
| `data.orderStatus` | String | 粗状态(创单后为 PENDING_PAY) |
| `data.flowStatus` | String | 细状态(创单后为 AWAITING_PAY) |
| `data.flowStep` | Integer | 线性步序(创单初态为 0) |
| `data.flowStepTotal` | Integer | 总步数(固定 6) |
| `data.productName` | String | 产品名 |
| `data.tierName` | String | 档位名 |
| `data.departureDate` | String | 出发日期 |
| `data.returnDate` | String | 返团日期 |
| `data.totalAmount` | String | 订单总价 |
| `data.depositAmount` | String | 建议定金金额 |
| `data.depositRatio` | Integer/null | 定金比例百分比 |
| `data.depositMode` | String | 定金计算模式(FIXED/RATIO/FULL) |
| `data.paymentMode` | String | 支付模式(DEPOSIT/FULL) |
| `data.groupBatchId` | String/null | 运营团期 ID(创单同事务回写);非空=团订单 |
| `data.productBatchId` | String/null | 产品侧班期 ID(创单入参原样固化);仅供溯源 |
| `data.groupOrder` | Boolean | 派生值,= groupBatchId != null;直接用于判团 |
#### 请求示例
```json
{
"productId": 2044306857534636034,
"tierSeq": 1,
"departureDate": "2026-10-01",
"adultCount": 2,
"childCount": 1,
"customerName": "张三",
"customerPhone": "13800138000",
"productBatchId": 2052935476557328386,
"createSource": "CONSULTANT"
}
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"id": "2096414445365338113",
"orderNo": "HL20260906094527867",
"orderStatus": "PENDING_PAY",
"orderStatusName": "待支付",
"flowStatus": "AWAITING_PAY",
"flowStatusName": "待补全信息",
"flowStep": 0,
"flowStepTotal": 6,
"flowStepName": "待支付",
"productName": "冻干粉发短信给",
"tierName": "经典档",
"departureDate": "2026-10-01",
"returnDate": "2026-10-03",
"totalAmount": "5850.00",
"depositAmount": "1000.00",
"depositRatio": null,
"depositMode": "FIXED",
"paymentMode": "DEPOSIT",
"expiryMinutes": 1440,
"payUrl": "https://pay.hulalv.com/pay/HL20260906094527867",
"customerName": "张三",
"groupBatchId": "2096412454643802114",
"productBatchId": "2052935476557328386",
"groupOrder": true
}
}
```
实测数据示例(2026-09-06 测试服):
- 产品「冻干粉发短信给」productId=2044306857534636034
- 班期 2026-10-01 productBatchId=2052935476557328386
- 团期主键 groupBatchId=2096412454643802114
- 团期编号 batchNo=Q202610012052935476548939777
#### 空数据 / 降级响应
创建订单成功后无空数据响应。
#### 错误响应
```json
{
"code": 400,
"message": "产品 ID 非法或产品已下架",
"success": false,
"data": null
}
```
#### 业务边界
- 创建普通订单时,`groupBatchId` / `productBatchId` 为 null,`groupOrder` 为 false。
- 创建 GROUP 产品订单时(必须提交 `productBatchId`),后端在同事务内懒创建或命中已有团期,回写 `groupBatchId`。
- `groupBatchName` 字段当前恒为 null(仅为兼容既有前端契约),**前端不要读它**。
- 响应中 `groupBatchId` / `productBatchId` 为字符串(JSON 序列化后,避免 JS 精度丢失);前端若需数值运算应转换为字符串存储。
---
## 四、契约约束与正确调用方式
| 场景 | 正确做法 |
|------|---------|
| 判断订单是否团单 | 读 `groupBatchId` 非空 或 `groupOrder == true`,两者等价 |
| 不要用 productBatchId 判团 | `productBatchId` 仅供溯源,可能 null(普通单)或有值(团单/非团单均可能) |
| 团单需显示团期名 | `groupBatchName` 恒为 null,读 `batchName`;团期软删时也为 null |
| 普通单与团单混合渲染 | 按 `groupOrder` 条件渲染,普通单该字段为 false;两类订单出参结构一致,仅值不同 |
---
## 五、数据库行为
| 订单类型 | groupBatchId | productBatchId | groupOrder | batchNo | batchName |
|---------|-------------|----------------|-----------|---------|-----------|
| 普通订单 | null | null | false | null | null |
| 团单(命中或懒建) | 非空 | 非空 | true | 有值 | 有值 |
| 团期已软删 | 非空 | 非空 | true | null | null |
---
## 六、边界行为
- 业务失败可能仍为 HTTP 200,必须同时检查 `code`、`success` 和 `message`。
- 详情接口 404/权限 403 时直接返回对应 HTTP 状态码;业务类失败(如订单状态不符)返回 HTTP 200 + code。
- 列表空结果返回 `total=0, list=[]`,分页参数超界时返回空列表(无 5XX)。
- 创单失败不落库,响应 HTTP 200 + code,data 为 null。
- 新增判团字段与现有字段同源、同时刷新,无时间差。
---
## 六.6、修改前后对比
### 字段级对比
| 字段 | 改前 | 改后 |
|------|------|------|
| `groupBatchId` | 无此字段 | 新增;运营团期主键 |
| `productBatchId` | 无此字段 | 新增;产品班期 ID(仅溯源) |
| `groupOrder` | 无此字段 | 新增;派生布尔,= groupBatchId != null |
| `batchNo` | 无此字段 | 新增;团期编号(详情/列表) |
| `batchName` | 无此字段 | 新增;团期名称(详情/列表) |
### 行为级对比
| 行为 | 改前 | 改后 |
|------|------|------|
| 前端判团依据 | 无判团字段,无法直接判别 | 读 groupBatchId 非空 或 groupOrder = true |
| 团单信息展示 | 依赖联查或额外接口 | 直接在订单响应中获得 |
| 产品班期溯源 | 不支持 | 新增 productBatchId(仅溯源展示) |
---
## 六.7、影响评估
- **是否破坏向后兼容**: 否。新增字段对旧客户端透明,非必需字段缺失时前端框架可靠 null 处理。
- **前端是否必须同步上线**: 是。前端需接入新增四个字段至详情/列表/创建成功弹窗模板,判团逻辑改用 groupBatchId 或 groupOrder。
- **前端 workaround 清理点**:
- 删除旧的"通过产品 ID 推断团单"逻辑,改用 groupBatchId 判别
- 不要硬编码团期编号/名称,改用响应中的 batchNo / batchName
- groupBatchName 恒为 null,勿读之;用 batchName 替代
---
## 七、不影响范围
- **仅影响**: 管理后台订单详情、列表和创建流程的前端渲染
- **零影响**:
- 订单创建/编辑/取消接口
- 小程序端(MpOrderDetailVO 不变)
- 数据库结构(新字段冻结在 order_main 表,无表改动)
- 订单写操作和业务流程
---
## 八、测试环境已验证
- **单测**: 559 条测试用例绿✓(新增判团字段相关的 UT 已覆盖普通单/团单双路径)
- **ArchTest**: 45 条架构测试绿✓
- **测试服网关实测**: 单测 + CR 通过;测试服网关实测见管理者补充
实测产品: `productId=2044306857534636034`(冻干粉发短信给),班期 `2026-10-01`(productBatchId=2052935476557328386),团期主键 `groupBatchId=2096412454643802114`,批号 `batchNo=Q202610012052935476548939777`。
---
## 九、相关历史 PR(功能演进)
| PR | Issue | 说明 | 是否仍有效 |
|----|-------|------|------------|
| #7083 | - | order_group_batch 一跳直连,订单主表冻结 groupBatchId/productBatchId | ✅ 有效 |
| #7135 | - | GROUP 产品创单校验与重整 | ✅ 有效 |
| #7143 | - | 团期看板 VO 补 productId(配合本 PR) | ✅ 有效 |
| **本 PR #7155** | **#7142** | **订单详情/列表/创单响应透出判团字段** | ✅ 最新 |
---
## 十、相关文档
- 关联 Issue: [wx/HL#7142](https://git.1814.love:8443/wx/HL/issues/7142)
- 关联 PR: [wx/HL#7155](https://git.1814.love:8443/wx/HL/pulls/7155)
- 团期接口文档: `docs/ARCHITECTURE.md` §0A.2.2(团单冻结口径)
- 团单业务规范: 见 #7135 changelog 中的团期创建规则
## 关联 / 联系人
### 链接
- **Issue**: [#7142](https://git.1814.love:8443/wx/HL/issues/7142)
- **PR**: [#7155](https://git.1814.love:8443/wx/HL/pulls/7155)
- **Merge commit**: [21d3d00de](https://git.1814.love:8443/wx/HL/commit/21d3d00de)
### 联系人
- **后端负责人**: @wx