| | |
| | | import java.math.RoundingMode; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.ArrayList; |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | import java.util.HashSet; |
| | |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | |
| | | calendar.add(Calendar.DAY_OF_MONTH, 1); |
| | | Date dayEnd = calendar.getTime(); |
| | | |
| | | |
| | | String dayStartStr=DateUtils.formatDate(dayStart, DateUtils.YYYY_MM_DD_HH_MM_SS); |
| | | String dayEndStr=DateUtils.formatDate(dayEnd, DateUtils.YYYY_MM_DD_HH_MM_SS); |
| | | // 2. 查询车辆在该日期的GPS数据(按时间排序) |
| | | List<VehicleGps> gpsList = vehicleGpsMapper.selectGpsDataByTimeRange(vehicleId, dayStart, dayEnd); |
| | | List<VehicleGps> gpsList = vehicleGpsMapper.selectGpsDataByTimeRange(vehicleId, dayStartStr, dayEndStr); |
| | | |
| | | if (gpsList == null || gpsList.isEmpty()) { |
| | | // logger.info("车辆ID: {} 在日期: {} 无GPS数据", vehicleId, statDate); |
| | | logger.info("---> 车辆ID:{} 在日期:{} 无GPS数据", vehicleId, statDate); |
| | | return null; |
| | | } |
| | | // logger.info("车辆ID:{} GPS数据条数:{}", vehicleId, gpsList.size()); |
| | | // logger.info("---> 车辆ID:{} GPS数据条数:{}", vehicleId, gpsList.size()); |
| | | // 3. 查询车辆在该日期的任务时间区间 |
| | | List<TaskTimeInterval> taskIntervals = vehicleMileageStatsMapper.selectTaskTimeIntervals(vehicleId, dayStart, dayEnd); |
| | | // logger.info("---> 车辆ID:{} 任务时间区间数:{}", vehicleId, taskIntervals.size()); |
| | | |
| | | List<VehicleGpsSegmentMileage> mileages = this.getTaskDistanceMileage(vehicleId, dayStart, dayEnd).stream().filter(e -> e.getSegmentDistance() != null && e.getSegmentDistance().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList()); |
| | | |
| | | List<VehicleGpsSegmentMileage> mileages = this.getTaskDistanceMileage(vehicleId, dayStart, dayEnd); |
| | | int totalGpsPoints = mileages.stream() |
| | | .filter(segment -> segment.getGpsPointCount() != null) |
| | | .mapToInt(VehicleGpsSegmentMileage::getGpsPointCount) |
| | | .sum(); |
| | | // logger.info("---> 车辆ID:{} 任务时间:{} 里程时间:{}", vehicleId, |
| | | // taskIntervals.stream().map(e->"开始时间:"+DateUtils.formatDate(e.getStartTime())+",结束时间:"+DateUtils.formatDate(e.getEndTime())).collect(Collectors.joining()), |
| | | // mileages.stream().map(e->"开始时间:"+DateUtils.formatDate(e.getSegmentStartTime())+",结束时间:"+DateUtils.formatDate(e.getSegmentEndTime())).collect(Collectors.joining())); |
| | | BigDecimal taskDistance = getTaskDistance(taskIntervals,mileages); |
| | | |
| | | // logger.info("---> 车辆ID:{} 任务总里程:{}", vehicleId, taskDistance); |
| | | MileageCalculation calculation = calculateMileage(gpsList, taskDistance); |
| | | // logger.info("计算出车辆当天总里程,车辆ID:{},总里程:{},任务里程:{}",vehicleId,calculation.totalMileage,calculation.taskMileage); |
| | | // logger.info("---> 计算出车辆当天总里程,车辆ID:{},总里程:{},任务里程:{}",vehicleId,calculation.totalMileage,calculation.taskMileage); |
| | | // 5. 查询或创建统计记录 |
| | | VehicleMileageStats stats = vehicleMileageStatsMapper.selectByVehicleIdAndDate(vehicleId, statDate); |
| | | boolean isNew = (stats == null); |
| | |
| | | stats.setTaskMileage(calculation.taskMileage); |
| | | stats.setNonTaskMileage(calculation.nonTaskMileage); |
| | | stats.setTaskRatio(calculation.taskRatio); |
| | | stats.setGpsPointCount(gpsList.size()); |
| | | stats.setGpsPointCount(totalGpsPoints); |
| | | stats.setTaskCount(taskIntervals == null ? 0 : taskIntervals.size()); |
| | | |
| | | // logger.info("车辆ID: {} 日期: {} 里程统计完成 - 总里程: {}km, 任务里程: {}km, 非任务里程: {}km, 占比: {}", |
| | |
| | | } else { |
| | | vehicleMileageStatsMapper.updateVehicleMileageStats(stats); |
| | | } |
| | | |
| | | logger.info("车辆ID: {} 日期: {} 里程统计完成 - 总里程: {}km, 任务里程: {}km, 非任务里程: {}km, 占比: {}", |
| | | vehicleId, statDate, calculation.totalMileage, calculation.taskMileage, |
| | | calculation.nonTaskMileage, calculation.taskRatio); |
| | | |
| | | |
| | | // if (taskIntervals != null) { |
| | | // logger.info("---> 同步里程完成,车辆ID: {} 日期: {} 里程统计完成 - 总里程: {}km,任务数量:{} 任务里程: {}km, 非任务里程: {}km, 占比: {}", |
| | | // vehicleId, statDate, calculation.totalMileage,taskIntervals.size(), calculation.taskMileage, |
| | | // calculation.nonTaskMileage, calculation.taskRatio); |
| | | // } |
| | | |
| | | return stats; |
| | | |
| | | } catch (Exception e) { |
| | | logger.error("计算车辆里程统计失败 - 车辆ID: {}, 日期: {}", vehicleId, statDate, e); |
| | | logger.error("---> 计算车辆里程统计失败 - 车辆ID: {}, 日期: {}", vehicleId, statDate, e); |
| | | throw new RuntimeException("计算里程统计失败: " + e.getMessage()); |
| | | } |
| | | } |
| | |
| | | calendar.setTime(statDate); |
| | | calendar.add(Calendar.DAY_OF_MONTH, -7); |
| | | Date startTime = calendar.getTime(); |
| | | |
| | | 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("没有找到活跃车辆"); |
| | |
| | | } |
| | | } |
| | | |
| | | logger.info("批量里程统计完成 - 日期: {}, 总车辆数: {}, 成功: {}", statDate, vehicleIds.size(), successCount); |
| | | // logger.info("批量里程统计完成 - 日期: {}, 总车辆数: {}, 成功: {}", statDate, vehicleIds.size(), successCount); |
| | | return successCount; |
| | | |
| | | } catch (Exception e) { |
| | |
| | | |
| | | |
| | | private BigDecimal calculateTotalMileage(List<VehicleGpsSegmentMileage> mileages) { |
| | | if (mileages == null || mileages.isEmpty()) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | |
| | | return mileages.stream() |
| | | .filter(mileage -> mileage.getSegmentDistance() != null) // 过滤掉距离为null的分段 |
| | | .map(mileage -> mileage.getSegmentDistance()) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | |
| | |
| | | |
| | | //计算任务时间段内的里程,应该拿到该任务在工作时间段里的分段距离然后相加 |
| | | private List<VehicleGpsSegmentMileage> getTaskDistanceMileage(Long vehicleId, Date segmentStart, Date segmentEnd) { |
| | | return segmentMileageMapper.selectSegmentsByDateRange(vehicleId, segmentStart, segmentEnd); |
| | | List<VehicleGpsSegmentMileage> mileages = segmentMileageMapper.selectSegmentsByDateRange(vehicleId, segmentStart, segmentEnd); |
| | | return mileages != null ? mileages : new ArrayList<>(); |
| | | } |
| | | |
| | | /** |
| | |
| | | // 遍历所有分段里程数据 |
| | | for (VehicleGpsSegmentMileage segment : segmentMileages) { |
| | | // 只处理有关联任务ID且有距离数据的分段 |
| | | |
| | | // if (segment.getTaskId() == null || segment.getSegmentDistance() == null) { |
| | | // continue; |
| | | // } |
| | | |
| | | // 检查该分段是否与任何任务时间段重叠 |
| | | Date segmentStart = segment.getSegmentStartTime(); |
| | |
| | | @Override |
| | | public VehicleMileageStats aggregateFromSegmentMileage(Long vehicleId, Date statDate) { |
| | | try { |
| | | calculateAndSaveMileageStats(vehicleId, statDate); |
| | | //TODO |
| | | // 1. 获取统计日期的开始和结束时间 |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(statDate); |
| | |
| | | } |
| | | |
| | | List<TaskTimeInterval> taskIntervals = vehicleMileageStatsMapper.selectTaskTimeIntervals(vehicleId, dayStart, dayEnd); |
| | | Integer taskCount = taskIntervals.size(); |
| | | |
| | | |
| | | List<VehicleGpsSegmentMileage> mileages = this.getTaskDistanceMileage(vehicleId, dayStart, dayEnd); |
| | | Integer totalGpsPoints = mileages.stream() |
| | | Integer taskCount = taskIntervals != null ? taskIntervals.size() : 0; |
| | | logger.info("车辆ID: {} 在日期: {} 有 {} 个任务", vehicleId, statDate, taskCount); |
| | | List<VehicleGpsSegmentMileage> mileages = this.getTaskDistanceMileage(vehicleId, dayStart, dayEnd).stream().filter(e -> e.getSegmentDistance() != null && e.getSegmentDistance().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList()); |
| | | logger.info("车辆ID: {} 在日期: {} 有 {} 个分段里程数据", vehicleId, statDate, mileages.size()); |
| | | Integer totalGpsPoints = mileages != null ? mileages.stream() |
| | | .filter(segment -> segment.getGpsPointCount() != null) |
| | | .mapToInt(VehicleGpsSegmentMileage::getGpsPointCount) |
| | | .sum(); |
| | | BigDecimal taskDistance = getTaskDistance(taskIntervals,mileages); |
| | | .sum() : 0; |
| | | BigDecimal taskDistance = getTaskDistance(taskIntervals, mileages); |
| | | BigDecimal totalDistance = calculateTotalMileage(segments); |
| | | BigDecimal nonTaskDistance = totalDistance.subtract(taskDistance); |
| | | BigDecimal taskRatio = taskDistance.divide(totalDistance, 4, RoundingMode.HALF_UP); |
| | | |
| | | // 防止除零错误 |
| | | BigDecimal taskRatio = BigDecimal.ZERO; |
| | | if (totalDistance != null && totalDistance.compareTo(BigDecimal.ZERO) > 0) { |
| | | taskRatio = taskDistance.divide(totalDistance, 4, RoundingMode.HALF_UP); |
| | | } |
| | | // 3. 汇总里程数据 |
| | | |
| | | |
| | |
| | | calendar.setTime(statDate); |
| | | calendar.add(Calendar.DAY_OF_MONTH, -7); |
| | | Date startTime = calendar.getTime(); |
| | | |
| | | 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("没有找到活跃车辆"); |