From f54c45de2ec6dfadc825c064b75e6707513bd094 Mon Sep 17 00:00:00 2001
From: wangjuncheng <1>
Date: 星期一, 28 四月 2025 10:07:08 +0800
Subject: [PATCH] change

---
 src/components/menu/TimeLine.vue |  336 ++++++++++++++++++++------------------------------------
 1 files changed, 120 insertions(+), 216 deletions(-)

diff --git a/src/components/menu/TimeLine.vue b/src/components/menu/TimeLine.vue
index b8cec2a..dd4acc6 100644
--- a/src/components/menu/TimeLine.vue
+++ b/src/components/menu/TimeLine.vue
@@ -2,30 +2,20 @@
   <div class="timeline-container">
     <div class="controls">
       <div class="control-btn" @click="skipBackward">
-        <img
-          src="@/assets/img/timeline/left.png"
-          class="fas fa-step-backward"
-        />
+        <img src="@/assets/img/timeline/left.png" class="fas fa-step-backward" />
       </div>
       <div class="control-btn play-btn" @click="togglePlay">
         <img v-show="isPlaying" src="@/assets/img/timeline/stop.png" />
         <img v-show="!isPlaying" src="@/assets/img/timeline/start.png" />
       </div>
       <div class="control-btn" @click="skipForward">
-        <img
-          src="@/assets/img/timeline/right.png"
-          class="fas fa-step-forward"
-        />
+        <img src="@/assets/img/timeline/right.png" class="fas fa-step-forward" />
       </div>
       <div class="speed-control">
         <div @click="toggleSpeedMenu">{{ playbackRate }}X</div>
         <div class="speed-menu" v-show="showSpeedMenu">
-          <div
-            v-for="rate in playbackRates"
-            :key="rate"
-            @click.capture="setPlaybackRate(rate)"
-            :class="{ active: playbackRate === rate }"
-          >
+          <div v-for="rate in playbackRates" :key="rate" @click.capture="setPlaybackRate(rate)"
+            :class="{ active: playbackRate === rate }">
             {{ rate }}X
           </div>
         </div>
@@ -34,29 +24,18 @@
 
     <div class="timeline">
       <div class="dates">
-        <div
-          v-for="(date, index) in visibleDates"
-          :key="index"
-          class="date-label"
-        >
-          {{ formatDate(date) }}
+        <div class="current-date">
+          褰撳墠鎾斁鏃堕棿锛歿{ currentPlayingTime }}
+        </div>
+        <div v-for="(date, index) in visibleDates" :key="index" class="date-label">
+          <!-- {{ formatDate(date) }} -->
         </div>
       </div>
       <div class="timeline-track" ref="timelineTrack" @click="seekToPosition">
-        <div
-          class="timeline-progress"
-          :style="{ width: progressPercentage + '%' }"
-        ></div>
-        <div
-          class="timeline-cursor"
-          :style="{ left: progressPercentage + '%' }"
-        ></div>
+        <div class="timeline-progress" :style="{ width: progressPercentage + '%' }"></div>
+        <div class="timeline-cursor" :style="{ left: progressPercentage + '%' }"></div>
         <div class="time-markers">
-          <div
-            v-for="(time, index) in timeMarkers"
-            :key="index"
-            class="time-marker"
-          >
+          <div v-for="(time, index) in timeMarkers" :key="index" class="time-marker">
             {{ time }}
           </div>
         </div>
@@ -70,7 +49,6 @@
 import {
   ref,
   computed,
-  onUnmounted,
   onMounted,
   watch,
   defineProps,
@@ -79,11 +57,13 @@
 } from "vue";
 import dayjs from "dayjs";
 import { createWaterPrimitive, destoryWaterPrimitive } from "@/utils/water";
-import { getRainfall } from "@/api/index";
-import { EventBus } from "@/eventBus"; // 寮曞叆浜嬩欢鎬荤嚎
-import { ElMessage } from 'element-plus'
+import { fetchWaterSimulationData } from "@/api/trApi.js";
+import { EventBus } from "@/eventBus";
+import { ElMessage } from 'element-plus';
 
+const emit = defineEmits(["timeUpdate", "isPlaying", "playbackFinished"]);
 
+// 瀹氫箟props
 const props = defineProps({
   waterSimulateParams: {
     type: Object,
@@ -92,229 +72,145 @@
     }),
   },
 });
+
 // 鍝嶅簲寮忕姸鎬�
+const currentPlayingTime = ref(""); // 褰撳墠鎾斁鏃堕棿
 const isPlaying = ref(false);
 const playbackFinished = ref(true);
 const currentTime = ref(0);
-const duration = ref(86400); // 涓�澶╃殑绉掓暟
-const playbackRate = ref(1);
+const duration = ref(60); // 涓�澶╃殑绉掓暟
+const playbackRate = ref(8);
 const playbackRates = ref([1, 2, 4, 8]);
 const showSpeedMenu = ref(false);
-
-const timeMarkers = ref([
-  "00:00",
-  "03:19",
-  "06:39",
-  "09:59",
-  "13:19",
-  "16:39",
-  "19:59",
-  "23:19",
-]);
+const waterTimestamps = ref([]); // 瀛樺偍鏃堕棿杞存暟鎹�
+const timeMarkers = ref([]);
 const timelineTrack = ref(null);
 
-const startDate = computed(() => {
-  return dayjs(props.waterSimulateParams.date[0]);
-});
-const endDate = computed(() => {
-  return dayjs(props.waterSimulateParams.date[1]);
-});
 let playInterval = null;
 
 // 璁$畻灞炴��
-const progressPercentage = computed(() => {
-  return (currentTime.value / duration.value) * 100;
-});
+const startDate = computed(() => dayjs(props.waterSimulateParams.date[0]));
+const endDate = computed(() => dayjs(props.waterSimulateParams.date[1]));
+const progressPercentage = computed(() => (currentTime.value / duration.value) * 100);
+const visibleDates = computed(() =>
+  Array.from(
+    new Set(waterTimestamps.value.map((ts) => dayjs(ts).format("YYYY-MM-DD")))
+  ).map((date) => dayjs(date).toDate())
+);
+const currentTimeFormatted = computed(() => formatTime(currentTime.value));
 
-const visibleDates = computed(() => {
-  // 鐢熸垚鏃堕棿杞翠笂鏄剧ず鐨勬棩鏈�
-  const dates = [];
-  const currentDateValue = dayjs(startDate.value);
-  const endDateValue = dayjs(endDate.value);
-
-  // let tempDate = currentDateValue
-  // while (tempDate.isSame(endDateValue) || tempDate.isBefore(endDateValue)) {
-  //   dates.push(tempDate.toDate())
-  //   tempDate = tempDate.add(1, 'day')
-  // }
-
-  return [currentDateValue, endDateValue];
-});
-
-const currentTimeFormatted = computed(() => {
-  return formatTime(currentTime.value);
-});
-
+// 鎾斁鎺у埗
 const togglePlay = () => {
   // 濡傛灉褰撳墠鏄仠姝㈢姸鎬佷笖宸茬粡鎾斁瀹屾瘯锛岀偣鍑绘椂閲嶇疆鏃堕棿
-  if (!isPlaying.value && currentTime.value >= duration.value) {
-    currentTime.value = 0;
-    emit("timeUpdate", progressPercentage.value);
-    // earthCtrl.environment.disableEffect("rain");
-  }
-
+  if (!isPlaying.value && currentTime.value >= duration.value) currentTime.value = 0;
   isPlaying.value = !isPlaying.value;
   emit("isPlaying", isPlaying.value);
-
   if (isPlaying.value) {
     startPlayback();
     // 濡傛灉鏄粠澶村紑濮嬫挱鏀�
-    if (currentTime.value === 0) {
-      emit("playbackFinished", false);
-    }
-  } else {
-    stopPlayback();
-  }
+    if (currentTime.value === 0) emit("playbackFinished", false);
+  } else stopPlayback();
 };
-
+const intervalMap = {
+  1: 1000, // 1鍊嶉��
+  2: 500,  // 2鍊嶉��
+  4: 250,  // 4鍊嶉��
+  8: 125,  // 8鍊嶉��
+};
 const startPlayback = () => {
-  // earthCtrl.environment.showEffect("rain");
+  // 鏍规嵁褰撳墠鍊嶉�熻幏鍙栧搴旂殑 interval
+  const interval = intervalMap[playbackRate.value] || 1000; // 榛樿涓�1000
+  // 璋冪敤 createWaterPrimitive 骞朵紶閫� interval
+  createWaterPrimitive({ interval });
   clearInterval(playInterval);
   playInterval = setInterval(() => {
-    currentTime.value += 600 * playbackRate.value;
-    // emit("playbackFinished", true);
-
+    // 璁$畻姣忔澧炲姞鐨勬椂闂撮噺
+    const timeIncrement = playbackRate.value; // 鍊嶉�熺洿鎺ヤ綔涓哄閲�
+    currentTime.value += timeIncrement;
+    // 濡傛灉瓒呰繃鎬绘椂闀匡紝鍒欏仠姝㈡挱鏀�
     if (currentTime.value >= duration.value) {
-      emit("playbackFinished", false);
-
       currentTime.value = duration.value; // 鍋滃湪鏈�鍚庝竴甯�
-      stopPlayback(); // 鍋滄鎾斁
-      isPlaying.value = false; // 鏇存柊鎾斁鐘舵��
-      emit("isPlaying", isPlaying.value); // 閫氱煡鎾斁鐘舵�佸彉鍖�
-      emit("playbackFinished", true); // 閫氱煡鎾斁瀹屾垚
-      emit("timeUpdate", progressPercentage.value); // 鏇存柊杩涘害鏉′綅缃�
+      stopPlayback();
+      isPlaying.value = false;
+      emit("isPlaying", false);
+      emit("playbackFinished", true);
     }
-
+    // 瑙﹀彂鏃堕棿鏇存柊浜嬩欢
     emit("timeUpdate", progressPercentage.value);
-  }, 1000);
+  }, 1000); // 姣忕鏇存柊涓�娆�
 };
 
-const stopPlayback = () => {
-  // earthCtrl.environment.disableEffect("rain");
-  clearInterval(playInterval);
-};
-
-const skipForward = () => {
-  // 鍚戝墠璺宠浆10鍒嗛挓
-  currentTime.value = Math.min(currentTime.value + 600, duration.value);
-  emit("timeUpdate", progressPercentage.value);
-};
-
-const skipBackward = () => {
-  // 鍚戝悗璺宠浆10鍒嗛挓
-  currentTime.value = Math.max(currentTime.value - 600, 0);
-  emit("timeUpdate", progressPercentage.value);
-};
-
-const toggleSpeedMenu = () => {
-  showSpeedMenu.value = !showSpeedMenu.value;
-};
-
+const stopPlayback = () => clearInterval(playInterval);
+const skipForward = () => (currentTime.value = Math.min(currentTime.value + 1, duration.value)); // 鍚戝墠璺宠浆1绉�
+const skipBackward = () => (currentTime.value = Math.max(currentTime.value - 1, 0)); // 鍚戝悗璺宠浆1绉�
+const toggleSpeedMenu = () => (showSpeedMenu.value = !showSpeedMenu.value);
 const setPlaybackRate = (rate) => {
   playbackRate.value = rate;
   showSpeedMenu.value = false;
-
-  if (isPlaying.value) {
-    stopPlayback();
-    startPlayback();
-  }
+  if (isPlaying.value) stopPlayback(), startPlayback(); // 濡傛灉姝e湪鎾斁锛屽垯閲嶆柊鍚姩浠ュ簲鐢ㄦ柊鐨勯�熺巼
 };
-
-const formatTime = (seconds) => {
-  const hours = Math.floor(seconds / 3600);
-  const minutes = Math.floor((seconds % 3600) / 60);
-  const secs = Math.floor(seconds % 60);
-
-  return `${hours.toString().padStart(2, "0")}:${minutes
-    .toString()
-    .padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
-};
-
-const formatDate = (date) => {
-  return dayjs(date).format("YYYY-MM-DD");
-};
-
 const seekToPosition = (event) => {
   const rect = timelineTrack.value.getBoundingClientRect();
-  const clickPosition = event.clientX - rect.left;
-  const percentage = clickPosition / rect.width;
-
-  currentTime.value = percentage * duration.value;
+  const percentage = (event.clientX - rect.left) / rect.width;
+  currentTime.value = Math.round(percentage * duration.value);
   emit("timeUpdate", progressPercentage.value);
+  if (waterTimestamps.value.length > 0) {
+    const clickedTimestamp = dayjs(waterTimestamps.value[0]).add(currentTime.value, "second");
+    console.log("Clicked timestamp:", clickedTimestamp.valueOf(), clickedTimestamp.format("YYYY-MM-DD HH:mm:ss"));
+  }
 };
-
-const rainFallData = ref([]);
-function getRainfallData() {
-  getRainfall().then((res) => {
-    // rainFallData.value = res.data.map(item => {
-    //   return dayjs(item.time).format("HH:mm")
-    // })
-
-    // const rainfallData = res.data.map(item => {
-    //   return item.rainfall
-    // })
-    rainFallData.value = res.data;
-  });
-}
-
-let mockTimer = null;
-let currentRainfall = ref(0.0001);
-function randomMockWater() {
-  let delay = (3 / playbackRate.value) * 1000;
-  if (delay < 1000) {
-    delay = 1000;
+watch(() => currentTime.value, () => {
+  if (waterTimestamps.value.length > 0) {
+    currentPlayingTime.value = dayjs(waterTimestamps.value[0])
+      .add(currentTime.value, "second")
+      .format("YYYY-MM-DD mm:ss");
   }
-  if (mockTimer) {
-    clearImmediate(mockTimer);
-    mockTimer = null;
-  }
-  mockTimer = setTimeout(() => {
-    const rainfall = rainFallData.value.find(
-      (item) =>
-        dayjs(item.time).format("HH:mm:ss") == currentTimeFormatted.value
-    );
-    if (rainfall && rainfall.total) {
-      // console.log(rainfall.total);
-
-      createWaterPrimitive(rainfall.total / 50000);
-    }
-  }, delay);
-}
-watch(
-  () => currentTime.value,
-  () => {
-    randomMockWater();
-  }
-);
-
-// 瀹氫箟缁勪欢浜嬩欢
-const emit = defineEmits(["timeUpdate", "isPlaying", "playbackFinished"]);
-
-// 鍒濆鍖栨椂瑙﹀彂涓�娆℃椂闂存洿鏂帮紝纭繚鐖剁粍浠惰兘鑾峰彇鍒濆鏃堕棿
-onMounted(() => {
-  getRainfallData();
-  emit("timeUpdate", progressPercentage.value);
 });
+// 鏃堕棿鏍囪鐢熸垚
+function generateTimeMarkers(timestamps) {
+  if (!timestamps || timestamps.length === 0) return [];
+  const sorted = [...timestamps].sort((a, b) => dayjs(a).diff(dayjs(b)));
+  const interval = Math.floor(dayjs(sorted.at(-1)).diff(dayjs(sorted[0]), "second") / 7);
+  return Array.from({ length: 8 }, (_, i) => dayjs(sorted[0]).add(i * interval, "second").format("mm:ss"));
+}
+watch(() => waterTimestamps.value, (newTimestamps) => {
+  if (newTimestamps.length > 0) timeMarkers.value = generateTimeMarkers(newTimestamps);
+}, { immediate: true });
+
+onMounted(async () => {
+  try {
+    const { waterTimestamps: timestamps } = await fetchWaterSimulationData();
+    if (timestamps) {
+      waterTimestamps.value = timestamps;
+      updateTimelineRange();
+      timeMarkers.value = generateTimeMarkers(timestamps);
+      currentPlayingTime.value = dayjs(timestamps[0]).format("YYYY-MM-DD HH:mm:ss");
+    }
+  } catch (error) {
+    console.error("Error loading water simulation data:", error);
+  }
+});
+
+function updateTimelineRange() {
+  if (waterTimestamps.value.length > 0) {
+    const [first, last] = [waterTimestamps.value[0], waterTimestamps.value.at(-1)];
+    props.waterSimulateParams.date = [dayjs(first).toISOString(), dayjs(last).toISOString()];
+    duration.value = dayjs(last).diff(dayjs(first), "second");
+    console.log("Updated timeline range:", { ...props.waterSimulateParams, duration: duration.value });
+  }
+}
 onBeforeUnmount(() => {
   stopPlayback();
-  let delay = (3 / playbackRate.value) * 1000;
-
-  setTimeout(() => {
-    destoryWaterPrimitive();
-  }, delay);
+  destoryWaterPrimitive();
 });
-const { startSimulate, endSimulate } = inject("simulateActions");
-// 杩斿洖鎸夐挳鐐瑰嚮浜嬩欢
+const { endSimulate } = inject("simulateActions");
 function handleBack() {
-  ElMessage({
-    message: '妯℃嫙杩涚▼姝e湪鍏抽棴涓�...',
-    type: 'success',
-  })
+  ElMessage({ message: '妯℃嫙杩涚▼姝e湪鍏抽棴涓�...', type: 'success' }); // 鏄剧ず娑堟伅閫氱煡鐢ㄦ埛妯℃嫙杩涚▼姝e湪鍏抽棴
   endSimulate();
+  destoryWaterPrimitive();
   EventBus.emit("hide-schemeInfo");
 }
 </script>
-
 <style scoped>
 .timeline-container {
   display: flex;
@@ -395,7 +291,7 @@
 }
 
 .speed-menu div {
-  padding: 5px 10px;
+  /* padding: 5px 5px; */
   text-align: center;
 }
 
@@ -406,7 +302,7 @@
 }
 
 .timeline {
-  margin-top: 20px;
+  margin-top: 10px;
   position: relative;
   flex: 1;
 }
@@ -460,8 +356,16 @@
 }
 
 .time-marker {
+  margin-top: 5px;
   font-size: 12px;
   color: #fff;
-  transform: translateX(-50%);
+  transform: translateX(-20%);
+}
+
+.current-date {
+  margin-bottom: 5px;
+  font-size: 15px;
+  color: #fff;
+  transform: translateX(-3%);
 }
 </style>

--
Gitblit v1.9.3