refactor(ops): simplify badge status management by removing redundant heartbeat logic
This commit is contained in:
@@ -24,250 +24,202 @@ import java.util.List;
|
||||
*/
|
||||
public interface BadgeDeviceStatusService {
|
||||
|
||||
// ==================== 状态管理 ====================
|
||||
// ==================== 状态管理 ====================
|
||||
|
||||
/**
|
||||
* 更新工牌设备状态
|
||||
* <p>
|
||||
* 状态转换会记录状态变更时间和操作原因
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param status 目标状态
|
||||
* @param operatorId 操作人ID(可为null,表示系统操作)
|
||||
* @param reason 状态变更原因
|
||||
*/
|
||||
void updateBadgeStatus(Long deviceId, BadgeDeviceStatusEnum status, Long operatorId, String reason);
|
||||
/**
|
||||
* 更新工牌设备状态
|
||||
* <p>
|
||||
* 状态转换会记录状态变更时间和操作原因
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param status 目标状态
|
||||
* @param operatorId 操作人ID(可为null,表示系统操作)
|
||||
* @param reason 状态变更原因
|
||||
*/
|
||||
void updateBadgeStatus(Long deviceId, BadgeDeviceStatusEnum status, Long operatorId, String reason);
|
||||
|
||||
/**
|
||||
* 批量更新工牌设备状态
|
||||
*
|
||||
* @param deviceIds 设备ID列表
|
||||
* @param status 目标状态
|
||||
* @param operatorId 操作人ID
|
||||
* @param reason 状态变更原因
|
||||
*/
|
||||
void batchUpdateBadgeStatus(List<Long> deviceIds, BadgeDeviceStatusEnum status, Long operatorId, String reason);
|
||||
/**
|
||||
* 批量更新工牌设备状态
|
||||
*
|
||||
* @param deviceIds 设备ID列表
|
||||
* @param status 目标状态
|
||||
* @param operatorId 操作人ID
|
||||
* @param reason 状态变更原因
|
||||
*/
|
||||
void batchUpdateBadgeStatus(List<Long> deviceIds, BadgeDeviceStatusEnum status, Long operatorId, String reason);
|
||||
|
||||
// ==================== 状态查询 ====================
|
||||
// ==================== 状态查询 ====================
|
||||
|
||||
/**
|
||||
* 获取工牌设备状态
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @return 设备状态DTO,不存在返回null
|
||||
*/
|
||||
BadgeDeviceStatusDTO getBadgeStatus(Long deviceId);
|
||||
/**
|
||||
* 获取工牌设备状态
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @return 设备状态DTO,不存在返回null
|
||||
*/
|
||||
BadgeDeviceStatusDTO getBadgeStatus(Long deviceId);
|
||||
|
||||
/**
|
||||
* 批量获取工牌设备状态
|
||||
*
|
||||
* @param deviceIds 设备ID列表
|
||||
* @return 设备状态DTO列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> batchGetBadgeStatus(List<Long> deviceIds);
|
||||
/**
|
||||
* 批量获取工牌设备状态
|
||||
*
|
||||
* @param deviceIds 设备ID列表
|
||||
* @return 设备状态DTO列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> batchGetBadgeStatus(List<Long> deviceIds);
|
||||
|
||||
/**
|
||||
* 获取指定区域的工牌设备列表
|
||||
* <p>
|
||||
* 只返回非 OFFLINE 状态的设备
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @return 设备状态DTO列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> listBadgesByArea(Long areaId);
|
||||
/**
|
||||
* 获取指定区域的工牌设备列表
|
||||
* <p>
|
||||
* 只返回非 OFFLINE 状态的设备
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @return 设备状态DTO列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> listBadgesByArea(Long areaId);
|
||||
|
||||
/**
|
||||
* 获取可接单的工牌设备(IDLE 状态)
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @return 可接单设备列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> listAvailableBadges(Long areaId);
|
||||
/**
|
||||
* 获取可接单的工牌设备(IDLE 状态)
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @return 可接单设备列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> listAvailableBadges(Long areaId);
|
||||
|
||||
/**
|
||||
* 获取所有活跃的工牌设备(非OFFLINE状态)
|
||||
*
|
||||
* @return 活跃设备列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> listActiveBadges();
|
||||
/**
|
||||
* 获取所有活跃的工牌设备(非OFFLINE状态)
|
||||
*
|
||||
* @return 活跃设备列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> listActiveBadges();
|
||||
|
||||
// ==================== 心跳处理 ====================
|
||||
// ==================== 状态更新 (IoT 事件驱动) ====================
|
||||
|
||||
/**
|
||||
* 处理工牌设备心跳
|
||||
* <p>
|
||||
* 更新最后心跳时间和电量:
|
||||
* <ul>
|
||||
* <li>如果设备之前为 OFFLINE,转为 IDLE</li>
|
||||
* <li>如果设备已存在,更新心跳时间和电量</li>
|
||||
* <li>如果设备不存在,创建新记录(状态为 IDLE)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param deviceCode 设备编码
|
||||
* @param batteryLevel 电量(0-100)
|
||||
*/
|
||||
void handleHeartbeat(Long deviceId, String deviceCode, Integer batteryLevel);
|
||||
/**
|
||||
* 更新工牌设备在线状态
|
||||
* <p>
|
||||
* 用于处理 IoT 设备状态变更事件和定时对账:
|
||||
* <ul>
|
||||
* <li>设备上线:创建或更新状态记录,状态设为 IDLE</li>
|
||||
* <li>设备离线:更新状态记录,状态设为 OFFLINE</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param deviceCode 设备编码
|
||||
* @param areaId 区域ID(可为null)
|
||||
* @param status 目标状态(IDLE 或 OFFLINE)
|
||||
* @param reason 状态变更原因
|
||||
*/
|
||||
void updateBadgeOnlineStatus(Long deviceId, String deviceCode, Long areaId,
|
||||
BadgeDeviceStatusEnum status, String reason);
|
||||
|
||||
/**
|
||||
* 处理工牌设备心跳(带区域信息)
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param deviceCode 设备编码
|
||||
* @param batteryLevel 电量(0-100)
|
||||
* @param areaId 当前所在区域ID
|
||||
* @param areaName 当前所在区域名称
|
||||
*/
|
||||
void handleHeartbeatWithArea(Long deviceId, String deviceCode, Integer batteryLevel,
|
||||
Long areaId, String areaName);
|
||||
// ==================== 在线状态检查 ====================
|
||||
|
||||
/**
|
||||
* 更新工牌设备在线状态
|
||||
* <p>
|
||||
* 用于处理 IoT 设备状态变更事件和定时对账:
|
||||
* <ul>
|
||||
* <li>设备上线:创建或更新状态记录,状态设为 IDLE</li>
|
||||
* <li>设备离线:更新状态记录,状态设为 OFFLINE</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 与 handleHeartbeat 区别:
|
||||
* - handleHeartbeat:处理位置上报心跳,包含电量等详细信息
|
||||
* - updateBadgeOnlineStatus:仅处理在线/离线状态变更
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param deviceCode 设备编码
|
||||
* @param areaId 区域ID(可为null)
|
||||
* @param status 目标状态(IDLE 或 OFFLINE)
|
||||
* @param reason 状态变更原因
|
||||
*/
|
||||
void updateBadgeOnlineStatus(Long deviceId, String deviceCode, Long areaId,
|
||||
BadgeDeviceStatusEnum status, String reason);
|
||||
/**
|
||||
* 检查工牌设备是否在线(非OFFLINE状态)
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @return 是否在线
|
||||
*/
|
||||
boolean isBadgeOnline(Long deviceId);
|
||||
|
||||
// ==================== 在线状态检查 ====================
|
||||
// ==================== 工单关联 ====================
|
||||
|
||||
/**
|
||||
* 检查工牌设备是否在线(非OFFLINE状态)
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @return 是否在线
|
||||
*/
|
||||
boolean isBadgeOnline(Long deviceId);
|
||||
/**
|
||||
* 设置当前工单
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param orderId 工单ID
|
||||
*/
|
||||
void setCurrentOrder(Long deviceId, Long orderId);
|
||||
|
||||
/**
|
||||
* 检查工牌设备心跳是否超时
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param thresholdMinutes 超时阈值(分钟)
|
||||
* @return 是否超时
|
||||
*/
|
||||
boolean isHeartbeatTimeout(Long deviceId, int thresholdMinutes);
|
||||
/**
|
||||
* 设置当前工单详细信息(原子操作,并发安全)
|
||||
* <p>
|
||||
* 一次性设置工单ID、工单状态、区域ID、信标MAC
|
||||
* 使用 Redis Hash 的 hset() 操作,保证原子性
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param orderId 工单ID
|
||||
* @param orderStatus 工单状态(DISPATCHED/ARRIVED/PAUSED)
|
||||
* @param areaId 区域ID
|
||||
* @param beaconMac 信标MAC地址(可为null)
|
||||
*/
|
||||
void setCurrentOrderInfo(Long deviceId, Long orderId, String orderStatus, Long areaId, String beaconMac);
|
||||
|
||||
/**
|
||||
* 检查心跳超时并将超时设备设为OFFLINE
|
||||
* <p>
|
||||
* 定时任务调用,默认超时时间为30分钟
|
||||
*/
|
||||
void checkAndMarkOfflineDevices();
|
||||
/**
|
||||
* 更新工单状态
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param orderStatus 工单状态
|
||||
*/
|
||||
void updateOrderStatus(Long deviceId, String orderStatus);
|
||||
|
||||
// ==================== 工单关联 ====================
|
||||
/**
|
||||
* 清除当前工单(包括工单ID、工单状态、信标MAC)
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
*/
|
||||
void clearCurrentOrder(Long deviceId);
|
||||
|
||||
/**
|
||||
* 设置当前工单
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param orderId 工单ID
|
||||
*/
|
||||
void setCurrentOrder(Long deviceId, Long orderId);
|
||||
/**
|
||||
* 获取当前有工单的设备列表
|
||||
*
|
||||
* @return 有工单的设备列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> listBadgesWithCurrentOrder();
|
||||
|
||||
/**
|
||||
* 设置当前工单详细信息(原子操作,并发安全)
|
||||
* <p>
|
||||
* 一次性设置工单ID、工单状态、区域ID、信标MAC
|
||||
* 使用 Redis Hash 的 hset() 操作,保证原子性
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param orderId 工单ID
|
||||
* @param orderStatus 工单状态(DISPATCHED/ARRIVED/PAUSED)
|
||||
* @param areaId 区域ID
|
||||
* @param beaconMac 信标MAC地址(可为null)
|
||||
*/
|
||||
void setCurrentOrderInfo(Long deviceId, Long orderId, String orderStatus, Long areaId, String beaconMac);
|
||||
// ==================== 区域管理 ====================
|
||||
|
||||
/**
|
||||
* 更新工单状态
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param orderStatus 工单状态
|
||||
*/
|
||||
void updateOrderStatus(Long deviceId, String orderStatus);
|
||||
/**
|
||||
* 更新工牌设备所在区域
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param areaId 区域ID
|
||||
* @param areaName 区域名称
|
||||
*/
|
||||
void updateBadgeArea(Long deviceId, Long areaId, String areaName);
|
||||
|
||||
/**
|
||||
* 清除当前工单(包括工单ID、工单状态、信标MAC)
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
*/
|
||||
void clearCurrentOrder(Long deviceId);
|
||||
/**
|
||||
* 初始化区域设备索引
|
||||
* <p>
|
||||
* 从 ops_area_device_relation 表加载 BADGE 类型的设备,
|
||||
* 建立区域到设备的索引关系
|
||||
*/
|
||||
void initAreaDeviceIndex();
|
||||
|
||||
/**
|
||||
* 获取当前有工单的设备列表
|
||||
*
|
||||
* @return 有工单的设备列表
|
||||
*/
|
||||
List<BadgeDeviceStatusDTO> listBadgesWithCurrentOrder();
|
||||
/**
|
||||
* 刷新区域设备索引
|
||||
* <p>
|
||||
* 重新从数据库加载区域设备关系
|
||||
*/
|
||||
void refreshAreaDeviceIndex();
|
||||
|
||||
// ==================== 区域管理 ====================
|
||||
/**
|
||||
* 将设备添加到区域索引
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param areaId 区域ID
|
||||
*/
|
||||
void addToAreaIndex(Long deviceId, Long areaId);
|
||||
|
||||
/**
|
||||
* 更新工牌设备所在区域
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param areaId 区域ID
|
||||
* @param areaName 区域名称
|
||||
*/
|
||||
void updateBadgeArea(Long deviceId, Long areaId, String areaName);
|
||||
/**
|
||||
* 从区域索引移除设备
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param areaId 区域ID
|
||||
*/
|
||||
void removeFromAreaIndex(Long deviceId, Long areaId);
|
||||
|
||||
/**
|
||||
* 初始化区域设备索引
|
||||
* <p>
|
||||
* 从 ops_area_device_relation 表加载 BADGE 类型的设备,
|
||||
* 建立区域到设备的索引关系
|
||||
*/
|
||||
void initAreaDeviceIndex();
|
||||
// ==================== 设备管理 ====================
|
||||
|
||||
/**
|
||||
* 刷新区域设备索引
|
||||
* <p>
|
||||
* 重新从数据库加载区域设备关系
|
||||
*/
|
||||
void refreshAreaDeviceIndex();
|
||||
/**
|
||||
* 删除工牌设备状态
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
*/
|
||||
void deleteBadgeStatus(Long deviceId);
|
||||
|
||||
/**
|
||||
* 将设备添加到区域索引
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param areaId 区域ID
|
||||
*/
|
||||
void addToAreaIndex(Long deviceId, Long areaId);
|
||||
|
||||
/**
|
||||
* 从区域索引移除设备
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param areaId 区域ID
|
||||
*/
|
||||
void removeFromAreaIndex(Long deviceId, Long areaId);
|
||||
|
||||
// ==================== 设备管理 ====================
|
||||
|
||||
/**
|
||||
* 删除工牌设备状态
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
*/
|
||||
void deleteBadgeStatus(Long deviceId);
|
||||
|
||||
/**
|
||||
* 清理所有离线设备的状态
|
||||
*/
|
||||
void clearOfflineBadges();
|
||||
/**
|
||||
* 清理所有离线设备的状态
|
||||
*/
|
||||
void clearOfflineBadges();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -245,80 +245,7 @@ public class BadgeDeviceStatusServiceImpl implements BadgeDeviceStatusService, I
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 心跳处理 ====================
|
||||
|
||||
@Override
|
||||
public void handleHeartbeat(Long deviceId, String deviceCode, Integer batteryLevel) {
|
||||
handleHeartbeatWithArea(deviceId, deviceCode, batteryLevel, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleHeartbeatWithArea(Long deviceId, String deviceCode, Integer batteryLevel,
|
||||
Long areaId, String areaName) {
|
||||
if (deviceId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String key = BADGE_STATUS_KEY_PREFIX + deviceId;
|
||||
Long now = System.currentTimeMillis();
|
||||
|
||||
// 获取当前状态
|
||||
Map<Object, Object> currentMap = redisTemplate.opsForHash().entries(key);
|
||||
BadgeDeviceStatusEnum currentStatus = null;
|
||||
if (!currentMap.isEmpty()) {
|
||||
String statusStr = (String) currentMap.get("status");
|
||||
currentStatus = BadgeDeviceStatusEnum.fromCode(statusStr);
|
||||
}
|
||||
|
||||
// 如果之前是 OFFLINE,转为 IDLE
|
||||
// 如果当前状态为空,初始化为 IDLE
|
||||
BadgeDeviceStatusEnum newStatus = currentStatus;
|
||||
if (currentStatus == null) {
|
||||
newStatus = BadgeDeviceStatusEnum.IDLE;
|
||||
} else if (currentStatus == BadgeDeviceStatusEnum.OFFLINE) {
|
||||
// 如果已标记为离线,心跳不再自动复活设备
|
||||
// 必须依赖 IoT 上线事件或定时对账 Job 来恢复在线状态
|
||||
// 这样做是为了防止因离线事件和心跳包乱序(幽灵心跳)导致的“假在线”问题
|
||||
log.debug("设备处于离线状态但收到心跳,保持离线状态: deviceId={}", deviceId);
|
||||
newStatus = BadgeDeviceStatusEnum.OFFLINE;
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
Map<String, Object> statusMap = new HashMap<>();
|
||||
statusMap.put("deviceId", deviceId);
|
||||
statusMap.put("deviceCode", deviceCode != null ? deviceCode : currentMap.get("deviceCode"));
|
||||
statusMap.put("status", newStatus.getCode());
|
||||
statusMap.put("batteryLevel", batteryLevel != null ? batteryLevel : currentMap.get("batteryLevel"));
|
||||
statusMap.put("lastHeartbeatTime", now);
|
||||
statusMap.put("statusChangeTime", LocalDateTime.now().toString());
|
||||
|
||||
// 更新区域信息
|
||||
if (areaId != null) {
|
||||
statusMap.put("currentAreaId", areaId);
|
||||
statusMap.put("currentAreaName", areaName);
|
||||
// 更新区域索引
|
||||
addToAreaIndex(deviceId, areaId);
|
||||
} else {
|
||||
statusMap.put("currentAreaId", currentMap.getOrDefault("currentAreaId", null));
|
||||
statusMap.put("currentAreaName", currentMap.getOrDefault("currentAreaName", null));
|
||||
}
|
||||
|
||||
// 保持当前工单相关字段
|
||||
statusMap.put("currentOpsOrderId", currentMap.get("currentOpsOrderId"));
|
||||
statusMap.put("currentOrderStatus", currentMap.get("currentOrderStatus"));
|
||||
statusMap.put("beaconMac", currentMap.get("beaconMac"));
|
||||
|
||||
redisTemplate.opsForHash().putAll(key, statusMap);
|
||||
redisTemplate.expire(key, STATUS_EXPIRE_HOURS, TimeUnit.HOURS);
|
||||
|
||||
log.debug("处理工牌设备心跳: deviceId={}, deviceCode={}, batteryLevel={}, status={}",
|
||||
deviceId, deviceCode, batteryLevel, newStatus);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理工牌设备心跳失败: deviceId={}", deviceId, e);
|
||||
}
|
||||
}
|
||||
// ==================== 状态更新 (IoT 事件驱动) ====================
|
||||
|
||||
@Override
|
||||
public void updateBadgeOnlineStatus(Long deviceId, String deviceCode, Long areaId,
|
||||
@@ -342,7 +269,7 @@ public class BadgeDeviceStatusServiceImpl implements BadgeDeviceStatusService, I
|
||||
statusMap.put("statusChangeTime", LocalDateTime.now().toString());
|
||||
statusMap.put("statusChangeReason", reason);
|
||||
|
||||
// 如果是上线(非 OFFLINE 状态),更新心跳时间
|
||||
// 如果是上线(非 OFFLINE 状态),更新心跳时间(此处作为活跃时间使用)
|
||||
if (status.isActive()) {
|
||||
statusMap.put("lastHeartbeatTime", now);
|
||||
}
|
||||
@@ -389,49 +316,12 @@ public class BadgeDeviceStatusServiceImpl implements BadgeDeviceStatusService, I
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 在线状态检查 ====================
|
||||
|
||||
@Override
|
||||
public boolean isBadgeOnline(Long deviceId) {
|
||||
BadgeDeviceStatusDTO status = getBadgeStatus(deviceId);
|
||||
return status != null && status.isOnline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHeartbeatTimeout(Long deviceId, int thresholdMinutes) {
|
||||
BadgeDeviceStatusDTO status = getBadgeStatus(deviceId);
|
||||
return status == null || status.isHeartbeatTimeout(thresholdMinutes);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Scheduled(cron = "0 */5 * * * ?")
|
||||
public void checkAndMarkOfflineDevices() {
|
||||
try {
|
||||
List<BadgeDeviceStatusDTO> activeBadges = listActiveBadges();
|
||||
|
||||
long thresholdMillis = System.currentTimeMillis() - (HEARTBEAT_TIMEOUT_MINUTES * 60L * 1000L);
|
||||
|
||||
List<Long> offlineDeviceIds = new ArrayList<>();
|
||||
for (BadgeDeviceStatusDTO device : activeBadges) {
|
||||
if (device.getLastHeartbeatTime() == null ||
|
||||
device.getLastHeartbeatTime() < thresholdMillis) {
|
||||
updateBadgeStatus(device.getDeviceId(), BadgeDeviceStatusEnum.OFFLINE, null, "心跳超时");
|
||||
offlineDeviceIds.add(device.getDeviceId());
|
||||
}
|
||||
}
|
||||
|
||||
if (!offlineDeviceIds.isEmpty()) {
|
||||
log.info("标记心跳超时设备为离线: count={}, deviceIds={}",
|
||||
offlineDeviceIds.size(), offlineDeviceIds);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("检查心跳超时失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 工单关联 ====================
|
||||
|
||||
@Override
|
||||
public void setCurrentOrder(Long deviceId, Long orderId) {
|
||||
if (deviceId == null || orderId == null) {
|
||||
|
||||
@@ -32,7 +32,7 @@ import static org.mockito.Mockito.*;
|
||||
*/
|
||||
@Slf4j
|
||||
@SpringJUnitConfig(classes = BadgeDispatchTestConfig.class)
|
||||
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
|
||||
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
|
||||
public class BadgeDeviceDispatchTest {
|
||||
|
||||
@Resource
|
||||
@@ -114,32 +114,30 @@ public class BadgeDeviceDispatchTest {
|
||||
log.info("测试:心跳调用");
|
||||
log.info("========================================");
|
||||
|
||||
// 模拟心跳调用
|
||||
badgeDeviceStatusService.handleHeartbeatWithArea(
|
||||
// 模拟状态更新调用
|
||||
badgeDeviceStatusService.updateBadgeOnlineStatus(
|
||||
TEST_DEVICE_ID,
|
||||
TEST_DEVICE_CODE,
|
||||
75,
|
||||
TEST_AREA_ID,
|
||||
"A座2楼男卫"
|
||||
);
|
||||
BadgeDeviceStatusEnum.IDLE,
|
||||
"测试心跳");
|
||||
|
||||
// 验证调用
|
||||
verify(badgeDeviceStatusService).handleHeartbeatWithArea(
|
||||
verify(badgeDeviceStatusService).updateBadgeOnlineStatus(
|
||||
eq(TEST_DEVICE_ID),
|
||||
eq(TEST_DEVICE_CODE),
|
||||
eq(75),
|
||||
eq(TEST_AREA_ID),
|
||||
eq("A座2楼男卫")
|
||||
);
|
||||
|
||||
eq(BadgeDeviceStatusEnum.IDLE),
|
||||
eq("测试心跳"));
|
||||
|
||||
// Mock getBadgeStatus return
|
||||
BadgeDeviceStatusDTO mockStatus = new BadgeDeviceStatusDTO();
|
||||
mockStatus.setStatus(BadgeDeviceStatusEnum.IDLE);
|
||||
mockStatus.setBatteryLevel(75);
|
||||
mockStatus.setCurrentAreaName("A座2楼男卫");
|
||||
|
||||
|
||||
when(badgeDeviceStatusService.getBadgeStatus(TEST_DEVICE_ID)).thenReturn(mockStatus);
|
||||
|
||||
|
||||
BadgeDeviceStatusDTO status = badgeDeviceStatusService.getBadgeStatus(TEST_DEVICE_ID);
|
||||
assertNotNull(status);
|
||||
assertEquals(BadgeDeviceStatusEnum.IDLE, status.getStatus());
|
||||
|
||||
Reference in New Issue
Block a user