Browse Source

合并错误

yangtaodemon 3 months ago
parent
commit
fcfec48c24

+ 0 - 1
components.d.ts

@@ -77,7 +77,6 @@ declare module 'vue' {
     Irrwatermap: typeof import('./src/components/irrpollution/irrwatermap.vue')['default']
     PaginationComponent: typeof import('./src/components/PaginationComponent.vue')['default']
     ReducedataStatistics: typeof import('./src/components/soilStatictics/reducedataStatistics.vue')['default']
-    RefluxcdStatictics: typeof import('./src/components/soilStatictics/refluxcdStatictics.vue')['default']
     RefluxcedataStatictics: typeof import('./src/components/soilStatictics/refluxcedataStatictics.vue')['default']
     Riverwaterassay: typeof import('./src/components/irrpollution/riverwaterassay.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']

+ 0 - 310
src/components/cdStatictics/reducedataStatistics.vue

@@ -1,310 +0,0 @@
-<template>
-  <div class="chart-container">
-    <div v-if="loading" class="loading">
-      <p>数据加载中...</p>
-    </div>
-    <div v-if="error" class="error">
-      <p>{{ error }}</p>
-      <button @click="fetchData">重试</button>
-    </div>
-    <div ref="chartRef" class="chart"></div>
-  </div>
-</template>
-
-<script>
-import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
-import * as echarts from 'echarts';
-import { api5000 } from '@/utils/request'; // 导入 api5000 实例
-
-export default {
-  name: 'HeavyMetalChart',
-  setup() {
-    // 接口数据 - 使用相对路径
-    const interfaces = [
-      { time: '20241229_201018', url: '/api/table-averages?table_name=dataset_5' },
-      { time: '20250104_171827', url: '/api/table-averages?table_name=dataset_35' },
-      { time: '20250104_171959', url: '/api/table-averages?table_name=dataset_36' },
-      { time: '20250104_214026', url: '/api/table-averages?table_name=dataset_37' },
-      { time: '20250308_161945', url: '/api/table-averages?table_name=dataset_65' },
-      { time: '20250308_163248', url: '/api/table-averages?table_name=dataset_66' },
-    ];
-    
-    const chartRef = ref(null);
-    const loading = ref(true);
-    const error = ref(null);
-    const selectedData = ref('Al');
-    const displayOption = ref('all');
-    const lastUpdate = ref(new Date().toLocaleString());
-    
-    const chartData = ref({
-      timestamps: [],
-      series: {
-        Al: [],
-        CL: [],
-        H: [],
-        OM: [],
-        Q_over_b: [],
-        pH: []
-      }
-    });
-    
-    let chartInstance = null;
-    
-    // 获取数据
-    async function fetchData() {
-      try {
-        loading.value = true;
-        error.value = null;
-        
-        // 使用 api5000 实例获取数据
-        const responses = await Promise.all(
-          interfaces.map(intf => 
-            api5000.get(intf.url)
-              .then(response => {
-                const data = response.data;
-                if (data.success !== "true" && data.success !== true) {
-                  throw new Error('接口返回失败状态');
-                }
-                return { time: intf.time, data: data.averages };
-              })
-              .catch(err => {
-                throw new Error(`请求失败: ${err.message}`);
-              })
-          )
-        );
-        
-        // 处理数据 - 直接使用原始时间字符串
-        chartData.value.timestamps = responses.map(item => item.time);
-        
-        // 初始化所有数据系列,并将数值固定为小数点后五位
-        Object.keys(chartData.value.series).forEach(key => {
-          chartData.value.series[key] = responses.map(item => {
-            const value = parseFloat(item.data[key]);
-            return isNaN(value) ? null : parseFloat(value.toFixed(5));
-          });
-        });
-        
-        renderChart();
-        lastUpdate.value = new Date().toLocaleString();
-      } catch (err) {
-        error.value = '获取数据失败: ' + err.message;
-        console.error('获取数据错误:', err);
-      } finally {
-        loading.value = false;
-      }
-    }
-    
-    // 渲染图表
-    function renderChart() {
-      if (!chartRef.value) return;
-      
-      // 初始化或更新ECharts实例
-      if (!chartInstance) {
-        chartInstance = echarts.init(chartRef.value);
-      }
-      
-      // 准备系列数据
-      const series = [];
-      
-      if (displayOption.value === 'all') {
-        // 显示所有数据
-        Object.keys(chartData.value.series).forEach(key => {
-          series.push({
-            name: key,
-            type: 'line',
-            symbol: 'circle',
-            symbolSize: 6,
-            data: chartData.value.series[key],
-            lineStyle: { width: 2 },
-            emphasis: {
-              focus: 'series'
-            }
-          });
-        });
-      } else {
-        // 显示选定的单个数据
-        series.push({
-          name: selectedData.value,
-          type: 'line',
-          symbol: 'circle',
-          symbolSize: 6,
-          data: chartData.value.series[selectedData.value],
-          lineStyle: { width: 2 },
-          emphasis: {
-            focus: 'series'
-          }
-        });
-      }
-      
-      const option = {
-        title: {
-          text: displayOption.value === 'all' ? '酸化缓解数据趋势图' : `${selectedData.value} 数据趋势`,
-          left: 'center',
-          top: 10
-        },
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            type: 'cross',
-            label: {
-              backgroundColor: '#6a7985'
-            }
-          },
-          // 格式化tooltip中的数值为小数点后五位
-          formatter: function(params) {
-            let result = params[0].name + '<br/>';
-            params.forEach(param => {
-              const value = param.value === null ? '无数据' : parseFloat(param.value).toFixed(5);
-              result += `${param.seriesName}: ${value}<br/>`;
-            });
-            return result;
-          }
-        },
-        legend: {
-          data: displayOption.value === 'all' ? Object.keys(chartData.value.series) : [selectedData.value],
-          top: 40,
-          type: 'scroll'
-        },
-        grid: {
-          left: '15%',
-          right: '4%',
-          bottom: '3%',
-          top: '80px',
-          containLabel: true
-        },
-        xAxis: {
-          type: 'category',
-          boundaryGap: false,
-          data: chartData.value.timestamps, // 直接使用原始时间字符串
-          axisLabel: {
-            rotate: 30,
-            fontSize: 12,
-            interval: 0, // 强制显示所有标签
-            formatter: (value) => value.replace('_', ' ') // 优化时间显示
-          }
-        },
-        yAxis: {
-          type: 'value',
-          scale: true,
-          // 格式化y轴标签为小数点后五位
-          axisLabel: {
-            formatter: function(value) {
-              return parseFloat(value).toFixed(5);
-            }
-          }
-        },
-        series: series,
-        color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272'] // 自定义颜色方案
-      };
-      
-      chartInstance.setOption(option);
-      chartInstance.resize();
-    }
-    
-    // 刷新数据
-    function refreshData() {
-      fetchData();
-    }
-    
-    onMounted(() => {
-      fetchData().then(() => {
-        // 等待 Vue 完成 DOM 更新
-        nextTick(() => {
-          if (chartInstance) {
-            chartInstance.resize();
-          }
-        });
-      });
-
-      // 窗口 resize 监听
-      const handleResize = () => {
-        if (chartInstance) {
-          chartInstance.resize();
-        }
-      };
-      
-      window.addEventListener('resize', handleResize);
-      
-      onUnmounted(() => {
-        window.removeEventListener('resize', handleResize);
-        if (chartInstance) {
-          chartInstance.dispose();
-        }
-      });
-    });
-    
-    // 监听显示选项变化
-    watch([selectedData, displayOption], () => {
-      renderChart();
-    });
-    
-    return {
-      chartRef,
-      loading,
-      error,
-      chartData,
-      selectedData,
-      displayOption,
-      lastUpdate,
-      refreshData,
-      fetchData // 暴露fetchData用于重试
-    };
-  }
-}
-</script>
-
-<style scoped>
-.chart-container {
-  width: 100%;
-  padding: 20px;
-  height: 470px;
-  box-sizing: border-box;
-  position: relative;
-}
-
-.chart {
-  width: 100%;
-  height: 100%;
-  margin-bottom: 20px;
-}
-
-.loading {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(255, 255, 255, 0.8);
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  z-index: 10;
-}
-
-.error {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(255, 255, 255, 0.8);
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  z-index: 10;
-  color: #f56c6c;
-  padding: 20px;
-  text-align: center;
-}
-
-.error button {
-  margin-top: 15px;
-  padding: 8px 16px;
-  background: #f56c6c;
-  color: white;
-  border: none;
-  border-radius: 4px;
-  cursor: pointer;
-}
-</style>

+ 0 - 341
src/components/cdStatictics/refluxcdStatictics.vue

@@ -1,341 +0,0 @@
-<template>
-  <div class="container">    
-    <div class="chart-container">
-      <div v-if="isLoading" class="loading-overlay">
-        <div class="spinner"></div>
-        <span class="loading-text">数据加载中...</span>
-      </div>
-      <div v-if="error" class="error-overlay">
-        <p>{{ errorMessage }}</p>
-        <button class="retry-btn" @click="loadData">重试</button>
-      </div>
-      <div ref="chartRef" class="chart-wrapper"></div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import { ref, onMounted, onUnmounted, nextTick } from 'vue' 
-import * as echarts from 'echarts' 
-import { api5000 } from '@/utils/request'; // 导入 api5000 实例
-
-const indicators = [
-  { key: 'Delta_pH', name: 'Delta_pH', color: '#f39c12' }
-];
-
-let chart = ref(null) // 存储 ECharts 实例
-let chartData = ref([]) // 存储图表数据
-const chartRef = ref(null) // 图表容器
-const statsByIndex = ref([]); // 存储每个指标的统计量
-const isLoading = ref(true);
-const error = ref(false);
-const errorMessage = ref('');
-
-function initChart() {
-  // 确保图表容器已渲染
-  if (!chartRef.value) return;
-  
-  // 初始化 ECharts 实例
-  chart.value = echarts.init(chartRef.value);
-  
-  const option = {
-    tooltip: {
-      trigger: 'item',
-      axisPointer: { type: 'shadow' },
-      formatter: function(params) {
-        const stat = statsByIndex.value[params.dataIndex];
-        if (!stat || stat.min === null) {
-          return `<div style="font-weight:bold;margin-bottom:8px;color:#2c3e50;">${params.name}</div>
-                  <div>无有效数据</div>`;
-        }  
-        return `
-          <div style="font-weight:bold;margin-bottom:8px;color:#2c3e50;">${stat.name}</div>
-          <div style="display:grid;grid-template-columns:1fr 1fr;gap:5px;">
-            <span style="color:#7f8c8d;">最小值:</span> <span style="text-align:right;font-weight:bold;">${stat.min}</span>
-            <span style="color:#7f8c8d;">下四分位:</span> <span style="text-align:right;font-weight:bold;color:#e74c3c;">${stat.q1}</span>
-            <span style="color:#7f8c8d;">中位数:</span> <span style="text-align:right;font-weight:bold;color:#3498db;">${stat.median}</span>
-            <span style="color:#7f8c8d;">上四分位:</span> <span style="text-align:right;font-weight:bold;color:#e74c3c;">${stat.q3}</span>
-            <span style="color:#7f8c8d;">最大值:</span> <span style="text-align:right;font-weight:bold;">${stat.max}</span>
-          </div>
-        `;
-      }
-    },
-    title: {
-      text: '酸化加剧指标箱线图展示',
-      left: 'center',
-      textStyle: {
-        fontSize: 18,
-        fontWeight: 'normal'
-      },
-      top: 10
-    },
-    grid: {
-      left: '0px',
-      right: '0px',
-      bottom: '0px',
-      top: '70px',
-      containLabel: true
-    },
-    xAxis: {
-      type: 'category',
-      data: indicators.map(i => i.name),
-      axisLabel: {
-        rotate: 30,
-        fontSize: 12,
-        margin: 15
-      },
-      axisTick: {
-        alignWithLabel: true
-      },
-    },
-    yAxis: {
-      type: 'value',
-      name: '数值',
-      nameTextStyle: {
-        fontSize: 14
-      },
-      nameGap: 25,
-      splitLine: {
-        lineStyle: {
-          type: 'dashed',
-          color: '#ddd'
-        }
-      }
-    },
-    series: [{
-      name: '指标分布',
-      type: 'boxplot',
-      itemStyle: {
-        color: function(params) {
-          return indicators[params.dataIndex].color;
-        },
-        borderWidth: 2
-      },
-      emphasis: {
-        itemStyle: {
-          shadowBlur: 10,
-          shadowColor: 'rgba(0, 0, 0, 0.3)'
-        }
-      }
-    }]
-  };
-  
-  chart.value.setOption(option);
-}
-
-
-function calculatePercentile(sortedArray, percentile) {
-  const n = sortedArray.length;
-  if (n === 0) return null;
-  if (percentile <= 0) return sortedArray[0];
-  if (percentile >= 100) return sortedArray[n - 1];
-  
-  const index = (n - 1) * (percentile / 100);
-  const lowerIndex = Math.floor(index);
-  const upperIndex = lowerIndex + 1;
-  const fraction = index - lowerIndex;
-  
-  if (upperIndex >= n) return sortedArray[lowerIndex];
-  return sortedArray[lowerIndex] + fraction * (sortedArray[upperIndex] - sortedArray[lowerIndex]);
-}
-
-
-function calculateBoxplotStats(data, indicators) {
-  const boxplotData = [];
-  const statsArray = [];
-  
-  indicators.forEach(indicator => {
-    const values = data
-      .map(item => Number(item[indicator.key]))
-      .filter(val => !isNaN(val))
-      .sort((a, b) => a - b);
-    
-    if (values.length === 0) {
-      boxplotData.push([null, null, null, null, null]);
-      statsArray.push({
-        min: null, q1: null, median: null, q3: null, max: null,
-        name: indicator.name,
-        color: indicator.color
-      });
-    } else {
-      const min = Math.min(...values);
-      const max = Math.max(...values);
-      const q1 = calculatePercentile(values, 25);
-      const median = calculatePercentile(values, 50);
-      const q3 = calculatePercentile(values, 75);
-      boxplotData.push([min, q1, median, q3, max]);
-      
-      statsArray.push({
-        min, q1, median, q3, max,
-        name: indicator.name,
-        color: indicator.color
-      });
-    }
-  });
-  
-  return { boxplotData, statsArray };
-}
-
-
-async function loadData() {
-  isLoading.value = true;
-  error.value = false;
-  errorMessage.value = '';
-  
-  try {
-    // 使用 api5000 实例获取数据
-    const response = await api5000.get('/api/table-data?table_name=dataset_60');
-    const result = response.data;
-    
-    // 检查响应是否成功
-    if (!result || !result.data) {
-      throw new Error('接口返回数据格式不正确');
-    }
-    
-    chartData.value = result.data;
-
-    const { boxplotData, statsArray } = calculateBoxplotStats(chartData.value, indicators);
-    statsByIndex.value = statsArray;
-    
-    // 确保图表已初始化
-    if (!chart.value) {
-      initChart();
-    }
-    
-    chart.value.setOption({
-      series: [{
-        data: boxplotData
-      }]
-    });
-    
-  } catch (err) {
-    error.value = true;
-    errorMessage.value = `加载失败: ${err.message || '网络错误'}`;
-    console.error('数据加载失败:', err);
-  } finally {
-    isLoading.value = false;
-  }
-}
-
-const handleResize = () => {
-  if (chart.value) {
-    chart.value.resize();
-  }
-};
-
-onMounted(() => {
-  nextTick(() => {
-    initChart();
-    loadData();
-  });
-  window.addEventListener('resize', handleResize);
-});
-
-onUnmounted(() => {
-  if (chart.value) {
-    chart.value.dispose(); // 销毁 ECharts 实例
-    chart.value = null;
-  }
-  window.removeEventListener('resize', handleResize);
-});
-</script>
-
-<style scoped>
-* {
-  margin: 0;
-  padding: 0;
-  box-sizing: border-box;
-  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
-}
-
-.container {
-  width: 100%;
-  height: 100%;
-  margin: 0 auto;
-  background: white;
-  border-radius: 12px;
-  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
-  overflow: hidden;
-}
-.chart-container {
-  width: 100%;
-  height: 100%;
-  padding: 20px;
-  position: relative;
-}
-.chart-wrapper {
-  width: 100%;
-  height: 100%; 
-  min-height: 200px;
-}
-
-.loading-overlay {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(255, 255, 255, 0.8);
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  z-index: 10;
-}
-
-.spinner {
-  width: 40px;
-  height: 40px;
-  border: 4px solid rgba(0, 0, 0, 0.1);
-  border-radius: 50%;
-  border-left-color: #3498db;
-  animation: spin 1s linear infinite;
-}
-
-.loading-text {
-  margin-top: 15px;
-  font-size: 16px;
-  color: #2c3e50;
-}
-
-.error-overlay {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: rgba(255, 255, 255, 0.9);
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  z-index: 10;
-  padding: 20px;
-  text-align: center;
-}
-
-.error-overlay p {
-  color: #e74c3c;
-  font-size: 16px;
-  margin-bottom: 20px;
-}
-
-.retry-btn {
-  padding: 8px 16px;
-  background: #3498db;
-  color: white;
-  border: none;
-  border-radius: 4px;
-  cursor: pointer;
-  font-size: 14px;
-  transition: background 0.3s;
-}
-
-.retry-btn:hover {
-  background: #2980b9;
-}
-
-@keyframes spin {
-  to { transform: rotate(360deg); }
-}
-</style>

+ 121 - 135
src/components/detectionStatistics/atmsampleStatistics.vue

@@ -2,7 +2,7 @@
   <div class="boxplot-container">
     <div class="chart-container">
       <div class="header">
-        <div class="chart-title">灌溉水重金属浓度统计箱线图</div>
+        <div class="chart-title">大气重金属浓度统计箱线图</div>
         <p>展示各重金属浓度的分布特征(最小值、四分位数、中位数、最大值)</p>
         <p class="sample-subtitle">样本来源:{{ totalPoints }}个数据</p>
       </div>
@@ -28,77 +28,58 @@
 import * as echarts from 'echarts'
 import VChart from 'vue-echarts'
 import { api8000 } from '@/utils/request' // 导入 api8000 实例
-import { ref, onMounted ,computed} from 'vue'
+import { ref, onMounted, computed } from 'vue'
 
 export default {
   components: { VChart },
   setup() {
-    // -------- 基本状态 --------
-    const apiUrl = ref('/api/vector/export/all?table_name=Atmo_sample_data')
-    const apiTimestamp = ref(null)
-    const statsData = ref({}); // 新增:存储接口返回的预统计数据
-    const chartOption = ref({})
-    const isLoading = ref(true)
-    const error = ref(null)
-    
-    // 样本数统计(从预统计数据中获取)
+    // -------- 核心配置 --------
+    // 新接口地址(直接返回箱线图所需统计数据)
+    const apiUrl = ref('/api/vector/stats/Atmo_sample_data') // 修改为相对路径
+    const heavyMetals = [
+      { key: 'Cr_particulate', name: '铬 (Cr)', color: '#FF9800' },
+      { key: 'As_particulate', name: '砷 (As)', color: '#4CAF50' },
+      { key: 'Cd_particulate', name: '镉 (Cd)', color: '#9C27B0' },
+      { key: 'Hg_particulate', name: '汞 (Hg)', color: '#2196F3' },
+      { key: 'Pb_particulate', name: '铅 (Pb)', color: '#F44336' },
+    ]
+
+    // -------- 状态管理 --------
+    const chartOption = ref({})   // ECharts 配置
+    const isLoading = ref(true)   // 加载状态
+    const error = ref(null)       // 错误信息
+    const statsByIndex = ref([])  // 与x轴对齐的统计结果(用于tooltip)
     const totalPoints = computed(() => {
-      const firstMetalKey = heavyMetals[0]?.key;
-      return statsData.value[firstMetalKey]?.count || 0;
+      // 从统计数据中获取样本总数(假设所有金属样本数相同)
+      return statsByIndex.value.length > 0 
+        ? statsByIndex.value[0].count || 0 
+        : 0;
     })
 
-    // 缓存每个品类的统计量(与 x 轴顺序一致)
-    const statsByIndex = ref([])
-
-    // -------- 配置:金属字段 --------
-    const heavyMetals = [
-      { key: 'cr_concentration', name: '铬 (Cr)', color: '#FF9800' },
-      { key: 'as_concentration', name: '砷 (As)', color: '#4CAF50' },
-      { key: 'cd_concentration', name: '镉 (Cd)', color: '#9C27B0' },
-      { key: 'hg_concentration', name: '汞 (Hg)', color: '#2196F3' },
-      { key: 'pb_concentration', name: '铅 (Pb)', color: '#F44336' }
-    ]
 
-    // -------- 日志 --------
+    // -------- 工具函数 --------
     const log = (message, metalName = '') => {
-      console.log(`%c[${metalName || '全局'}] %c${message}`,
-        'color:#4CAF50;font-weight:bold', 'color:#333')
+      console.log(
+        `%c[${metalName || '全局'}] %c${message}`,
+        'color:#4CAF50;font-weight:bold',
+        'color:#333'
+      )
     }
 
-    // -------- 构建箱线数据 --------
-    const buildBoxplotData = () => {
-      const xAxisData = heavyMetals.map(m => m.name);
-
-      // 缓存每个重金属的统计量(用于tooltip)
-      statsByIndex.value = heavyMetals.map(metal => {
-        const stat = statsData.value[metal.key] || {};
-        return {
-          key: metal.key,
-          name: metal.name,
-          min: stat.min,
-          q1: stat.q1,
-          median: stat.median,
-          q3: stat.q3,
-          max: stat.max,
-          color: metal.color
-        };
-      });
-
-      // 构建ECharts箱线图数据
-      const data = statsByIndex.value.map(s => {
-        if (s.min === undefined || s.min === null) {
-          return [null, null, null, null, null];
-        }
-        return [s.min, s.q1, s.median, s.q3, s.max];
-      });
-
-      return { xAxisData, data };
-    };
-
-    // -------- 初始化图表 --------
-    const initChart = () => {
-      const { xAxisData, data } = buildBoxplotData(); // 修复:直接调用构建函数
+    const buildBoxplotData = (stats) => {
+      const xAxisData = heavyMetals.map(m => m.name)
+      // 生成箱线图所需格式:[[min, q1, median, q3, max], ...]
+      const data = stats.map(s => 
+        s.min === null 
+          ? [null, null, null, null, null] 
+          : [s.min, s.q1, s.median, s.q3, s.max]
+      )
+      return { xAxisData, data }
+    }
 
+    const initChart = (xAxisData, data, stats) => {
+      statsByIndex.value = stats // 缓存统计数据用于tooltip
+      
       chartOption.value = {
         tooltip: {
           trigger: 'item',
@@ -106,7 +87,7 @@ export default {
             const s = statsByIndex.value[params.dataIndex]
             if (!s || s.min === null) {
               return `<div style="font-weight:bold;color:#f56c6c">${xAxisData[params.dataIndex]}</div><div>无有效数据</div>`
-            }
+            }          
             return `<div style="font-weight:bold">${xAxisData[params.dataIndex]}</div>
               <div style="margin-top:8px">
                 <div>最小值:<span style="color:#5a5;">${s.min.toFixed(4)}</span></div>
@@ -115,29 +96,28 @@ export default {
                 <div>上四分位:<span style="color:#d87a80;">${s.q3.toFixed(4)}</span></div>
                 <div>最大值:<span style="color:#5a5;">${s.max.toFixed(4)}</span></div>
               </div>`
-          },
+          }
         },
         xAxis: {
           type: 'category',
           data: xAxisData,
           name: '重金属类型',
           nameLocation: 'middle',
-          nameGap: 30,
-          axisLabel: { color: '#555', rotate: 0, fontWeight: 'bold' ,fontSize :11}
+          nameGap: 45,
+          axisLabel: { color: '#555', rotate: 30, fontWeight: 'bold', fontSize: 11 }
         },
         yAxis: {
           type: 'value',
-          name: 'ug/L',
-          nameTextStyle: { fontSize: 12 }, 
+          name: 'mg/kg',
           nameLocation: 'end',
-          nameGap: 8,
-          axisLabel: { color: '#555', fontWeight: 'bold',fontSize:11 },
+          nameGap: 5,
+          axisLabel: { color: '#555', fontWeight: 'bold', fontSize: 11 },
           splitLine: { lineStyle: { color: '#f0f0f0' } }
         },
         series: [{
           name: '重金属浓度分布',
           type: 'boxplot',
-          data,
+          data, // 直接使用接口返回的统计数据
           itemStyle: {
             color: (p) => (heavyMetals[p.dataIndex]?.color || '#1890ff'),
             borderWidth: 2
@@ -146,50 +126,61 @@ export default {
             itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0,0,0,0.2)', borderWidth: 3 }
           }
         }],
-        grid: { top: '10%', right: '3%', left: '6%', bottom: '10%' }
+        grid: { top: '8%', right: '5%', left: '8%', bottom: '20%' }
       }
-
-      isLoading.value = false
     }
 
     // -------- 接口请求 --------
-      onMounted(async () => {
+    onMounted(async () => {
       try {
-        // log('发起API请求...')
-        const response = await api8000.get(apiUrl.value) // 使用 api8000 实例
-        // console.log('接口原始响应:', response.data) // 调试必看!
-
-        let data = response.data
+        log('发起新接口请求,获取统计数据...')
+        // 使用 api8000 替代 axios
+        const response = await api8000.get(apiUrl.value)
+        const apiData = response.data
+
+        // 从接口数据中提取每个重金属的统计量
+        const stats = heavyMetals.map(metal => {
+          const metalStats = apiData[metal.key]
+          if (!metalStats) {
+            log(`警告:接口缺少${metal.name}的统计数据`)
+            return { ...metal, min: null, q1: null, median: null, q3: null, max: null, count: 0 }
+          }
+          
+          // 验证必要的统计字段
+          const requiredFields = ['min', 'q1', 'median', 'q3', 'max']
+          const hasValidData = requiredFields.every(field => 
+            metalStats[field] !== undefined && !isNaN(metalStats[field])
+          )
+
+          if (!hasValidData) {
+            log(`警告:${metal.name}的统计数据不完整`)
+            return { ...metal, min: null, q1: null, median: null, q3: null, max: null, count: 0 }
+          }
 
-        // ✅ 兼容接口返回字符串的情况(比如后端没设置 application/json)
-        if (typeof data === 'string') {
-          try {
-            // 尝试解析字符串为JSON
-            data = JSON.parse(data);
-          } catch (parseError) {
-            console.warn('接口返回字符串但解析失败,尝试重新请求', parseError);
-            // 如果解析失败,重新请求
-            const retryResponse = await api8000.get(apiUrl.value);
-            data = retryResponse.data;
+          return {
+            ...metal,
+            min: Number(metalStats.min),
+            q1: Number(metalStats.q1),
+            median: Number(metalStats.median),
+            q3: Number(metalStats.q3),
+            max: Number(metalStats.max),
+            count: metalStats.count ? Number(metalStats.count) : 0
           }
-        }
+        })
+
+        // 构建图表数据并初始化图表
+        const { xAxisData, data } = buildBoxplotData(stats)
+        initChart(xAxisData, data, stats)
+        isLoading.value = false
 
-        // 赋值并更新UI
-        statsData.value = data;
-        apiTimestamp.value = new Date().toLocaleString();
-        initChart();
-        isLoading.value = false;
-        
       } catch (err) {
-        error.value = err;
-        isLoading.value = false;
-        console.error('接口请求失败:', err);
+        error.value = err
+        isLoading.value = false
+        console.error('接口请求失败:', err)
       }
-    });
+    })
 
     return {
-      apiUrl,
-      apiTimestamp,
       chartOption,
       isLoading,
       error,
@@ -208,14 +199,13 @@ export default {
 }
 .header { 
   text-align: left;
-   margin-bottom: 10px; 
+  margin-bottom: 20px; 
+}
+.chart-title {
+  font-size: 14px;
+  color: #2980b9;
+  font-weight: 600;
 }
-
-.header h2 { 
-  font-size: 0.6rem; 
-  color: #333; 
-  margin-bottom: 4px;
- }
 .header p { 
   font-size: 0.6rem; 
   color: #666;
@@ -223,42 +213,38 @@ export default {
 }
 .loading-state { 
   text-align: center;
-   padding: 40px 0;
-   color: #666; 
+  padding: 40px 0;
+  color: #666; 
 }
 .loading-state .spinner {
-  display: inline-block; width: 24px; height: 24px; margin-right: 8px;
-  border: 3px solid #ccc; border-top-color: #1890ff; border-radius: 50%;
+  display: inline-block; 
+  width: 24px; 
+  height: 24px; 
+  margin-right: 8px;
+  border: 3px solid #ccc; 
+  border-top-color: #1890ff; 
+  border-radius: 50%;
   animation: spin 1s linear infinite;
 }
-@keyframes spin { to { transform: rotate(360deg); } }
-.error-state { text-align: center; padding: 40px 0; color: #f56c6c; }
-.chart-wrapper { width: 100%; height: 220px; }
+@keyframes spin { 
+  to { transform: rotate(360deg); } 
+}
+.error-state { 
+  text-align: center; 
+  padding: 40px 0; 
+  color: #f56c6c; 
+}
+.chart-wrapper { 
+  width: 100%; 
+  height: 220px; 
+}
 .chart-container {
   background: white;
   border-radius: 12px;
   box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
+  padding: 20px;
   margin-bottom: 25px;
   height: 100%;
-  box-sizing: border-box;
-}
-
-.chart-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: flex-start;
-  margin-bottom: 15px;
-}
-
-.chart-title {
-  font-size: 14px;
-  color: #2980b9;
-  font-weight: 600;
-}
-
-.title-group {
-    display: flex;
-    align-items: left;
 }
 
 .sample-subtitle {
@@ -266,4 +252,4 @@ export default {
   color: #888;
   margin-top: 4px;
 }
-</style>
+</style>

+ 22 - 23
src/components/detectionStatistics/irrigationstatistics.vue

@@ -28,29 +28,29 @@
 import * as echarts from 'echarts'
 import VChart from 'vue-echarts'
 import { api8000 } from '@/utils/request' // 导入 api8000 实例
-import { ref, onMounted ,computed} from 'vue'
+import { ref, onMounted, computed } from 'vue'
 
 export default {
   components: { VChart },
   setup() {
     // -------- 基本状态 --------
-    const apiUrl = ref('/api/vector/export/all?table_name=water_sampling_data') // 使用相对路径
+    const apiUrl = ref('/api/vector/stats/water_sampling_data') // 修改为相对路径
     const apiTimestamp = ref(null)
-    const sampleCount = ref(0)
     const statsData = ref({}); 
     const chartOption = ref({})
     const isLoading = ref(true)
     const error = ref(null)
-    const stats = null;
+    
+    // 样本数统计(从预统计数据中获取)
     const totalPoints = computed(() => {
       const firstMetalKey = heavyMetals[0]?.key;
       return statsData.value[firstMetalKey]?.count || 0;
     })
 
-    // 关键:缓存每个品类的统计量(与 x 轴顺序一致)
+    // 缓存每个品类的统计量(与 x 轴顺序一致)
     const statsByIndex = ref([])
 
-    // -------- 配置:金属字段(保持你原样) --------
+    // -------- 配置:金属字段 --------
     const heavyMetals = [
       { key: 'cr_concentration', name: '铬 (Cr)', color: '#FF9800' },
       { key: 'as_concentration', name: '砷 (As)', color: '#4CAF50' },
@@ -58,13 +58,14 @@ export default {
       { key: 'hg_concentration', name: '汞 (Hg)', color: '#2196F3' },
       { key: 'pb_concentration', name: '铅 (Pb)', color: '#F44336' }
     ]
-    // -------- 构建箱线数据(保留你自己的顺序) --------
+
+    // -------- 构建箱线数据 --------
     const buildBoxplotData = () => {
-      const xAxisData = heavyMetals.map(m => m.name); // 保持x轴顺序与配置一致
+      const xAxisData = heavyMetals.map(m => m.name);
 
       // 缓存每个重金属的统计量(用于tooltip)
       statsByIndex.value = heavyMetals.map(metal => {
-       const stat = statsData.value[metal.key] || {}; // 从接口数据中取当前金属的统计
+        const stat = statsData.value[metal.key] || {};
         return {
           key: metal.key,
           name: metal.name,
@@ -77,25 +78,24 @@ export default {
         };
       });
 
-      // 构建ECharts箱线图所需的二维数组格式 [[min, q1, median, q3, max], ...]
+      // 构建ECharts箱线图数据
       const data = statsByIndex.value.map(s => {
         if (s.min === undefined || s.min === null) {
-          return [null, null, null, null, null]; // 无数据时返回空数组
+          return [null, null, null, null, null];
         }
         return [s.min, s.q1, s.median, s.q3, s.max];
       });
 
-       return { xAxisData, data };
+      return { xAxisData, data };
     };
 
     // -------- 初始化图表 --------
     const initChart = () => {
-      const { xAxisData, data } = buildBoxplotData(stats)
+      const { xAxisData, data } = buildBoxplotData();
 
       chartOption.value = {
         tooltip: {
           trigger: 'item',
-          // 关键:不从 params.data 取,直接读我们缓存的原始统计值,彻底避免被内部处理影响
           formatter: (params) => {
             const s = statsByIndex.value[params.dataIndex]
             if (!s || s.min === null) {
@@ -149,22 +149,21 @@ export default {
     // -------- 拉取接口并绘图 --------
     onMounted(async () => {
       try {
-        //log('发起API请求...')
-        const response = await axios.get(apiUrl.value);
+        // 使用api8000替代axios
+        const response = await api8000.get(apiUrl.value);
         statsData.value = response.data; 
-        apiTimestamp.value = new Date().toLocaleString()
-          initChart()
+        apiTimestamp.value = new Date().toLocaleString();
+        initChart();
       } catch (err) {
-        error.value = err
-        isLoading.value = false
-        console.error('接口请求失败:', err)
+        error.value = err;
+        isLoading.value = false;
+        console.error('接口请求失败:', err);
       }
     })
 
     return {
       apiUrl,
       apiTimestamp,
-      sampleCount,
       chartOption,
       isLoading,
       error,
@@ -221,7 +220,7 @@ export default {
 .chart-header {
   display: flex;
   justify-content: space-between;
-  align-items: flex-start; /**与顶部对齐 */
+  align-items: flex-start;
   margin-bottom: 15px;
 }
 

+ 0 - 4
src/components/irrpollution/crossSetionData1.vue

@@ -216,11 +216,7 @@ onBeforeUnmount(() => {
 
 .chart-container {
   width: 100%; 
-<<<<<<< HEAD
-  height: 500px; /* 增加高度以容纳旋转的标签 */
-=======
   height:400px;
->>>>>>> origin/lili
   margin: 0 auto;
   border-radius: 12px;
 }

+ 16 - 10
src/components/soilStatictics/reducedataStatistics.vue

@@ -25,18 +25,19 @@
 <script>
 import { ref, onMounted, onUnmounted, nextTick } from 'vue';
 import * as echarts from 'echarts';
+import { api5000 } from '@/utils/request'; // 导入 api5000 实例
 
 export default {
   name: 'PhTrendChart',
   setup() {
     // 接口数据 - 不同时间点的数据集
     const interfaces = [
-      { time: '20241229_201018', url: 'http://localhost:5000/api/table-data?table_name=dataset_5' },
-      { time: '20250104_171827', url: 'http://localhost:5000/api/table-data?table_name=dataset_35' },
-      { time: '20250104_171959', url: 'http://localhost:5000/api/table-data?table_name=dataset_36' },
-      { time: '20250104_214026', url: 'http://localhost:5000/api/table-data?table_name=dataset_37' },
-      { time: '20250308_161945', url: 'http://localhost:5000/api/table-data?table_name=dataset_65' },
-      { time: '20250308_163248', url: 'http://localhost:5000/api/table-data?table_name=dataset_66' },
+      { time: '20241229_201018', url: '/api/table-data?table_name=dataset_5' },
+      { time: '20250104_171827', url: '/api/table-data?table_name=dataset_35' },
+      { time: '20250104_171959', url: '/api/table-data?table_name=dataset_36' },
+      { time: '20250104_214026', url: '/api/table-data?table_name=dataset_37' },
+      { time: '20250308_161945', url: '/api/table-data?table_name=dataset_65' },
+      { time: '20250308_163248', url: '/api/table-data?table_name=dataset_66' },
     ];
     
     const chartRef = ref(null);
@@ -78,10 +79,15 @@ export default {
         
         // 按时间顺序获取每个表的数据
         for (const intf of interfaces) {
-          const response = await fetch(intf.url);
-          if (!response.ok) throw new Error(`网络响应错误: ${response.status}`);
+          // 使用 api5000 替代 fetch
+          const response = await api5000.get(intf.url);
           
-          const responseData = await response.json();
+          // 检查响应状态
+          if (response.status !== 200) {
+            throw new Error(`网络响应错误: ${response.status}`);
+          }
+          
+          const responseData = response.data;
           const dataArray = responseData.data || [];
           
           for (const id of newSelectedIds) {
@@ -93,7 +99,7 @@ export default {
               };
             }
             
-            // 查找匹配的项目 ,使用小写id
+            // 查找匹配的项目,使用小写id
             const targetItem = dataArray.find(item => item.id === id);
             
             if (targetItem) {

+ 16 - 29
src/components/soilStatictics/refluxcedataStatictics.vue

@@ -8,7 +8,7 @@
 <script setup>
 import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
 import * as echarts from 'echarts';
-import axios from 'axios';
+import { api5000 } from '@/utils/request'; // 导入 api5000 实例
 
 // 图表相关
 const chartRef = ref(null);
@@ -19,35 +19,33 @@ const chartData = ref([]);
 const isLoading = ref(false);
 const errorMessage = ref('');
 
-// 接口地址(请替换为实际接口地址
-const API_URL = 'http://localhost:5000/api/table-data?table_name=dataset_60'; // 替换为实际接口
+// 接口地址(使用相对路径
+const API_URL = '/api/table-data?table_name=dataset_60'; // 相对路径
 
 // 获取数据函数
 const fetchData = async () => {
-  //console.log('开始获取数据...');
   // 重置状态
   errorMessage.value = '';
   isLoading.value = true;
   
   try {
-    // 发起请求
-    const response = await axios.get(API_URL);
-    //console.log('API响应:', response);
+    // 使用 api5000 替代 axios
+    const response = await api5000.get(API_URL);
     
     // 检查响应数据是否符合预期格式
     if (response.data && response.data.success) {
-  if (Array.isArray(response.data.data) && response.data.data.length > 0) {
-    if (response.data.data[0].id !== undefined && response.data.data[0].Delta_pH !== undefined) {
-      chartData.value = response.data.data;
+      if (Array.isArray(response.data.data) && response.data.data.length > 0) {
+        if (response.data.data[0].id !== undefined && response.data.data[0].Delta_pH !== undefined) {
+          chartData.value = response.data.data;
+        } else {
+          errorMessage.value = '数据字段缺失:缺少 id 或 Delta_pH';
+        }
+      } else {
+        errorMessage.value = '未获取到有效数据,请稍后重试';
+      }
     } else {
-      errorMessage.value = '数据字段缺失:缺少 id 或 Delta_pH';
+      errorMessage.value = 'API返回失败状态';
     }
-  } else {
-    errorMessage.value = '未获取到有效数据,请稍后重试';
-  }
-} else {
-  errorMessage.value = 'API返回失败状态';
-}
   } catch (error) {
     console.error('数据获取失败:', error);
     // 根据错误类型显示不同信息
@@ -65,7 +63,6 @@ const fetchData = async () => {
 
 // 初始化图表
 const initChart = () => {
-  //console.log('初始化图表,数据长度:', chartData.value.length);
   // 确保DOM已挂载且有数据
   if (!chartRef.value) {
     console.error('图表容器未找到');
@@ -80,16 +77,10 @@ const initChart = () => {
   // 销毁已有实例
   if (myChart) {
     myChart.dispose();
-    //console.log('已销毁旧图表实例');
   }
   
   // 初始化图表
   myChart = echarts.init(chartRef.value);
-  //console.log('ECharts实例已创建');
-
-   myChart.on('rendered', () => {
-    //console.log('图表已渲染');
-  });
   
   // 提取数据
   const xAxisData = chartData.value.map(item => item.id);
@@ -100,9 +91,6 @@ const initChart = () => {
       color: item.Delta_pH >= 0 ? '#0F52BA' : '#F44336'
     }
   }));
-
-  //console.log('X轴数据:', xAxisData);
-  //console.log('系列数据:', seriesData);
   
   // 图表配置
   const option = {
@@ -164,7 +152,6 @@ watch(chartData, () => {
   nextTick(()=>{
     initChart();  
   })
-
 });
 
 // 窗口大小变化时重绘图表
@@ -211,4 +198,4 @@ onUnmounted(() => {
 .title {
   text-align: center;
 }
-</style>
+</style>

+ 9 - 14
src/components/soilcdStatistics/cropcdStatictics.vue

@@ -46,7 +46,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted, watch, nextTick } from 'vue';
+import { ref, onMounted, nextTick } from 'vue';
 import * as echarts from 'echarts';
 import { api8000 } from '@/utils/request'; // 导入 api8000 实例
 
@@ -61,12 +61,8 @@ let chartInstanceNutrient = null;
 let chartInstanceExtra = null;
 
 // 响应式状态
-const showDialog = ref(false);
-const dialogTitle = ref("");
-
 const isLoading = ref(true);
 const error = ref(null);
-const lastUpdate = ref("");
 const stats = ref({
   cd002Avg: 0,
   cd02Avg: 0,
@@ -123,9 +119,8 @@ const fieldConfig = {
 // 数据请求(作物态Cd接口)
 const fetchData = async () => {
   try {
-    const apiUrl = 'http://localhost:8000/api/vector/stats/CropCd_input_data';
-    const response = await axios.get(apiUrl);
-    
+    const apiUrl = '/api/vector/stats/CropCd_input_data'; // 相对路径
+    const response = await api8000.get(apiUrl); // 使用 api8000
     return response.data;
   } catch (err) {
     throw new Error('数据加载失败: ' + err.message);
@@ -240,17 +235,17 @@ const initExtraChart = () => {
 };
 
 // 格式化Tooltip
-const formatTooltip = (stat , unit ='') => {
+const formatTooltip = (stat, unit = '') => {
   if (!stat || !stat.min) {
     return `<div style="font-weight:bold;color:#f56c6c">${stat?.name || '未知'}</div><div>无有效数据</div>`;
   }
   return `<div style="font-weight:bold">${stat.name}</div>
     <div style="margin-top:8px">
-      <div>最小值:<span style="color:#5a5;">${stat.min.toFixed(4)}</span></div>
-      <div>下四分位:<span style="color:#d87a80;">${stat.q1.toFixed(4)}</span></div>
-      <div>中位数:<span style="color:#f56c6c;font-weight:bold;">${stat.median.toFixed(4)}</span></div>
-      <div>上四分位:<span style="color:#d87a80;">${stat.q3.toFixed(4)}</span></div>
-      <div>最大值:<span style="color:#5a5;">${stat.max.toFixed(4)}</span></div>
+      <div>最小值:<span style="color:#5a5;">${stat.min.toFixed(4)} ${unit}</span></div>
+      <div>下四分位:<span style="color:#d87a80;">${stat.q1.toFixed(4)} ${unit}</span></div>
+      <div>中位数:<span style="color:#f56c6c;font-weight:bold;">${stat.median.toFixed(4)} ${unit}</span></div>
+      <div>上四分位:<span style="color:#d87a80;">${stat.q3.toFixed(4)} ${unit}</span></div>
+      <div>最大值:<span style="color:#5a5;">${stat.max.toFixed(4)} ${unit}</span></div>
     </div>`;
 };
 

+ 14 - 7
src/components/soilcdStatistics/effcdStatistics.vue

@@ -44,7 +44,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted, watch, nextTick } from 'vue';
+import { ref, onMounted, nextTick } from 'vue';
 import * as echarts from 'echarts';
 import { api8000 } from '@/utils/request'; // 导入 api8000 实例
 
@@ -57,7 +57,6 @@ const extraBoxChart = ref(null);
 let chartInstanceCd = null;
 let chartInstanceNutrient = null;
 let chartInstanceExtra = null;
-const chartInstancePopup =null;
 
 // 响应式状态
 const isLoading = ref(true);
@@ -104,10 +103,9 @@ const fieldConfig = {
 // 数据请求
 const fetchData = async () => {
   try {
-    // 实际项目中替换为真实API
-     const res = await axios.get("http://localhost:8000/api/vector/stats/EffCd_input_data");
-     return res.data;
-
+    // 使用 api8000 替代 axios
+    const res = await api8000.get("/api/vector/stats/EffCd_input_data");
+    return res.data;
   } catch (err) {
     throw new Error('数据加载失败: ' + err.message);
   }
@@ -117,7 +115,16 @@ const fetchData = async () => {
 const calculateFieldStats = (statsData, fieldKey, fieldName, fieldConfigItem) => {
   const fieldStats = statsData[fieldKey]; // 从接口数据中取当前字段的统计结果
   if (!fieldStats) {
-    return { key: fieldKey, name: fieldName, min: null, q1: null, median: null, q3: null, max: null, mean: null };
+    return { 
+      key: fieldKey, 
+      name: fieldName, 
+      min: null, 
+      q1: null, 
+      median: null, 
+      q3: null, 
+      max: null, 
+      mean: null 
+    };
   }
 
   // 提取原始统计值

+ 2 - 21
src/components/soilcdStatistics/fluxcdStatictics.vue

@@ -60,7 +60,6 @@ const initialCdChart = ref(null);   // 初始Cd图表
 const otherIndicatorsChart = ref(null); // 其他指标图表
 const chartInstanceInitial = ref(null);   // 初始Cd实例
 const chartInstanceOther = ref(null);     // 其他指标实例
-const chartInstancePopup = ref(null);     // 弹窗实例
 
 // 响应式状态
 const isLoading = ref(true);
@@ -89,8 +88,8 @@ const fieldConfig = {
 // 数据请求
 const fetchData = async () => {
   try {
-    const apiUrl = 'http://localhost:8000/api/vector/stats/FluxCd_input_data';
-    const response = await axios.get(apiUrl);
+    const apiUrl = '/api/vector/stats/FluxCd_input_data'; // 相对路径
+    const response = await api8000.get(apiUrl); // 使用 api8000
     const rawData = response.data.features 
       ? response.data.features.map(f => f.properties) 
       : response.data;
@@ -100,22 +99,6 @@ const fetchData = async () => {
   }
 };
 
-// 分位数计算(QUARTILE.INC)
-const calculatePercentile = (sortedArray, percentile) => {
-  const n = sortedArray.length;
-  if (n === 0) return null;
-  if (percentile <= 0) return sortedArray[0];
-  if (percentile >= 100) return sortedArray[n - 1];
-  
-  const index = (n - 1) * (percentile / 100);
-  const lowerIndex = Math.floor(index);
-  const upperIndex = lowerIndex + 1;
-  const fraction = index - lowerIndex;
-  
-  if (upperIndex >= n) return sortedArray[lowerIndex];
-  return sortedArray[lowerIndex] + fraction * (sortedArray[upperIndex] - sortedArray[lowerIndex]);
-};
-
 // 计算单个字段的统计量
 const calculateFieldStats = (statsData, fieldKey, fieldName) => {
   // 从接口数据中获取当前字段的统计结果
@@ -377,7 +360,6 @@ onMounted(() => {
   const handleResize = () => {
     if (chartInstanceInitial.value) chartInstanceInitial.value.resize();
     if (chartInstanceOther.value) chartInstanceOther.value.resize();
-    if (chartInstancePopup.value) chartInstancePopup.value.resize();
   };
   window.addEventListener('resize', handleResize);
   
@@ -385,7 +367,6 @@ onMounted(() => {
     window.removeEventListener('resize', handleResize);
     if (chartInstanceInitial.value) chartInstanceInitial.value.dispose();
     if (chartInstanceOther.value) chartInstanceOther.value.dispose();
-    if (chartInstancePopup.value) chartInstancePopup.value.dispose();
   };
 });
 </script>

+ 2 - 1
src/locales/en.json

@@ -29,7 +29,8 @@
     "registerButton": "Register",
     "passwordMismatch": "Passwords do not match",
     "successMessage": "Registration successful, please log in",
-    "errorMessage": "Registration failed"
+    "errorMessage": "Registration failed",
+    "registerFailed": "Registration failed"
   },
   "validation": {
     "usernameRequired": "Please enter your username",

+ 1 - 1
src/locales/zh.json

@@ -33,7 +33,7 @@
     "registerButton": "注册",
     "passwordMismatch": "两次输入的密码不一致",
     "successMessage": "注册成功,请登录",
-    "errorMessage": "注册失败"
+    "registerFailed": "注册失败"
   },
   "validation": {
     "usernameRequired": "请输入账号",