| | |
| | | value="气" /> |
| | | </el-select> |
| | | </el-form-item> --> |
| | | <el-form-item label="能耗用途"> |
| | | <!-- <el-form-item label="能耗用途"> |
| | | <el-select |
| | | v-model="searchForm.type" |
| | | placeholder="" |
| | |
| | | <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'" |
| | |
| | | <el-card class="chart-card" 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', '能耗单价对比')" |
| | | @click="downloadChart('consumption', '能耗用量对比')" |
| | | > |
| | | 下载 |
| | | </button> |
| | | <button |
| | | class="chart-tool" |
| | | type="button" |
| | | @click="openBigChart('price', '能耗单价对比')" |
| | | @click="openBigChart('consumption', '能耗用量对比')" |
| | | > |
| | | 大图 |
| | | </button> |
| | |
| | | </div> |
| | | </template> |
| | | <div |
| | | ref="priceChartWrap" |
| | | ref="consumptionChartWrap" |
| | | class="chart-wrap" |
| | | v-loading="tableLoading" |
| | | > |
| | | <div |
| | | ref="priceChart" |
| | | ref="consumptionChart" |
| | | class="chart-content" |
| | | v-show="hasTableData" |
| | | ></div> |
| | |
| | | </template> |
| | | <el-table-column type="index" label="序号" width="60" align="center" /> |
| | | <el-table-column |
| | | prop="timePeriod" |
| | | prop="meterReadingDate" |
| | | :label="timeColumnLabel" |
| | | align="center" |
| | | sortable="custom" |
| | |
| | | // 搜索表单 |
| | | const searchForm = reactive({ |
| | | // energyType: "", |
| | | type: "", |
| | | // type: "", |
| | | dateRange: (() => { |
| | | // 默认最近7天 |
| | | const end = new Date(); |
| | |
| | | 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); |
| | |
| | | if (key === "cost") return costChartInstance; |
| | | if (key === "type") return typeChartInstance; |
| | | if (key === "purpose") return purposeChartInstance; |
| | | if (key === "price") return priceChartInstance; |
| | | if (key === "consumption") return consumptionChartInstance; |
| | | 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 === "consumption") chartPanel.value = "advanced"; |
| | | }; |
| | | |
| | | const downloadChart = (key, title) => { |
| | |
| | | const costChart = ref(null); |
| | | const typeChart = ref(null); |
| | | const purposeChart = ref(null); |
| | | const priceChart = ref(null); |
| | | const consumptionChart = ref(null); |
| | | |
| | | const costChartWrap = ref(null); |
| | | const typeChartWrap = ref(null); |
| | | const purposeChartWrap = ref(null); |
| | | const priceChartWrap = ref(null); |
| | | const consumptionChartWrap = ref(null); |
| | | |
| | | const tableAnchor = ref(null); |
| | | |
| | |
| | | let costChartInstance = null; |
| | | let typeChartInstance = null; |
| | | let purposeChartInstance = null; |
| | | let priceChartInstance = null; |
| | | let consumptionChartInstance = null; |
| | | |
| | | // 图表区切换:core | advanced | none(点击当前选中可收起) |
| | | const chartPanel = ref("core"); |
| | |
| | | if (panel === "advanced") { |
| | | if (purposeChart.value && !purposeChartInstance) |
| | | purposeChartInstance = echarts.init(purposeChart.value); |
| | | if (priceChart.value && !priceChartInstance) |
| | | priceChartInstance = echarts.init(priceChart.value); |
| | | if (consumptionChart.value && !consumptionChartInstance) |
| | | consumptionChartInstance = echarts.init(consumptionChart.value); |
| | | if (purposeChartInstance) updatePurposeChart(); |
| | | if (priceChartInstance) updatePriceChart(); |
| | | if (consumptionChartInstance) updateConsumptionChart(); |
| | | } |
| | | }; |
| | | |
| | |
| | | }, |
| | | 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)", |
| | |
| | | purposeChartInstance.setOption(option); |
| | | }; |
| | | |
| | | // 更新能耗单价对比图 |
| | | const updatePriceChart = () => { |
| | | // 更新能耗用量对比图 |
| | | const updateConsumptionChart = () => { |
| | | const data = tableData.value; |
| | | const priceData = {}; |
| | | const consumptionData = {}; |
| | | |
| | | data.forEach((item) => { |
| | | if (!priceData[item.energyType]) { |
| | | priceData[item.energyType] = { |
| | | if (!consumptionData[item.energyType]) { |
| | | consumptionData[item.energyType] = { |
| | | 生产: 0, |
| | | 办公: 0, |
| | | }; |
| | | } |
| | | if (priceData[item.energyType].hasOwnProperty(item.type)) { |
| | | priceData[item.energyType][item.type] = parseFloat(item.price); |
| | | if (consumptionData[item.energyType].hasOwnProperty(item.type)) { |
| | | consumptionData[item.energyType][item.type] = parseFloat( |
| | | item.consumption |
| | | ); |
| | | } |
| | | }); |
| | | |
| | | const energyTypes = Object.keys(priceData); |
| | | const productionPrices = energyTypes.map((type) => priceData[type].生产); |
| | | const officePrices = energyTypes.map((type) => priceData[type].办公); |
| | | const energyTypes = Object.keys(consumptionData); |
| | | const productionConsumptions = energyTypes.map( |
| | | (type) => consumptionData[type].生产 |
| | | ); |
| | | const officeConsumptions = energyTypes.map( |
| | | (type) => consumptionData[type].办公 |
| | | ); |
| | | |
| | | const option = { |
| | | tooltip: { |
| | |
| | | "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)" }, |
| | |
| | | }, |
| | | yAxis: { |
| | | type: "value", |
| | | name: "单价(元)", |
| | | name: "用量", |
| | | nameTextStyle: { color: "rgba(15, 23, 42, 0.58)" }, |
| | | axisLabel: { color: "rgba(15, 23, 42, 0.58)" }, |
| | | axisLine: { show: false }, |
| | |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "生产能耗单价", |
| | | name: "生产能耗用量", |
| | | type: "bar", |
| | | data: productionPrices, |
| | | data: productionConsumptions, |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#2f6fed" }, |
| | |
| | | }, |
| | | }, |
| | | { |
| | | name: "办公能耗单价", |
| | | name: "办公能耗用量", |
| | | type: "bar", |
| | | data: officePrices, |
| | | data: officeConsumptions, |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: "#16a34a" }, |
| | |
| | | }, |
| | | ], |
| | | }; |
| | | priceChartInstance.setOption(option); |
| | | consumptionChartInstance.setOption(option); |
| | | }; |
| | | |
| | | // 统计维度切换 |
| | |
| | | const params = { |
| | | days: 0, |
| | | // energyType: searchForm.energyType || undefined, |
| | | type: searchForm.type || undefined, |
| | | // type: searchForm.type || undefined, |
| | | pageNum: page.current, |
| | | pageSize: page.size, |
| | | }; |
| | |
| | | .then((res) => { |
| | | if (res.code === 200) { |
| | | const data = res.data; |
| | | overview.totalConsumption = data.totalEnergyConsumption || "0"; |
| | | overview.totalAmount = data.totalEnergyCost || "0"; |
| | | overview.avgConsumption = data.averageConsumption || "0"; |
| | | overview.compareRate = data.changeVite || 0; |
| | | overview.totalCost = data.totalEnergyConsumption || "0"; |
| | | overview.productionCost = data.totalEnergyCost || "0"; |
| | | overview.avgCost = data.averageConsumption || "0"; |
| | | overview.officeCost = data.changeVite || 0; |
| | | |
| | | // 处理表格数据 |
| | | tableData.value = data.energyCostDtos || []; |
| | |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.error("获取数据异常:", err); |
| | | // 【假数据(Mock)已禁用】接口异常时不再生成随机假数据,避免误用到生产数据链路 |
| | | ElMessage.error("获取数据异常"); |
| | | tableData.value = []; |
| | | page.total = 0; |
| | |
| | | if (costChartInstance) updateCostChart(); |
| | | if (typeChartInstance) updateTypeChart(); |
| | | if (purposeChartInstance) updatePurposeChart(); |
| | | if (priceChartInstance) updatePriceChart(); |
| | | if (consumptionChartInstance) updateConsumptionChart(); |
| | | }); |
| | | }; |
| | | |
| | |
| | | costChartInstance && costChartInstance.resize(); |
| | | typeChartInstance && typeChartInstance.resize(); |
| | | purposeChartInstance && purposeChartInstance.resize(); |
| | | priceChartInstance && priceChartInstance.resize(); |
| | | consumptionChartInstance && consumptionChartInstance.resize(); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | |
| | | } |
| | | |
| | | .filter-form { |
| | | flex: 1 1 auto; |
| | | flex: 0.1 1 auto; |
| | | min-width: 0; |
| | | } |
| | | |