From 8ab349b4e271a068b67ad767587e23685760bd12 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期二, 17 三月 2026 11:34:57 +0800
Subject: [PATCH] 销售统计看板和生产统计看板页面设计

---
 src/views/reportAnalysis/productionStatistics/index.vue |  866 ++++++++++++++++++++++++++++
 src/views/reportAnalysis/salesStatistics/index.vue      |  923 ++++++++++++++++++++++++++++++
 2 files changed, 1,789 insertions(+), 0 deletions(-)

diff --git a/src/views/reportAnalysis/productionStatistics/index.vue b/src/views/reportAnalysis/productionStatistics/index.vue
new file mode 100644
index 0000000..64acd40
--- /dev/null
+++ b/src/views/reportAnalysis/productionStatistics/index.vue
@@ -0,0 +1,866 @@
+<template>
+  <div class="dashboard-container">
+    <div class="data-dashboard">
+
+    <!-- 椤堕儴鏍囬鏍� -->
+    <!-- <div class="dashboard-header">
+      <div class="factory-name">鐢熶骇缁熻鐪嬫澘</div>
+    </div> -->
+
+    <!-- 绛涢�夊尯鍩� -->
+    <div class="filter-area">
+      <div class="filter-section">
+        <span class="filter-label">鏃堕棿缁村害锛�</span>
+        <el-radio-group v-model="dateType" @change="handleDateTypeChange" class="radio-group">
+          <el-radio-button label="month">鏈堝害</el-radio-button>
+          <el-radio-button label="year">骞村害</el-radio-button>
+        </el-radio-group>
+      </div>
+      <div class="filter-section">
+        <span class="filter-label">浜у搧绫诲瀷锛�</span>
+        <el-radio-group v-model="productType" @change="handleProductTypeChange" class="radio-group">
+          <el-radio-button label="block">鐮屽潡</el-radio-button>
+          <el-radio-button label="plate">鏉挎潗</el-radio-button>
+        </el-radio-group>
+      </div>
+    </div>
+
+    <!-- 涓昏鍐呭鍖哄煙 -->
+    <div class="dashboard-content">
+      <!-- 绗竴琛� -->
+      <div class="row row-1">
+        <div class="panel-card card-1">
+          <div class="panel-title">浜ч噺鎸囨爣</div>
+          <div class="chart-container">
+            <div ref="productionChart" style="width: 100%; height: 100%"></div>
+          </div>
+        </div>
+        <div class="panel-card card-2">
+          <div class="panel-title">鍥哄簾澶勭悊閲�</div>
+          <div class="chart-container">
+            <div ref="solidWasteChart" style="width: 100%; height: 100%"></div>
+          </div>
+        </div>
+        <div class="panel-card card-3">
+          <div class="panel-title">缁煎悎缁熻</div>
+          <div class="stats-grid">
+            <div class="stat-item">
+              <div class="stat-label">鎬讳骇鑳�</div>
+              <div class="stat-value">{{ totalProduction }}</div>
+              <div class="stat-unit">绔嬫柟绫�</div>
+            </div>
+            <div class="stat-item">
+              <div class="stat-label">鎬诲浐搴熷鐞�</div>
+              <div class="stat-value">{{ totalSolidWaste }}</div>
+              <div class="stat-unit">鍚�</div>
+            </div>
+            <div class="stat-item">
+              <div class="stat-label">骞冲潎鍗曡��</div>
+              <div class="stat-value">{{ averageUnitConsumption }}</div>
+              <div class="stat-unit">鍚�/绔嬫柟绫�</div>
+            </div>
+            <div class="stat-item">
+              <div class="stat-label">鎬昏兘鑰�</div>
+              <div class="stat-value">{{ totalEnergy }}</div>
+              <div class="stat-unit">kWh</div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 绗簩琛� -->
+      <div class="row row-2">
+        <div class="panel-card card-4">
+          <div class="panel-title">鐢熶骇鎴愭湰鍗曡��</div>
+          <div class="chart-container">
+            <div ref="costChart" style="width: 100%; height: 100%"></div>
+          </div>
+        </div>
+        <div class="panel-card card-5">
+          <div class="panel-title">鐢熶骇鑳借�楁暟鎹�</div>
+          <div class="chart-container">
+            <div ref="energyChart" style="width: 100%; height: 100%"></div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 绗笁琛� -->
+      <div class="row row-3">
+        <div class="panel-card card-6">
+          <div class="panel-title">鍗曡�楁暟鎹槑缁�</div>
+          <div class="table-container">
+            <el-table :data="costTableData" style="width: 100%">
+              <el-table-column prop="material" label="鐗╂枡绫诲瀷" width="120" />
+              <el-table-column prop="unit" label="鍗曚綅" width="100" />
+              <el-table-column prop="monthlyConsumption" label="鏈堝害绱鐢ㄩ噺" />
+              <el-table-column prop="monthlyProduction" label="鏈堝害绱浜ч噺" />
+              <el-table-column prop="monthlyUnitConsumption" label="鏈堝害绱鍗曡��" />
+              <el-table-column prop="yearlyConsumption" label="骞村害绱鐢ㄩ噺" />
+              <el-table-column prop="yearlyProduction" label="骞村害绱浜ч噺" />
+              <el-table-column prop="yearlyUnitConsumption" label="骞村害绱鍗曡��" />
+            </el-table>
+          </div>
+        </div>
+      </div>
+    </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
+import * as echarts from 'echarts'
+
+// 绛涢�夋潯浠�
+const dateType = ref('month') // month 鎴� year
+const productType = ref('block') // block 鎴� plate
+
+// 鍥捐〃寮曠敤
+const productionChart = ref(null)
+const solidWasteChart = ref(null)
+const costChart = ref(null)
+const energyChart = ref(null)
+
+// 鍥捐〃瀹炰緥
+let productionChartInstance = null
+let solidWasteChartInstance = null
+let costChartInstance = null
+let energyChartInstance = null
+
+// 妯℃嫙鏁版嵁
+const productionData = ref({
+  month: [
+    { name: '1鏈�', block: 1200, plate: 800 },
+    { name: '2鏈�', block: 1300, plate: 850 },
+    { name: '3鏈�', block: 1100, plate: 750 },
+    { name: '4鏈�', block: 1400, plate: 900 },
+    { name: '5鏈�', block: 1500, plate: 950 },
+    { name: '6鏈�', block: 1350, plate: 880 },
+    { name: '7鏈�', block: 1450, plate: 920 },
+    { name: '8鏈�', block: 1600, plate: 1000 },
+    { name: '9鏈�', block: 1550, plate: 980 },
+    { name: '10鏈�', block: 1700, plate: 1050 },
+    { name: '11鏈�', block: 1650, plate: 1020 },
+    { name: '12鏈�', block: 1800, plate: 1100 }
+  ],
+  year: [
+    { name: '2023', block: 15000, plate: 9500 },
+    { name: '2024', block: 16500, plate: 10200 },
+    { name: '2025', block: 18000, plate: 11000 }
+  ]
+})
+
+const solidWasteData = ref({
+  month: [
+    { name: '1鏈�', 绮夌叅鐏�: 200, 鐭宠啅: 150, 鐭崇伆: 100 },
+    { name: '2鏈�', 绮夌叅鐏�: 220, 鐭宠啅: 160, 鐭崇伆: 110 },
+    { name: '3鏈�', 绮夌叅鐏�: 190, 鐭宠啅: 140, 鐭崇伆: 95 },
+    { name: '4鏈�', 绮夌叅鐏�: 230, 鐭宠啅: 170, 鐭崇伆: 115 },
+    { name: '5鏈�', 绮夌叅鐏�: 240, 鐭宠啅: 180, 鐭崇伆: 120 },
+    { name: '6鏈�', 绮夌叅鐏�: 225, 鐭宠啅: 165, 鐭崇伆: 112 }
+  ],
+  year: [
+    { name: '2023', 绮夌叅鐏�: 2500, 鐭宠啅: 1800, 鐭崇伆: 1200 },
+    { name: '2024', 绮夌叅鐏�: 2700, 鐭宠啅: 1950, 鐭崇伆: 1300 },
+    { name: '2025', 绮夌叅鐏�: 2900, 鐭宠啅: 2100, 鐭崇伆: 1400 }
+  ]
+})
+
+const costData = ref({
+  materials: ['姘存偿', '閾濈矇鑶�', '鑴辨ā鍓�', '闃茶厫鍓�', '姘寲鍓�', '鍐锋嫈涓�'],
+  month: {
+    consumption: [1200, 50, 80, 30, 40, 60],
+    production: [12000, 12000, 12000, 8000, 8000, 8000],
+    unitConsumption: [0.1, 0.0042, 0.0067, 0.0038, 0.005, 0.0075]
+  },
+  year: {
+    consumption: [14000, 600, 950, 350, 480, 720],
+    production: [140000, 140000, 140000, 95000, 95000, 95000],
+    unitConsumption: [0.1, 0.0043, 0.0068, 0.0037, 0.0051, 0.0076]
+  }
+})
+
+const energyData = ref({
+  month: [
+    { name: '1鏈�', 鐢甸噺: 12000, 姘撮噺: 8000, 姘旈噺: 5000 },
+    { name: '2鏈�', 鐢甸噺: 13000, 姘撮噺: 8500, 姘旈噺: 5500 },
+    { name: '3鏈�', 鐢甸噺: 11000, 姘撮噺: 7500, 姘旈噺: 4800 },
+    { name: '4鏈�', 鐢甸噺: 14000, 姘撮噺: 9000, 姘旈噺: 6000 },
+    { name: '5鏈�', 鐢甸噺: 15000, 姘撮噺: 9500, 姘旈噺: 6500 },
+    { name: '6鏈�', 鐢甸噺: 13500, 姘撮噺: 8800, 姘旈噺: 5800 }
+  ],
+  year: [
+    { name: '2023', 鐢甸噺: 140000, 姘撮噺: 95000, 姘旈噺: 65000 },
+    { name: '2024', 鐢甸噺: 150000, 姘撮噺: 100000, 姘旈噺: 70000 },
+    { name: '2025', 鐢甸噺: 160000, 姘撮噺: 105000, 姘旈噺: 75000 }
+  ]
+})
+
+// 璁$畻灞炴��
+const productionChartOption = computed(() => {
+  const data = productionData.value[dateType.value]
+  return {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    legend: {
+      data: ['鐮屽潡', '鏉挎潗'],
+      textStyle: {
+        color: '#333'
+      }
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      data: data.map(item => item.name),
+      axisLabel: {
+        color: '#333'
+      }
+    },
+    yAxis: {
+      type: 'value',
+      name: '浜ч噺 (绔嬫柟绫�)',
+      axisLabel: {
+        color: '#333'
+      }
+    },
+    series: [
+      {
+        name: '鐮屽潡',
+        type: 'line',
+        data: data.map(item => item.block),
+        smooth: true,
+        lineStyle: {
+          width: 3
+        },
+        itemStyle: {
+          color: '#409EFF'
+        }
+      },
+      {
+        name: '鏉挎潗',
+        type: 'line',
+        data: data.map(item => item.plate),
+        smooth: true,
+        lineStyle: {
+          width: 3
+        },
+        itemStyle: {
+          color: '#67C23A'
+        }
+      }
+    ]
+  }
+})
+
+const solidWasteChartOption = computed(() => {
+  const data = solidWasteData.value[dateType.value]
+  return {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    legend: {
+      data: ['绮夌叅鐏�', '鐭宠啅', '鐭崇伆'],
+      textStyle: {
+        color: '#333'
+      }
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      data: data.map(item => item.name),
+      axisLabel: {
+        color: '#333'
+      }
+    },
+    yAxis: {
+      type: 'value',
+      name: '澶勭悊閲� (鍚�)',
+      axisLabel: {
+        color: '#333'
+      }
+    },
+    series: [
+      {
+        name: '绮夌叅鐏�',
+        type: 'bar',
+        data: data.map(item => item.绮夌叅鐏�),
+        itemStyle: {
+          color: '#909399'
+        }
+      },
+      {
+        name: '鐭宠啅',
+        type: 'bar',
+        data: data.map(item => item.鐭宠啅),
+        itemStyle: {
+          color: '#E6A23C'
+        }
+      },
+      {
+        name: '鐭崇伆',
+        type: 'bar',
+        data: data.map(item => item.鐭崇伆),
+        itemStyle: {
+          color: '#F56C6C'
+        }
+      }
+    ]
+  }
+})
+
+const costChartOption = computed(() => {
+  const data = costData.value
+  return {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    legend: {
+      data: ['鏈堝害鍗曡��', '骞村害鍗曡��'],
+      textStyle: {
+        color: '#333'
+      }
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      data: data.materials,
+      axisLabel: {
+        color: '#333',
+        rotate: 45
+      }
+    },
+    yAxis: {
+      type: 'value',
+      name: '鍗曡�� (鍚�/绔嬫柟绫�)',
+      axisLabel: {
+        color: '#333'
+      }
+    },
+    series: [
+      {
+        name: '鏈堝害鍗曡��',
+        type: 'bar',
+        data: data.month.unitConsumption,
+        itemStyle: {
+          color: '#409EFF'
+        }
+      },
+      {
+        name: '骞村害鍗曡��',
+        type: 'bar',
+        data: data.year.unitConsumption,
+        itemStyle: {
+          color: '#67C23A'
+        }
+      }
+    ]
+  }
+})
+
+const energyChartOption = computed(() => {
+  const data = energyData.value[dateType.value]
+  return {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    legend: {
+      data: ['鐢甸噺', '姘撮噺', '姘旈噺'],
+      textStyle: {
+        color: '#333'
+      }
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      data: data.map(item => item.name),
+      axisLabel: {
+        color: '#333'
+      }
+    },
+    yAxis: {
+      type: 'value',
+      name: '鑳借�楅噺',
+      axisLabel: {
+        color: '#333'
+      }
+    },
+    series: [
+      {
+        name: '鐢甸噺',
+        type: 'line',
+        data: data.map(item => item.鐢甸噺),
+        smooth: true,
+        lineStyle: {
+          width: 3
+        },
+        itemStyle: {
+          color: '#409EFF'
+        }
+      },
+      {
+        name: '姘撮噺',
+        type: 'line',
+        data: data.map(item => item.姘撮噺),
+        smooth: true,
+        lineStyle: {
+          width: 3
+        },
+        itemStyle: {
+          color: '#67C23A'
+        }
+      },
+      {
+        name: '姘旈噺',
+        type: 'line',
+        data: data.map(item => item.姘旈噺),
+        smooth: true,
+        lineStyle: {
+          width: 3
+        },
+        itemStyle: {
+          color: '#E6A23C'
+        }
+      }
+    ]
+  }
+})
+
+const costTableData = computed(() => {
+  const data = costData.value
+  const materials = data.materials
+  const monthData = data.month
+  const yearData = data.year
+  
+  return materials.map((material, index) => ({
+    material,
+    unit: '鍚�/绔嬫柟绫�',
+    monthlyConsumption: monthData.consumption[index],
+    monthlyProduction: monthData.production[index],
+    monthlyUnitConsumption: monthData.unitConsumption[index].toFixed(4),
+    yearlyConsumption: yearData.consumption[index],
+    yearlyProduction: yearData.production[index],
+    yearlyUnitConsumption: yearData.unitConsumption[index].toFixed(4)
+  }))
+})
+
+const totalProduction = computed(() => {
+  const data = productionData.value[dateType.value]
+  if (dateType.value === 'month') {
+    return data.reduce((sum, item) => sum + item[productType.value === 'block' ? 'block' : 'plate'], 0)
+  } else {
+    return data[data.length - 1][productType.value === 'block' ? 'block' : 'plate']
+  }
+})
+
+const totalSolidWaste = computed(() => {
+  const data = solidWasteData.value[dateType.value]
+  if (dateType.value === 'month') {
+    return data.reduce((sum, item) => sum + item.绮夌叅鐏� + item.鐭宠啅 + item.鐭崇伆, 0)
+  } else {
+    const lastItem = data[data.length - 1]
+    return lastItem.绮夌叅鐏� + lastItem.鐭宠啅 + lastItem.鐭崇伆
+  }
+})
+
+const averageUnitConsumption = computed(() => {
+  const data = costData.value
+  const unitConsumption = dateType.value === 'month' ? data.month.unitConsumption : data.year.unitConsumption
+  const average = unitConsumption.reduce((sum, value) => sum + value, 0) / unitConsumption.length
+  return average.toFixed(4)
+})
+
+const totalEnergy = computed(() => {
+  const data = energyData.value[dateType.value]
+  if (dateType.value === 'month') {
+    return data.reduce((sum, item) => sum + item.鐢甸噺 + item.姘撮噺 + item.姘旈噺, 0)
+  } else {
+    const lastItem = data[data.length - 1]
+    return lastItem.鐢甸噺 + lastItem.姘撮噺 + lastItem.姘旈噺
+  }
+})
+
+// 浜嬩欢澶勭悊
+const handleDateTypeChange = () => {
+  updateCharts()
+}
+
+const handleProductTypeChange = () => {
+  updateCharts()
+}
+
+// 鍒濆鍖栧浘琛�
+const initCharts = () => {
+  if (productionChart.value) {
+    productionChartInstance = echarts.init(productionChart.value)
+    productionChartInstance.setOption(productionChartOption.value)
+  }
+  
+  if (solidWasteChart.value) {
+    solidWasteChartInstance = echarts.init(solidWasteChart.value)
+    solidWasteChartInstance.setOption(solidWasteChartOption.value)
+  }
+  
+  if (costChart.value) {
+    costChartInstance = echarts.init(costChart.value)
+    costChartInstance.setOption(costChartOption.value)
+  }
+  
+  if (energyChart.value) {
+    energyChartInstance = echarts.init(energyChart.value)
+    energyChartInstance.setOption(energyChartOption.value)
+  }
+}
+
+// 鏇存柊鍥捐〃
+const updateCharts = () => {
+  if (productionChartInstance) {
+    productionChartInstance.setOption(productionChartOption.value)
+  }
+  
+  if (solidWasteChartInstance) {
+    solidWasteChartInstance.setOption(solidWasteChartOption.value)
+  }
+  
+  if (costChartInstance) {
+    costChartInstance.setOption(costChartOption.value)
+  }
+  
+  if (energyChartInstance) {
+    energyChartInstance.setOption(energyChartOption.value)
+  }
+}
+
+// 璋冩暣鍥捐〃澶у皬
+const resizeCharts = () => {
+  productionChartInstance?.resize()
+  solidWasteChartInstance?.resize()
+  costChartInstance?.resize()
+  energyChartInstance?.resize()
+}
+
+// 绐楀彛澶у皬鍙樺寲澶勭悊
+const handleResize = () => {
+  // 寤惰繜鎵ц锛岀‘淇滵OM鏇存柊瀹屾垚
+  setTimeout(() => {
+    resizeCharts()
+  }, 100)
+}
+
+// 鐢熷懡鍛ㄦ湡閽╁瓙
+onMounted(() => {
+  // 浣跨敤nextTick纭繚DOM瀹屽叏娓叉煋鍚庡啀鍒濆鍖�
+  nextTick(() => {
+    // 鍒濆鍖栧浘琛�
+    initCharts()
+  })
+
+  window.addEventListener('resize', handleResize)
+})
+
+onBeforeUnmount(() => {
+  window.removeEventListener('resize', handleResize)
+  
+  // 閿�姣佸浘琛ㄥ疄渚�
+  productionChartInstance?.dispose()
+  solidWasteChartInstance?.dispose()
+  costChartInstance?.dispose()
+  energyChartInstance?.dispose()
+})
+</script>
+
+<style scoped>
+/* 澶栭儴瀹瑰櫒 - 鍗犳嵁鏁翠釜瑙嗗彛 */
+.dashboard-container {
+  position: relative;
+  width: 100%;
+  /* 椤甸潰鍦ㄥ父瑙勫竷灞�涓嬶紙鏈夐《鏍忥級榛樿鍑忓幓 84px锛岄伩鍏嶅唴瀹硅瑁佸垏 */
+  min-height: calc(100vh - 84px);
+  background-color: #f5f7fa;
+  overflow: hidden;
+}
+
+/* 鍐呴儴鍐呭鍖哄煙 - 鑷�傚簲瀹藉害 */
+.data-dashboard {
+  position: relative;
+  width: 100%;
+  min-height: 100%;
+  background-color: #ffffff;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
+}
+
+.dashboard-header {
+  position: relative;
+  z-index: 1;
+  height: 86px;
+  background-color: #ffffff;
+  border-bottom: 1px solid #e4e7ed;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.factory-name {
+  font-weight: 600;
+  font-size: 32px;
+  color: #303133;
+}
+
+.filter-area {
+  padding: 20px;
+  background-color: #ffffff;
+  border-bottom: 1px solid #e4e7ed;
+  display: flex;
+  gap: 40px;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.filter-section {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.filter-label {
+  font-size: 14px;
+  font-weight: 500;
+  color: #303133;
+  white-space: nowrap;
+}
+
+.radio-group {
+  display: flex;
+  align-items: center;
+}
+
+/* 鎸夐挳鏍峰紡 */
+:deep(.el-radio-button__inner) {
+  border-radius: 4px;
+  padding: 8px 20px;
+  font-size: 14px;
+  transition: all 0.3s ease;
+}
+
+:deep(.el-radio-button__orig-radio:checked + .el-radio-button__inner) {
+  background-color: #409eff;
+  border-color: #409eff;
+  color: #ffffff;
+  box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3);
+}
+
+:deep(.el-radio-button__inner:hover) {
+  color: #409eff;
+  border-color: #c6e2ff;
+}
+
+:deep(.el-radio-button:first-child .el-radio-button__inner) {
+  border-radius: 4px 0 0 4px;
+}
+
+:deep(.el-radio-button:last-child .el-radio-button__inner) {
+  border-radius: 0 4px 4px 0;
+}
+
+.dashboard-content {
+  position: relative;
+  z-index: 1;
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+  padding: 20px;
+  min-height: 800px;
+  overflow: hidden;
+}
+
+/* 琛屽竷灞� */
+.row {
+  display: flex;
+  gap: 20px;
+  align-items: stretch;
+}
+
+/* 绗竴琛岋細3涓崱鐗� */
+.row-1 {
+  height: 300px;
+}
+
+/* 绗簩琛岋細2涓崱鐗� */
+.row-2 {
+  height: 300px;
+}
+
+/* 绗笁琛岋細1涓崱鐗� */
+.row-3 {
+  min-height: 250px;
+}
+
+/* 鍗$墖鏍峰紡 */
+.panel-card {
+  background-color: #ffffff;
+  border-radius: 8px;
+  border: 1px solid #e4e7ed;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  transition: all 0.3s ease;
+}
+
+.panel-card:hover {
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
+  transform: translateY(-2px);
+}
+
+/* 鍗$墖甯冨眬 */
+.card-1 {
+  flex: 1;
+}
+
+.card-2 {
+  flex: 1;
+}
+
+.card-3 {
+  flex: 0.8;
+}
+
+.card-4 {
+  flex: 1.2;
+}
+
+.card-5 {
+  flex: 0.8;
+}
+
+.card-6 {
+  flex: 1;
+}
+
+.panel-card {
+  background-color: #ffffff;
+  border-radius: 8px;
+  border: 1px solid #e4e7ed;
+  overflow: hidden;
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+}
+
+.panel-title {
+  padding: 15px 20px;
+  font-size: 16px;
+  font-weight: 500;
+  color: #303133;
+  border-bottom: 1px solid #e4e7ed;
+  background-color: #fafafa;
+}
+
+.chart-container {
+  flex: 1;
+  padding: 20px;
+}
+
+.table-container {
+  flex: 1;
+  padding: 20px;
+  overflow: auto;
+}
+
+.stats-grid {
+  flex: 1;
+  padding: 15px;
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  grid-template-rows: repeat(2, 1fr);
+  gap: 15px;
+}
+
+.stat-item {
+  background-color: #fafafa;
+  border-radius: 8px;
+  padding: 15px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  border: 1px solid #e4e7ed;
+  min-height: 80px;
+}
+
+.stat-label {
+  font-size: 13px;
+  color: #606266;
+  margin-bottom: 8px;
+}
+
+.stat-value {
+  font-size: 20px;
+  font-weight: 600;
+  color: #303133;
+  margin-bottom: 3px;
+}
+
+.stat-unit {
+  font-size: 11px;
+  color: #909399;
+}
+
+/* 琛ㄦ牸鏍峰紡 */
+:deep(.el-table) {
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+:deep(.el-table th) {
+  background-color: #fafafa;
+  font-weight: 500;
+}
+
+:deep(.el-table tr:hover > td) {
+  background-color: #ecf5ff;
+}
+
+/* 鎸夐挳鏍峰紡 */
+:deep(.el-radio-button__inner) {
+  border-radius: 4px;
+}
+
+:deep(.el-radio-button__orig-radio:checked + .el-radio-button__inner) {
+  background-color: #409eff;
+  border-color: #409eff;
+  color: #ffffff;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/reportAnalysis/salesStatistics/index.vue b/src/views/reportAnalysis/salesStatistics/index.vue
new file mode 100644
index 0000000..8dc1a6a
--- /dev/null
+++ b/src/views/reportAnalysis/salesStatistics/index.vue
@@ -0,0 +1,923 @@
+<template>
+  <div class="sales-statistics-container">
+    <div class="data-dashboard">
+      <!-- 椤甸潰鏍囬 -->
+      <!-- <div class="dashboard-header">
+        <div class="factory-name">閿�鍞粺璁$湅鏉�</div>
+      </div> -->
+      
+      <!-- 绛涢�夋潯浠� -->
+      <div class="filter-area">
+        <div class="filter-section">
+          <span class="filter-label">鏃堕棿鑼冨洿锛�</span>
+          <el-date-picker
+            v-model="dateRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            value-format="YYYY-MM-DD"
+            @change="handleDateChange"
+            style="width: 240px;"
+          />
+        </div>
+        <div class="filter-section">
+          <span class="filter-label">浜у搧绫诲瀷锛�</span>
+          <el-select v-model="productType" placeholder="璇烽�夋嫨浜у搧绫诲瀷" @change="handleFilterChange" style="width: 160px;">
+            <el-option label="鍏ㄩ儴" value="" />
+            <el-option label="鐮屽潡" value="block" />
+            <el-option label="鏉挎潗" value="board" />
+            <el-option label="鍨嬫潗" value="profile" />
+          </el-select>
+        </div>
+        <div class="filter-section">
+          <span class="filter-label">閿�鍞尯鍩燂細</span>
+          <el-select v-model="salesArea" placeholder="璇烽�夋嫨閿�鍞尯鍩�" @change="handleFilterChange" style="width: 160px;">
+            <el-option label="鍏ㄩ儴" value="" />
+            <el-option label="鍗庝笢" value="east" />
+            <el-option label="鍗庡寳" value="north" />
+            <el-option label="鍗庡崡" value="south" />
+            <el-option label="瑗垮崡" value="southwest" />
+            <el-option label="瑗垮寳" value="northwest" />
+          </el-select>
+        </div>
+        <div class="filter-section">
+          <span class="filter-label">缁熻缁村害锛�</span>
+          <el-select v-model="statDimension" placeholder="璇烽�夋嫨缁熻缁村害" @change="handleFilterChange" style="width: 160px;">
+            <el-option label="鏈堝害" value="month" />
+            <el-option label="骞村害" value="year" />
+          </el-select>
+        </div>
+      </div>
+      
+      <div class="dashboard-content">
+        <!-- 鏍稿績鎸囨爣鍗$墖 -->
+        <div class="row row-1">
+          <div class="panel-card card-1">
+            <div class="panel-title">鍚堣閿�閲�</div>
+            <div class="stats-grid">
+              <div class="stat-item">
+                <div class="stat-value">{{ totalSalesVolume }}</div>
+                <div class="stat-unit">绔嬫柟绫�</div>
+                <div class="stat-change">{{ salesVolumeChange }}%</div>
+              </div>
+            </div>
+          </div>
+          <div class="panel-card card-2">
+            <div class="panel-title">閿�鍞噾棰�</div>
+            <div class="stats-grid">
+              <div class="stat-item">
+                <div class="stat-value">{{ totalSalesAmount }}</div>
+                <div class="stat-unit">涓囧厓</div>
+                <div class="stat-change">{{ salesAmountChange }}%</div>
+              </div>
+            </div>
+          </div>
+          <div class="panel-card card-3">
+            <div class="panel-title">鏂板瀹㈡埛</div>
+            <div class="stats-grid">
+              <div class="stat-item">
+                <div class="stat-value">{{ newCustomerCount }}</div>
+                <div class="stat-unit">涓�</div>
+                <div class="stat-change">{{ customerCountChange }}%</div>
+              </div>
+            </div>
+          </div>
+          <div class="panel-card card-4">
+            <div class="panel-title">鍚堣瀹㈡埛</div>
+            <div class="stats-grid">
+              <div class="stat-item">
+                <div class="stat-value">{{ totalCustomerCount }}</div>
+                <div class="stat-unit">涓�</div>
+                <div class="stat-change">{{ totalCustomerChange }}%</div>
+              </div>
+            </div>
+          </div>
+        </div>
+        
+        <!-- 閿�閲忓拰閿�鍞噾棰濊秼鍔� -->
+        <div class="row row-2">
+          <div class="panel-card card-5">
+            <div class="panel-title">閿�閲忚秼鍔�</div>
+            <div class="chart-container">
+              <div ref="salesVolumeChart" style="width: 100%; height: 100%;"></div>
+            </div>
+          </div>
+          <div class="panel-card card-6">
+            <div class="panel-title">閿�鍞噾棰濊秼鍔�</div>
+            <div class="chart-container">
+              <div ref="salesAmountChart" style="width: 100%; height: 100%;"></div>
+            </div>
+          </div>
+        </div>
+        
+        <!-- 绱鏁版嵁瓒嬪娍 -->
+        <div class="row row-3">
+          <div class="panel-card card-10">
+            <div class="panel-title">绱閿�閲忚秼鍔�</div>
+            <div class="chart-container">
+              <div ref="cumulativeSalesVolumeChart" style="width: 100%; height: 100%;"></div>
+            </div>
+          </div>
+          <div class="panel-card card-11">
+            <div class="panel-title">绱閿�鍞噾棰濊秼鍔�</div>
+            <div class="chart-container">
+              <div ref="cumulativeSalesAmountChart" style="width: 100%; height: 100%;"></div>
+            </div>
+          </div>
+        </div>
+        
+        <!-- 鍥捐〃鍖哄煙鍜岃〃鏍� -->
+        <div class="row row-4">
+          <!-- 宸﹁竟锛氳缁嗘暟鎹〃鏍� -->
+          <div class="panel-card card-9" style="flex: 2;">
+            <div class="panel-title">閿�鍞粺璁¤缁嗘暟鎹�</div>
+            <div class="table-container">
+              <el-table :data="tableData" style="width: 100%">
+                <el-table-column prop="productType" label="浜у搧绫诲瀷" width="120" />
+                <el-table-column prop="salesArea" label="閿�鍞尯鍩�" width="120" />
+                <el-table-column prop="period" label="缁熻鍛ㄦ湡" width="120" />
+                <el-table-column prop="salesVolume" label="閿�閲�(绔嬫柟绫�)" />
+                <el-table-column prop="salesAmount" label="閿�鍞噾棰�(涓囧厓)" />
+                <el-table-column prop="newCustomers" label="鏂板瀹㈡埛(涓�)" width="150" />
+                <el-table-column prop="totalCustomers" label="鍚堣瀹㈡埛(涓�)" width="150" />
+              </el-table>
+            </div>
+          </div>
+          
+          <!-- 鍙宠竟锛氫骇鍝佺被鍨嬪垎甯冨拰閿�鍞尯鍩熷垎甯� -->
+          <div class="chart-column" style="flex: 1; display: flex; flex-direction: column; gap: 20px;">
+            <div class="panel-card card-7" style="flex: 1;">
+              <div class="panel-title">浜у搧绫诲瀷鍒嗗竷</div>
+              <div class="chart-container">
+                <div ref="productTypeChart" style="width: 100%; height: 100%;"></div>
+              </div>
+            </div>
+            <div class="panel-card card-8" style="flex: 1;">
+              <div class="panel-title">閿�鍞尯鍩熷垎甯�</div>
+              <div class="chart-container">
+                <div ref="salesAreaChart" style="width: 100%; height: 100%;"></div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';
+import { useRouter } from 'vue-router';
+import * as echarts from 'echarts';
+import dayjs from 'dayjs';
+
+const router = useRouter();
+
+// 绛涢�夋潯浠�
+const dateRange = ref([]);
+const productType = ref('');
+const salesArea = ref('');
+const statDimension = ref('month');
+
+// 鍥捐〃寮曠敤
+const salesVolumeChart = ref(null);
+const salesAmountChart = ref(null);
+const productTypeChart = ref(null);
+const salesAreaChart = ref(null);
+const cumulativeSalesVolumeChart = ref(null);
+const cumulativeSalesAmountChart = ref(null);
+
+// 鍥捐〃瀹炰緥
+let salesVolumeChartInstance = null;
+let salesAmountChartInstance = null;
+let productTypeChartInstance = null;
+let salesAreaChartInstance = null;
+let cumulativeSalesVolumeChartInstance = null;
+let cumulativeSalesAmountChartInstance = null;
+
+// 妯℃嫙鏁版嵁
+const mockData = [
+  // 2026骞�1鏈堟暟鎹�
+  { productType: '鐮屽潡', salesArea: '鍗庝笢', period: '2026-01', salesVolume: 1200, salesAmount: 180, newCustomers: 5, totalCustomers: 120 },
+  { productType: '鐮屽潡', salesArea: '鍗庡寳', period: '2026-01', salesVolume: 800, salesAmount: 120, newCustomers: 3, totalCustomers: 80 },
+  { productType: '鐮屽潡', salesArea: '鍗庡崡', period: '2026-01', salesVolume: 600, salesAmount: 90, newCustomers: 2, totalCustomers: 60 },
+  { productType: '鏉挎潗', salesArea: '鍗庝笢', period: '2026-01', salesVolume: 900, salesAmount: 270, newCustomers: 4, totalCustomers: 100 },
+  { productType: '鏉挎潗', salesArea: '鍗庡寳', period: '2026-01', salesVolume: 500, salesAmount: 150, newCustomers: 2, totalCustomers: 70 },
+  { productType: '鍨嬫潗', salesArea: '鍗庝笢', period: '2026-01', salesVolume: 400, salesAmount: 200, newCustomers: 3, totalCustomers: 50 },
+  // 2026骞�2鏈堟暟鎹�
+  { productType: '鐮屽潡', salesArea: '鍗庝笢', period: '2026-02', salesVolume: 1300, salesAmount: 195, newCustomers: 4, totalCustomers: 124 },
+  { productType: '鐮屽潡', salesArea: '鍗庡寳', period: '2026-02', salesVolume: 850, salesAmount: 127.5, newCustomers: 2, totalCustomers: 82 },
+  { productType: '鐮屽潡', salesArea: '鍗庡崡', period: '2026-02', salesVolume: 650, salesAmount: 97.5, newCustomers: 1, totalCustomers: 61 },
+  { productType: '鏉挎潗', salesArea: '鍗庝笢', period: '2026-02', salesVolume: 950, salesAmount: 285, newCustomers: 3, totalCustomers: 103 },
+  { productType: '鏉挎潗', salesArea: '鍗庡寳', period: '2026-02', salesVolume: 550, salesAmount: 165, newCustomers: 1, totalCustomers: 71 },
+  { productType: '鍨嬫潗', salesArea: '鍗庝笢', period: '2026-02', salesVolume: 450, salesAmount: 225, newCustomers: 2, totalCustomers: 52 },
+  // 2026骞�3鏈堟暟鎹�
+  { productType: '鐮屽潡', salesArea: '鍗庝笢', period: '2026-03', salesVolume: 1400, salesAmount: 210, newCustomers: 6, totalCustomers: 130 },
+  { productType: '鐮屽潡', salesArea: '鍗庡寳', period: '2026-03', salesVolume: 900, salesAmount: 135, newCustomers: 3, totalCustomers: 85 },
+  { productType: '鐮屽潡', salesArea: '鍗庡崡', period: '2026-03', salesVolume: 700, salesAmount: 105, newCustomers: 2, totalCustomers: 63 },
+  { productType: '鏉挎潗', salesArea: '鍗庝笢', period: '2026-03', salesVolume: 1000, salesAmount: 300, newCustomers: 5, totalCustomers: 108 },
+  { productType: '鏉挎潗', salesArea: '鍗庡寳', period: '2026-03', salesVolume: 600, salesAmount: 180, newCustomers: 2, totalCustomers: 73 },
+  { productType: '鍨嬫潗', salesArea: '鍗庝笢', period: '2026-03', salesVolume: 500, salesAmount: 250, newCustomers: 3, totalCustomers: 55 },
+  // 瑗垮崡鍜岃タ鍖楀湴鍖烘暟鎹�
+  { productType: '鐮屽潡', salesArea: '瑗垮崡', period: '2026-03', salesVolume: 500, salesAmount: 75, newCustomers: 2, totalCustomers: 40 },
+  { productType: '鏉挎潗', salesArea: '瑗垮崡', period: '2026-03', salesVolume: 300, salesAmount: 90, newCustomers: 1, totalCustomers: 30 },
+  { productType: '鐮屽潡', salesArea: '瑗垮寳', period: '2026-03', salesVolume: 400, salesAmount: 60, newCustomers: 1, totalCustomers: 35 },
+  { productType: '鏉挎潗', salesArea: '瑗垮寳', period: '2026-03', salesVolume: 200, salesAmount: 60, newCustomers: 1, totalCustomers: 25 },
+];
+
+
+// 璁$畻灞炴��
+const filteredData = computed(() => {
+  let result = [...mockData];
+  
+  // 鎸変骇鍝佺被鍨嬬瓫閫�
+  if (productType.value) {
+    result = result.filter(item => {
+      const typeMap = { block: '鐮屽潡', board: '鏉挎潗', profile: '鍨嬫潗' };
+      return item.productType === typeMap[productType.value];
+    });
+  }
+  
+  // 鎸夐攢鍞尯鍩熺瓫閫�
+  if (salesArea.value) {
+    result = result.filter(item => {
+      const areaMap = { east: '鍗庝笢', north: '鍗庡寳', south: '鍗庡崡', southwest: '瑗垮崡', northwest: '瑗垮寳' };
+      return item.salesArea === areaMap[salesArea.value];
+    });
+  }
+  
+  // 鎸夋椂闂磋寖鍥寸瓫閫�
+  if (dateRange.value && dateRange.value.length === 2) {
+    const startDate = dayjs(dateRange.value[0]);
+    const endDate = dayjs(dateRange.value[1]);
+    
+    result = result.filter(item => {
+      const itemDate = dayjs(item.period);
+      return itemDate.isAfter(startDate.subtract(1, 'day')) && itemDate.isBefore(endDate.add(1, 'day'));
+    });
+  }
+  
+  return result;
+});
+
+// 鏍稿績鎸囨爣璁$畻
+const totalSalesVolume = computed(() => {
+  return filteredData.value.reduce((sum, item) => sum + item.salesVolume, 0);
+});
+
+const totalSalesAmount = computed(() => {
+  return filteredData.value.reduce((sum, item) => sum + item.salesAmount, 0).toFixed(2);
+});
+
+const newCustomerCount = computed(() => {
+  return filteredData.value.reduce((sum, item) => sum + item.newCustomers, 0);
+});
+
+const totalCustomerCount = computed(() => {
+  // 璁$畻姣忎釜鍖哄煙鍜屼骇鍝佺被鍨嬬殑鏈�澶у鎴锋暟
+  const customerMap = {};
+  filteredData.value.forEach(item => {
+    const key = `${item.productType}-${item.salesArea}`;
+    if (!customerMap[key] || item.totalCustomers > customerMap[key]) {
+      customerMap[key] = item.totalCustomers;
+    }
+  });
+  return Object.values(customerMap).reduce((sum, count) => sum + count, 0);
+});
+
+// 鍙樺寲鐜囪绠楋紙妯℃嫙锛�
+const salesVolumeChange = ref('+5.2');
+const salesAmountChange = ref('+7.8');
+const customerCountChange = ref('+3.5');
+const totalCustomerChange = ref('+2.1');
+
+// 琛ㄦ牸鏁版嵁
+const tableData = computed(() => {
+  return filteredData.value.map(item => {
+    // 璁$畻绱鍊硷紙妯℃嫙锛�
+    const cumulativeSalesVolume = item.salesVolume * 1.5;
+    const cumulativeSalesAmount = item.salesAmount * 1.5;
+    const cumulativeNewCustomers = item.newCustomers * 2;
+    
+    return {
+      ...item,
+      cumulativeSalesVolume,
+      cumulativeSalesAmount,
+      cumulativeNewCustomers
+    };
+  });
+});
+
+// 閿�閲忚秼鍔垮浘琛ㄩ厤缃�
+const salesVolumeChartOption = computed(() => {
+  // 鎸夊懆鏈熷垎缁�
+  const periodMap = {};
+  filteredData.value.forEach(item => {
+    if (!periodMap[item.period]) {
+      periodMap[item.period] = 0;
+    }
+    periodMap[item.period] += item.salesVolume;
+  });
+  
+  const periods = Object.keys(periodMap).sort();
+  const values = periods.map(period => periodMap[period]);
+  
+  return {
+    tooltip: {
+      trigger: 'axis',
+      formatter: '{b}: {c} 绔嬫柟绫�'
+    },
+    xAxis: {
+      type: 'category',
+      data: periods
+    },
+    yAxis: {
+      type: 'value',
+      name: '閿�閲忥紙绔嬫柟绫筹級'
+    },
+    series: [{
+      data: values,
+      type: 'line',
+      smooth: true,
+      lineStyle: {
+        width: 3
+      },
+      itemStyle: {
+        color: '#409EFF'
+      }
+    }]
+  };
+});
+
+// 閿�鍞噾棰濊秼鍔垮浘琛ㄩ厤缃�
+const salesAmountChartOption = computed(() => {
+  // 鎸夊懆鏈熷垎缁�
+  const periodMap = {};
+  filteredData.value.forEach(item => {
+    if (!periodMap[item.period]) {
+      periodMap[item.period] = 0;
+    }
+    periodMap[item.period] += item.salesAmount;
+  });
+  
+  const periods = Object.keys(periodMap).sort();
+  const values = periods.map(period => periodMap[period]);
+  
+  return {
+    tooltip: {
+      trigger: 'axis',
+      formatter: '{b}: {c} 涓囧厓'
+    },
+    xAxis: {
+      type: 'category',
+      data: periods
+    },
+    yAxis: {
+      type: 'value',
+      name: '閿�鍞噾棰濓紙涓囧厓锛�'
+    },
+    series: [{
+      data: values,
+      type: 'bar',
+      itemStyle: {
+        color: '#67C23A'
+      }
+    }]
+  };
+});
+
+// 浜у搧绫诲瀷鍒嗗竷鍥捐〃閰嶇疆
+const productTypeChartOption = computed(() => {
+  // 鎸変骇鍝佺被鍨嬪垎缁�
+  const typeMap = {};
+  filteredData.value.forEach(item => {
+    if (!typeMap[item.productType]) {
+      typeMap[item.productType] = 0;
+    }
+    typeMap[item.productType] += item.salesVolume;
+  });
+  
+  const types = Object.keys(typeMap);
+  const values = types.map(type => typeMap[type]);
+  
+  return {
+    tooltip: {
+      trigger: 'item',
+      formatter: '{b}: {c} 绔嬫柟绫� ({d}%)'
+    },
+    series: [{
+      type: 'pie',
+      radius: '60%',
+      data: types.map((type, index) => ({
+        name: type,
+        value: values[index]
+      })),
+      emphasis: {
+        itemStyle: {
+          shadowBlur: 10,
+          shadowOffsetX: 0,
+          shadowColor: 'rgba(0, 0, 0, 0.5)'
+        }
+      }
+    }]
+  };
+});
+
+// 閿�鍞尯鍩熷垎甯冨浘琛ㄩ厤缃�
+const salesAreaChartOption = computed(() => {
+  // 鎸夐攢鍞尯鍩熷垎缁�
+  const areaMap = {};
+  filteredData.value.forEach(item => {
+    if (!areaMap[item.salesArea]) {
+      areaMap[item.salesArea] = 0;
+    }
+    areaMap[item.salesArea] += item.salesVolume;
+  });
+  
+  const areas = Object.keys(areaMap);
+  const values = areas.map(area => areaMap[area]);
+  
+  return {
+    tooltip: {
+      trigger: 'item',
+      formatter: '{b}: {c} 绔嬫柟绫� ({d}%)'
+    },
+    series: [{
+      type: 'pie',
+      radius: '60%',
+      data: areas.map((area, index) => ({
+        name: area,
+        value: values[index]
+      })),
+      emphasis: {
+        itemStyle: {
+          shadowBlur: 10,
+          shadowOffsetX: 0,
+          shadowColor: 'rgba(0, 0, 0, 0.5)'
+        }
+      }
+    }]
+  };
+});
+
+// 绱閿�閲忚秼鍔垮浘琛ㄩ厤缃�
+const cumulativeSalesVolumeChartOption = computed(() => {
+  // 鎸夊懆鏈熷垎缁�
+  const periodMap = {};
+  let cumulativeValue = 0;
+  
+  // 鎸夊懆鏈熸帓搴�
+  const sortedData = [...filteredData.value].sort((a, b) => a.period.localeCompare(b.period));
+  
+  sortedData.forEach(item => {
+    cumulativeValue += item.salesVolume;
+    periodMap[item.period] = cumulativeValue;
+  });
+  
+  const periods = Object.keys(periodMap).sort();
+  const values = periods.map(period => periodMap[period]);
+  
+  return {
+    tooltip: {
+      trigger: 'axis',
+      formatter: '{b}: {c} 绔嬫柟绫�'
+    },
+    xAxis: {
+      type: 'category',
+      data: periods
+    },
+    yAxis: {
+      type: 'value',
+      name: '绱閿�閲忥紙绔嬫柟绫筹級'
+    },
+    series: [{
+      data: values,
+      type: 'line',
+      smooth: true,
+      areaStyle: {
+        opacity: 0.3
+      },
+      itemStyle: {
+        color: '#E6A23C'
+      },
+      lineStyle: {
+        width: 3
+      }
+    }]
+  };
+});
+
+// 绱閿�鍞噾棰濊秼鍔垮浘琛ㄩ厤缃�
+const cumulativeSalesAmountChartOption = computed(() => {
+  // 鎸夊懆鏈熷垎缁�
+  const periodMap = {};
+  let cumulativeValue = 0;
+  
+  // 鎸夊懆鏈熸帓搴�
+  const sortedData = [...filteredData.value].sort((a, b) => a.period.localeCompare(b.period));
+  
+  sortedData.forEach(item => {
+    cumulativeValue += item.salesAmount;
+    periodMap[item.period] = cumulativeValue;
+  });
+  
+  const periods = Object.keys(periodMap).sort();
+  const values = periods.map(period => periodMap[period]);
+  
+  return {
+    tooltip: {
+      trigger: 'axis',
+      formatter: '{b}: {c} 涓囧厓'
+    },
+    xAxis: {
+      type: 'category',
+      data: periods
+    },
+    yAxis: {
+      type: 'value',
+      name: '绱閿�鍞噾棰濓紙涓囧厓锛�'
+    },
+    series: [{
+      data: values,
+      type: 'bar',
+      itemStyle: {
+        color: '#F56C6C'
+      }
+    }]
+  };
+});
+
+// 鏂规硶
+const goBack = () => {
+  router.back();
+};
+
+const handleDateChange = () => {
+  // 澶勭悊鏃ユ湡鍙樺寲
+  updateCharts();
+};
+
+const handleFilterChange = () => {
+  // 澶勭悊绛涢�夋潯浠跺彉鍖�
+  updateCharts();
+};
+
+// 鍒濆鍖栧浘琛�
+const initCharts = () => {
+  // 鍒濆鍖栭攢閲忚秼鍔垮浘琛�
+  if (salesVolumeChart.value && !salesVolumeChartInstance) {
+    salesVolumeChartInstance = echarts.init(salesVolumeChart.value);
+  }
+  
+  // 鍒濆鍖栭攢鍞噾棰濊秼鍔垮浘琛�
+  if (salesAmountChart.value && !salesAmountChartInstance) {
+    salesAmountChartInstance = echarts.init(salesAmountChart.value);
+  }
+  
+  // 鍒濆鍖栦骇鍝佺被鍨嬪垎甯冨浘琛�
+  if (productTypeChart.value && !productTypeChartInstance) {
+    productTypeChartInstance = echarts.init(productTypeChart.value);
+  }
+  
+  // 鍒濆鍖栭攢鍞尯鍩熷垎甯冨浘琛�
+  if (salesAreaChart.value && !salesAreaChartInstance) {
+    salesAreaChartInstance = echarts.init(salesAreaChart.value);
+  }
+  
+  // 鍒濆鍖栫疮璁¢攢閲忚秼鍔垮浘琛�
+  if (cumulativeSalesVolumeChart.value && !cumulativeSalesVolumeChartInstance) {
+    cumulativeSalesVolumeChartInstance = echarts.init(cumulativeSalesVolumeChart.value);
+  }
+  
+  // 鍒濆鍖栫疮璁¢攢鍞噾棰濊秼鍔垮浘琛�
+  if (cumulativeSalesAmountChart.value && !cumulativeSalesAmountChartInstance) {
+    cumulativeSalesAmountChartInstance = echarts.init(cumulativeSalesAmountChart.value);
+  }
+  
+  updateCharts();
+};
+
+// 鏇存柊鍥捐〃
+const updateCharts = () => {
+  // 鏇存柊閿�閲忚秼鍔垮浘琛�
+  if (salesVolumeChartInstance) {
+    salesVolumeChartInstance.setOption(salesVolumeChartOption.value);
+  }
+  
+  // 鏇存柊閿�鍞噾棰濊秼鍔垮浘琛�
+  if (salesAmountChartInstance) {
+    salesAmountChartInstance.setOption(salesAmountChartOption.value);
+  }
+  
+  // 鏇存柊浜у搧绫诲瀷鍒嗗竷鍥捐〃
+  if (productTypeChartInstance) {
+    productTypeChartInstance.setOption(productTypeChartOption.value);
+  }
+  
+  // 鏇存柊閿�鍞尯鍩熷垎甯冨浘琛�
+  if (salesAreaChartInstance) {
+    salesAreaChartInstance.setOption(salesAreaChartOption.value);
+  }
+  
+  // 鏇存柊绱閿�閲忚秼鍔垮浘琛�
+  if (cumulativeSalesVolumeChartInstance) {
+    cumulativeSalesVolumeChartInstance.setOption(cumulativeSalesVolumeChartOption.value);
+  }
+  
+  // 鏇存柊绱閿�鍞噾棰濊秼鍔垮浘琛�
+  if (cumulativeSalesAmountChartInstance) {
+    cumulativeSalesAmountChartInstance.setOption(cumulativeSalesAmountChartOption.value);
+  }
+};
+
+// 鐩戝惉绐楀彛澶у皬鍙樺寲
+const handleResize = () => {
+  if (salesVolumeChartInstance) {
+    salesVolumeChartInstance.resize();
+  }
+  if (salesAmountChartInstance) {
+    salesAmountChartInstance.resize();
+  }
+  if (productTypeChartInstance) {
+    productTypeChartInstance.resize();
+  }
+  if (salesAreaChartInstance) {
+    salesAreaChartInstance.resize();
+  }
+  if (cumulativeSalesVolumeChartInstance) {
+    cumulativeSalesVolumeChartInstance.resize();
+  }
+  if (cumulativeSalesAmountChartInstance) {
+    cumulativeSalesAmountChartInstance.resize();
+  }
+};
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  // 璁剧疆榛樿鏃ユ湡鑼冨洿涓烘渶杩�3涓湀
+  const endDate = dayjs();
+  const startDate = endDate.subtract(3, 'month');
+  dateRange.value = [startDate.format('YYYY-MM-DD'), endDate.format('YYYY-MM-DD')];
+  
+  // 绛夊緟DOM鏇存柊鍚庡垵濮嬪寲鍥捐〃
+  nextTick(() => {
+    initCharts();
+  });
+  
+  // 娣诲姞绐楀彛澶у皬鍙樺寲鐩戝惉
+  window.addEventListener('resize', handleResize);
+});
+
+// 缁勪欢鍗歌浇鏃堕攢姣佸浘琛ㄥ疄渚�
+onBeforeUnmount(() => {
+  if (salesVolumeChartInstance) {
+    salesVolumeChartInstance.dispose();
+  }
+  if (salesAmountChartInstance) {
+    salesAmountChartInstance.dispose();
+  }
+  if (productTypeChartInstance) {
+    productTypeChartInstance.dispose();
+  }
+  if (salesAreaChartInstance) {
+    salesAreaChartInstance.dispose();
+  }
+  if (cumulativeSalesVolumeChartInstance) {
+    cumulativeSalesVolumeChartInstance.dispose();
+  }
+  if (cumulativeSalesAmountChartInstance) {
+    cumulativeSalesAmountChartInstance.dispose();
+  }
+  
+  // 绉婚櫎绐楀彛澶у皬鍙樺寲鐩戝惉
+  window.removeEventListener('resize', handleResize);
+});
+</script>
+
+<style scoped>
+/* 澶栭儴瀹瑰櫒 - 鍗犳嵁鏁翠釜瑙嗗彛 */
+.sales-statistics-container {
+  position: relative;
+  width: 100%;
+  /* 椤甸潰鍦ㄥ父瑙勫竷灞�涓嬶紙鏈夐《鏍忥級榛樿鍑忓幓 84px锛岄伩鍏嶅唴瀹硅瑁佸垏 */
+  min-height: calc(100vh - 84px);
+  background-color: #f5f7fa;
+  overflow: hidden;
+}
+
+/* 鍐呴儴鍐呭鍖哄煙 - 鑷�傚簲瀹藉害 */
+.data-dashboard {
+  position: relative;
+  width: 100%;
+  min-height: 100%;
+  background-color: #ffffff;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
+}
+
+.filter-area {
+  padding: 20px;
+  background-color: #ffffff;
+  border-bottom: 1px solid #e4e7ed;
+  display: flex;
+  gap: 40px;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.filter-section {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.filter-label {
+  font-size: 14px;
+  font-weight: 500;
+  color: #303133;
+  white-space: nowrap;
+}
+
+.dashboard-content {
+  position: relative;
+  z-index: 1;
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+  padding: 20px;
+  min-height: 800px;
+  overflow: hidden;
+}
+
+/* 琛屽竷灞� */
+.row {
+  display: flex;
+  gap: 20px;
+  align-items: stretch;
+}
+
+/* 绗竴琛岋細4涓寚鏍囧崱鐗� */
+.row-1 {
+  height: 180px;
+}
+
+/* 绗簩琛岋細2涓秼鍔垮浘琛� */
+.row-2 {
+  height: 350px;
+}
+
+/* 绗笁琛岋細绱鏁版嵁瓒嬪娍 */
+.row-3 {
+  height: 350px;
+}
+
+/* 绗洓琛岋細琛ㄦ牸鍜屽浘琛� */
+.row-4 {
+  height: 600px;
+}
+
+/* 鍗$墖鏍峰紡 */
+.panel-card {
+  background-color: #ffffff;
+  border-radius: 8px;
+  border: 1px solid #e4e7ed;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  transition: all 0.3s ease;
+}
+
+.panel-card:hover {
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
+  transform: translateY(-2px);
+}
+
+/* 鍗$墖甯冨眬 */
+.card-1 {
+  flex: 1;
+}
+
+.card-2 {
+  flex: 1;
+}
+
+.card-3 {
+  flex: 1;
+}
+
+.card-4 {
+  flex: 1;
+}
+
+.card-5 {
+  flex: 1;
+}
+
+.card-6 {
+  flex: 1;
+}
+
+.card-7 {
+  flex: 1;
+}
+
+.card-8 {
+  flex: 1;
+}
+
+.card-9 {
+  flex: 1;
+}
+
+.card-10 {
+  flex: 1;
+}
+
+.card-11 {
+  flex: 1;
+}
+
+.panel-title {
+  padding: 15px 20px;
+  font-size: 16px;
+  font-weight: 500;
+  color: #303133;
+  border-bottom: 1px solid #e4e7ed;
+  background-color: #fafafa;
+}
+
+.chart-container {
+  flex: 1;
+  padding: 20px;
+}
+
+.table-container {
+  flex: 1;
+  padding: 20px;
+  overflow: auto;
+}
+
+.stats-grid {
+  flex: 1;
+  padding: 15px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.stat-item {
+  background-color: #fafafa;
+  border-radius: 8px;
+  padding: 15px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  border: 1px solid #e4e7ed;
+  min-height: 80px;
+  width: 100%;
+}
+
+.stat-value {
+  font-size: 24px;
+  font-weight: 600;
+  color: #303133;
+  margin-bottom: 5px;
+}
+
+.stat-unit {
+  font-size: 12px;
+  color: #909399;
+  margin-bottom: 3px;
+}
+
+.stat-change {
+  font-size: 12px;
+  color: #67c23a;
+}
+
+/* 琛ㄦ牸鏍峰紡 */
+:deep(.el-table) {
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+:deep(.el-table th) {
+  background-color: #fafafa;
+  font-weight: 500;
+}
+
+:deep(.el-table tr:hover > td) {
+  background-color: #ecf5ff;
+}
+
+/* 涓嬫媺閫夋嫨妗嗘牱寮� */
+:deep(.el-select) {
+  width: 100%;
+}
+
+:deep(.el-date-picker) {
+  width: 100%;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3