文件
hl-api-changelog/changelogs-v2/2026-09/18_7737_餐食管理接口-新增接口-管理后台.md
T
Mimingguang 265dcd0408
changelog-filename-gate / validate (push) Failing after 1s
docs(changelog): #7737 餐食管理前端已实现并验证(hl-admin 7d18b442)
frontend_status pending→verified,frontend_owner=mmg,
frontend_ref=7d18b442071bb50db9d260cb80224f9e413f3058,status_note 追加实现摘要。
2026-09-18 11:37:47 +08:00

16 KiB
原始文件 Blame 文件历史

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 7737 餐食管理接口(分页、下拉、详情、新建、修改、上下架、删除) admin lc(GIT) 新增接口 deployed verified verified mmg 7d18b442071bb50db9d260cb80224f9e413f3058 2026-09-18 新增 7 个接口与「资源管理 → 餐食管理」菜单(component 为 /resource/dish)。前端需新做餐食管理页面并按本文契约对接。[mmg 2026-09-18 已实现并验证] 新建 src/api/dish.js(7 函数+DISH_STATUS 0/1 原码字典+statusMeta 兜底;cleanQuery 空值剥离 status=0 保留;ID String 透传;四写 cancelDuplicate:false)与 src/views/resource/dish/ 页面(import.meta.glob 自动映射不改路由;useListPage 筛选 keyword 模糊/settleType 字典/status/createdByName;列含单价千分位/结算方式字典空显-/状态 tag 原码;行操作[编辑,上下架|删除] renderActionsWithMore;EditModal 必填三项 NForm rules,新建选填空值不带键,编辑 view 回填后整份提交可选传 null)。定向 20/20 + checkpoint 全绿。 2026-09-18 dev-v3

resource/user/gateway: 餐食管理接口

服务: hl-resource-service(接口)、hl-user-service(菜单)、hl-gateway(路由) PR: #7918 Issue: #7737


⚠️ 关键变化

🔴 新增 7 个接口,路径前缀 /admin/dish/items。 餐食不关联餐厅;下拉(1.2)只返回上架餐食,不按餐厅过滤。

🔴 新增菜单「资源管理 → 餐食管理」:menu_id 422,path /dish/list,component /resource/dish,与「餐厅管理」同级同排序;已授权超级管理员、管理员、定制师。前端需按该 component 路径提供页面。

🔴 新建不传 settleType 时存 cash(现付);修改是整份覆盖,imageUrl / settleType / remark 传 null 即清空。


一、背景

新增「餐食管理」:维护餐食(编码、名称、单价、图片、结算方式、上下架),供订单「用餐」选用。系统不预置任何餐食。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 分页查询餐食 GET /admin/dish/items/page 新增 餐食管理列表
2 查询餐食列表 GET /admin/dish/items/list 新增 下拉用,只返回上架
3 查询餐食详情 GET /admin/dish/items/{dishId}/view 新增 编辑回显
4 新建餐食 POST /admin/dish/items/add 新增 默认上架、默认现付
5 修改餐食 PUT /admin/dish/items/{dishId}/update 新增 整份覆盖
6 上架 / 下架餐食 PUT /admin/dish/items/{dishId}/status/update 新增 不走审批,立即生效
7 删除餐食 DELETE /admin/dish/items/{dishId}/del 新增 软删除,不检查是否在用

三、接口详情

1. 分页查询餐食 GET /admin/dish/items/page

VO: DishPageReqVO → PageResult<DishListItemRespVO>

使用场景

餐食管理列表分页查询。

入参字段表

字段 位置 类型 必填 约束 说明
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[].dishId String 餐食 ID(雪花,字符串)
records[].dishCode String 编码
records[].dishName String 餐食名称
records[].unitPrice Number 单价(每人每餐,元,两位小数)
records[].imageUrl String 图片 URL,可为 null
records[].settleType String 结算方式,字典 resource_settle_type:cash / sign / company,可为 null
records[].status Integer 0=下架,1=上架
records[].remark String 备注,可为 null
records[].createdBy String 创建人 ID
records[].createdByName String 创建人姓名(企微姓名优先,没有取管理员用户名);查不到为 null
records[].createdAt String 创建时间 yyyy-MM-dd HH:mm:ss
total / page / pageSize Integer 总条数、当前页、每页条数

请求示例

GET /admin/dish/items/page?keyword=三百&status=1&page=1&pageSize=20
Authorization: Bearer <admin token>

响应示例

{
  "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。创建人姓名查询失败时 createdByName 为 null,列表照常返回;按创建人姓名筛选而无匹配时返回空页。

错误响应

{ "code": 400, "message": "每页条数最大为100", "success": false, "data": null }

业务边界

  • 只查未删除餐食,各条件之间是「并且」。
  • 按更新时间倒序、餐食 ID 倒序。

2. 查询餐食列表 GET /admin/dish/items/list

VO: DishListReqVO → List<DishListItemRespVO>

使用场景

下拉数据源:订单「用餐」的餐食选择、保存模版时选餐食。

入参字段表

字段 位置 类型 必填 约束 说明
keyword Query String 否 去首尾空格后 ≤64 模糊匹配编码、名称
settleType Query String 否 cash / sign / company 结算方式
limit Query Integer 否 1–200,默认 50 最大返回条数

出参字段表

字段 类型 说明
[] Array 每项字段同接口 1 的 records[],status 恒为 1

请求示例

GET /admin/dish/items/list?limit=50
Authorization: Bearer <admin token>

响应示例

{
  "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 为 []。

错误响应

{ "code": 400, "message": "limit最大为200", "success": false, "data": null }

业务边界

  • 只返回未删除且上架的餐食;下架后立即查不到,重新上架后恢复。
  • 不按餐厅过滤;按创建时间升序、餐食 ID 升序。

3. 查询餐食详情 GET /admin/dish/items/{dishId}/view

VO: DishRespVO

使用场景

编辑回显。

入参字段表

字段 位置 类型 必填 约束 说明
dishId Path String 是 正数 餐食 ID

出参字段表

字段 类型 说明
(同接口 1 的 records[]) — 字段完全一致

请求示例

GET /admin/dish/items/2100767707048636418/view
Authorization: Bearer <admin token>

响应示例

{
  "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。

错误响应

{ "code": 340001, "message": "餐食不存在", "success": false, "data": null }

业务边界

  • dishId 非正数或非数字返回 400。

4. 新建餐食 POST /admin/dish/items/add

VO: DishCreateReqVO → DishWriteRespVO

使用场景

新建餐食;新建默认上架,不走审批。

入参字段表

字段 位置 类型 必填 约束 说明
dishCode Body String 是 去首尾空格后 1–20 编码,未删除餐食内不能重复
dishName Body String 是 去首尾空格后 1–500 餐食名称,未删除餐食内不能重复
unitPrice Body Number 是 0–99999999.99,最多两位小数 单价
imageUrl Body String 否 ≤65535 图片 URL
settleType Body String 否 cash / sign / company 结算方式;不传存 cash
status Body Integer 否 0 / 1 不传为 1(上架)
remark Body String 否 ≤500 备注

出参字段表

字段 类型 说明
dishId String 新餐食 ID
dishName String 餐食名称

请求示例

{
  "dishCode": "STANDARD_300",
  "dishName": "标准三百快",
  "unitPrice": 30.00,
  "settleType": "sign"
}

响应示例

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": { "dishId": "2100767707048636418", "dishName": "标准三百快" }
}

空数据 / 降级响应

无降级:要么 200 写入,要么返回错误码且零写入。

错误响应

{ "code": 340002, "message": "编码已存在:STANDARD_300", "success": false, "data": null }
{ "code": 340003, "message": "餐食名称已存在:标准三百快", "success": false, "data": null }

业务边界

  • 字符串入参先去首尾空格,再校验长度、查重。
  • 编码、名称只在未删除餐食内唯一;删除后同编码、同名称可以重新新建。

5. 修改餐食 PUT /admin/dish/items/{dishId}/update

VO: DishUpdateReqVO → DishWriteRespVO

使用场景

修改餐食全部字段(整份覆盖)。

入参字段表

字段 位置 类型 必填 约束 说明
dishId Path String 是 正数 餐食 ID
dishCode Body String 是 去首尾空格后 1–20 未删除餐食内不能重复(排除自己)
dishName Body String 是 去首尾空格后 1–500 未删除餐食内不能重复(排除自己)
unitPrice Body Number 是 0–99999999.99,最多两位小数 单价
imageUrl Body String 否 ≤65535 传 null 清空
settleType Body String 否 cash / sign / company 传 null 清空
status Body Integer 是 0 / 1 状态
remark Body String 否 ≤500 传 null 清空

出参字段表

字段 类型 说明
dishId String 餐食 ID
dishName String 修改后的名称

请求示例

{
  "dishCode": "STANDARD_300",
  "dishName": "标准三百快",
  "unitPrice": 32.00,
  "imageUrl": null,
  "settleType": "company",
  "status": 1,
  "remark": null
}

响应示例

{
  "code": 200,
  "message": "成功",
  "success": true,
  "data": { "dishId": "2100767707048636418", "dishName": "标准三百快" }
}

空数据 / 降级响应

无降级:要么 200 覆盖写入,要么返回错误码且不改动数据。

错误响应

{ "code": 340001, "message": "餐食不存在", "success": false, "data": null }

业务边界

  • 整份覆盖:未传或传 null 的可选字段会被清空,编辑前先调接口 3 读回全量。
  • 编码重复 340002、名称重复 340003;已生成的订单用餐信息不受修改影响。

6. 上架 / 下架餐食 PUT /admin/dish/items/{dishId}/status/update

VO: DishStatusUpdateReqVO

使用场景

切换上下架,不走审批,立即生效。

入参字段表

字段 位置 类型 必填 约束 说明
dishId Path String 是 正数 餐食 ID
status Body Integer 是 0 / 1 0=下架,1=上架

出参字段表

字段 类型 说明
data null 无返回数据

请求示例

{ "status": 0 }

响应示例

{ "code": 200, "message": "成功", "success": true, "data": null }

空数据 / 降级响应

状态没变化直接返回成功。

错误响应

{ "code": 340001, "message": "餐食不存在", "success": false, "data": null }

业务边界

  • 下架后接口 2 立即查不到;重新上架后恢复。

7. 删除餐食 DELETE /admin/dish/items/{dishId}/del

VO: Result<Void>(无请求体)

使用场景

软删除餐食。

入参字段表

字段 位置 类型 必填 约束 说明
dishId Path String 是 正数 餐食 ID

出参字段表

字段 类型 说明
data null 无返回数据

请求示例

DELETE /admin/dish/items/2100767707048636418/del
Authorization: Bearer <admin token>

响应示例

{ "code": 200, "message": "成功", "success": true, "data": null }

空数据 / 降级响应

无降级:已删除的餐食再删返回 340001。

错误响应

{ "code": 340001, "message": "餐食不存在", "success": false, "data": null }

业务边界

  • 不检查是否被模版或订单用过;删除后同编码、同名称可以重新新建。

四、契约约束与正确调用方式

  • ID 均为字符串,原样透传,不要转成数字。
  • 编辑流程:接口 3 读全量 → 修改 → 接口 5 整份提交;可选字段不传即清空。
  • 结算方式取值见字典 resource_settle_type(cash 现付 / sign 签单 / company 公司付款)。
  • 参数校验失败统一返回 code=400 与中文提示;业务错误码见各接口。

五、数据库行为

  • 新建、修改、上下架、删除都只写餐食数据;删除为软删除,删除后同编码、同名称可重建。
  • 失败请求(参数校验、重复、不存在)零写入。
  • 写接口记操作日志,模块「餐食管理」。

六、边界行为

场景 行为
新建不传 settleType / status 存 cash、上架
编码或名称前后带空格 去掉后保存、查重
编码与未删除餐食重复 340002,零写入
名称与未删除餐食重复 340003,零写入
餐食不存在或已删除(详情/修改/上下架/删除) 340001
上下架目标状态与当前相同 200,不改数据
下架后调接口 2 查不到;重新上架后恢复
删除后用同编码、同名称新建 200,得到新 ID

七、不影响范围

  • 既有接口、既有错误码不变;餐厅选项接口 /admin/resource-options/restaurants 不变。
  • 产品行程天仍用字典 meal_option,不接餐食。

八、测试环境已验证

TEST 已部署 dev-v3 00e882be4(hl-resource-service、hl-user-service、hl-gateway),经网关用管理员身份逐项实测:7 个接口的入参边界与出参字段、新建默认现付与上架、340001/340002/340003、下架后下拉不返回与重新上架恢复、删除后同编码同名称重建、「资源管理」下出现「餐食管理」菜单,全部通过。


十、相关文档


关联 / 联系人

  • 后端:@lc