浏览代码

修改研学联建

BAI 2 周之前
父节点
当前提交
a2926c062b

二进制
src/assets/images/image.png


+ 1 - 0
src/components/mCard/index.vue

@@ -506,6 +506,7 @@ onMounted(() => {
       min-height: 64px;
       pointer-events: all;
       overflow: hidden;
+      height: calc(100% - 36px);
     }
   }
 }

+ 294 - 62
src/views/study/components/StudyBase.vue

@@ -1,81 +1,313 @@
 <template>
-  <div class="study-base">
-    <div class="m-card">
-      <div class="m-card-hd">
-        <div class="title">示范基地全景</div>
+  <m-card title="示范基地全景" :width="398" :height="450">
+    <div class="study-base">
+      <div class="core-indicator">
+        <div class="indicator-main">
+          <span class="main-value">30000</span>
+          <span class="main-unit">㎡</span>
+        </div>
+        <div class="indicator-label">基地占地面积</div>
       </div>
-      <div class="m-card-bd">
-        <div class="base-panorama">
-          <img src="@/assets/images/昆山水文站.jpg" alt="昆山水文站全景" class="panorama-image">
-          <div class="panorama-info">
-            <h3>昆山水文站示范基地</h3>
-            <p>占地面积:10000平方米</p>
-            <p>建设时间:2023年</p>
-            <p>功能定位:水文监测、研学教育、科普展示</p>
+      <div class="stats-grid">
+        <div class="stat-item">
+          <div class="stat-value">50+</div>
+          <div class="stat-label">研学课程</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">20+</div>
+          <div class="stat-label">合作学校</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">1200+</div>
+          <div class="stat-label">参与学生</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">2023</div>
+          <div class="stat-label">建设年份</div>
+        </div>
+      </div>
+      <div class="architecture-flow">
+        <div class="architecture-title">功能区域</div>
+        <div class="architecture-tabs">
+          <div class="tab-item" :class="{ active: activeTab === 0 }" @click="switchTab(0)">技术实践区</div>
+          <div class="tab-item" :class="{ active: activeTab === 1 }" @click="switchTab(1)">技术研发区</div>
+          <div class="tab-item" :class="{ active: activeTab === 2 }" @click="switchTab(2)">沉浸体验区</div>
+        </div>
+        <div class="tab-content">
+          <div v-if="activeTab === 0">
+            <p>配备先进的水文监测设备和实践设施,提供 hands-on 实践体验,培养学生的实际操作能力。</p>
+          </div>
+          <div v-else-if="activeTab === 1">
+            <p>集合水文领域的前沿技术和设备,开展水文监测新技术、新方法的研发与测试。</p>
+          </div>
+          <div v-else-if="activeTab === 2">
+            <p>通过 VR/AR 技术,沉浸式体验水文监测过程,增强学习趣味性和互动性。</p>
           </div>
         </div>
+        <div class="architecture-title">产学研协同</div>
+        <div class="collaboration-flow">
+          <div class="arch-node">
+            <div class="node-icon">🔍</div>
+            <div class="node-label">需求调研</div>
+          </div>
+          <div class="arch-arrow">→</div>
+          <div class="arch-node">
+            <div class="node-icon">🔬</div>
+            <div class="node-label">联合实验室</div>
+          </div>
+          <div class="arch-arrow">→</div>
+          <div class="arch-node">
+            <div class="node-icon">🚀</div>
+            <div class="node-label">技术产品化</div>
+          </div>
+          <div class="arch-arrow">→</div>
+          <div class="arch-node">
+            <div class="node-icon">💼</div>
+            <div class="node-label">企业应用</div>
+          </div>
+        </div>
+      </div>
+      <div class="action-buttons">
+        <button class="action-btn primary">
+          <span>🏫</span> 查看基地详情
+        </button>
       </div>
     </div>
-  </div>
+  </m-card>
 </template>
 
 <script setup>
+import { ref, inject } from 'vue'
+import mCard from "@/components/mCard/index.vue"
+import emitter from "@/utils/emitter"
 
+const activeTab = ref(1)
+
+function switchTab(index) {
+  activeTab.value = index
+  // 当点击技术实践区时,切换背景图
+  if (index === 0) {
+    emitter.$emit('switchStudyBgImage', 'practice')
+  } else {
+    emitter.$emit('switchStudyBgImage', 'default')
+  }
+}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 .study-base {
+  padding: 12px;
   height: 100%;
-  .m-card {
-    height: 100%;
-    display: flex;
-    flex-direction: column;
-    .m-card-hd {
-      padding: 15px 20px;
-      border-bottom: 1px solid rgba(48, 220, 255, 0.3);
-      .title {
-        font-size: 18px;
-        font-weight: bold;
-        color: #30dcfd;
-      }
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  box-sizing: border-box;
+  overflow-y: auto;
+  &::-webkit-scrollbar {
+    width: 6px;
+  }
+  &::-webkit-scrollbar-track {
+    background: rgba(0, 40, 80, 0.6);
+    border-radius: 3px;
+  }
+  &::-webkit-scrollbar-thumb {
+    background: rgba(48, 220, 255, 0.5);
+    border-radius: 3px;
+  }
+  &::-webkit-scrollbar-thumb:hover {
+    background: rgba(48, 220, 255, 0.8);
+  }
+}
+
+.core-indicator {
+  text-align: center;
+  padding: 12px;
+  background: linear-gradient(135deg, rgba(48, 220, 255, 0.1) 0%, rgba(0, 191, 255, 0.05) 100%);
+  border-radius: 8px;
+  border: 1px solid rgba(48, 220, 255, 0.3);
+}
+
+.indicator-main {
+  margin-bottom: 5px;
+}
+
+.main-value {
+  font-size: 40px;
+  font-weight: 700;
+  color: #30DCFF;
+  font-family: "D-DIN";
+  text-shadow: 0 0 20px rgba(48, 220, 255, 0.5);
+}
+
+.main-unit {
+  font-size: 20px;
+  color: rgba(48, 220, 255, 0.8);
+  font-weight: 600;
+}
+
+.indicator-label {
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 12px;
+  letter-spacing: 1px;
+}
+
+.stats-grid {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  gap: 6px;
+}
+
+.stat-item {
+  background: rgba(0, 180, 255, 0.08);
+  border: 1px solid rgba(0, 180, 255, 0.2);
+  border-radius: 4px;
+  padding: 6px 4px;
+  text-align: center;
+  transition: all 0.3s ease;
+  &:hover {
+    background: rgba(0, 180, 255, 0.15);
+    border-color: rgba(48, 220, 255, 0.5);
+  }
+}
+
+.stat-value {
+  font-size: 16px;
+  font-weight: 700;
+  color: #30DCFF;
+  font-family: "D-DIN";
+  margin-bottom: 2px;
+}
+
+.stat-label {
+  font-size: 9px;
+  color: rgba(255, 255, 255, 0.6);
+  line-height: 1.2;
+}
+
+.architecture-flow {
+  flex: 1;
+  background: rgba(0, 180, 255, 0.05);
+  border-radius: 6px;
+  padding: 8px;
+  display: flex;
+  flex-direction: column;
+  gap: 6px;
+}
+
+.architecture-title {
+  font-size: 11px;
+  color: #30DCFF;
+  font-weight: 600;
+  padding-bottom: 4px;
+  border-bottom: 1px solid rgba(48, 220, 255, 0.2);
+}
+
+.architecture-tabs {
+  display: flex;
+  gap: 4px;
+  margin: 4px 0;
+  .tab-item {
+    flex: 1;
+    padding: 6px 0;
+    text-align: center;
+    font-size: 10px;
+    background: rgba(0, 40, 80, 0.6);
+    border: 1px solid rgba(48, 220, 255, 0.2);
+    border-radius: 4px;
+    color: rgba(255, 255, 255, 0.7);
+    cursor: pointer;
+    transition: all 0.3s ease;
+    &.active {
+      background: linear-gradient(135deg, #30DCFF, #00BFFF);
+      color: white;
+      border-color: #30DCFF;
+    }
+  }
+}
+
+.tab-content {
+  padding: 8px;
+  background: rgba(0, 40, 80, 0.4);
+  border-radius: 4px;
+  border: 1px solid rgba(48, 220, 255, 0.2);
+  p {
+    font-size: 11px;
+    color: rgba(255, 255, 255, 0.8);
+    line-height: 1.4;
+    margin: 0;
+    text-align: center;
+  }
+}
+
+.collaboration-flow {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 4px;
+  padding: 6px 0;
+  flex-wrap: wrap;
+}
+
+.arch-node {
+  background: rgba(48, 220, 255, 0.15);
+  border: 1px solid rgba(48, 220, 255, 0.4);
+  border-radius: 6px;
+  padding: 6px 4px;
+  text-align: center;
+  min-width: 60px;
+}
+
+.node-icon {
+  font-size: 14px;
+  margin-bottom: 2px;
+}
+
+.node-label {
+  font-size: 8px;
+  color: rgba(255, 255, 255, 0.9);
+}
+
+.arch-arrow {
+  color: #30DCFF;
+  font-size: 12px;
+  font-weight: bold;
+}
+
+.action-buttons {
+  display: flex;
+  gap: 10px;
+}
+
+.action-btn {
+  flex: 1;
+  padding: 10px 12px;
+  border-radius: 6px;
+  border: none;
+  cursor: pointer;
+  font-size: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 5px;
+  transition: all 0.3s ease;
+  &.primary {
+    background: linear-gradient(135deg, #30DCFF, #00BFFF);
+    color: #fff;
+    &:hover {
+      box-shadow: 0 0 15px rgba(48, 220, 255, 0.5);
+      transform: translateY(-2px);
     }
-    .m-card-bd {
-      flex: 1;
-      padding: 20px;
-      display: flex;
-      flex-direction: column;
-      justify-content: center;
-      .base-panorama {
-        position: relative;
-        width: 100%;
-        height: 280px;
-        border-radius: 8px;
-        overflow: hidden;
-        .panorama-image {
-          width: 100%;
-          height: 100%;
-          object-fit: cover;
-        }
-        .panorama-info {
-          position: absolute;
-          bottom: 0;
-          left: 0;
-          right: 0;
-          background: linear-gradient(transparent, rgba(0, 20, 40, 0.9));
-          padding: 15px;
-          color: white;
-          h3 {
-            font-size: 16px;
-            margin-bottom: 10px;
-          }
-          p {
-            font-size: 12px;
-            margin-bottom: 5px;
-            opacity: 0.8;
-          }
-        }
-      }
+  }
+  &.secondary {
+    background: rgba(48, 220, 255, 0.15);
+    border: 1px solid rgba(48, 220, 255, 0.4);
+    color: #30DCFF;
+    &:hover {
+      background: rgba(48, 220, 255, 0.25);
     }
   }
+  span {
+    font-size: 14px;
+  }
 }
 </style>

+ 226 - 116
src/views/study/components/StudyEffect.vue

@@ -1,139 +1,249 @@
 <template>
-  <div class="study-effect">
-    <div class="m-card">
-      <div class="m-card-hd">
-        <div class="title">研学成效数据</div>
+  <m-card title="研学成效数据" :width="398" :height="450">
+    <div class="study-effect">
+      <div class="core-indicator">
+        <div class="indicator-main">
+          <span class="main-value">1200+</span>
+          <span class="main-unit">人</span>
+        </div>
+        <div class="indicator-label">累计参与学生</div>
       </div>
-      <div class="m-card-bd">
-        <div class="effect-content">
-          <div class="effect-item">
-            <div class="item-value">1200+</div>
-            <div class="item-label">参与学生</div>
+      <div class="stats-grid">
+        <div class="stat-item">
+          <div class="stat-value">50+</div>
+          <div class="stat-label">研学课程</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">20+</div>
+          <div class="stat-label">合作学校</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">98%</div>
+          <div class="stat-label">满意度</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">15</div>
+          <div class="stat-label">合作机构</div>
+        </div>
+      </div>
+      <div class="chart-section">
+        <div class="chart-title">近一年研学活动趋势</div>
+        <div class="chart-content">
+          <div class="chart-bar">
+            <div class="bar" style="height: 30%"></div>
+            <div class="bar-label">1月</div>
           </div>
-          <div class="effect-item">
-            <div class="item-value">50+</div>
-            <div class="item-label">研学课程</div>
+          <div class="chart-bar">
+            <div class="bar" style="height: 45%"></div>
+            <div class="bar-label">3月</div>
           </div>
-          <div class="effect-item">
-            <div class="item-value">20+</div>
-            <div class="item-label">合作学校</div>
+          <div class="chart-bar">
+            <div class="bar" style="height: 80%"></div>
+            <div class="bar-label">6月</div>
           </div>
-          <div class="effect-item">
-            <div class="item-value">98%</div>
-            <div class="item-label">满意度</div>
+          <div class="chart-bar">
+            <div class="bar" style="height: 60%"></div>
+            <div class="bar-label">9月</div>
           </div>
-        </div>
-        <div class="effect-chart">
-          <div class="chart-title">近一年研学活动趋势</div>
-          <div class="chart-content">
-            <div class="chart-bar">
-              <div class="bar" style="height: 30%"></div>
-              <div class="bar-label">1月</div>
-            </div>
-            <div class="chart-bar">
-              <div class="bar" style="height: 45%"></div>
-              <div class="bar-label">3月</div>
-            </div>
-            <div class="chart-bar">
-              <div class="bar" style="height: 80%"></div>
-              <div class="bar-label">6月</div>
-            </div>
-            <div class="chart-bar">
-              <div class="bar" style="height: 60%"></div>
-              <div class="bar-label">9月</div>
-            </div>
-            <div class="chart-bar">
-              <div class="bar" style="height: 95%"></div>
-              <div class="bar-label">12月</div>
-            </div>
+          <div class="chart-bar">
+            <div class="bar" style="height: 95%"></div>
+            <div class="bar-label">12月</div>
           </div>
         </div>
       </div>
+      <div class="action-buttons">
+        <button class="action-btn primary">
+          <span>📊</span> 查看详细数据
+        </button>
+        <button class="action-btn secondary">
+          <span>📈</span> 下载报告
+        </button>
+      </div>
     </div>
-  </div>
+  </m-card>
 </template>
 
 <script setup>
+import mCard from "@/components/mCard/index.vue"
 
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 .study-effect {
+  padding: 12px;
   height: 100%;
-  .m-card {
-    height: 100%;
-    display: flex;
-    flex-direction: column;
-    .m-card-hd {
-      padding: 15px 20px;
-      border-bottom: 1px solid rgba(48, 220, 255, 0.3);
-      .title {
-        font-size: 18px;
-        font-weight: bold;
-        color: #30dcfd;
-      }
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  box-sizing: border-box;
+  overflow-y: auto;
+  &::-webkit-scrollbar {
+    width: 6px;
+  }
+  &::-webkit-scrollbar-track {
+    background: rgba(0, 40, 80, 0.6);
+    border-radius: 3px;
+  }
+  &::-webkit-scrollbar-thumb {
+    background: rgba(48, 220, 255, 0.5);
+    border-radius: 3px;
+  }
+  &::-webkit-scrollbar-thumb:hover {
+    background: rgba(48, 220, 255, 0.8);
+  }
+  .chart-section {
+    flex: 0 1 auto;
+    min-height: 0;
+  }
+}
+
+.core-indicator {
+  text-align: center;
+  padding: 12px;
+  background: linear-gradient(135deg, rgba(48, 220, 255, 0.1) 0%, rgba(0, 191, 255, 0.05) 100%);
+  border-radius: 8px;
+  border: 1px solid rgba(48, 220, 255, 0.3);
+}
+
+.indicator-main {
+  margin-bottom: 5px;
+}
+
+.main-value {
+  font-size: 40px;
+  font-weight: 700;
+  color: #30DCFF;
+  font-family: "D-DIN";
+  text-shadow: 0 0 20px rgba(48, 220, 255, 0.5);
+}
+
+.main-unit {
+  font-size: 20px;
+  color: rgba(48, 220, 255, 0.8);
+  font-weight: 600;
+}
+
+.indicator-label {
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 12px;
+  letter-spacing: 1px;
+}
+
+.stats-grid {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  gap: 6px;
+}
+
+.stat-item {
+  background: rgba(0, 180, 255, 0.08);
+  border: 1px solid rgba(0, 180, 255, 0.2);
+  border-radius: 4px;
+  padding: 6px 4px;
+  text-align: center;
+  transition: all 0.3s ease;
+  &:hover {
+    background: rgba(0, 180, 255, 0.15);
+    border-color: rgba(48, 220, 255, 0.5);
+  }
+}
+
+.stat-value {
+  font-size: 16px;
+  font-weight: 700;
+  color: #30DCFF;
+  font-family: "D-DIN";
+  margin-bottom: 2px;
+}
+
+.stat-label {
+  font-size: 9px;
+  color: rgba(255, 255, 255, 0.6);
+  line-height: 1.2;
+}
+
+.chart-section {
+  flex: 1;
+  background: rgba(0, 180, 255, 0.05);
+  border-radius: 6px;
+  padding: 8px;
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.chart-title {
+  font-size: 11px;
+  color: #30DCFF;
+  font-weight: 600;
+  padding-bottom: 4px;
+  border-bottom: 1px solid rgba(48, 220, 255, 0.2);
+}
+
+.chart-content {
+  flex: 1;
+  padding: 16px;
+  display: flex;
+  align-items: flex-end;
+  justify-content: space-around;
+  height: 120px;
+}
+
+.chart-bar {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 5px;
+}
+
+.bar {
+  width: 20px;
+  background: linear-gradient(to top, #30DCFF, rgba(48, 220, 255, 0.3));
+  border-radius: 4px 4px 0 0;
+  transition: height 1s ease;
+  box-shadow: 0 0 10px rgba(48, 220, 255, 0.3);
+}
+
+.bar-label {
+  font-size: 10px;
+  color: rgba(255, 255, 255, 0.6);
+}
+
+.action-buttons {
+  display: flex;
+  gap: 10px;
+}
+
+.action-btn {
+  flex: 1;
+  padding: 10px 12px;
+  border-radius: 6px;
+  border: none;
+  cursor: pointer;
+  font-size: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 5px;
+  transition: all 0.3s ease;
+  &.primary {
+    background: linear-gradient(135deg, #30DCFF, #00BFFF);
+    color: #fff;
+    &:hover {
+      box-shadow: 0 0 15px rgba(48, 220, 255, 0.5);
+      transform: translateY(-2px);
     }
-    .m-card-bd {
-      flex: 1;
-      padding: 20px;
-      display: flex;
-      flex-direction: column;
-      justify-content: space-between;
-      .effect-content {
-        display: grid;
-        grid-template-columns: 1fr 1fr;
-        gap: 15px;
-        margin-bottom: 20px;
-        .effect-item {
-          background: rgba(0, 20, 40, 0.5);
-          border: 1px solid rgba(48, 220, 255, 0.2);
-          border-radius: 8px;
-          padding: 15px;
-          text-align: center;
-          .item-value {
-            font-size: 24px;
-            font-weight: bold;
-            color: #30dcfd;
-            margin-bottom: 5px;
-          }
-          .item-label {
-            font-size: 12px;
-            color: rgba(255, 255, 255, 0.8);
-          }
-        }
-      }
-      .effect-chart {
-        flex: 1;
-        .chart-title {
-          font-size: 14px;
-          font-weight: bold;
-          color: white;
-          margin-bottom: 15px;
-        }
-        .chart-content {
-          display: flex;
-          align-items: flex-end;
-          justify-content: space-around;
-          height: 120px;
-          .chart-bar {
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            gap: 5px;
-            .bar {
-              width: 20px;
-              background: linear-gradient(to top, #30dcfd, rgba(48, 220, 255, 0.3));
-              border-radius: 4px 4px 0 0;
-              transition: height 1s ease;
-            }
-            .bar-label {
-              font-size: 10px;
-              color: rgba(255, 255, 255, 0.6);
-            }
-          }
-        }
-      }
+  }
+  &.secondary {
+    background: rgba(48, 220, 255, 0.15);
+    border: 1px solid rgba(48, 220, 255, 0.4);
+    color: #30DCFF;
+    &:hover {
+      background: rgba(48, 220, 255, 0.25);
     }
   }
+  span {
+    font-size: 14px;
+  }
 }
 </style>

+ 262 - 78
src/views/study/components/StudyIntegration.vue

@@ -1,102 +1,286 @@
 <template>
-  <div class="study-integration">
-    <div class="m-card">
-      <div class="m-card-hd">
-        <div class="title">研学机制融合</div>
+  <m-card title="研学机制融合" :width="398" :height="450">
+    <div class="study-integration">
+      <div class="core-indicator">
+        <div class="indicator-main">
+          <span class="main-value">98</span>
+          <span class="main-unit">%</span>
+        </div>
+        <div class="indicator-label">课程满意度</div>
       </div>
-      <div class="m-card-bd">
-        <div class="integration-content">
-          <div class="integration-item">
-            <div class="item-icon">1</div>
-            <div class="item-content">
-              <h4>理论与实践结合</h4>
-              <p>将水文理论知识与实际监测操作相结合,通过实地观测、数据采集等实践活动,加深对水文知识的理解。</p>
+      <div class="stats-grid">
+        <div class="stat-item">
+          <div class="stat-value">3</div>
+          <div class="stat-label">融合维度</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">50+</div>
+          <div class="stat-label">课程数量</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">15</div>
+          <div class="stat-label">合作机构</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">95</div>
+          <div class="stat-label">实践占比</div>
+        </div>
+      </div>
+      <div class="integration-flow">
+        <div class="integration-title">融合机制</div>
+        <div class="flow-items">
+          <div class="flow-item">
+            <div class="flow-number">1</div>
+            <div class="flow-content">
+              <div class="flow-title">理论与实践结合</div>
+              <div class="flow-description">将水文理论知识与实际监测操作相结合,通过实地观测、数据采集等实践活动,加深对水文知识的理解。</div>
             </div>
           </div>
-          <div class="integration-item">
-            <div class="item-icon">2</div>
-            <div class="item-content">
-              <h4>多学科融合</h4>
-              <p>融合水文、地理、环境、信息技术等多学科知识,构建完整的研学课程体系,培养综合能力。</p>
+          <div class="flow-arrow"></div>
+          <div class="flow-item">
+            <div class="flow-number">2</div>
+            <div class="flow-content">
+              <div class="flow-title">多学科融合</div>
+              <div class="flow-description">融合水文、地理、环境、信息技术等多学科知识,构建完整的研学课程体系,培养综合能力。</div>
             </div>
           </div>
-          <div class="integration-item">
-            <div class="item-icon">3</div>
-            <div class="item-content">
-              <h4>产学研合作</h4>
-              <p>与高校、科研机构、企业建立合作关系,提供专业指导和技术支持,提升研学质量。</p>
+          <div class="flow-arrow"></div>
+          <div class="flow-item">
+            <div class="flow-number">3</div>
+            <div class="flow-content">
+              <div class="flow-title">产学研合作</div>
+              <div class="flow-description">与高校、科研机构、企业建立合作关系,提供专业指导和技术支持,提升研学质量。</div>
             </div>
           </div>
         </div>
       </div>
+      <div class="action-buttons">
+        <button class="action-btn primary">
+          <span>📚</span> 查看课程体系
+        </button>
+        <button class="action-btn secondary">
+          <span>🤝</span> 合作申请
+        </button>
+      </div>
     </div>
-  </div>
+  </m-card>
 </template>
 
 <script setup>
+import mCard from "@/components/mCard/index.vue"
 
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 .study-integration {
+  padding: 12px;
   height: 100%;
-  .m-card {
-    height: 100%;
-    display: flex;
-    flex-direction: column;
-    .m-card-hd {
-      padding: 15px 20px;
-      border-bottom: 1px solid rgba(48, 220, 255, 0.3);
-      .title {
-        font-size: 18px;
-        font-weight: bold;
-        color: #30dcfd;
-      }
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  box-sizing: border-box;
+  overflow-y: auto;
+  &::-webkit-scrollbar {
+    width: 6px;
+  }
+  &::-webkit-scrollbar-track {
+    background: rgba(0, 40, 80, 0.6);
+    border-radius: 3px;
+  }
+  &::-webkit-scrollbar-thumb {
+    background: rgba(48, 220, 255, 0.5);
+    border-radius: 3px;
+  }
+  &::-webkit-scrollbar-thumb:hover {
+    background: rgba(48, 220, 255, 0.8);
+  }
+}
+
+.core-indicator {
+  text-align: center;
+  padding: 12px;
+  background: linear-gradient(135deg, rgba(48, 220, 255, 0.1) 0%, rgba(0, 191, 255, 0.05) 100%);
+  border-radius: 8px;
+  border: 1px solid rgba(48, 220, 255, 0.3);
+}
+
+.indicator-main {
+  margin-bottom: 5px;
+}
+
+.main-value {
+  font-size: 40px;
+  font-weight: 700;
+  color: #30DCFF;
+  font-family: "D-DIN";
+  text-shadow: 0 0 20px rgba(48, 220, 255, 0.5);
+}
+
+.main-unit {
+  font-size: 20px;
+  color: rgba(48, 220, 255, 0.8);
+  font-weight: 600;
+}
+
+.indicator-label {
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 12px;
+  letter-spacing: 1px;
+}
+
+.stats-grid {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  gap: 6px;
+}
+
+.stat-item {
+  background: rgba(0, 180, 255, 0.08);
+  border: 1px solid rgba(0, 180, 255, 0.2);
+  border-radius: 4px;
+  padding: 6px 4px;
+  text-align: center;
+  transition: all 0.3s ease;
+  &:hover {
+    background: rgba(0, 180, 255, 0.15);
+    border-color: rgba(48, 220, 255, 0.5);
+  }
+}
+
+.stat-value {
+  font-size: 16px;
+  font-weight: 700;
+  color: #30DCFF;
+  font-family: "D-DIN";
+  margin-bottom: 2px;
+}
+
+.stat-label {
+  font-size: 9px;
+  color: rgba(255, 255, 255, 0.6);
+  line-height: 1.2;
+}
+
+.integration-flow {
+  flex: 1;
+  background: rgba(0, 180, 255, 0.05);
+  border-radius: 6px;
+  padding: 8px;
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.integration-title {
+  font-size: 11px;
+  color: #30DCFF;
+  font-weight: 600;
+  padding-bottom: 4px;
+  border-bottom: 1px solid rgba(48, 220, 255, 0.2);
+}
+
+.flow-items {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+  flex: 1;
+  overflow-y: auto;
+  padding-right: 4px;
+}
+
+.flow-item {
+  display: flex;
+  gap: 8px;
+  background: rgba(0, 40, 80, 0.4);
+  border: 1px solid rgba(48, 220, 255, 0.2);
+  border-radius: 6px;
+  padding: 8px;
+  align-items: flex-start;
+}
+
+.flow-number {
+  width: 24px;
+  height: 24px;
+  border-radius: 50%;
+  background: linear-gradient(135deg, #30DCFF, #00BFFF);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 12px;
+  font-weight: 700;
+  color: white;
+  flex-shrink: 0;
+  box-shadow: 0 0 10px rgba(48, 220, 255, 0.4);
+}
+
+.flow-content {
+  flex: 1;
+}
+
+.flow-title {
+  font-size: 12px;
+  font-weight: 600;
+  color: #30DCFF;
+  margin-bottom: 4px;
+}
+
+.flow-description {
+  font-size: 10px;
+  color: rgba(255, 255, 255, 0.8);
+  line-height: 1.4;
+}
+
+.flow-arrow {
+  height: 12px;
+  width: 100%;
+  position: relative;
+  &::after {
+    content: '';
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    border-left: 8px solid transparent;
+    border-right: 8px solid transparent;
+    border-top: 8px solid rgba(48, 220, 255, 0.3);
+  }
+}
+
+.action-buttons {
+  display: flex;
+  gap: 10px;
+}
+
+.action-btn {
+  flex: 1;
+  padding: 10px 12px;
+  border-radius: 6px;
+  border: none;
+  cursor: pointer;
+  font-size: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 5px;
+  transition: all 0.3s ease;
+  &.primary {
+    background: linear-gradient(135deg, #30DCFF, #00BFFF);
+    color: #fff;
+    &:hover {
+      box-shadow: 0 0 15px rgba(48, 220, 255, 0.5);
+      transform: translateY(-2px);
     }
-    .m-card-bd {
-      flex: 1;
-      padding: 20px;
-      display: flex;
-      flex-direction: column;
-      justify-content: space-between;
-      .integration-content {
-        display: flex;
-        flex-direction: column;
-        gap: 15px;
-        .integration-item {
-          display: flex;
-          gap: 15px;
-          .item-icon {
-            width: 30px;
-            height: 30px;
-            border-radius: 50%;
-            background: rgba(48, 220, 255, 0.2);
-            border: 1px solid rgba(48, 220, 255, 0.5);
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            font-size: 14px;
-            font-weight: bold;
-            color: #30dcfd;
-            flex-shrink: 0;
-          }
-          .item-content {
-            flex: 1;
-            h4 {
-              font-size: 14px;
-              font-weight: bold;
-              color: white;
-              margin-bottom: 5px;
-            }
-            p {
-              font-size: 12px;
-              color: rgba(255, 255, 255, 0.8);
-              line-height: 1.4;
-            }
-          }
-        }
-      }
+  }
+  &.secondary {
+    background: rgba(48, 220, 255, 0.15);
+    border: 1px solid rgba(48, 220, 255, 0.4);
+    color: #30DCFF;
+    &:hover {
+      background: rgba(48, 220, 255, 0.25);
     }
   }
+  span {
+    font-size: 14px;
+  }
 }
 </style>

+ 307 - 96
src/views/study/components/StudyProcess.vue

@@ -1,124 +1,335 @@
 <template>
-  <div class="study-process">
-    <div class="m-card">
-      <div class="m-card-hd">
-        <div class="title">研学联建流程</div>
+  <m-card title="研学联建流程" :width="398" :height="450">
+    <div class="study-process">
+      <div class="core-indicator">
+        <div class="indicator-main">
+          <span class="main-value">5</span>
+          <span class="main-unit">步</span>
+        </div>
+        <div class="indicator-label">标准流程</div>
       </div>
-      <div class="m-card-bd">
-        <div class="process-content">
-          <div class="process-step">
-            <div class="step-number">01</div>
-            <div class="step-content">
-              <h4>需求对接</h4>
-              <p>与学校、教育机构等合作方进行需求沟通,了解研学目标、参与人数、时间安排等具体要求。</p>
+      <div class="stats-grid">
+        <div class="stat-item">
+          <div class="stat-value">7</div>
+          <div class="stat-label">工作日</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">100%</div>
+          <div class="stat-label">成功率</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">20+</div>
+          <div class="stat-label">合作学校</div>
+        </div>
+        <div class="stat-item">
+          <div class="stat-value">50+</div>
+          <div class="stat-label">完成项目</div>
+        </div>
+      </div>
+      <div class="process-flow">
+        <div class="process-title">联建流程</div>
+        <div class="flow-items">
+          <div class="flow-item" :class="{ active: currentStep === 0 }">
+            <div class="flow-number">1</div>
+            <div class="flow-content">
+              <div class="flow-title">需求对接</div>
+              <div class="flow-description">与学校、教育机构等合作方进行需求沟通,了解研学目标、参与人数、时间安排等具体要求。</div>
             </div>
           </div>
-          <div class="process-arrow"></div>
-          <div class="process-step">
-            <div class="step-number">02</div>
-            <div class="step-content">
-              <h4>方案定制</h4>
-              <p>根据需求定制专属研学方案,包括课程内容、活动安排、安全保障等,确保符合教育目标和学生特点。</p>
+          <div class="flow-arrow"></div>
+          <div class="flow-item" :class="{ active: currentStep === 1 }">
+            <div class="flow-number">2</div>
+            <div class="flow-content">
+              <div class="flow-title">方案定制</div>
+              <div class="flow-description">根据需求定制专属研学方案,包括课程内容、活动安排、安全保障等,确保符合教育目标和学生特点。</div>
             </div>
           </div>
-          <div class="process-arrow"></div>
-          <div class="process-step">
-            <div class="step-number">03</div>
-            <div class="step-content">
-              <h4>活动实施</h4>
-              <p>组织专业导师团队,开展实地研学活动,包括水文监测体验、数据采集分析、科普讲座等环节。</p>
+          <div class="flow-arrow"></div>
+          <div class="flow-item" :class="{ active: currentStep === 2 }">
+            <div class="flow-number">3</div>
+            <div class="flow-content">
+              <div class="flow-title">活动实施</div>
+              <div class="flow-description">组织专业导师团队,开展实地研学活动,包括水文监测体验、数据采集分析、科普讲座等环节。</div>
             </div>
           </div>
-          <div class="process-arrow"></div>
-          <div class="process-step">
-            <div class="step-number">04</div>
-            <div class="step-content">
-              <h4>效果评估</h4>
-              <p>通过问卷调查、学生反馈、成果展示等方式,评估研学活动效果,持续优化研学方案。</p>
+          <div class="flow-arrow"></div>
+          <div class="flow-item" :class="{ active: currentStep === 3 }">
+            <div class="flow-number">4</div>
+            <div class="flow-content">
+              <div class="flow-title">效果评估</div>
+              <div class="flow-description">通过问卷调查、学生反馈、成果展示等方式,评估研学活动效果,持续优化研学方案。</div>
             </div>
           </div>
-          <div class="process-arrow"></div>
-          <div class="process-step">
-            <div class="step-number">05</div>
-            <div class="step-content">
-              <h4>长期合作</h4>
-              <p>建立长期合作关系,定期开展研学活动,共同推进水文科普教育,培养更多水文人才。</p>
+          <div class="flow-arrow"></div>
+          <div class="flow-item" :class="{ active: currentStep === 4 }">
+            <div class="flow-number">5</div>
+            <div class="flow-content">
+              <div class="flow-title">长期合作</div>
+              <div class="flow-description">建立长期合作关系,定期开展研学活动,共同推进水文科普教育,培养更多水文人才。</div>
             </div>
           </div>
         </div>
       </div>
+      <div class="action-buttons">
+        <button class="action-btn primary" @click="startProcess">
+          <span>🚀</span> 启动流程
+        </button>
+        <button class="action-btn secondary" @click="downloadGuide">
+          <span>📋</span> 下载指南
+        </button>
+      </div>
     </div>
-  </div>
+  </m-card>
 </template>
 
 <script setup>
+import { ref, onMounted, onUnmounted } from "vue"
+import mCard from "@/components/mCard/index.vue"
+
+const currentStep = ref(0)
+let stepInterval = null
+
+onMounted(() => {
+  startStepAnimation()
+})
 
+onUnmounted(() => {
+  if (stepInterval) clearInterval(stepInterval)
+})
+
+function startStepAnimation() {
+  stepInterval = setInterval(() => {
+    currentStep.value = (currentStep.value + 1) % 5
+  }, 3000)
+}
+
+function startProcess() {
+  console.log("启动研学联建流程")
+}
+
+function downloadGuide() {
+  console.log("下载研学联建指南")
+}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 .study-process {
+  padding: 12px;
   height: 100%;
-  .m-card {
-    height: 100%;
-    display: flex;
-    flex-direction: column;
-    .m-card-hd {
-      padding: 15px 20px;
-      border-bottom: 1px solid rgba(48, 220, 255, 0.3);
-      .title {
-        font-size: 18px;
-        font-weight: bold;
-        color: #30dcfd;
-      }
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  box-sizing: border-box;
+  overflow-y: auto;
+  &::-webkit-scrollbar {
+    width: 6px;
+  }
+  &::-webkit-scrollbar-track {
+    background: rgba(0, 40, 80, 0.6);
+    border-radius: 3px;
+  }
+  &::-webkit-scrollbar-thumb {
+    background: rgba(48, 220, 255, 0.5);
+    border-radius: 3px;
+  }
+  &::-webkit-scrollbar-thumb:hover {
+    background: rgba(48, 220, 255, 0.8);
+  }
+  .process-flow {
+    flex: 0 1 auto;
+    min-height: 0;
+  }
+}
+
+.core-indicator {
+  text-align: center;
+  padding: 12px;
+  background: linear-gradient(135deg, rgba(48, 220, 255, 0.1) 0%, rgba(0, 191, 255, 0.05) 100%);
+  border-radius: 8px;
+  border: 1px solid rgba(48, 220, 255, 0.3);
+}
+
+.indicator-main {
+  margin-bottom: 5px;
+}
+
+.main-value {
+  font-size: 40px;
+  font-weight: 700;
+  color: #30DCFF;
+  font-family: "D-DIN";
+  text-shadow: 0 0 20px rgba(48, 220, 255, 0.5);
+}
+
+.main-unit {
+  font-size: 20px;
+  color: rgba(48, 220, 255, 0.8);
+  font-weight: 600;
+}
+
+.indicator-label {
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 12px;
+  letter-spacing: 1px;
+}
+
+.stats-grid {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  gap: 6px;
+}
+
+.stat-item {
+  background: rgba(0, 180, 255, 0.08);
+  border: 1px solid rgba(0, 180, 255, 0.2);
+  border-radius: 4px;
+  padding: 6px 4px;
+  text-align: center;
+  transition: all 0.3s ease;
+  &:hover {
+    background: rgba(0, 180, 255, 0.15);
+    border-color: rgba(48, 220, 255, 0.5);
+  }
+}
+
+.stat-value {
+  font-size: 16px;
+  font-weight: 700;
+  color: #30DCFF;
+  font-family: "D-DIN";
+  margin-bottom: 2px;
+}
+
+.stat-label {
+  font-size: 9px;
+  color: rgba(255, 255, 255, 0.6);
+  line-height: 1.2;
+}
+
+.process-flow {
+  flex: 1;
+  background: rgba(0, 180, 255, 0.05);
+  border-radius: 6px;
+  padding: 8px;
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+  overflow-y: auto;
+}
+
+.process-title {
+  font-size: 11px;
+  color: #30DCFF;
+  font-weight: 600;
+  padding-bottom: 4px;
+  border-bottom: 1px solid rgba(48, 220, 255, 0.2);
+}
+
+.flow-items {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+}
+
+.flow-item {
+  display: flex;
+  gap: 8px;
+  background: rgba(0, 40, 80, 0.4);
+  border: 1px solid rgba(48, 220, 255, 0.2);
+  border-radius: 6px;
+  padding: 8px;
+  align-items: flex-start;
+  transition: all 0.3s ease;
+  &.active {
+    background: rgba(0, 40, 80, 0.6);
+    border-color: #30DCFF;
+    box-shadow: 0 0 10px rgba(48, 220, 255, 0.3);
+  }
+}
+
+.flow-number {
+  width: 24px;
+  height: 24px;
+  border-radius: 50%;
+  background: linear-gradient(135deg, #30DCFF, #00BFFF);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 12px;
+  font-weight: 700;
+  color: white;
+  flex-shrink: 0;
+  box-shadow: 0 0 10px rgba(48, 220, 255, 0.4);
+}
+
+.flow-content {
+  flex: 1;
+}
+
+.flow-title {
+  font-size: 12px;
+  font-weight: 600;
+  color: #30DCFF;
+  margin-bottom: 4px;
+}
+
+.flow-description {
+  font-size: 10px;
+  color: rgba(255, 255, 255, 0.8);
+  line-height: 1.4;
+}
+
+.flow-arrow {
+  height: 12px;
+  width: 100%;
+  position: relative;
+  &::after {
+    content: '';
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    border-left: 8px solid transparent;
+    border-right: 8px solid transparent;
+    border-top: 8px solid rgba(48, 220, 255, 0.3);
+  }
+}
+
+.action-buttons {
+  display: flex;
+  gap: 10px;
+}
+
+.action-btn {
+  flex: 1;
+  padding: 10px 12px;
+  border-radius: 6px;
+  border: none;
+  cursor: pointer;
+  font-size: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 5px;
+  transition: all 0.3s ease;
+  &.primary {
+    background: linear-gradient(135deg, #30DCFF, #00BFFF);
+    color: #fff;
+    &:hover {
+      box-shadow: 0 0 15px rgba(48, 220, 255, 0.5);
+      transform: translateY(-2px);
     }
-    .m-card-bd {
-      flex: 1;
-      padding: 20px;
-      overflow-y: auto;
-      .process-content {
-        display: flex;
-        flex-direction: column;
-        gap: 20px;
-        .process-step {
-          display: flex;
-          gap: 15px;
-          .step-number {
-            width: 40px;
-            height: 40px;
-            border-radius: 50%;
-            background: rgba(48, 220, 255, 0.2);
-            border: 1px solid rgba(48, 220, 255, 0.5);
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            font-size: 16px;
-            font-weight: bold;
-            color: #30dcfd;
-            flex-shrink: 0;
-          }
-          .step-content {
-            flex: 1;
-            h4 {
-              font-size: 14px;
-              font-weight: bold;
-              color: white;
-              margin-bottom: 5px;
-            }
-            p {
-              font-size: 12px;
-              color: rgba(255, 255, 255, 0.8);
-              line-height: 1.4;
-            }
-          }
-        }
-        .process-arrow {
-          width: 2px;
-          height: 20px;
-          background: linear-gradient(to bottom, rgba(48, 220, 255, 0.5), rgba(48, 220, 255, 0.1));
-          margin-left: 19px;
-        }
-      }
+  }
+  &.secondary {
+    background: rgba(48, 220, 255, 0.15);
+    border: 1px solid rgba(48, 220, 255, 0.4);
+    color: #30DCFF;
+    &:hover {
+      background: rgba(48, 220, 255, 0.25);
     }
   }
+  span {
+    font-size: 14px;
+  }
 }
 </style>

+ 0 - 1
src/views/study/index.vue

@@ -38,7 +38,6 @@ import StudyProcess from "./components/StudyProcess.vue"
   right: 0;
   bottom: 0;
   z-index: 2;
-  pointer-events: none;
 }
 
 .left-column {

文件差异内容过多而无法显示
+ 71 - 0
vite.config.js.timestamp-1771985207117-635bfec70b137.mjs


部分文件因为文件数量过多而无法显示