From 4f2925f1974844b66225ac70ae35065b8262b315 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期四, 04 十二月 2025 13:26:11 +0800
Subject: [PATCH] feat:增加微信token缓存
---
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java | 285 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 280 insertions(+), 5 deletions(-)
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java
index 4bd7aa3..f795378 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java
@@ -2,18 +2,26 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.VehicleGps;
import com.ruoyi.system.domain.VehicleMileageStats;
+import com.ruoyi.system.domain.VehicleGpsSegmentMileage;
import com.ruoyi.system.domain.TaskTimeInterval;
+import com.ruoyi.system.domain.VehicleInfo;
import com.ruoyi.system.mapper.VehicleGpsMapper;
import com.ruoyi.system.mapper.VehicleMileageStatsMapper;
+import com.ruoyi.system.mapper.VehicleGpsSegmentMileageMapper;
+import com.ruoyi.system.mapper.VehicleInfoMapper;
import com.ruoyi.system.service.IVehicleMileageStatsService;
/**
@@ -32,6 +40,12 @@
@Autowired
private VehicleGpsMapper vehicleGpsMapper;
+
+ @Autowired
+ private VehicleGpsSegmentMileageMapper segmentMileageMapper;
+
+ @Autowired
+ private VehicleInfoMapper vehicleInfoMapper;
/**
* 鏌ヨ杞﹁締閲岀▼缁熻
@@ -122,10 +136,18 @@
stats.setVehicleId(vehicleId);
stats.setStatDate(statDate);
- // 鑾峰彇杞︾墝鍙�
+ // 鑾峰彇杞︾墝鍙凤細浼樺厛浠嶨PS鏁版嵁锛屽鏋滄病鏈夊垯浠庤溅杈嗚〃鏌ヨ
+ String vehicleNo = null;
if (!gpsList.isEmpty() && gpsList.get(0).getVehicleNo() != null) {
- stats.setVehicleNo(gpsList.get(0).getVehicleNo());
+ vehicleNo = gpsList.get(0).getVehicleNo();
}
+ if (vehicleNo == null || vehicleNo.trim().isEmpty()) {
+ VehicleInfo vehicleInfo = vehicleInfoMapper.selectVehicleInfoById(vehicleId);
+ if (vehicleInfo != null) {
+ vehicleNo = vehicleInfo.getVehicleNo();
+ }
+ }
+ stats.setVehicleNo(vehicleNo);
}
// 6. 璁剧疆缁熻鏁版嵁
@@ -161,8 +183,14 @@
@Override
public int batchCalculateMileageStats(Date statDate) {
try {
+ // 璁$畻鏌ヨ寮�濮嬫椂闂达紙7澶╁墠锛�
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(statDate);
+ calendar.add(Calendar.DAY_OF_MONTH, -7);
+ Date startTime = calendar.getTime();
+
// 鏌ヨ鎵�鏈夋椿璺冭溅杈�
- List<Long> vehicleIds = vehicleGpsMapper.selectActiveVehicleIds();
+ List<Long> vehicleIds = vehicleGpsMapper.selectActiveVehicleIds(startTime);
if (vehicleIds == null || vehicleIds.isEmpty()) {
logger.info("娌℃湁鎵惧埌娲昏穬杞﹁締");
@@ -208,8 +236,8 @@
);
// 鑾峰彇杩欐璺濈鐨勬椂闂村尯闂�
- Date segmentStart = p1.getCollectTime();
- Date segmentEnd = p2.getCollectTime();
+ Date segmentStart = parseDateTime(p1.getCollectTime());
+ Date segmentEnd = parseDateTime(p2.getCollectTime());
// 璁$畻杩欐璺濈鍦ㄤ换鍔℃椂娈电殑鍗犳瘮
double taskRatio = calculateTaskOverlapRatio(segmentStart, segmentEnd, taskIntervals);
@@ -226,6 +254,16 @@
// 璁$畻浠诲姟閲岀▼鍗犳瘮
if (result.totalMileage.compareTo(BigDecimal.ZERO) > 0) {
result.taskRatio = result.taskMileage.divide(result.totalMileage, 4, RoundingMode.HALF_UP);
+
+ // 鏁版嵁鏍¢獙:鍗犳瘮搴斿湪0-1涔嬮棿
+ if (result.taskRatio.compareTo(BigDecimal.ONE) > 0) {
+ logger.warn("浠诲姟閲岀▼鍗犳瘮寮傚父: {} (浠诲姟閲岀▼:{}, 鎬婚噷绋�:{}), 寮哄埗璁句负1.0",
+ result.taskRatio, result.taskMileage, result.totalMileage);
+ result.taskRatio = BigDecimal.ONE;
+ } else if (result.taskRatio.compareTo(BigDecimal.ZERO) < 0) {
+ logger.warn("浠诲姟閲岀▼鍗犳瘮涓鸿礋: {}, 寮哄埗璁句负0", result.taskRatio);
+ result.taskRatio = BigDecimal.ZERO;
+ }
}
// 淇濈暀涓や綅灏忔暟
@@ -240,6 +278,11 @@
* 浣跨敤Haversine鍏紡璁$畻涓や釜GPS鍧愭爣涔嬮棿鐨勮窛绂伙紙鍏噷锛�
*/
private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
+ // 濡傛灉璧风偣鍜岀粓鐐圭粡绾害鐩稿悓锛岀洿鎺ヨ繑鍥�0锛岄伩鍏嶄笉蹇呰鐨勮绠�
+ if (lat1 == lat2 && lon1 == lon2) {
+ return 0.0;
+ }
+
// 灏嗚搴﹁浆鎹负寮у害
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
@@ -293,4 +336,236 @@
BigDecimal nonTaskMileage = BigDecimal.ZERO;
BigDecimal taskRatio = BigDecimal.ZERO;
}
+
+ /**
+ * 瑙f瀽鏃ユ湡鏃堕棿瀛楃涓�
+ *
+ * @param dateTimeStr 鏃ユ湡鏃堕棿瀛楃涓诧紝鏍煎紡锛歽yyy-MM-dd HH:mm:ss
+ * @return Date瀵硅薄
+ * @throws RuntimeException 濡傛灉瑙f瀽澶辫触
+ */
+ private Date parseDateTime(String dateTimeStr) {
+ if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
+ throw new RuntimeException("鏃ユ湡鏃堕棿瀛楃涓蹭笉鑳戒负绌�");
+ }
+
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ sdf.setLenient(false);
+ return sdf.parse(dateTimeStr.trim());
+ } catch (ParseException e) {
+ throw new RuntimeException("鏃ユ湡鏃堕棿鏍煎紡閿欒: " + dateTimeStr + ", 搴斾负 yyyy-MM-dd HH:mm:ss", e);
+ }
+ }
+
+ /**
+ * 浠庡垎娈甸噷绋嬫暟鎹眹鎬荤敓鎴愭寜鏃ョ粺璁�
+ */
+ @Override
+ public VehicleMileageStats aggregateFromSegmentMileage(Long vehicleId, Date statDate) {
+ try {
+ // 1. 鑾峰彇缁熻鏃ユ湡鐨勫紑濮嬪拰缁撴潫鏃堕棿
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(statDate);
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ Date dayStart = calendar.getTime();
+
+ calendar.add(Calendar.DAY_OF_MONTH, 1);
+ Date dayEnd = calendar.getTime();
+
+ // 2. 鏌ヨ璇ユ棩鏈熻寖鍥村唴鐨勬墍鏈夊垎娈甸噷绋嬫暟鎹�
+ List<VehicleGpsSegmentMileage> segments = segmentMileageMapper.selectSegmentsByDateRange(vehicleId, dayStart, dayEnd);
+
+ if (segments == null || segments.isEmpty()) {
+ logger.info("杞﹁締ID: {} 鍦ㄦ棩鏈�: {} 鏃犲垎娈甸噷绋嬫暟鎹�", vehicleId, statDate);
+ return null;
+ }
+
+ // 3. 姹囨�婚噷绋嬫暟鎹�
+ BigDecimal totalMileage = BigDecimal.ZERO;
+ int totalGpsPoints = 0;
+
+ for (VehicleGpsSegmentMileage segment : segments) {
+ if (segment.getSegmentDistance() != null) {
+ totalMileage = totalMileage.add(segment.getSegmentDistance());
+ }
+ if (segment.getGpsPointCount() != null) {
+ totalGpsPoints += segment.getGpsPointCount();
+ }
+ }
+
+ // 4. 璁$畻浠诲姟閲岀▼鍜岄潪浠诲姟閲岀▼锛堜紭鍖栵細浼樺厛浣跨敤task_id鐩存帴鑱氬悎锛�
+ BigDecimal taskMileage = BigDecimal.ZERO;
+ BigDecimal nonTaskMileage = BigDecimal.ZERO;
+ int taskCount = 0; // 浠诲姟鏁伴噺
+
+ // 4.1 缁熻鏈塼ask_id鐨勫垎娈垫暟閲�
+ int segmentsWithTask = 0;
+ for (VehicleGpsSegmentMileage segment : segments) {
+ if (segment.getTaskId() != null) {
+ segmentsWithTask++;
+ }
+ }
+
+ // 4.2 濡傛灉澶ч儴鍒嗗垎娈甸兘鏈塼ask_id锛屼娇鐢ㄤ紭鍖栨柟妗堬紙鐩存帴鎸塼ask_id鑱氬悎锛�
+ if (segmentsWithTask > segments.size() * 0.8) {
+ logger.debug("杞﹁締ID: {} 鏃ユ湡: {} 浣跨敤浼樺寲鏂规锛氱洿鎺ユ寜task_id鑱氬悎锛坽}涓垎娈垫湁task_id锛屽崰姣攞}%锛�",
+ vehicleId, statDate, segmentsWithTask, (segmentsWithTask * 100.0 / segments.size()));
+
+ // 浣跨敤Set缁熻鍘婚噸鐨勪换鍔D鏁伴噺
+ Set<Long> uniqueTaskIds = new HashSet<>();
+
+ // 鐩存帴鎸塼ask_id鍒嗙粍鑱氬悎
+ for (VehicleGpsSegmentMileage segment : segments) {
+ BigDecimal segDistance = segment.getSegmentDistance() != null ? segment.getSegmentDistance() : BigDecimal.ZERO;
+
+ if (segment.getTaskId() != null) {
+ // 鏈変换鍔D锛岃鍏ヤ换鍔¢噷绋�
+ taskMileage = taskMileage.add(segDistance);
+ uniqueTaskIds.add(segment.getTaskId());
+ } else {
+ // 娌℃湁浠诲姟ID锛岃鍏ラ潪浠诲姟閲岀▼
+ nonTaskMileage = nonTaskMileage.add(segDistance);
+ }
+ }
+
+ // 璁剧疆鍘婚噸鍚庣殑浠诲姟鏁伴噺
+ taskCount = uniqueTaskIds.size();
+
+ } else {
+ // 4.3 闄嶇骇鏂规锛氫娇鐢ㄥ師鏈夌殑鏃堕棿閲嶅彔璁$畻鏂瑰紡
+ logger.debug("杞﹁締ID: {} 鏃ユ湡: {} 浣跨敤闄嶇骇鏂规锛氭椂闂撮噸鍙犺绠楋紙鍙湁{}涓垎娈垫湁task_id锛屽崰姣攞}%锛�",
+ vehicleId, statDate, segmentsWithTask, (segmentsWithTask * 100.0 / segments.size()));
+
+ List<TaskTimeInterval> taskIntervals = vehicleMileageStatsMapper.selectTaskTimeIntervals(vehicleId, dayStart, dayEnd);
+
+ for (VehicleGpsSegmentMileage segment : segments) {
+ Date segStart = segment.getSegmentStartTime();
+ Date segEnd = segment.getSegmentEndTime();
+ BigDecimal segDistance = segment.getSegmentDistance() != null ? segment.getSegmentDistance() : BigDecimal.ZERO;
+
+ // 璁$畻璇ュ垎娈典笌浠诲姟鏃舵鐨勯噸鍙犳瘮渚�
+ double taskRatio = calculateTaskOverlapRatio(segStart, segEnd, taskIntervals);
+
+ // 鍒嗘憡閲岀▼
+ BigDecimal taskDist = segDistance.multiply(BigDecimal.valueOf(taskRatio));
+ BigDecimal nonTaskDist = segDistance.multiply(BigDecimal.valueOf(1 - taskRatio));
+
+ taskMileage = taskMileage.add(taskDist);
+ nonTaskMileage = nonTaskMileage.add(nonTaskDist);
+ }
+
+ // 璁剧疆浠诲姟鏁伴噺
+ taskCount = taskIntervals == null ? 0 : taskIntervals.size();
+ }
+
+ // 璁$畻浠诲姟閲岀▼鍗犳瘮
+ BigDecimal taskRatio = BigDecimal.ZERO;
+ if (totalMileage.compareTo(BigDecimal.ZERO) > 0) {
+ taskRatio = taskMileage.divide(totalMileage, 4, RoundingMode.HALF_UP);
+
+ // 鏁版嵁鏍¢獙:鍗犳瘮搴斿湪0-1涔嬮棿,濡傛灉瓒呭嚭璇存槑鏁版嵁寮傚父
+ if (taskRatio.compareTo(BigDecimal.ONE) > 0) {
+ logger.warn("杞﹁締ID: {} 鏃ユ湡: {} 浠诲姟閲岀▼鍗犳瘮寮傚父: {} (浠诲姟閲岀▼:{}, 鎬婚噷绋�:{}), 寮哄埗璁句负1.0",
+ vehicleId, statDate, taskRatio, taskMileage, totalMileage);
+ taskRatio = BigDecimal.ONE;
+ } else if (taskRatio.compareTo(BigDecimal.ZERO) < 0) {
+ logger.warn("杞﹁締ID: {} 鏃ユ湡: {} 浠诲姟閲岀▼鍗犳瘮涓鸿礋: {}, 寮哄埗璁句负0",
+ vehicleId, statDate, taskRatio);
+ taskRatio = BigDecimal.ZERO;
+ }
+ }
+
+ // 5. 鏌ヨ鎴栧垱寤虹粺璁¤褰�
+ VehicleMileageStats stats = vehicleMileageStatsMapper.selectByVehicleIdAndDate(vehicleId, statDate);
+ boolean isNew = (stats == null);
+
+ if (isNew) {
+ stats = new VehicleMileageStats();
+ stats.setVehicleId(vehicleId);
+ stats.setStatDate(statDate);
+
+ // 鑾峰彇杞︾墝鍙凤細浼樺厛浠庡垎娈垫暟鎹紝濡傛灉娌℃湁鍒欎粠杞﹁締琛ㄦ煡璇�
+ String vehicleNo = null;
+ if (!segments.isEmpty() && segments.get(0).getVehicleNo() != null) {
+ vehicleNo = segments.get(0).getVehicleNo();
+ }
+ if (vehicleNo == null || vehicleNo.trim().isEmpty()) {
+ VehicleInfo vehicleInfo = vehicleInfoMapper.selectVehicleInfoById(vehicleId);
+ if (vehicleInfo != null) {
+ vehicleNo = vehicleInfo.getVehicleNo();
+ }
+ }
+ stats.setVehicleNo(vehicleNo);
+ }
+
+ // 6. 璁剧疆缁熻鏁版嵁
+ stats.setTotalMileage(totalMileage.setScale(2, RoundingMode.HALF_UP));
+ stats.setTaskMileage(taskMileage.setScale(2, RoundingMode.HALF_UP));
+ stats.setNonTaskMileage(nonTaskMileage.setScale(2, RoundingMode.HALF_UP));
+ stats.setTaskRatio(taskRatio);
+ stats.setGpsPointCount(totalGpsPoints);
+ stats.setTaskCount(taskCount);
+ stats.setSegmentCount(segments.size());
+ stats.setDataSource("segment"); // 鏍囪鏁版嵁鏉ユ簮涓哄垎娈垫眹鎬�
+
+ // 7. 淇濆瓨鍒版暟鎹簱
+ if (isNew) {
+ vehicleMileageStatsMapper.insertVehicleMileageStats(stats);
+ } else {
+ vehicleMileageStatsMapper.updateVehicleMileageStats(stats);
+ }
+
+ logger.info("杞﹁締ID: {} 鏃ユ湡: {} 浠庡垎娈垫眹鎬诲畬鎴� - 鎬婚噷绋�: {}km, 浠诲姟閲岀▼: {}km, 闈炰换鍔¢噷绋�: {}km, 鍒嗘鏁�: {}",
+ vehicleId, statDate, totalMileage, taskMileage, nonTaskMileage, segments.size());
+
+ return stats;
+
+ } catch (Exception e) {
+ logger.error("浠庡垎娈垫眹鎬婚噷绋嬬粺璁″け璐� - 杞﹁締ID: {}, 鏃ユ湡: {}", vehicleId, statDate, e);
+ throw new RuntimeException("姹囨�婚噷绋嬬粺璁″け璐�: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 鎵归噺浠庡垎娈甸噷绋嬫眹鎬荤敓鎴愭寜鏃ョ粺璁�
+ */
+ @Override
+ public int batchAggregateFromSegmentMileage(Date statDate) {
+ try {
+ // 璁$畻鏌ヨ寮�濮嬫椂闂达紙7澶╁墠锛�
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(statDate);
+ calendar.add(Calendar.DAY_OF_MONTH, -7);
+ Date startTime = calendar.getTime();
+
+ // 鏌ヨ鎵�鏈夋椿璺冭溅杈�
+ List<Long> vehicleIds = vehicleGpsMapper.selectActiveVehicleIds(startTime);
+
+ if (vehicleIds == null || vehicleIds.isEmpty()) {
+ logger.info("娌℃湁鎵惧埌娲昏穬杞﹁締");
+ return 0;
+ }
+
+ int successCount = 0;
+ for (Long vehicleId : vehicleIds) {
+ try {
+ aggregateFromSegmentMileage(vehicleId, statDate);
+ successCount++;
+ } catch (Exception e) {
+ logger.error("姹囨�昏溅杈� {} 鐨勯噷绋嬬粺璁″け璐�", vehicleId, e);
+ }
+ }
+
+ logger.info("鎵归噺閲岀▼姹囨�诲畬鎴� - 鏃ユ湡: {}, 鎬昏溅杈嗘暟: {}, 鎴愬姛: {}", statDate, vehicleIds.size(), successCount);
+ return successCount;
+
+ } catch (Exception e) {
+ logger.error("鎵归噺姹囨�婚噷绋嬬粺璁″け璐� - 鏃ユ湡: {}", statDate, e);
+ throw new RuntimeException("鎵归噺姹囨�诲け璐�: " + e.getMessage());
+ }
+ }
}
--
Gitblit v1.9.1