From e95d6f2a9141c05903098065b4356d1158c0c4e2 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期六, 28 三月 2026 14:32:35 +0800
Subject: [PATCH] 能耗统计年月日修改
---
src/views/costAccounting/energyCosts/index.vue | 898 +++++++++++++++++++++++++++++++++--------------------------
1 files changed, 507 insertions(+), 391 deletions(-)
diff --git a/src/views/costAccounting/energyCosts/index.vue b/src/views/costAccounting/energyCosts/index.vue
index 039e8da..3680891 100644
--- a/src/views/costAccounting/energyCosts/index.vue
+++ b/src/views/costAccounting/energyCosts/index.vue
@@ -18,16 +18,16 @@
@change="handleTypeChange">
<el-radio-button label="day">鎸夋棩</el-radio-button>
<el-radio-button label="month">鎸夋湀</el-radio-button>
+ <el-radio-button label="year">鎸夊勾</el-radio-button>
</el-radio-group>
</div>
</div>
</template>
-
<div class="filter-layout">
<el-form :model="searchForm"
:inline="true"
class="filter-form">
- <el-form-item label="鑳借�楃被鍨�">
+ <!-- <el-form-item label="鑳借�楃被鍨�">
<el-select v-model="searchForm.energyType"
placeholder="鍏ㄩ儴"
clearable
@@ -42,21 +42,19 @@
<el-option label="姘�"
value="姘�" />
</el-select>
- </el-form-item>
- <el-form-item label="鑳借�楃敤閫�">
- <el-select v-model="searchForm.energyPurpose"
- placeholder="鍏ㄩ儴"
- clearable
- class="w-140"
- @change="handleQuery">
- <el-option label="鍏ㄩ儴"
- value="鍏ㄩ儴" />
- <el-option label="鐢熶骇"
- value="鐢熶骇" />
- <el-option label="鍔炲叕"
- value="鍔炲叕" />
+ </el-form-item> -->
+ <!-- <el-form-item label="鑳借�楃敤閫�">
+ <el-select
+ v-model="searchForm.type"
+ placeholder=""
+ clearable
+ class="w-140"
+ @change="handleQuery"
+ >
+ <el-option label="鐢熶骇" value="鐢熶骇" />
+ <el-option label="鍔炲叕" value="鍔炲叕" />
</el-select>
- </el-form-item>
+ </el-form-item> -->
<el-form-item label="鏃堕棿鑼冨洿">
<el-date-picker v-if="statisticsType === 'day'"
v-model="searchForm.dateRange"
@@ -67,7 +65,7 @@
value-format="YYYY-MM-DD"
class="w-260"
@change="handleQuery" />
- <el-date-picker v-else
+ <el-date-picker v-else-if="statisticsType === 'month'"
v-model="searchForm.monthRange"
type="monthrange"
range-separator="鑷�"
@@ -76,6 +74,16 @@
value-format="YYYY-MM"
class="w-260"
@change="handleQuery" />
+ <el-select v-else-if="statisticsType === 'year'"
+ v-model="searchForm.selectedYear"
+ placeholder="璇烽�夋嫨骞翠唤"
+ class="w-260"
+ @change="handleYearChange">
+ <el-option v-for="year in recentYears"
+ :key="year"
+ :label="year + '骞�'"
+ :value="year" />
+ </el-select>
</el-form-item>
</el-form>
<div class="filter-actions">
@@ -92,7 +100,6 @@
</div>
</div>
</el-card>
-
<!-- 鍥捐〃鍖哄煙 -->
<div class="charts">
<el-card class="panel-card"
@@ -106,11 +113,14 @@
@click="handleKpiClick('all')">
<div class="kpi-left">
<div class="kpi-label">鎬昏兘鑰楁垚鏈�</div>
- <div class="kpi-value">楼{{ formatMoney(animatedOverview.totalCost) }}</div>
+ <div class="kpi-value">
+ 楼{{ formatMoney(animatedOverview.totalEnergyCost) }}
+ </div>
<div class="kpi-meta">
<span class="kpi-chip"
:class="kpiDelta.total.pct >= 0 ? 'up' : 'down'"
- v-if="kpiDelta.total.valid">{{ kpiDelta.total.pct >= 0 ? '+' : '' }}{{ kpiDelta.total.pct.toFixed(1) }}%</span>
+ v-if="kpiDelta.total.valid">{{ kpiDelta.total.pct >= 0 ? "+" : ""
+ }}{{ kpiDelta.total.pct.toFixed(1) }}%</span>
<svg class="kpi-spark"
viewBox="0 0 72 22"
aria-hidden="true">
@@ -132,10 +142,14 @@
@click.stop>
<button class="kpi-action"
type="button"
- @click="copyKpi('totalCost')">澶嶅埗</button>
+ @click="copyKpi('totalEnergyCost')">
+ 澶嶅埗
+ </button>
<button class="kpi-action"
type="button"
- @click="viewKpiDetails('all')">鏄庣粏</button>
+ @click="viewKpiDetails('all')">
+ 鏄庣粏
+ </button>
</div>
</button>
<button class="kpi-item kpi-production"
@@ -144,11 +158,14 @@
@click="handleKpiClick('production')">
<div class="kpi-left">
<div class="kpi-label">鐢熶骇鑳借�楁垚鏈�</div>
- <div class="kpi-value">楼{{ formatMoney(animatedOverview.productionCost) }}</div>
+ <div class="kpi-value">
+ 楼{{ formatMoney(animatedOverview.productEnergyCost) }}
+ </div>
<div class="kpi-meta">
<span class="kpi-chip"
:class="kpiDelta.production.pct >= 0 ? 'up' : 'down'"
- v-if="kpiDelta.production.valid">{{ kpiDelta.production.pct >= 0 ? '+' : '' }}{{ kpiDelta.production.pct.toFixed(1) }}%</span>
+ v-if="kpiDelta.production.valid">{{ kpiDelta.production.pct >= 0 ? "+" : ""
+ }}{{ kpiDelta.production.pct.toFixed(1) }}%</span>
<svg class="kpi-spark"
viewBox="0 0 72 22"
aria-hidden="true">
@@ -170,10 +187,14 @@
@click.stop>
<button class="kpi-action"
type="button"
- @click="copyKpi('productionCost')">澶嶅埗</button>
+ @click="copyKpi('productEnergyCost')">
+ 澶嶅埗
+ </button>
<button class="kpi-action"
type="button"
- @click="viewKpiDetails('production')">鏄庣粏</button>
+ @click="viewKpiDetails('production')">
+ 鏄庣粏
+ </button>
</div>
</button>
<button class="kpi-item kpi-office"
@@ -182,11 +203,14 @@
@click="handleKpiClick('office')">
<div class="kpi-left">
<div class="kpi-label">鍔炲叕鑳借�楁垚鏈�</div>
- <div class="kpi-value">楼{{ formatMoney(animatedOverview.officeCost) }}</div>
+ <div class="kpi-value">
+ 楼{{ formatMoney(animatedOverview.officeEnergyCost) }}
+ </div>
<div class="kpi-meta">
<span class="kpi-chip"
:class="kpiDelta.office.pct >= 0 ? 'up' : 'down'"
- v-if="kpiDelta.office.valid">{{ kpiDelta.office.pct >= 0 ? '+' : '' }}{{ kpiDelta.office.pct.toFixed(1) }}%</span>
+ v-if="kpiDelta.office.valid">{{ kpiDelta.office.pct >= 0 ? "+" : ""
+ }}{{ kpiDelta.office.pct.toFixed(1) }}%</span>
<svg class="kpi-spark"
viewBox="0 0 72 22"
aria-hidden="true">
@@ -208,10 +232,14 @@
@click.stop>
<button class="kpi-action"
type="button"
- @click="copyKpi('officeCost')">澶嶅埗</button>
+ @click="copyKpi('officeEnergyCost')">
+ 澶嶅埗
+ </button>
<button class="kpi-action"
type="button"
- @click="viewKpiDetails('office')">鏄庣粏</button>
+ @click="viewKpiDetails('office')">
+ 鏄庣粏
+ </button>
</div>
</button>
<button class="kpi-item kpi-avg"
@@ -219,7 +247,10 @@
@click="handleKpiClick('all')">
<div class="kpi-left">
<div class="kpi-label">骞冲潎鎴愭湰</div>
- <div class="kpi-value">楼{{ formatMoney(animatedOverview.avgCost) }} <span class="kpi-unit">/{{ statisticsType === 'day' ? '鏃�' : '鏈�' }}</span></div>
+ <div class="kpi-value">
+ 楼{{ formatMoney(animatedOverview.averageEnergyCost) }}
+ <span class="kpi-unit">/{{ statisticsType === "day" ? "鏃�" : statisticsType === "month" ? "鏈�" : "骞�" }}</span>
+ </div>
<div class="kpi-meta muted">鍩轰簬褰撳墠绛涢�変笌鏄庣粏缁熻</div>
</div>
<div class="kpi-icon">
@@ -231,14 +262,17 @@
@click.stop>
<button class="kpi-action"
type="button"
- @click="copyKpi('avgCost')">澶嶅埗</button>
+ @click="copyKpi('averageEnergyCost')">
+ 澶嶅埗
+ </button>
<button class="kpi-action"
type="button"
- @click="viewKpiDetails('all')">鏄庣粏</button>
+ @click="viewKpiDetails('all')">
+ 鏄庣粏
+ </button>
</div>
</button>
</div>
-
<div class="panel-head">
<div class="segmented"
role="tablist"
@@ -267,7 +301,6 @@
</button>
</div>
</div>
-
<transition name="lux-collapse">
<div v-show="chartPanel === 'core'"
class="panel-body">
@@ -283,10 +316,14 @@
@click.stop>
<button class="chart-tool"
type="button"
- @click="downloadChart('cost', '鑳借�楁垚鏈秼鍔�')">涓嬭浇</button>
+ @click="downloadChart('cost', '鑳借�楁垚鏈秼鍔�')">
+ 涓嬭浇
+ </button>
<button class="chart-tool"
type="button"
- @click="openBigChart('cost', '鑳借�楁垚鏈秼鍔�')">澶у浘</button>
+ @click="openBigChart('cost', '鑳借�楁垚鏈秼鍔�')">
+ 澶у浘
+ </button>
</div>
</div>
</template>
@@ -314,10 +351,14 @@
@click.stop>
<button class="chart-tool"
type="button"
- @click="downloadChart('type', '鑳借�楃被鍨嬫垚鏈崰姣�')">涓嬭浇</button>
+ @click="downloadChart('type', '鑳借�楃被鍨嬫垚鏈崰姣�')">
+ 涓嬭浇
+ </button>
<button class="chart-tool"
type="button"
- @click="openBigChart('type', '鑳借�楃被鍨嬫垚鏈崰姣�')">澶у浘</button>
+ @click="openBigChart('type', '鑳借�楃被鍨嬫垚鏈崰姣�')">
+ 澶у浘
+ </button>
</div>
</div>
</template>
@@ -337,7 +378,6 @@
</el-row>
</div>
</transition>
-
<transition name="lux-collapse">
<div v-show="chartPanel === 'advanced'"
class="panel-body">
@@ -354,10 +394,14 @@
@click.stop>
<button class="chart-tool"
type="button"
- @click="downloadChart('purpose', '鑳借�楃敤閫旀垚鏈崰姣�')">涓嬭浇</button>
+ @click="downloadChart('purpose', '鑳借�楃敤閫旀垚鏈崰姣�')">
+ 涓嬭浇
+ </button>
<button class="chart-tool"
type="button"
- @click="openBigChart('purpose', '鑳借�楃敤閫旀垚鏈崰姣�')">澶у浘</button>
+ @click="openBigChart('purpose', '鑳借�楃敤閫旀垚鏈崰姣�')">
+ 澶у浘
+ </button>
</div>
</div>
</template>
@@ -380,22 +424,26 @@
shadow="never">
<template #header>
<div class="chart-head">
- <span class="chart-title">鑳借�楀崟浠峰姣�</span>
+ <span class="chart-title">鑳借�楃敤閲忓姣�</span>
<div class="chart-tools"
@click.stop>
<button class="chart-tool"
type="button"
- @click="downloadChart('price', '鑳借�楀崟浠峰姣�')">涓嬭浇</button>
+ @click="downloadChart('unit', '鑳借�楃敤閲忓姣�')">
+ 涓嬭浇
+ </button>
<button class="chart-tool"
type="button"
- @click="openBigChart('price', '鑳借�楀崟浠峰姣�')">澶у浘</button>
+ @click="openBigChart('unit', '鑳借�楃敤閲忓姣�')">
+ 澶у浘
+ </button>
</div>
</div>
</template>
- <div ref="priceChartWrap"
+ <div ref="unitChartWrap"
class="chart-wrap"
v-loading="tableLoading">
- <div ref="priceChart"
+ <div ref="unitChart"
class="chart-content"
v-show="hasTableData"></div>
<div class="chart-empty"
@@ -410,7 +458,6 @@
</transition>
</el-card>
</div>
-
<el-dialog v-model="bigChartVisible"
:title="bigChartTitle"
width="92%"
@@ -431,7 +478,6 @@
</div>
</template>
</el-dialog>
-
<!-- 鏁版嵁琛ㄦ牸 -->
<el-card class="table-card"
shadow="never">
@@ -449,7 +495,6 @@
</div>
</div>
</template>
-
<el-table :data="displayTableData"
v-loading="tableLoading"
stripe
@@ -463,11 +508,11 @@
label="搴忓彿"
width="60"
align="center" />
- <el-table-column prop="timePeriod"
+ <el-table-column prop="meterReadingDate"
:label="timeColumnLabel"
align="center"
sortable="custom" />
- <el-table-column prop="energyType"
+ <el-table-column prop="energyTyep"
label="鑳借�楃被鍨�"
width="100"
align="center"
@@ -475,12 +520,12 @@
:filter-method="filterEnergyType"
filter-placement="bottom-end">
<template #default="scope">
- <el-tag :type="getEnergyTypeType(scope.row.energyType)">
- {{ scope.row.energyType }}
+ <el-tag :type="getEnergyTypeType(scope.row.energyTyep)">
+ {{ scope.row.energyTyep }}
</el-tag>
</template>
</el-table-column>
- <el-table-column prop="energyPurpose"
+ <el-table-column prop="type"
label="鑳借�楃敤閫�"
width="100"
align="center"
@@ -488,25 +533,29 @@
:filter-method="filterEnergyPurpose"
filter-placement="bottom-end">
<template #default="scope">
- <el-tag :type="scope.row.energyPurpose === '鐢熶骇' ? 'primary' : 'info'">
- {{ scope.row.energyPurpose }}
+ <el-tag :type="scope.row.type === '鐢熶骇' ? 'primary' : 'warning'">
+ {{ scope.row.type }}
</el-tag>
</template>
</el-table-column>
- <el-table-column prop="consumption"
+ <el-table-column prop="dosage"
label="鐢ㄩ噺"
align="right">
<template #default="scope">
- <span class="consumption-value">{{ formatNumber(scope.row.consumption, 2) }}</span>
- <span class="consumption-unit">{{ scope.row.unit }}</span>
+ <span class="unit-value">{{
+ formatNumber(scope.row.dosage, 2)
+ }}</span>
+ <span class="unit-unit">{{ scope.row.unit }}</span>
</template>
</el-table-column>
- <el-table-column prop="price"
+ <el-table-column prop="unitPrice"
label="鍗曚环(鍏�)"
align="right"
sortable="custom">
<template #default="scope">
- <span class="price-value">{{ formatNumber(scope.row.price, 2) }}</span>
+ <span class="price-value">{{
+ formatNumber(scope.row.unitPrice, 2)
+ }}</span>
</template>
</el-table-column>
<el-table-column prop="cost"
@@ -519,7 +568,6 @@
</template>
</el-table-column>
</el-table>
-
<div class="pagination-container">
<el-pagination v-model:current-page="page.current"
v-model:page-size="page.size"
@@ -534,7 +582,15 @@
</template>
<script setup>
- import { ref, reactive, onMounted, onUnmounted, computed, nextTick, watch } from "vue";
+ import {
+ ref,
+ reactive,
+ onMounted,
+ onUnmounted,
+ computed,
+ nextTick,
+ watch,
+ } from "vue";
import { ElMessage } from "element-plus";
import {
Money,
@@ -546,14 +602,14 @@
} from "@element-plus/icons-vue";
import * as echarts from "echarts";
// import { energyCostStatistics } from "@/api/costAccounting/energyCosts";
- import { energyConsumptionDetailStatistics } from "@/api/energyManagement/energyType";
+ import { energyConsumptionDetailAccount } from "@/api/energyManagement/energyType";
// 缁熻缁村害锛歞ay-鎸夋棩锛宮onth-鎸夋湀
const statisticsType = ref("day");
// 鎼滅储琛ㄥ崟
const searchForm = reactive({
- energyType: "",
- energyPurpose: "",
+ // energyType: "",
+ // type: "",
dateRange: (() => {
// 榛樿鏈�杩�7澶�
const end = new Date();
@@ -568,39 +624,59 @@
start.setMonth(start.getMonth() - 2);
return [start.toISOString().slice(0, 7), end.toISOString().slice(0, 7)];
})(),
+ selectedYear: new Date().getFullYear(), // 榛樿浠婂勾
+ });
+
+ // 鏈�杩戜竷骞�
+ const recentYears = computed(() => {
+ const currentYear = new Date().getFullYear();
+ const years = [];
+ for (let i = 6; i >= 0; i--) {
+ years.push(currentYear - i);
+ }
+ return years;
});
// 鏃堕棿鍒楁爣绛�
const timeColumnLabel = computed(() => {
- return statisticsType.value === "day" ? "鏃ユ湡" : "鏈堜唤";
+ if (statisticsType.value === "day") return "鏃ユ湡";
+ if (statisticsType.value === "month") return "鏈堜唤";
+ if (statisticsType.value === "year") return "骞翠唤";
+ return "鏃堕棿";
});
// 缁熻姒傝
const overview = reactive({
- totalCost: "0.00",
- productionCost: "0.00",
- officeCost: "0.00",
- avgCost: "0.00",
+ totalEnergyCost: "0.00",
+ productEnergyCost: "0.00",
+ officeEnergyCost: "0.00",
+ averageEnergyCost: "0.00",
});
const selectedKpi = ref("all"); // all | production | office
const animatedOverview = reactive({
- totalCost: 0,
- productionCost: 0,
- officeCost: 0,
- avgCost: 0,
+ totalEnergyCost: 0,
+ productEnergyCost: 0,
+ officeEnergyCost: 0,
+ averageEnergyCost: 0,
});
const formatMoney = v => {
const n = Number.parseFloat(v);
const value = Number.isFinite(n) ? n : 0;
- return value.toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
+ return value.toLocaleString("zh-CN", {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2,
+ });
};
const formatNumber = (v, digits = 2) => {
const n = Number.parseFloat(v);
if (!Number.isFinite(n)) return "--";
- return n.toLocaleString("zh-CN", { minimumFractionDigits: digits, maximumFractionDigits: digits });
+ return n.toLocaleString("zh-CN", {
+ minimumFractionDigits: digits,
+ maximumFractionDigits: digits,
+ });
};
const animateNumber = (key, toValue, duration = 420) => {
@@ -620,10 +696,16 @@
watch(
() => ({ ...overview }),
val => {
- animateNumber("totalCost", Number.parseFloat(val.totalCost));
- animateNumber("productionCost", Number.parseFloat(val.productionCost));
- animateNumber("officeCost", Number.parseFloat(val.officeCost));
- animateNumber("avgCost", Number.parseFloat(val.avgCost));
+ animateNumber("totalEnergyCost", Number.parseFloat(val.totalEnergyCost));
+ animateNumber(
+ "productEnergyCost",
+ Number.parseFloat(val.productEnergyCost)
+ );
+ animateNumber("officeEnergyCost", Number.parseFloat(val.officeEnergyCost));
+ animateNumber(
+ "averageEnergyCost",
+ Number.parseFloat(val.averageEnergyCost)
+ );
},
{ deep: true, immediate: true }
);
@@ -631,24 +713,28 @@
// 琛ㄦ牸鏁版嵁
const tableData = ref([]);
const tableLoading = ref(false);
- const hasTableData = computed(() => Array.isArray(tableData.value) && tableData.value.length > 0);
+ const hasTableData = computed(
+ () => Array.isArray(tableData.value) && tableData.value.length > 0
+ );
const queryPulse = ref(false);
const kpiSeries = computed(() => {
const rows = Array.isArray(tableData.value) ? tableData.value : [];
const byTime = new Map();
for (const r of rows) {
- const t = r?.timePeriod ?? "";
+ const t = r?.meterReadingDate ?? "";
if (!t) continue;
if (!byTime.has(t)) byTime.set(t, { total: 0, production: 0, office: 0 });
const bucket = byTime.get(t);
const c = Number.parseFloat(r?.cost);
const cost = Number.isFinite(c) ? c : 0;
bucket.total += cost;
- if (r?.energyPurpose === "鐢熶骇") bucket.production += cost;
- if (r?.energyPurpose === "鍔炲叕") bucket.office += cost;
+ if (r?.type === "鐢熶骇") bucket.production += cost;
+ if (r?.type === "鍔炲叕") bucket.office += cost;
}
- const times = Array.from(byTime.keys()).sort((a, b) => String(a).localeCompare(String(b)));
+ const times = Array.from(byTime.keys()).sort((a, b) =>
+ String(a).localeCompare(String(b))
+ );
const total = times.map(t => byTime.get(t).total);
const production = times.map(t => byTime.get(t).production);
const office = times.map(t => byTime.get(t).office);
@@ -690,9 +776,9 @@
const handleKpiClick = key => {
selectedKpi.value = key;
- if (key === "all") searchForm.energyPurpose = "";
- if (key === "production") searchForm.energyPurpose = "鐢熶骇";
- if (key === "office") searchForm.energyPurpose = "鍔炲叕";
+ if (key === "all") searchForm.type = "";
+ if (key === "production") searchForm.type = "鐢熶骇";
+ if (key === "office") searchForm.type = "鍔炲叕";
page.current = 1;
handleQuery();
};
@@ -701,16 +787,17 @@
handleKpiClick(key);
nextTick(() => {
const el = tableAnchor.value;
- if (el?.scrollIntoView) el.scrollIntoView({ behavior: "smooth", block: "start" });
+ if (el?.scrollIntoView)
+ el.scrollIntoView({ behavior: "smooth", block: "start" });
});
};
const copyKpi = async field => {
const map = {
- totalCost: animatedOverview.totalCost,
- productionCost: animatedOverview.productionCost,
- officeCost: animatedOverview.officeCost,
- avgCost: animatedOverview.avgCost,
+ totalEnergyCost: animatedOverview.totalEnergyCost,
+ productEnergyCost: animatedOverview.productEnergyCost,
+ officeEnergyCost: animatedOverview.officeEnergyCost,
+ averageEnergyCost: animatedOverview.averageEnergyCost,
};
const raw = map[field];
const text = `楼${formatMoney(raw)}`;
@@ -736,13 +823,13 @@
if (key === "cost") return costChartInstance;
if (key === "type") return typeChartInstance;
if (key === "purpose") return purposeChartInstance;
- if (key === "price") return priceChartInstance;
+ if (key === "unit") return unitChartInstance;
return null;
};
const ensurePanelForChart = key => {
if (key === "cost" || key === "type") chartPanel.value = "core";
- if (key === "purpose" || key === "price") chartPanel.value = "advanced";
+ if (key === "purpose" || key === "unit") chartPanel.value = "advanced";
};
const downloadChart = (key, title) => {
@@ -755,12 +842,17 @@
const a = document.createElement("a");
a.href = url;
const typePart = searchForm.energyType ? `_${searchForm.energyType}` : "";
- const purposePart = searchForm.energyPurpose ? `_${searchForm.energyPurpose}` : "";
+ const purposePart = searchForm.type ? `_${searchForm.type}` : "";
let rangePart = "";
if (statisticsType.value === "day") {
- if (searchForm.dateRange?.length === 2) rangePart = `_${searchForm.dateRange[0]}~${searchForm.dateRange[1]}`;
- } else {
- if (searchForm.monthRange?.length === 2) rangePart = `_${searchForm.monthRange[0]}~${searchForm.monthRange[1]}`;
+ if (searchForm.dateRange?.length === 2)
+ rangePart = `_${searchForm.dateRange[0]}~${searchForm.dateRange[1]}`;
+ } else if (statisticsType.value === "month") {
+ if (searchForm.monthRange?.length === 2)
+ rangePart = `_${searchForm.monthRange[0]}~${searchForm.monthRange[1]}`;
+ } else if (statisticsType.value === "year") {
+ if (searchForm.yearRange?.length === 2)
+ rangePart = `_${searchForm.yearRange[0]}~${searchForm.yearRange[1]}`;
}
a.download = `${title || "chart"}${typePart}${purposePart}${rangePart}.png`;
a.click();
@@ -826,7 +918,7 @@
const prop = sortState.prop;
const direction = sortState.order === "ascending" ? 1 : -1;
- const numFields = new Set(["price", "cost", "consumption"]);
+ const numFields = new Set(["price", "cost", "unit"]);
return data.sort((a, b) => {
const av = a?.[prop];
@@ -840,7 +932,9 @@
return (aNum - bNum) * direction;
}
- return String(av ?? "").localeCompare(String(bv ?? ""), "zh-Hans-CN") * direction;
+ return (
+ String(av ?? "").localeCompare(String(bv ?? ""), "zh-Hans-CN") * direction
+ );
});
});
@@ -854,8 +948,8 @@
{ text: "鍔炲叕", value: "鍔炲叕" },
];
- const filterEnergyType = (value, row) => row.energyType === value;
- const filterEnergyPurpose = (value, row) => row.energyPurpose === value;
+ const filterEnergyType = (value, row) => row.energyTyep === value;
+ const filterEnergyPurpose = (value, row) => row.type === value;
// 鍒嗛〉
const page = reactive({
@@ -868,12 +962,12 @@
const costChart = ref(null);
const typeChart = ref(null);
const purposeChart = ref(null);
- const priceChart = ref(null);
+ const unitChart = ref(null);
const costChartWrap = ref(null);
const typeChartWrap = ref(null);
const purposeChartWrap = ref(null);
- const priceChartWrap = ref(null);
+ const unitChartWrap = ref(null);
const tableAnchor = ref(null);
@@ -901,24 +995,32 @@
let costChartInstance = null;
let typeChartInstance = null;
let purposeChartInstance = null;
- let priceChartInstance = null;
+ let unitChartInstance = null;
// 鍥捐〃鍖哄垏鎹細core | advanced | none锛堢偣鍑诲綋鍓嶉�変腑鍙敹璧凤級
const chartPanel = ref("core");
const ensureChartsReady = panel => {
if (panel === "core") {
- if (costChart.value && !costChartInstance) costChartInstance = echarts.init(costChart.value);
- if (typeChart.value && !typeChartInstance) typeChartInstance = echarts.init(typeChart.value);
- if (costChartInstance) updateCostChart();
- if (typeChartInstance) updateTypeChart();
+ if (costChart.value && !costChartInstance) {
+ costChartInstance = echarts.init(costChart.value);
+ setTimeout(() => costChartInstance?.resize(), 50);
+ }
+ if (typeChart.value && !typeChartInstance) {
+ typeChartInstance = echarts.init(typeChart.value);
+ setTimeout(() => typeChartInstance?.resize(), 50);
+ }
return;
}
if (panel === "advanced") {
- if (purposeChart.value && !purposeChartInstance) purposeChartInstance = echarts.init(purposeChart.value);
- if (priceChart.value && !priceChartInstance) priceChartInstance = echarts.init(priceChart.value);
- if (purposeChartInstance) updatePurposeChart();
- if (priceChartInstance) updatePriceChart();
+ if (purposeChart.value && !purposeChartInstance) {
+ purposeChartInstance = echarts.init(purposeChart.value);
+ setTimeout(() => purposeChartInstance?.resize(), 50);
+ }
+ if (unitChart.value && !unitChartInstance) {
+ unitChartInstance = echarts.init(unitChart.value);
+ setTimeout(() => unitChartInstance?.resize(), 50);
+ }
}
};
@@ -942,6 +1044,20 @@
watch(chartPanel, val => {
if (val !== "none") resizeChartsAfterExpand();
});
+
+ // 鐩戝惉琛ㄦ牸鏁版嵁鍙樺寲锛岀‘淇濇暟鎹姞杞藉悗鍥捐〃姝g‘娓叉煋
+ watch(
+ tableData,
+ () => {
+ nextTick(() => {
+ updateCharts();
+ nextTick(() => {
+ handleResize();
+ });
+ });
+ },
+ { deep: true }
+ );
// 鑾峰彇鑳借�楃被鍨嬫爣绛剧被鍨�
const getEnergyTypeType = type => {
@@ -972,7 +1088,8 @@
borderColor: "#2f6fed",
borderWidth: 1,
textStyle: { color: "rgba(15, 23, 42, 0.92)" },
- extraCssText: "box-shadow: 0 14px 40px rgba(15,23,42,.14); border-radius: 12px;",
+ extraCssText:
+ "box-shadow: 0 14px 40px rgba(15,23,42,.14); border-radius: 12px;",
},
legend: {
data: ["鐢熶骇鑳借�楁垚鏈�", "鍔炲叕鑳借�楁垚鏈�"],
@@ -989,7 +1106,7 @@
},
xAxis: {
type: "category",
- data: data.map(item => item.timePeriod),
+ data: data.map(item => item.meterReadingDate),
axisLabel: {
rotate: statisticsType.value === "day" ? 45 : 0,
color: "rgba(15, 23, 42, 0.62)",
@@ -1009,7 +1126,7 @@
{
name: "鐢熶骇鑳借�楁垚鏈�",
type: "bar",
- data: data.map(item => (item.energyPurpose === "鐢熶骇" ? item.cost : 0)),
+ data: data.map(item => (item.type === "鐢熶骇" ? item.cost : 0)),
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#409EFF" },
@@ -1024,7 +1141,7 @@
{
name: "鍔炲叕鑳借�楁垚鏈�",
type: "bar",
- data: data.map(item => (item.energyPurpose === "鍔炲叕" ? item.cost : 0)),
+ data: data.map(item => (item.type === "鍔炲叕" ? item.cost : 0)),
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#67C23A" },
@@ -1051,10 +1168,10 @@
const typeCosts = {};
data.forEach(item => {
- if (!typeCosts[item.energyType]) {
- typeCosts[item.energyType] = 0;
+ if (!typeCosts[item.energyTyep]) {
+ typeCosts[item.energyTyep] = 0;
}
- typeCosts[item.energyType] += parseFloat(item.cost);
+ typeCosts[item.energyTyep] += parseFloat(item.cost);
});
const chartData = Object.entries(typeCosts).map(([name, value]) => ({
@@ -1070,7 +1187,8 @@
borderColor: "#2f6fed",
borderWidth: 1,
textStyle: { color: "rgba(15, 23, 42, 0.92)" },
- extraCssText: "box-shadow: 0 14px 40px rgba(15,23,42,.14); border-radius: 12px;",
+ extraCssText:
+ "box-shadow: 0 14px 40px rgba(15,23,42,.14); border-radius: 12px;",
},
legend: {
orient: "horizontal",
@@ -1126,8 +1244,8 @@
};
data.forEach(item => {
- if (purposeCosts.hasOwnProperty(item.energyPurpose)) {
- purposeCosts[item.energyPurpose] += parseFloat(item.cost);
+ if (purposeCosts.hasOwnProperty(item.type)) {
+ purposeCosts[item.type] += parseFloat(item.cost);
}
});
@@ -1144,7 +1262,8 @@
borderColor: "#2f6fed",
borderWidth: 1,
textStyle: { color: "rgba(15, 23, 42, 0.92)" },
- extraCssText: "box-shadow: 0 14px 40px rgba(15,23,42,.14); border-radius: 12px;",
+ extraCssText:
+ "box-shadow: 0 14px 40px rgba(15,23,42,.14); border-radius: 12px;",
},
legend: {
orient: "horizontal",
@@ -1181,26 +1300,26 @@
purposeChartInstance.setOption(option);
};
- // 鏇存柊鑳借�楀崟浠峰姣斿浘
- const updatePriceChart = () => {
+ // 鏇存柊鑳借�楃敤閲忓姣斿浘
+ const updateConsumptionChart = () => {
const data = tableData.value;
- const priceData = {};
+ const unitData = {};
data.forEach(item => {
- if (!priceData[item.energyType]) {
- priceData[item.energyType] = {
+ if (!unitData[item.energyTyep]) {
+ unitData[item.energyTyep] = {
鐢熶骇: 0,
鍔炲叕: 0,
};
}
- if (priceData[item.energyType].hasOwnProperty(item.energyPurpose)) {
- priceData[item.energyType][item.energyPurpose] = parseFloat(item.price);
+ if (unitData[item.energyTyep].hasOwnProperty(item.type)) {
+ unitData[item.energyTyep][item.type] += parseFloat(item.dosage || 0);
}
});
- const energyTypes = Object.keys(priceData);
- const productionPrices = energyTypes.map(type => priceData[type].鐢熶骇);
- const officePrices = energyTypes.map(type => priceData[type].鍔炲叕);
+ const energyTypes = Object.keys(unitData);
+ const productionConsumptions = energyTypes.map(type => unitData[type].鐢熶骇);
+ const officeConsumptions = energyTypes.map(type => unitData[type].鍔炲叕);
const option = {
tooltip: {
@@ -1210,10 +1329,11 @@
borderColor: "#2f6fed",
borderWidth: 1,
textStyle: { color: "rgba(15, 23, 42, 0.92)" },
- extraCssText: "box-shadow: 0 14px 40px rgba(15,23,42,.14); border-radius: 12px;",
+ extraCssText:
+ "box-shadow: 0 14px 40px rgba(15,23,42,.14); border-radius: 12px;",
},
legend: {
- data: ["鐢熶骇鑳借�楀崟浠�", "鍔炲叕鑳借�楀崟浠�"],
+ data: ["鐢熶骇鑳借�楃敤閲�", "鍔炲叕鑳借�楃敤閲�"],
top: 0,
right: 10,
textStyle: { color: "rgba(15, 23, 42, 0.62)" },
@@ -1234,7 +1354,7 @@
},
yAxis: {
type: "value",
- name: "鍗曚环(鍏�)",
+ name: "鐢ㄩ噺",
nameTextStyle: { color: "rgba(15, 23, 42, 0.58)" },
axisLabel: { color: "rgba(15, 23, 42, 0.58)" },
axisLine: { show: false },
@@ -1242,9 +1362,9 @@
},
series: [
{
- name: "鐢熶骇鑳借�楀崟浠�",
+ name: "鐢熶骇鑳借�楃敤閲�",
type: "bar",
- data: productionPrices,
+ data: productionConsumptions,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#2f6fed" },
@@ -1254,9 +1374,9 @@
},
},
{
- name: "鍔炲叕鑳借�楀崟浠�",
+ name: "鍔炲叕鑳借�楃敤閲�",
type: "bar",
- data: officePrices,
+ data: officeConsumptions,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#16a34a" },
@@ -1267,7 +1387,7 @@
},
],
};
- priceChartInstance.setOption(option);
+ unitChartInstance.setOption(option);
};
// 缁熻缁村害鍒囨崲
@@ -1281,7 +1401,7 @@
start.toISOString().split("T")[0],
end.toISOString().split("T")[0],
];
- } else {
+ } else if (statisticsType.value === "month") {
const end = new Date();
const start = new Date();
start.setMonth(start.getMonth() - 2);
@@ -1289,7 +1409,15 @@
start.toISOString().slice(0, 7),
end.toISOString().slice(0, 7),
];
+ } else if (statisticsType.value === "year") {
+ searchForm.selectedYear = new Date().getFullYear(); // 榛樿浠婂勾
}
+ page.current = 1;
+ handleQuery();
+ };
+
+ // 骞翠唤閫夋嫨鍙樺寲
+ const handleYearChange = () => {
page.current = 1;
handleQuery();
};
@@ -1304,12 +1432,17 @@
// 鏋勯�犺姹傚弬鏁�
const params = {
- type: statisticsType.value,
- energyType: searchForm.energyType || undefined,
- energyPurpose: searchForm.energyPurpose || undefined,
- // 椤圭洰鍐呭父鐢ㄥ垎椤靛弬鏁板懡鍚�
+ days: 0,
+ // energyType: searchForm.energyType || undefined,
+ // type: searchForm.type || undefined,
pageNum: page.current,
pageSize: page.size,
+ state:
+ statisticsType.value === "day"
+ ? "鏃�"
+ : statisticsType.value === "month"
+ ? "鏈�"
+ : "骞�",
};
if (statisticsType.value === "day") {
@@ -1317,37 +1450,80 @@
params.startDate = searchForm.dateRange[0];
params.endDate = searchForm.dateRange[1];
}
- } else {
+ } else if (statisticsType.value === "month") {
if (searchForm.monthRange && searchForm.monthRange.length === 2) {
params.startDate = searchForm.monthRange[0] + "-01";
- params.endDate = searchForm.monthRange[1] + "-01";
+
+ // 缁撴潫鏃堕棿闇�瑕佸彇缁撴潫鏈堜唤鐨勬渶鍚庝竴澶╋紙渚嬪 2026-03 -> 2026-03-31锛�
+ const [endYearStr, endMonthStr] = String(searchForm.monthRange[1]).split(
+ "-"
+ );
+ const endYear = Number(endYearStr);
+ const endMonth = Number(endMonthStr); // 1-12
+ if (
+ !Number.isNaN(endYear) &&
+ !Number.isNaN(endMonth) &&
+ endMonth >= 1 &&
+ endMonth <= 12
+ ) {
+ const lastDay = new Date(endYear, endMonth, 0).getDate(); // 涓嬩釜鏈堢0澶� = 鏈湀鏈�鍚庝竴澶�
+ params.endDate = `${endYearStr}-${endMonthStr}-${String(
+ lastDay
+ ).padStart(2, "0")}`;
+ } else {
+ params.endDate = searchForm.monthRange[1] + "-01";
+ }
+ }
+ } else if (statisticsType.value === "year") {
+ if (searchForm.selectedYear) {
+ const year = searchForm.selectedYear;
+ params.startDate = year + "-01-01";
+ params.endDate = year + "-12-31";
+ }
+ }
+
+ // 璁$畻寮�濮嬪埌缁撴潫鐨勫ぉ鏁帮紙鍖呭惈璧锋涓ゅぉ锛�
+ if (params.startDate && params.endDate) {
+ const start = new Date(params.startDate);
+ const end = new Date(params.endDate);
+ if (!Number.isNaN(start.getTime()) && !Number.isNaN(end.getTime())) {
+ const diffTime = end.getTime() - start.getTime();
+ const diffDays = Math.floor(diffTime / (24 * 60 * 60 * 1000)) + 1;
+ params.days = diffDays > 0 ? diffDays : 0;
}
}
// 璋冪敤鎺ュ彛鑾峰彇鏁版嵁
- energyConsumptionDetailStatistics(params)
+ energyConsumptionDetailAccount(params)
.then(res => {
if (res.code === 200) {
- tableData.value = res.data.records || [];
- page.total = res.data.total || 0;
+ const data = res.data;
+ overview.totalEnergyCost = data.totalEnergyCost || "0";
+ overview.productEnergyCost = data.productEnergyCost || "0";
+ overview.officeEnergyCost = data.officeEnergyCost || "0";
+ overview.averageEnergyCost = data.averageEnergyCost || "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";
- }
+ // 澶勭悊琛ㄦ牸鏁版嵁
+ tableData.value = data.energyConsumptionDetailDtoList || [];
+ page.total = tableData.value.length || 0;
} else {
ElMessage.error(res.message || "鑾峰彇鏁版嵁澶辫触");
tableData.value = [];
page.total = 0;
+ overview.totalEnergyCost = "0.00";
+ overview.productEnergyCost = "0.00";
+ overview.officeEnergyCost = "0.00";
+ overview.averageEnergyCost = "0.00";
}
})
.catch(err => {
- console.error("鑾峰彇鏁版嵁寮傚父锛�", err);
- // 鐢熸垚鍋囨暟鎹�
- generateMockData();
+ ElMessage.error("鑾峰彇鏁版嵁寮傚父");
+ tableData.value = [];
+ page.total = 0;
+ overview.totalEnergyCost = "0.00";
+ overview.productEnergyCost = "0.00";
+ overview.officeEnergyCost = "0.00";
+ overview.averageEnergyCost = "0.00";
})
.finally(() => {
tableLoading.value = false;
@@ -1355,174 +1531,29 @@
});
};
- // 鐢熸垚鍋囨暟鎹�
- 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(() => {
+ // 纭繚 core 闈㈡澘鐨勫浘琛ㄥ缁堝垵濮嬪寲锛堝洜涓洪粯璁ゆ樉绀虹殑鏄� core锛�
+ ensureChartsReady("core");
+
+ // 鍚屾椂涔熷垵濮嬪寲褰撳墠鍙闈㈡澘鐨勫浘琛�
+ if (chartPanel.value === "advanced") {
+ ensureChartsReady("advanced");
+ }
+
+ // 鏇存柊鎵�鏈夊凡鍒濆鍖栫殑鍥捐〃
if (costChartInstance) updateCostChart();
if (typeChartInstance) updateTypeChart();
if (purposeChartInstance) updatePurposeChart();
- if (priceChartInstance) updatePriceChart();
+ if (unitChartInstance) updateConsumptionChart();
});
};
// 閲嶇疆
const handleReset = () => {
- searchForm.energyType = "";
- searchForm.energyPurpose = "";
+ // searchForm.energyType = "";
+ searchForm.type = "";
if (statisticsType.value === "day") {
const end = new Date();
const start = new Date();
@@ -1531,7 +1562,7 @@
start.toISOString().split("T")[0],
end.toISOString().split("T")[0],
];
- } else {
+ } else if (statisticsType.value === "month") {
const end = new Date();
const start = new Date();
start.setMonth(start.getMonth() - 2);
@@ -1539,6 +1570,8 @@
start.toISOString().slice(0, 7),
end.toISOString().slice(0, 7),
];
+ } else if (statisticsType.value === "year") {
+ searchForm.selectedYear = new Date().getFullYear(); // 榛樿浠婂勾
}
page.current = 1;
handleQuery();
@@ -1567,7 +1600,7 @@
costChartInstance && costChartInstance.resize();
typeChartInstance && typeChartInstance.resize();
purposeChartInstance && purposeChartInstance.resize();
- priceChartInstance && priceChartInstance.resize();
+ unitChartInstance && unitChartInstance.resize();
};
onMounted(() => {
@@ -1637,9 +1670,16 @@
--lux-radius-sm: 12px;
padding: 18px 22px 24px;
- background:
- radial-gradient(1200px 420px at 20% 0%, rgba(47, 111, 237, 0.10), transparent 55%),
- radial-gradient(900px 380px at 90% 10%, rgba(22, 163, 74, 0.06), transparent 55%),
+ background: radial-gradient(
+ 1200px 420px at 20% 0%,
+ rgba(47, 111, 237, 0.1),
+ transparent 55%
+ ),
+ radial-gradient(
+ 900px 380px at 90% 10%,
+ rgba(22, 163, 74, 0.06),
+ transparent 55%
+ ),
linear-gradient(180deg, var(--lux-bg) 0%, #ffffff 58%);
}
@@ -1675,7 +1715,7 @@
}
.filter-form {
- flex: 1 1 auto;
+ flex: 0.1 1 auto;
min-width: 0;
}
@@ -1689,7 +1729,7 @@
&:hover {
transform: translateY(-1px);
- box-shadow: 0 10px 22px rgba(15, 23, 42, 0.10);
+ box-shadow: 0 10px 22px rgba(15, 23, 42, 0.1);
filter: saturate(1.02);
}
@@ -1710,7 +1750,7 @@
/* 鏌ヨ鍖烘帶浠剁粺涓�鐨偆 */
:deep(.filter-card .el-form-item__label) {
- color: rgba(15, 23, 42, 0.70);
+ color: rgba(15, 23, 42, 0.7);
font-weight: 650;
}
@@ -1718,20 +1758,21 @@
:deep(.filter-card .el-select__wrapper) {
border-radius: 12px;
box-shadow: none;
- border: 1px solid rgba(15, 23, 42, 0.10);
+ border: 1px solid rgba(15, 23, 42, 0.1);
background: rgba(255, 255, 255, 0.82);
- transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
+ transition: border-color 0.18s ease, box-shadow 0.18s ease,
+ transform 0.18s ease;
}
:deep(.filter-card .el-input__wrapper:hover),
:deep(.filter-card .el-select__wrapper:hover) {
- border-color: rgba(47, 111, 237, 0.20);
+ border-color: rgba(47, 111, 237, 0.2);
transform: translateY(-1px);
}
:deep(.filter-card .is-focus .el-input__wrapper),
:deep(.filter-card .is-focus .el-select__wrapper) {
- border-color: rgba(47, 111, 237, 0.30);
+ border-color: rgba(47, 111, 237, 0.3);
box-shadow: 0 0 0 3px rgba(47, 111, 237, 0.14);
}
@@ -1853,7 +1894,7 @@
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
min-height: 78px;
- transition: box-shadow 0.20s ease, transform 0.20s ease, border-color 0.20s ease;
+ transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease;
&:hover {
transform: translateY(-1px);
@@ -1902,23 +1943,43 @@
}
.metric-total {
- background: linear-gradient(135deg, rgba(47, 111, 237, 0.12), rgba(47, 111, 237, 0.02));
+ background: linear-gradient(
+ 135deg,
+ rgba(47, 111, 237, 0.12),
+ rgba(47, 111, 237, 0.02)
+ );
.metric-right {
- background: linear-gradient(135deg, var(--lux-primary), var(--lux-primary-2));
+ background: linear-gradient(
+ 135deg,
+ var(--lux-primary),
+ var(--lux-primary-2)
+ );
}
}
.metric-production {
- background: linear-gradient(135deg, rgba(22, 163, 74, 0.12), rgba(22, 163, 74, 0.02));
+ background: linear-gradient(
+ 135deg,
+ rgba(22, 163, 74, 0.12),
+ rgba(22, 163, 74, 0.02)
+ );
.metric-right {
- background: linear-gradient(135deg, var(--lux-success), rgba(22, 163, 74, 0.65));
+ background: linear-gradient(
+ 135deg,
+ var(--lux-success),
+ rgba(22, 163, 74, 0.65)
+ );
}
}
.metric-office {
- background: linear-gradient(135deg, rgba(144, 147, 153, 0.14), rgba(144, 147, 153, 0.03));
+ background: linear-gradient(
+ 135deg,
+ rgba(144, 147, 153, 0.14),
+ rgba(144, 147, 153, 0.03)
+ );
.metric-right {
background: linear-gradient(135deg, #909399, #b1b3b8);
@@ -1926,10 +1987,18 @@
}
.metric-avg {
- background: linear-gradient(135deg, rgba(245, 158, 11, 0.12), rgba(245, 158, 11, 0.02));
+ background: linear-gradient(
+ 135deg,
+ rgba(245, 158, 11, 0.12),
+ rgba(245, 158, 11, 0.02)
+ );
.metric-right {
- background: linear-gradient(135deg, var(--lux-warning), rgba(245, 158, 11, 0.62));
+ background: linear-gradient(
+ 135deg,
+ var(--lux-warning),
+ rgba(245, 158, 11, 0.62)
+ );
}
}
@@ -1958,7 +2027,7 @@
filter: saturate(1.02);
}
35% {
- filter: saturate(1.10);
+ filter: saturate(1.1);
}
100% {
filter: saturate(1.02);
@@ -1974,7 +2043,8 @@
border-radius: 14px;
border: 1px solid rgba(15, 23, 42, 0.08);
background: rgba(255, 255, 255, 0.86);
- transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
+ transition: transform 0.18s ease, box-shadow 0.18s ease,
+ border-color 0.18s ease;
min-height: 68px;
text-align: left;
cursor: pointer;
@@ -1986,7 +2056,7 @@
.kpi-item:hover {
transform: translateY(-1px);
- box-shadow: 0 16px 40px rgba(15, 23, 42, 0.10);
+ box-shadow: 0 16px 40px rgba(15, 23, 42, 0.1);
border-color: rgba(47, 111, 237, 0.18);
}
@@ -1994,9 +2064,16 @@
content: "";
position: absolute;
inset: 0;
- background:
- radial-gradient(520px 140px at 20% 0%, rgba(255, 255, 255, 0.65), transparent 60%),
- radial-gradient(620px 180px at 90% 40%, rgba(47, 111, 237, 0.10), transparent 55%);
+ background: radial-gradient(
+ 520px 140px at 20% 0%,
+ rgba(255, 255, 255, 0.65),
+ transparent 60%
+ ),
+ radial-gradient(
+ 620px 180px at 90% 40%,
+ rgba(47, 111, 237, 0.1),
+ transparent 55%
+ );
opacity: 0;
transform: translateX(-8%) translateY(-2%);
transition: opacity 0.22s ease, transform 0.42s cubic-bezier(0.16, 1, 0.3, 1);
@@ -2016,7 +2093,7 @@
background: linear-gradient(
135deg,
rgba(47, 111, 237, 0.18),
- rgba(255, 255, 255, 0.0),
+ rgba(255, 255, 255, 0),
rgba(22, 163, 74, 0.14)
);
opacity: 0;
@@ -2034,17 +2111,15 @@
}
.kpi-item:focus-visible {
- box-shadow:
- 0 16px 44px rgba(15, 23, 42, 0.10),
+ box-shadow: 0 16px 44px rgba(15, 23, 42, 0.1),
0 0 0 3px rgba(47, 111, 237, 0.18);
border-color: rgba(47, 111, 237, 0.22);
}
.kpi-item.selected {
border-color: rgba(47, 111, 237, 0.22);
- box-shadow:
- 0 16px 44px rgba(15, 23, 42, 0.10),
- inset 0 0 0 1px rgba(47, 111, 237, 0.10);
+ box-shadow: 0 16px 44px rgba(15, 23, 42, 0.1),
+ inset 0 0 0 1px rgba(47, 111, 237, 0.1);
}
.kpi-left {
@@ -2096,13 +2171,13 @@
}
.kpi-chip.up {
- border-color: rgba(22, 163, 74, 0.20);
+ border-color: rgba(22, 163, 74, 0.2);
color: rgba(22, 163, 74, 0.96);
background: rgba(22, 163, 74, 0.06);
}
.kpi-chip.down {
- border-color: rgba(239, 68, 68, 0.20);
+ border-color: rgba(239, 68, 68, 0.2);
color: rgba(239, 68, 68, 0.96);
background: rgba(239, 68, 68, 0.06);
}
@@ -2111,7 +2186,7 @@
width: 72px;
height: 22px;
opacity: 0.9;
- filter: drop-shadow(0 8px 16px rgba(15, 23, 42, 0.10));
+ filter: drop-shadow(0 8px 16px rgba(15, 23, 42, 0.1));
}
.kpi-actions {
@@ -2138,11 +2213,12 @@
font-weight: 650;
padding: 4px 8px;
border-radius: 999px;
- border: 1px solid rgba(15, 23, 42, 0.10);
+ border: 1px solid rgba(15, 23, 42, 0.1);
background: rgba(255, 255, 255, 0.78);
color: rgba(15, 23, 42, 0.78);
cursor: pointer;
- transition: background-color 0.16s ease, border-color 0.16s ease, transform 0.16s ease;
+ transition: background-color 0.16s ease, border-color 0.16s ease,
+ transform 0.16s ease;
}
.kpi-action:hover {
@@ -2165,7 +2241,7 @@
height: 240px;
display: grid;
place-items: center;
- background: rgba(255, 255, 255, 0.70);
+ background: rgba(255, 255, 255, 0.7);
border-radius: 12px;
position: absolute;
inset: 0;
@@ -2178,8 +2254,11 @@
:deep(.big-chart-dialog .el-dialog__header) {
padding: 14px 16px;
- background:
- radial-gradient(900px 240px at 10% 0%, rgba(47, 111, 237, 0.10), transparent 55%),
+ background: radial-gradient(
+ 900px 240px at 10% 0%,
+ rgba(47, 111, 237, 0.1),
+ transparent 55%
+ ),
rgba(255, 255, 255, 0.92);
border-bottom: 1px solid rgba(15, 23, 42, 0.06);
}
@@ -2213,7 +2292,7 @@
display: flex;
align-items: center;
gap: 8px;
- opacity: 0.0;
+ opacity: 0;
transform: translateY(-2px);
transition: opacity 0.16s ease, transform 0.16s ease;
}
@@ -2239,11 +2318,12 @@
font-weight: 650;
padding: 4px 8px;
border-radius: 10px;
- border: 1px solid rgba(15, 23, 42, 0.10);
+ border: 1px solid rgba(15, 23, 42, 0.1);
background: rgba(255, 255, 255, 0.78);
color: rgba(15, 23, 42, 0.78);
cursor: pointer;
- transition: background-color 0.16s ease, border-color 0.16s ease, transform 0.16s ease;
+ transition: background-color 0.16s ease, border-color 0.16s ease,
+ transform 0.16s ease;
}
.chart-tool:hover {
@@ -2279,31 +2359,55 @@
}
.kpi-total {
- background: linear-gradient(135deg, rgba(47, 111, 237, 0.10), rgba(255, 255, 255, 0.86));
+ background: linear-gradient(
+ 135deg,
+ rgba(47, 111, 237, 0.1),
+ rgba(255, 255, 255, 0.86)
+ );
}
.kpi-total .kpi-icon {
background: linear-gradient(135deg, var(--lux-primary), var(--lux-primary-2));
}
.kpi-production {
- background: linear-gradient(135deg, rgba(22, 163, 74, 0.10), rgba(255, 255, 255, 0.86));
+ background: linear-gradient(
+ 135deg,
+ rgba(22, 163, 74, 0.1),
+ rgba(255, 255, 255, 0.86)
+ );
}
.kpi-production .kpi-icon {
- background: linear-gradient(135deg, var(--lux-success), rgba(22, 163, 74, 0.65));
+ background: linear-gradient(
+ 135deg,
+ var(--lux-success),
+ rgba(22, 163, 74, 0.65)
+ );
}
.kpi-office {
- background: linear-gradient(135deg, rgba(100, 116, 139, 0.10), rgba(255, 255, 255, 0.86));
+ background: linear-gradient(
+ 135deg,
+ rgba(100, 116, 139, 0.1),
+ rgba(255, 255, 255, 0.86)
+ );
}
.kpi-office .kpi-icon {
background: linear-gradient(135deg, #64748b, #94a3b8);
}
.kpi-avg {
- background: linear-gradient(135deg, rgba(245, 158, 11, 0.10), rgba(255, 255, 255, 0.86));
+ background: linear-gradient(
+ 135deg,
+ rgba(245, 158, 11, 0.1),
+ rgba(255, 255, 255, 0.86)
+ );
}
.kpi-avg .kpi-icon {
- background: linear-gradient(135deg, var(--lux-warning), rgba(245, 158, 11, 0.62));
+ background: linear-gradient(
+ 135deg,
+ var(--lux-warning),
+ rgba(245, 158, 11, 0.62)
+ );
}
.panel-card {
@@ -2358,10 +2462,13 @@
}
.segmented.no-active {
- background:
- radial-gradient(900px 220px at 20% 0%, rgba(47, 111, 237, 0.06), transparent 55%),
+ background: radial-gradient(
+ 900px 220px at 20% 0%,
+ rgba(47, 111, 237, 0.06),
+ transparent 55%
+ ),
rgba(15, 23, 42, 0.03);
- border-color: rgba(15, 23, 42, 0.10);
+ border-color: rgba(15, 23, 42, 0.1);
}
.segmented-indicator {
@@ -2371,14 +2478,15 @@
width: calc(50% - 4px);
height: calc(100% - 8px);
border-radius: 13px;
- background: linear-gradient(180deg, rgba(47, 111, 237, 0.10), rgba(255, 255, 255, 0.82));
+ background: linear-gradient(
+ 180deg,
+ rgba(47, 111, 237, 0.1),
+ rgba(255, 255, 255, 0.82)
+ );
border: 1px solid rgba(47, 111, 237, 0.18);
- box-shadow:
- 0 14px 30px rgba(15, 23, 42, 0.10),
+ box-shadow: 0 14px 30px rgba(15, 23, 42, 0.1),
0 1px 0 rgba(255, 255, 255, 0.65) inset;
- transition:
- transform 0.36s cubic-bezier(0.16, 1, 0.3, 1),
- opacity 0.20s ease;
+ transition: transform 0.36s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s ease;
pointer-events: none;
will-change: transform;
z-index: 1;
@@ -2401,7 +2509,8 @@
border: 1px solid transparent;
background: transparent;
cursor: pointer;
- transition: transform 0.16s ease, color 0.16s ease, background-color 0.16s ease;
+ transition: transform 0.16s ease, color 0.16s ease,
+ background-color 0.16s ease;
}
.segmented-item:hover {
@@ -2452,7 +2561,8 @@
background: var(--lux-card);
backdrop-filter: blur(10px);
box-shadow: var(--lux-shadow-soft);
- transition: box-shadow 0.22s ease, transform 0.22s ease, border-color 0.22s ease;
+ transition: box-shadow 0.22s ease, transform 0.22s ease,
+ border-color 0.22s ease;
&:hover {
transform: translateY(-2px);
@@ -2483,12 +2593,13 @@
background: var(--lux-card);
backdrop-filter: blur(10px);
box-shadow: var(--lux-shadow-soft);
- transition: box-shadow 0.22s ease, transform 0.22s ease, border-color 0.22s ease;
+ transition: box-shadow 0.22s ease, transform 0.22s ease,
+ border-color 0.22s ease;
&:hover {
transform: translateY(-1px);
box-shadow: var(--lux-shadow);
- border-color: rgba(15, 23, 42, 0.10);
+ border-color: rgba(15, 23, 42, 0.1);
}
}
@@ -2496,12 +2607,12 @@
width: 100%;
}
- .consumption-value {
+ .unit-value {
font-weight: bold;
color: var(--lux-primary);
}
- .consumption-unit {
+ .unit-unit {
font-size: 12px;
color: var(--lux-muted);
margin-left: 2px;
@@ -2535,8 +2646,11 @@
}
:deep(.lux-table .el-table__header-wrapper) {
- background:
- linear-gradient(180deg, rgba(15, 23, 42, 0.04) 0%, rgba(15, 23, 42, 0.02) 100%);
+ background: linear-gradient(
+ 180deg,
+ rgba(15, 23, 42, 0.04) 0%,
+ rgba(15, 23, 42, 0.02) 100%
+ );
}
:deep(.lux-table th.el-table__cell) {
@@ -2560,10 +2674,12 @@
}
:deep(.lux-table .el-table__row:hover) {
- box-shadow: inset 3px 0 0 rgba(47, 111, 237, 0.30);
+ box-shadow: inset 3px 0 0 rgba(47, 111, 237, 0.3);
}
- :deep(.lux-table .el-table__body tr.el-table__row--striped > td.el-table__cell) {
+ :deep(
+ .lux-table .el-table__body tr.el-table__row--striped > td.el-table__cell
+ ) {
background: rgba(15, 23, 42, 0.018);
}
@@ -2623,4 +2739,4 @@
max-height: 600px;
opacity: 1;
}
-</style>
\ No newline at end of file
+</style>
--
Gitblit v1.9.3