修复 商品选择列表接口 500 错误 (PR #746)
这个提交包含在:
父节点
b48b46578b
当前提交
b1daf3f132
@ -0,0 +1,161 @@
|
|||||||
|
# 修复 商品选择列表接口 500 错误
|
||||||
|
|
||||||
|
- **日期**: 2026-04-17
|
||||||
|
- **服务**: hl-product-service-v2(端口 8083)
|
||||||
|
- **类型**: BUG 修复(非破坏性)
|
||||||
|
- **前端影响**: **无需改动**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 修复说明
|
||||||
|
|
||||||
|
### 现象
|
||||||
|
|
||||||
|
调用订单创建「选择商品」弹窗的商品列表接口时,**100% 返回 500**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 500,
|
||||||
|
"message": "服务器内部错误",
|
||||||
|
"data": null,
|
||||||
|
"success": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
该接口一上线就无法使用,前端弹窗里产品列表始终为空。
|
||||||
|
|
||||||
|
### 根因
|
||||||
|
|
||||||
|
Mapper 使用 `selectAll(ProductDO.class)` 把 `ProductDO` 所有字段映射到 VO。其中:
|
||||||
|
|
||||||
|
- 实体 `ProductDO.tiers` 是 **String 类型(存 JSON 字符串)**
|
||||||
|
- VO `ProductSimpleItemRespVO.tiers` 是 **`List<TierItem>`(结构化列表)**
|
||||||
|
|
||||||
|
MyBatis-Plus Join 在构造 ResultMap 阶段发现同名字段类型不一致,抛 `IllegalStateException`,整个请求返回 500。
|
||||||
|
|
||||||
|
### 修复方式
|
||||||
|
|
||||||
|
Mapper 改为**显式 selectFields**,只映射基础字段;`tiers` 字段由 Service 层单独查 `ProductTierDO` 表并解析为结构化列表再塞回 VO。
|
||||||
|
|
||||||
|
对前端而言:**接口路径、请求参数、响应结构完全不变**,原来调不通的接口现在正常返回数据。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 接口信息
|
||||||
|
|
||||||
|
### 请求
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /admin/product/item/simple-list
|
||||||
|
```
|
||||||
|
|
||||||
|
**Header**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Authorization: Bearer {token}
|
||||||
|
tenant-id: {租户ID}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查询参数
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| productType | String | 否 | 产品类型(`CORE`=核心产品,`GROUP`=小蒙马),不传=全部 |
|
||||||
|
| keyword | String | 否 | 搜索关键词(匹配产品名称) |
|
||||||
|
| pageNo | Integer | 否 | 页码,默认 1 |
|
||||||
|
| pageSize | Integer | 否 | 每页条数,默认 50 |
|
||||||
|
|
||||||
|
> 后端固定只返回**已上架**(status=PUBLISHED)的产品,前端不需要传 status。
|
||||||
|
|
||||||
|
### 响应字段
|
||||||
|
|
||||||
|
外层(`data`):
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| records | Array | 产品列表 |
|
||||||
|
| total | Long | 总数 |
|
||||||
|
|
||||||
|
`records` 数组中每一项:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| productId | Long | 产品ID(JSON 序列化为字符串防精度丢失) |
|
||||||
|
| productNo | String | 产品编号(如 `C260416002`) |
|
||||||
|
| name | String | 产品名称 |
|
||||||
|
| tripDays | Integer | 行程天数 |
|
||||||
|
| lineName | String | 所属产品线名称(LEFT JOIN 查出) |
|
||||||
|
| tiers | Array | 该产品的档位列表(可能为空数组) |
|
||||||
|
|
||||||
|
`tiers` 数组中每一项(档位):
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| tierSeq | Integer | 档位序号(1 开始) |
|
||||||
|
| tierName | String | 档位名称(如 `舒适`、`豪华`) |
|
||||||
|
| tierDescription | String | 档位描述,可能为空字符串 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 完整请求示例
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /admin/product/item/simple-list?productType=CORE&pageNo=1&pageSize=20
|
||||||
|
Authorization: Bearer eyJxxx...
|
||||||
|
tenant-id: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## 完整响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"productId": "2044704111294672897",
|
||||||
|
"productNo": "C260416002",
|
||||||
|
"name": "嗨冰雪3.0南线(6天5晚)",
|
||||||
|
"tripDays": 6,
|
||||||
|
"lineName": "嗨冰雪",
|
||||||
|
"tiers": [
|
||||||
|
{ "tierSeq": 1, "tierName": "舒适", "tierDescription": "" },
|
||||||
|
{ "tierSeq": 2, "tierName": "豪华", "tierDescription": "" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 5
|
||||||
|
},
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 前端无需改动
|
||||||
|
|
||||||
|
> 🟢 **该修复纯属后端 Bug 修复,前端不需要任何调整。**
|
||||||
|
>
|
||||||
|
> - 接口路径:**不变**
|
||||||
|
> - 请求参数:**不变**
|
||||||
|
> - 响应字段结构:**不变**
|
||||||
|
> - 错误码/成功码:**不变**
|
||||||
|
>
|
||||||
|
> 此前调用此接口拿到 500 的地方,现在可以正常拿到数据;已经写好的调用代码无需修改。
|
||||||
|
|
||||||
|
如果之前前端为了"兼容 500"加过 try/catch 降级逻辑,可以保留,不会有副作用。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 重启服务
|
||||||
|
|
||||||
|
- `hl-product-service-v2`(端口 8083)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 关联信息
|
||||||
|
|
||||||
|
- **Issue**: #745
|
||||||
|
- **PR**: #746(已合并到 dev)
|
||||||
|
- **Commit**: `cfd901e5`
|
||||||
正在加载...
x
在新工单中引用
屏蔽一个用户