refactor(iot): 重构配置模型与实现双层缓存优化

- 将 buttonEvent 配置从区域级移至设备级(iot_device.config)
- 添加 getConfigWrapperByDeviceId 方法支持一对一设备查询
- 实现设备索引缓存 + 区域配置缓存的双层缓存设计
- 添加设备类型常量 DEVICE_RELATION_TYPES
- 完善 JavaDoc 注释说明配置层级划分

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
lzh
2026-02-01 00:57:03 +08:00
parent b73ef4f39f
commit 89e68eceb2
5 changed files with 396 additions and 238 deletions

View File

@@ -132,17 +132,44 @@ public class BadgeDeviceStatusEventListener {
var waitingTasks = orderQueueService.getWaitingTasksByUserIdFromDb(deviceId);
switch (newStatus) {
case DISPATCHED:
// 工单已推送到工牌,设置工单关联,设备状态转为 BUSY
badgeDeviceStatusService.setCurrentOrder(deviceId, orderId);
// 工单已推送到工牌,设置工单关联和区域信息
// currentAreaId 应该设置为工单所属区域,而非设备物理位置
badgeDeviceStatusService.updateBadgeStatus(deviceId, BadgeDeviceStatusEnum.BUSY, null, "新工单已推送");
log.info("[BadgeDeviceStatusEventListener] 工单已推送,设备状态转为 BUSY: deviceId={}, orderId={}", deviceId,
orderId);
OpsOrderDO order = opsOrderMapper.selectById(orderId);
if (order != null && order.getAreaId() != null) {
badgeDeviceStatusService.setCurrentOrderInfo(
deviceId, orderId,
event.getNewStatus().getStatus(),
order.getAreaId(),
null
);
log.info("[BadgeDeviceStatusEventListener] 工单已推送,设备状态转为 BUSY: deviceId={}, orderId={}, areaId={}",
deviceId, orderId, order.getAreaId());
} else {
badgeDeviceStatusService.setCurrentOrder(deviceId, orderId);
log.info("[BadgeDeviceStatusEventListener] 工单已推送,设备状态转为 BUSY: deviceId={}, orderId={}", deviceId,
orderId);
}
break;
case CONFIRMED:
// 设备按键确认,设备保持 BUSY
badgeDeviceStatusService.setCurrentOrder(deviceId, orderId);
log.debug("[BadgeDeviceStatusEventListener] 工单已确认: deviceId={}, orderId={}", deviceId, orderId);
// 设备按键确认,更新工单关联和区域信息
// currentAreaId 应该设置为工单所属区域,而非设备物理位置
OpsOrderDO order = opsOrderMapper.selectById(orderId);
if (order != null && order.getAreaId() != null) {
badgeDeviceStatusService.setCurrentOrderInfo(
deviceId, orderId,
event.getNewStatus().getStatus(),
order.getAreaId(),
null
);
log.debug("[BadgeDeviceStatusEventListener] 工单已确认,更新区域信息: deviceId={}, orderId={}, areaId={}",
deviceId, orderId, order.getAreaId());
} else {
badgeDeviceStatusService.setCurrentOrder(deviceId, orderId);
log.debug("[BadgeDeviceStatusEventListener] 工单已确认: deviceId={}, orderId={}", deviceId, orderId);
}
break;
case ARRIVED:

View File

@@ -279,20 +279,19 @@ public class BadgeDeviceStatusServiceImpl implements BadgeDeviceStatusService, I
statusMap.put("lastHeartbeatTime", now);
}
// 更新实时物理区域信息 (Key2)
// 更新区域信息
// 注意currentAreaId 应该表示当前工单所属区域,而非设备物理位置
// 只有在没有工单时,才同步 IoT 上报的物理位置
if (areaId != null) {
statusMap.put("currentAreaId", areaId);
// 同时更新区域设备索引缓存 (这里注释掉了,保持原样)
// addToAreaIndex(deviceId, areaId);
} else {
// 保持现有实时物理区域信息
Object existingAreaId = currentMap.get("currentAreaId");
if (existingAreaId != null) {
statusMap.put("currentAreaId", existingAreaId);
}
Object existingAreaName = currentMap.get("currentAreaName");
if (existingAreaName != null) {
statusMap.put("currentAreaName", existingAreaName);
// 检查是否有正在执行的工单
Object currentOrderId = currentMap.get("currentOpsOrderId");
if (currentOrderId != null) {
// 有工单:保持 currentAreaId 不变(用工单区域),不覆盖
log.debug("设备 {} 有执行中工单 {},保持 currentAreaId 不变,忽略 IoT 上报的物理位置 {}",
deviceId, currentOrderId, areaId);
} else {
// 无工单:用 IoT 上报的物理位置
statusMap.put("currentAreaId", areaId);
}
}