From ea6ad9ddc3d5b33897e93276282245f7023836ff Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期四, 28 八月 2025 17:45:28 +0800
Subject: [PATCH] 大数据市场分析

---
 src/views/marketAnalysis/index.vue | 1082 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,082 insertions(+), 0 deletions(-)

diff --git a/src/views/marketAnalysis/index.vue b/src/views/marketAnalysis/index.vue
new file mode 100644
index 0000000..cd8feda
--- /dev/null
+++ b/src/views/marketAnalysis/index.vue
@@ -0,0 +1,1082 @@
+<template>
+  <div class="market-analysis-container">
+
+    <!-- 鏁版嵁姒傝鍗$墖 -->
+    <el-row :gutter="20" class="data-overview">
+      <el-col :span="6">
+        <el-card class="overview-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-icon price-icon">
+              <el-icon><TrendCharts /></el-icon>
+            </div>
+            <div class="card-info">
+              <div class="card-title">骞冲潎鐓や环</div>
+              <div class="card-value">楼{{ marketData.avgPrice.toFixed(2) }}</div>
+              <div class="card-change" :class="marketData.priceChange >= 0 ? 'positive' : 'negative'">
+                {{ marketData.priceChange >= 0 ? '+' : '' }}{{ marketData.priceChange.toFixed(2) }}%
+              </div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      
+      <el-col :span="6">
+        <el-card class="overview-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-icon volume-icon">
+              <el-icon><DataLine /></el-icon>
+            </div>
+            <div class="card-info">
+              <div class="card-title">浜ゆ槗閲�</div>
+              <div class="card-value">{{ marketData.totalVolume }}涓囧惃</div>
+              <div class="card-change" :class="marketData.volumeChange >= 0 ? 'positive' : 'negative'">
+                {{ marketData.volumeChange >= 0 ? '+' : '' }}{{ marketData.volumeChange.toFixed(2) }}%
+              </div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      
+      <el-col :span="6">
+        <el-card class="overview-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-icon customer-icon">
+              <el-icon><User /></el-icon>
+            </div>
+            <div class="card-info">
+              <div class="card-title">娲昏穬瀹㈡埛</div>
+              <div class="card-value">{{ marketData.activeCustomers }}瀹�</div>
+              <div class="card-change" :class="marketData.customerChange >= 0 ? 'positive' : 'negative'">
+                {{ marketData.customerChange >= 0 ? '+' : '' }}{{ marketData.customerChange.toFixed(2) }}%
+              </div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      
+      <el-col :span="6">
+        <el-card class="overview-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-icon trend-icon">
+              <el-icon><TrendCharts /></el-icon>
+            </div>
+            <div class="card-info">
+              <div class="card-title">甯傚満瓒嬪娍</div>
+              <div class="card-value">{{ marketData.marketTrend }}</div>
+              <div class="card-change" :class="marketData.trendScore >= 0 ? 'positive' : 'negative'">
+                淇″績鎸囨暟: {{ marketData.trendScore }}
+              </div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 涓昏鍒嗘瀽鍖哄煙 -->
+    <el-row :gutter="20" class="main-analysis">
+      <!-- 浠锋牸瓒嬪娍鍒嗘瀽 -->
+      <el-col :span="16">
+        <el-card class="analysis-card" shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>鐓ょ浠锋牸瓒嬪娍鍒嗘瀽</span>
+              <div class="header-controls">
+                <el-select v-model="selectedCoalType" placeholder="閫夋嫨鐓ょ" size="small" style="width: 120px">
+                  <el-option label="娣风叅" value="mixed" />
+                  <el-option label="绮剧叅" value="refined" />
+                  <el-option label="鍔ㄥ姏鐓�" value="power" />
+                  <el-option label="鐒︾叅" value="coking" />
+                </el-select>
+                <el-select v-model="selectedRegion" placeholder="閫夋嫨浜у湴" size="small" style="width: 120px">
+                  <el-option label="灞辫タ" value="shanxi" />
+                  <el-option label="鍐呰挋鍙�" value="neimenggu" />
+                  <el-option label="闄曡タ" value="shaanxi" />
+                  <el-option label="鏂扮枂" value="xinjiang" />
+                </el-select>
+                <el-select v-model="selectedPeriod" placeholder="鏃堕棿鍛ㄦ湡" size="small" style="width: 100px">
+                  <el-option label="鏃�" value="day" />
+                  <el-option label="鍛�" value="week" />
+                  <el-option label="鏈�" value="month" />
+                  <el-option label="瀛�" value="quarter" />
+                </el-select>
+              </div>
+            </div>
+          </template>
+          
+          <div class="chart-container">
+            <div ref="priceChartRef" class="chart" style="height: 400px;"></div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <!-- 瀹㈡埛琛屼负鍒嗘瀽 -->
+      <el-col :span="8">
+        <el-card class="analysis-card" shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>瀹㈡埛琛屼负鐢诲儚</span>
+            </div>
+          </template>
+          
+          <div class="customer-analysis">
+            <div class="customer-type-distribution">
+              <h4>瀹㈡埛绫诲瀷鍒嗗竷</h4>
+              <div ref="customerChartRef" class="chart" style="height: 200px;"></div>
+            </div>
+            
+            <div class="purchase-preference">
+              <h4>閲囪喘鍋忓ソ鍒嗘瀽</h4>
+              <div class="preference-item" v-for="item in customerPreferences" :key="item.type">
+                <div class="preference-label">{{ item.type }}</div>
+                <div class="preference-bar">
+                  <div class="bar-fill" :style="{ width: item.percentage + '%' }"></div>
+                </div>
+                <div class="preference-value">{{ item.percentage }}%</div>
+              </div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 璇︾粏鍒嗘瀽鍖哄煙 -->
+    <el-row :gutter="20" class="detail-analysis">
+      <!-- 鍖哄煙浠锋牸瀵规瘮 -->
+      <el-col :span="12">
+        <el-card class="analysis-card" shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>鍖哄煙浠锋牸瀵规瘮</span>
+            </div>
+          </template>
+          
+          <div class="region-comparison">
+            <div ref="regionChartRef" class="chart" style="height: 300px;"></div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <!-- 瀹㈡埛閲囪喘鍛ㄦ湡鍒嗘瀽 -->
+      <el-col :span="12">
+        <el-card class="analysis-card" shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>瀹㈡埛閲囪喘鍛ㄦ湡鍒嗘瀽</span>
+            </div>
+          </template>
+          
+          <div class="purchase-cycle">
+            <div ref="cycleChartRef" class="chart" style="height: 300px;"></div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 鏅鸿兘鎺ㄨ崘鍖哄煙 -->
+    <el-row :gutter="20" class="smart-recommendations">
+      <el-col :span="24">
+        <el-card class="analysis-card" shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>鏅鸿兘钀ラ攢鎺ㄨ崘</span>
+              <el-tag type="warning" size="small">AI绠楁硶椹卞姩</el-tag>
+            </div>
+          </template>
+          
+          <div class="recommendations-content">
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <div class="recommendation-section">
+                  <h4>涓�у寲瀹氫环寤鸿</h4>
+                  <div class="pricing-suggestions">
+                    <div class="suggestion-item" v-for="suggestion in pricingSuggestions" :key="suggestion.id">
+                      <div class="suggestion-header">
+                        <span class="customer-name">{{ suggestion.customerName }}</span>
+                        <el-tag :type="suggestion.priority" size="small">{{ suggestion.priorityText }}</el-tag>
+                      </div>
+                      <div class="suggestion-content">
+                        <p>寤鸿浠锋牸锛毬{ suggestion.suggestedPrice }}/鍚�</p>
+                        <p>璁环绌洪棿锛歿{ suggestion.negotiationSpace }}%</p>
+                        <p>鎺ㄥ崟鏃舵満锛歿{ suggestion.timing }}</p>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </el-col>
+              
+              <el-col :span="8">
+                <div class="recommendation-section">
+                  <h4>鐑攢鐓ゅ瀷鎺ㄨ崘</h4>
+                  <div class="hot-coal-types">
+                    <div class="coal-type-item" v-for="coal in hotCoalTypes" :key="coal.id">
+                      <div class="coal-info">
+                        <div class="coal-name">{{ coal.name }}</div>
+                        <div class="coal-spec">{{ coal.specification }}</div>
+                      </div>
+                      <div class="coal-metrics">
+                        <div class="metric">
+                          <span class="label">鐑害鎸囨暟锛�</span>
+                          <span class="value">{{ coal.heatIndex }}</span>
+                        </div>
+                        <div class="metric">
+                          <span class="label">搴撳瓨鐘舵�侊細</span>
+                          <el-tag :type="coal.stockStatus === '鍏呰冻' ? 'success' : 'warning'" size="small">
+                            {{ coal.stockStatus }}
+                          </el-tag>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </el-col>
+              
+              <el-col :span="8">
+                <div class="recommendation-section">
+                  <h4>瀹㈡埛绮樻�ф彁鍗�</h4>
+                  <div class="loyalty-improvements">
+                    <div class="improvement-item" v-for="improvement in loyaltyImprovements" :key="improvement.id">
+                      <div class="improvement-header">
+                        <span class="strategy-name">{{ improvement.strategyName }}</span>
+                        <span class="success-rate">鎴愬姛鐜�: {{ improvement.successRate }}%</span>
+                      </div>
+                      <div class="improvement-content">
+                        <p>{{ improvement.description }}</p>
+                        <div class="action-buttons">
+                          <el-button type="primary" size="small">鎵ц绛栫暐</el-button>
+                          <el-button size="small">鏌ョ湅璇︽儏</el-button>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </el-col>
+            </el-row>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'
+import { ElMessage } from 'element-plus'
+import { Refresh, TrendCharts, DataLine, User } from '@element-plus/icons-vue'
+import * as echarts from 'echarts'
+
+// 鍝嶅簲寮忔暟鎹�
+const refreshing = ref(false)
+const lastUpdateTime = ref('')
+const selectedCoalType = ref('mixed')
+const selectedRegion = ref('shanxi')
+const selectedPeriod = ref('month')
+
+// 鍥捐〃寮曠敤
+const priceChartRef = ref(null)
+const customerChartRef = ref(null)
+const regionChartRef = ref(null)
+const cycleChartRef = ref(null)
+
+// 鍥捐〃瀹炰緥
+let priceChart = null
+let customerChart = null
+let regionChart = null
+let cycleChart = null
+
+// 甯傚満鏁版嵁
+const marketData = reactive({
+  avgPrice: 1250.50,
+  priceChange: 2.35,
+  totalVolume: 1250.8,
+  volumeChange: -1.25,
+  activeCustomers: 156,
+  customerChange: 3.45,
+  marketTrend: '绋充腑鏈夊崌',
+  trendScore: 8.5
+})
+
+// 瀹㈡埛鍋忓ソ鏁版嵁
+const customerPreferences = ref([
+  { type: '鐒﹀寲鍘�', percentage: 35 },
+  { type: '鐢靛巶', percentage: 28 },
+  { type: '閽㈠巶', percentage: 22 },
+  { type: '鍖栧伐鍘�', percentage: 15 }
+])
+
+// 瀹氫环寤鸿
+const pricingSuggestions = ref([
+  {
+    id: 1,
+    customerName: '灞辫タ鐒﹀寲闆嗗洟',
+    priority: 'high',
+    priorityText: '楂樹紭鍏堢骇',
+    suggestedPrice: 1280,
+    negotiationSpace: 5.2,
+    timing: '鏈懆鍐�'
+  },
+  {
+    id: 2,
+    customerName: '鍗庤兘鐢靛姏',
+    priority: 'medium',
+    priorityText: '涓紭鍏堢骇',
+    suggestedPrice: 1250,
+    negotiationSpace: 3.8,
+    timing: '涓嬪懆鍒�'
+  },
+  {
+    id: 3,
+    customerName: '瀹濋挗闆嗗洟',
+    priority: 'low',
+    priorityText: '浣庝紭鍏堢骇',
+    suggestedPrice: 1220,
+    negotiationSpace: 2.5,
+    timing: '鏈湀鍐�'
+  }
+])
+
+// 鐑攢鐓ゅ瀷
+const hotCoalTypes = ref([
+  {
+    id: 1,
+    name: '浼樿川娣风叅',
+    specification: '鍙戠儹閲�5500澶у崱',
+    heatIndex: 9.2,
+    stockStatus: '鍏呰冻'
+  },
+  {
+    id: 2,
+    name: '绮炬礂鐒︾叅',
+    specification: '鐏板垎鈮�8%',
+    heatIndex: 8.8,
+    stockStatus: '鍏呰冻'
+  },
+  {
+    id: 3,
+    name: '鍔ㄥ姏鐓�',
+    specification: '鍙戠儹閲�6000澶у崱',
+    heatIndex: 8.5,
+    stockStatus: '绱у紶'
+  }
+])
+
+// 瀹㈡埛绮樻�ф彁鍗囩瓥鐣�
+const loyaltyImprovements = ref([
+  {
+    id: 1,
+    strategyName: '宸紓鍖栧畾浠风瓥鐣�',
+    successRate: 85,
+    description: '鏍规嵁瀹㈡埛閲囪喘棰戞鍜岃浠疯兘鍔涳紝鍒跺畾涓�у寲浠锋牸鏂规'
+  },
+  {
+    id: 2,
+    strategyName: '绮惧噯鎺ㄥ崟鑺傚',
+    successRate: 78,
+    description: '鍩轰簬瀹㈡埛閲囪喘鍛ㄦ湡鍒嗘瀽锛屽湪鏈�浣虫椂鏈烘帹閫佺浉鍏充骇鍝�'
+  },
+  {
+    id: 3,
+    strategyName: '澧炲�兼湇鍔″寘',
+    successRate: 92,
+    description: '鎻愪緵鐗╂祦閰嶉�併�佽川閲忔娴嬬瓑澧炲�兼湇鍔★紝鎻愬崌瀹㈡埛婊℃剰搴�'
+  }
+])
+
+// 妯℃嫙鏁版嵁鐢熸垚
+const generateMockData = () => {
+  // 鐢熸垚浠锋牸瓒嬪娍鏁版嵁
+  const dates = []
+  const prices = []
+  const volumes = []
+  
+  for (let i = 30; i >= 0; i--) {
+    const date = new Date()
+    date.setDate(date.getDate() - i)
+    dates.push(date.toLocaleDateString())
+    
+    const basePrice = 1200 + Math.random() * 200
+    prices.push(basePrice)
+    
+    const baseVolume = 30 + Math.random() * 20
+    volumes.push(baseVolume)
+  }
+  
+  return { dates, prices, volumes }
+}
+
+// 鍒濆鍖栦环鏍艰秼鍔垮浘琛�
+const initPriceChart = () => {
+  if (!priceChartRef.value) return
+  
+  priceChart = echarts.init(priceChartRef.value)
+  const { dates, prices, volumes } = generateMockData()
+  
+  const option = {
+    title: {
+      text: '娣风叅鏈堝害浠锋牸鍙樺寲瓒嬪娍',
+      left: 'center',
+      textStyle: {
+        fontSize: 16,
+        fontWeight: 'bold'
+      }
+    },
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'cross'
+      }
+    },
+    legend: {
+      data: ['浠锋牸(鍏�/鍚�)', '浜ゆ槗閲�(涓囧惃)'],
+      top: 30
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      data: dates,
+      axisLabel: {
+        rotate: 45
+      }
+    },
+    yAxis: [
+      {
+        type: 'value',
+        name: '浠锋牸(鍏�/鍚�)',
+        position: 'left'
+      },
+      {
+        type: 'value',
+        name: '浜ゆ槗閲�(涓囧惃)',
+        position: 'right'
+      }
+    ],
+    series: [
+      {
+        name: '浠锋牸(鍏�/鍚�)',
+        type: 'line',
+        data: prices,
+        smooth: true,
+        lineStyle: {
+          color: '#409EFF',
+          width: 3
+        },
+        itemStyle: {
+          color: '#409EFF'
+        }
+      },
+      {
+        name: '浜ゆ槗閲�(涓囧惃)',
+        type: 'bar',
+        yAxisIndex: 1,
+        data: volumes,
+        itemStyle: {
+          color: '#67C23A'
+        }
+      }
+    ]
+  }
+  
+  priceChart.setOption(option)
+}
+
+// 鍒濆鍖栧鎴峰垎甯冨浘琛�
+const initCustomerChart = () => {
+  if (!customerChartRef.value) return
+  
+  customerChart = echarts.init(customerChartRef.value)
+  
+  const option = {
+    tooltip: {
+      trigger: 'item',
+      formatter: '{a} <br/>{b}: {c} ({d}%)'
+    },
+    series: [
+      {
+        name: '瀹㈡埛绫诲瀷',
+        type: 'pie',
+        radius: ['40%', '70%'],
+        avoidLabelOverlap: false,
+        label: {
+          show: false,
+          position: 'center'
+        },
+        emphasis: {
+          label: {
+            show: true,
+            fontSize: '18',
+            fontWeight: 'bold'
+          }
+        },
+        labelLine: {
+          show: false
+        },
+        data: [
+          { value: 35, name: '鐒﹀寲鍘�' },
+          { value: 28, name: '鐢靛巶' },
+          { value: 22, name: '閽㈠巶' },
+          { value: 15, name: '鍖栧伐鍘�' }
+        ]
+      }
+    ]
+  }
+  
+  customerChart.setOption(option)
+}
+
+// 鍒濆鍖栧尯鍩熷姣斿浘琛�
+const initRegionChart = () => {
+  if (!regionChartRef.value) return
+  
+  regionChart = echarts.init(regionChartRef.value)
+  
+  const option = {
+    title: {
+      text: '鍚勪骇鍦扮叅浠峰姣�',
+      left: 'center'
+    },
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    legend: {
+      data: ['娣风叅', '绮剧叅', '鍔ㄥ姏鐓�', '鐒︾叅'],
+      top: 30
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      data: ['灞辫タ', '鍐呰挋鍙�', '闄曡タ', '鏂扮枂']
+    },
+    yAxis: {
+      type: 'value',
+      name: '浠锋牸(鍏�/鍚�)'
+    },
+    series: [
+      {
+        name: '娣风叅',
+        type: 'bar',
+        data: [1250, 1180, 1220, 1150]
+      },
+      {
+        name: '绮剧叅',
+        type: 'bar',
+        data: [1350, 1280, 1320, 1250]
+      },
+      {
+        name: '鍔ㄥ姏鐓�',
+        type: 'bar',
+        data: [1150, 1080, 1120, 1050]
+      },
+      {
+        name: '鐒︾叅',
+        type: 'bar',
+        data: [1450, 1380, 1420, 1350]
+      }
+    ]
+  }
+  
+  regionChart.setOption(option)
+}
+
+// 鍒濆鍖栭噰璐懆鏈熷浘琛�
+const initCycleChart = () => {
+  if (!cycleChartRef.value) return
+  
+  cycleChart = echarts.init(cycleChartRef.value)
+  
+  const option = {
+    title: {
+      text: '瀹㈡埛閲囪喘鍛ㄦ湡鍒嗗竷',
+      left: 'center'
+    },
+    tooltip: {
+      trigger: 'item'
+    },
+    series: [
+      {
+        name: '閲囪喘鍛ㄦ湡',
+        type: 'funnel',
+        left: '10%',
+        top: 60,
+        bottom: 60,
+        width: '80%',
+        height: '80%',
+        min: 0,
+        max: 100,
+        minSize: '0%',
+        maxSize: '100%',
+        sort: 'descending',
+        gap: 2,
+        label: {
+          show: true,
+          position: 'inside'
+        },
+        labelLine: {
+          length: 10,
+          lineStyle: {
+            width: 1,
+            type: 'solid'
+          }
+        },
+        itemStyle: {
+          borderColor: '#fff',
+          borderWidth: 1
+        },
+        emphasis: {
+          label: {
+            fontSize: 20
+          }
+        },
+        data: [
+          { value: 100, name: '楂橀瀹㈡埛(鍛ㄩ噰璐�)' },
+          { value: 80, name: '涓瀹㈡埛(鏈堥噰璐�)' },
+          { value: 60, name: '浣庨瀹㈡埛(瀛i噰璐�)' },
+          { value: 40, name: '鍋跺彂瀹㈡埛(骞撮噰璐�)' }
+        ]
+      }
+    ]
+  }
+  
+  cycleChart.setOption(option)
+}
+
+// 鍒锋柊鏁版嵁
+const refreshData = async () => {
+  refreshing.value = true
+  
+  try {
+    // 妯℃嫙鏁版嵁鍒锋柊
+    await new Promise(resolve => setTimeout(resolve, 2000))
+    
+    // 鏇存柊甯傚満鏁版嵁
+    marketData.avgPrice = 1200 + Math.random() * 200
+    marketData.priceChange = (Math.random() - 0.5) * 10
+    marketData.totalVolume = 1000 + Math.random() * 500
+    marketData.volumeChange = (Math.random() - 0.5) * 8
+    marketData.activeCustomers = 140 + Math.floor(Math.random() * 40)
+    marketData.customerChange = (Math.random() - 0.5) * 6
+    marketData.trendScore = 7 + Math.random() * 3
+    
+    // 鏇存柊鏃堕棿
+    lastUpdateTime.value = new Date().toLocaleString()
+    
+    // 閲嶆柊鍒濆鍖栧浘琛�
+    await nextTick()
+    initPriceChart()
+    initCustomerChart()
+    initRegionChart()
+    initCycleChart()
+    
+    ElMessage.success('鏁版嵁鍒锋柊鎴愬姛')
+  } catch (error) {
+    ElMessage.error('鏁版嵁鍒锋柊澶辫触')
+  } finally {
+    refreshing.value = false
+  }
+}
+
+// 鑷姩鍒锋柊瀹氭椂鍣�
+let refreshTimer = null
+
+// 鍚姩鑷姩鍒锋柊
+const startAutoRefresh = () => {
+  refreshTimer = setInterval(() => {
+    refreshData()
+  }, 10 * 60 * 1000) // 10鍒嗛挓
+}
+
+// 鍋滄鑷姩鍒锋柊
+const stopAutoRefresh = () => {
+  if (refreshTimer) {
+    clearInterval(refreshTimer)
+    refreshTimer = null
+  }
+}
+
+// 鐩戝惉绐楀彛澶у皬鍙樺寲
+const handleResize = () => {
+  if (priceChart) priceChart.resize()
+  if (customerChart) customerChart.resize()
+  if (regionChart) regionChart.resize()
+  if (cycleChart) cycleChart.resize()
+}
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(async () => {
+  // 鍒濆鍖栨椂闂�
+  lastUpdateTime.value = new Date().toLocaleString()
+  
+  // 绛夊緟DOM娓叉煋瀹屾垚
+  await nextTick()
+  
+  // 鍒濆鍖栧浘琛�
+  initPriceChart()
+  initCustomerChart()
+  initRegionChart()
+  initCycleChart()
+  
+  // 鍚姩鑷姩鍒锋柊
+  startAutoRefresh()
+  
+  // 鐩戝惉绐楀彛澶у皬鍙樺寲
+  window.addEventListener('resize', handleResize)
+})
+
+onUnmounted(() => {
+  // 鍋滄鑷姩鍒锋柊
+  stopAutoRefresh()
+  
+  // 閿�姣佸浘琛�
+  if (priceChart) priceChart.dispose()
+  if (customerChart) customerChart.dispose()
+  if (regionChart) regionChart.dispose()
+  if (cycleChart) cycleChart.dispose()
+  
+  // 绉婚櫎浜嬩欢鐩戝惉
+  window.removeEventListener('resize', handleResize)
+})
+</script>
+
+<style scoped>
+.market-analysis-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding: 20px;
+  background: white;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.page-header h1 {
+  margin: 0;
+  color: #303133;
+  font-size: 24px;
+  font-weight: 600;
+}
+
+.header-info {
+  display: flex;
+  align-items: center;
+  gap: 15px;
+}
+
+.update-time {
+  color: #909399;
+  font-size: 14px;
+}
+
+.data-overview {
+  margin-bottom: 20px;
+}
+
+.overview-card {
+  height: 120px;
+}
+
+.card-content {
+  display: flex;
+  align-items: center;
+  height: 100%;
+}
+
+.card-icon {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 15px;
+  font-size: 24px;
+  color: white;
+}
+
+.price-icon {
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+}
+
+.volume-icon {
+  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
+}
+
+.customer-icon {
+  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+}
+
+.trend-icon {
+  background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+}
+
+.card-info {
+  flex: 1;
+}
+
+.card-title {
+  font-size: 14px;
+  color: #909399;
+  margin-bottom: 8px;
+}
+
+.card-value {
+  font-size: 24px;
+  font-weight: 600;
+  color: #303133;
+  margin-bottom: 8px;
+}
+
+.card-change {
+  font-size: 12px;
+  font-weight: 500;
+}
+
+.card-change.positive {
+  color: #67c23a;
+}
+
+.card-change.negative {
+  color: #f56c6c;
+}
+
+.main-analysis {
+  margin-bottom: 20px;
+}
+
+.analysis-card {
+  margin-bottom: 20px;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-weight: 600;
+  font-size: 16px;
+}
+
+.header-controls {
+  display: flex;
+  gap: 10px;
+}
+
+.chart-container {
+  padding: 10px 0;
+}
+
+.chart {
+  width: 100%;
+}
+
+.customer-analysis h4 {
+  margin: 0 0 15px 0;
+  color: #303133;
+  font-size: 14px;
+}
+
+.customer-type-distribution {
+  margin-bottom: 20px;
+}
+
+.preference-item {
+  display: flex;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.preference-label {
+  width: 80px;
+  font-size: 12px;
+  color: #606266;
+}
+
+.preference-bar {
+  flex: 1;
+  height: 8px;
+  background-color: #f0f0f0;
+  border-radius: 4px;
+  margin: 0 10px;
+  overflow: hidden;
+}
+
+.bar-fill {
+  height: 100%;
+  background: linear-gradient(90deg, #409eff 0%, #67c23a 100%);
+  border-radius: 4px;
+  transition: width 0.3s ease;
+}
+
+.preference-value {
+  width: 40px;
+  font-size: 12px;
+  color: #409eff;
+  font-weight: 500;
+}
+
+.detail-analysis {
+  margin-bottom: 20px;
+}
+
+.smart-recommendations {
+  margin-bottom: 20px;
+}
+
+.recommendations-content {
+  padding: 10px 0;
+}
+
+.recommendation-section h4 {
+  margin: 0 0 15px 0;
+  color: #303133;
+  font-size: 14px;
+  border-bottom: 2px solid #409eff;
+  padding-bottom: 5px;
+}
+
+.suggestion-item {
+  background: #f8f9fa;
+  border-radius: 6px;
+  padding: 12px;
+  margin-bottom: 12px;
+  border-left: 4px solid #409eff;
+}
+
+.suggestion-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.customer-name {
+  font-weight: 500;
+  color: #303133;
+}
+
+.suggestion-content p {
+  margin: 5px 0;
+  font-size: 12px;
+  color: #606266;
+}
+
+.coal-type-item {
+  background: #f8f9fa;
+  border-radius: 6px;
+  padding: 12px;
+  margin-bottom: 12px;
+  border-left: 4px solid #67c23a;
+}
+
+.coal-info {
+  margin-bottom: 8px;
+}
+
+.coal-name {
+  font-weight: 500;
+  color: #303133;
+  font-size: 14px;
+}
+
+.coal-spec {
+  font-size: 12px;
+  color: #909399;
+}
+
+.coal-metrics {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.metric {
+  font-size: 12px;
+}
+
+.metric .label {
+  color: #909399;
+}
+
+.metric .value {
+  color: #409eff;
+  font-weight: 500;
+}
+
+.improvement-item {
+  background: #f8f9fa;
+  border-radius: 6px;
+  padding: 12px;
+  margin-bottom: 12px;
+  border-left: 4px solid #e6a23c;
+}
+
+.improvement-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.strategy-name {
+  font-weight: 500;
+  color: #303133;
+}
+
+.success-rate {
+  font-size: 12px;
+  color: #67c23a;
+  font-weight: 500;
+}
+
+.improvement-content p {
+  margin: 5px 0 10px 0;
+  font-size: 12px;
+  color: #606266;
+}
+
+.action-buttons {
+  display: flex;
+  gap: 8px;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 1200px) {
+  .header-controls {
+    flex-direction: column;
+    gap: 5px;
+  }
+  
+  .header-controls .el-select {
+    width: 100px !important;
+  }
+}
+
+@media (max-width: 768px) {
+  .page-header {
+    flex-direction: column;
+    gap: 15px;
+    text-align: center;
+  }
+  
+  .header-info {
+    flex-direction: column;
+    gap: 10px;
+  }
+}
+</style>

--
Gitblit v1.9.3