- 删除密码登录相关代码和布局资源,简化登录流程 - 修改 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,统一接口调用参数格式
272 lines
9.0 KiB
Markdown
272 lines
9.0 KiB
Markdown
# 餐盘柜设备端 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 | 设备id(nut_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。
|