Files
SmartPlateCabinet/餐盘柜-API文档.md
mazengfei 8fcbbb38f6 refactor(api): 优化餐盘柜接口路径和数据模型
- 删除密码登录相关代码和布局资源,简化登录流程
- 修改 ApiService 接口路径由旧项目旧路径切换为新 nutrition 模块路径
- 修改设备用户信息 EquipmentUserInfo 中 id 类型由 Long 改为 String,防止精度丢失
- 重构 RemoteRepository 中绑定和解绑接口,适配新参数结构
- 优化 UserViewModel 中获取用户信息接口,添加静默请求支持
- 改进 DiagnosticExporter,优先导出到 U 盘,不可用时回落到应用目录
- UsbStorageHelper 增强 U 盘识别算法,结合路径与文件系统类型双重校验
- 移除无用的 LoginParam 请求模型以及密码登录相关引用
- 调整网络请求相关的导入语句,清理多余依赖
- 修正设备初始化 ActiveKey 的使用方式,恢复为后台下发值
- BindPlateFragment 中绑定失败提示改为“绑定成功,开柜失败”
- OpsActivity 导出诊断包按钮弹窗改为 AlertDialog 显示结果信息
- SearchParam 默认分页参数改为 pageNum=1,pageSize=10
- 修改 SettingViewModel.unbindPlate 参数类型为 String,统一接口调用参数格式
2026-09-09 15:57:44 +08:00

272 lines
9.0 KiB
Markdown
Raw Permalink 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 文档
> 更新时间:2026-09-09 服务:platform-nutrition(端口 24810
## 一、通用约定
### 1. 路径与鉴权
- 所有接口路径前缀为 `/nutrition`,在 Nacos 白名单 `/nutrition/neglect/**` 下,**无需登录 token**
- 设备上下文统一靠请求头 **`X-DEVICE-CODE`** 解析(值为终端管理的设备编码),请求体无需传 deviceCode
### 2. 统一响应结构
```json
{ "code": "00000", "msg": "操作成功", "data": { }, "total": 0 }
```
| 字段 | 类型 | 说明 |
|------|------|------|
| code | string | `00000` 成功;`99999` 等为失败 |
| msg | string | 失败时直接展示给设备端(业务异常中文提示) |
| data | object/array | 业务数据 |
| total | int | 分页接口返回总条数,非分页为 0 |
### 3. 数据类型说明
- 所有 id(Long)序列化为**字符串**,防止精度丢失
- 金额为 BigDecimal,按原样输出(不转科学计数法)
- 时间格式 `yyyy-MM-dd HH:mm:ss`,日期 `yyyy-MM-dd`
### 4. 收费模式 chargeType
| 值 | 含义 | price |
|----|------|-------|
| 1 | 按餐计费 | 有值(元/份) |
| 2 | 称重计费 | null |
| 3 | 免费 | null |
---
## 二、接口明细
### 1. 获取设备绑定用户列表
`GET /nutrition/neglect/sideboard/app/getYxMemberRefPlateByEquipmentCode`
返回当前设备(按 X-DEVICE-CODE)全部格子,按格子序号升序。
**返回 data:数组**
| 字段 | 类型 | 说明 |
|------|------|------|
| id | string | 绑定记录id(解绑时使用) |
| equipmentId | string | 设备idnut_terminal.id |
| equipmentName | string | 设备名称 |
| equipmentCode | string | 设备编码 |
| equipmentBoxCode | string | 格子编号(1..N |
| faceId | string | 绑定用户id=nut_user.id),空格子为 null |
| plateNumber | string | 餐盘号,空格子为 null |
| orderNo | int | 格子排序号 |
| name | string | 用户姓名(未绑定为 null) |
| phone | string | 用户手机号(未绑定为 null) |
| faceUrl | string | 预留,人脸头像 |
| mealTime | string | 就餐时间(预留) |
| openTime | string | 最近开柜绑定时间 |
| updateTime | string | 更新时间 |
| eatCount | int | 预留 |
**示例**
```json
{
"code": "00000", "msg": "操作成功", "total": 0,
"data": [
{ "id": "1948000001", "equipmentId": "1001", "equipmentName": "1号餐盘柜",
"equipmentCode": "DEV-PLATE-CABINET-01", "equipmentBoxCode": "1",
"faceId": "10001", "plateNumber": "PLATE-001", "orderNo": 1,
"name": "张三", "phone": "138****0001", "faceUrl": null,
"mealTime": null, "openTime": "2026-09-04 11:20:00",
"updateTime": "2026-09-04 11:20:00", "eatCount": 0 }
]
}
```
---
### 2. 餐盘绑定
`POST /nutrition/neglect/sideboard/app/plateBinding`
**入参(JSON 请求体)**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| equipmentBoxCode | string | 是 | 目标格子编号 |
| faceId | long | 是 | 用户id(用户搜索接口返回的 faceId) |
| plateNumber | string | 是 | 餐盘号 |
| equipmentId / equipmentCode | - | 否 | 兼容旧项目的冗余字段,后端以请求头为准 |
```json
{ "equipmentBoxCode": "1", "faceId": 10001, "plateNumber": "PLATE-001" }
```
**处理规则**
1. 目标格子已绑定用户 → 报错「当前柜子已绑定用户」
2. 餐盘号已被其他用户绑定 → 报错「当前柜子已绑定用户」
3. 用户不存在或**不是会员**(is_vip≠1)→ 报错「用户查询失败」
4. 用户已绑定其他格子 → 自动释放旧格子并重建空格
5. 成功返回 `Result<Void>`,同时记录开柜时间
---
### 3. 餐盘解绑
`POST /nutrition/neglect/sideboard/app/plateUnbind`
> ⚠️ 与旧项目不同:参数在 **JSON 请求体**,不是 QueryString
**入参(JSON 请求体)**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | long | 是 | 绑定记录id(列表接口返回的 id) |
```json
{ "id": 1948000001 }
```
**错误**:记录不存在 → 「绑定记录不存在」。成功后原格子重建为空格。
---
### 4. 用户信息模糊搜索
`POST /nutrition/neglect/common/app/getUserInfoByNameOrPhone`
按姓名或手机号模糊搜索**会员**(仅 is_vip=1 且状态正常),不按食堂过滤。
**入参(JSON 请求体)**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| name | string | 否 | 姓名模糊 |
| phone | string | 否 | 手机号模糊(name/phone 至少一个) |
| pageNum | int | 否 | 默认 1 |
| pageSize | int | 否 | 默认 10,最大 500 |
**返回 data:数组**total 为总条数)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | string | 用户id |
| faceId | string | 同 id(键名对齐旧项目) |
| name | string | 姓名 |
| phone | string | 手机号 |
```json
{
"code": "00000", "msg": "操作成功", "total": 1,
"data": [ { "id": "10001", "faceId": "10001", "name": "张三", "phone": "13800000001" } ]
}
```
---
### 5. 通过餐盘号获取信息
`GET /nutrition/neglect/sideboard/app/getMemberRefPlateByPlateNumber?plateNumber=PLATE-001`
用户刷餐盘取餐时调用;**cardBalance 为真实账户余额**:余额 > 0 可开柜,负数提示用户充值。
**返回 data**
| 字段 | 类型 | 说明 |
|------|------|------|
| equipmentId | string | 设备id |
| equipmentName | string | 设备名称 |
| equipmentCode | string | 设备编码 |
| id | string | 绑定记录id |
| equipmentBoxCode | string | 格子编号 |
| updateTime | string | 更新时间 |
| plateNumber | string | 餐盘号 |
| faceId | string | 绑定用户id,未绑定为 null |
| name | string | 用户姓名,未绑定为 null |
| phone | string | 用户手机号,未绑定为 null |
| cardBalance | number | 账户真实余额(元);未绑定/无账户为 null |
**错误**:餐盘号为空 → 「餐盘号不能为空」;查无绑定 → 「未找到餐盘绑定信息」
```json
{
"code": "00000", "msg": "操作成功", "total": 0,
"data": {
"equipmentId": "1001", "equipmentName": "1号餐盘柜", "equipmentCode": "DEV-PLATE-CABINET-01",
"id": "1948000001", "equipmentBoxCode": "1", "updateTime": "2026-09-04 11:20:00",
"plateNumber": "PLATE-001", "faceId": "10001", "name": "张三", "phone": "13800000001",
"cardBalance": 25.50
}
}
```
---
### 6. 通过用户ID获取信息
`GET /nutrition/neglect/sideboard/app/getMemberRefPlateByUserId?userId=10001`
人脸识别匹配到 `userId` 后调用;查询**当前设备**上该用户绑定的餐盘/格子,**cardBalance 为真实账户余额**:余额 > 0 可开柜,负数提示用户充值。
**返回 data**(字段同「通过餐盘号获取信息」)
| 字段 | 类型 | 说明 |
|------|------|------|
| equipmentId | string | 设备id |
| equipmentName | string | 设备名称 |
| equipmentCode | string | 设备编码 |
| id | string | 绑定记录id |
| equipmentBoxCode | string | 格子编号 |
| updateTime | string | 更新时间 |
| plateNumber | string | 餐盘号 |
| faceId | string | 绑定用户id |
| name | string | 用户姓名 |
| phone | string | 用户手机号 |
| cardBalance | number | 账户真实余额(元) |
**错误**:用户ID为空 → 「用户ID不能为空」;查无绑定 → 「未找到用户绑定信息」
```json
{
"code": "00000", "msg": "操作成功", "total": 0,
"data": {
"equipmentId": "1001", "equipmentName": "1号餐盘柜", "equipmentCode": "DEV-PLATE-CABINET-01",
"id": "1948000001", "equipmentBoxCode": "1", "updateTime": "2026-09-04 11:20:00",
"plateNumber": "PLATE-001", "faceId": "10001", "name": "张三", "phone": "13800000001",
"cardBalance": 25.50
}
}
```
---
### 7. 获取扣费规则
`GET /nutrition/neglect/sideboard/app/getChargeRuleByEquipmentCode`
键名对齐旧项目 `getRegionRuleByEquipmentCode`。按「终端绑定餐线 → 今天星期 × 当前时段餐次」查询收费模式矩阵(nut_canteen_line_charge)。
**返回 data**
| 字段 | 类型 | 说明 |
|------|------|------|
| chargeType | int | 1按餐计费 / 2称重计费 / 3免费 |
| price | number | 仅 chargeType=1 时有值(元/份) |
**规则**
- 终端未绑定餐线 / 餐线停用 / 当日当餐未配置 → 默认返回 `chargeType=2`(称重计费)
- 餐次时段:早餐 06:00-10:00 / 午餐 10:00-14:00 / 加餐 14:00-16:00 / 晚餐 16:00-20:00(全局统一)
- **按餐计费的扣费由后端定时任务完成**:该餐次取餐结束(最后一条取餐记录 15 分钟后)统一按份扣余额,**硬件无需在取盘时扣款**,仅需按 cardBalance > 0 判断是否开柜
- 余额不足会扣成负数(后续充值回补),负余额即提示充值
```json
{ "code": "00000", "msg": "操作成功", "total": 0, "data": { "chargeType": 1, "price": 15.00 } }
```
---
## 三、错误响应示例
```json
{ "code": "99999", "msg": "当前柜子已绑定用户", "data": null, "total": 0 }
```
业务校验失败的 msg 为中文提示,可直接在设备端展示;参数校验失败(缺必填字段)返回 PARAM_ERROR。