Эх сурвалжийг харах

修复农业投入品逻辑

yangtaodemon 3 сар өмнө
parent
commit
edbfe20a4c

+ 105 - 185
src/views/User/HmOutFlux/agriInput/prodInputFlux.vue

@@ -7,67 +7,67 @@
           <el-form label-width="250px" label-position="top">
             <div class="form-section">
               <div class="input-group">
-                <el-form-item label="氮肥镉含量平均值 (mg/kg)" class="form-item">
-                  <el-input v-model="formData.f3_nitrogen_cd_content" placeholder="0.05"></el-input>
+                <el-form-item label="氮肥镉含量平均值 (mg/kg)" class="form-item">
+                  <el-input v-model="formData.f3_nitrogen_cd_content" placeholder="0.12"></el-input>
                 </el-form-item>
                 <el-form-item label="氮肥单位面积使用量 (t/ha/a)" class="form-item">
-                  <el-input v-model="formData.nf_nitrogen_usage" placeholder="0.05"></el-input>
+                  <el-input v-model="formData.nf_nitrogen_usage" placeholder="0.25"></el-input>
                 </el-form-item>
               </div>
               <div class="input-group">
-                <el-form-item label="磷肥镉含量平均值 (mg/kg)" class="form-item">
-                  <el-input v-model="formData.f4_phosphorus_cd_content" placeholder="0.158"></el-input>
+                <el-form-item label="磷肥镉含量平均值 (mg/kg)" class="form-item">
+                  <el-input v-model="formData.f4_phosphorus_cd_content" placeholder="0.85"></el-input>
                 </el-form-item>
                 <el-form-item label="磷肥单位面积使用量 (t/ha/a)" class="form-item">
-                  <el-input v-model="formData.pf_phosphorus_usage" placeholder="0.158"></el-input>
+                  <el-input v-model="formData.pf_phosphorus_usage" placeholder="0.15"></el-input>
                 </el-form-item>
               </div>
               <div class="input-group">
-                <el-form-item label="钾肥镉含量平均值 (mg/kg)" class="form-item">
-                  <el-input v-model="formData.f5_potassium_cd_content" placeholder="0.06"></el-input>
+                <el-form-item label="钾肥镉含量平均值 (mg/kg)" class="form-item">
+                  <el-input v-model="formData.f5_potassium_cd_content" placeholder="0.05"></el-input>
                 </el-form-item>
                 <el-form-item label="钾肥单位面积使用量 (t/ha/a)" class="form-item">
-                  <el-input v-model="formData.kf_potassium_usage" placeholder="0.06"></el-input>
+                  <el-input v-model="formData.kf_potassium_usage" placeholder="0.12"></el-input>
                 </el-form-item>
               </div>
               <div class="input-group">
-                <el-form-item label="复合肥镉含量平均值 (mg/kg)" class="form-item">
-                  <el-input v-model="formData.f6_compound_cd_content" placeholder="0.065"></el-input>
+                <el-form-item label="复合肥镉含量平均值 (mg/kg)" class="form-item">
+                  <el-input v-model="formData.f6_compound_cd_content" placeholder="0.45"></el-input>
                 </el-form-item>
                 <el-form-item label="复合肥单位面积使用量 (t/ha/a)" class="form-item">
-                  <el-input v-model="formData.cf_compound_usage" placeholder="0.065"></el-input>
+                  <el-input v-model="formData.cf_compound_usage" placeholder="0.30"></el-input>
                 </el-form-item>
               </div>
               <div class="input-group">
-                <el-form-item label="有机肥镉含量平均值 (mg/kg)" class="form-item">
-                  <el-input v-model="formData.f7_organic_cd_content" placeholder="0.6"></el-input>
+                <el-form-item label="有机肥镉含量平均值 (mg/kg)" class="form-item">
+                  <el-input v-model="formData.f7_organic_cd_content" placeholder="0.22"></el-input>
                 </el-form-item>
                 <el-form-item label="有机肥单位面积使用量 (t/ha/a)" class="form-item">
-                  <el-input v-model="formData.of_organic_usage" placeholder="0.6"></el-input>
+                  <el-input v-model="formData.of_organic_usage" placeholder="2.50"></el-input>
                 </el-form-item>
               </div>
               <div class="input-group">
-                <el-form-item label="农药镉含量 (mg/kg)" class="form-item">
-                  <el-input v-model="formData.f8_pesticide_cd_content" placeholder="0.25"></el-input>
+                <el-form-item label="农药镉含量 (mg/kg)" class="form-item">
+                  <el-input v-model="formData.f8_pesticide_cd_content" placeholder="0.08"></el-input>
                 </el-form-item>
                 <el-form-item label="农药单位面积使用量 (t/ha/a)" class="form-item">
-                  <el-input v-model="formData.p_pesticide_usage" placeholder="0.25"></el-input>
+                  <el-input v-model="formData.p_pesticide_usage" placeholder="0.02"></el-input>
                 </el-form-item>
               </div>
               <div class="input-group">
-                <el-form-item label="农家肥镉含量 (mg/kg)" class="form-item">
-                  <el-input v-model="formData.f9_farmyard_cd_content" placeholder="0.35"></el-input>
+                <el-form-item label="农家肥镉含量 (mg/kg)" class="form-item">
+                  <el-input v-model="formData.f9_farmyard_cd_content" placeholder="0.15"></el-input>
                 </el-form-item>
                 <el-form-item label="农家肥单位面积使用量 (t/ha/a)" class="form-item">
-                  <el-input v-model="formData.ff_farmyard_usage" placeholder="0.35"></el-input>
+                  <el-input v-model="formData.ff_farmyard_usage" placeholder="1.80"></el-input>
                 </el-form-item>
               </div>
               <div class="input-group">
-                <el-form-item label="农膜镉含量 (mg/kg)" class="form-item">
-                  <el-input v-model="formData.f10_film_cd_content" placeholder="0.25"></el-input>
+                <el-form-item label="农膜镉含量 (mg/kg)" class="form-item">
+                  <el-input v-model="formData.f10_film_cd_content" placeholder="0.03"></el-input>
                 </el-form-item>
                 <el-form-item label="农膜(存留)单位面积使用量 (t/ha/a)" class="form-item">
-                  <el-input v-model="formData.af_film_usage" placeholder="0.6"></el-input>
+                  <el-input v-model="formData.af_film_usage" placeholder="0.05"></el-input>
                 </el-form-item>
               </div>
             </div>
@@ -79,10 +79,10 @@
           <div class="bottom-overlay"></div>
           <el-button 
             class="calculate-btn" 
-            @click="calculateAll"
+            @click="calculateAndVisualize"
             :loading="loading"
           >
-            <span class="btn-text">农产品输入通量计算</span>
+            <span class="btn-text">计算并生成可视化</span>
           </el-button>
         </div>
       </div>
@@ -99,11 +99,11 @@
         返回计算
       </el-button>
       <!-- 结果页面标题 -->
-      <h2 class="results-title">农业输入通量计算结果</h2>
+      <h2 class="results-title">农业投入Cd通量计算结果</h2>
       
       <!-- 自定义数据计算结果卡片 -->
       <el-card class="result-card" v-if="customResult.success">
-        <h3>当前地区农业投入Cd通量计算结果</h3>
+        <h3>农业投入Cd通量计算结果</h3>
         <p>总通量: {{ customResult.data.total_cd_flux }} g/ha/a</p>
         <el-table :data="customResultDetails" border>
           <el-table-column prop="type" label="投入类型"></el-table-column>
@@ -133,16 +133,13 @@
 
 <script>
 import axios from 'axios';
-import * as echarts from 'echarts'; 
+import * as echarts from 'echarts';
 import { ElNotification } from 'element-plus';
 
 export default {
   data() {
     return {
-      // 控制显示输入表单或结果页面
       showInputForm: true,
-      
-      // 表单数据 - 使用API定义的字段名
       formData: {
         f3_nitrogen_cd_content: "0.12",
         f4_phosphorus_cd_content: "0.85",
@@ -162,17 +159,9 @@ export default {
         af_film_usage: "0.05",
         description: "自定义数据计算结果"
       },
-      
-      // 结果数据
       loading: false,
       customResult: {},
-      allAreasResult: {},
-
-      // ECharts实例
       customPieChart: null,
-      allAreasPieChart: null,
-      
-      // 地图相关数据
       mapImageUrl: null,
       mapProgress: 0,
       mapStatus: 'success',
@@ -180,7 +169,6 @@ export default {
     };
   },
   computed: {
-    // 将自定义数据结果详情转换为表格数据
     customResultDetails() {
       if (!this.customResult.data || !this.customResult.data.details) return [];
       return Object.entries(this.customResult.data.details).map(([type, flux]) => ({
@@ -188,45 +176,23 @@ export default {
         flux: flux
       }));
     },
-    
-    // 获取所有地区列表
-    allAreasList() {
-      if (!this.allAreasResult.data || !this.allAreasResult.data.results) return [];
-      return this.allAreasResult.data.results.map(area => ({
-        area: area.area,
-        total_cd_flux: area.total_cd_flux
-      }));
-    },
-    // 获取当前地区饼图数据
     customPieData() {
       if (!this.customResult.data || !this.customResult.data.details) return [];
       return Object.entries(this.customResult.data.details).map(([type, value]) => ({
         name: this.getTypeName(type),
         value: value
       }));
-    },
-    
-    // 获取所有地区饼图数据(取前8个地区)
-    allAreasPieData() {
-      if (!this.allAreasList || this.allAreasList.length === 0) return [];
-      
-      // 复制并排序
-      const sortedAreas = [...this.allAreasList].sort((a, b) => b.total_cd_flux - a.total_cd_flux);
-      
-      // 取前8个地区
-      return sortedAreas.slice(0, 8).map(area => ({
-        name: area.area,
-        value: area.total_cd_flux
-      }));
     }
   },
   methods: {
-    // 计算所有数据
-    async calculateAll() {
+    async calculateAndVisualize() {
       try {
         this.loading = true;
+        this.mapImageUrl = null;
+        this.mapProgress = 0;
+        this.mapStatus = 'success';
         
-        // 准备自定义数据请求体
+        // 准备请求数据
         const requestBody = {
           ...this.formData,
           // 将字符串值转换为数字
@@ -245,42 +211,73 @@ export default {
           of_organic_usage: parseFloat(this.formData.of_organic_usage),
           p_pesticide_usage: parseFloat(this.formData.p_pesticide_usage),
           ff_farmyard_usage: parseFloat(this.formData.ff_farmyard_usage),
-          af_film_usage: parseFloat(this.formData.af_film_usage)
+          af_film_usage: parseFloat(this.formData.af_film_usage),
+          description: this.formData.description
         };
-        
-        // 同时调用两个API
-        const [customResponse] = await Promise.all([
+
+        // 启动进度条模拟
+        this.startProgressSimulation();
+
+        // 调用计算并可视化接口(返回FileResponse)
+        const [mapResponse, calcResponse] = await Promise.all([
           axios.post(
-            'http://localhost:8000/api/agricultural-input/calculate-with-custom-data', 
-            requestBody
+            'http://localhost:8000/api/agricultural-input/calculate-and-visualize-file',
+            requestBody,
+            {
+              params: {
+                area: '乐昌市',
+                level: 'county',
+                colormap: 'green_yellow_red_purple',
+                resolution_factor: 4.0,
+                enable_interpolation: false,
+                cleanup_intermediate: true
+              },
+              responseType: 'blob' // 重要:指定响应类型为blob
+            }
           ),
+          // 同时调用计算接口获取结果数据
+          axios.post(
+            'http://localhost:8000/api/agricultural-input/calculate-with-custom-data',
+            requestBody
+          )
         ]);
-        
-        // 处理自定义数据结果
-        this.customResult = customResponse.data;
-        if (!this.customResult.success) {
-          this.$message.error(this.customResult.message || '自定义数据计算失败');
+
+        // 处理地图响应
+        const blob = new Blob([mapResponse.data], { type: 'image/jpeg' });
+        this.mapImageUrl = URL.createObjectURL(blob);
+
+        // 处理计算结果
+        if (calcResponse.data.success) {
+          this.customResult = {
+            success: true,
+            data: calcResponse.data.data
+          };
+
+          // 显示结果页面
+          this.showInputForm = false;
+
+          // 初始化图表
+          this.$nextTick(() => {
+            this.initCharts();
+          });
+        } else {
+          throw new Error(calcResponse.data.message);
         }
         
-        // 切换到结果页面
-        this.showInputForm = false;
-
-        // 等待DOM更新
-        this.$nextTick(() => {
-          this.initCharts();
-          
-          // 调用地图生成方法
-          this.generateMap();
-        });
       } catch (error) {
         console.error('API调用错误:', error);
-        this.$message.error('计算失败,请检查网络连接');
+        this.mapStatus = 'exception';
+        ElNotification.error({
+          title: '计算失败',
+          message: error.message || '请检查网络连接',
+          duration: 5000
+        });
       } finally {
+        this.stopProgressSimulation();
         this.loading = false;
       }
     },
-    
-    // 获取类型的中文名称
+
     getTypeName(type) {
       const typeNames = {
         'nitrogen_fertilizer': '氮肥',
@@ -294,25 +291,18 @@ export default {
       };
       return typeNames[type] || type;
     },
-    
-    // 初始化图表
+
     initCharts() {
-      // 销毁已有实例
       if (this.customPieChart) {
         this.customPieChart.dispose();
       }
-      if (this.allAreasPieChart) {
-        this.allAreasPieChart.dispose();
-      }
       
-      // 创建新的图表实例
       this.customPieChart = echarts.init(this.$refs.customPieChart);
+      this.customPieChart.setOption(this.getPieChartOption('各项投入通量占比', this.customPieData));
       
-      // 设置图表选项
-      this.customPieChart.setOption(this.getPieChartOption('当前地区各项投入通量占比', this.customPieData));
+      window.addEventListener('resize', this.onResize);
     },
-    
-    // 获取饼图配置
+
     getPieChartOption(title, data) {
       return {
         title: {
@@ -365,57 +355,13 @@ export default {
         ]
       };
     },
-    
-    // 响应窗口大小变化
+
     onResize() {
       if (this.customPieChart) {
         this.customPieChart.resize();
       }
     },
-    
-    // 新增:生成地图的方法
-    async generateMap() {
-      try {
-        // 重置地图状态
-        this.mapImageUrl = null;
-        this.mapProgress = 0;
-        this.mapStatus = 'success';
-        
-        // 启动进度条模拟
-        this.startProgressSimulation();
-        
-        // 调用后端地图生成接口
-        const response = await axios.get(
-          'http://localhost:8000/api/agricultural-input/visualize',
-          {
-            params: {
-              area: '乐昌市', // 使用固定地区
-              level: 'county' // 使用县级行政层级
-            },
-            responseType: 'blob' // 重要:指定响应类型为blob
-          }
-        );
-        
-        // 停止进度条模拟
-        this.stopProgressSimulation();
-        
-        // 创建Blob URL
-        const blob = new Blob([response.data], { type: 'image/jpeg' });
-        this.mapImageUrl = URL.createObjectURL(blob);
-        
-      } catch (error) {
-        console.error('地图生成失败:', error);
-        this.stopProgressSimulation();
-        this.mapStatus = 'exception';
-        ElNotification.error({
-          title: '地图生成失败',
-          message: '无法生成空间分布图,请稍后再试',
-          duration: 5000
-        });
-      }
-    },
-    
-    // 启动进度条模拟
+
     startProgressSimulation() {
       this.mapInterval = setInterval(() => {
         if (this.mapProgress < 90) {
@@ -425,8 +371,7 @@ export default {
         }
       }, 500);
     },
-    
-    // 停止进度条模拟
+
     stopProgressSimulation() {
       if (this.mapInterval) {
         clearInterval(this.mapInterval);
@@ -435,25 +380,15 @@ export default {
       this.mapProgress = 100;
     }
   },
-  watch: {
-    // 当结果数据变化时更新图表
-    customPieData() {
-      if (this.customPieChart) {
-        this.customPieChart.setOption(this.getPieChartOption('当前地区各项投入通量占比', this.customPieData));
-      }
-    }
-  },
   beforeUnmount() {
-    // 组件销毁前移除事件监听
     window.removeEventListener('resize', this.onResize);
-    
-    // 销毁图表实例
     if (this.customPieChart) {
       this.customPieChart.dispose();
     }
-    
-    // 清理地图相关资源
-    this.stopProgressSimulation();
+    if (this.mapInterval) {
+      clearInterval(this.mapInterval);
+    }
+    // 释放Blob URL内存
     if (this.mapImageUrl) {
       URL.revokeObjectURL(this.mapImageUrl);
     }
@@ -462,7 +397,7 @@ export default {
 </script>
 
 <style scoped>
-/* 原有样式保持不变 */
+/* 样式部分保持不变,与之前相同 */
 .fertilizer-input-form {
   padding: 20px;
   display: flex;
@@ -476,10 +411,10 @@ export default {
   max-width: 1200px;
   margin: 0 auto;
   background: linear-gradient(135deg, #FAFDFF, #FFFAA2);
-  border: 1极端的 solid #e6e6e6;
+  border: 1px solid #e6e6e6;
   border-radius: 12px;
   overflow: hidden;
-  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
+  box-shadow: 0 8px 24px rgba极端的(0, 0, 0, 0.1);
 }
 
 .card-content {
@@ -498,7 +433,7 @@ export default {
   display: flex;
   align-items: center;
   justify-content: center;
-  padding: 30px;
+  padding: 极端的30px;
   position: relative;
   overflow: hidden;
 }
@@ -606,7 +541,7 @@ export default {
 .calculate-btn:active {
   transform: scale(0.98);
   box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15),
-              0 2px 8px rgba(38, 176, 70, 0.4) inset;
+              0 2px 8px rgba(38, 176, 70, 极端的0.4) inset;
 }
 
 .btn-text {
@@ -639,7 +574,6 @@ export default {
   font-size: 28px;
 }
 
-/* 结果卡片样式 */
 .result-card {
   width: 100%;
   margin: 0 auto;
@@ -663,18 +597,6 @@ export default {
   color: #26B046;
 }
 
-/* 表格样式 */
-.result-table {
-  padding: 20px;
-}
-
-.result-table .el-table {
-  width: 100%;
-  margin-top: 15px;
-  margin-bottom: 20px;
-}
-
-/* 图表容器 */
 .chart-container {
   margin-top: 20px;
   border: 1px solid #eee;
@@ -683,7 +605,6 @@ export default {
   background: #f9f9f9;
 }
 
-/* 地图容器样式 */
 .map-container {
   margin-top: 30px;
   padding: 20px;
@@ -734,7 +655,6 @@ export default {
   color: #666;
 }
 
-/* 返回按钮样式 */
 .back-button {
   position: absolute;
   top: 20px;