Bläddra i källkod

Merge branch 'master' of http://139.9.51.218:3000/qw/12 into lili

# Conflicts:
#	components.d.ts
yes-yes-yes-k 2 månader sedan
förälder
incheckning
cd1b17cf39

+ 11 - 1
components.d.ts

@@ -3,7 +3,7 @@
 // Generated by unplugin-vue-components
 // Read more: https://github.com/vuejs/core/pull/3399
 // biome-ignore lint: disable
-export {}
+export { }
 
 /* prettier-ignore */
 declare module 'vue' {
@@ -29,6 +29,7 @@ declare module 'vue' {
     CrossSetionData2: typeof import('./src/components/irrpollution/crossSetionData2.vue')['default']
     CrossSetionTencentmap: typeof import('./src/components/irrpollution/crossSetionTencentmap.vue')['default']
     EffcdStatistics: typeof import('./src/components/soilcdStatistics/effcdStatistics.vue')['default']
+    ElAlert: typeof import('element-plus/es')['ElAlert']
     ElAside: typeof import('element-plus/es')['ElAside']
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElButton: typeof import('element-plus/es')['ElButton']
@@ -36,12 +37,16 @@ declare module 'vue' {
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
     ElContainer: typeof import('element-plus/es')['ElContainer']
+    ElDialog: typeof import('element-plus/es')['ElDialog']
     ElDropdown: typeof import('element-plus/es')['ElDropdown']
     ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
     ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
+    ElForm: typeof import('element-plus/es')['ElForm']
+    ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElHeader: typeof import('element-plus/es')['ElHeader']
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElImage: typeof import('element-plus/es')['ElImage']
+    ElInput: typeof import('element-plus/es')['ElInput']
     ElMain: typeof import('element-plus/es')['ElMain']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
@@ -55,6 +60,8 @@ declare module 'vue' {
     ElTabPane: typeof import('element-plus/es')['ElTabPane']
     ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
+    ElTooltip: typeof import('element-plus/es')['ElTooltip']
+    ElUpload: typeof import('element-plus/es')['ElUpload']
     FluxcdStatictics: typeof import('./src/components/soilcdStatistics/fluxcdStatictics.vue')['default']
     HeavyMetalEnterprisechart: typeof import('./src/components/atmpollution/heavyMetalEnterprisechart.vue')['default']
     HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
@@ -80,4 +87,7 @@ declare module 'vue' {
     Waterdataline: typeof import('./src/components/irrpollution/waterdataline.vue')['default']
     WelcomeItem: typeof import('./src/components/WelcomeItem.vue')['default']
   }
+  export interface GlobalDirectives {
+    vLoading: typeof import('element-plus/es')['ElLoadingDirective']
+  }
 }

BIN
src/assets/videos/农业投入品.mp4


BIN
src/assets/videos/地下渗漏.mp4


BIN
src/assets/videos/地表径流.mp4


BIN
src/assets/videos/干湿沉降.mp4


BIN
src/assets/videos/灌溉水.mp4


BIN
src/assets/videos/秸秆移除.mp4


BIN
src/assets/videos/籽粒移除.mp4


BIN
src/assets/videos/输入总通量.mp4


BIN
src/assets/videos/输出总通量.mp4


+ 3 - 3
src/locales/zh.json

@@ -140,17 +140,17 @@
   },
   "strawRemoval": {
     "Title": "秸秆移除",
-    "samplingDesc2": "秸秆移除说明",
+    "samplingDesc2": "秸秆移除采样说明",
     "strawRemovalInputFlux": "秸秆移除输出通量"
   },
   "subsurfaceLeakage": {
     "Title": "地下渗漏",
-    "samplingDesc3": "地下渗漏说明",
+    "samplingDesc3": "地下渗漏采样说明",
     "subsurfaceLeakageInputFlux": "地下渗漏输出通量"
   },
   "surfaceRunoff": {
     "Title": "地表径流",
-    "samplingDesc4": "地表径流说明",
+    "samplingDesc4": "地表径流采样说明",
     "surfaceRunoffInputFlux": "地表径流输出通量"
   },
   "mapView": {

+ 4 - 0
src/router/index.ts

@@ -15,6 +15,10 @@ const routes = [
         path: "/:catchAll(.*)",
         redirect: "/404", // 确保重定向到有效页面
       },
+      {
+        path: '',
+        redirect: '/irriSampleData'
+      },
       {
         path: "select-city", // remove leading slash
         name: "selectCityAndCounty",

+ 100 - 0
src/views/User/HmOutFlux/agriInput/farmInputSamplingDesc.vue

@@ -175,6 +175,22 @@
         </div>
       </div>
     </div>
+
+    <div class="process-section">
+      <div class="section-header">
+        <div class="section-number">5</div>
+        <h2>农业投入品输入过程视频演示</h2>
+      </div>
+      
+      <div class="video-section">
+        <div class="video-container">
+          <video controls class="sampling-video">
+            <source src='@/assets/videos/农业投入品.mp4' type="video/mp4">
+            您的浏览器不支持HTML5视频播放。
+          </video>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -596,4 +612,88 @@ h2 {
     max-height: 250px;
   }
 }
+/* 新增视频模块样式 */
+.video-section {
+  display: flex;
+  flex-direction: column;
+  gap: 30px;
+  margin-top: 20px;
+}
+
+.video-container {
+  border-radius: 12px;
+  overflow: hidden;
+  position: relative;
+  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
+  max-width: 800px;
+  margin: 0 auto;
+  transition: all 0.4s ease;
+}
+
+.video-container:hover {
+  transform: translateY(-5px);
+  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2);
+}
+
+.sampling-video {
+  width: 100%;
+  height: auto;
+  display: block;
+  background: #f8fafc;
+  min-height: 400px;
+}
+
+.video-caption {
+  text-align: center;
+  font-size: 1.1rem;
+  color: #1a365d;
+  padding: 15px;
+  font-weight: 600;
+  background: linear-gradient(to right, rgba(248, 250, 252, 0.9), rgba(240, 248, 255, 0.9));
+  margin: 0;
+  border-top: 1px dashed #cbd5e0;
+  position: relative;
+}
+
+.video-caption::before {
+  content: "📹";
+  position: absolute;
+  left: 20px;
+  top: 50%;
+  transform: translateY(-50%);
+}
+
+.video-description {
+  background: rgba(245, 249, 255, 0.6);
+  border-radius: 12px;
+  padding: 20px;
+  border-left: 4px solid #3acfd5;
+}
+
+.video-description h3 {
+  color: #1a365d;
+  margin-top: 0;
+  margin-bottom: 15px;
+  font-size: 1.4rem;
+}
+
+.video-description ul {
+  padding-left: 25px;
+  margin: 15px 0;
+}
+
+.video-description li {
+  margin-bottom: 10px;
+  line-height: 1.7;
+  position: relative;
+}
+
+.video-description li::before {
+  content: "•";
+  color: #3acfd5;
+  font-size: 1.2rem;
+  position: absolute;
+  left: -20px;
+  top: 0;
+}
 </style>

+ 99 - 0
src/views/User/HmOutFlux/irrigationWater/samplingMethodDevice1.vue

@@ -95,6 +95,21 @@
         </div>
       </div>
     </div>
+    <div class="section-container">
+      <div class="section-header">
+        <div class="section-number">3</div>
+        <h2>灌溉水输入过程视频演示</h2>
+      </div>
+      
+      <div class="video-section">
+        <div class="video-container">
+          <video controls class="sampling-video">
+            <source src='@/assets/videos/灌溉水.mp4' type="video/mp4">
+            您的浏览器不支持HTML5视频播放。
+          </video>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -383,4 +398,88 @@ h2 {
     height: 200px;
   }
 }
+/* 新增视频模块样式 */
+.video-section {
+  display: flex;
+  flex-direction: column;
+  gap: 30px;
+  margin-top: 20px;
+}
+
+.video-container {
+  border-radius: 12px;
+  overflow: hidden;
+  position: relative;
+  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
+  max-width: 800px;
+  margin: 0 auto;
+  transition: all 0.4s ease;
+}
+
+.video-container:hover {
+  transform: translateY(-5px);
+  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2);
+}
+
+.sampling-video {
+  width: 100%;
+  height: auto;
+  display: block;
+  background: #f8fafc;
+  min-height: 400px;
+}
+
+.video-caption {
+  text-align: center;
+  font-size: 1.1rem;
+  color: #1a365d;
+  padding: 15px;
+  font-weight: 600;
+  background: linear-gradient(to right, rgba(248, 250, 252, 0.9), rgba(240, 248, 255, 0.9));
+  margin: 0;
+  border-top: 1px dashed #cbd5e0;
+  position: relative;
+}
+
+.video-caption::before {
+  content: "📹";
+  position: absolute;
+  left: 20px;
+  top: 50%;
+  transform: translateY(-50%);
+}
+
+.video-description {
+  background: rgba(245, 249, 255, 0.6);
+  border-radius: 12px;
+  padding: 20px;
+  border-left: 4px solid #3acfd5;
+}
+
+.video-description h3 {
+  color: #1a365d;
+  margin-top: 0;
+  margin-bottom: 15px;
+  font-size: 1.4rem;
+}
+
+.video-description ul {
+  padding-left: 25px;
+  margin: 15px 0;
+}
+
+.video-description li {
+  margin-bottom: 10px;
+  line-height: 1.7;
+  position: relative;
+}
+
+.video-description li::before {
+  content: "•";
+  color: #3acfd5;
+  font-size: 1.2rem;
+  position: absolute;
+  left: -20px;
+  top: 0;
+}
 </style>

+ 99 - 0
src/views/User/HmOutFlux/totalInputFluxDesc.vue

@@ -32,6 +32,21 @@
         </div>
       </div>
     </div>
+    <div class="content-section">
+      <div class="section-header">
+        <div class="section-number">2</div>
+        <h2>总通量输入过程视频演示</h2>
+      </div>
+      
+      <div class="video-section">
+        <div class="video-container">
+          <video controls class="sampling-video">
+            <source src='@/assets/videos/输入总通量.mp4' type="video/mp4">
+            您的浏览器不支持HTML5视频播放。
+          </video>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -364,4 +379,88 @@ h2 {
     font-size: 1.5rem;
   }
 }
+/* 新增视频模块样式 */
+.video-section {
+  display: flex;
+  flex-direction: column;
+  gap: 30px;
+  margin-top: 20px;
+}
+
+.video-container {
+  border-radius: 12px;
+  overflow: hidden;
+  position: relative;
+  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
+  max-width: 800px;
+  margin: 0 auto;
+  transition: all 0.4s ease;
+}
+
+.video-container:hover {
+  transform: translateY(-5px);
+  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2);
+}
+
+.sampling-video {
+  width: 100%;
+  height: auto;
+  display: block;
+  background: #f8fafc;
+  min-height: 400px;
+}
+
+.video-caption {
+  text-align: center;
+  font-size: 1.1rem;
+  color: #1a365d;
+  padding: 15px;
+  font-weight: 600;
+  background: linear-gradient(to right, rgba(248, 250, 252, 0.9), rgba(240, 248, 255, 0.9));
+  margin: 0;
+  border-top: 1px dashed #cbd5e0;
+  position: relative;
+}
+
+.video-caption::before {
+  content: "📹";
+  position: absolute;
+  left: 20px;
+  top: 50%;
+  transform: translateY(-50%);
+}
+
+.video-description {
+  background: rgba(245, 249, 255, 0.6);
+  border-radius: 12px;
+  padding: 20px;
+  border-left: 4px solid #3acfd5;
+}
+
+.video-description h3 {
+  color: #1a365d;
+  margin-top: 0;
+  margin-bottom: 15px;
+  font-size: 1.4rem;
+}
+
+.video-description ul {
+  padding-left: 25px;
+  margin: 15px 0;
+}
+
+.video-description li {
+  margin-bottom: 10px;
+  line-height: 1.7;
+  position: relative;
+}
+
+.video-description li::before {
+  content: "•";
+  color: #3acfd5;
+  font-size: 1.2rem;
+  position: absolute;
+  left: -20px;
+  top: 0;
+}
 </style>

+ 104 - 23
src/views/User/cadmiumPrediction/CropCadmiumPrediction.vue

@@ -90,8 +90,9 @@
         </div>
         
         <div v-if="!loadingStats && statisticsData.length" class="stats-container">
-          <!-- 统计表格 -->
-         <el-table 
+          <!-- 基础统计表格 -->
+          <h4>基础统计信息</h4>
+          <el-table 
             :data="statisticsData" 
             style="width: 100%; margin-bottom: 20px;"
             border
@@ -102,6 +103,25 @@
             <el-table-column prop="unit" label="单位" min-width="100" />
             <el-table-column prop="description" label="描述" min-width="200" />
           </el-table>
+
+          <!-- 分布统计表格 -->
+          <h4>水稻镉含量分布统计</h4>
+          <el-table 
+            :data="distributionData" 
+            style="width: 100%; margin-bottom: 20px;"
+            border
+            stripe
+          >
+            <el-table-column prop="序号" label="序号" width="80" />
+            <el-table-column prop="分布区间" label="分布区间 (mg/kg)" min-width="150" />
+            <el-table-column prop="区间说明" label="区间说明" min-width="120" />
+            <el-table-column prop="数据点数量" label="数据点数量" min-width="120" />
+            <el-table-column prop="占比" label="占比 (%)" min-width="100">
+              <template #default="{ row }">
+                {{ row.占比 }}%
+              </template>
+            </el-table-column>
+          </el-table>
         </div>
         
         <div v-if="!loadingStats && !statisticsData.length" class="no-data">
@@ -149,6 +169,9 @@ export default {
       loadingHistogram: false,
       loadingStats: false,
       statisticsData: [],
+      distributionData: [],
+      distributionSummary: null,
+      distributionTotal: 0,
       modelInfo: {
         modelType: '',
         unit: '',
@@ -178,6 +201,9 @@ export default {
     this.fetchLatestResults();
     this.fetchStatistics();
     this.initTownshipMap();
+    
+    // 添加窗口调整事件监听
+    window.addEventListener('resize', this.handleResize);
   },
 
   beforeDestroy() {
@@ -188,6 +214,9 @@ export default {
       this.townshipMapInstance.dispose();
       this.townshipMapInstance = null;
     }
+    
+    // 移除窗口调整事件监听
+    window.removeEventListener('resize', this.handleResize);
   },
   methods: {
     // 触发文件选择
@@ -329,6 +358,13 @@ export default {
           const statsData = response.data;
           this.statisticsData = this.formatStatisticsData(statsData);
           
+          // 设置分布统计表格数据
+          if (statsData.data.分布统计表格 && statsData.data.分布统计表格.表格数据) {
+            this.distributionData = statsData.data.分布统计表格.表格数据;
+            this.distributionSummary = statsData.data.分布统计表格.汇总;
+            this.distributionTotal = statsData.data.分布统计表格.总数据点数;
+          }
+          
           // 设置模型信息
           this.modelInfo = {
             modelType: statsData.data.模型类型,
@@ -367,7 +403,9 @@ export default {
         this.loadingTownshipMap = true;
         // 步骤1:加载本地 GeoJSON 边界文件
         await this.loadLocalGeoJson();
-        // 步骤2:渲染边界地图(不关联接口数据)
+        // 步骤2:等待DOM更新完成
+        await this.$nextTick();
+        // 步骤3:渲染边界地图(不关联接口数据)
         this.renderTownshipMap();
       } catch (error) {
         console.error('乡镇边界加载失败:', error);
@@ -522,10 +560,12 @@ export default {
       // 5. 渲染地图
       this.townshipMapInstance.setOption(option);
 
-      // 6. 监听窗口 resize(地图自适应)
-      window.addEventListener('resize', () => {
-        this.townshipMapInstance && this.townshipMapInstance.resize();
-      });
+      // 6. 关键修复:添加延迟resize确保地图正确渲染
+      setTimeout(() => {
+        if (this.townshipMapInstance) {
+          this.townshipMapInstance.resize();
+        }
+      }, 100);
     },
     
     // 上传并计算
@@ -702,7 +742,9 @@ export default {
     
     // 处理窗口大小变化
     handleResize() {
-      if (this.distributionChart) this.distributionChart.resize();
+      if (this.townshipMapInstance) {
+        this.townshipMapInstance.resize();
+      }
     },
   }
 };
@@ -720,28 +762,18 @@ export default {
   box-sizing: border-box;
 }
 
-/* 新增:乡镇地图样式 */
-.township-map-section {
-  background-color: rgba(255, 255, 255, 0.8);
-  border-radius: 8px;
-  padding: 15px;
-  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
-  position: relative;
-  min-height: 500px; /* 与原有地图高度一致 */
-  backdrop-filter: blur(5px);
-  margin-bottom: 20px; /* 与下方地图间距 */
-}
 
 .township-map-container {
-  width: 1000px;
-  height: 500px; /* 减去标题高度 */
-  min-height: 470px;
+  width: 90%; /* 使用百分比宽度 */
+  max-width: 1000px; /* 最大宽度限制 */
+  height: 500px;
   border-radius: 4px;
   background-color: #fff;
+  margin: 15px auto; /* 上下15px,水平自动居中 */
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
 }
 
 
-
 .toolbar {
   display: flex;
   flex-direction: column;
@@ -901,6 +933,55 @@ export default {
   animation: rotate 2s linear infinite;
 }
 
+/* 新增样式 */
+.summary-info {
+  margin-top: 20px;
+}
+
+.card-header {
+  font-weight: bold;
+  color: #409EFF;
+}
+
+.summary-items {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+}
+
+.summary-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 8px 0;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.summary-item:last-child {
+  border-bottom: none;
+}
+
+.summary-item .label {
+  font-weight: bold;
+  color: #606266;
+}
+
+.summary-item .value {
+  font-weight: bold;
+}
+
+.summary-item .value.safe {
+  color: #67C23A;
+}
+
+.summary-item .value.warning {
+  color: #E6A23C;
+}
+
+.summary-item .value.danger {
+  color: #F56C6C;
+}
+
 @keyframes rotate {
   from {
     transform: rotate(0deg);

+ 1 - 1
src/views/User/hmInFlux/grainRemoval/samplingDesc1.vue

@@ -30,7 +30,7 @@
           
           <div class="image-card">
             <video controls class="sampling-image">
-              <source src="@/assets/videos/秸秆移除和籽粒移除.mp4" type="video/mp4">
+              <source src="@/assets/videos/籽粒移除.mp4" type="video/mp4">
               您的浏览器不支持HTML5视频播放。
             </video>
             <div class="image-info">

+ 1 - 1
src/views/User/hmInFlux/strawRemoval/samplingDesc2.vue

@@ -30,7 +30,7 @@
           
           <div class="image-card">
             <video controls class="sampling-image">
-              <source src="@/assets/videos/秸秆移除和籽粒移除.mp4" type="video/mp4">
+              <source src="@/assets/videos/秸秆移除.mp4" type="video/mp4">
               您的浏览器不支持HTML5视频播放。
             </video>
             <div class="image-info">

+ 99 - 0
src/views/User/hmInFlux/totalOutputFluxDesc.vue

@@ -33,6 +33,21 @@
         </div>
       </div>
     </div>
+     <div class="content-section">
+      <div class="section-header">
+        <div class="section-number">2</div>
+        <h2>总通量输出过程视频演示</h2>
+      </div>
+      
+      <div class="video-section">
+        <div class="video-container">
+          <video controls class="sampling-video">
+            <source src='@/assets/videos/输出总通量.mp4' type="video/mp4">
+            您的浏览器不支持HTML5视频播放。
+          </video>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -368,4 +383,88 @@ h2 {
     font-size: 1.5rem;
   }
 }
+/* 新增视频模块样式 */
+.video-section {
+  display: flex;
+  flex-direction: column;
+  gap: 30px;
+  margin-top: 20px;
+}
+
+.video-container {
+  border-radius: 12px;
+  overflow: hidden;
+  position: relative;
+  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
+  max-width: 800px;
+  margin: 0 auto;
+  transition: all 0.4s ease;
+}
+
+.video-container:hover {
+  transform: translateY(-5px);
+  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2);
+}
+
+.sampling-video {
+  width: 100%;
+  height: auto;
+  display: block;
+  background: #f8fafc;
+  min-height: 400px;
+}
+
+.video-caption {
+  text-align: center;
+  font-size: 1.1rem;
+  color: #1a365d;
+  padding: 15px;
+  font-weight: 600;
+  background: linear-gradient(to right, rgba(248, 250, 252, 0.9), rgba(240, 248, 255, 0.9));
+  margin: 0;
+  border-top: 1px dashed #cbd5e0;
+  position: relative;
+}
+
+.video-caption::before {
+  content: "📹";
+  position: absolute;
+  left: 20px;
+  top: 50%;
+  transform: translateY(-50%);
+}
+
+.video-description {
+  background: rgba(245, 249, 255, 0.6);
+  border-radius: 12px;
+  padding: 20px;
+  border-left: 4px solid #3acfd5;
+}
+
+.video-description h3 {
+  color: #1a365d;
+  margin-top: 0;
+  margin-bottom: 15px;
+  font-size: 1.4rem;
+}
+
+.video-description ul {
+  padding-left: 25px;
+  margin: 15px 0;
+}
+
+.video-description li {
+  margin-bottom: 10px;
+  line-height: 1.7;
+  position: relative;
+}
+
+.video-description li::before {
+  content: "•";
+  color: #3acfd5;
+  font-size: 1.2rem;
+  position: absolute;
+  left: -20px;
+  top: 0;
+}
 </style>

+ 1 - 0
src/views/login/loginView.vue

@@ -518,6 +518,7 @@ onMounted(() => {
   width: 100%;
   padding: 15px 10px;
   margin-bottom: 20px;
+  max-width: 600px; /* 限制最大宽度 */
 }
 
 /* 错误提示样式 */