liusuyi
2026-02-10 4ac9edd4c0030d2daafd712cd14ef9080b2f1e43
ard-device/src/main/java/com/ard/device/camera/service/impl/ArdCameraServiceImpl.java
@@ -28,7 +28,9 @@
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.Validator;
import java.util.*;
@@ -58,6 +60,8 @@
    @Resource
    protected Validator validator;
    @Resource(name = "globalExecutor")
    private ThreadPoolTaskExecutor executorService;
    @Override
    public void run(ApplicationArguments args) {
@@ -66,23 +70,15 @@
    public void initCamera() {
        //清空相机缓存
        redisService.deleteObject(redisService.keys(getCacheKey("*")));
        redisService.deleteObject(CacheConstants.CAMERA_LIST);
        //重新加载相机到缓存
        ardCameraMapper.selectArdCameraList(new ArdCamera()).forEach(ardCamera -> {
            ardCameraMapper.resetCameraLoginId(ardCamera);
            redisService.setCacheObject(getCacheKey(ardCamera.getId()), ardCamera);
            cameraSDKService.login(ardCamera);
            redisService.setCacheMapValue(CacheConstants.CAMERA_LIST, ardCamera.getId(), ardCamera);
            // 提交到线程池异步执行
            executorService.submit(() -> {
                cameraSDKService.login(ardCamera);
            });
        });
    }
    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    private String getCacheKey(String configKey) {
        return CacheConstants.CAMERA_LIST_KEY + configKey;
    }
@@ -145,6 +141,7 @@
        ardCamera.setUserId(SecurityUtils.getUserId());
        int res = ardCameraMapper.insertArdCamera(ardCamera);
        if (res > 0) {
            redisService.setCacheMapValue(CacheConstants.CAMERA_LIST, ardCamera.getId(), ardCamera);
            cameraSDKService.login(ardCamera);//sdk登录获取通道信息
        }
        return res;
@@ -162,7 +159,8 @@
        ardCamera.setUpdateBy(SecurityUtils.getUsername());
        int res = ardCameraMapper.updateArdCamera(ardCamera);
        if (res > 0) {
            cameraSDKService.logout(ardCamera.getId());//sdk注销
            redisService.setCacheMapValue(CacheConstants.CAMERA_LIST, ardCamera.getId(), ardCamera);
            cameraSDKService.logout(ardCamera);//sdk注销
            cameraSDKService.login(ardCamera);//sdk登录获取通道信息
        }
        return res;
@@ -181,11 +179,11 @@
            ArdCamera camera = ardCameraMapper.selectArdCameraById(id);
            if (camera != null) {
                //redis中删除
                redisService.deleteObject(getCacheKey(id));
                redisService.deleteCacheMapValue(CacheConstants.CAMERA_LIST, id);
                //删除当前相机的所有通道
                ardChannelService.deleteArdChannelByDeviceId(id);
                //sdk注销
                cameraSDKService.logout(id);
                cameraSDKService.logout(camera);
            }
        }
        return ardCameraMapper.deleteArdCameraByIds(ids);
@@ -202,11 +200,11 @@
        int i = ardCameraMapper.deleteArdCameraById(id);
        if (i > 0) {
            //redis中删除
            redisService.deleteObject(getCacheKey(id));
            redisService.deleteCacheMapValue(CacheConstants.CAMERA_LIST, id);
            //删除当前相机的所有通道
            ardChannelService.deleteArdChannelByDeviceId(id);
            //sdk注销
            cameraSDKService.logout(id);
            cameraSDKService.logout(ArdCamera.builder().id(id).build());
        }
        return i;
    }
@@ -295,6 +293,20 @@
        return DeviceConstants.UNIQUE;
    }
    /**
     * 校验机场是否已关联相机
     *
     * @param camera 相机
     * @return 结果
     */
    @Override
    public ArdCamera checkAirportHasCamera(ArdCamera camera) {
        ArdCamera info = ardCameraMapper.checkAirportHasCamera(camera);
        if (StringUtils.isNotNull(info) && !info.getId().equals(camera.getId())) {
            return info;
        }
        return null;
    }
    /**
     * 同步通道
@@ -354,52 +366,27 @@
    public void LoginEventListener(LoginEvent loginEvent) {
        ArdCamera camera = loginEvent.getCamera();
        ardCameraMapper.updateArdCamera(camera);
        // SDK 登录成功后写入 Redis
        redisService.setCacheObject(getCacheKey(camera.getId()), camera);
    }
    /**
     * 同步设备通道与本地通道库信息
     *
     * @author 刘苏义
     * @date 2024/8/22 14:37
     */
    @Scheduled(cron = "0/10 * * * * ?")
    public void syncChannel() {
        try {
            log.debug("定时执行同步通道任务");
            List<ArdCamera> ardCameraList = this.selectArdCameraList(new ArdCamera());
            if (!ardCameraList.isEmpty()) {
                ardCameraList
                        .forEach(ardCamera -> {
                            //SDK获取实际通道
                            List<ArdChannel> ardChannelListSDK = cameraSDKService.getChannels(ardCamera);
                            //数据库获取通道
                            ArdChannel ardChannel = new ArdChannel();
                            ardChannel.setDeviceId(ardCamera.getId());
                            List<ArdChannel> ardChannelListDb = ardChannelService.selectArdChannelList(ardChannel);
                            //同步通道
                            asyncChannel(ardChannelListDb, ardChannelListSDK);
                        });
            }
        } catch (Exception ex) {
            log.error("定时执行同步通道任务异常:{}", ex.getMessage());
        }
    }
    /**
     * 定时执行登录失败相机重新登录
     *
     * @author 刘苏义
     * @date 2024/8/22 14:37
     */
    @Scheduled(cron = "0/30 * * * * ?")
    @Scheduled(cron = "0/10 * * * * ?")
    public void failedReconnect() {
        try {
            log.debug("定时执行失败相机重连任务");
            List<Object> ardCameras = redisService.getListKey(CacheConstants.CAMERA_LIST_KEY);
            ardCameras.stream()
                    .map(object -> (ArdCamera) object) // 将Object转换为ArdCameras
                    .filter(camera -> !GlobalVariable.loginMap.containsKey(camera.getId()))
                    .forEach(camera -> cameraSDKService.login(camera));
            // 从数据库取全部设备
            ArdCamera ardCamera = new ArdCamera();
            ardCamera.setUseDataScope(false);
            List<ArdCamera> cameraList = this.selectArdCameraList(ardCamera);
            cameraList.stream()
                    // 只处理登录失败或离线的设备
                    .filter(camera -> camera.getLoginId() == null || camera.getLoginId() < 0 || "0".equals(camera.getState()))
                    .forEach(camera -> {
                        log.info("尝试重新登录设备 {}:{}", camera.getIp(), camera.getPort());
                        cameraSDKService.login(camera);
                    });
        } catch (Exception ex) {
            log.error("定时执行失败相机重连任务异常:{}", ex.getMessage());
        }
@@ -407,20 +394,18 @@
    /**
     * 同步相机在线状态
     * 刘苏义
     * 2023/10/8 14:54:41
     */
    @Scheduled(cron = "0/10 * * * * ?")
    public void cameraState() {
    public void syncCameraState() {
        try {
            log.debug("定时执行同步相机在线状态任务");
            //调用查询方法
            List<ArdCamera> ardCameraList = selectArdCameraList(new ArdCamera());
            ArdCamera ardCamera = new ArdCamera();
            ardCamera.setUseDataScope(false);
            List<ArdCamera> ardCameraList = this.selectArdCameraList(ardCamera);
            ardCameraList
                    .forEach(camera -> {
                        CameraCmd cmd = new CameraCmd();
                        cmd.setCameraId(camera.getId());
                        boolean onLineNew = cameraSDKService.isOnLine(cmd);
                        boolean onLineNew = cameraSDKService.isOnLine(camera);
                        boolean onLineOld = "1".equals(camera.getState());
                        if (onLineNew != onLineOld) {
                            if (onLineNew) {
@@ -436,4 +421,35 @@
            log.error("同步相机在线状态异常:{}", ex.getMessage());
        }
    }
    /**
     * 同步相机通道
     */
    @Scheduled(cron = "0/10 * * * * ?")
    public void syncChannel() {
        try {
            log.debug("定时执行同步通道任务");
            ArdCamera camera = new ArdCamera();
            camera.setUseDataScope(false);
            List<ArdCamera> ardCameraList = this.selectArdCameraList(camera);
            if (!ardCameraList.isEmpty()) {
                ardCameraList
                        .forEach(ardCamera -> {
                            //SDK获取实际通道
                            List<ArdChannel> ardChannelListSDK = cameraSDKService.getChannels(ardCamera);
                            //数据库获取通道
                            ArdChannel ardChannel = new ArdChannel();
                            ardChannel.setUseDataScope(false);
                            ardChannel.setDeviceId(ardCamera.getId());
                            List<ArdChannel> ardChannelListDb = ardChannelService.selectArdChannelList(ardChannel);
                            //同步通道
                            asyncChannel(ardChannelListDb, ardChannelListSDK);
                        });
            }
        } catch (Exception ex) {
            log.error("定时执行同步通道任务异常:{}", ex.getMessage());
        }
    }
}