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

242 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 货柜设备端 — 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`
**响应**
```json
{
"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
```
**请求体**
```json
{
"cabinetType": 1, // 必填 — 1=毛菜柜,2=净菜柜
"cabinetId": "CAB-001", // 必填 — 智能柜编号
"slotNo": "1", // 必填 — 格口编号
"materId": 10001, // 必填 — 食材id
"materName": "菠菜", // 必填 — 食材名称
"traceCode": "TC20260601", // 选填 — 溯源码(净菜柜用于精确匹配)
"weight": 5.2 // 必填 — 入柜重量(kg)
}
```
**说明**
- 后端按食材+重量匹配对应入库记录(选重量最接近的一条),将其标记为"已入柜"
- 传 traceCode 时先按溯源码精确过滤,再按重量匹配
- 格口必须已由 `/init` 预置,否则报错"格口未初始化"
- 格口已有物品时拒绝入柜
- 格口行 UPDATE,流水表 INSERT
**响应**
```json
{ "code": 200, "data": "IN20260623001", "msg": "操作成功" }
```
---
## 三、格口列表(全部格口)
```
POST /neglect/mater-cabinet/slots
```
**请求体**
```json
{
"cabinetType": 1, // 必填 — 1=毛菜柜,2=净菜柜
"cabinetId": "CAB-001" // 必填 — 智能柜编号
}
```
**响应** — 与 `/init` 返回的 `slots` 字段结构完全相同
```json
[{
"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
```
**请求体**
```json
{
"cabinetType": 1, // 必填 — 货柜类型
"cabinetId": "CAB-001", // 必填 — 智能柜编号(DTO 校验要求,实际查询用 canteenId)
"canteenId": 100 // 必填 — 食堂id
}
```
**响应**
```json
[{
"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
```
**请求体**
```json
{
"cabinetType": 1, // 必填
"cabinetId": "CAB-001", // 必填
"slotNo": "1" // 必填
}
```
**响应** — 与 `/init` 返回的 `slots` 元素结构相同
```json
{
"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
```
**请求体**
```json
{
"cabinetType": 1, // 必填 — 货柜类型
"cabinetId": "CAB-001", // 必填 — 智能柜编号
"slotList": [
{ "slotNo": "1", "weight": 5.1 },
{ "slotNo": "2", "weight": 3.0 },
{ "slotNo": "3", "weight": 0 }
]
}
```
**说明**
- 终端定时上报整柜各格口当前重量,后端比对变化写流水
- `weight: 0` 表示空格口,空置格口不产生重量变化流水
- 建议上报所有格口(含空格口),不要只报有变化的格口
**响应**
```json
{ "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. **格口结构**:一个格口即一条数据库记录,响应为扁平对象,无嵌套