510 行
18 KiB
Markdown
510 行
18 KiB
Markdown
---
|
||
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<String> | 否 | — | 订单标签 |
|
||
|
||
#### 出参 `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
|