Files
IntelligentShelves/货柜设备端-API文档.md
T
lvmeng a78eaf7233 feat(app): 集成V3货柜管理功能
- 将应用包名从com.shuwei.intelligent.shelves迁移至com.sw.scalefusion.shelf
- 更新AndroidManifest.xml中的Activity声明路径以匹配新包名
- 在InitActivity中同步更新包名引用及依赖导入
- 修改GridLayoutTool工具类适配V3货柜布局排序逻辑
- 新增ApiResponse和BaseRepository统一网络响应处理
- 添加V3 API服务定义支持毛菜柜/净菜柜功能
- 新增HomeV3Activity和ShelfV3Activity实现新版货柜界面
- 集成API文档定义的货柜初始化、入柜、同步重量等核心功能
- 添加SlotModel等数据模型支持V3货柜操作
- 更新ProtocolConstants增加设备类型映射配置
- 重构网络管理层实现V2/V3接口实例分离管理
2026-06-24 17:39:44 +08:00

5.9 KiB
Raw Blame History

货柜设备端 — API 文档

Controller: NutCabinetController(毛菜柜/净菜柜通用,通过 cabinetType 区分) 路径前缀: /neglect/mater-cabinetNacos 白名单,无需 Sa-Token 日期: 2026-06-24


一、货柜初始化

设备端首次加载调用,后端从 nut_terminal.device_type 推导毛菜/净菜类型,懒创建空置格口,返回柜体元信息 + 全量格口。

GET /neglect/mater-cabinet/init?cabinetId=CAB-001

参数cabinetId — 必填,智能柜编号(即 nut_terminal.device_code

响应

{
  "cabinetType": 1,             // 1=毛菜柜,2=净菜柜(后端推导)
  "cabinetId": "CAB-001",
  "deviceName": "毛菜柜-A区",
  "canteenId": 100,
  "canteenName": "第一食堂",
  "horizontalRows": 4,
  "verticalCount": 5,
  "slots": [
    {
      "id": 1,
      "slotNo": "1",
      "cabinetId": "CAB-001",
      "cabinetType": 1,
      "hasContent": true,
      "inboundNo": "IN20260623001",
      "materId": 10001,
      "materName": "菠菜",
      "traceCode": "TC20260601",
      "vegTypeId": 10,
      "weight": 5.2,
      "storeTime": "2026-06-23 10:30:00"
    },
    {
      "id": null,
      "slotNo": "2",
      "cabinetId": "CAB-001",
      "cabinetType": 1,
      "hasContent": false,
      "weight": null,
      "storeTime": null
    }
  ]
}

说明

  • cabinetType 由后端根据 nut_terminal.device_type 推导(raw_cabinet→1 / clean_cabinet→2),前端无需传
  • hasContent=true 时有存放数据,业务字段(inboundNo/materId 等)有值
  • hasContent=false 时空置,业务字段均为 null
  • 格口按 slotNo 数值升序排列
  • 每次调用均幂等:格口数不足时自动补建,已足则跳过

二、格口入柜

POST /neglect/mater-cabinet/put

请求体

{
  "cabinetType": 1,          // 必填 — 1=毛菜柜,2=净菜柜
  "cabinetId": "CAB-001",    // 必填 — 智能柜编号
  "slotNo": "1",             // 必填 — 格口编号
  "materId": 10001,          // 必填 — 食材id
  "materName": "菠菜",        // 必填 — 食材名称
  "traceCode": "TC20260601", // 选填 — 溯源码(净菜柜用于精确匹配)
  "weight": 5.2              // 必填 — 入柜重量(kg)
}

说明

  • 后端按食材+重量匹配对应入库记录(选重量最接近的一条),将其标记为"已入柜"
  • 传 traceCode 时先按溯源码精确过滤,再按重量匹配
  • 格口必须已由 /init 预置,否则报错"格口未初始化"
  • 格口已有物品时拒绝入柜
  • 格口行 UPDATE,流水表 INSERT

响应

{ "code": 200, "data": "IN20260623001", "msg": "操作成功" }

三、格口列表(全部格口)

POST /neglect/mater-cabinet/slots

请求体

{
  "cabinetType": 1,       // 必填 — 1=毛菜柜,2=净菜柜
  "cabinetId": "CAB-001"  // 必填 — 智能柜编号
}

响应 — 与 /init 返回的 slots 字段结构完全相同

[{
  "id": 1,
  "slotNo": "1",
  "cabinetId": "CAB-001",
  "cabinetType": 1,
  "hasContent": true,
  "inboundNo": "IN20260623001",
  "materId": 10001,
  "materName": "菠菜",
  "traceCode": "TC20260601",
  "vegTypeId": 10,
  "weight": 5.2,
  "storeTime": "2026-06-23 10:30:00"
}]

四、待入柜列表

POST /neglect/mater-cabinet/pending-inbound

请求体

{
  "cabinetType": 1,       // 必填 — 货柜类型
  "cabinetId": "CAB-001", // 必填 — 智能柜编号(DTO 校验要求,实际查询用 canteenId)
  "canteenId": 100        // 必填 — 食堂id
}

响应

[{
  "id": 1,
  "materId": 10001,
  "materName": "菠菜",
  "traceCode": "TC20260601",
  "weight": 10.0,
  "inboundNo": "IN20260623001",
  "inboundTime": "2026-06-23 09:00:00",
  "vegTypeId": 10,
  "vegTypeName": "净菜包",
  "spec": "500g"
}]

五、格口详情

POST /neglect/mater-cabinet/slot-detail

请求体

{
  "cabinetType": 1,       // 必填
  "cabinetId": "CAB-001", // 必填
  "slotNo": "1"           // 必填
}

响应 — 与 /init 返回的 slots 元素结构相同

{
  "id": 1,
  "slotNo": "1",
  "cabinetId": "CAB-001",
  "cabinetType": 1,
  "hasContent": true,
  "inboundNo": "IN20260623001",
  "materId": 10001,
  "materName": "菠菜",
  "traceCode": "TC20260601",
  "vegTypeId": 10,
  "weight": 5.2,
  "storeTime": "2026-06-23 10:30:00"
}

六、全量同步格口重量

POST /neglect/mater-cabinet/sync-weight

请求体

{
  "cabinetType": 1,         // 必填 — 货柜类型
  "cabinetId": "CAB-001",   // 必填 — 智能柜编号
  "slotList": [
    { "slotNo": "1", "weight": 5.1 },
    { "slotNo": "2", "weight": 3.0 },
    { "slotNo": "3", "weight": 0 }
  ]
}

说明

  • 终端定时上报整柜各格口当前重量,后端比对变化写流水
  • weight: 0 表示空格口,空置格口不产生重量变化流水
  • 建议上报所有格口(含空格口),不要只报有变化的格口

响应

{ "code": 200, "msg": "操作成功" }

七、前端注意事项

  1. 调用顺序:设备端启动后先调 /init 获取柜体元信息(行列数、食堂名)+ 全量格口。后续定时刷新格口状态走 /sync-weight
  2. cabinetType/init 无需传,后端从 nut_terminal.device_type 推导;其余接口仍需传(毛菜柜=1,净菜柜=2)
  3. deviceType / deviceCode:由后端自动从请求头 X-DEVICE-CODE 填充,前端无需传
  4. sync-weight 的 slotList:上报所有格口(含空格口 weight=0),不要只报有变化的格口
  5. 格口编号:毛菜柜和净菜柜的 slotNo 均为数字字符串("1", "2", …),最大编号 = horizontalRows × verticalCount
  6. 格口结构:一个格口即一条数据库记录,响应为扁平对象,无嵌套