package com.ruoyi.quartz.task; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.stream.Collectors; import com.ruoyi.common.utils.PlateNumberExtractor; import com.ruoyi.system.domain.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.service.ICmsGpsCollectService; import com.ruoyi.system.service.IVehicleGpsService; import com.ruoyi.system.service.IVehicleInfoService; /** * CMS车辆同步定时任务 * * @author ruoyi */ @Component("cmsVehicleSyncTask") public class CmsVehicleSyncTask { private static final Logger log = LoggerFactory.getLogger(CmsVehicleSyncTask.class); @Autowired private ICmsGpsCollectService cmsGpsCollectService; @Autowired private IVehicleInfoService vehicleInfoService; @Autowired private IVehicleGpsService vehicleGpsService; public void syncVehicleInfo() { // log.info("开始同步CMS车辆信息"); try { // 获取CMS所有车辆信息 CmsVehicleDeviceListResponse response = cmsGpsCollectService.getDeviceByVehicle(null); if (response.getResult() != 0) { log.error("获取CMS车辆信息失败"); return; } // 获取所有CMS车辆的车牌号 List cmsPlateNos = new ArrayList<>(); response.getDevices().forEach(vehicle -> { if (StringUtils.isNotEmpty(vehicle.getVid())) { // 从车辆名称中提取车牌号(假设格式为"★车牌号(地区)") String plateNo =this.getPlateNo(vehicle.getVid()); cmsPlateNos.add(plateNo); } }); // 获取本地所有车辆 VehicleInfo query = new VehicleInfo(); query.setStatus("0"); List localVehicles = vehicleInfoService.selectVehicleInfoList(query); //找到所有车辆中不是CMS平台的车辆 List notCmsVehicles = localVehicles.stream().filter(e->!e.getPlatformCode().equals("CMS")).map(e->e.getVehicleNo()).collect((Collectors.toList())); List onlyCms=cmsPlateNos.stream().filter(e->!notCmsVehicles.contains(e)).collect((Collectors.toList())); Integer syncCarCount=0; for (CmsVehicleDeviceListResponse.CmsVehicleDevice vehicle : response.getDevices()) { try { if (!onlyCms.contains(this.getPlateNo(vehicle.getVid()))) { continue; } String plateNo = this.getPlateNo(vehicle.getVid()); // 使用重试机制处理死锁 int maxRetries = 3; int retryCount = 0; boolean success = false; while (!success && retryCount < maxRetries) { try { // 查询车辆信息(使用精确匹配) VehicleInfo vehicleInfo = vehicleInfoService.selectVehicleInfoByPlateNumber(plateNo); if (vehicleInfo == null) { // 新增车辆 vehicleInfo = new VehicleInfo(); vehicleInfo.setVehicleNo(plateNo); vehicleInfo.setDeviceId(vehicle.getDid()); vehicleInfo.setPlatformCode("CMS"); vehicleInfo.setStatus("0"); vehicleInfoService.insertVehicleInfo(vehicleInfo); syncCarCount++; // log.info("新增CMS车辆: {}", plateNo); } else { // 更新车辆 - 仅更新必要字段,避免触发关联表操作 vehicleInfo.setDeviceId(vehicle.getDid()); vehicleInfo.setPlatformCode("CMS"); vehicleInfo.setStatus("0"); vehicleInfo.setDeptIds(null); // 不更新部门关联,避免死锁 vehicleInfoService.updateVehicleInfo(vehicleInfo); syncCarCount++; // log.debug("更新CMS车辆: {}", plateNo); } success = true; } catch (org.springframework.dao.DeadlockLoserDataAccessException e) { retryCount++; if (retryCount < maxRetries) { log.warn("同步车辆 {} 遇到死锁,第{}次重试", plateNo, retryCount); // 随机等待50-200ms后重试,避免多个线程同时重试 Thread.sleep(50 + (long)(Math.random() * 150)); } else { log.error("同步车辆 {} 失败: 死锁重试{}次后仍失败", plateNo, maxRetries); throw e; } } } } catch (Exception e) { log.error("同步车辆 {} 失败: {}", vehicle.getVid(), e.getMessage()); // 继续处理下一个车辆 } } // log.info("成功同步{}个CMS车辆信息", syncCarCount); // log.info("CMS车辆信息同步完成"); } catch (Exception e) { log.error("同步CMS车辆信息异常", e); } } //对车牌处理的通用方法 private String getPlateNo(String plateNo){ if (StringUtils.isNotEmpty(plateNo)) { // 从车辆名称中提取车牌号(假设格式为"★车牌号(地区)") if(plateNo.contains("(")) { plateNo = plateNo.replace("★", "").replace("☆", "").split("\\(")[0]; }else{ plateNo = plateNo.replace("★", "").replace("☆", "").split("(")[0]; } } //xxx粤VSX120 plateNo = plateNo.replaceAll("[^a-zA-Z0-9]", ""); return PlateNumberExtractor.extractPlateNumber(plateNo); } /** * 同步CMS车辆位置信息 */ public void syncVehicleLocation() { // log.info("开始同步CMS车辆位置信息"); try { //先获得本地CMS上的所有CMS车辆 VehicleInfo query = new VehicleInfo(); query.setPlatformCode("CMS"); query.setStatus("0"); List localVehicles = vehicleInfoService.selectVehicleInfoList(query); // 获取车辆最新位置信息 CmsVehicleLocationResponse response = cmsGpsCollectService.getVehicleLocation( null,2,1,null,null); if (response.getResult() != 0 ) { log.warn("获取车辆位置信息失败"); return; } List cmsVehicles = response.getInfos(); Double defaultZero = 0.0; for(CmsVehicleLocationResponse.VehicleLocation vehicle:cmsVehicles){ //与车辆信息进行匹配,如果匹配成功,则保存车辆位置信息 //对车牌进行处理 String plateNo =this.getPlateNo(vehicle.getVi()); if (!localVehicles.stream().anyMatch(e->e.getVehicleNo().equals(plateNo))) { continue; } VehicleInfo f= localVehicles.stream().filter(e->e.getVehicleNo().equals(plateNo)).findFirst().get(); if(f==null){ continue; } if(vehicle.getJd()==null||vehicle.getWd()==null){ continue; } // 创建GPS记录 VehicleGps gps = new VehicleGps(); gps.setVehicleId(f.getVehicleId()); gps.setDeviceId(null); gps.setLongitude(vehicle.getJd()/1000000); gps.setLatitude(vehicle.getWd()/1000000); gps.setSpeed(defaultZero); gps.setVehicleNo(plateNo); gps.setDirection(defaultZero); gps.setAltitude(defaultZero); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String deviceTime=sdf.format(new Date(vehicle.getTm())); gps.setDeviceReportTime(deviceTime); gps.setPlatformProcessTime(sdf.format(new Date())); gps.setCreateTime(new Date()); gps.setCollectTime(deviceTime); // 保存GPS记录 vehicleGpsService.insertVehicleGps(gps); } } catch (Exception e) { log.error("同步车辆位置信息异常", e); } } }