docs(changelog): #7933 餐食单价说明改为「单价(元)」,不限定每人(修改接口,前端无需改代码)
changelog-filename-gate / validate (push) Failing after 2s

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
这个提交包含在:
lc
2026-09-18 16:05:44 +08:00
共同撰写人 Claude Opus 5
父节点 87ed9d0a3f
当前提交 6fbcb70331
@@ -0,0 +1,486 @@
---
schema: "hl-changelog/v2"
ticket: "7933"
title: "餐食单价说明改为「单价(元)」,不再限定每人每餐"
consumer: "admin"
author: "lc(GIT)"
change_type: "修改接口"
backend_status: "deployed"
gateway_status: "verified"
frontend_status: "not_required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "仅告知:餐食接口中 unitPrice 的说明由「单价(每人每餐,元)」改为「单价(元)」,不再限定每人。字段名、类型、必填、校验、取值全部不变,前端无需改代码。"
updated_at: "2026-09-18"
base: "dev-v3"
---
# resource: 餐食单价说明改为「单价(元)」
> **服务**: hl-resource-service
> **PR**: #7938
> **Issue**: #7933
> **日期**: 2026-09-18
> **影响范围**: 管理后台「餐食管理」接口中 `unitPrice` 的说明文字
---
## ⚠️ 关键变化
📝 **`unitPrice` 的含义从「每人每餐的单价」改为「单价(元)」,不再限定每人。** 订单用餐金额改为按人、按桌两种算法,餐食单价按哪种算由订单用餐决定。#7737 Changelog 里「单价(每人每餐,元,两位小数)」的说明以本文为准。
**前端无需改代码**:字段名、类型、必填、校验、取值全部不变。
---
## 一、背景
订单用餐金额改为按人、按桌两种算法(2026-09-18 定),餐食单价不再只表示每人每餐的价格。
---
## 二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 分页查询餐食 | GET | `/admin/dish/items/page` | 仅说明变化 | 出参 `records[].unitPrice` 说明改为「单价(元)」 |
| 2 | 查询餐食列表 | GET | `/admin/dish/items/list` | 仅说明变化 | 出参 `[].unitPrice` 说明改为「单价(元)」 |
| 3 | 查询餐食详情 | GET | `/admin/dish/items/{dishId}/view` | 仅说明变化 | 出参 `unitPrice` 说明改为「单价(元)」 |
| 4 | 新建餐食 | POST | `/admin/dish/items/add` | 仅说明变化 | 入参 `unitPrice` 说明改为「单价(元)」 |
| 5 | 修改餐食 | PUT | `/admin/dish/items/{dishId}/update` | 仅说明变化 | 入参 `unitPrice` 说明改为「单价(元)」 |
---
## 三、接口详情
### 1. 分页查询餐食 `GET /admin/dish/items/page`
**VO**: `DishPageReqVO` → `PageResult<DishListItemRespVO>`
#### 使用场景
餐食管理列表分页查询。本次只有出参 `unitPrice` 的说明变化。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| keyword | Query | String | 否 | 去首尾空格后 ≤64 | 模糊匹配编码、名称(不变) |
| dishCode | Query | String | 否 | 去首尾空格后 ≤20 | 编码精确匹配(不变) |
| status | Query | Integer | 否 | 0 / 1 | 0=下架,1=上架(不变) |
| settleType | Query | String | 否 | cash / sign / company | 结算方式(不变) |
| createdByName | Query | String | 否 | — | 创建人姓名包含式匹配(不变) |
| page | Query | Integer | 否 | ≥1,默认 1 | 页码(不变) |
| pageSize | Query | Integer | 否 | 1–100,默认 20 | 每页条数(不变) |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| records[].unitPrice | Number | **单价(元)**,两位小数;原说明「单价(每人每餐,元)」 |
| records[] 其余字段、total / page / pageSize | — | 不变 |
#### 请求示例
```http
GET /admin/dish/items/page?page=1&pageSize=20
Authorization: Bearer <admin token>
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"records": [
{
"dishId": "2100767707048636418",
"dishCode": "STANDARD_300",
"dishName": "标准三百快",
"unitPrice": 30.00,
"imageUrl": null,
"settleType": "sign",
"status": 1,
"remark": null,
"createdBy": "1900000000000000001",
"createdByName": "张三",
"createdAt": "2026-09-18 10:02:11"
}
],
"total": 1,
"page": 1,
"pageSize": 20
}
}
```
#### 空数据 / 降级响应
不变:无数据时 `records` 为 `[]`、`total` 为 0。
#### 错误响应
```json
{ "code": 400, "message": "每页条数最大为100", "success": false, "data": null }
```
#### 业务边界
- 返回值与改前逐字段一致,只是 `unitPrice` 不再理解为每人每餐。
---
### 2. 查询餐食列表 `GET /admin/dish/items/list`
**VO**: `DishListReqVO` → `List<DishListItemRespVO>`
#### 使用场景
餐食下拉数据源。本次只有出参 `unitPrice` 的说明变化。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| keyword | Query | String | 否 | 去首尾空格后 ≤64 | 模糊匹配编码、名称(不变) |
| settleType | Query | String | 否 | cash / sign / company | 结算方式(不变) |
| limit | Query | Integer | 否 | 1–200,默认 50 | 最大返回条数(不变) |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| [].unitPrice | Number | **单价(元)**,两位小数;原说明「单价(每人每餐,元)」 |
| [] 其余字段 | — | 不变,同接口 1 的 `records[]` |
#### 请求示例
```http
GET /admin/dish/items/list?limit=50
Authorization: Bearer <admin token>
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": [
{
"dishId": "2100767707048636418",
"dishCode": "STANDARD_300",
"dishName": "标准三百快",
"unitPrice": 30.00,
"imageUrl": null,
"settleType": "sign",
"status": 1,
"remark": null,
"createdBy": "1900000000000000001",
"createdByName": "张三",
"createdAt": "2026-09-18 10:02:11"
}
]
}
```
#### 空数据 / 降级响应
不变:没有上架餐食时 `data` 为 `[]`。
#### 错误响应
```json
{ "code": 400, "message": "limit最大为200", "success": false, "data": null }
```
#### 业务边界
- 返回值与改前逐字段一致,只是 `unitPrice` 不再理解为每人每餐。
---
### 3. 查询餐食详情 `GET /admin/dish/items/{dishId}/view`
**VO**: `DishRespVO`
#### 使用场景
编辑回显。本次只有出参 `unitPrice` 的说明变化。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| dishId | Path | String | 是 | 正数 | 餐食 ID(不变) |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| unitPrice | Number | **单价(元)**,两位小数;原说明「单价(每人每餐,元)」 |
| 其余字段 | — | 不变,同接口 1 的 `records[]` |
#### 请求示例
```http
GET /admin/dish/items/2100767707048636418/view
Authorization: Bearer <admin token>
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"dishId": "2100767707048636418",
"dishCode": "STANDARD_300",
"dishName": "标准三百快",
"unitPrice": 30.00,
"imageUrl": null,
"settleType": "cash",
"status": 1,
"remark": null,
"createdBy": "1900000000000000001",
"createdByName": "张三",
"createdAt": "2026-09-18 10:02:11"
}
}
```
#### 空数据 / 降级响应
不变:无空数据分支,餐食不存在或已删除返回 340001。
#### 错误响应
```json
{ "code": 340001, "message": "餐食不存在", "success": false, "data": null }
```
#### 业务边界
- 返回值与改前逐字段一致,只是 `unitPrice` 不再理解为每人每餐。
---
### 4. 新建餐食 `POST /admin/dish/items/add`
**VO**: `DishCreateReqVO` → `DishWriteRespVO`
#### 使用场景
新建餐食。本次只有入参 `unitPrice` 的说明变化。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| unitPrice | Body | Number | 是 | 0–99999999.99,最多两位小数(不变) | **单价(元)**;原说明「单价(每人每餐,元)」 |
| 其余入参 | Body | — | — | 不变 | dishCode、dishName、imageUrl、settleType、status、remark 全部不变 |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| dishId | String | 新餐食 ID(不变) |
| dishName | String | 餐食名称(不变) |
#### 请求示例
```json
{
"dishCode": "STANDARD_300",
"dishName": "标准三百快",
"unitPrice": 30.00,
"settleType": "sign"
}
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": { "dishId": "2100767707048636418", "dishName": "标准三百快" }
}
```
#### 空数据 / 降级响应
不变:要么 200 写入,要么返回错误码且零写入。
#### 错误响应
单价校验提示不变:
```json
{ "code": 400, "message": "单价最多两位小数", "success": false, "data": null }
```
#### 业务边界
- 单价仍必填,0–99999999.99,最多两位小数;不填、负数、三位小数的提示与改前一致。
---
### 5. 修改餐食 `PUT /admin/dish/items/{dishId}/update`
**VO**: `DishUpdateReqVO` → `DishWriteRespVO`
#### 使用场景
修改餐食(整份覆盖)。本次只有入参 `unitPrice` 的说明变化。
#### 入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| dishId | Path | String | 是 | 正数 | 餐食 ID(不变) |
| unitPrice | Body | Number | 是 | 0–99999999.99,最多两位小数(不变) | **单价(元)**;原说明「单价(每人每餐,元)」 |
| 其余入参 | Body | — | — | 不变 | dishCode、dishName、imageUrl、settleType、status、remark 全部不变 |
#### 出参字段表
| 字段 | 类型 | 说明 |
|------|------|------|
| dishId | String | 餐食 ID(不变) |
| dishName | String | 修改后的名称(不变) |
#### 请求示例
```json
{
"dishCode": "STANDARD_300",
"dishName": "标准三百快",
"unitPrice": 32.00,
"imageUrl": null,
"settleType": "company",
"status": 1,
"remark": null
}
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": { "dishId": "2100767707048636418", "dishName": "标准三百快" }
}
```
#### 空数据 / 降级响应
不变:要么 200 覆盖写入,要么返回错误码且不改动数据。
#### 错误响应
```json
{ "code": 340001, "message": "餐食不存在", "success": false, "data": null }
```
#### 业务边界
- 单价仍必填,0–99999999.99,最多两位小数;不填、负数、三位小数的提示与改前一致。
---
## 四、契约约束与正确调用方式
请求怎么传与改前完全一致,`unitPrice` 仍是必填的两位小数金额。
| 场景 | payload |
|------|---------|
| ✅ 单价 30 元 | `{ "unitPrice": 30.00, ... }` |
| ❌ 不传单价 | 400「单价不能为空」 |
| ❌ 单价 -1 | 400「单价不能小于0」 |
| ❌ 单价 1.234 | 400「单价最多两位小数」 |
---
## 五、数据库行为
不变:新建、修改按传入的单价原样保存两位小数,已有餐食的单价不改。
---
## 六、边界行为
- 未登录 → 401(网关拦截),不变。
- 已有餐食的单价数值不变,只是含义不再限定每人。
---
## 六.6、修改前后对比
### 字段级对比
| 字段 | 改前 | 改后 |
|------|------|------|
| `unitPrice` 说明(接口 1–5) | 单价(每人每餐,元) | 单价(元) |
| `unitPrice` 类型、必填、校验、取值 | — | 不变 |
### 行为级对比
| 行为 | 改前 | 改后 |
|------|------|------|
| 接口入参、出参、校验、返回值 | — | 不变 |
## 六.7、影响评估
- **是否破坏向后兼容**: 否
- **前端是否必须同步上线**: 否,前端无需改代码
- **前端 workaround 清理点**: 无
## 七、不影响范围
- **仅影响**: 餐食接口 1–5 中 `unitPrice` 的说明文字
- **零影响**:
- 餐食上下架 `PUT /admin/dish/items/{dishId}/status/update`、删除 `DELETE /admin/dish/items/{dishId}/del`
- 已有餐食数据
---
## 八、测试环境已验证
部署前后各抓一次比对:
```
Swagger 新建/修改/列表行/详情 4 个模型 unitPrice 说明 → 「单价(每人每餐,元)」改为「单价(元)」 ✓
4 个模型其余字段、7 个餐食接口定义 → 部署前后一致 ✓
GET /admin/dish/items/page、/list、6 个 /{dishId}/view → 返回逐行逐字段一致 ✓
POST /add、PUT /{dishId}/update 单价不填 / -1 / 1.234 → 提示部署前后一致,均未写入 ✓
```
---
## 十、相关文档
- 关联 Issue: [wx/HL#7933](https://git.1814.love:8443/wx/HL/issues/7933)
- 关联 PR: [wx/HL#7938](https://git.1814.love:8443/wx/HL/pulls/7938)
## 关联 / 联系人
### 链接
- **Issue**: [#7933](https://git.1814.love:8443/wx/HL/issues/7933)
- **PR**: [#7938](https://git.1814.love:8443/wx/HL/pulls/7938)
- **Merge commit**: [3acf432c4](https://git.1814.love:8443/wx/HL/commit/3acf432c439b517814b14caa59884ec167ec382f)
### 联系人
- **后端负责人**: @lc