--- schema: "hl-changelog/v2" ticket: "7933" title: "餐食单价说明改为「单价(元)」,不再限定每人每餐" consumer: "admin" author: "lc(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "verified" frontend_owner: "mmg" frontend_ref: "175d2b72dc32574d6eb850051b60d3d1e9d6f0ac" target_release: "" verified_at: "2026-09-18" status_note: "仅告知:餐食接口中 unitPrice 的说明由「单价(每人每餐,元)」改为「单价(元)」,不再限定每人。字段名、类型、必填、校验、取值全部不变,前端无需改代码。[mmg 2026-09-18 复核] 数据链确零改动,但 grep 实证 EditModal 单价 placeholder 残留旧口径「每人每餐,元」(suffix 已有元),移除并注释缘由,spec 加无「每人每餐」残留断言,定向 6/6+scoped checkpoint 全绿;有一处 UI 文案改动故由 not_required 改 verified。" 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` #### 使用场景 餐食管理列表分页查询。本次只有出参 `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 ``` #### 响应示例 ```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` #### 使用场景 餐食下拉数据源。本次只有出参 `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 ``` #### 响应示例 ```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 ``` #### 响应示例 ```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