浏览代码

cd预测添加从数据库计算的按钮,修复标题居中对齐的bug

yangtaodemon 3 月之前
父节点
当前提交
62c2e515fa

+ 0 - 1
src/components/detectionStatistics/atmcompanyStatics.vue

@@ -333,7 +333,6 @@ body {
 }
 
 header {
-  text-align: center;
   padding: 20px 0;
   margin-bottom: 20px;
 }

+ 73 - 283
src/views/User/cadmiumPrediction/CropCadmiumPrediction.vue

@@ -19,6 +19,15 @@
         <el-icon class="upload-icon"><Document /></el-icon>  
         上传并计算
         </el-button>
+        <!-- 添加从数据库计算按钮 -->
+        <el-button 
+          class="custom-button" 
+          :loading="isCalculatingFromDB" 
+          @click="calculateFromDatabase"
+        >
+        <el-icon class="upload-icon"><Box /></el-icon>  
+        从数据库计算
+        </el-button>
       </div>
       <!-- 操作按钮 -->
       <div class="action-buttons">
@@ -28,9 +37,6 @@
         <el-button class="custom-button" :disabled="!histogramBlob" @click="exportHistogram">
           <el-icon class="upload-icon"><Download /></el-icon>
           导出直方图</el-button>
-        <el-button class="custom-button" :disabled="!statisticsData.length" @click="exportData">
-          <el-icon class="upload-icon"><Download /></el-icon>
-          导出数据</el-button>
       </div>
     </div>
 
@@ -50,53 +56,7 @@
         </div>
       </div>
       
-      <!-- 统计图表区域 -->
-      <div class="stats-area">
-        <h3>{{countyName}} - 作物Cd预测统计信息</h3>
-        <div class="model-info">
-          <el-tag type="info">{{currentStats?.['模型类型'] || '作物Cd模型'}}</el-tag>
-          <span class="update-time">
-            最后更新: {{currentStats?.['数据更新时间'] ? new Date(currentStats['数据更新时间']).toLocaleString() : '未知'}}
-          </span>
-        </div>
-        
-        <div v-if="loadingStats" class="loading-container">
-          <el-icon class="loading-icon"><Loading /></el-icon>
-          <span>统计数据加载中...</span>
-        </div>
-        
-        <div v-if="!loadingStats && statisticsData.length" class="stats-container">
-          <!-- 统计表格 -->
-         <el-table 
-            :data="statisticsData" 
-            style="width: 100%; margin-bottom: 20px;"
-            border
-            stripe
-          >
-            <el-table-column prop="name" label="统计项" min-width="180" />
-            <el-table-column prop="value" label="值" min-width="150" />
-            <el-table-column prop="unit" label="单位" min-width="100" />
-            <el-table-column prop="description" label="描述" min-width="200" />
-          </el-table>
-          
-          <!-- 统计图表 -->
-          <div class="charts-container">
-            <div class="chart-item">
-              <div ref="distributionChart" style="width: 100%; height: 400px;"></div>
-            </div>
-            <div class="chart-item">
-              <div ref="exceedanceChart" style="width: 100%; height: 400px;"></div>
-            </div>
-          </div>
-        </div>
-        
-        <div v-if="!loadingStats && !statisticsData.length" class="no-data">
-          <el-icon><DataAnalysis /></el-icon>
-          <p>暂无统计数据</p>
-        </div>
-      </div>
-      
-      <!-- 直方图区域 - 单独一行,放在统计信息下面 -->
+      <!-- 直方图区域 - 单独一行 -->
       <div class="histogram-section">
         <h3>作物态Cd预测直方图</h3>
         <div v-if="loadingHistogram" class="loading-container">
@@ -116,47 +76,39 @@
 <script>
 import * as XLSX from 'xlsx';
 import { saveAs } from 'file-saver';
-import { api8000 } from '@/utils/request';  // 导入api8000
-import * as echarts from 'echarts';
+import { api8000 } from '@/utils/request';
 import { 
-  Loading, Upload, Picture, Histogram, Download, Document, DataAnalysis 
+  Loading, Upload, Picture, Histogram, Download, Document, Box 
 } from '@element-plus/icons-vue';
 
 export default {
   name: 'CropCadmiumPrediction',
   components: { 
-    Loading, Upload, Picture, Histogram, Download, Document, DataAnalysis 
+    Loading, Upload, Picture, Histogram, Download, Document, Box 
   },
   data() {
     return {
       isCalculating: false,
+      isCalculatingFromDB: false,
       loadingMap: false,
       loadingHistogram: false,
-      loadingStats: false,
-      statisticsData: [],
       mapImageUrl: null,
       histogramImageUrl: null,
       mapBlob: null,
       histogramBlob: null,
       selectedFile: null,
-      countyName: '乐昌市', // 默认县市名称
-      distributionChart: null,
-      exceedanceChart: null,
-      currentStats: null
+      countyName: '乐昌市' // 默认县市名称
     };
   },
 
   mounted() {
     // 组件挂载时获取最新数据
     this.fetchLatestResults();
-    this.fetchStatistics();
   },
 
   beforeDestroy() {
     if (this.mapImageUrl) URL.revokeObjectURL(this.mapImageUrl);
     if (this.histogramImageUrl) URL.revokeObjectURL(this.histogramImageUrl);
-    if (this.distributionChart) this.distributionChart.dispose();
-    if (this.exceedanceChart) this.exceedanceChart.dispose();
   },
   methods: {
     // 触发文件选择
@@ -227,197 +179,6 @@ export default {
       }
     },
     
-    // 格式化统计数据
-    formatStatisticsData(stats) {
-      return [
-        { name: '数据点总数', value: stats['基础统计']['数据点总数'], unit: '个', description: '总样本数量' },
-        { name: '平均值', value: stats['基础统计']['均值'].toFixed(4), unit: '(mg/kg)', description: '所有样本的平均Cd含量' },
-        { name: '中位数', value: stats['基础统计']['中位数'].toFixed(4), unit: '(mg/kg)', description: '样本的中位Cd含量' },
-        { name: '标准差', value: stats['基础统计']['标准差'].toFixed(4), unit: '(mg/kg)', description: 'Cd含量的标准差' },
-        { name: '最小值', value: stats['基础统计']['最小值'].toFixed(4), unit: '(mg/kg)', description: '样本中的最小Cd含量' },
-        { name: '最大值', value: stats['基础统计']['最大值'].toFixed(4), unit: '(mg/kg)', description: '样本中的最大Cd含量' },
-        { name: '偏度', value: stats['基础统计']['偏度'].toFixed(4), unit: '', description: '数据分布偏斜程度' },
-        { name: '峰度', value: stats['基础统计']['峰度'].toFixed(4), unit: '', description: '数据分布峰态' },
-        { 
-          name: '经度范围', 
-          value: `${stats['空间统计']['经度范围']['最小值'].toFixed(6)} - ${stats['空间统计']['经度范围']['最大值'].toFixed(6)}`, 
-          unit: '度', 
-          description: `跨度: ${stats['空间统计']['经度范围']['跨度'].toFixed(6)}度` 
-        },
-        { 
-          name: '纬度范围', 
-          value: `${stats['空间统计']['纬度范围']['最小值'].toFixed(6)} - ${stats['空间统计']['纬度范围']['最大值'].toFixed(6)}`, 
-          unit: '度', 
-          description: `跨度: ${stats['空间统计']['纬度范围']['跨度'].toFixed(6)}度` 
-        }
-      ];
-    },
-
-    // 初始化图表 - 根据实际数据更新
-    initCharts() {
-      if (!this.statisticsData.length || !this.currentStats) return;
-      
-      // 销毁旧图表
-      if (this.distributionChart) this.distributionChart.dispose();
-      if (this.exceedanceChart) this.exceedanceChart.dispose();
-      
-      const histData = this.currentStats['分布直方图'];
-      
-      // 1. 分布直方图
-      this.distributionChart = echarts.init(this.$refs.distributionChart);
-      this.distributionChart.setOption({
-        title: {
-          text: 'Cd含量分布直方图',
-          left: 'center'
-        },
-        tooltip: {
-          trigger: 'item',
-          formatter: params => {
-            const index = params.dataIndex;
-            const lowerBound = histData['区间边界'][index].toFixed(4);
-            const upperBound = histData['区间边界'][index + 1].toFixed(4);
-            return `区间: ${lowerBound} ~ ${upperBound}<br/>频次: ${params.value}`;
-          }
-        },
-        xAxis: {
-          type: 'category',
-          data: histData['区间中心'].map(v => v.toFixed(4)),
-          name: 'Cd含量',
-          axisLabel: {
-            rotate: 45
-          }
-        },
-        yAxis: {
-          type: 'value',
-          name: '频次'
-        },
-        series: [{
-          name: '样本分布',
-          type: 'bar',
-          data: histData['频次'],
-          itemStyle: {
-            color: '#47C3B9'
-          },
-          barWidth: '80%'
-        }],
-        grid: {
-          bottom: '20%'
-        }
-      });
-      
-      // 2. 箱线图/统计图表
-      this.exceedanceChart = echarts.init(this.$refs.exceedanceChart);
-      
-      // 准备箱线图数据
-      const boxData = [
-        [
-          this.currentStats['基础统计']['最小值'],
-          this.currentStats['基础统计']['25%分位数'],
-          this.currentStats['基础统计']['中位数'],
-          this.currentStats['基础统计']['75%分位数'],
-          this.currentStats['基础统计']['最大值'],
-          // 还可以添加离群点数据(如果有)
-        ]
-      ];
-      
-      this.exceedanceChart.setOption({
-        title: {
-          text: 'Cd含量统计指标',
-          left: 'center'
-        },
-        tooltip: {
-          trigger: 'item',
-          axisPointer: {
-            type: 'shadow'
-          },
-          formatter: params => {
-            const data = boxData[0];
-            return [
-              '最大值: ' + data[4].toFixed(4),
-              '75%分位数: ' + data[3].toFixed(4),
-              '中位数: ' + data[2].toFixed(4),
-              '25%分位数: ' + data[1].toFixed(4),
-              '最小值: ' + data[0].toFixed(4)
-            ].join('<br/>');
-          }
-        },
-        xAxis: {
-          type: 'category',
-          data: ['Cd含量统计'],
-          axisLabel: {
-            rotate: 45
-          }
-        },
-        yAxis: {
-          type: 'value',
-          name: '(Cd含量)'
-        },
-        series: [{
-          name: '统计值',
-          type: 'boxplot',
-          data: boxData,
-          itemStyle: {
-            color: '#47C3B9',
-            borderColor: '#2F4554'
-          },
-          emphasis: {
-            itemStyle: {
-              color: '#FF6B6B',
-              borderColor: '#C23531'
-            }
-          },
-          tooltip: {
-            formatter: param => {
-              const data = boxData[0];
-              return [
-                '最大值: ' + data[4].toFixed(4),
-                '75%分位数: ' + data[3].toFixed(4),
-                '中位数: ' + data[2].toFixed(4),
-                '25%分位数: ' + data[1].toFixed(4),
-                '最小值: ' + data[0].toFixed(4)
-            ].join('<br/>');
-            }
-          }
-        }],
-        grid: {
-          bottom: '15%'
-        }
-      });
-      
-      // 响应式调整
-      window.addEventListener('resize', this.handleResize);
-    },
-
-    // 修改fetchStatistics方法
-    async fetchStatistics() {
-      try {
-        this.loadingStats = true;
-        
-        const response = await api8000.get(
-          `/api/cd-prediction/crop-cd/statistics/${this.countyName}`
-        );
-        
-        if (response.data.success && response.data.data) {
-          this.currentStats = response.data.data; // 保存原始统计数据
-          this.statisticsData = this.formatStatisticsData(response.data.data);
-          this.$nextTick(() => {
-            this.initCharts();
-          });
-        }
-      } catch (error) {
-        console.error('获取统计信息失败:', error);
-        this.$message.warning('获取统计信息失败');
-      } finally {
-        this.loadingStats = false;
-      }
-    },
-    
-    // 处理窗口大小变化
-    handleResize() {
-      if (this.distributionChart) this.distributionChart.resize();
-      if (this.exceedanceChart) this.exceedanceChart.resize();
-    },
-    
     // 上传并计算
     async calculate() {
       if (!this.selectedFile) {
@@ -429,12 +190,12 @@ export default {
         this.isCalculating = true;
         this.loadingMap = true;
         this.loadingHistogram = true;
-        this.loadingStats = true;
         
         // 创建FormData
         const formData = new FormData();
-        formData.append('county_name', this.countyName);
+        formData.append('area', this.countyName);
         formData.append('data_file', this.selectedFile);
+        formData.append('use_database', 'false'); // 使用上传的文件
         
         // 调用作物Cd地图接口
         const mapResponse = await api8000.post(
@@ -452,9 +213,8 @@ export default {
         this.mapBlob = mapResponse.data;
         this.mapImageUrl = URL.createObjectURL(this.mapBlob);
         
-        // 更新后重新获取直方图和统计数据
+        // 更新后重新获取直方图
         await this.fetchLatestHistogram();
-        await this.fetchStatistics();
         
         this.$message.success('计算完成!');
         
@@ -477,7 +237,61 @@ export default {
         this.isCalculating = false;
         this.loadingMap = false;
         this.loadingHistogram = false;
-        this.loadingStats = false;
+      }
+    },
+    
+    // 从数据库计算
+    async calculateFromDatabase() {
+      try {
+        this.isCalculatingFromDB = true;
+        this.loadingMap = true;
+        this.loadingHistogram = true;
+        
+        // 创建FormData
+        const formData = new FormData();
+        formData.append('area', this.countyName);
+        formData.append('use_database', 'true'); // 使用数据库数据
+        
+        // 调用作物Cd地图接口
+        const mapResponse = await api8000.post(
+          '/api/cd-prediction/crop-cd/generate-and-get-map',
+          formData,
+          {
+            headers: {
+              'Content-Type': 'multipart/form-data'
+            },
+            responseType: 'blob'
+          }
+        );
+        
+        // 保存地图数据
+        this.mapBlob = mapResponse.data;
+        this.mapImageUrl = URL.createObjectURL(this.mapBlob);
+        
+        // 更新后重新获取直方图
+        await this.fetchLatestHistogram();
+        
+        this.$message.success('数据库计算完成!');
+        
+      } catch (error) {
+        console.error('从数据库计算失败:', error);
+        let errorMessage = '数据库计算失败,请重试';
+        
+        if (error.response) {
+          if (error.response.status === 400) {
+            errorMessage = '参数错误:' + (error.response.data.detail || '请检查县市名称');
+          } else if (error.response.status === 404) {
+            errorMessage = '不支持的县市:' + this.countyName;
+          } else if (error.response.status === 500) {
+            errorMessage = '服务器错误:' + (error.response.data.detail || '请稍后重试');
+          }
+        }
+        
+        this.$message.error(errorMessage);
+      } finally {
+        this.isCalculatingFromDB = false;
+        this.loadingMap = false;
+        this.loadingHistogram = false;
       }
     },
     
@@ -508,30 +322,6 @@ export default {
       link.click();
       URL.revokeObjectURL(link.href);
     },
-    
-    // 导出数据 - 修改为获取作物Cd的CSV文件
-    async exportData() {
-      try {
-        this.$message.info('正在获取作物Cd预测数据...');
-        
-        const response = await api8000.get(
-          `/api/cd-prediction/download-final-crop-cd-csv`,
-          { responseType: 'blob' }
-        );
-        
-        const blob = new Blob([response.data], { type: 'text/csv' });
-        const link = document.createElement('a');
-        link.href = URL.createObjectURL(blob);
-        link.download = `${this.countyName}_作物Cd预测数据.csv`;
-        link.click();
-        URL.revokeObjectURL(link.href);
-        
-        this.$message.success('数据导出成功');
-      } catch (error) {
-        console.error('导出数据失败:', error);
-        this.$message.error('导出数据失败: ' + (error.response?.data?.detail || '请稍后重试'));
-      }
-    }
   }
 };
 </script>

+ 74 - 269
src/views/User/cadmiumPrediction/EffectiveCadmiumPrediction.vue

@@ -19,6 +19,15 @@
         <el-icon class="upload-icon"><Document /></el-icon>  
         上传并计算
         </el-button>
+        <!-- 添加从数据库计算按钮 -->
+        <el-button 
+          class="custom-button" 
+          :loading="isCalculatingFromDB" 
+          @click="calculateFromDatabase"
+        >
+        <el-icon class="upload-icon"><Box /></el-icon>  
+        从数据库计算
+        </el-button>
       </div>
       <!-- 操作按钮 -->
       <div class="action-buttons">
@@ -28,9 +37,6 @@
         <el-button class="custom-button" :disabled="!histogramBlob" @click="exportHistogram">
           <el-icon class="upload-icon"><Download /></el-icon>
           导出直方图</el-button>
-        <el-button class="custom-button" :disabled="!statisticsData.length" @click="exportData">
-          <el-icon class="upload-icon"><Download /></el-icon>
-          导出数据</el-button>
       </div>
     </div>
 
@@ -50,52 +56,6 @@
         </div>
       </div>
       
-      <!-- 统计图表区域 -->
-      <div class="stats-area">
-        <h3>{{countyName}} - 有效Cd预测统计信息</h3>
-        <div class="model-info">
-          <el-tag type="info">{{currentStats?.['模型类型'] || '有效Cd模型'}}</el-tag>
-          <span class="update-time">
-            最后更新: {{currentStats?.['数据更新时间'] ? new Date(currentStats['数据更新时间']).toLocaleString() : '未知'}}
-          </span>
-        </div>
-        
-        <div v-if="loadingStats" class="loading-container">
-          <el-icon class="loading-icon"><Loading /></el-icon>
-          <span>统计数据加载中...</span>
-        </div>
-        
-        <div v-if="!loadingStats && statisticsData.length" class="stats-container">
-          <!-- 统计表格 -->
-         <el-table 
-            :data="statisticsData" 
-            style="width: 100%; margin-bottom: 20px;"
-            border
-            stripe
-          >
-            <el-table-column prop="name" label="统计项" min-width="180" />
-            <el-table-column prop="value" label="值" min-width="150" />
-            <el-table-column prop="unit" label="单位" min-width="100" />
-            <el-table-column prop="description" label="描述" min-width="200" />
-          </el-table>
-          
-          <!-- 统计图表 -->
-          <div class="charts-container">
-            <div class="chart-item">
-              <div ref="distributionChart" style="width: 100%; height: 400px;"></div>
-            </div>
-            <div class="chart-item">
-              <div ref="exceedanceChart" style="width: 100%; height: 400px;"></div>
-            </div>
-          </div>
-        </div>
-        
-        <div v-if="!loadingStats && !statisticsData.length" class="no-data">
-          <el-icon><DataAnalysis /></el-icon>
-          <p>暂无统计数据</p>
-        </div>
-      </div>
-      
       <!-- 直方图区域 - 单独一行,放在统计信息下面 -->
       <div class="histogram-section">
         <h3>有效态Cd预测直方图</h3>
@@ -116,47 +76,40 @@
 <script>
 import * as XLSX from 'xlsx';
 import { saveAs } from 'file-saver';
-import { api8000 } from '@/utils/request';  // 导入api8000
+import { api8000 } from '@/utils/request';
 import * as echarts from 'echarts';
 import { 
-  Loading, Upload, Picture, Histogram, Download, Document, DataAnalysis 
+  Loading, Upload, Picture, Histogram, Download, Document, Box 
 } from '@element-plus/icons-vue';
 
 export default {
-  name: 'CropCadmiumPrediction',
+  name: 'EffectiveCadmiumPrediction',
   components: { 
-    Loading, Upload, Picture, Histogram, Download, Document, DataAnalysis 
+    Loading, Upload, Picture, Histogram, Download, Document, Box 
   },
   data() {
     return {
       isCalculating: false,
+      isCalculatingFromDB: false,
       loadingMap: false,
       loadingHistogram: false,
-      loadingStats: false,
-      statisticsData: [],
       mapImageUrl: null,
       histogramImageUrl: null,
       mapBlob: null,
       histogramBlob: null,
       selectedFile: null,
-      countyName: '乐昌市', // 默认县市名称
-      distributionChart: null,
-      exceedanceChart: null,
-      currentStats: null
+      countyName: '乐昌市' // 默认县市名称
     };
   },
 
   mounted() {
     // 组件挂载时获取最新数据
     this.fetchLatestResults();
-    this.fetchStatistics();
   },
 
   beforeDestroy() {
     if (this.mapImageUrl) URL.revokeObjectURL(this.mapImageUrl);
     if (this.histogramImageUrl) URL.revokeObjectURL(this.histogramImageUrl);
-    if (this.distributionChart) this.distributionChart.dispose();
-    if (this.exceedanceChart) this.exceedanceChart.dispose();
   },
   methods: {
     // 触发文件选择
@@ -227,197 +180,6 @@ export default {
       }
     },
     
-    // 格式化统计数据
-    formatStatisticsData(stats) {
-      return [
-        { name: '数据点总数', value: stats['基础统计']['数据点总数'], unit: '个', description: '总样本数量' },
-        { name: '平均值', value: stats['基础统计']['均值'].toFixed(4), unit: '(mg/kg)', description: '所有样本的平均Cd含量' },
-        { name: '中位数', value: stats['基础统计']['中位数'].toFixed(4), unit: '(mg/kg)', description: '样本的中位Cd含量' },
-        { name: '标准差', value: stats['基础统计']['标准差'].toFixed(4), unit: '(mg/kg)', description: 'Cd含量的标准差' },
-        { name: '最小值', value: stats['基础统计']['最小值'].toFixed(4), unit: '(mg/kg)', description: '样本中的最小Cd含量' },
-        { name: '最大值', value: stats['基础统计']['最大值'].toFixed(4), unit: '(mg/kg)', description: '样本中的最大Cd含量' },
-        { name: '偏度', value: stats['基础统计']['偏度'].toFixed(4), unit: '', description: '数据分布偏斜程度' },
-        { name: '峰度', value: stats['基础统计']['峰度'].toFixed(4), unit: '', description: '数据分布峰态' },
-        { 
-          name: '经度范围', 
-          value: `${stats['空间统计']['经度范围']['最小值'].toFixed(6)} - ${stats['空间统计']['经度范围']['最大值'].toFixed(6)}`, 
-          unit: '度', 
-          description: `跨度: ${stats['空间统计']['经度范围']['跨度'].toFixed(6)}度` 
-        },
-        { 
-          name: '纬度范围', 
-          value: `${stats['空间统计']['纬度范围']['最小值'].toFixed(6)} - ${stats['空间统计']['纬度范围']['最大值'].toFixed(6)}`, 
-          unit: '度', 
-          description: `跨度: ${stats['空间统计']['纬度范围']['跨度'].toFixed(6)}度` 
-        }
-      ];
-    },
-
-    // 初始化图表 - 根据实际数据更新
-    initCharts() {
-      if (!this.statisticsData.length || !this.currentStats) return;
-      
-      // 销毁旧图表
-      if (this.distributionChart) this.distributionChart.dispose();
-      if (this.exceedanceChart) this.exceedanceChart.dispose();
-      
-      const histData = this.currentStats['分布直方图'];
-      
-      // 1. 分布直方图
-      this.distributionChart = echarts.init(this.$refs.distributionChart);
-      this.distributionChart.setOption({
-        title: {
-          text: 'Cd含量分布直方图',
-          left: 'center'
-        },
-        tooltip: {
-          trigger: 'item',
-          formatter: params => {
-            const index = params.dataIndex;
-            const lowerBound = histData['区间边界'][index].toFixed(4);
-            const upperBound = histData['区间边界'][index + 1].toFixed(4);
-            return `区间: ${lowerBound} ~ ${upperBound}<br/>频次: ${params.value}`;
-          }
-        },
-        xAxis: {
-          type: 'category',
-          data: histData['区间中心'].map(v => v.toFixed(4)),
-          name: 'Cd含量',
-          axisLabel: {
-            rotate: 45
-          }
-        },
-        yAxis: {
-          type: 'value',
-          name: '频次'
-        },
-        series: [{
-          name: '样本分布',
-          type: 'bar',
-          data: histData['频次'],
-          itemStyle: {
-            color: '#47C3B9'
-          },
-          barWidth: '80%'
-        }],
-        grid: {
-          bottom: '20%'
-        }
-      });
-      
-      // 2. 箱线图/统计图表
-      this.exceedanceChart = echarts.init(this.$refs.exceedanceChart);
-      
-      // 准备箱线图数据
-      const boxData = [
-        [
-          this.currentStats['基础统计']['最小值'],
-          this.currentStats['基础统计']['25%分位数'],
-          this.currentStats['基础统计']['中位数'],
-          this.currentStats['基础统计']['75%分位数'],
-          this.currentStats['基础统计']['最大值'],
-          // 还可以添加离群点数据(如果有)
-        ]
-      ];
-      
-      this.exceedanceChart.setOption({
-        title: {
-          text: 'Cd含量统计指标',
-          left: 'center'
-        },
-        tooltip: {
-          trigger: 'item',
-          axisPointer: {
-            type: 'shadow'
-          },
-          formatter: params => {
-            const data = boxData[0];
-            return [
-              '最大值: ' + data[4].toFixed(4),
-              '75%分位数: ' + data[3].toFixed(4),
-              '中位数: ' + data[2].toFixed(4),
-              '25%分位数: ' + data[1].toFixed(4),
-              '最小值: ' + data[0].toFixed(4)
-            ].join('<br/>');
-          }
-        },
-        xAxis: {
-          type: 'category',
-          data: ['Cd含量统计'],
-          axisLabel: {
-            rotate: 45
-          }
-        },
-        yAxis: {
-          type: 'value',
-          name: '(Cd含量)'
-        },
-        series: [{
-          name: '统计值',
-          type: 'boxplot',
-          data: boxData,
-          itemStyle: {
-            color: '#47C3B9',
-            borderColor: '#2F4554'
-          },
-          emphasis: {
-            itemStyle: {
-              color: '#FF6B6B',
-              borderColor: '#C23531'
-            }
-          },
-          tooltip: {
-            formatter: param => {
-              const data = boxData[0];
-              return [
-                '最大值: ' + data[4].toFixed(4),
-                '75%分位数: ' + data[3].toFixed(4),
-                '中位数: ' + data[2].toFixed(4),
-                '25%分位数: ' + data[1].toFixed(4),
-                '最小值: ' + data[0].toFixed(4)
-            ].join('<br/>');
-            }
-          }
-        }],
-        grid: {
-          bottom: '15%'
-        }
-      });
-      
-      // 响应式调整
-      window.addEventListener('resize', this.handleResize);
-    },
-
-    // 修改fetchStatistics方法
-    async fetchStatistics() {
-      try {
-        this.loadingStats = true;
-        
-        const response = await api8000.get(
-          `/api/cd-prediction/effective-cd/statistics/${this.countyName}`
-        );
-        
-        if (response.data.success && response.data.data) {
-          this.currentStats = response.data.data; // 保存原始统计数据
-          this.statisticsData = this.formatStatisticsData(response.data.data);
-          this.$nextTick(() => {
-            this.initCharts();
-          });
-        }
-      } catch (error) {
-        console.error('获取统计信息失败:', error);
-        this.$message.warning('获取统计信息失败');
-      } finally {
-        this.loadingStats = false;
-      }
-    },
-    
-    // 处理窗口大小变化
-    handleResize() {
-      if (this.distributionChart) this.distributionChart.resize();
-      if (this.exceedanceChart) this.exceedanceChart.resize();
-    },
-    
     // 上传并计算
     async calculate() {
       if (!this.selectedFile) {
@@ -429,12 +191,12 @@ export default {
         this.isCalculating = true;
         this.loadingMap = true;
         this.loadingHistogram = true;
-        this.loadingStats = true;
         
         // 创建FormData
         const formData = new FormData();
-        formData.append('county_name', this.countyName);
+        formData.append('area', this.countyName);
         formData.append('data_file', this.selectedFile);
+        formData.append('use_database', 'false'); // 使用上传的文件
         
         // 调用有效Cd地图接口
         const mapResponse = await api8000.post(
@@ -452,9 +214,8 @@ export default {
         this.mapBlob = mapResponse.data;
         this.mapImageUrl = URL.createObjectURL(this.mapBlob);
         
-        // 更新后重新获取直方图和统计数据
+        // 更新后重新获取直方图
         await this.fetchLatestHistogram();
-        await this.fetchStatistics();
         
         this.$message.success('计算完成!');
         
@@ -477,7 +238,61 @@ export default {
         this.isCalculating = false;
         this.loadingMap = false;
         this.loadingHistogram = false;
-        this.loadingStats = false;
+      }
+    },
+    
+    // 从数据库计算
+    async calculateFromDatabase() {
+      try {
+        this.isCalculatingFromDB = true;
+        this.loadingMap = true;
+        this.loadingHistogram = true;
+        
+        // 创建FormData
+        const formData = new FormData();
+        formData.append('area', this.countyName);
+        formData.append('use_database', 'true'); // 使用数据库数据
+        
+        // 调用有效Cd地图接口
+        const mapResponse = await api8000.post(
+          '/api/cd-prediction/effective-cd/generate-and-get-map',
+          formData,
+          {
+            headers: {
+              'Content-Type': 'multipart/form-data'
+            },
+            responseType: 'blob'
+          }
+        );
+        
+        // 保存地图数据
+        this.mapBlob = mapResponse.data;
+        this.mapImageUrl = URL.createObjectURL(this.mapBlob);
+        
+        // 更新后重新获取直方图
+        await this.fetchLatestHistogram();
+        
+        this.$message.success('数据库计算完成!');
+        
+      } catch (error) {
+        console.error('从数据库计算失败:', error);
+        let errorMessage = '数据库计算失败,请重试';
+        
+        if (error.response) {
+          if (error.response.status === 400) {
+            errorMessage = '参数错误:' + (error.response.data.detail || '请检查县市名称');
+          } else if (error.response.status === 404) {
+            errorMessage = '不支持的县市:' + this.countyName;
+          } else if (error.response.status === 500) {
+            errorMessage = '服务器错误:' + (error.response.data.detail || '请稍后重试');
+          }
+        }
+        
+        this.$message.error(errorMessage);
+      } finally {
+        this.isCalculatingFromDB = false;
+        this.loadingMap = false;
+        this.loadingHistogram = false;
       }
     },
     
@@ -509,7 +324,7 @@ export default {
       URL.revokeObjectURL(link.href);
     },
     
-    // 导出数据 - 修改为获取有效Cd的CSV文件
+    // 导出数据
     async exportData() {
       try {
         this.$message.info('正在获取有效Cd预测数据...');
@@ -624,16 +439,6 @@ export default {
   border-radius: 4px;
 }
 
-/* 统计图表区域 */
-.stats-area {
-  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;
-  backdrop-filter: blur(5px); /* 添加模糊效果增强半透明感 */
-}
-
 /* 直方图区域 */
 .histogram-section {
   background-color: rgba(255, 255, 255, 0.8); /* 调整为半透明白色 */