docs(changelog): #8086 餐食不关联餐厅时餐厅名返回 null,分页按餐厅建档先后排序(修改接口·管理后台)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,361 @@
|
|||||||
|
---
|
||||||
|
schema: "hl-changelog/v2"
|
||||||
|
ticket: "8086"
|
||||||
|
title: "餐食不关联餐厅时餐厅名返回 null,分页按餐厅排序"
|
||||||
|
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: "餐食出参 restaurantName 不再对不关联餐厅的餐食返回「全部」,改为 null(分页、下拉、详情一致);餐食分页顺序改为按餐厅建档先后归并、组内创建时间倒序、不关联餐厅的排最后。前端需按本文对接。"
|
||||||
|
updated_at: "2026-09-21"
|
||||||
|
base: "dev-v3"
|
||||||
|
---
|
||||||
|
|
||||||
|
# resource: 餐食不关联餐厅时餐厅名返回 null,分页按餐厅排序
|
||||||
|
|
||||||
|
> **服务**: hl-resource-service
|
||||||
|
> **PR**: #8090
|
||||||
|
> **Issue**: #8086
|
||||||
|
> **日期**: 2026-09-21
|
||||||
|
> **影响范围**: 管理后台「餐食管理」分页、下拉、详情 3 个读接口
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ 关键变化
|
||||||
|
|
||||||
|
- 🔁 **`restaurantName` 不再返回「全部」**:不关联餐厅的餐食,`restaurantName` 由 `"全部"` 改为 `null`;`restaurantId` 仍为 `null`。分页、下拉、详情三个接口口径一致。页面上要显示「全部」由前端在 `restaurantId` 为 `null` 时自行展示。
|
||||||
|
- 🔁 **分页顺序变了**:`GET /admin/dish/items/page` 由「更新时间倒序」改为「按餐厅建档先后归并 → 同一餐厅内创建时间倒序 → 不关联餐厅的整组排最后」。改过的餐食不再被顶到列表最前。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、变更接口清单
|
||||||
|
|
||||||
|
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| 1 | 分页查询餐食 | GET | `/admin/dish/items/page` | 修改 | 出参 `restaurantName` 取值变化;返回顺序变化 |
|
||||||
|
| 2 | 餐食下拉列表 | GET | `/admin/dish/items/list` | 修改 | 出参 `restaurantName` 取值变化;顺序不变 |
|
||||||
|
| 3 | 餐食详情 | GET | `/admin/dish/items/{dishId}/view` | 修改 | 出参 `restaurantName` 取值变化 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、接口详情
|
||||||
|
|
||||||
|
出参 `restaurantName` 的取值口径三个接口完全一致,下表对三处都适用:
|
||||||
|
|
||||||
|
| 情况 | `restaurantId` | 改动前 `restaurantName` | 改动后 `restaurantName` |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 餐食不关联餐厅 | `null` | `"全部"` | `null` |
|
||||||
|
| 关联餐厅,餐厅正常 | 餐厅 ID | 餐厅名称 | 餐厅名称(不变) |
|
||||||
|
| 关联餐厅,餐厅已删除/查不到 | 餐厅 ID | `null` | `null`(不变) |
|
||||||
|
|
||||||
|
### 1. 分页查询餐食 `GET /admin/dish/items/page`
|
||||||
|
|
||||||
|
**VO**: `DishPageReqVO` → `PageResult<DishListItemRespVO>`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
管理后台「餐食管理」列表页。
|
||||||
|
|
||||||
|
#### 入参字段表
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|------|------|------|------|------|------|
|
||||||
|
| 全部入参 | Query | — | — | — | `page`、`pageSize`、`keyword`、`status`、`settleType`、`createdByName` 均不变,本次不新增、不删除入参 |
|
||||||
|
|
||||||
|
不支持自定义排序参数,顺序由后端固定。
|
||||||
|
|
||||||
|
#### 出参字段表
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| records[].restaurantId | String | 餐厅 ID;不关联餐厅为 `null`(不变) |
|
||||||
|
| records[].restaurantName | String | **取值变化**。按上表:不关联餐厅由 `"全部"` 改为 `null` |
|
||||||
|
| records[] 其余字段 | — | `dishId`、`dishName`、`unitPrice`、`priceUnit`、`imageUrl`、`settleType`、`status`、`remark`、`createdBy`、`createdByName`、`createdAt` 均不变 |
|
||||||
|
| total / page / pageSize | — | 不变 |
|
||||||
|
|
||||||
|
**返回顺序变化**,排序键依次为:不关联餐厅的排最后 → 餐厅建档先后(餐厅 ID 升序)→ 同一餐厅内创建时间倒序 → 餐食 ID 倒序。改动前是「更新时间倒序、餐食 ID 倒序」。
|
||||||
|
|
||||||
|
```
|
||||||
|
餐厅甲(建档最早) 其下餐食按创建时间倒序
|
||||||
|
餐厅乙 其下餐食按创建时间倒序
|
||||||
|
…
|
||||||
|
不关联餐厅的餐食 按创建时间倒序,整组排在最后
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /admin/dish/items/page?page=1&pageSize=20
|
||||||
|
Authorization: Bearer <admin token>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"success": true,
|
||||||
|
"data": {
|
||||||
|
"total": 32,
|
||||||
|
"page": 1,
|
||||||
|
"pageSize": 20,
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"dishId": "2100978382416141313",
|
||||||
|
"restaurantId": "2023382100664676353",
|
||||||
|
"restaurantName": "菌香园火锅",
|
||||||
|
"dishName": "儿童餐",
|
||||||
|
"unitPrice": 25.00,
|
||||||
|
"priceUnit": "person",
|
||||||
|
"settleType": "cash",
|
||||||
|
"status": 1,
|
||||||
|
"createdAt": "2026-09-19 00:00:38"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"dishId": "2101571815203901441",
|
||||||
|
"restaurantId": null,
|
||||||
|
"restaurantName": null,
|
||||||
|
"dishName": "全顺车队-特供",
|
||||||
|
"unitPrice": 200.00,
|
||||||
|
"priceUnit": "person",
|
||||||
|
"settleType": "cash",
|
||||||
|
"status": 1,
|
||||||
|
"createdAt": "2026-09-20 15:19:01"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
`records` 为 `[]`、`total` 为 `0`:筛选条件没命中任何未删除餐食。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "code": 400, "message": "每页条数最大为100", "success": false, "data": null }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 翻页按同一顺序切分,不会出现跨页重复或遗漏。
|
||||||
|
- 餐厅被删除后,其下餐食仍按原餐厅的位置排序,不会跑到末尾;末尾只放 `restaurantId` 为 `null` 的餐食。
|
||||||
|
- 同一餐厅内创建时间相同的餐食,按餐食 ID 倒序稳定排列。
|
||||||
|
- 餐食被修改后不再被顶到列表最前(排序基准由更新时间改为创建时间)。
|
||||||
|
|
||||||
|
### 2. 餐食下拉列表 `GET /admin/dish/items/list`
|
||||||
|
|
||||||
|
**VO**: `DishListReqVO` → `List<DishListItemRespVO>`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
餐食下拉数据源。
|
||||||
|
|
||||||
|
#### 入参字段表
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|------|------|------|------|------|------|
|
||||||
|
| 全部入参 | Query | — | — | — | `restaurantId`、`keyword`、`settleType`、`limit` 均不变,本次不新增、不删除入参 |
|
||||||
|
|
||||||
|
#### 出参字段表
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| [].restaurantName | String | **取值变化**。按上表:不关联餐厅由 `"全部"` 改为 `null` |
|
||||||
|
| [] 其余字段 | — | 均不变 |
|
||||||
|
|
||||||
|
返回顺序(创建时间升序、餐食 ID 升序)与条数上限不变。
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /admin/dish/items/list?limit=50
|
||||||
|
Authorization: Bearer <admin token>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"success": true,
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"dishId": "2100767758525329410",
|
||||||
|
"restaurantId": null,
|
||||||
|
"restaurantName": null,
|
||||||
|
"dishName": "GL8车队-特供",
|
||||||
|
"unitPrice": 99999999.99,
|
||||||
|
"priceUnit": "person",
|
||||||
|
"settleType": "company",
|
||||||
|
"status": 1,
|
||||||
|
"createdAt": "2026-09-18 10:03:59"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
`data` 为 `[]`:按当前条件没有上架餐食。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "code": 400, "message": "limit最大为200", "success": false, "data": null }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 本次只改 `restaurantName` 取值,不改该接口返回哪些行、返回顺序与条数上限。
|
||||||
|
- 下架、已删除的餐食任何情况下都不返回。
|
||||||
|
|
||||||
|
### 3. 餐食详情 `GET /admin/dish/items/{dishId}/view`
|
||||||
|
|
||||||
|
**VO**: `Long dishId` → `DishRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
「餐食管理」列表点开编辑时回显单条餐食。
|
||||||
|
|
||||||
|
#### 入参字段表
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|------|------|------|------|------|------|
|
||||||
|
| dishId | Path | String | 是 | 雪花 ID | 餐食 ID(不变) |
|
||||||
|
|
||||||
|
#### 出参字段表
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| restaurantName | String | **取值变化**。按上表:不关联餐厅由 `"全部"` 改为 `null` |
|
||||||
|
| 其余字段 | — | 与分页 `records[]` 相同,均不变 |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /admin/dish/items/2101571815203901441/view
|
||||||
|
Authorization: Bearer <admin token>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"success": true,
|
||||||
|
"data": {
|
||||||
|
"dishId": "2101571815203901441",
|
||||||
|
"restaurantId": null,
|
||||||
|
"restaurantName": null,
|
||||||
|
"dishName": "全顺车队-特供",
|
||||||
|
"unitPrice": 200.00,
|
||||||
|
"priceUnit": "person",
|
||||||
|
"settleType": "cash",
|
||||||
|
"status": 1,
|
||||||
|
"createdAt": "2026-09-20 15:19:01"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
不存在空数据形态;餐食不存在或已删除时走错误响应。
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "code": 340001, "message": "餐食不存在", "success": false, "data": null }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 回显时 `restaurantId` 为 `null` 即该餐食不关联具体餐厅;`restaurantName` 同为 `null`,不再下发「全部」文案。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、契约约束与正确调用方式
|
||||||
|
|
||||||
|
- 判断一条餐食「有没有餐厅」只看 `restaurantId` 是否为 `null`,不要再用 `restaurantName === "全部"` 判断。
|
||||||
|
- 页面需要显示「全部」字样时,前端在 `restaurantId` 为 `null` 时自行渲染;后端不再下发该文案。
|
||||||
|
- 入参不变:新建、修改餐食时不传 `restaurantId` 仍表示该餐食不关联具体餐厅。
|
||||||
|
- 分页不支持自定义排序参数,顺序由后端固定。
|
||||||
|
- 「全部」仍是业务上的一类(不关联具体餐厅的餐食),同期 #8087 的餐食下拉按餐厅联动沿用该语义;本次只是后端不再把「全部」作为 `restaurantName` 的值下发。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、边界行为
|
||||||
|
|
||||||
|
- 餐厅被删除后,其下餐食的 `restaurantName` 为 `null`、`restaurantId` 仍返回原值;该餐食仍按原餐厅的位置排序,不会跑到末尾(末尾只放 `restaurantId` 为 `null` 的餐食)。
|
||||||
|
- 同一餐厅内创建时间相同的餐食,按餐食 ID 倒序稳定排列。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六.6、修改前后对比
|
||||||
|
|
||||||
|
| 项 | 改动前 | 改动后 |
|
||||||
|
|---|---|---|
|
||||||
|
| 不关联餐厅的 `restaurantName` | `"全部"` | `null` |
|
||||||
|
| 分页排序 | `更新时间倒序, 餐食ID倒序` | `不关联餐厅排最后, 餐厅建档先后, 创建时间倒序, 餐食ID倒序` |
|
||||||
|
| 下拉、详情排序与其他字段 | — | 不变 |
|
||||||
|
|
||||||
|
## 六.7、影响评估
|
||||||
|
|
||||||
|
- **是否破坏向后兼容**: 是(依赖 `restaurantName === "全部"` 的前端判断会失效;列表顺序改变)
|
||||||
|
- **前端是否必须同步上线**: 是,按本文改判断条件与「全部」文案渲染
|
||||||
|
- **前端 workaround 清理点**: 去掉对 `restaurantName` 取值 `"全部"` 的依赖
|
||||||
|
|
||||||
|
## 七、不影响范围
|
||||||
|
|
||||||
|
- **仅影响**: 餐食分页、下拉、详情 3 个读接口的 `restaurantName` 取值,以及分页返回顺序
|
||||||
|
- **零影响**:
|
||||||
|
- 餐食新建 `POST /admin/dish/items/add`、修改 `PUT /admin/dish/items/{dishId}/update`、上下架、删除接口与其入参校验
|
||||||
|
- 餐食其余出参字段、分页筛选条件、错误码
|
||||||
|
- 下拉与详情的返回顺序
|
||||||
|
- 餐厅管理接口与 `restaurant` 表
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、测试环境已验证
|
||||||
|
|
||||||
|
部署提交 `3dcbaabef`,经 Gateway 用真实 TEST 身份实测 16 项全部通过:
|
||||||
|
|
||||||
|
```
|
||||||
|
分页 32 条中 20 条不关联餐厅 → restaurantName 全为 null ✓
|
||||||
|
分页 32 条中 12 条关联餐厅 → 仍返回餐厅名称 ✓
|
||||||
|
分页整体顺序 → 不关联餐厅排最后 + 餐厅建档先后 + 组内创建时间倒序 + 餐食ID倒序 ✓
|
||||||
|
4 家餐厅的分组先后 → 菌香园火锅 → 苏日姥爷蒙餐融合菜 → 七间房全羊馆 → 九牧羊鲜羊火锅 ✓
|
||||||
|
不关联餐厅的 20 条 → 整组排在最后,组内创建时间倒序 ✓
|
||||||
|
pageSize=10 逐页拼接 → 与一次取回 50 条的顺序完全一致,不重复不遗漏 ✓
|
||||||
|
详情(不关联餐厅 / 关联餐厅各一条) → null / 餐厅名称 ✓
|
||||||
|
下拉 9 条 → restaurantName 全为 null,顺序与本次改动前完全一致 ✓
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、相关文档
|
||||||
|
|
||||||
|
- 关联 Issue: [wx/HL#8086](https://git.1814.love:8443/wx/HL/issues/8086)
|
||||||
|
- 关联 PR: [wx/HL#8090](https://git.1814.love:8443/wx/HL/pulls/8090)
|
||||||
|
|
||||||
|
## 关联 / 联系人
|
||||||
|
|
||||||
|
### 链接
|
||||||
|
|
||||||
|
- **Issue**: [#8086](https://git.1814.love:8443/wx/HL/issues/8086)
|
||||||
|
- **PR**: [wx/HL#8090](https://git.1814.love:8443/wx/HL/pulls/8090)
|
||||||
|
- **Merge commit**: [3dcbaabef](https://git.1814.love:8443/wx/HL/commit/3dcbaabef8384ec42238b051dbbdd6a8d8e48054)
|
||||||
|
|
||||||
|
### 联系人
|
||||||
|
|
||||||
|
- 后端: @lc
|
||||||
在新工单中引用
屏蔽一个用户