From 62c24bfb0f54998fceeb3b37eb14a74e6bfd83e9 Mon Sep 17 00:00:00 2001
From: guonan <guonan201020@163.com>
Date: 星期二, 01 七月 2025 11:01:35 +0800
Subject: [PATCH] 修改小时雨强 echart暂停播放的问题 威胁人房户 定时器问题

---
 src/components/monifangzhen/echartInfo.vue |   46 ++++-
 src/components/tools/DebuffDetail.vue      |  231 ++++++++++++++++------------
 src/views/left/CitySim.vue                 |  167 +++++++++++++-------
 src/components/monifangzhen/schemeCard.vue |    5 
 4 files changed, 281 insertions(+), 168 deletions(-)

diff --git a/src/components/monifangzhen/echartInfo.vue b/src/components/monifangzhen/echartInfo.vue
index 3f73aaa..c2e4352 100644
--- a/src/components/monifangzhen/echartInfo.vue
+++ b/src/components/monifangzhen/echartInfo.vue
@@ -450,16 +450,33 @@
     }
   };
 
-  // 鎺у埗鏂规硶锛氱簿纭帶鍒跺姩鐢绘椂闂达紝鏈�鍚庝竴甯у湪绗� 90 绉�
+  let fixedFrameNum = null;
+  let startTime = null; // 灏唖tartTime绉诲埌澶栧眰
+  let elapsedBeforePause = 0; // 璁板綍鏆傚仠鍓嶅凡缁忚繃鍘荤殑鏃堕棿
+
   const startUpdating = () => {
-    if (updateInterval || dataIndex.value >= rainfallData.value.length) return;
+    if (updateInterval || dataIndex.value >= rainfallData.value.length) {
+      console.log("Animation already running or completed");
+      return;
+    }
 
-    const totalDuration = simStore.frameNum * 1000; // 90绉�
+    // 濡傛灉鏄娆″惎鍔ㄦ垨閲嶆柊寮�濮�
+    if (fixedFrameNum === null) {
+      fixedFrameNum = simStore.frameNum;
+      elapsedBeforePause = 0;
+      startTime = Date.now();
+    } else {
+      // 濡傛灉鏄殏鍋滃悗缁х画锛岃皟鏁磗tartTime浠ュ弽鏄犲凡缁忚繃鍘荤殑鏃堕棿
+      startTime = Date.now() - elapsedBeforePause;
+    }
+
+    const totalDuration = fixedFrameNum * 1000;
     const totalPoints = rainfallData.value.length;
-    const startTime = Date.now();
 
-    const animate = (index = 0) => {
+
+    const animate = (index) => {
       if (index >= totalPoints) {
+        console.log("Animation completed");
         stopUpdating();
         return;
       }
@@ -469,7 +486,7 @@
       const delay = Math.max(0, startTime + expectedTime - now);
 
       updateInterval = setTimeout(() => {
-        dataIndex.value = index + 1; // 鍥犱负鏄粠 0 寮�濮� push 鐨�
+        dataIndex.value = index;
         updateData();
         animate(index + 1);
       }, delay);
@@ -478,13 +495,26 @@
     animate(dataIndex.value);
   };
 
+  // 鏆傚仠鍑芥暟闇�瑕佽褰曞凡缁忚繃鍘荤殑鏃堕棿
   const stopUpdating = () => {
-    clearTimeout(updateInterval);
-    updateInterval = null;
+    if (updateInterval) {
+      clearTimeout(updateInterval);
+      updateInterval = null;
+      // 璁板綍鏆傚仠鏃跺凡缁忚繃鍘荤殑鏃堕棿
+      elapsedBeforePause = Date.now() - startTime;
+    }
   };
+
+  // const stopUpdating = () => {
+  //   clearTimeout(updateInterval);
+  //   updateInterval = null;
+  // };
 
   const resetLoading = () => {
     stopUpdating();
+    fixedFrameNum = null;
+    startTime = null;
+    elapsedBeforePause = 0;
     dataIndex.value = 0;
     data1.value = [0];
     data2.value = [0];
diff --git a/src/components/monifangzhen/schemeCard.vue b/src/components/monifangzhen/schemeCard.vue
index 32073b0..ec72b32 100644
--- a/src/components/monifangzhen/schemeCard.vue
+++ b/src/components/monifangzhen/schemeCard.vue
@@ -220,9 +220,11 @@
       (item) =>
         item.result == "鍒涘缓浠跨湡" ||
         item.result == "瀹屾垚" ||
-        item.result == "-1"
+        item.result == "-1" ||
+        item.result == null
     );
     simAPIStore.shouldPoll = !shouldStop; // 淇敼 Pinia 鐘舵��
+    console.log(shouldStop, "aaaaaaaaaaaaaaaa");
     // 3. 濡傛灉闇�瑕佸仠姝�
     if (shouldStop) {
       if (intervalId) {
@@ -241,7 +243,6 @@
 watch(
   () => simAPIStore.shouldPoll,
   (isStarted) => {
-    console.log(isStarted, "瀹氭椂鍣�");
     if (isStarted) {
       getScheme(); // 棣栨绔嬪嵆鑾峰彇涓�娆�
       intervalId = setInterval(getScheme, 60 * 1000); // 姣忛殧涓�鍒嗛挓鎵ц
diff --git a/src/components/tools/DebuffDetail.vue b/src/components/tools/DebuffDetail.vue
index f5b1506..1c4b688 100644
--- a/src/components/tools/DebuffDetail.vue
+++ b/src/components/tools/DebuffDetail.vue
@@ -12,108 +12,149 @@
   </div>
 </template>
 
-<script>
-// 鐘舵�佺鐞嗗櫒
+<script setup>
+import { ref, onMounted } from "vue";
 import { useSimStore } from "@/store/simulation";
 import { storeToRefs } from "pinia";
+
 const simStore = useSimStore();
 const { selectedScheme } = storeToRefs(simStore);
 
-export default {
-  name: "detail",
-  components: {},
-  props: {
-    areaName: {
-      type: String,
-      default: "灏瑰瑗挎矡",
-    },
-  },
-  data() {
-    return {
-      show: false,
-      detailList: [
-        {
-          name: "鏈�澶ч洦寮猴細",
-          value: Number(Math.random() * 100).toFixed(2) + " mm/h",
-        },
-        {
-          name: "骞冲潎闆ㄥ己锛�",
-          value: Number(Math.random() * 10).toFixed(2) + " mm/h",
-        },
-        {
-          name: "鏈�澶ф按娣憋細",
-          value: "1.86 m",
-        },
-        {
-          name: "鏈�澶ф祦閫燂細",
-          value: "7 m/s",
-        },
-        {
-          name: "濞佽儊鎴垮眿锛�",
-          value: "406 闂�",
-        },
-        {
-          name: "濞佽儊浜哄彛锛�",
-          value: "145 鎴�",
-        },
-        {
-          name: "濞佽儊璐骇锛�",
-          value: "4872 涓囧厓",
-        },
-      ],
-    };
-  },
-  mounted() {
-    this.getRainfallData(); // 缁勪欢鎸傝浇鍚庢墽琛岃幏鍙栭洦閲忔暟鎹�
-  },
-  methods: {
-    getRainfallData() {
-      if (!selectedScheme.value || !selectedScheme.value.data) {
-        console.warn("selectedScheme 鎴� data 涓嶅瓨鍦�");
-        return;
-      }
-      let data = selectedScheme.value.data;
-      // 濡傛灉鏄瓧绗︿覆锛屽垯灏濊瘯瑙f瀽鎴愬璞�
-      if (typeof data === "string") {
-        try {
-          data = JSON.parse(data);
-        } catch (e) {
-          console.error("data 涓嶆槸鏈夋晥鐨� JSON 瀛楃涓�");
-          return;
-        }
-      }
+// 闅愭偅鐐�
+const filteredData = simStore.DangerPoint.filter((item) =>
+  item.position?.includes("瀛欒儭娌�")
+);
 
-      if (selectedScheme.value.type !== 2) {
-        const rainfallList = data.rainfalls;
-
-        // 鎻愬彇 intensity 鍊�
-        const rainValues = rainfallList.map((r) => r.intensity);
-        const minRain = Math.min(...rainValues);
-        const maxRain = Math.max(...rainValues);
-        const avgRain =
-          rainValues.reduce((sum, val) => sum + val, 0) / rainValues.length;
-
-        // 鏇存柊 detailList 涓殑鈥滄渶澶ч洦寮衡�濆拰鈥滃钩鍧囬洦寮衡��
-        this.detailList[0].value = maxRain.toFixed(2) + " mm/h"; // 鏈�澶ч洦寮�
-        this.detailList[1].value = avgRain.toFixed(2) + " mm/h"; // 骞冲潎闆ㄥ己
-
-        console.log(
-          "褰撳墠鏂规涓嬫渶灏忛洦閲忋�佹渶澶ч洦閲忋�佸钩鍧囬洦閲忥細",
-          minRain.toFixed(2),
-          maxRain.toFixed(2),
-          avgRain.toFixed(2)
-        );
-      }
-    },
-    closeMsg() {
-      this.$emit("close");
-    },
-    showMsg() {
-      this.$emit("open");
-    },
+// 鍝嶅簲寮忔暟鎹�
+const detailList = ref([
+  {
+    name: "鏈�澶ч洦寮猴細",
+    value: (Math.random() * 100).toFixed(2) + " mm/h",
   },
+  {
+    name: "骞冲潎闆ㄥ己锛�",
+    value: (Math.random() * 10).toFixed(2) + " mm/h",
+  },
+  {
+    name: "鏈�澶ф按娣憋細",
+    value: "1.86 m",
+  },
+  {
+    name: "鏈�澶ф祦閫燂細",
+    value: "7 m/s",
+  },
+  {
+    name: "濞佽儊鎴挎暟锛�",
+    value: "406 闂�",
+  },
+  {
+    name: "濞佽儊鎴锋暟锛�",
+    value: "145 鎴�",
+  },
+  {
+    name: "濞佽儊浜哄彛锛�",
+    value: "145 浜�",
+  },
+  {
+    name: "濞佽儊璐骇锛�",
+    value: "4872 涓囧厓",
+  },
+]);
+
+const updateThreatData = () => {
+  // 绛涢�� position 鍖呭惈 "瀛欒儭娌�" 鐨勬暟鎹�
+  const filteredData = simStore.DangerPoint.filter((item) =>
+    item.position?.includes("瀛欒儭娌�")
+  );
+
+  if (filteredData.length === 0) {
+    console.warn("鏈壘鍒� position 鍖呭惈 '瀛欒儭娌�' 鐨勬暟鎹�");
+    return;
+  }
+
+  // 鍒濆鍖栫疮鍔犲��
+  let totalHousehold = 0; // 濞佽儊鎴锋暟
+  let totalPerson = 0; // 濞佽儊浜烘暟
+  let totalRoom = 0; // 濞佽儊鎴挎暟
+
+  // 閬嶅巻骞剁疮鍔�
+  filteredData.forEach((item) => {
+    totalHousehold += Number(item.threatHouseNum) || 0;
+    totalPerson += Number(item.threatPersonNum) || 0;
+    totalRoom += Number(item.threatRoomNum) || 0;
+  });
+
+  // 鏇存柊 detailList
+  detailList.value[5].value = `${totalHousehold} 鎴穈;
+  detailList.value[6].value = `${totalPerson} 浜篳;
+  detailList.value[4].value = `${totalRoom} 闂碻;
+
+  console.log("濞佽儊鎴锋暟:", totalHousehold);
+  console.log("濞佽儊浜烘暟:", totalPerson);
+  console.log("濞佽儊鎴挎暟:", totalRoom);
 };
+// 鏂规硶瀹氫箟
+const getRainfallData = () => {
+  if (!selectedScheme.value || !selectedScheme.value.data) {
+    console.warn("selectedScheme 鎴� data 涓嶅瓨鍦�");
+    return;
+  }
+
+  let data = selectedScheme.value.data;
+
+  // 濡傛灉鏄瓧绗︿覆锛屽垯灏濊瘯瑙f瀽鎴愬璞�
+  if (typeof data === "string") {
+    try {
+      data = JSON.parse(data);
+    } catch (e) {
+      console.error("data 涓嶆槸鏈夋晥鐨� JSON 瀛楃涓�");
+      return;
+    }
+  }
+
+  if (selectedScheme.value.type !== 2) {
+    const rainfallList = data.rainfalls;
+
+    // 鎻愬彇 intensity 鍊�
+    const rainValues = rainfallList.map((r) => r.intensity);
+    const minRain = Math.min(...rainValues);
+    const maxRain = Math.max(...rainValues);
+    const avgRain =
+      rainValues.reduce((sum, val) => sum + val, 0) / rainValues.length;
+
+    // 鏇存柊 detailList 涓殑鈥滄渶澶ч洦寮衡�濆拰鈥滃钩鍧囬洦寮衡��
+    detailList.value[0].value = maxRain.toFixed(2) + " mm/h"; // 鏈�澶ч洦寮�
+    detailList.value[1].value = avgRain.toFixed(2) + " mm/h"; // 骞冲潎闆ㄥ己
+
+    console.log(
+      "褰撳墠鏂规涓嬫渶灏忛洦閲忋�佹渶澶ч洦閲忋�佸钩鍧囬洦閲忥細",
+      minRain.toFixed(2),
+      maxRain.toFixed(2),
+      avgRain.toFixed(2)
+    );
+  }
+};
+
+const closeMsg = () => {
+  // 浣跨敤 defineEmits 瀹氫箟 emit
+  emit("close");
+};
+
+const showMsg = () => {
+  emit("open");
+};
+
+// 瀹氫箟 emit
+const emit = defineEmits(["close", "open"]);
+
+// 鐢熷懡鍛ㄦ湡閽╁瓙
+onMounted(() => {
+  console.log(filteredData);
+  updateThreatData();
+  getRainfallData();
+});
 </script>
+
 <style lang="less" scoped>
 .detail {
   background: url("@/assets/img/tools/messagebg.png");
@@ -133,7 +174,6 @@
   left: 20px;
   font-weight: 700;
   font-size: 18px;
-  font-weight: 700;
   color: #fff;
   line-height: 40px;
   width: 270px;
@@ -148,11 +188,8 @@
   height: 20px;
   text-align: center;
   line-height: 20px;
-  text-align: center;
-
   font-weight: 700;
   font-size: 18px;
-  font-weight: 700;
   color: #fff;
   cursor: pointer;
 }
diff --git a/src/views/left/CitySim.vue b/src/views/left/CitySim.vue
index 27af36b..63348ca 100644
--- a/src/views/left/CitySim.vue
+++ b/src/views/left/CitySim.vue
@@ -447,15 +447,16 @@
 
 /**
  * 鏁版嵁澶勭悊涓诲嚱鏁�
+ * @param {Array} data - 瑙f瀽鍚庣殑鍘熷鏁版嵁鏁扮粍锛屾瘡涓厓绱犳槸涓�涓璞�
  */
 const processData = (data) => {
-  // 妫�鏌ョ┖鏁版嵁
+  // 妫�鏌ユ槸鍚︿负绌烘暟鎹�
   if (data.length === 0) {
     ElMessage.warning("鏂囦欢鍐呭涓虹┖锛�");
     return;
   }
 
-  // 鍖归厤瀛楁鍚�
+  // 鍖归厤鍒楀悕锛堜緥濡傗�滄椂闂粹�濄�佲�滃皬鏃堕洦寮衡�濓級
   const columns = matchColumns(data[0]);
 
   // 鏍¢獙蹇呰瀛楁鏄惁瀛樺湪
@@ -475,22 +476,18 @@
     return;
   }
 
-  // 鏃堕棿鍒楁牎楠屾槸鍚﹀崌搴�
+  // 鏍¢獙鏃堕棿鍒楁槸鍚﹀崌搴忔帓鍒�
   if (!isTimeColumnSorted(data, columns.time)) {
     ElMessage.error("鏃堕棿鍒楀繀椤绘寜鍗囧簭鎺掑垪锛�");
     forms.fileList = [];
     return;
   }
 
-  // 鎻愬彇鍗曚綅
-  forms.intensityUnit = extractUnitFromHeader(columns.intensity);
+  // 鎻愬彇鍗曚綅锛堝 mm/h锛夛紝鑻ユ病鏈夊垯璁句负绌哄瓧绗︿覆
+  forms.intensityUnit = extractUnitFromHeader(columns.intensity) || "";
 
-  if (!forms.intensityUnit) {
-    forms.intensityUnit = "";
-  }
-
-  // 杞崲 key 鍚嶅苟杞崲鏁板�肩被鍨�
-  forms.rainFallList = data.map((row) => ({
+  // 灏嗗師濮嬫暟鎹浆鎹负缁熶竴缁撴瀯鐨勫璞℃暟缁�
+  const rawRainFallList = data.map((row) => ({
     time: row[columns.time],
     intensity: parseFloat(row[columns.intensity]),
     total: columns.totalRainfall
@@ -498,21 +495,45 @@
       : undefined,
   }));
 
-  console.log(forms.rainFallList, "瑙f瀽鍚庣殑闄嶉洦鏁版嵁");
+  console.log(rawRainFallList, "鍘熷闄嶉洦鏁版嵁");
 
-  // 璁$畻缁熻淇℃伅
-  const firstTime = parseDateTime(data[0][columns.time]);
-  const lastTime = parseDateTime(data[data.length - 1][columns.time]);
+  // 鍒ゆ柇鏄惁涓烘暣灏忔椂鏁版嵁锛堝嵆鐩搁偦鏃堕棿闂撮殧鏄惁涓烘暣灏忔椂锛�
+  const isHourlyData = checkIfHourlyData(rawRainFallList);
+
+  let hourlyRainfallList = [];
+
+  if (!isHourlyData) {
+    // 濡傛灉涓嶆槸鏁村皬鏃舵暟鎹紝鎸夊皬鏃惰繘琛岃仛鍚堝鐞�
+    hourlyRainfallList = aggregateToHourlyRainfall(rawRainFallList);
+    console.log(hourlyRainfallList, "淇鍚庣殑灏忔椂闆ㄥ己");
+  } else {
+    // 濡傛灉鏄暣灏忔椂鏁版嵁锛岀洿鎺ヤ娇鐢ㄥ師濮嬮洦寮哄��
+    hourlyRainfallList = rawRainFallList.map((item) => ({
+      time: item.time,
+      intensity: item.intensity,
+    }));
+  }
+
+  // 鏇存柊 forms.rainFallList锛屽彲鐢ㄤ簬鍥捐〃鏄剧ず绛夌敤閫�
+  forms.rainFallList = hourlyRainfallList;
+
+  // 璁$畻璧峰鏃堕棿鍜岀粨鏉熸椂闂达紙姣鏁帮級
+  const firstTime = parseDateTime(hourlyRainfallList[0]?.time);
+  const lastTime = parseDateTime(
+    hourlyRainfallList[hourlyRainfallList.length - 1]?.time
+  );
+
+  // 璁$畻鎸佺画鏃堕棿锛堝崟浣嶏細灏忔椂锛�
   const durationSeconds = Math.floor((lastTime - firstTime) / 1000);
-  forms.duration = (durationSeconds / 3600).toFixed(2); // 灏忔椂
+  forms.duration = (durationSeconds / 3600).toFixed(2); // 鍗曚綅锛氬皬鏃�
 
+  // 鎵惧嚭鏈�澶у皬鏃堕洦寮�
   const maxIntensity = Math.max(
-    ...data
-      .map((row) => parseFloat(row[columns.intensity]))
-      .filter((v) => !isNaN(v))
+    ...hourlyRainfallList.map((item) => item.intensity).filter((v) => !isNaN(v))
   ).toFixed(2);
   forms.intensity = maxIntensity;
 
+  // 鑻ユ湁鎬婚檷闆ㄩ噺鍒楋紝鍙栧嚭鏈�鍚庝竴涓�间綔涓烘�婚檷闆ㄩ噺
   if (columns.totalRainfall) {
     const lastTotal = parseFloat(data[data.length - 1][columns.totalRainfall]);
     forms.rainfall = isNaN(lastTotal) ? 0 : lastTotal.toFixed(2);
@@ -521,56 +542,80 @@
   }
 };
 
-// // 澶勭悊鏁版嵁
-// const processData = (data) => {
-//   // 1. 妫�鏌ユ暟鎹槸鍚︿负绌�
-//   if (data.length === 0) {
-//     ElMessage.warning("鏂囦欢鍐呭涓虹┖锛�");
-//     return;
-//   }
+/**
+ * 妫�鏌ユ暟鎹槸鍚︿负鏁村皬鏃惰褰�
+ * @param {Array} rainList - 鍘熷闄嶉洦鏁版嵁鍒楄〃锛屾瘡涓厓绱犲寘鍚� time 鍜� intensity
+ * @returns {boolean} - 鏄惁涓烘暣灏忔椂鏁版嵁
+ */
+function checkIfHourlyData(rainList) {
+  if (rainList.length < 2) return true; // 鍙湁涓�涓偣锛岄粯璁よ涓烘暣灏忔椂鏁版嵁
 
-//   // 2. 鑾峰彇琛ㄥご锛堢涓�鍒楁槸鏃堕棿鍒楋級
-//   const tableColumns = Object.keys(data[0]);
-//   const timeColumn = tableColumns[0]; // 鍋囪绗竴鍒楁槸鏃堕棿
+  for (let i = 1; i < rainList.length; i++) {
+    // 瑙f瀽涓や釜鐩搁偦鏃堕棿鐐�
+    const time1 = parseDateTime(rainList[i - 1].time);
+    const time2 = parseDateTime(rainList[i].time);
 
-//   // 3. 鏍¢獙鏃堕棿鍒楁槸鍚︽寜鍗囧簭鎺掑垪
-//   if (!isTimeColumnSorted(data, timeColumn)) {
-//     ElMessage.error("鏃堕棿鍒楀繀椤绘寜鍗囧簭鎺掑垪锛�");
-//     forms.fileList = [];
-//     return; // 缁堟澶勭悊
-//   }
+    // 璁$畻鏃堕棿宸紙鍒嗛挓锛�
+    const diffMinutes = Math.abs(time2 - time1) / (1000 * 60);
 
-//   const intensityColumn = tableColumns[1]; // 闆ㄥ己鍒楋紙濡� "灏忔椂闆ㄥ己(mm/h)"锛�
-//   // console.log(intensityColumn, "intensityColumnintensityColumnintensityColumn");
-//   // 3. 鎻愬彇绗簩鍒楃殑鍗曚綅锛堝 "(mm/h)" 鈫� "mm/h"锛�
-//   const intensityUnit = extractUnitFromHeader(intensityColumn);
-//   forms.intensityUnit = intensityUnit; // 瀛樺偍鍗曚綅锛堝彲閫夛級
-//   console.log(forms.intensityUnit,'aaaaaaaaaaaaaaaaaaaaa')
+    // 濡傛灉鏃堕棿宸笉鏄暣灏忔椂锛堜笉鑳借60鏁撮櫎锛夛紝鍒欎笉鏄暣灏忔椂鏁版嵁
+    if (diffMinutes % 60 !== 0) {
+      return false;
+    }
+  }
 
-//   // 4. 濡傛灉鏍¢獙閫氳繃锛岀户缁鐞嗘暟鎹�
-//   forms.rainFallList = transformKeys(data);
-//   console.log(forms.rainFallList, "data");
+  return true;
+}
 
-//   // 5. 璁$畻闄嶉洦鏃堕暱銆侀洦寮恒�佺疮璁¢洦閲忥紙鍘熼�昏緫锛�
-//   const firstTime = parseDateTime(data[0][timeColumn]);
-//   const lastTime = parseDateTime(data[data.length - 1][timeColumn]);
-//   const timeDuration = Math.floor((lastTime - firstTime) / 1000);
-//   // 闄嶉洦鏃堕暱
-//   forms.duration = (timeDuration / 3600).toFixed(2);
-//   // 闄嶉洦寮哄害
-//   const maxValue = Math.max(
-//     ...data.map((row) => {
-//       const value = parseFloat(row[tableColumns[1]]);
-//       return isNaN(value) ? -Infinity : value;
-//     })
-//   ).toFixed(2);
-//   forms.intensity = maxValue;
+/**
+ * 灏嗕换鎰忔椂闂寸矑搴︾殑闆ㄥ己鏁版嵁锛屾寜灏忔椂鑱氬悎涓衡�滃皬鏃堕洦寮衡��
+ * @param {Array} rainList - 鍘熷鏁版嵁鍒楄〃锛屾瘡涓厓绱犲寘鍚� time 鍜� intensity
+ * @returns {Array} - 鎸夊皬鏃跺垎缁勭殑鑱氬悎缁撴灉
+ */
+function aggregateToHourlyRainfall(rainList) {
+  const grouped = {}; // 鐢ㄤ簬涓存椂瀛樺偍姣忎釜灏忔椂鐨勬暟鎹�
 
-//   const lastValue = data[data.length - 1][tableColumns[2]];
-//   forms.rainfall = lastValue;
+  for (const item of rainList) {
+    // 瑙f瀽鏃堕棿瀛楃涓蹭负鏃堕棿鎴�
+    const timestamp = parseDateTime(item.time);
 
-// };
+    // 濡傛灉瑙f瀽澶辫触锛岃烦杩囧綋鍓嶉」
+    if (isNaN(timestamp)) {
+      console.warn("鏃犳晥鐨勬椂闂存牸寮忥紝宸茶烦杩�", item.time);
+      continue;
+    }
 
+    // 灏嗘椂闂存埑杞负 Date 瀵硅薄浠ヤ究鎿嶄綔鏃ユ湡
+    const dt = new Date(timestamp);
+
+    // 鏋勯�犲勾鏈堟棩+灏忔椂閿紙濡傦細"2024-08-25 14"锛�
+    const year = String(dt.getFullYear()).padStart(4, "0");
+    const month = String(dt.getMonth() + 1).padStart(2, "0"); // 娉ㄦ剰鏈堜唤浠�0寮�濮�
+    const date = String(dt.getDate()).padStart(2, "0");
+    const hour = String(dt.getHours()).padStart(2, "0");
+
+    const hourKey = `${year}-${month}-${date} ${hour}`;
+
+    // 鍒濆鍖栬灏忔椂鐨勮仛鍚堝璞�
+    if (!grouped[hourKey]) {
+      grouped[hourKey] = {
+        time: `${hourKey}:00:00`, // 鏍囧噯鍖栦负鏁寸偣鏃堕棿
+        intensity: 0,
+      };
+    }
+
+    // 绱姞璇ュ皬鏃跺唴鎵�鏈夐洦寮哄��
+    grouped[hourKey].intensity += item.intensity;
+  }
+
+  // 灏嗚仛鍚堢粨鏋滆浆涓烘暟缁勫苟淇濈暀涓や綅灏忔暟
+  const result = Object.values(grouped).map((item) => ({
+    time: item.time,
+    intensity: Number(item.intensity.toFixed(2)),
+  }));
+
+  return result;
+}
 /**
  * 瑙f瀽鏃ユ湡鏃堕棿瀛楃涓叉垨Excel鏁板瓧鏃ユ湡锛岃繑鍥炴椂闂存埑锛堟绉掓暟锛�
  * @param {string|number} dateString - 鏃ユ湡瀛楃涓叉垨Excel鏁板瓧鏃ユ湡

--
Gitblit v1.9.3