From 73e810fc9569597be99accd08d63aab6e7c0daac Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期二, 06 十月 2026 09:36:41 +0800
Subject: [PATCH] fix(holiday): 提高平均拥挤度走势图标签精度
---
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java | 170 ++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 121 insertions(+), 49 deletions(-)
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java
index 8ccd624..2309466 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java
@@ -8,7 +8,9 @@
import com.trafficaudit.holiday.entity.HolidayCalendar;
import com.trafficaudit.holiday.entity.HolidayPassengerFlow;
import com.trafficaudit.holiday.entity.HolidayVehicleFlow;
+import com.trafficaudit.holiday.entity.HolidayVehicleAdjustment;
import com.trafficaudit.holiday.mapper.HolidayPassengerFlowMapper;
+import com.trafficaudit.holiday.mapper.HolidayVehicleAdjustmentMapper;
import com.trafficaudit.holiday.mapper.HolidayVehicleFlowMapper;
import lombok.Data;
import org.springframework.stereotype.Service;
@@ -36,6 +38,8 @@
private HolidayPassengerFlowMapper passengerFlowMapper;
@Resource
private HolidayVehicleFlowMapper vehicleFlowMapper;
+ @Resource
+ private HolidayVehicleAdjustmentMapper vehicleAdjustmentMapper;
@Resource
private ImportBatchMapper importBatchMapper;
@@ -93,37 +97,33 @@
Map<LocalDate, Map<String, BigDecimal>> vehicleByDate = loadVehicleByDate(year);
Map<LocalDate, BigDecimal> comparisonBaseByDate = loadComparisonBaseByDate(year);
BigDecimal coefficient = configService.coefficientOf(year, HolidayConstants.CATEGORY_HOLIDAY);
- List<Map<String, Object>> rows = new ArrayList<>();
- BigDecimal previousNationalProvincial = null;
+ Map<Integer, HolidayCalendar> calendarByDay = new LinkedHashMap<>();
for (HolidayCalendar day : calendar) {
- Map<String, BigDecimal> passenger = passengerByDate.getOrDefault(day.getHolidayDate(), Collections.emptyMap());
- Map<String, BigDecimal> vehicle = vehicleByDate.getOrDefault(day.getHolidayDate(), Collections.emptyMap());
- BigDecimal expressway = vehicle.get(HolidayConstants.ROAD_EXPRESSWAY);
- BigDecimal nationalProvincial = vehicle.get(HolidayConstants.ROAD_NATIONAL_PROVINCIAL);
- BigDecimal comparisonBase = comparisonBaseByDate.get(day.getHolidayDate());
- BigDecimal nationalProvincialRingRatio = nationalProvincialRingRatio(
- year, nationalProvincial, previousNationalProvincial, comparisonBase);
- BigDecimal nonBusinessPersonFlow = null;
- if (coefficient != null && (expressway != null || nationalProvincial != null)) {
- nonBusinessPersonFlow = HolidayNumberUtils.multiply(
- HolidayNumberUtils.sumNullable(expressway, nationalProvincial), coefficient);
- }
+ if (day.getDayIndex() != null) calendarByDay.put(day.getDayIndex(), day);
+ }
+ List<Map<String, Object>> rows = new ArrayList<>();
+ for (HolidayCalendar day : calendar) {
+ DailyMetrics current = buildDailyMetrics(year, holidayType, day.getDayIndex(), day.getHolidayDate(),
+ passengerByDate, vehicleByDate, comparisonBaseByDate, coefficient);
+ DailyMetrics ringRatioBase = ringRatioBaseFromMaps(year, holidayType, day.getDayIndex(), calendarByDay,
+ passengerByDate, vehicleByDate, comparisonBaseByDate, coefficient);
+ BigDecimal nationalProvincialRingRatio = ratio(current.getNationalProvincial(),
+ ringRatioBase == null ? null : ringRatioBase.getNationalProvincial());
Map<String, Object> row = new LinkedHashMap<>();
row.put("dayIndex", day.getDayIndex());
row.put("date", day.getHolidayDate());
- row.put("rail", passenger.get(HolidayConstants.MODE_RAIL));
- row.put("civilAviation", passenger.get(HolidayConstants.MODE_CIVIL_AVIATION));
- row.put("road", passenger.get(HolidayConstants.MODE_ROAD));
- row.put("water", passenger.get(HolidayConstants.MODE_WATER));
- row.put("expressway", expressway);
- row.put("nationalProvincial", nationalProvincial);
- row.put("comparisonBase", comparisonBase);
+ row.put("rail", current.getRail());
+ row.put("civilAviation", current.getCivilAviation());
+ row.put("road", current.getRoad());
+ row.put("water", current.getWater());
+ row.put("expressway", current.getExpressway());
+ row.put("nationalProvincial", current.getNationalProvincial());
+ row.put("comparisonBase", current.getComparisonBase());
row.put("nationalProvincialRingRatio", nationalProvincialRingRatio);
- row.put("coefficient", coefficient);
- row.put("nonBusinessPersonFlow", nonBusinessPersonFlow);
- row.put("totalPersonFlow", totalPersonFlow(passenger, nonBusinessPersonFlow));
+ row.put("coefficient", current.getCoefficient());
+ row.put("nonBusinessPersonFlow", current.getNonBusinessPersonFlow());
+ row.put("totalPersonFlow", current.getTotalPersonFlow());
rows.add(row);
- previousNationalProvincial = nationalProvincial;
}
return rows;
}
@@ -138,27 +138,55 @@
}
}
if (target == null) return null;
+ return dailyMetrics(year, holidayType, dayIndex, target.getHolidayDate());
+ }
+ public DailyMetrics dailyMetricsByDate(LocalDate date) {
+ if (date == null) return null;
+ return dailyMetrics(date.getYear(), null, 0, date);
+ }
+
+ private DailyMetrics dailyMetrics(int year, String holidayType, int dayIndex, LocalDate date) {
Map<LocalDate, Map<String, BigDecimal>> passengerByDate = loadPassengerByDate(year);
Map<LocalDate, Map<String, BigDecimal>> vehicleByDate = loadVehicleByDate(year);
Map<LocalDate, BigDecimal> comparisonBaseByDate = loadComparisonBaseByDate(year);
- Map<String, BigDecimal> passenger = passengerByDate.getOrDefault(target.getHolidayDate(), Collections.emptyMap());
- Map<String, BigDecimal> vehicle = vehicleByDate.getOrDefault(target.getHolidayDate(), Collections.emptyMap());
BigDecimal coefficient = configService.coefficientOf(year, HolidayConstants.CATEGORY_HOLIDAY);
+ return buildDailyMetrics(year, holidayType, dayIndex, date, passengerByDate, vehicleByDate,
+ comparisonBaseByDate, coefficient);
+ }
+
+ public DailyMetrics ringRatioBaseMetrics(int year, String holidayType, int dayIndex) {
+ if (dayIndex <= 1) return null;
+ List<HolidayCalendar> calendar = configService.findHolidayDays(year, holidayType);
+ Map<Integer, HolidayCalendar> calendarByDay = new LinkedHashMap<>();
+ for (HolidayCalendar day : calendar) {
+ if (day.getDayIndex() != null) calendarByDay.put(day.getDayIndex(), day);
+ }
+ Map<LocalDate, Map<String, BigDecimal>> passengerByDate = loadPassengerByDate(year);
+ Map<LocalDate, Map<String, BigDecimal>> vehicleByDate = loadVehicleByDate(year);
+ Map<LocalDate, BigDecimal> comparisonBaseByDate = loadComparisonBaseByDate(year);
+ BigDecimal coefficient = configService.coefficientOf(year, HolidayConstants.CATEGORY_HOLIDAY);
+ return ringRatioBaseFromMaps(year, holidayType, dayIndex, calendarByDay, passengerByDate,
+ vehicleByDate, comparisonBaseByDate, coefficient);
+ }
+
+ private DailyMetrics buildDailyMetrics(int year, String holidayType, int dayIndex, LocalDate date,
+ Map<LocalDate, Map<String, BigDecimal>> passengerByDate,
+ Map<LocalDate, Map<String, BigDecimal>> vehicleByDate,
+ Map<LocalDate, BigDecimal> comparisonBaseByDate,
+ BigDecimal coefficient) {
+ Map<String, BigDecimal> passenger = passengerByDate.getOrDefault(date, Collections.emptyMap());
+ Map<String, BigDecimal> vehicle = vehicleByDate.getOrDefault(date, Collections.emptyMap());
BigDecimal expressway = vehicle.get(HolidayConstants.ROAD_EXPRESSWAY);
BigDecimal nationalProvincial = vehicle.get(HolidayConstants.ROAD_NATIONAL_PROVINCIAL);
- BigDecimal comparisonBase = comparisonBaseByDate.get(target.getHolidayDate());
- BigDecimal nonBusiness = null;
- if (coefficient != null && (expressway != null || nationalProvincial != null)) {
- nonBusiness = HolidayNumberUtils.multiply(
- HolidayNumberUtils.sumNullable(expressway, nationalProvincial), coefficient);
- }
+ BigDecimal comparisonBase = comparisonBaseByDate.get(date);
+ BigDecimal nonBusiness = nonBusinessPersonFlow(expressway, nationalProvincial, coefficient);
DailyMetrics metrics = new DailyMetrics();
metrics.setYear(year);
metrics.setHolidayType(holidayType);
metrics.setDayIndex(dayIndex);
- metrics.setDate(target.getHolidayDate());
+ metrics.setDate(date);
metrics.setRail(passenger.get(HolidayConstants.MODE_RAIL));
metrics.setCivilAviation(passenger.get(HolidayConstants.MODE_CIVIL_AVIATION));
metrics.setRoad(passenger.get(HolidayConstants.MODE_ROAD));
@@ -168,9 +196,43 @@
metrics.setComparisonBase(comparisonBase);
metrics.setCoefficient(coefficient);
metrics.setNonBusinessPersonFlow(nonBusiness);
- metrics.setRoadPersonFlow(sumNullable(metrics.getRoad(), nonBusiness));
- metrics.setTotalPersonFlow(totalPersonFlow(passenger, nonBusiness));
+ recalculateDerived(metrics);
return metrics;
+ }
+
+ private DailyMetrics ringRatioBaseFromMaps(int year, String holidayType, int dayIndex,
+ Map<Integer, HolidayCalendar> calendarByDay,
+ Map<LocalDate, Map<String, BigDecimal>> passengerByDate,
+ Map<LocalDate, Map<String, BigDecimal>> vehicleByDate,
+ Map<LocalDate, BigDecimal> comparisonBaseByDate,
+ BigDecimal coefficient) {
+ if (dayIndex <= 1) return null;
+ HolidayCalendar previous = calendarByDay.get(dayIndex - 1);
+ if (previous == null || previous.getHolidayDate() == null) return null;
+ DailyMetrics base = buildDailyMetrics(year, holidayType, previous.getDayIndex(), previous.getHolidayDate(),
+ passengerByDate, vehicleByDate, comparisonBaseByDate, coefficient);
+ BigDecimal comparisonBase = comparisonBaseByDate.get(previous.getHolidayDate());
+ if (comparisonBase != null) {
+ base.setNationalProvincial(comparisonBase);
+ recalculateDerived(base);
+ }
+ return base;
+ }
+
+ private void recalculateDerived(DailyMetrics metrics) {
+ BigDecimal nonBusiness = nonBusinessPersonFlow(metrics.getExpressway(), metrics.getNationalProvincial(),
+ metrics.getCoefficient());
+ metrics.setNonBusinessPersonFlow(nonBusiness);
+ metrics.setRoadPersonFlow(sumNullable(metrics.getRoad(), nonBusiness));
+ metrics.setTotalPersonFlow(totalPersonFlow(nonBusiness, metrics.getRoad(), metrics.getRail(),
+ metrics.getCivilAviation(), metrics.getWater()));
+ }
+
+ private BigDecimal nonBusinessPersonFlow(BigDecimal expressway, BigDecimal nationalProvincial,
+ BigDecimal coefficient) {
+ if (coefficient == null || (expressway == null && nationalProvincial == null)) return null;
+ return HolidayNumberUtils.multiply(
+ HolidayNumberUtils.sumNullable(expressway, nationalProvincial), coefficient);
}
public DailyMetrics cumulativeMetrics(int year, String holidayType, int dayIndex) {
@@ -220,6 +282,23 @@
result.computeIfAbsent(row.getFlowDate(), key -> new LinkedHashMap<>())
.put(row.getRoadCategory(), row.getVehicleCount());
}
+ Map<LocalDate, BigDecimal> adjustments = loadNationalProvincialAdjustmentsByDate(year);
+ for (Map.Entry<LocalDate, BigDecimal> entry : adjustments.entrySet()) {
+ result.computeIfAbsent(entry.getKey(), key -> new LinkedHashMap<>())
+ .put(HolidayConstants.ROAD_NATIONAL_PROVINCIAL, entry.getValue());
+ }
+ return result;
+ }
+
+ private Map<LocalDate, BigDecimal> loadNationalProvincialAdjustmentsByDate(int year) {
+ Map<LocalDate, BigDecimal> result = new LinkedHashMap<>();
+ List<HolidayVehicleAdjustment> rows = vehicleAdjustmentMapper.selectList(
+ new LambdaQueryWrapper<HolidayVehicleAdjustment>().eq(HolidayVehicleAdjustment::getYear, year));
+ for (HolidayVehicleAdjustment row : rows) {
+ if (row.getFlowDate() != null && row.getAdjustedValue() != null) {
+ result.put(row.getFlowDate(), row.getAdjustedValue());
+ }
+ }
return result;
}
@@ -235,23 +314,16 @@
return result;
}
- private BigDecimal totalPersonFlow(Map<String, BigDecimal> passenger, BigDecimal nonBusinessPersonFlow) {
+ private BigDecimal totalPersonFlow(BigDecimal nonBusinessPersonFlow, BigDecimal road, BigDecimal rail,
+ BigDecimal civilAviation, BigDecimal water) {
BigDecimal total = nonBusinessPersonFlow;
- total = sumNullable(total, passenger.get(HolidayConstants.MODE_ROAD));
- total = sumNullable(total, passenger.get(HolidayConstants.MODE_RAIL));
- total = sumNullable(total, passenger.get(HolidayConstants.MODE_CIVIL_AVIATION));
- total = sumNullable(total, passenger.get(HolidayConstants.MODE_WATER));
+ total = sumNullable(total, road);
+ total = sumNullable(total, rail);
+ total = sumNullable(total, civilAviation);
+ total = sumNullable(total, water);
return total;
}
- private BigDecimal nationalProvincialRingRatio(int year, BigDecimal current,
- BigDecimal previous, BigDecimal comparisonBase) {
- if (current == null) return null;
- if (HolidayConstants.supportsComparisonBase(year) && comparisonBase != null) {
- return ratio(current, comparisonBase);
- }
- return previous == null ? null : ratio(current, previous);
- }
private BigDecimal ratio(BigDecimal current, BigDecimal base) {
BigDecimal quotient = HolidayNumberUtils.divide(current, base);
--
Gitblit v1.9.1