WQQ 1 месяц назад
Родитель
Сommit
b3aa14c717

BIN
src/assets/images/culture.png


BIN
src/assets/images/home.png


BIN
src/assets/images/walk.png


BIN
src/assets/images/weather.png


BIN
src/assets/images/weatherTool.png


BIN
src/assets/images/导览.png


BIN
src/assets/video/TSQRoam.mp4


+ 1 - 1
src/components/HydrologyForecastPanel.vue

@@ -155,7 +155,7 @@
         </div>
         <div class="data-card">
         <div class="card-header" @click="toggleFlowForecast">
-          <h3 class="card-title">流量预报</h3>
+          <h3 class="card-title">黑林流量预报</h3>
           <div class="header-actions">
             <span class="toggle-btn">{{ flowForecastExpanded ? '▼' : '▶' }}</span>
           </div>

+ 261 - 0
src/components/SidebarButtons.vue

@@ -0,0 +1,261 @@
+<template>
+  <div class="sidebar-wrapper">
+    <div class="sidebar-buttons">
+      <button class="sidebar-btn" title="返回主视角" @click="handleClick('home')">
+        <img src="/src/assets/images/home.png" alt="首页" />
+      </button>
+      <button class="sidebar-btn" title="天气" @click="toggleWeatherPanel">
+        <img src="/src/assets/images/weather.png" alt="天气" />
+      </button>
+      <button class="sidebar-btn" title="导览" @click="playVideo">
+        <img src="/src/assets/images/walk.png" alt="导览" />
+      </button>
+    </div>
+    
+    <transition name="slide-left">
+      <div v-if="showWeatherPanel" class="weather-panel">
+        <div class="weather-content">
+          <button 
+            v-for="(weather, index) in weatherTypes" 
+            :key="weather.id"
+            class="weather-btn"
+            :title="weather.label"
+            @click="selectWeather(weather.id)"
+          >
+            <span class="weather-icon">{{ weather.icon }}</span>
+          </button>
+        </div>
+      </div>
+    </transition>
+
+    <teleport to="body">
+      <transition name="fade">
+        <div v-if="showVideo" class="video-modal" @click="closeVideo">
+          <div class="video-container" @click.stop>
+            <button class="close-btn" @click="closeVideo">×</button>
+            <video 
+              ref="videoPlayer"
+              class="video-player"
+              :src="videoSrc"
+              loop
+              muted
+              autoplay
+            ></video>
+          </div>
+        </div>
+      </transition>
+    </teleport>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'SidebarButtons',
+  emits: ['button-click'],
+  data() {
+    return {
+      showWeatherPanel: false,
+      showVideo: false,
+      videoSrc: '/src/assets/video/TSQRoam.mp4',
+      weatherTypes: [
+        { id: 'sunny', label: '晴朗', icon: '☀️' },
+        { id: 'cloudy', label: '阴天', icon: '☁️' },
+        { id: 'rainy', label: '下雨', icon: '🌧️' },
+        { id: 'snowy', label: '下雪', icon: '❄️' }
+      ]
+    }
+  },
+  methods: {
+    handleClick(type) {
+      this.$emit('button-click', type)
+    },
+    toggleWeatherPanel() {
+      this.showWeatherPanel = !this.showWeatherPanel
+    },
+    selectWeather(weatherId) {
+      this.$emit('button-click', { type: 'weather', value: weatherId })
+    },
+    playVideo() {
+      this.showVideo = true
+      this.showWeatherPanel = false
+      this.$nextTick(() => {
+        if (this.$refs.videoPlayer) {
+          this.$refs.videoPlayer.play()
+        }
+      })
+    },
+    closeVideo() {
+      this.showVideo = false
+      if (this.$refs.videoPlayer) {
+        this.$refs.videoPlayer.pause()
+        this.$refs.videoPlayer.currentTime = 0
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.sidebar-wrapper {
+  position: absolute;
+  left: -55px;
+  top: 0;
+  display: flex;
+  flex-direction: row;
+  gap: 0;
+  z-index: 100;
+}
+
+.sidebar-buttons {
+  display: flex;
+  flex-direction: column;
+  gap: 4px;
+}
+
+.sidebar-btn {
+  width: 60px;
+  height: 60px;
+  border: none;
+  background: transparent;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  transition: all 0.3s ease;
+  outline: none;
+  padding: 0;
+}
+
+.sidebar-btn:focus {
+  outline: none;
+  box-shadow: none;
+}
+
+.sidebar-btn:hover {
+  opacity: 0.8;
+}
+
+.sidebar-btn img {
+  width: 44px;
+  height: 44px;
+  object-fit: contain;
+}
+
+.weather-panel {
+  position: absolute;
+  left: -200px;
+  top: 64px;
+  display: flex;
+  align-items: center;
+}
+
+.weather-content {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  background: rgba(0, 60, 120, 0.5);
+  border-radius: 8px;
+  padding: 8px 12px;
+  gap: 0;
+}
+
+.weather-btn {
+  width: 44px;
+  height: 44px;
+  border: none;
+  background: transparent;
+  border-right: 1px solid rgba(0, 212, 255, 0.3);
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  transition: all 0.3s ease;
+  outline: none;
+  padding: 0;
+}
+
+.weather-btn:last-child {
+  border-right: none;
+}
+
+.weather-btn:hover {
+  background: rgba(0, 212, 255, 0.2);
+}
+
+.weather-icon {
+  font-size: 24px;
+  line-height: 1;
+}
+
+.video-modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  z-index: 9999;
+  background: rgba(0, 0, 0, 0.7);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.video-container {
+  position: relative;
+  width: 80%;
+  max-width: 1200px;
+  aspect-ratio: 16 / 9;
+  background: #000;
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+.video-player {
+  width: 100%;
+  height: 100%;
+  object-fit: contain;
+}
+
+.close-btn {
+  position: absolute;
+  top: 10px;
+  right: 10px;
+  width: 32px;
+  height: 32px;
+  border: none;
+  background: rgba(0, 0, 0, 0.5);
+  color: #fff;
+  font-size: 18px;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 50%;
+  z-index: 10;
+}
+
+.close-btn:hover {
+  background: rgba(255, 0, 0, 0.7);
+}
+
+.slide-left-enter-active,
+.slide-left-leave-active {
+  transition: all 0.3s ease;
+}
+
+.slide-left-enter-from,
+.slide-left-leave-to {
+  opacity: 0;
+  transform: translateX(-20px);
+}
+
+.fade-enter-active,
+.fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+
+.fade-enter-from,
+.fade-leave-to {
+  opacity: 0;
+}
+</style>

+ 53 - 9
src/views/HeilinStationView.vue

@@ -113,12 +113,18 @@
       <div class="right-sidebar">
         <!-- 右侧数据框容器 -->
         <div class="right-container">
+          <!-- 侧边栏小按钮 -->
+          <SidebarButtons />
+          
           <!-- 右侧面板 1:监测数据 -->
           <div class="data-card data-card-1">
-            <div class="panel-header">
+            <div class="panel-header" @click="toggleMonitoringData">
               <h3>监测数据</h3>
+              <div class="header-actions">
+                <span class="toggle-btn">{{ monitoringDataExpanded ? '▼' : '▶' }}</span>
+              </div>
             </div>
-            <div class="panel-content">
+            <div v-show="monitoringDataExpanded" class="panel-content">
               <!-- 第一行:水位卡片 -->
               <div class="water-level-cards">
                 <div class="water-card">
@@ -166,10 +172,13 @@
           
           <!-- 右侧面板 2:蒸发量过程线 -->
           <div class="data-card data-card-2">
-            <div class="panel-header">
+            <div class="panel-header" @click="toggleEvaporationData">
               <h3>蒸发量过程线</h3>
+              <div class="header-actions">
+                <span class="toggle-btn">{{ evaporationDataExpanded ? '▼' : '▶' }}</span>
+              </div>
             </div>
-            <div class="panel-content">
+            <div v-show="evaporationDataExpanded" class="panel-content">
               <!-- 蒸发量数据卡片 -->
               <div class="water-level-cards">
                 <div class="water-card">
@@ -198,10 +207,13 @@
           
           <!-- 右侧面板 3:土壤含水量过程线 -->
           <div class="data-card data-card-3">
-            <div class="panel-header">
+            <div class="panel-header" @click="toggleSoilMoisture">
               <h3>土壤含水量过程线</h3>
+              <div class="header-actions">
+                <span class="toggle-btn">{{ soilMoistureExpanded ? '▼' : '▶' }}</span>
+              </div>
             </div>
-            <div class="panel-content">
+            <div v-show="soilMoistureExpanded" class="panel-content">
               <!-- 土壤含水量数据卡片 -->
               <div class="water-level-cards">
                 <div class="water-card">
@@ -371,6 +383,7 @@
 import { ref, onMounted } from 'vue'
 import { useRouter } from 'vue-router'
 import GradientOverlay from '../components/gradient-overlay.vue'
+import SidebarButtons from '../components/SidebarButtons.vue'
 import * as echarts from 'echarts'
 
 const router = useRouter()
@@ -382,6 +395,22 @@ const combinedChart = ref(null)
 const evaporationChart = ref(null)
 const soilMoistureChart = ref(null)
 
+const monitoringDataExpanded = ref(true)
+const evaporationDataExpanded = ref(true)
+const soilMoistureExpanded = ref(true)
+
+const toggleMonitoringData = () => {
+  monitoringDataExpanded.value = !monitoringDataExpanded.value
+}
+
+const toggleEvaporationData = () => {
+  evaporationDataExpanded.value = !evaporationDataExpanded.value
+}
+
+const toggleSoilMoisture = () => {
+  soilMoistureExpanded.value = !soilMoistureExpanded.value
+}
+
 const goBack = () => {
   router.push('/')
 }
@@ -912,6 +941,7 @@ onMounted(() => {
   width: 400px;
   display: flex;
   flex-direction: column;
+  z-index: 100;
 }
 
 .data-card {
@@ -949,6 +979,19 @@ onMounted(() => {
   line-height: 1;
   width: 100%;
   color: #ffffff;
+  background: transparent;
+}
+
+.header-actions {
+  display: flex;
+  align-items: center;
+}
+
+.toggle-btn {
+  color: #e0fcff;
+  font-size: 12px;
+  cursor: pointer;
+  padding: 5px;
 }
 
 .station-intro {
@@ -1552,18 +1595,19 @@ onMounted(() => {
   display: flex;
   flex-direction: column;
   gap: 10px;
+  position: relative;
 }
 
 /* 右侧数据框高度 */
 .data-card-1 {
-  min-height: 380px;
+  min-height: 50px;
 }
 
 .data-card-2 {
-  min-height: 290px;
+  min-height: 50px;
 }
 
 .data-card-3 {
-  min-height: 320px;
+  min-height: 50px;
 }
 </style>

+ 0 - 7
src/views/HomeView.vue

@@ -39,13 +39,6 @@
     >
       水资源
     </div>
-    <div 
-      class="sub-title right-2" 
-      :class="{ active: activeTab === '孪生水文站' }"
-      @click="selectTab('孪生水文站')"
-    >
-      孪生水文站
-    </div>
     
     <!-- 流域总览视图 -->
     <OverviewView v-if="activeTab === '流域总览'" @selectTab="selectTab" />

+ 22 - 0
src/views/OverviewView.vue

@@ -185,6 +185,18 @@
           </div>
         </div>
       </div>
+      
+      <!-- 监控视频卡片 -->
+      <div class="data-card mt-20">
+        <div class="card-header">
+          <h3 class="card-title">监控视频</h3>
+        </div>
+        <div class="card-body">
+          <div class="video-preview">
+            <img src="/src/assets/images/Heilin/图1.jpeg" alt="监控视频" />
+          </div>
+        </div>
+      </div>
     </div>
     
     <!-- 底部数据栏 -->
@@ -1924,4 +1936,14 @@ export default {
   margin-bottom: 4px;
   text-align: center;
 }
+
+.video-preview {
+  width: 100%;
+}
+
+.video-preview img {
+  width: 100%;
+  height: auto;
+  border-radius: 4px;
+}
 </style>