设备与门店模块业务说明
本文档描述设备管理、门店管理、库存管理及设备回调链路。
帮助开发人员快速理解"为什么这样设计"以及各环节的特殊处理方式。
一、设备管理
1.1 Device 实体
| 字段 |
类型 |
说明 |
| id |
Long |
雪花算法主键 |
| deviceId |
String |
设备SN号(唯一标识) |
| shopId |
Long |
所属门店ID |
| name |
String |
设备名称 |
| authToken |
String |
设备认证Token |
| status |
Integer |
设备状态 |
| doorStatus |
String |
门状态:ERROR / OPENED / CLOSED / ANOTHER(设备繁忙) |
| currentInventoryHash |
String |
当前库存哈希(用于同步判断) |
| createTime / updateTime |
LocalDateTime |
时间戳 |
非DB字段(@TableField(exist = false)):shopName, address, deviceTypeLabel, statusLabel, statusColor, isOnline, temperature, volume, doorCount, layerCount, hasScreen, totalSales, todaySales, orderCount, lastOnlineTime
1.2 门状态枚举 (DeviceDoorStatus)
| code |
枚举值 |
说明 |
| ERROR |
开门失败 |
远程开门请求失败 |
| OPENED |
门已开 |
门处于打开状态 |
| CLOSED |
门已关 |
门处于关闭状态 |
| ANOTHER |
设备繁忙 |
设备正忙,无法开门 |
为什么门状态用字符串而非数字编码?
门状态直接来自哈哈平台设备端的回调,设备端使用字符串状态码(如 "1"=ERROR, "2"=OPENED, "3"=CLOSED, "4"=ANOTHER)。为避免数字编码与数据库值之间的映射混乱,DeviceDoorStatus 枚举在数据库中存储英文状态字符串(ERROR/OPENED/CLOSED/ANOTHER),并在 convertToDbValue() 方法中处理原始数字码到字符串的转换。这种设计使得数据库中的值自解释,排查问题时一目了然。
1.3 设备服务核心方法 (DeviceService)
| 方法 |
说明 |
| getPage() |
分页查询设备列表(支持门店/状态筛选) |
| getDetailById() |
设备详情(含门店名、状态标签填充) |
| getStatistics() |
设备统计数据 |
| openDoor() |
远程开门 |
| scanCodeOpenDoor() |
扫码开门业务(含支付分校验) |
| setTemperature() |
设置温度 |
| setVolume() |
设置音量 |
| getNearbyDevices() |
附近设备查询(经纬度+距离) |
| getDeviceBySn() |
通过SN号查询设备 |
| updateDeviceStatus() |
更新设备状态 |
| updateInventoryHash() |
更新库存哈希 |
二、设备回调处理 (HahaCallbackService)
什么是设备回调?
哈哈平台(智能售卖机设备平台)采用回调机制主动推送设备事件。我们的服务端作为回调接收方,在 CallbackController 中接收并分发处理。回调类型包括设备状态变更、AI识别结果、订单信息等。
为什么用回调而非轮询?
- 实时性:设备事件立即推送,无需等待轮询周期
- 高效:只有事件发生时才产生网络请求,节省资源
- 可靠:回调失败可重试,配合签名验证保证安全
2.1 回调消息类型
| 类型 |
方法 |
说明 |
| DEVICE_STATUS |
handleDeviceStatus() |
开关门状态通知 |
| ONLINE_STATUS |
handleOnlineStatus() |
设备在线/离线通知 |
| VOICE_RESULT |
handleVoiceResult() |
音量调节结果 |
| CLIENT_NEW_PRODUCT |
handleNewProductAudit() |
新品审核结果 |
| MERGE_PRODUCT |
handleMergeProduct() |
商品合并结果 |
| ORC_RESULT |
handleOrcResult() |
AI识别结果通知 |
| 订单回调 |
handleOrderCallback() |
设备端订单信息回调 |
2.2 核心回调流程
ORC_RESULT(AI识别回调)
设备AI识别完成
↓
解析 sku_list: [{code, quantity}]
↓
创建/查找订单 createOrderFromRecognition()
- 幂等:通过 activityId 防重复
- 订单金额初始化为0(等待设备端回调)
↓
解析视频URL等资源信息
↓
创建 DoorRecord(doorStatus=CLOSED)
订单回调
设备端计算好订单金额和商品明细后回调
↓
查找或创建本地订单
↓
updateOrderFromCallback()
- 写入 orderNo, totalAmount, items
- 初始化 discountAmount=0, paidAmount=totalAmount
↓
saveOrderGoods() — 保存订单商品明细
↓
processCouponDiscount() — 自动优惠券扣减
↓
processPayScorePayment() — 支付分扣费
三、开关门记录 (DoorRecord)
3.1 实体字段
| 字段 |
类型 |
说明 |
| id |
Long |
雪花算法主键 |
| activityId |
String |
哈哈平台活动ID |
| deviceId |
String |
设备ID |
| userId |
Long |
用户ID |
| doorIndex |
String |
门索引(A/B/C/D) |
| openType |
String |
开门类型:IN-上货,OUT-消费 |
| doorStatus |
String |
门状态:OPENED-已开,CLOSED-已关 |
| nobuy |
Integer |
是否无消费:0-有消费,1-无消费 |
| orderId |
Long |
关联订单ID(有消费时) |
| openTime |
LocalDateTime |
开门时间 |
| closeTime |
LocalDateTime |
关门时间 |
| duration |
Integer |
持续时长(秒) |
| source |
String |
来源:MINIAPP / ADMIN |
| remark |
String |
备注 |
3.2 开门类型 (OpenType)
| code |
说明 |
| IN |
上货开门(运营人员补货) |
| OUT |
消费开门(用户购物) |
四、门店管理
4.1 Shop 实体
| 字段 |
类型 |
说明 |
| id |
Long |
雪花算法主键 |
| shopCode |
String |
门店编码(唯一标识) |
| name |
String |
门店名称 |
| address |
String |
门店地址 |
| province / city / district |
String |
省市区 |
| longitude / latitude |
Double |
经纬度 |
| contactName / contactPhone |
String |
联系人/电话 |
| businessHours |
String |
营业时间 |
| status |
Integer |
状态:0-禁用 1-启用 |
| remark |
String |
备注 |
非DB字段:deviceCount(设备总数), onlineCount(在线设备数), statusLabel, statusColor
4.2 门店服务核心方法 (ShopService)
| 方法 |
说明 |
| getPage() |
分页查询门店 |
| getDetailById() |
门店详情(含设备数/在线数) |
| getStatistics() |
门店统计 |
| getNearbyShops() |
附近门店查询(小程序端) |
4.3 门店补货员 (ShopReplenisher)
关联门店和补货人员,用于补货权限管理。
五、库存管理
5.1 DeviceInventory 实体(设备商品库存)
| 字段 |
类型 |
说明 |
| id |
Long |
雪花算法主键 |
| deviceId |
String |
设备ID(SN号) |
| productId |
Long |
商品ID(本地) |
| productCode |
String |
商品编码(哈哈平台code) |
| productName |
String |
商品名称(冗余) |
| stock |
Integer |
当前库存数量 |
| shelfNum |
Integer |
货架层号 |
| position |
String |
货道位置(left/right) |
| warningThreshold |
Integer |
库存预警阈值 |
| lastRestockTime |
LocalDateTime |
最后补货时间 |
5.2 库存服务 (DeviceInventoryService)
| 方法 |
说明 |
| getInventoryByDevice() |
查询设备库存列表 |
| syncInventory() |
同步设备库存(从设备端获取最新数据) |
| deductStock() |
扣减库存(订单完成后) |
| checkLowStock() |
低库存预警检查 |
5.3 库存同步流程
设备端上报库存变更
↓
HahaCallbackService 接收通知
↓
比对 currentInventoryHash
↓
如不一致 → 调用哈哈SDK获取最新库存
↓
更新 DeviceInventory 记录
↓
更新 currentInventoryHash
↓
检查低库存 → 触发告警
库存哈希机制的设计考量
currentInventoryHash 是设备当前库存的哈希摘要。每次设备端回调库存变更时,先比对哈希值:
- 哈希一致 → 库存未变化,跳过同步,减少不必要的SDK调用
- 哈希不一致 → 库存有变化,拉取最新数据并更新
这种设计避免了频繁全量同步的性能开销,只在库存确实变化时才触发同步。
5.4 补货记录 (StockRecord / StockRecordItem)
| 实体 |
说明 |
| StockRecord |
补货记录主表(操作人、设备、时间) |
| StockRecordItem |
补货明细(商品、数量变化) |
六、设备告警体系
6.1 DeviceAlertRecord 实体
| 字段 |
类型 |
说明 |
| id |
Long |
雪花算法主键 |
| deviceId |
String |
设备ID |
| alertType |
String |
告警类型 |
| alertLevel |
Integer |
告警级别 |
| title |
String |
告警标题 |
| content |
String |
告警内容 |
| status |
Integer |
处理状态 |
6.2 告警类型 (DeviceAlertType)
| code |
说明 |
| OFFLINE |
设备离线 |
| LOW_STOCK |
低库存 |
| DOOR_ERROR |
开门异常 |
6.3 告警通知
告警通过企业微信 Webhook 推送,配置在 haha-service/.../notify/ 中。
七、商品管理
7.1 Product 实体
| 字段 |
类型 |
说明 |
| id |
Long |
雪花算法主键 |
| productId |
String |
哈哈平台商品ID |
| code |
String |
商品编码(哈哈平台code) |
| barcode |
String |
商品条码 |
| name |
String |
商品名称 |
| type |
String |
商品分类 |
| pic |
String |
商品图片URL |
| retailPrice |
Double |
零售价 |
| costPrice |
Double |
成本价 |
| applyStatus |
String |
适用设备:全部柜/静态柜/动态柜 |
| syncStatus |
Integer |
同步状态:0-未同步 1-同步中 2-已同步 3-同步失败 |
7.2 商品同步
商品数据从哈哈平台(SDK)同步到本地,DataSyncServiceImpl 处理全量/增量同步。
八、核心代码文件索引
| 文件 |
职责 |
haha-entity/.../Device.java |
设备实体 |
haha-entity/.../Shop.java |
门店实体 |
haha-entity/.../Product.java |
商品实体 |
haha-entity/.../DoorRecord.java |
开关门记录 |
haha-entity/.../DeviceInventory.java |
设备库存 |
haha-entity/.../StockRecord.java |
补货记录 |
haha-entity/.../DeviceAlertRecord.java |
设备告警记录 |
haha-service/.../DeviceServiceImpl.java |
设备服务 |
haha-service/.../ShopServiceImpl.java |
门店服务 |
haha-service/.../ProductServiceImpl.java |
商品服务 |
haha-service/.../DoorRecordServiceImpl.java |
开关门记录服务 |
haha-service/.../DeviceInventoryServiceImpl.java |
库存服务 |
haha-service/.../DeviceAlertServiceImpl.java |
告警服务 |
haha-service/.../HahaCallbackServiceImpl.java |
设备回调处理 |
haha-service/.../DataSyncServiceImpl.java |
数据同步服务 |
haha-admin/.../DeviceController.java |
运营平台-设备API |
haha-admin/.../ShopController.java |
运营平台-门店API |
haha-admin/.../InventoryController.java |
运营平台-库存API |
haha-admin/.../DeviceAlertController.java |
运营平台-告警API |
haha-miniapp/.../DeviceController.java |
小程序-设备API |
haha-common/.../enums/DeviceDoorStatus.java |
门状态枚举 |
haha-common/.../enums/DeviceAlertType.java |
告警类型枚举 |
haha-common/.../enums/DeviceOnlineStatus.java |
在线状态枚举 |
haha-common/.../constant/DeviceConstants.java |
设备常量 |