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接口实例分离管理
This commit is contained in:
+241
@@ -0,0 +1,241 @@
|
||||
# 货柜设备端 — 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. **格口结构**:一个格口即一条数据库记录,响应为扁平对象,无嵌套
|
||||
Reference in New Issue
Block a user