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