| | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.*; |
| | | |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | public int batchCalculateSegmentMileage(Date startTime, Date endTime) { |
| | | try { |
| | | // logger.info("开始批量计算GPS分段里程 - 时间范围: {} 到 {}", startTime, endTime); |
| | | |
| | | String startTimeStr = DateUtils.formatDate(startTime,DateUtils.YYYY_MM_DD_HH_MM_SS); |
| | | String endTimeStr = DateUtils.formatDate(endTime,DateUtils.YYYY_MM_DD_HH_MM_SS); |
| | | // 查询在指定时间范围内有GPS数据的所有车辆(添加慢SQL监控) |
| | | long startQueryTime = System.currentTimeMillis(); |
| | | List<Long> vehicleIds = vehicleGpsMapper.selectActiveVehicleIds(startTime); |
| | | List<Long> vehicleIds = vehicleGpsMapper.selectActiveVehicleIds(startTimeStr); |
| | | long queryTime = System.currentTimeMillis() - startQueryTime; |
| | | |
| | | // 慢查询警告(超过1秒) |
| | |
| | | Date startTime = cal.getTime(); |
| | | |
| | | logger.info("开始补偿计算 - 回溯天数: {}, 时间范围: {} 到 {}", lookbackDays, startTime, endTime); |
| | | |
| | | |
| | | String startTimeStr=DateUtils.formatDate(startTime, DateUtils.YYYY_MM_DD_HH_MM_SS); |
| | | // 查询所有活跃车辆 |
| | | List<Long> vehicleIds = vehicleGpsMapper.selectActiveVehicleIds(startTime); |
| | | List<Long> vehicleIds = vehicleGpsMapper.selectActiveVehicleIds(startTimeStr); |
| | | |
| | | if (vehicleIds == null || vehicleIds.isEmpty()) { |
| | | logger.info("没有找到活跃车辆"); |
| | |
| | | |
| | | int successCount = 0; |
| | | int totalUncalculated = 0; |
| | | |
| | | |
| | | |
| | | String endTimeStr=DateUtils.formatDate(endTime, DateUtils.YYYY_MM_DD_HH_MM_SS); |
| | | for (Long vehicleId : vehicleIds) { |
| | | try { |
| | | // 查询该车辆未被计算的GPS数据 |
| | | List<VehicleGps> uncalculatedGps = vehicleGpsMapper.selectUncalculatedGps(vehicleId, startTime, endTime); |
| | | List<VehicleGps> uncalculatedGps = vehicleGpsMapper.selectUncalculatedGps(vehicleId, startTimeStr, endTimeStr); |
| | | |
| | | if (uncalculatedGps == null || uncalculatedGps.isEmpty()) { |
| | | logger.debug("车辆 {} 没有未计算的GPS数据", vehicleId); |
| | |
| | | public int calculateVehicleSegmentMileage(Long vehicleId, Date startTime, Date endTime) { |
| | | try { |
| | | // 查询车辆在时间范围内的GPS数据 |
| | | List<VehicleGps> gpsList = vehicleGpsMapper.selectGpsDataByTimeRange(vehicleId, startTime, endTime); |
| | | String startTimeStr=DateUtils.formatDate(startTime, DateUtils.YYYY_MM_DD_HH_MM_SS); |
| | | String endTimeStr=DateUtils.formatDate(endTime, DateUtils.YYYY_MM_DD_HH_MM_SS); |
| | | List<VehicleGps> gpsList = vehicleGpsMapper.selectGpsDataByTimeRange(vehicleId, startTimeStr, endTimeStr); |
| | | |
| | | if (gpsList == null || gpsList.isEmpty()) { |
| | | logger.debug("车辆ID: {} 在时间范围 {} 到 {} 内无GPS数据", vehicleId, startTime, endTime); |
| | | return 0; |
| | | } |
| | | |
| | | logger.info("车辆ID: {} 查询到 {} 条GPS数据 startTime:{},endTime:{}", vehicleId, gpsList.size(),startTime,endTime); |
| | | // logger.info("车辆ID: {} 查询到 {} 条GPS数据 startTime:{},endTime:{}", vehicleId, gpsList.size(),startTime,endTime); |
| | | |
| | | return calculateVehicleSegmentMileageWithGpsList(vehicleId, gpsList, startTime, endTime); |
| | | |
| | |
| | | // 处理每个时间段并计算里程 |
| | | int savedCount = processSegmentedGpsData(vehicleId, segmentedData, config); |
| | | |
| | | logger.info("车辆 {} 计算完成,保存了 {} 个时间段的里程数据", vehicleId, savedCount); |
| | | // logger.info("车辆 {} 计算完成,保存了 {} 个时间段的里程数据", vehicleId, savedCount); |
| | | |
| | | // 自动触发每日统计汇总 |
| | | if (savedCount > 0) { |
| | |
| | | // 获取是否跳过已计算GPS点的配置 |
| | | String skipCalculatedConfig = configService.selectConfigByKey("gps.mileage.skip.calculated"); |
| | | config.skipCalculated = skipCalculatedConfig == null || "true".equalsIgnoreCase(skipCalculatedConfig); |
| | | logger.info("控制跳过重复计算标识: {}", config.skipCalculated); |
| | | // logger.info("控制跳过重复计算标识: {}", config.skipCalculated); |
| | | |
| | | return config; |
| | | } |
| | |
| | | |
| | | // 如果本段只有1个点,且没有上一段的最后一个点,无法计算距离 |
| | | if (segmentGpsList.size() == 1 && previousSegmentLastPoint == null) { |
| | | logger.debug("车辆 {} 时间段 {} 只有1个GPS点且无前置点,暂存待下一段计算", vehicleId, segmentStartTime); |
| | | // logger.debug("车辆 {} 时间段 {} 只有1个GPS点且无前置点,暂存待下一段计算", vehicleId, segmentStartTime); |
| | | return false; |
| | | } |
| | | |
| | |
| | | String gpsIds = gpsIdList.stream() |
| | | .map(String::valueOf) |
| | | .collect(java.util.stream.Collectors.joining(",")); |
| | | |
| | | |
| | | // 创建分段里程记录 |
| | | VehicleGpsSegmentMileage segment = buildSegmentMileageRecord( |
| | | vehicleId, segmentStartTime, segmentEndTime, segmentGpsList, |
| | | distance, gpsIdList, gpsIds, config.calculateMethod); |
| | | |
| | | // 保存到数据库 |
| | | logger.info("保存车辆分时段里程到数据库中,车辆ID: {}, 时间段: {} 到 {}", vehicleId, segmentStartTime, segmentEndTime); |
| | | // logger.info("保存车辆分时段里程到数据库中,车辆ID: {}, 时间段: {} 到 {}", vehicleId, segmentStartTime, segmentEndTime); |
| | | segmentMileageMapper.insertVehicleGpsSegmentMileage(segment); |
| | | |
| | | // 记录已计算的GPS点(如果开启了重复计算控制) |
| | |
| | | recordCalculatedGpsPoints(gpsIdList, segment.getSegmentId(), vehicleId); |
| | | } |
| | | |
| | | logger.debug("车辆 {} 时间段 {} 到 {} 里程: {}km, GPS点数: {}, GPS IDs: {}", |
| | | vehicleId, segmentStartTime, segmentEndTime, distance, segmentGpsList.size(), |
| | | gpsIds.length() > 50 ? gpsIds.substring(0, 50) + "..." : gpsIds); |
| | | // logger.debug("车辆 {} 时间段 {} 到 {} 里程: {}km, GPS点数: {}, GPS IDs: {}", |
| | | // vehicleId, segmentStartTime, segmentEndTime, distance, segmentGpsList.size(), |
| | | // gpsIds.length() > 50 ? gpsIds.substring(0, 50) + "..." : gpsIds); |
| | | |
| | | return true; |
| | | |
| | |
| | | for (Date statDate : affectedDates) { |
| | | try { |
| | | mileageStatsService.aggregateFromSegmentMileage(vehicleId, statDate); |
| | | logger.info("车辆 {} 日期 {} 的统计数据已自动汇总生成", vehicleId, statDate); |
| | | // logger.info("车辆 {} 日期 {} 的统计数据已自动汇总生成", vehicleId, statDate); |
| | | } catch (Exception e) { |
| | | logger.error("车辆 {} 日期 {} 自动汇总统计失败", vehicleId, statDate, e); |
| | | } |
| | |
| | | ); |
| | | totalDistance = totalDistance.add(BigDecimal.valueOf(gapDistance)); |
| | | |
| | | logger.debug("跨段间隙距离: {}km (上一段末点 -> 当前段首点)", |
| | | String.format("%.3f", gapDistance)); |
| | | // logger.debug("跨段间隙距离: {}km (上一段末点 -> 当前段首点)", |
| | | // String.format("%.3f", gapDistance)); |
| | | } |
| | | |
| | | // 2. 再计算当前段内部的距离(如果有2个或以上GPS点) |
| | |
| | | Date segmentStartTime, Date segmentEndTime) { |
| | | try { |
| | | // 查询该车辆正在执行的任务列表 |
| | | List<SysTask> activeTasks = sysTaskMapper.selectTaskByVehicleIdAndDate(vehicleId,segmentStartTime,segmentEndTime); |
| | | String segmentStartTimeStr = DateUtils.formatDate(segmentStartTime, "yyyy-MM-dd HH:mm:ss"); |
| | | String segmentEndTimeStr = DateUtils.formatDate(segmentEndTime, "yyyy-MM-dd HH:mm:ss"); |
| | | List<SysTask> activeTasks = sysTaskMapper.selectTaskByVehicleIdAndDate(vehicleId,segmentStartTimeStr,segmentEndTimeStr); |
| | | |
| | | if (activeTasks == null || activeTasks.isEmpty()) { |
| | | logger.debug("车辆 {} 在时间段 {} - {} 没有正在执行的任务", vehicleId, segmentStartTime, segmentEndTime); |
| | | logger.info("车辆 {} 在时间段 {} - {} 没有正在执行的任务", vehicleId, segmentStartTime, segmentEndTime); |
| | | return; |
| | | } |
| | | |
| | |
| | | segment.setTaskId(task.getTaskId()); |
| | | segment.setTaskCode(task.getTaskCode()); |
| | | |
| | | logger.debug("车辆 {} 时间段 {} - {} 关联任务: taskId={}, taskCode={}", |
| | | vehicleId, segmentStartTime, segmentEndTime, task.getTaskId(), task.getTaskCode()); |
| | | // logger.debug("车辆 {} 时间段 {} - {} 关联任务: taskId={}, taskCode={}", |
| | | // vehicleId, segmentStartTime, segmentEndTime, task.getTaskId(), task.getTaskCode()); |
| | | break; // 找到一个匹配的任务即可 |
| | | } |
| | | } |