From e0699ce1a404b1d819d7ef0b40cfd2631bb964d1 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期四, 12 三月 2026 17:56:06 +0800
Subject: [PATCH] 问题修改

---
 src/views/costAccounting/energyCosts/index.vue | 1135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,135 insertions(+), 0 deletions(-)

diff --git a/src/views/costAccounting/energyCosts/index.vue b/src/views/costAccounting/energyCosts/index.vue
new file mode 100644
index 0000000..e5d470a
--- /dev/null
+++ b/src/views/costAccounting/energyCosts/index.vue
@@ -0,0 +1,1135 @@
+<template>
+  <div class="app-container">
+    <!-- 鎼滅储鍖哄煙 -->
+    <div class="search_form">
+      <el-form :model="searchForm"
+               :inline="true">
+        <el-form-item label="缁熻缁村害:">
+          <el-radio-group v-model="statisticsType"
+                          @change="handleTypeChange">
+            <el-radio-button label="day">鎸夋棩缁熻</el-radio-button>
+            <el-radio-button label="month">鎸夋湀缁熻</el-radio-button>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="鑳借�楃被鍨�:">
+          <el-select v-model="searchForm.energyType"
+                     placeholder="鍏ㄩ儴"
+                     clearable
+                     style="width: 140px;"
+                     @change="handleQuery">
+            <el-option label="鍏ㄩ儴"
+                       value="鍏ㄩ儴" />
+            <el-option label="姘�"
+                       value="姘�" />
+            <el-option label="鐢�"
+                       value="鐢�" />
+            <el-option label="姘�"
+                       value="姘�" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鑳借�楃敤閫�:">
+          <el-select v-model="searchForm.energyPurpose"
+                     placeholder="鍏ㄩ儴"
+                     clearable
+                     style="width: 140px;"
+                     @change="handleQuery">
+            <el-option label="鍏ㄩ儴"
+                       value="鍏ㄩ儴" />
+            <el-option label="鐢熶骇"
+                       value="鐢熶骇" />
+            <el-option label="鍔炲叕"
+                       value="鍔炲叕" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鏃堕棿鑼冨洿:">
+          <el-date-picker v-if="statisticsType === 'day'"
+                          v-model="searchForm.dateRange"
+                          type="daterange"
+                          range-separator="鑷�"
+                          start-placeholder="寮�濮嬫棩鏈�"
+                          end-placeholder="缁撴潫鏃ユ湡"
+                          value-format="YYYY-MM-DD"
+                          style="width: 240px;"
+                          @change="handleQuery" />
+          <el-date-picker v-else
+                          v-model="searchForm.monthRange"
+                          type="monthrange"
+                          range-separator="鑷�"
+                          start-placeholder="寮�濮嬫湀浠�"
+                          end-placeholder="缁撴潫鏈堜唤"
+                          value-format="YYYY-MM"
+                          style="width: 240px;"
+                          @change="handleQuery" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary"
+                     @click="handleQuery">鏌ヨ</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button type="success"
+                   @click="handleExport">瀵煎嚭鎶ヨ〃</el-button>
+      </div>
+    </div>
+    <!-- 缁熻姒傝鍗$墖 -->
+    <div class="statistics-overview">
+      <h2 class="section-header">
+        <el-icon class="header-icon">
+          <DataLine />
+        </el-icon>
+        鑳借�楁垚鏈瑙�
+      </h2>
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <div class="overview-card blue-card">
+            <div class="overview-icon blue-icon">
+              <el-icon>
+                <Money />
+              </el-icon>
+            </div>
+            <div class="overview-info">
+              <div class="overview-label">鎬昏兘鑰楁垚鏈�</div>
+              <div class="overview-value">楼{{ overview.totalCost }}</div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <div class="overview-card green-card">
+            <div class="overview-icon green-icon">
+              <el-icon>
+                <DataLine />
+              </el-icon>
+            </div>
+            <div class="overview-info">
+              <div class="overview-label">鐢熶骇鑳借�楁垚鏈�</div>
+              <div class="overview-value">楼{{ overview.productionCost }}</div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <div class="overview-card purple-card">
+            <div class="overview-icon purple-icon">
+              <el-icon>
+                <TrendCharts />
+              </el-icon>
+            </div>
+            <div class="overview-info">
+              <div class="overview-label">鍔炲叕鑳借�楁垚鏈�</div>
+              <div class="overview-value">楼{{ overview.officeCost }}</div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <div class="overview-card gray-card">
+            <div class="overview-icon gray-icon">
+              <el-icon>
+                <Histogram />
+              </el-icon>
+            </div>
+            <div class="overview-info">
+              <div class="overview-label">骞冲潎鑳借�楁垚鏈�</div>
+              <div class="overview-value">楼{{ overview.avgCost }} <span class="unit">/{{ statisticsType === 'day' ? '鏃�' : '鏈�' }}</span></div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+    <!-- 鍥捐〃鍖哄煙 -->
+    <div class="charts-container">
+      <h2 class="section-header">
+        <el-icon class="header-icon">
+          <Histogram />
+        </el-icon>
+        鑳借�楁垚鏈垎鏋�
+      </h2>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <div class="chart-card">
+            <div class="chart-title">鑳借�楁垚鏈秼鍔�</div>
+            <div ref="costChart"
+                 class="chart-content"></div>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="chart-card">
+            <div class="chart-title">鑳借�楃被鍨嬫垚鏈崰姣�</div>
+            <div ref="typeChart"
+                 class="chart-content"></div>
+          </div>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20"
+              style="margin-top: 20px;">
+        <el-col :span="12">
+          <div class="chart-card">
+            <div class="chart-title">鑳借�楃敤閫旀垚鏈崰姣�</div>
+            <div ref="purposeChart"
+                 class="chart-content"></div>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="chart-card">
+            <div class="chart-title">鑳借�楀崟浠峰姣�</div>
+            <div ref="priceChart"
+                 class="chart-content"></div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <div class="table-section">
+      <h2 class="section-header">
+        <el-icon class="header-icon">
+          <List />
+        </el-icon>
+        璇︾粏鏁版嵁
+      </h2>
+      <el-table :data="tableData"
+                v-loading="tableLoading"
+                border>
+        <el-table-column type="index"
+                         label="搴忓彿"
+                         width="60"
+                         align="center" />
+        <el-table-column prop="timePeriod"
+                         :label="timeColumnLabel"
+                         align="center" />
+        <el-table-column prop="energyType"
+                         label="鑳借�楃被鍨�"
+                         width="100"
+                         align="center">
+          <template #default="scope">
+            <el-tag :type="getEnergyTypeType(scope.row.energyType)">
+              {{ scope.row.energyType }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="energyPurpose"
+                         label="鑳借�楃敤閫�"
+                         width="100"
+                         align="center">
+          <template #default="scope">
+            <el-tag :type="scope.row.energyPurpose === '鐢熶骇' ? 'primary' : 'info'">
+              {{ scope.row.energyPurpose }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="consumption"
+                         label="鐢ㄩ噺"
+                         align="right">
+          <template #default="scope">
+            <span class="consumption-value">{{ scope.row.consumption }}</span>
+            <span class="consumption-unit">{{ scope.row.unit }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="price"
+                         label="鍗曚环(鍏�)"
+                         align="right">
+          <template #default="scope">
+            <span class="price-value">{{ scope.row.price }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="cost"
+                         label="鎴愭湰(鍏�)"
+                         align="right"
+                         fixed="right">
+          <template #default="scope">
+            <span class="cost-value">楼{{ scope.row.cost }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- 鍒嗛〉 -->
+    <div class="pagination-container">
+      <el-pagination v-model:current-page="page.current"
+                     v-model:page-size="page.size"
+                     :page-sizes="[10, 20, 50, 100]"
+                     :total="page.total"
+                     layout="total, sizes, prev, pager, next, jumper"
+                     @size-change="handleSizeChange"
+                     @current-change="handleCurrentChange" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+  import { ref, reactive, onMounted, computed, nextTick } from "vue";
+  import { ElMessage } from "element-plus";
+  import {
+    Money,
+    DataLine,
+    TrendCharts,
+    Histogram,
+    List,
+  } from "@element-plus/icons-vue";
+  import * as echarts from "echarts";
+  import { energyCostStatistics } from "@/api/costAccounting/energyCosts";
+
+  // 缁熻缁村害锛歞ay-鎸夋棩锛宮onth-鎸夋湀
+  const statisticsType = ref("day");
+
+  // 鎼滅储琛ㄥ崟
+  const searchForm = reactive({
+    energyType: "",
+    energyPurpose: "",
+    dateRange: (() => {
+      // 榛樿鏈�杩�7澶�
+      const end = new Date();
+      const start = new Date();
+      start.setDate(start.getDate() - 6);
+      return [start.toISOString().split("T")[0], end.toISOString().split("T")[0]];
+    })(),
+    monthRange: (() => {
+      // 榛樿鏈�杩�3涓湀
+      const end = new Date();
+      const start = new Date();
+      start.setMonth(start.getMonth() - 2);
+      return [start.toISOString().slice(0, 7), end.toISOString().slice(0, 7)];
+    })(),
+  });
+
+  // 鏃堕棿鍒楁爣绛�
+  const timeColumnLabel = computed(() => {
+    return statisticsType.value === "day" ? "鏃ユ湡" : "鏈堜唤";
+  });
+
+  // 缁熻姒傝
+  const overview = reactive({
+    totalCost: "0.00",
+    productionCost: "0.00",
+    officeCost: "0.00",
+    avgCost: "0.00",
+  });
+
+  // 琛ㄦ牸鏁版嵁
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+
+  // 鍒嗛〉
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+
+  // 鍥捐〃寮曠敤
+  const costChart = ref(null);
+  const typeChart = ref(null);
+  const purposeChart = ref(null);
+  const priceChart = ref(null);
+
+  // 鍥捐〃瀹炰緥
+  let costChartInstance = null;
+  let typeChartInstance = null;
+  let purposeChartInstance = null;
+  let priceChartInstance = null;
+
+  // 鑾峰彇鑳借�楃被鍨嬫爣绛剧被鍨�
+  const getEnergyTypeType = type => {
+    const typeMap = {
+      姘�: "primary",
+      鐢�: "warning",
+      姘�: "success",
+    };
+    return typeMap[type] || "info";
+  };
+
+  // 鍒濆鍖栧浘琛�
+  const initCharts = () => {
+    nextTick(() => {
+      // 鑳借�楁垚鏈秼鍔垮浘
+      if (costChart.value) {
+        costChartInstance = echarts.init(costChart.value);
+        updateCostChart();
+      }
+      // 鑳借�楃被鍨嬫垚鏈崰姣斿浘
+      if (typeChart.value) {
+        typeChartInstance = echarts.init(typeChart.value);
+        updateTypeChart();
+      }
+      // 鑳借�楃敤閫旀垚鏈崰姣斿浘
+      if (purposeChart.value) {
+        purposeChartInstance = echarts.init(purposeChart.value);
+        updatePurposeChart();
+      }
+      // 鑳借�楀崟浠峰姣斿浘
+      if (priceChart.value) {
+        priceChartInstance = echarts.init(priceChart.value);
+        updatePriceChart();
+      }
+    });
+  };
+
+  // 鏇存柊鑳借�楁垚鏈秼鍔垮浘
+  const updateCostChart = () => {
+    const data = tableData.value;
+    const option = {
+      tooltip: {
+        trigger: "axis",
+        axisPointer: { type: "shadow" },
+        backgroundColor: "rgba(255, 255, 255, 0.95)",
+        borderColor: "#409EFF",
+        borderWidth: 1,
+        textStyle: { color: "#303133" },
+      },
+      legend: {
+        data: ["鐢熶骇鑳借�楁垚鏈�", "鍔炲叕鑳借�楁垚鏈�"],
+        top: 0,
+        right: 10,
+        textStyle: { color: "#606266" },
+      },
+      grid: {
+        left: "3%",
+        right: "4%",
+        bottom: "10%",
+        top: "15%",
+        containLabel: true,
+      },
+      xAxis: {
+        type: "category",
+        data: data.map(item => item.timePeriod),
+        axisLabel: {
+          rotate: statisticsType.value === "day" ? 45 : 0,
+          color: "#606266",
+        },
+        axisLine: { lineStyle: { color: "#ebeef5" } },
+        splitLine: { show: false },
+      },
+      yAxis: {
+        type: "value",
+        name: "鎴愭湰(鍏�)",
+        nameTextStyle: { color: "#606266" },
+        axisLabel: { color: "#606266" },
+        axisLine: { show: false },
+        splitLine: { lineStyle: { color: "#f0f2f5" } },
+      },
+      series: [
+        {
+          name: "鐢熶骇鑳借�楁垚鏈�",
+          type: "bar",
+          data: data.map(item => (item.energyPurpose === "鐢熶骇" ? item.cost : 0)),
+          itemStyle: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              { offset: 0, color: "#409EFF" },
+              { offset: 1, color: "#66b1ff" },
+            ]),
+            borderRadius: [4, 4, 0, 0],
+          },
+          animationDelay: function (idx) {
+            return idx * 100;
+          },
+        },
+        {
+          name: "鍔炲叕鑳借�楁垚鏈�",
+          type: "bar",
+          data: data.map(item => (item.energyPurpose === "鍔炲叕" ? item.cost : 0)),
+          itemStyle: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              { offset: 0, color: "#67C23A" },
+              { offset: 1, color: "#85ce61" },
+            ]),
+            borderRadius: [4, 4, 0, 0],
+          },
+          animationDelay: function (idx) {
+            return idx * 100 + 100;
+          },
+        },
+      ],
+      animationEasing: "elasticOut",
+      animationDelayUpdate: function (idx) {
+        return idx * 5;
+      },
+    };
+    costChartInstance.setOption(option);
+  };
+
+  // 鏇存柊鑳借�楃被鍨嬫垚鏈崰姣斿浘
+  const updateTypeChart = () => {
+    const data = tableData.value;
+    const typeCosts = {};
+
+    data.forEach(item => {
+      if (!typeCosts[item.energyType]) {
+        typeCosts[item.energyType] = 0;
+      }
+      typeCosts[item.energyType] += parseFloat(item.cost);
+    });
+
+    const chartData = Object.entries(typeCosts).map(([name, value]) => ({
+      name,
+      value: value.toFixed(2),
+    }));
+
+    const option = {
+      tooltip: {
+        trigger: "item",
+        formatter: "{a} <br/>{b}: 楼{c} ({d}%)",
+        backgroundColor: "rgba(255, 255, 255, 0.95)",
+        borderColor: "#409EFF",
+        borderWidth: 1,
+        textStyle: { color: "#303133" },
+      },
+      legend: {
+        orient: "horizontal",
+        bottom: 0,
+        textStyle: { color: "#606266" },
+      },
+      series: [
+        {
+          name: "鑳借�楃被鍨嬫垚鏈�",
+          type: "pie",
+          radius: ["40%", "70%"],
+          center: ["50%", "40%"],
+          avoidLabelOverlap: false,
+          itemStyle: {
+            borderRadius: 4,
+            borderColor: "#fff",
+            borderWidth: 2,
+          },
+          label: {
+            show: false,
+            position: "center",
+          },
+          emphasis: {
+            label: {
+              show: true,
+              fontSize: "18",
+              fontWeight: "bold",
+              color: "#303133",
+            },
+            itemStyle: {
+              shadowBlur: 10,
+              shadowOffsetX: 0,
+              shadowColor: "rgba(0, 0, 0, 0.3)",
+            },
+          },
+          labelLine: {
+            show: false,
+          },
+          data: chartData,
+        },
+      ],
+      color: ["#409EFF", "#67C23A", "#E6A23C"],
+    };
+    typeChartInstance.setOption(option);
+  };
+
+  // 鏇存柊鑳借�楃敤閫旀垚鏈崰姣斿浘
+  const updatePurposeChart = () => {
+    const data = tableData.value;
+    const purposeCosts = {
+      鐢熶骇: 0,
+      鍔炲叕: 0,
+    };
+
+    data.forEach(item => {
+      if (purposeCosts.hasOwnProperty(item.energyPurpose)) {
+        purposeCosts[item.energyPurpose] += parseFloat(item.cost);
+      }
+    });
+
+    const chartData = Object.entries(purposeCosts).map(([name, value]) => ({
+      name,
+      value: value.toFixed(2),
+    }));
+
+    const option = {
+      tooltip: {
+        trigger: "item",
+        formatter: "{a} <br/>{b}: 楼{c} ({d}%)",
+        backgroundColor: "rgba(255, 255, 255, 0.95)",
+        borderColor: "#409EFF",
+        borderWidth: 1,
+        textStyle: { color: "#303133" },
+      },
+      legend: {
+        orient: "horizontal",
+        bottom: 0,
+        textStyle: { color: "#606266" },
+      },
+      series: [
+        {
+          name: "鑳借�楃敤閫旀垚鏈�",
+          type: "pie",
+          radius: "60%",
+          center: ["50%", "40%"],
+          data: chartData,
+          emphasis: {
+            itemStyle: {
+              shadowBlur: 10,
+              shadowOffsetX: 0,
+              shadowColor: "rgba(0, 0, 0, 0.3)",
+            },
+          },
+          label: {
+            show: true,
+            formatter: "{b}: {d}%",
+            color: "#606266",
+          },
+          labelLine: {
+            show: true,
+            lineStyle: { color: "#dcdfe6" },
+          },
+        },
+      ],
+      color: ["#409EFF", "#67C23A"],
+    };
+    purposeChartInstance.setOption(option);
+  };
+
+  // 鏇存柊鑳借�楀崟浠峰姣斿浘
+  const updatePriceChart = () => {
+    const data = tableData.value;
+    const priceData = {};
+
+    data.forEach(item => {
+      if (!priceData[item.energyType]) {
+        priceData[item.energyType] = {
+          鐢熶骇: 0,
+          鍔炲叕: 0,
+        };
+      }
+      if (priceData[item.energyType].hasOwnProperty(item.energyPurpose)) {
+        priceData[item.energyType][item.energyPurpose] = parseFloat(item.price);
+      }
+    });
+
+    const energyTypes = Object.keys(priceData);
+    const productionPrices = energyTypes.map(type => priceData[type].鐢熶骇);
+    const officePrices = energyTypes.map(type => priceData[type].鍔炲叕);
+
+    const option = {
+      tooltip: {
+        trigger: "axis",
+        axisPointer: { type: "shadow" },
+        backgroundColor: "rgba(255, 255, 255, 0.95)",
+        borderColor: "#409EFF",
+        borderWidth: 1,
+        textStyle: { color: "#303133" },
+      },
+      legend: {
+        data: ["鐢熶骇鑳借�楀崟浠�", "鍔炲叕鑳借�楀崟浠�"],
+        top: 0,
+        right: 10,
+        textStyle: { color: "#606266" },
+      },
+      grid: {
+        left: "3%",
+        right: "4%",
+        bottom: "10%",
+        top: "15%",
+        containLabel: true,
+      },
+      xAxis: {
+        type: "category",
+        data: energyTypes,
+        axisLabel: { color: "#606266" },
+        axisLine: { lineStyle: { color: "#ebeef5" } },
+        splitLine: { show: false },
+      },
+      yAxis: {
+        type: "value",
+        name: "鍗曚环(鍏�)",
+        nameTextStyle: { color: "#606266" },
+        axisLabel: { color: "#606266" },
+        axisLine: { show: false },
+        splitLine: { lineStyle: { color: "#f0f2f5" } },
+      },
+      series: [
+        {
+          name: "鐢熶骇鑳借�楀崟浠�",
+          type: "bar",
+          data: productionPrices,
+          itemStyle: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              { offset: 0, color: "#409EFF" },
+              { offset: 1, color: "#66b1ff" },
+            ]),
+            borderRadius: [4, 4, 0, 0],
+          },
+        },
+        {
+          name: "鍔炲叕鑳借�楀崟浠�",
+          type: "bar",
+          data: officePrices,
+          itemStyle: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              { offset: 0, color: "#67C23A" },
+              { offset: 1, color: "#85ce61" },
+            ]),
+            borderRadius: [4, 4, 0, 0],
+          },
+        },
+      ],
+    };
+    priceChartInstance.setOption(option);
+  };
+
+  // 缁熻缁村害鍒囨崲
+  const handleTypeChange = () => {
+    // 閲嶇疆鏃堕棿鑼冨洿
+    if (statisticsType.value === "day") {
+      const end = new Date();
+      const start = new Date();
+      start.setDate(start.getDate() - 6);
+      searchForm.dateRange = [
+        start.toISOString().split("T")[0],
+        end.toISOString().split("T")[0],
+      ];
+    } else {
+      const end = new Date();
+      const start = new Date();
+      start.setMonth(start.getMonth() - 2);
+      searchForm.monthRange = [
+        start.toISOString().slice(0, 7),
+        end.toISOString().slice(0, 7),
+      ];
+    }
+    page.current = 1;
+    handleQuery();
+  };
+
+  // 鏌ヨ
+  const handleQuery = () => {
+    tableLoading.value = true;
+
+    // 鏋勯�犺姹傚弬鏁�
+    const params = {
+      type: statisticsType.value,
+      energyType: searchForm.energyType || undefined,
+      energyPurpose: searchForm.energyPurpose || undefined,
+    };
+
+    if (statisticsType.value === "day") {
+      if (searchForm.dateRange && searchForm.dateRange.length === 2) {
+        params.startDate = searchForm.dateRange[0];
+        params.endDate = searchForm.dateRange[1];
+      }
+    } else {
+      if (searchForm.monthRange && searchForm.monthRange.length === 2) {
+        params.startDate = searchForm.monthRange[0] + "-01";
+        params.endDate = searchForm.monthRange[1] + "-01";
+      }
+    }
+
+    // 璋冪敤鎺ュ彛鑾峰彇鏁版嵁
+    energyCostStatistics(params)
+      .then(res => {
+        if (res.code === 200) {
+          tableData.value = res.data.records || [];
+          page.total = res.data.total || 0;
+
+          // 鏇存柊缁熻姒傝鏁版嵁
+          if (res.data.overview) {
+            overview.totalCost = res.data.overview.totalCost || "0.00";
+            overview.productionCost = res.data.overview.productionCost || "0.00";
+            overview.officeCost = res.data.overview.officeCost || "0.00";
+            overview.avgCost = res.data.overview.avgCost || "0.00";
+          }
+        } else {
+          ElMessage.error(res.message || "鑾峰彇鏁版嵁澶辫触");
+          tableData.value = [];
+          page.total = 0;
+        }
+      })
+      .catch(err => {
+        console.error("鑾峰彇鏁版嵁寮傚父锛�", err);
+        // 鐢熸垚鍋囨暟鎹�
+        generateMockData();
+      })
+      .finally(() => {
+        tableLoading.value = false;
+        updateCharts();
+      });
+  };
+
+  // 鐢熸垚鍋囨暟鎹�
+  const generateMockData = () => {
+    if (statisticsType.value === "day") {
+      // 鐢熸垚鏈�杩�7澶╃殑鍋囨暟鎹�
+      const mockData = [];
+      const today = new Date();
+
+      for (let i = 6; i >= 0; i--) {
+        const date = new Date(today);
+        date.setDate(date.getDate() - i);
+        const dateStr = date.toISOString().split("T")[0];
+
+        // 鐢熶骇鑳借�楁暟鎹�
+        mockData.push({
+          timePeriod: dateStr,
+          energyType: "鐢�",
+          energyPurpose: "鐢熶骇",
+          consumption: (Math.random() * 1000 + 500).toFixed(2),
+          unit: "kWh",
+          price: "0.85",
+          cost: (Math.random() * 850 + 425).toFixed(2),
+        });
+        mockData.push({
+          timePeriod: dateStr,
+          energyType: "姘�",
+          energyPurpose: "鐢熶骇",
+          consumption: (Math.random() * 500 + 200).toFixed(2),
+          unit: "m鲁",
+          price: "3.50",
+          cost: (Math.random() * 1750 + 700).toFixed(2),
+        });
+        mockData.push({
+          timePeriod: dateStr,
+          energyType: "姘�",
+          energyPurpose: "鐢熶骇",
+          consumption: (Math.random() * 300 + 100).toFixed(2),
+          unit: "m鲁",
+          price: "2.80",
+          cost: (Math.random() * 840 + 280).toFixed(2),
+        });
+
+        // 鍔炲叕鑳借�楁暟鎹�
+        mockData.push({
+          timePeriod: dateStr,
+          energyType: "鐢�",
+          energyPurpose: "鍔炲叕",
+          consumption: (Math.random() * 200 + 100).toFixed(2),
+          unit: "kWh",
+          price: "0.85",
+          cost: (Math.random() * 170 + 85).toFixed(2),
+        });
+        mockData.push({
+          timePeriod: dateStr,
+          energyType: "姘�",
+          energyPurpose: "鍔炲叕",
+          consumption: (Math.random() * 50 + 20).toFixed(2),
+          unit: "m鲁",
+          price: "3.50",
+          cost: (Math.random() * 175 + 70).toFixed(2),
+        });
+      }
+
+      tableData.value = mockData;
+      page.total = mockData.length;
+    } else {
+      // 鐢熸垚鏈�杩�3涓湀鐨勫亣鏁版嵁
+      const mockData = [];
+      const today = new Date();
+
+      for (let i = 2; i >= 0; i--) {
+        const date = new Date(today);
+        date.setMonth(date.getMonth() - i);
+        const monthStr = date.toISOString().slice(0, 7);
+
+        // 鐢熶骇鑳借�楁暟鎹�
+        mockData.push({
+          timePeriod: monthStr,
+          energyType: "鐢�",
+          energyPurpose: "鐢熶骇",
+          consumption: (Math.random() * 30000 + 15000).toFixed(2),
+          unit: "kWh",
+          price: "0.85",
+          cost: (Math.random() * 25500 + 12750).toFixed(2),
+        });
+        mockData.push({
+          timePeriod: monthStr,
+          energyType: "姘�",
+          energyPurpose: "鐢熶骇",
+          consumption: (Math.random() * 15000 + 6000).toFixed(2),
+          unit: "m鲁",
+          price: "3.50",
+          cost: (Math.random() * 52500 + 21000).toFixed(2),
+        });
+        mockData.push({
+          timePeriod: monthStr,
+          energyType: "姘�",
+          energyPurpose: "鐢熶骇",
+          consumption: (Math.random() * 9000 + 3000).toFixed(2),
+          unit: "m鲁",
+          price: "2.80",
+          cost: (Math.random() * 25200 + 8400).toFixed(2),
+        });
+
+        // 鍔炲叕鑳借�楁暟鎹�
+        mockData.push({
+          timePeriod: monthStr,
+          energyType: "鐢�",
+          energyPurpose: "鍔炲叕",
+          consumption: (Math.random() * 6000 + 3000).toFixed(2),
+          unit: "kWh",
+          price: "0.85",
+          cost: (Math.random() * 5100 + 2550).toFixed(2),
+        });
+        mockData.push({
+          timePeriod: monthStr,
+          energyType: "姘�",
+          energyPurpose: "鍔炲叕",
+          consumption: (Math.random() * 1500 + 600).toFixed(2),
+          unit: "m鲁",
+          price: "3.50",
+          cost: (Math.random() * 5250 + 2100).toFixed(2),
+        });
+      }
+
+      tableData.value = mockData;
+      page.total = mockData.length;
+    }
+
+    // 鏇存柊缁熻姒傝鏁版嵁
+    calculateOverview();
+  };
+
+  // 璁$畻缁熻姒傝鏁版嵁
+  const calculateOverview = () => {
+    let totalCost = 0;
+    let productionCost = 0;
+    let officeCost = 0;
+
+    tableData.value.forEach(item => {
+      const cost = parseFloat(item.cost);
+      totalCost += cost;
+      if (item.energyPurpose === "鐢熶骇") {
+        productionCost += cost;
+      } else if (item.energyPurpose === "鍔炲叕") {
+        officeCost += cost;
+      }
+    });
+
+    overview.totalCost = totalCost.toFixed(2);
+    overview.productionCost = productionCost.toFixed(2);
+    overview.officeCost = officeCost.toFixed(2);
+    overview.avgCost = (totalCost / tableData.value.length).toFixed(2);
+  };
+
+  // 鏇存柊鎵�鏈夊浘琛�
+  const updateCharts = () => {
+    nextTick(() => {
+      if (costChartInstance) updateCostChart();
+      if (typeChartInstance) updateTypeChart();
+      if (purposeChartInstance) updatePurposeChart();
+      if (priceChartInstance) updatePriceChart();
+    });
+  };
+
+  // 閲嶇疆
+  const handleReset = () => {
+    searchForm.energyType = "";
+    searchForm.energyPurpose = "";
+    if (statisticsType.value === "day") {
+      const end = new Date();
+      const start = new Date();
+      start.setDate(start.getDate() - 6);
+      searchForm.dateRange = [
+        start.toISOString().split("T")[0],
+        end.toISOString().split("T")[0],
+      ];
+    } else {
+      const end = new Date();
+      const start = new Date();
+      start.setMonth(start.getMonth() - 2);
+      searchForm.monthRange = [
+        start.toISOString().slice(0, 7),
+        end.toISOString().slice(0, 7),
+      ];
+    }
+    page.current = 1;
+    handleQuery();
+  };
+
+  // 瀵煎嚭
+  const handleExport = () => {
+    ElMessage.success("鎶ヨ〃瀵煎嚭鎴愬姛");
+  };
+
+  // 鍒嗛〉澶у皬鍙樺寲
+  const handleSizeChange = val => {
+    page.size = val;
+  };
+
+  // 椤电爜鍙樺寲
+  const handleCurrentChange = val => {
+    page.current = val;
+  };
+
+  // 绐楀彛澶у皬鍙樺寲鏃堕噸鏂版覆鏌撳浘琛�
+  const handleResize = () => {
+    costChartInstance && costChartInstance.resize();
+    typeChartInstance && typeChartInstance.resize();
+    purposeChartInstance && purposeChartInstance.resize();
+    priceChartInstance && priceChartInstance.resize();
+  };
+
+  onMounted(() => {
+    handleQuery();
+    initCharts();
+    window.addEventListener("resize", handleResize);
+  });
+</script>
+
+<style scoped lang="scss">
+  .app-container {
+    padding: 20px;
+  }
+
+  .search_form {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+    padding: 15px;
+    background-color: #f5f7fa;
+    border-radius: 8px;
+  }
+
+  .statistics-overview {
+    margin-bottom: 30px;
+  }
+
+  .charts-container {
+    margin-bottom: 30px;
+  }
+
+  .table-section {
+    margin-bottom: 20px;
+  }
+
+  .section-header {
+    display: flex;
+    align-items: center;
+    font-size: 18px;
+    font-weight: bold;
+    color: #303133;
+    margin-bottom: 15px;
+    padding-left: 10px;
+    border-left: 3px solid #409eff;
+
+    .header-icon {
+      margin-right: 8px;
+      color: #409eff;
+    }
+  }
+
+  .overview-card {
+    display: flex;
+    align-items: center;
+    padding: 20px;
+    border-radius: 4px;
+    background: #fff;
+    border: 1px solid #ebeef5;
+
+    &.blue-card {
+      background-color: #ecf5ff;
+    }
+
+    &.green-card {
+      background-color: #f0f9eb;
+    }
+
+    &.purple-card {
+      background-color: #f3f0ff;
+    }
+
+    &.gray-card {
+      background-color: #f5f7fa;
+    }
+
+    .overview-icon {
+      width: 40px;
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      border-radius: 50%;
+      margin-right: 15px;
+
+      &.blue-icon {
+        background-color: #409eff;
+        color: #fff;
+      }
+
+      &.green-icon {
+        background-color: #67c23a;
+        color: #fff;
+      }
+
+      &.purple-icon {
+        background-color: #909399;
+        color: #fff;
+      }
+
+      &.gray-icon {
+        background-color: #909399;
+        color: #fff;
+      }
+
+      .el-icon {
+        font-size: 20px;
+      }
+    }
+
+    .overview-info {
+      flex: 1;
+
+      .overview-label {
+        font-size: 14px;
+        color: #606266;
+        margin-bottom: 5px;
+      }
+
+      .overview-value {
+        font-size: 20px;
+        font-weight: bold;
+        color: #303133;
+
+        .unit {
+          font-size: 12px;
+          font-weight: normal;
+          color: #909399;
+        }
+      }
+    }
+  }
+
+  .chart-card {
+    background: #fff;
+    border-radius: 4px;
+    border: 1px solid #ebeef5;
+    padding: 20px;
+
+    .chart-title {
+      font-size: 14px;
+      font-weight: bold;
+      color: #303133;
+      margin-bottom: 15px;
+      padding-bottom: 10px;
+      border-bottom: 1px solid #ebeef5;
+    }
+
+    .chart-content {
+      height: 300px;
+    }
+  }
+
+  .consumption-value {
+    font-weight: bold;
+    color: #409eff;
+  }
+
+  .consumption-unit {
+    font-size: 12px;
+    color: #909399;
+    margin-left: 2px;
+  }
+
+  .price-value {
+    font-weight: bold;
+    color: #67c23a;
+  }
+
+  .cost-value {
+    font-weight: bold;
+    color: #f56c6c;
+  }
+
+  .pagination-container {
+    display: flex;
+    justify-content: flex-end;
+  }
+</style>
\ No newline at end of file

--
Gitblit v1.9.3