package com.ard.work.service.impl; import com.ard.common.constant.CacheConstants; import com.ard.common.core.domain.entity.SysUser; import com.ard.common.core.redis.RedisCache; import com.ard.common.utils.DateUtils; import com.ard.work.component.forest.TyClient; import com.ard.work.domain.dto.BoxHistoryDTO; import com.ard.work.domain.entity.ArdFlightTask; import com.ard.work.domain.receiver.BoxHistoryReceiver; import com.ard.work.domain.receiver.TyHttpCommonReceiver; import com.ard.work.mapper.ArdFlightTaskMapper; import com.ard.work.service.IArdFlightTaskService; import com.ard.work.service.IArdMediaService; import com.ard.work.service.IArdServerInfoService; import com.ard.work.service.control.UavControlService; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Date; import java.util.List; @Slf4j @Service public class ArdFlightTaskServiceImpl implements IArdFlightTaskService { @Resource private ArdFlightTaskMapper ardFlightTaskMapper; @Resource private IArdServerInfoService ardServerInfoService; @Resource private UavControlService uavControlService; @Resource private IArdMediaService ardMediaService; @Resource private RedisCache redisCache; @Resource private TyClient tyClient; /** * 查询飞行架次列表 * * @param ardFlightTask 飞行架次 * @return 飞行架次集合 */ @Override public List selectArdFlightTask(ArdFlightTask ardFlightTask) { return ardFlightTaskMapper.selectArdFlightTask(ardFlightTask); } /** * 同步所有服务的飞行历史 */ @Scheduled(fixedDelay = 5000) public void syncAllFlightHistory() { try { List serverIds = ardServerInfoService.getServerIdsList(); for (String serverId : serverIds) { // 获取上次同步的时间(即数据库中最大 startTime) Date lastSyncTime = getLastSyncTimeForServer(serverId); // 根据上次同步时间同步飞行历史 syncFlightHistory(serverId, lastSyncTime); } } catch (Exception e) { log.error("同步飞行历史失败", e); } } // 获取上次同步时间(获取最大 startTime) private Date getLastSyncTimeForServer(String serverId) { Date maxStartTime = ardFlightTaskMapper.findMaxStartTimeByServerId(serverId); return maxStartTime != null ? maxStartTime : new Date(0); // 如果没有数据,返回 Unix 纪元时间作为起点 } // 调用接口获取飞行历史数据 private List getBoxHistory(String serverId, BoxHistoryDTO boxHistoryDTO) { TyHttpCommonReceiver> boxHistory = tyClient.getBoxHistory(serverId, boxHistoryDTO); return boxHistory.getContent(); } // 根据上次同步时间同步飞行历史 public void syncFlightHistory(String serverId, Date startTime) { // 创建查询条件 BoxHistoryDTO,并设置 startTime 作为过滤条件 BoxHistoryDTO boxHistoryDTO = BoxHistoryDTO.builder() .pageIndex(1) .pageSize(20) .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, startTime)) .build(); // 获取飞行历史 List historyList = getBoxHistory(serverId, boxHistoryDTO); // 如果获取到数据,处理并同步到本地数据库 if (historyList != null && !historyList.isEmpty()) { for (BoxHistoryReceiver boxHistory : historyList) { syncToLocalDatabase(serverId, boxHistory); } } } // 将数据同步到本地数据库 private void syncToLocalDatabase(String serverId, BoxHistoryReceiver boxHistoryReceiver) { // 检查是否已经存在相同任务ID的记录 ArdFlightTask ardFlightTask = ardFlightTaskMapper.getArdFlightTaskById(boxHistoryReceiver.getTaskId()); if (ardFlightTask == null) { // 如果不存在,则插入新记录 log.info("insert task {}", boxHistoryReceiver.getTaskId()); Date endTime = null; if (boxHistoryReceiver.getEndTime() != null) { endTime = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getEndTime()); } // 创建FlightTask实体对象并填充数据 ArdFlightTask flightTask = ArdFlightTask.builder() .taskId(boxHistoryReceiver.getTaskId()) .boxSn(boxHistoryReceiver.getBoxSn()) .boxName(boxHistoryReceiver.getBoxName()) .taskName(boxHistoryReceiver.getTaskName()) .photoCount(Integer.parseInt(boxHistoryReceiver.getPhotoCount())) .videoCount((boxHistoryReceiver.getVideoPathList() != null) ? boxHistoryReceiver.getVideoPathList().size() : 0) .videoPath(boxHistoryReceiver.getVideoPath()) .serverId(serverId) .startTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getStartTime())) .endTime(endTime) .flightMileage(boxHistoryReceiver.getFlightMileage()) .flightDuration(boxHistoryReceiver.getFlightDuration()) .aveSpeed(boxHistoryReceiver.getAveSpeed()) .maxSpeed(boxHistoryReceiver.getMaxSpeed()) .build(); Long flyUserId = uavControlService.getCurrentController(flightTask.getBoxSn(), "fly"); if (flyUserId != null) { SysUser flyUser = redisCache.getCacheObject(CacheConstants.SYS_USER_KEY + flyUserId); if (flyUser != null && flyUser.getNickName() != null) { flightTask.setCreateBy(flyUser.getNickName()); } } flightTask.setCreateTime(DateUtils.getNowDate()); // 插入新记录 int rows = ardFlightTaskMapper.insertArdFlightTask(flightTask); if (rows > 0) { // 插入视频 ardMediaService.insertVideoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn()); // 插入图片 ardMediaService.insertPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn()); } } else { // 如果存在,则更新记录 log.debug("sync task {}", boxHistoryReceiver.getTaskId()); updateFlightTask(ardFlightTask, boxHistoryReceiver); // 同步任务图片 ardMediaService.syncPicToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn()); // 同步任务视频 ardMediaService.syncVideoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn()); } } private void updateFlightTask(ArdFlightTask local, BoxHistoryReceiver remote) { boolean needUpdate = false; // endTime 更新(重要!!!) if (remote.getEndTime() != null) { Date newEnd = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, remote.getEndTime()); if (local.getEndTime() == null || !local.getEndTime().equals(newEnd)) { local.setEndTime(newEnd); local.setAveSpeed(remote.getAveSpeed()); local.setMaxSpeed(remote.getMaxSpeed()); local.setFlightDuration(remote.getFlightDuration()); local.setFlightMileage(remote.getFlightMileage()); needUpdate = true; } } // photoCount 更新 int remotePhotoCount = Integer.parseInt(remote.getPhotoCount()); if (local.getPhotoCount() != remotePhotoCount) { local.setPhotoCount(remotePhotoCount); needUpdate = true; } // videoCount 更新 int remoteVideoCount = remote.getVideoPathList() != null ? remote.getVideoPathList().size() : 0; if (local.getVideoCount() != remoteVideoCount) { local.setVideoCount(remoteVideoCount); needUpdate = true; } if (needUpdate) { ardFlightTaskMapper.updateArdFlightTask(local); } } }