diff --git a/src/main/java/com/ycwl/basic/controller/pc/DeviceVideoContinuityController.java b/src/main/java/com/ycwl/basic/controller/pc/DeviceVideoContinuityController.java index 1affd237..9e0a03cb 100644 --- a/src/main/java/com/ycwl/basic/controller/pc/DeviceVideoContinuityController.java +++ b/src/main/java/com/ycwl/basic/controller/pc/DeviceVideoContinuityController.java @@ -6,7 +6,6 @@ import com.ycwl.basic.device.entity.common.DeviceVideoContinuityCache; import com.ycwl.basic.model.pc.device.entity.DeviceEntity; import com.ycwl.basic.model.pc.device.req.VideoContinuityReportReq; import com.ycwl.basic.repository.DeviceRepository; -import com.ycwl.basic.task.DeviceVideoContinuityCheckTask; import com.ycwl.basic.utils.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -37,7 +36,6 @@ public class DeviceVideoContinuityController { private final RedisTemplate redisTemplate; private final ObjectMapper objectMapper; - private final DeviceVideoContinuityCheckTask checkTask; private final DeviceRepository deviceRepository; /** @@ -78,15 +76,7 @@ public class DeviceVideoContinuityController { @PostMapping("/{deviceId}/check") public ApiResponse manualCheck(@PathVariable Long deviceId) { log.info("手动触发设备 {} 的视频连续性检查", deviceId); - - try { - DeviceVideoContinuityCache result = checkTask.manualCheck(deviceId); - return ApiResponse.success(result); - - } catch (Exception e) { - log.error("手动检查设备 {} 视频连续性失败", deviceId, e); - return ApiResponse.buildResponse(500, null, "检查失败: " + e.getMessage()); - } + return ApiResponse.success(null); } /** diff --git a/src/main/java/com/ycwl/basic/task/DeviceVideoContinuityCheckTask.java b/src/main/java/com/ycwl/basic/task/DeviceVideoContinuityCheckTask.java deleted file mode 100644 index 65dd0a37..00000000 --- a/src/main/java/com/ycwl/basic/task/DeviceVideoContinuityCheckTask.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.ycwl.basic.task; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.ycwl.basic.device.DeviceFactory; -import com.ycwl.basic.device.entity.common.DeviceVideoContinuityCache; -import com.ycwl.basic.device.entity.common.VideoContinuityResult; -import com.ycwl.basic.device.operator.IDeviceStorageOperator; -import com.ycwl.basic.integration.common.response.PageResponse; -import com.ycwl.basic.integration.device.dto.device.DeviceV2DTO; -import com.ycwl.basic.integration.device.service.DeviceIntegrationService; -import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; -import com.ycwl.basic.repository.DeviceRepository; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Profile; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import java.util.Calendar; -import java.util.Date; -import java.util.concurrent.TimeUnit; - -/** - * 设备视频连续性检查定时任务 - * - 仅在生产环境(prod)运行 - * - 每5分钟执行一次 - * - 检查前12分钟到前2分钟的视频连续性 - * - 仅在9点到18点之间检查 - * - 结果缓存到Redis中 - * - * @author Claude Code - * @date 2025-09-01 - */ -@Slf4j -@Component -@EnableScheduling -//@Profile("prod") -public class DeviceVideoContinuityCheckTask { - - private static final String REDIS_KEY_PREFIX = "device:video:continuity:"; - private static final int CACHE_TTL_HOURS = 24; // 缓存24小时 - private static final int START_HOUR = 9; // 开始检查时间 9:00 - private static final int END_HOUR = 18; // 结束检查时间 18:00 - - @Autowired - private DeviceIntegrationService deviceIntegrationService; - - @Autowired - private DeviceRepository deviceRepository; - - @Autowired - private RedisTemplate redisTemplate; - - @Autowired - private ObjectMapper objectMapper; - - /** - * 定时任务:每5分钟执行一次 - * cron表达式: 0 0/5 * * * * 表示每5分钟执行一次 - */ - @Scheduled(cron = "0 0/5 * * * *") - public void checkDeviceVideoContinuity() { - // 检查是否在执行时间范围内(9:00-18:00) - int currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); - if (currentHour < START_HOUR || currentHour >= END_HOUR) { - log.debug("当前时间 {}:00 不在检查时间范围内({}:00-{}:00),跳过检查", - currentHour, START_HOUR, END_HOUR); - return; - } - - log.info("开始执行设备视频连续性检查定时任务"); - long startTime = System.currentTimeMillis(); - - try { - // 获取所有激活的设备(分页获取,每次100个) - int pageSize = 100; - int currentPage = 1; - int totalChecked = 0; - int successCount = 0; - int failureCount = 0; - - while (true) { - PageResponse pageResponse = deviceIntegrationService.listDevices( - currentPage, pageSize, null, null, null, 1, null, null - ); - - if (pageResponse == null || pageResponse.getList() == null - || pageResponse.getList().isEmpty()) { - break; - } - - // 检查每个设备的视频连续性 - for (DeviceV2DTO device : pageResponse.getList()) { - try { - boolean checked = checkSingleDevice(device); - totalChecked++; - if (checked) { - successCount++; - } else { - failureCount++; - } - } catch (Exception e) { - log.error("检查设备 {} 视频连续性失败: {}", device.getId(), e.getMessage(), e); - failureCount++; - totalChecked++; - } - } - - // 检查是否还有更多页 - int totalPages = (int) Math.ceil((double) pageResponse.getTotal() / pageSize); - if (currentPage >= totalPages) { - break; - } - currentPage++; - } - - long endTime = System.currentTimeMillis(); - log.info("设备视频连续性检查任务完成: 总计检查 {} 个设备, 成功 {}, 失败 {}, 耗时 {}ms", - totalChecked, successCount, failureCount, (endTime - startTime)); - - } catch (Exception e) { - log.error("执行设备视频连续性检查定时任务失败", e); - } - } - - /** - * 检查单个设备的视频连续性 - * - * @param device 设备信息 - * @return true表示检查成功并缓存,false表示跳过检查 - */ - private boolean checkSingleDevice(DeviceV2DTO device) { - try { - // 获取设备配置 - DeviceConfigEntity config = deviceRepository.getDeviceConfig(device.getId()); - if (config == null) { - log.debug("设备 {} 没有配置信息,跳过检查", device.getId()); - return false; - } - - // 获取设备的存储操作器 - IDeviceStorageOperator operator = DeviceFactory.getDeviceStorageOperator(device, config); - if (operator == null) { - log.debug("设备 {} 没有配置存储操作器,跳过检查", device.getId()); - return false; - } - - // 计算检查时间范围: 当前时间向前12分钟到向前2分钟 - Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.MINUTE, -2); - Date endDate = calendar.getTime(); - - calendar.add(Calendar.MINUTE, -10); // 再向前10分钟,总共12分钟 - Date startDate = calendar.getTime(); - - // 执行连续性检查(允许2秒间隙) - VideoContinuityResult result = operator.checkVideoContinuity(startDate, endDate, 2000L); - - // 如果设备不支持连续性检查,检查是否已有外部上报的缓存记录 - String redisKey = REDIS_KEY_PREFIX + device.getId(); - if (!result.isSupport()) { - String existingCache = redisTemplate.opsForValue().get(redisKey); - if (existingCache != null) { - // 已有缓存记录(可能是外部工具上报的),不覆盖 - log.debug("设备 {} 不支持内部连续性检查,但已有缓存记录,跳过覆盖", device.getId()); - return false; - } - } - - // 创建缓存对象 - DeviceVideoContinuityCache cache = DeviceVideoContinuityCache.fromResult( - device.getId(), result, startDate, endDate - ); - - // 存储到Redis - String cacheJson = objectMapper.writeValueAsString(cache); - redisTemplate.opsForValue().set(redisKey, cacheJson, CACHE_TTL_HOURS, TimeUnit.HOURS); - - log.info("设备 {} 视频连续性检查完成: support={}, continuous={}, videos={}, gaps={}, duration={}ms", - device.getId(), result.isSupport(), result.isContinuous(), - result.getTotalVideos(), result.getGapCount(), result.getTotalDurationMs()); - - return true; - - } catch (Exception e) { - log.error("检查设备 {} 视频连续性失败", device.getId(), e); - throw new RuntimeException("检查设备视频连续性失败", e); - } - } - - /** - * 手动触发检查(用于测试) - * - * @param deviceId 设备ID - * @return 检查结果 - */ - public DeviceVideoContinuityCache manualCheck(Long deviceId) { - log.info("手动触发设备 {} 的视频连续性检查", deviceId); - - try { - // 获取设备信息 - DeviceV2DTO device = deviceIntegrationService.getDevice(deviceId); - if (device == null) { - throw new RuntimeException("设备不存在: " + deviceId); - } - - // 检查设备 - checkSingleDevice(device); - - // 从Redis获取结果 - String redisKey = REDIS_KEY_PREFIX + deviceId; - String cacheJson = redisTemplate.opsForValue().get(redisKey); - if (cacheJson == null) { - throw new RuntimeException("检查完成但未找到缓存结果"); - } - - return objectMapper.readValue(cacheJson, DeviceVideoContinuityCache.class); - - } catch (Exception e) { - log.error("手动检查设备 {} 视频连续性失败", deviceId, e); - throw new RuntimeException("手动检查失败: " + e.getMessage(), e); - } - } -} diff --git a/src/main/resources/logback-spring-prod.xml b/src/main/resources/logback-spring-prod.xml index 44f3a5f0..cc9e5fe9 100644 --- a/src/main/resources/logback-spring-prod.xml +++ b/src/main/resources/logback-spring-prod.xml @@ -98,10 +98,6 @@ - - - -