- 将应用包名从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接口实例分离管理
5.9 KiB
5.9 KiB
货柜设备端 — API 文档
Controller:
NutCabinetController(毛菜柜/净菜柜通用,通过cabinetType区分) 路径前缀:/neglect/mater-cabinet(Nacos 白名单,无需 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": "操作成功" }
七、前端注意事项
- 调用顺序:设备端启动后先调
/init获取柜体元信息(行列数、食堂名)+ 全量格口。后续定时刷新格口状态走/sync-weight cabinetType:/init无需传,后端从nut_terminal.device_type推导;其余接口仍需传(毛菜柜=1,净菜柜=2)deviceType/deviceCode:由后端自动从请求头X-DEVICE-CODE填充,前端无需传- sync-weight 的
slotList:上报所有格口(含空格口 weight=0),不要只报有变化的格口 - 格口编号:毛菜柜和净菜柜的 slotNo 均为数字字符串("1", "2", …),最大编号 = horizontalRows × verticalCount
- 格口结构:一个格口即一条数据库记录,响应为扁平对象,无嵌套