package com.multictrl.common.task; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.google.common.collect.Maps; import com.multictrl.common.utils.DateUtils; import com.multictrl.common.utils.map.Spatial4jUtils; import com.multictrl.modules.business.dao.FlightTaskDao; import com.multictrl.modules.business.entity.FlightTaskEntity; import com.multictrl.modules.business.entity.MediaFileEntity; import com.multictrl.modules.business.influxdb.UavReport; import com.multictrl.modules.business.service.FlightTaskService; import com.multictrl.modules.business.service.InfluxService; import com.multictrl.modules.business.service.MediaFileService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.*; /** * 航线任务矫正 * * @author Sdy * @since 1.0.0 2025/5/29 */ @Slf4j @Component @RequiredArgsConstructor public class FlightTaskUpdate { private final InfluxService influxService; private final MediaFileService mediaFileService; private final FlightTaskService flightTaskService; private final FlightTaskDao flightTaskDao; @Scheduled(fixedRate = 60 * 1000) // 每 60秒执行一次(单位:毫秒) public void updateFlightTask() { Date threeHoursAgo = DateUtil.offsetHour(new Date(), -3); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.gt(FlightTaskEntity::getCreateDate, threeHoursAgo) .and(wrapper2 -> wrapper2 .isNull(FlightTaskEntity::getTaskStatus) .or() .eq(FlightTaskEntity::getTaskStatus, 0) .or() .isNull(FlightTaskEntity::getFlightDistance) .or() .isNull(FlightTaskEntity::getFlightDuration) .or() .isNull(FlightTaskEntity::getMediaNum) .or() .eq(FlightTaskEntity::getMediaNum, 0) ); List taskList = flightTaskDao.selectList(wrapper); Map updateMap = new HashMap<>(); for (FlightTaskEntity entity : taskList) { Date createDate = entity.getCreateDate(); long createMillis = createDate.getTime(); long diffSeconds = Math.abs((new Date().getTime() - createMillis) / 1000); // 1. 处理状态字段 handleStatus(entity, diffSeconds, updateMap); // 2. 处理飞行距离 handleFlightDistance(entity, diffSeconds, updateMap); // 3. 处理飞行时长 handleFlightDuration(entity, diffSeconds, updateMap); // 4. 处理媒体数量 handleMediaNum(entity, diffSeconds, updateMap); } if (!updateMap.isEmpty()) { flightTaskService.updateBatchById(new ArrayList<>(updateMap.values())); } } private void handleStatus(FlightTaskEntity entity, long diffSeconds, Map updateMap) { if (entity.getTaskStatus() == null || entity.getTaskStatus() == 0) { if (entity.getFailureReason() != null) { entity.setTaskStatus(-1); updateMap.put(entity.getTaskId(), entity); } else if (entity.getInboundDate() != null) { entity.setTaskStatus(1); updateMap.put(entity.getTaskId(), entity); } else if (diffSeconds > 7200) { entity.setTaskStatus(-1); updateMap.put(entity.getTaskId(), entity); } else if (entity.getTaskStatus() == null) { entity.setTaskStatus(0); updateMap.put(entity.getTaskId(), entity); } } } private void handleFlightDistance(FlightTaskEntity entity, long diffSeconds, Map updateMap) { if (entity.getFlightDistance() == null) { if (entity.getOutboundDate() != null && entity.getInboundDate() != null) { entity.setFlightDistance(getFlightDistance(entity.getDockSn(), entity.getOutboundDate(), entity.getInboundDate())); updateMap.put(entity.getTaskId(), entity); } else if (diffSeconds > 7200) { if (entity.getInboundDate() != null) { entity.setFlightDistance(getFlightDistance(entity.getDockSn(), entity.getCreateDate(), entity.getInboundDate())); updateMap.put(entity.getTaskId(), entity); } else if (entity.getOutboundDate() != null) { entity.setFlightDistance(getFlightDistance(entity.getDockSn(), entity.getOutboundDate(), DateUtils.getBeforeHour(entity.getOutboundDate(), 1))); updateMap.put(entity.getTaskId(), entity); } else { entity.setFlightDistance(getFlightDistance(entity.getDockSn(), entity.getCreateDate(), DateUtils.getBeforeHour(entity.getCreateDate(), 1))); updateMap.put(entity.getTaskId(), entity); } } } } //获取飞行距离 private double getFlightDistance(String dockSn, Date startDate, Date endDate) { HashMap condition = Maps.newHashMap(); condition.put("dockSn", dockSn); List flyList = influxService.queryData(DateUtils.format(startDate, DateUtils.DATE_TIME_PATTERN), DateUtils.format(endDate, DateUtils.DATE_TIME_PATTERN), "uav_osd", condition, UavReport.class, "longitude", "latitude", "elevation", "_time"); double total = 0; for (int i = 0; i < flyList.size() - 1; i++) { UavReport p1 = flyList.get(i); UavReport p2 = flyList.get(i + 1); total += Spatial4jUtils.distance(p1.getLatitude(), p1.getLongitude(), p2.getLatitude(), p2.getLongitude()); } return total; } private void handleFlightDuration(FlightTaskEntity entity, long diffSeconds, Map updateMap) { if (entity.getFlightDuration() == null) { if (entity.getOutboundDate() != null && entity.getInboundDate() != null) { setFlightDuration(entity, entity.getOutboundDate(), entity.getInboundDate()); updateMap.put(entity.getTaskId(), entity); } else if (diffSeconds > 7200) { if (entity.getInboundDate() != null) { setFlightDuration(entity, entity.getCreateDate(), entity.getInboundDate()); updateMap.put(entity.getTaskId(), entity); } else if (entity.getOutboundDate() != null) { setFlightDuration(entity, entity.getOutboundDate(), DateUtils.getBeforeHour(entity.getOutboundDate(), 1)); updateMap.put(entity.getTaskId(), entity); } else { setFlightDuration(entity, entity.getCreateDate(), DateUtils.getBeforeHour(entity.getCreateDate(), 1)); updateMap.put(entity.getTaskId(), entity); } } } } //设置飞行时间 private void setFlightDuration(FlightTaskEntity entity, Date startTime, Date endTime) { HashMap condition = Maps.newHashMap(); condition.put("dockSn", entity.getDockSn()); List flyList = influxService.queryData(DateUtils.format(startTime, DateUtils.DATE_TIME_PATTERN), DateUtils.format(endTime, DateUtils.DATE_TIME_PATTERN), "uav_osd", condition, UavReport.class, "longitude", "latitude", "elevation", "_time"); UavReport start = null; UavReport end = null; for (int i = 0; i < flyList.size() - 1; i++) { //过滤出起飞和降落的记录,当飞机和机场的相对高度大于0,则认为飞机在飞行中,开始计算飞行时长 if (flyList.get(i).getElevation() > 0) { end = flyList.get(i); if (start == null) { start = flyList.get(i); } } } String flightDurationText = "0秒"; long flightDuration = 0L; if (start != null && end != null) { DateTime startDate = DateUtil.parseDateTime(start.getTimeStr()); DateTime endDate = DateUtil.parseDateTime(end.getTimeStr()); flightDurationText = DateUtils.formatDifference(startDate, endDate); flightDuration = Math.abs((endDate.getTime() - startDate.getTime()) / 1000); } entity.setFlightDurationText(flightDurationText); entity.setFlightDuration(flightDuration); } private void handleMediaNum(FlightTaskEntity entity, long diffSeconds, Map updateMap) { if ((entity.getMediaNum() == null || entity.getMediaNum() == 0) && diffSeconds > 7200) { Long count = mediaFileService.getDao().selectCount(new QueryWrapper() .eq("task_id", entity.getTaskId()).eq("dock_sn", entity.getDockSn())); entity.setMediaNum(count.intValue()); updateMap.put(entity.getTaskId(), entity); } } }