You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2174 lines
69 KiB
2174 lines
69 KiB
<template> |
|
<div class="water-energy-trend"> |
|
<!-- 时间选择器 --> |
|
<div class="time-selector"> |
|
<div class="selector-label">时间段选择</div> |
|
<div class="time-periods"> |
|
<div |
|
v-for="(period, index) in timePeriods" |
|
:key="index" |
|
:class="['period-item', { active: activePeriod === index }]" |
|
@click="handlePeriodChange(index)" |
|
> |
|
{{ period }} |
|
</div> |
|
</div> |
|
<div class="date-range" v-if="activePeriod === 3"> |
|
<el-date-picker |
|
v-model="dateRange" |
|
type="daterange" |
|
range-separator="至" |
|
start-placeholder="开始日期" |
|
end-placeholder="结束日期" |
|
value-format="yyyy-MM-dd" |
|
@change="handleDateChange" |
|
class="custom-picker" |
|
/> |
|
</div> |
|
</div> |
|
|
|
<!-- 对比控制 --> |
|
<div class="compare-control"> |
|
<el-checkbox v-model="enableCompare">开启对比模式</el-checkbox> |
|
<div class="compare-range" v-if="enableCompare"> |
|
<span class="compare-label">对比时间段:</span> |
|
<el-date-picker |
|
v-model="compareRange" |
|
type="daterange" |
|
range-separator="至" |
|
start-placeholder="开始日期" |
|
end-placeholder="结束日期" |
|
value-format="yyyy-MM-dd" |
|
size="small" |
|
/> |
|
</div> |
|
<el-checkbox v-model="showWarningMarkers" style="margin-left: 0.2rem;">显示预警标记</el-checkbox> |
|
</div> |
|
|
|
<!-- 核心指标卡片 --> |
|
<div class="indicator-cards"> |
|
<div class="indicator-card"> |
|
<div class="card-icon" style="background: linear-gradient(135deg, #5470C6 0%, #91CAFC 100%);"> |
|
<span>总用电</span> |
|
</div> |
|
<div class="card-content"> |
|
<div class="card-value">{{ indicators.totalElectricity }}</div> |
|
<div class="card-label">总用电量(kWh)</div> |
|
<div class="card-change" :class="indicators.electricityChange <= 0 ? 'positive' : 'negative'"> |
|
<span v-if="indicators.electricityChange > 0">↑</span> |
|
<span v-else>↓</span> |
|
{{ Math.abs(indicators.electricityChange) }}% |
|
</div> |
|
</div> |
|
</div> |
|
<div class="indicator-card"> |
|
<div class="card-icon" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);"> |
|
<span>总供水</span> |
|
</div> |
|
<div class="card-content"> |
|
<div class="card-value">{{ indicators.totalWaterSupply }}</div> |
|
<div class="card-label">总供水量(m³)</div> |
|
<div class="card-change" :class="indicators.waterSupplyChange >= 0 ? 'positive' : 'negative'"> |
|
<span v-if="indicators.waterSupplyChange >= 0">↑</span> |
|
<span v-else>↓</span> |
|
{{ Math.abs(indicators.waterSupplyChange) }}% |
|
</div> |
|
</div> |
|
</div> |
|
<div class="indicator-card"> |
|
<div class="card-icon" style="background: linear-gradient(135deg, #91CC75 0%, #F5A623 100%);"> |
|
<span>节能率</span> |
|
</div> |
|
<div class="card-content"> |
|
<div class="card-value">{{ indicators.savingRate }}%</div> |
|
<div class="card-label">综合节能率</div> |
|
<div class="card-change" :class="indicators.savingRateChange >= 0 ? 'positive' : 'negative'"> |
|
<span v-if="indicators.savingRateChange >= 0">↑</span> |
|
<span v-else>↓</span> |
|
{{ Math.abs(indicators.savingRateChange) }}% |
|
</div> |
|
</div> |
|
</div> |
|
<div class="indicator-card"> |
|
<div class="card-icon" style="background: linear-gradient(135deg, #FAC858 0%, #F59E0B 100%);"> |
|
<span>吨水能耗</span> |
|
</div> |
|
<div class="card-content"> |
|
<div class="card-value">{{ indicators.unitWaterEnergy }}</div> |
|
<div class="card-label">吨水能耗(kWh/m³)</div> |
|
<div class="card-change" :class="indicators.unitWaterEnergyChange <= 0 ? 'positive' : 'negative'"> |
|
<span v-if="indicators.unitWaterEnergyChange > 0">↑</span> |
|
<span v-else>↓</span> |
|
{{ Math.abs(indicators.unitWaterEnergyChange) }}% |
|
</div> |
|
</div> |
|
</div> |
|
<div class="indicator-card"> |
|
<div class="card-icon" style="background: linear-gradient(135deg, #73C0DE 0%, #3BA272 100%);"> |
|
<span>节电金额</span> |
|
</div> |
|
<div class="card-content"> |
|
<div class="card-value">{{ indicators.savingMoney }}万元</div> |
|
<div class="card-label">累计节电金额</div> |
|
<div class="card-change" :class="indicators.savingMoneyChange >= 0 ? 'positive' : 'negative'"> |
|
<span v-if="indicators.savingMoneyChange >= 0">↑</span> |
|
<span v-else>↓</span> |
|
{{ Math.abs(indicators.savingMoneyChange) }}% |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<!-- 水泵系统总用电量趋势图 --> |
|
<div class="chart-container"> |
|
<div class="chart-header"> |
|
<div class="chart-title"> |
|
<span class="title-icon" style="background: #15e1fd;"></span> |
|
<span>水泵系统总用电量趋势</span> |
|
</div> |
|
<div class="chart-legend"> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #15e1fd;"></span> |
|
<span>当前时段</span> |
|
</div> |
|
<div class="legend-item" v-if="enableCompare"> |
|
<span class="legend-dot" style="background: #91CC75;"></span> |
|
<span>对比时段</span> |
|
</div> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #EE6666;"></span> |
|
<span>预警时段</span> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="chart" ref="totalElectricityChartRef"></div> |
|
</div> |
|
|
|
<!-- 水泵系统总供水量趋势图 --> |
|
<div class="chart-container"> |
|
<div class="chart-header"> |
|
<div class="chart-title"> |
|
<span class="title-icon" style="background: #4facfe;"></span> |
|
<span>水泵系统总供水量趋势</span> |
|
</div> |
|
<div class="chart-legend"> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #4facfe;"></span> |
|
<span>当前时段</span> |
|
</div> |
|
<div class="legend-item" v-if="enableCompare"> |
|
<span class="legend-dot" style="background: #5470C6;"></span> |
|
<span>对比时段</span> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="chart" ref="totalWaterSupplyChartRef"></div> |
|
</div> |
|
|
|
<!-- 分区用电量趋势图 --> |
|
<div class="chart-container"> |
|
<div class="chart-header"> |
|
<div class="chart-title"> |
|
<span class="title-icon" style="background: #FAC858;"></span> |
|
<span>分区用电量趋势</span> |
|
</div> |
|
<div class="chart-legend"> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #667eea;"></span> |
|
<span>高区</span> |
|
</div> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #f093fb;"></span> |
|
<span>中区</span> |
|
</div> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #4facfe;"></span> |
|
<span>低区</span> |
|
</div> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #fa709a;"></span> |
|
<span>消防区</span> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="chart" ref="zoneElectricityChartRef"></div> |
|
</div> |
|
|
|
<!-- 分区供水量趋势图 --> |
|
<div class="chart-container"> |
|
<div class="chart-header"> |
|
<div class="chart-title"> |
|
<span class="title-icon" style="background: #91CC75;"></span> |
|
<span>分区供水量趋势</span> |
|
</div> |
|
<div class="chart-legend"> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #667eea;"></span> |
|
<span>高区</span> |
|
</div> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #f093fb;"></span> |
|
<span>中区</span> |
|
</div> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #4facfe;"></span> |
|
<span>低区</span> |
|
</div> |
|
<div class="legend-item"> |
|
<span class="legend-dot" style="background: #fa709a;"></span> |
|
<span>消防区</span> |
|
</div> |
|
</div> |
|
</div> |
|
<div class="chart" ref="zoneWaterSupplyChartRef"></div> |
|
</div> |
|
|
|
<!-- 吨水能耗对比图 --> |
|
<div class="chart-container"> |
|
<div class="chart-header"> |
|
<div class="chart-title"> |
|
<span class="title-icon" style="background: #5470C6;"></span> |
|
<span>吨水能耗对比</span> |
|
</div> |
|
<div class="chart-controls"> |
|
<el-select v-model="waterEnergyChartType" @change="updateWaterEnergyChart" size="small" class="custom-select" style="width: 1rem;"> |
|
<el-option label="柱状图" value="bar"></el-option> |
|
<el-option label="折线图" value="line"></el-option> |
|
</el-select> |
|
</div> |
|
</div> |
|
<div class="chart" ref="waterEnergyChartRef"></div> |
|
</div> |
|
|
|
<!-- 节能效果对比分析 --> |
|
<div class="compare-analysis"> |
|
<div class="analysis-header"> |
|
<div class="analysis-title">节能效果对比分析</div> |
|
</div> |
|
<div class="analysis-content" v-if="enableCompare"> |
|
<div class="analysis-item"> |
|
<div class="analysis-label">用电量变化</div> |
|
<div class="analysis-value" :class="compareAnalysis.electricityDiff <= 0 ? 'up' : 'down'"> |
|
{{ compareAnalysis.electricityDiff > 0 ? '+' : '' }}{{ compareAnalysis.electricityDiff }}kWh |
|
</div> |
|
<div class="analysis-percentage" :class="compareAnalysis.electricityRate <= 0 ? 'up' : 'down'"> |
|
({{ compareAnalysis.electricityRate > 0 ? '+' : '' }}{{ compareAnalysis.electricityRate }}%) |
|
</div> |
|
</div> |
|
<div class="analysis-item"> |
|
<div class="analysis-label">供水量变化</div> |
|
<div class="analysis-value" :class="compareAnalysis.waterSupplyDiff >= 0 ? 'up' : 'down'"> |
|
{{ compareAnalysis.waterSupplyDiff > 0 ? '+' : '' }}{{ compareAnalysis.waterSupplyDiff }}m³ |
|
</div> |
|
<div class="analysis-percentage" :class="compareAnalysis.waterSupplyRate >= 0 ? 'up' : 'down'"> |
|
({{ compareAnalysis.waterSupplyRate > 0 ? '+' : '' }}{{ compareAnalysis.waterSupplyRate }}%) |
|
</div> |
|
</div> |
|
<div class="analysis-item"> |
|
<div class="analysis-label">节能率变化</div> |
|
<div class="analysis-value" :class="compareAnalysis.savingRateDiff >= 0 ? 'up' : 'down'"> |
|
{{ compareAnalysis.savingRateDiff > 0 ? '+' : '' }}{{ compareAnalysis.savingRateDiff }}% |
|
</div> |
|
<div class="analysis-percentage" :class="compareAnalysis.savingRateRate >= 0 ? 'up' : 'down'"> |
|
({{ compareAnalysis.savingRateRate > 0 ? '+' : '' }}{{ compareAnalysis.savingRateRate }}%) |
|
</div> |
|
</div> |
|
<div class="analysis-item"> |
|
<div class="analysis-label">节电金额变化</div> |
|
<div class="analysis-value" :class="compareAnalysis.moneyDiff >= 0 ? 'up' : 'down'"> |
|
{{ compareAnalysis.moneyDiff > 0 ? '+' : '' }}{{ compareAnalysis.moneyDiff }}万元 |
|
</div> |
|
<div class="analysis-percentage" :class="compareAnalysis.moneyRate >= 0 ? 'up' : 'down'"> |
|
({{ compareAnalysis.moneyRate > 0 ? '+' : '' }}{{ compareAnalysis.moneyRate }}%) |
|
</div> |
|
</div> |
|
</div> |
|
<div class="analysis-hint" v-else> |
|
<svg class="hint-icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> |
|
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/> |
|
<path d="M464 336a48 48 0 1096 0 48 48 0 10-96 0zm72 112h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V456c0-4.4-3.6-8-8-8z" fill="currentColor"/> |
|
</svg> |
|
<span>开启对比模式后可查看两个时间段的用电量、供水量及节能效果对比分析</span> |
|
</div> |
|
</div> |
|
|
|
<!-- 能耗预警与关联分析 --> |
|
<div class="warning-energy-analysis"> |
|
<div class="section-header"> |
|
<div class="section-title">能耗预警与关联分析</div> |
|
<div class="section-actions"> |
|
<el-select v-model="warningFilter.level" placeholder="预警级别" clearable size="small" class="custom-select" style="width: 1.2rem;"> |
|
<el-option label="全部" value=""></el-option> |
|
<el-option label="严重" value="critical"></el-option> |
|
<el-option label="重要" value="major"></el-option> |
|
<el-option label="一般" value="minor"></el-option> |
|
</el-select> |
|
</div> |
|
</div> |
|
|
|
<!-- 预警时间轴与能耗影响 --> |
|
<div class="warning-timeline-chart"> |
|
<div class="timeline-header"> |
|
<div class="header-item"> |
|
<span class="label">预警次数</span> |
|
<span class="value">{{ warningStats.total }}</span> |
|
</div> |
|
<div class="header-item"> |
|
<span class="label">用电损失</span> |
|
<span class="value warning-impact">{{ warningStats.electricityLoss }}kWh</span> |
|
</div> |
|
<div class="header-item"> |
|
<span class="label">节能率下降</span> |
|
<span class="value warning-impact">{{ warningStats.savingRateDrop }}%</span> |
|
</div> |
|
<div class="header-item"> |
|
<span class="label">影响时长</span> |
|
<span class="value">{{ warningStats.impactDuration }}小时</span> |
|
</div> |
|
</div> |
|
<div class="timeline-chart" ref="warningTimelineChartRef"></div> |
|
</div> |
|
|
|
<!-- 预警影响详情表格 --> |
|
<div class="warning-impact-table"> |
|
<div class="table-header"> |
|
<div class="table-title">预警影响详情</div> |
|
</div> |
|
<div class="table-container"> |
|
<table class="impact-table"> |
|
<thead> |
|
<tr> |
|
<th>预警时间</th> |
|
<th>预警级别</th> |
|
<th>预警标题</th> |
|
<th>区域</th> |
|
<th>状态</th> |
|
<th>用电影响</th> |
|
<th>供水影响</th> |
|
<th>节能率影响</th> |
|
<th>影响时长</th> |
|
<th>操作</th> |
|
</tr> |
|
</thead> |
|
<tbody> |
|
<tr v-for="warning in filteredWarnings" :key="warning.id"> |
|
<td>{{ warning.warningTime }}</td> |
|
<td> |
|
<span class="level-badge" :class="warning.level">{{ getWarningLevelText(warning.level) }}</span> |
|
</td> |
|
<td class="title-cell">{{ warning.title }}</td> |
|
<td>{{ warning.zoneName }}</td> |
|
<td> |
|
<span class="status-badge" :class="warning.status">{{ getWarningStatusText(warning.status) }}</span> |
|
</td> |
|
<td :class="warning.electricityImpact > 0 ? 'energy-loss' : 'energy-save'"> |
|
{{ warning.electricityImpact > 0 ? '+' : '' }}{{ warning.electricityImpact }}kWh |
|
</td> |
|
<td :class="warning.waterSupplyImpact >= 0 ? 'water-up' : 'water-down'"> |
|
{{ warning.waterSupplyImpact > 0 ? '+' : '' }}{{ warning.waterSupplyImpact }}m³ |
|
</td> |
|
<td :class="warning.savingRateImpact < 0 ? 'saving-drop' : 'saving-rise'"> |
|
{{ warning.savingRateImpact > 0 ? '+' : '' }}{{ warning.savingRateImpact }}% |
|
</td> |
|
<td>{{ warning.impactDuration }}h</td> |
|
<td> |
|
<div class="action-buttons"> |
|
<el-button |
|
size="small" |
|
type="primary" |
|
@click="viewWarningDetail(warning)" |
|
class="action-btn" |
|
> |
|
详情 |
|
</el-button> |
|
<el-button |
|
v-if="warning.status === 'pending' || warning.status === 'processing'" |
|
size="small" |
|
type="success" |
|
@click="handleWarningResolve(warning)" |
|
class="action-btn" |
|
> |
|
处理 |
|
</el-button> |
|
<el-dropdown @command="(cmd) => handleWarningCommand(cmd, warning)" class="action-dropdown"> |
|
<el-button size="small" class="action-btn"> |
|
更多 |
|
<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" style="margin-left: 0.04rem; width: 0.1rem; height: 0.1rem;"> |
|
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="currentColor"/> |
|
<path d="M688 464H336c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h352c8.8 0 16-7.2 16-16v-64c0-8.8-7.2-16-16-16z" fill="currentColor"/> |
|
</svg> |
|
</el-button> |
|
<template #dropdown> |
|
<el-dropdown-menu class="custom-dropdown-menu"> |
|
<el-dropdown-item command="markResolved" v-if="warning.status !== 'resolved'">标记已处理</el-dropdown-item> |
|
<el-dropdown-item command="close" v-if="warning.status !== 'resolved'">关闭预警</el-dropdown-item> |
|
<el-dropdown-item command="reopen" v-if="warning.status === 'resolved'">重新打开</el-dropdown-item> |
|
<el-dropdown-item command="export" divided>导出报告</el-dropdown-item> |
|
</el-dropdown-menu> |
|
</template> |
|
</el-dropdown> |
|
</div> |
|
</td> |
|
</tr> |
|
</tbody> |
|
</table> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<!-- 预警详情弹窗 --> |
|
<el-dialog |
|
v-model="warningDetailDialogVisible" |
|
title="预警与能耗关联详情" |
|
width="900px" |
|
class="custom-dialog" |
|
> |
|
<div class="warning-detail-content" v-if="selectedWarning"> |
|
<div class="detail-section"> |
|
<div class="section-title">预警信息</div> |
|
<div class="info-grid"> |
|
<div class="info-item"> |
|
<span class="item-label">预警ID:</span> |
|
<span class="item-value">{{ selectedWarning.id }}</span> |
|
</div> |
|
<div class="info-item"> |
|
<span class="item-label">预警级别:</span> |
|
<span class="item-value level-badge" :class="selectedWarning.level">{{ getWarningLevelText(selectedWarning.level) }}</span> |
|
</div> |
|
<div class="info-item"> |
|
<span class="item-label">区域名称:</span> |
|
<span class="item-value">{{ selectedWarning.zoneName }}</span> |
|
</div> |
|
<div class="info-item"> |
|
<span class="item-label">预警时间:</span> |
|
<span class="item-value">{{ selectedWarning.warningTime }}</span> |
|
</div> |
|
<div class="info-item full-width"> |
|
<span class="item-label">预警描述:</span> |
|
<span class="item-value">{{ selectedWarning.description }}</span> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="detail-section"> |
|
<div class="section-title">能耗影响分析</div> |
|
<div class="impact-cards"> |
|
<div class="impact-card"> |
|
<div class="card-label">用电增加</div> |
|
<div class="card-value energy-impact">{{ selectedWarning.electricityImpact }}kWh</div> |
|
<div class="card-desc">相比正常运行时段</div> |
|
</div> |
|
<div class="impact-card"> |
|
<div class="card-label">供水减少</div> |
|
<div class="card-value water-impact">{{ selectedWarning.waterSupplyImpact }}m³</div> |
|
<div class="card-desc">系统供水量减少</div> |
|
</div> |
|
<div class="impact-card"> |
|
<div class="card-label">节能率下降</div> |
|
<div class="card-value saving-impact">{{ selectedWarning.savingRateImpact }}%</div> |
|
<div class="card-desc">系统节能率降低</div> |
|
</div> |
|
<div class="impact-card"> |
|
<div class="card-label">经济损失</div> |
|
<div class="card-value cost-impact">{{ selectedWarning.costImpact }}元</div> |
|
<div class="card-desc">电费损失估算</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="detail-section"> |
|
<div class="section-title">能耗与供水趋势对比</div> |
|
<div class="energy-comparison-chart" ref="energyComparisonChartRef"></div> |
|
</div> |
|
</div> |
|
<template #footer> |
|
<el-button @click="warningDetailDialogVisible = false" class="custom-btn">关闭</el-button> |
|
</template> |
|
</el-dialog> |
|
</div> |
|
</template> |
|
|
|
<script> |
|
import * as echarts from "echarts"; |
|
|
|
export default { |
|
name: "WaterEnergyConsumptionEfficiencyTrend", |
|
data() { |
|
return { |
|
timePeriods: ["近七日", "近一月", "近三月", "自定义"], |
|
activePeriod: 0, |
|
dateRange: [], |
|
compareRange: [], |
|
enableCompare: false, |
|
showWarningMarkers: true, |
|
indicators: { |
|
totalElectricity: 285600, |
|
electricityChange: -8.5, |
|
totalWaterSupply: 125000, |
|
waterSupplyChange: 5.2, |
|
savingRate: 25.8, |
|
savingRateChange: 6.8, |
|
unitWaterEnergy: 0.73, |
|
unitWaterEnergyChange: -12.5, |
|
savingMoney: 28.6, |
|
savingMoneyChange: 9.3 |
|
}, |
|
compareAnalysis: { |
|
electricityDiff: -26500, |
|
electricityRate: -8.5, |
|
waterSupplyDiff: 6200, |
|
waterSupplyRate: 5.2, |
|
savingRateDiff: 1.8, |
|
savingRateRate: 7.5, |
|
moneyDiff: 2.5, |
|
moneyRate: 9.6 |
|
}, |
|
warningStats: { |
|
total: 15, |
|
electricityLoss: 3850, |
|
savingRateDrop: -4.8, |
|
impactDuration: 72 |
|
}, |
|
warningFilter: { |
|
level: "" |
|
}, |
|
warningList: [], |
|
waterEnergyChartType: "bar", |
|
totalElectricityChart: null, |
|
totalWaterSupplyChart: null, |
|
zoneElectricityChart: null, |
|
zoneWaterSupplyChart: null, |
|
waterEnergyChart: null, |
|
warningTimelineChart: null, |
|
energyComparisonChart: null, |
|
warningDetailDialogVisible: false, |
|
selectedWarning: null |
|
}; |
|
}, |
|
computed: { |
|
filteredWarnings() { |
|
let warnings = [...this.warningList]; |
|
if (this.warningFilter.level) { |
|
warnings = warnings.filter(w => w.level === this.warningFilter.level); |
|
} |
|
return warnings; |
|
} |
|
}, |
|
mounted() { |
|
this.initTotalElectricityChart(); |
|
this.initTotalWaterSupplyChart(); |
|
this.initZoneElectricityChart(); |
|
this.initZoneWaterSupplyChart(); |
|
this.initWaterEnergyChart(); |
|
this.initWarningTimelineChart(); |
|
this.initWarningList(); |
|
window.addEventListener("resize", this.handleResize); |
|
}, |
|
beforeDestroy() { |
|
window.removeEventListener("resize", this.handleResize); |
|
if (this.totalElectricityChart) this.totalElectricityChart.dispose(); |
|
if (this.totalWaterSupplyChart) this.totalWaterSupplyChart.dispose(); |
|
if (this.zoneElectricityChart) this.zoneElectricityChart.dispose(); |
|
if (this.zoneWaterSupplyChart) this.zoneWaterSupplyChart.dispose(); |
|
if (this.waterEnergyChart) this.waterEnergyChart.dispose(); |
|
if (this.warningTimelineChart) this.warningTimelineChart.dispose(); |
|
if (this.energyComparisonChart) this.energyComparisonChart.dispose(); |
|
}, |
|
watch: { |
|
activePeriod() { |
|
this.updateAllCharts(); |
|
}, |
|
enableCompare() { |
|
this.updateAllCharts(); |
|
}, |
|
compareRange() { |
|
if (this.enableCompare) { |
|
this.updateAllCharts(); |
|
} |
|
}, |
|
showWarningMarkers() { |
|
this.updateAllCharts(); |
|
}, |
|
"warningFilter.level"() { |
|
this.updateWarningTimelineChart(); |
|
} |
|
}, |
|
methods: { |
|
handlePeriodChange(index) { |
|
this.activePeriod = index; |
|
}, |
|
handleDateChange(value) { |
|
this.updateAllCharts(); |
|
}, |
|
initTotalElectricityChart() { |
|
this.totalElectricityChart = echarts.init(this.$refs.totalElectricityChartRef); |
|
this.updateTotalElectricityChart(); |
|
}, |
|
updateTotalElectricityChart() { |
|
const dataMap = { |
|
0: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
current: [42000, 45000, 43000, 48000, 51000, 46000, 44000], |
|
compare: [46000, 49000, 47000, 52000, 55000, 50000, 48000], |
|
warningData: [0, 1, 0, 2, 1, 0, 0] |
|
}, |
|
1: { |
|
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], |
|
current: [410000, 450000, 430000, 480000, 510000, 460000, 440000], |
|
compare: [450000, 490000, 470000, 520000, 550000, 500000, 480000], |
|
warningData: [3, 5, 2, 8, 6, 4, 3] |
|
}, |
|
2: { |
|
xData: ["1月", "2月", "3月"], |
|
current: [12500000, 13800000, 13200000], |
|
compare: [13600000, 15000000, 14400000], |
|
warningData: [45, 62, 38] |
|
}, |
|
3: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
current: [42000, 45000, 43000, 48000, 51000, 46000, 44000], |
|
compare: [46000, 49000, 47000, 52000, 55000, 50000, 48000], |
|
warningData: [0, 1, 0, 2, 1, 0, 0] |
|
} |
|
}; |
|
|
|
const currentData = dataMap[this.activePeriod]; |
|
const series = [ |
|
{ |
|
name: "当前时段", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.current, |
|
itemStyle: { color: "#15e1fd" }, |
|
lineStyle: { color: "#15e1fd", width: 3 }, |
|
areaStyle: { |
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
|
{ offset: 0, color: "rgba(21, 225, 253, 0.5)" }, |
|
{ offset: 1, color: "rgba(21, 225, 253, 0)" } |
|
]) |
|
} |
|
} |
|
]; |
|
|
|
if (this.showWarningMarkers) { |
|
const warningPoints = currentData.warningData.map((value, index) => { |
|
if (value > 0) { |
|
return { |
|
name: currentData.xData[index], |
|
value: value, |
|
xAxis: index, |
|
yAxis: this.activePeriod === 2 ? 14000000 : 50000, |
|
itemStyle: { color: "#EE6666" } |
|
}; |
|
} |
|
return null; |
|
}).filter(item => item !== null); |
|
|
|
if (warningPoints.length > 0) { |
|
series[0].markPoint = { |
|
data: warningPoints, |
|
symbol: "pin", |
|
symbolSize: 30, |
|
label: { show: true, color: "#ffffff", fontSize: 10, formatter: "预警" } |
|
}; |
|
} |
|
} |
|
|
|
if (this.enableCompare) { |
|
series.push({ |
|
name: "对比时段", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.compare, |
|
itemStyle: { color: "#91CC75" }, |
|
lineStyle: { color: "#91CC75", width: 2, type: "dashed" } |
|
}); |
|
} |
|
|
|
const option = { |
|
tooltip: { trigger: "axis", axisPointer: { type: "cross" } }, |
|
grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true }, |
|
xAxis: { |
|
type: "category", |
|
boundaryGap: false, |
|
data: currentData.xData, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
axisTick: { show: false } |
|
}, |
|
yAxis: { |
|
type: "value", |
|
name: "kWh", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { lineStyle: { color: "#1a3d62", type: "dashed" } } |
|
}, |
|
series: series |
|
}; |
|
this.totalElectricityChart.setOption(option); |
|
}, |
|
initTotalWaterSupplyChart() { |
|
this.totalWaterSupplyChart = echarts.init(this.$refs.totalWaterSupplyChartRef); |
|
this.updateTotalWaterSupplyChart(); |
|
}, |
|
updateTotalWaterSupplyChart() { |
|
const dataMap = { |
|
0: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
current: [18500, 19500, 18800, 21000, 22500, 20000, 19000], |
|
compare: [17500, 18500, 17800, 20000, 21500, 19000, 18000] |
|
}, |
|
1: { |
|
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], |
|
current: [180000, 190000, 183000, 205000, 220000, 195000, 185000], |
|
compare: [170000, 180000, 173000, 195000, 210000, 185000, 175000] |
|
}, |
|
2: { |
|
xData: ["1月", "2月", "3月"], |
|
current: [5500000, 5800000, 5650000], |
|
compare: [5200000, 5500000, 5350000] |
|
}, |
|
3: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
current: [18500, 19500, 18800, 21000, 22500, 20000, 19000], |
|
compare: [17500, 18500, 17800, 20000, 21500, 19000, 18000] |
|
} |
|
}; |
|
|
|
const currentData = dataMap[this.activePeriod]; |
|
const series = [ |
|
{ |
|
name: "当前时段", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.current, |
|
itemStyle: { color: "#4facfe" }, |
|
lineStyle: { color: "#4facfe", width: 3 }, |
|
areaStyle: { |
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
|
{ offset: 0, color: "rgba(79, 172, 254, 0.5)" }, |
|
{ offset: 1, color: "rgba(79, 172, 254, 0)" } |
|
]) |
|
} |
|
} |
|
]; |
|
|
|
if (this.enableCompare) { |
|
series.push({ |
|
name: "对比时段", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.compare, |
|
itemStyle: { color: "#5470C6" }, |
|
lineStyle: { color: "#5470C6", width: 2, type: "dashed" } |
|
}); |
|
} |
|
|
|
const option = { |
|
tooltip: { trigger: "axis", axisPointer: { type: "cross" } }, |
|
grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true }, |
|
xAxis: { |
|
type: "category", |
|
boundaryGap: false, |
|
data: currentData.xData, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
axisTick: { show: false } |
|
}, |
|
yAxis: { |
|
type: "value", |
|
name: "m³", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { lineStyle: { color: "#1a3d62", type: "dashed" } } |
|
}, |
|
series: series |
|
}; |
|
this.totalWaterSupplyChart.setOption(option); |
|
}, |
|
initZoneElectricityChart() { |
|
this.zoneElectricityChart = echarts.init(this.$refs.zoneElectricityChartRef); |
|
this.updateZoneElectricityChart(); |
|
}, |
|
updateZoneElectricityChart() { |
|
const dataMap = { |
|
0: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
highZone: [12500, 13500, 12800, 14500, 15500, 13800, 13000], |
|
middleZone: [9200, 9800, 9400, 10500, 11200, 10100, 9500], |
|
lowZone: [18000, 19000, 18500, 20500, 22000, 19500, 18500], |
|
fireZone: [2300, 2200, 2300, 2500, 2300, 2400, 2500] |
|
}, |
|
1: { |
|
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], |
|
highZone: [120000, 135000, 128000, 145000, 155000, 138000, 130000], |
|
middleZone: [88000, 94000, 90000, 101000, 108000, 97000, 91000], |
|
middleZone: [172000, 182000, 177000, 197000, 212000, 187000, 177000], |
|
fireZone: [22000, 21000, 22000, 24000, 22000, 23000, 24000] |
|
}, |
|
2: { |
|
xData: ["1月", "2月", "3月"], |
|
highZone: [3750000, 4200000, 4000000], |
|
middleZone: [2750000, 2920000, 2820000], |
|
lowZone: [5380000, 5700000, 5550000], |
|
fireZone: [680000, 650000, 680000] |
|
}, |
|
3: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
highZone: [12500, 13500, 12800, 14500, 15500, 13800, 13000], |
|
middleZone: [9200, 9800, 9400, 10500, 11200, 10100, 9500], |
|
lowZone: [18000, 19000, 18500, 20500, 22000, 19500, 18500], |
|
fireZone: [2300, 2200, 2300, 2500, 2300, 2400, 2500] |
|
} |
|
}; |
|
|
|
const currentData = dataMap[this.activePeriod]; |
|
|
|
const option = { |
|
tooltip: { trigger: "axis", axisPointer: { type: "shadow" } }, |
|
grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true }, |
|
xAxis: { |
|
type: "category", |
|
data: currentData.xData, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
axisTick: { show: false } |
|
}, |
|
yAxis: { |
|
type: "value", |
|
name: "kWh", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { lineStyle: { color: "#1a3d62", type: "dashed" } } |
|
}, |
|
series: [ |
|
{ |
|
name: "高区", |
|
type: "bar", |
|
stack: "zone", |
|
data: currentData.highZone, |
|
itemStyle: { color: "#667eea" } |
|
}, |
|
{ |
|
name: "中区", |
|
type: "bar", |
|
stack: "zone", |
|
data: currentData.middleZone, |
|
itemStyle: { color: "#f093fb" } |
|
}, |
|
{ |
|
name: "低区", |
|
type: "bar", |
|
stack: "zone", |
|
data: currentData.lowZone, |
|
itemStyle: { color: "#4facfe" } |
|
}, |
|
{ |
|
name: "消防区", |
|
type: "bar", |
|
stack: "zone", |
|
data: currentData.fireZone, |
|
itemStyle: { color: "#fa709a" } |
|
} |
|
] |
|
}; |
|
this.zoneElectricityChart.setOption(option); |
|
}, |
|
initZoneWaterSupplyChart() { |
|
this.zoneWaterSupplyChart = echarts.init(this.$refs.zoneWaterSupplyChartRef); |
|
this.updateZoneWaterSupplyChart(); |
|
}, |
|
updateZoneWaterSupplyChart() { |
|
const dataMap = { |
|
0: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
highZone: [5500, 5800, 5600, 6300, 6800, 6100, 5700], |
|
middleZone: [4100, 4300, 4200, 4700, 5100, 4600, 4300], |
|
lowZone: [8000, 8500, 8200, 9200, 9800, 8800, 8200], |
|
fireZone: [900, 900, 900, 1000, 900, 950, 1000] |
|
}, |
|
1: { |
|
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], |
|
highZone: [52000, 56000, 54000, 61000, 66000, 59000, 55000], |
|
middleZone: [39000, 41000, 40000, 45000, 49000, 44000, 41000], |
|
lowZone: [76000, 81000, 78000, 88000, 94000, 84000, 78000], |
|
fireZone: [8500, 8500, 8500, 9500, 8500, 9000, 9500] |
|
}, |
|
2: { |
|
xData: ["1月", "2月", "3月"], |
|
highZone: [1620000, 1820000, 1740000], |
|
middleZone: [1210000, 1280000, 1230000], |
|
lowZone: [2360000, 2520000, 2420000], |
|
fireZone: [265000, 250000, 265000] |
|
}, |
|
3: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
highZone: [5500, 5800, 5600, 6300, 6800, 6100, 5700], |
|
middleZone: [4100, 4300, 4200, 4700, 5100, 4600, 4300], |
|
lowZone: [8000, 8500, 8200, 9200, 9800, 8800, 8200], |
|
fireZone: [900, 900, 900, 1000, 900, 950, 1000] |
|
} |
|
}; |
|
|
|
const currentData = dataMap[this.activePeriod]; |
|
|
|
const option = { |
|
tooltip: { trigger: "axis", axisPointer: { type: "shadow" } }, |
|
grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true }, |
|
xAxis: { |
|
type: "category", |
|
data: currentData.xData, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
axisTick: { show: false } |
|
}, |
|
yAxis: { |
|
type: "value", |
|
name: "m³", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { lineStyle: { color: "#1a3d62", type: "dashed" } } |
|
}, |
|
series: [ |
|
{ |
|
name: "高区", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.highZone, |
|
itemStyle: { color: "#667eea" }, |
|
lineStyle: { color: "#667eea", width: 2 } |
|
}, |
|
{ |
|
name: "中区", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.middleZone, |
|
itemStyle: { color: "#f093fb" }, |
|
lineStyle: { color: "#f093fb", width: 2 } |
|
}, |
|
{ |
|
name: "低区", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.lowZone, |
|
itemStyle: { color: "#4facfe" }, |
|
lineStyle: { color: "#4facfe", width: 2 } |
|
}, |
|
{ |
|
name: "消防区", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.fireZone, |
|
itemStyle: { color: "#fa709a" }, |
|
lineStyle: { color: "#fa709a", width: 2 } |
|
} |
|
] |
|
}; |
|
this.zoneWaterSupplyChart.setOption(option); |
|
}, |
|
initWaterEnergyChart() { |
|
this.waterEnergyChart = echarts.init(this.$refs.waterEnergyChartRef); |
|
this.updateWaterEnergyChart(); |
|
}, |
|
updateWaterEnergyChart() { |
|
const dataMap = { |
|
0: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
current: [0.72, 0.73, 0.71, 0.74, 0.75, 0.72, 0.73], |
|
compare: [0.78, 0.79, 0.77, 0.80, 0.81, 0.78, 0.79] |
|
}, |
|
1: { |
|
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], |
|
current: [0.71, 0.72, 0.70, 0.73, 0.74, 0.71, 0.72], |
|
compare: [0.76, 0.77, 0.75, 0.78, 0.79, 0.76, 0.77] |
|
}, |
|
2: { |
|
xData: ["1月", "2月", "3月"], |
|
current: [0.73, 0.74, 0.73], |
|
compare: [0.78, 0.79, 0.78] |
|
}, |
|
3: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
current: [0.72, 0.73, 0.71, 0.74, 0.75, 0.72, 0.73], |
|
compare: [0.78, 0.79, 0.77, 0.80, 0.81, 0.78, 0.79] |
|
} |
|
}; |
|
|
|
const currentData = dataMap[this.activePeriod]; |
|
|
|
if (this.waterEnergyChartType === "bar") { |
|
const series = [ |
|
{ |
|
name: "当前时段", |
|
type: "bar", |
|
data: currentData.current, |
|
itemStyle: { |
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
|
{ offset: 0, color: "#5470C6" }, |
|
{ offset: 1, color: "#3E5F8A" } |
|
]) |
|
} |
|
} |
|
]; |
|
|
|
if (this.enableCompare) { |
|
series.push({ |
|
name: "对比时段", |
|
type: "bar", |
|
data: currentData.compare, |
|
itemStyle: { |
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
|
{ offset: 0, color: "#91CC75" }, |
|
{ offset: 1, color: "#66BB6A" } |
|
]) |
|
} |
|
}); |
|
} |
|
|
|
const option = { |
|
tooltip: { trigger: "axis", axisPointer: { type: "shadow" } }, |
|
grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true }, |
|
xAxis: { |
|
type: "category", |
|
data: currentData.xData, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
axisTick: { show: false } |
|
}, |
|
yAxis: { |
|
type: "value", |
|
name: "kWh/m³", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { lineStyle: { color: "#1a3d62", type: "dashed" } } |
|
}, |
|
series: series |
|
}; |
|
this.waterEnergyChart.setOption(option); |
|
} else { |
|
const series = [ |
|
{ |
|
name: "当前时段", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.current, |
|
itemStyle: { color: "#5470C6" }, |
|
lineStyle: { color: "#5470C6", width: 3 } |
|
} |
|
]; |
|
|
|
if (this.enableCompare) { |
|
series.push({ |
|
name: "对比时段", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.compare, |
|
itemStyle: { color: "#91CC75" }, |
|
lineStyle: { color: "#91CC75", width: 2, type: "dashed" } |
|
}); |
|
} |
|
|
|
const option = { |
|
tooltip: { trigger: "axis", axisPointer: { type: "cross" } }, |
|
grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true }, |
|
xAxis: { |
|
type: "category", |
|
boundaryGap: false, |
|
data: currentData.xData, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
axisTick: { show: false } |
|
}, |
|
yAxis: { |
|
type: "value", |
|
name: "kWh/m³", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { lineStyle: { color: "#1a3d62", type: "dashed" } } |
|
}, |
|
series: series |
|
}; |
|
this.waterEnergyChart.setOption(option); |
|
} |
|
}, |
|
updateAllCharts() { |
|
this.updateTotalElectricityChart(); |
|
this.updateTotalWaterSupplyChart(); |
|
this.updateZoneElectricityChart(); |
|
this.updateZoneWaterSupplyChart(); |
|
this.updateWaterEnergyChart(); |
|
this.updateWarningTimelineChart(); |
|
}, |
|
handleResize() { |
|
if (this.totalElectricityChart) this.totalElectricityChart.resize(); |
|
if (this.totalWaterSupplyChart) this.totalWaterSupplyChart.resize(); |
|
if (this.zoneElectricityChart) this.zoneElectricityChart.resize(); |
|
if (this.zoneWaterSupplyChart) this.zoneWaterSupplyChart.resize(); |
|
if (this.waterEnergyChart) this.waterEnergyChart.resize(); |
|
if (this.warningTimelineChart) this.warningTimelineChart.resize(); |
|
if (this.energyComparisonChart) this.energyComparisonChart.resize(); |
|
}, |
|
initWarningList() { |
|
this.warningList = [ |
|
{ |
|
id: "WRN202403050001", |
|
level: "critical", |
|
title: "高区水泵能耗超标", |
|
description: "高区水泵系统能耗超出阈值28.56%", |
|
zoneName: "高区供水", |
|
warningTime: "2024-03-05 10:30:25", |
|
status: "pending", |
|
electricityImpact: 520, |
|
waterSupplyImpact: -85, |
|
savingRateImpact: -9.2, |
|
impactDuration: 8, |
|
costImpact: 624, |
|
energyData: { before: [12500, 12200, 12400, 12300], after: [13200, 12900, 13100, 13000] } |
|
}, |
|
{ |
|
id: "WRN202403050002", |
|
level: "critical", |
|
title: "中区水泵异常", |
|
description: "中区水泵系统能耗超出阈值35.68%", |
|
zoneName: "中区供水", |
|
warningTime: "2024-03-05 09:15:42", |
|
status: "processing", |
|
electricityImpact: 680, |
|
waterSupplyImpact: -120, |
|
savingRateImpact: -11.5, |
|
impactDuration: 6, |
|
costImpact: 816, |
|
energyData: { before: [9200, 9100, 9300, 9200], after: [9950, 9850, 10050, 9950] } |
|
}, |
|
{ |
|
id: "WRN202403050003", |
|
level: "major", |
|
title: "低区水泵运行异常", |
|
description: "低区水泵系统能耗超出阈值15.25%", |
|
zoneName: "低区供水", |
|
warningTime: "2024-03-05 08:45:18", |
|
status: "pending", |
|
electricityImpact: 380, |
|
waterSupplyImpact: -65, |
|
savingRateImpact: -7.8, |
|
impactDuration: 5, |
|
costImpact: 456, |
|
energyData: { before: [18000, 17800, 17900, 17800], after: [18550, 18350, 18450, 18350] } |
|
}, |
|
{ |
|
id: "WRN202403040004", |
|
level: "major", |
|
title: "消防区泵能耗异常", |
|
description: "消防区水泵能耗超出时长超标12.35%", |
|
zoneName: "消防供水", |
|
warningTime: "2024-03-04 16:22:33", |
|
status: "resolved", |
|
electricityImpact: 220, |
|
waterSupplyImpact: 0, |
|
savingRateImpact: -5.5, |
|
impactDuration: 4, |
|
costImpact: 264, |
|
energyData: { before: [2300, 2250, 2280, 2270], after: [2480, 2430, 2460, 2450] } |
|
}, |
|
{ |
|
id: "WRN202403040005", |
|
level: "minor", |
|
title: "系统吨水能耗轻微超标", |
|
description: "系统吨水能耗超出阈值6.80%", |
|
zoneName: "全系统", |
|
warningTime: "2024-03-04 14:10:22", |
|
status: "resolved", |
|
electricityImpact: 180, |
|
waterSupplyImpact: -25, |
|
savingRateImpact: -4.2, |
|
impactDuration: 3, |
|
costImpact: 216, |
|
energyData: { before: [42000, 41500, 41800, 41700], after: [42300, 41800, 42100, 42000] } |
|
} |
|
]; |
|
}, |
|
getWarningLevelText(level) { |
|
const map = { critical: "严重", major: "重要", minor: "一般" }; |
|
return map[level] || level; |
|
}, |
|
getWarningStatusText(status) { |
|
const map = { pending: "待处理", processing: "处理中", resolved: "已处理" }; |
|
return map[status] || status; |
|
}, |
|
initWarningTimelineChart() { |
|
this.warningTimelineChart = echarts.init(this.$refs.warningTimelineChartRef); |
|
this.updateWarningTimelineChart(); |
|
}, |
|
updateWarningTimelineChart() { |
|
const dataMap = { |
|
0: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
electricityData: [42000, 45000, 43000, 48000, 51000, 46000, 44000], |
|
waterSupplyData: [18500, 19500, 18800, 21000, 22500, 20000, 19000], |
|
savingRateData: [25.5, 26.2, 25.8, 24.5, 23.8, 25.0, 25.3], |
|
warningData: [0, 1, 0, 2, 1, 0, 0] |
|
}, |
|
1: { |
|
xData: ["1日", "5日", "10日", "15日", "20日", "25日", "30日"], |
|
electricityData: [410000, 450000, 430000, 480000, 510000, 460000, 440000], |
|
waterSupplyData: [180000, 190000, 183000, 205000, 220000, 195000, 185000], |
|
savingRateData: [25.0, 26.0, 25.5, 24.8, 24.0, 25.2, 25.5], |
|
warningData: [3, 5, 2, 8, 6, 4, 3] |
|
}, |
|
2: { |
|
xData: ["1月", "2月", "3月"], |
|
electricityData: [12500000, 13800000, 13200000], |
|
waterSupplyData: [5500000, 5800000, 5650000], |
|
savingRateData: [24.5, 26.0, 25.5], |
|
warningData: [45, 62, 38] |
|
}, |
|
3: { |
|
xData: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"], |
|
electricityData: [42000, 45000, 43000, 48000, 51000, 46000, 44000], |
|
waterSupplyData: [18500, 19500, 18800, 21000, 22500, 20000, 19000], |
|
savingRateData: [25.5, 26.2, 25.8, 24.5, 23.8, 25.0, 25.3], |
|
warningData: [0, 1, 0, 2, 1, 0, 0] |
|
} |
|
}; |
|
|
|
const currentData = dataMap[this.activePeriod]; |
|
|
|
const option = { |
|
tooltip: { trigger: "axis", axisPointer: { type: "cross" } }, |
|
legend: { |
|
data: ["用电量", "供水量", "节能率", "预警次数"], |
|
textStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
top: 0 |
|
}, |
|
grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true, top: "15%" }, |
|
xAxis: { |
|
type: "category", |
|
boundaryGap: false, |
|
data: currentData.xData, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
axisTick: { show: false } |
|
}, |
|
yAxis: [ |
|
{ |
|
type: "value", |
|
name: "用电量(kWh)", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { lineStyle: { color: "#1a3d62", type: "dashed" } } |
|
}, |
|
{ |
|
type: "value", |
|
name: "供水量(m³)", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { show: false } |
|
}, |
|
{ |
|
type: "value", |
|
name: "节能率/预警数", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { show: false } |
|
} |
|
], |
|
series: [ |
|
{ |
|
name: "用电量", |
|
type: "line", |
|
smooth: true, |
|
data: currentData.electricityData, |
|
itemStyle: { color: "#15e1fd" }, |
|
lineStyle: { color: "#15e1fd", width: 3 } |
|
}, |
|
{ |
|
name: "供水量", |
|
type: "line", |
|
smooth: true, |
|
yAxisIndex: 1, |
|
data: currentData.waterSupplyData, |
|
itemStyle: { color: "#4facfe" }, |
|
lineStyle: { color: "#4facfe", width: 2 } |
|
}, |
|
{ |
|
name: "节能率", |
|
type: "line", |
|
smooth: true, |
|
yAxisIndex: 2, |
|
data: currentData.savingRateData, |
|
itemStyle: { color: "#91CC75" }, |
|
lineStyle: { color: "#91CC75", width: 2 } |
|
}, |
|
{ |
|
name: "预警次数", |
|
type: "bar", |
|
yAxisIndex: 2, |
|
data: currentData.warningData, |
|
itemStyle: { |
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
|
{ offset: 0, color: "rgba(238, 102, 102, 0.8)" }, |
|
{ offset: 1, color: "rgba(238, 102, 102, 0.3)" } |
|
]) |
|
} |
|
} |
|
] |
|
}; |
|
this.warningTimelineChart.setOption(option); |
|
}, |
|
viewWarningDetail(warning) { |
|
this.selectedWarning = warning; |
|
this.warningDetailDialogVisible = true; |
|
this.$nextTick(() => { |
|
this.initEnergyComparisonChart(); |
|
}); |
|
}, |
|
handleWarningResolve(warning) { |
|
warning.status = "processing"; |
|
this.$message.success("预警已开始处理"); |
|
}, |
|
handleWarningCommand(command, warning) { |
|
if (command === "markResolved") { |
|
warning.status = "resolved"; |
|
this.$message.success("已标记为已处理"); |
|
} else if (command === "close") { |
|
warning.status = "resolved"; |
|
this.$message.success("预警已关闭"); |
|
} else if (command === "reopen") { |
|
warning.status = "pending"; |
|
this.$message.success("预警已重新打开"); |
|
} else if (command === "export") { |
|
this.$message.success("预警报告导出成功"); |
|
} |
|
}, |
|
initEnergyComparisonChart() { |
|
if (!this.$refs.energyComparisonChartRef || !this.selectedWarning) return; |
|
this.energyComparisonChart = echarts.init(this.$refs.energyComparisonChartRef); |
|
const { energyData } = this.selectedWarning; |
|
|
|
const option = { |
|
tooltip: { trigger: "axis", axisPointer: { type: "shadow" } }, |
|
legend: { |
|
data: ["预警前", "预警后"], |
|
textStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
top: 0 |
|
}, |
|
grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true, top: "10%" }, |
|
xAxis: { |
|
type: "category", |
|
data: ["时段1", "时段2", "时段3", "时段4", "时段5"], |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
axisTick: { show: false } |
|
}, |
|
yAxis: { |
|
type: "value", |
|
name: "kWh", |
|
nameTextStyle: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLabel: { color: "rgba(255, 255, 255, 0.8)" }, |
|
axisLine: { lineStyle: { color: "#365576" } }, |
|
splitLine: { lineStyle: { color: "#1a3d62", type: "dashed" } } |
|
}, |
|
series: [ |
|
{ |
|
name: "预警前", |
|
type: "bar", |
|
data: energyData.before, |
|
itemStyle: { color: "#91CC75" } |
|
}, |
|
{ |
|
name: "预警后", |
|
type: "bar", |
|
data: energyData.after, |
|
itemStyle: { color: "#EE6666" } |
|
} |
|
] |
|
}; |
|
this.energyComparisonChart.setOption(option); |
|
} |
|
} |
|
}; |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.water-energy-trend { |
|
padding: 0.16rem; |
|
} |
|
|
|
.time-selector { |
|
display: flex; |
|
align-items: center; |
|
gap: 0.2rem; |
|
padding: 0.15rem; |
|
background: rgba(255, 255, 255, 0.05); |
|
border-radius: 0.08rem; |
|
margin-bottom: 0.16rem; |
|
|
|
.selector-label { |
|
font-size: 0.14rem; |
|
color: #ffffff; |
|
font-weight: bold; |
|
} |
|
|
|
.time-periods { |
|
display: flex; |
|
gap: 0.08rem; |
|
|
|
.period-item { |
|
padding: 0.06rem 0.15rem; |
|
font-size: 0.13rem; |
|
color: #ffffff; |
|
opacity: 0.6; |
|
cursor: pointer; |
|
border-radius: 0.04rem; |
|
transition: all 0.3s ease; |
|
border: 1px solid transparent; |
|
|
|
&:hover { |
|
opacity: 0.9; |
|
background: rgba(255, 255, 255, 0.1); |
|
} |
|
|
|
&.active { |
|
opacity: 1; |
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|
border-color: transparent; |
|
} |
|
} |
|
} |
|
|
|
.date-range { |
|
::v-deep .custom-picker { |
|
.el-input__wrapper { |
|
background: rgba(255, 255, 255, 0.1); |
|
border: 1px solid rgba(255, 255, 255, 0.2); |
|
|
|
.el-input__inner { |
|
color: #ffffff; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
.compare-control { |
|
display: flex; |
|
align-items: center; |
|
gap: 0.15rem; |
|
padding: 0.15rem 0.2rem; |
|
background: rgba(255, 255, 255, 0.05); |
|
border-radius: 0.08rem; |
|
margin-bottom: 0.16rem; |
|
|
|
.compare-range { |
|
display: flex; |
|
align-items: center; |
|
gap: 0.1rem; |
|
|
|
.compare-label { |
|
font-size: 0.13rem; |
|
color: #ffffff; |
|
opacity: 0.7; |
|
} |
|
|
|
::v-deep .el-date-picker { |
|
.el-input__wrapper { |
|
background: rgba(255, 255, 255, 0.1); |
|
border: 1px solid rgba(255, 255, 255, 0.2); |
|
|
|
.el-input__inner { |
|
color: #ffffff; |
|
} |
|
} |
|
} |
|
} |
|
|
|
::v-deep .el-checkbox { |
|
.el-checkbox__label { |
|
color: #ffffff; |
|
} |
|
} |
|
} |
|
|
|
.indicator-cards { |
|
display: grid; |
|
grid-template-columns: repeat(auto-fit, minmax(2.5rem, 1fr)); |
|
gap: 0.15rem; |
|
margin-bottom: 0.16rem; |
|
|
|
.indicator-card { |
|
display: flex; |
|
align-items: center; |
|
padding: 0.2rem; |
|
background: rgba(255, 255, 255, 0.05); |
|
border-radius: 0.08rem; |
|
transition: all 0.3s ease; |
|
|
|
&:hover { |
|
transform: translateY(-0.02rem); |
|
box-shadow: 0 0.08rem 0.16rem rgba(0, 0, 0, 0.3); |
|
} |
|
|
|
.card-icon { |
|
width: 0.6rem; |
|
height: 0.6rem; |
|
border-radius: 0.06rem; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
margin-right: 0.15rem; |
|
color: #ffffff; |
|
font-size: 0.18rem; |
|
font-weight: bold; |
|
} |
|
|
|
.card-content { |
|
flex: 1; |
|
|
|
.card-value { |
|
font-size: 0.24rem; |
|
color: #15e1fd; |
|
font-weight: bold; |
|
margin-bottom: 0.05rem; |
|
} |
|
|
|
.card-label { |
|
font-size: 0.12rem; |
|
color: #ffffff; |
|
opacity: 0.7; |
|
margin-bottom: 0.05rem; |
|
} |
|
|
|
.card-change { |
|
font-size: 0.12rem; |
|
font-weight: 500; |
|
|
|
&.positive { |
|
color: #91CC75; |
|
} |
|
|
|
&.negative { |
|
color: #EE6666; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
.chart-container { |
|
background: rgba(255, 255, 255, 0.03); |
|
border-radius: 0.08rem; |
|
padding: 0.2rem; |
|
margin-bottom: 0.16rem; |
|
|
|
.chart-header { |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
margin-bottom: 0.2rem; |
|
|
|
.chart-title { |
|
font-size: 0.15rem; |
|
color: #ffffff; |
|
font-weight: bold; |
|
display: flex; |
|
align-items: center; |
|
gap: 0.08rem; |
|
|
|
.title-icon { |
|
width: 0.04rem; |
|
height: 0.16rem; |
|
border-radius: 0.02rem; |
|
} |
|
} |
|
|
|
.chart-legend { |
|
display: flex; |
|
gap: 0.15rem; |
|
|
|
.legend-item { |
|
display: flex; |
|
align-items: center; |
|
gap: 0.05rem; |
|
font-size: 0.13rem; |
|
color: #ffffff; |
|
opacity: 0.7; |
|
|
|
.legend-dot { |
|
width: 0.1rem; |
|
height: 0.1rem; |
|
border-radius: 50%; |
|
} |
|
} |
|
} |
|
|
|
.chart-controls { |
|
::v-deep .custom-select { |
|
.el-input__wrapper { |
|
background: rgba(255, 255, 255, 0.1); |
|
border: 1px solid rgba(255, 255, 255, 0.2); |
|
|
|
.el-input__inner { |
|
color: #ffffff; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
.chart { |
|
width: 100%; |
|
height: 3.5rem; |
|
} |
|
} |
|
|
|
.compare-analysis { |
|
background: rgba(255, 255, 255, 0.03); |
|
border-radius: 0.08rem; |
|
padding: 0.2rem; |
|
margin-bottom: 0.16rem; |
|
|
|
.analysis-header { |
|
margin-bottom: 0.2rem; |
|
|
|
.analysis-title { |
|
font-size: 0.15rem; |
|
color: #ffffff; |
|
font-weight: bold; |
|
padding-left: 0.12rem; |
|
border-left: 0.04rem solid #15e1fd; |
|
} |
|
} |
|
|
|
.analysis-content { |
|
display: grid; |
|
grid-template-columns: repeat(auto-fit, minmax(2rem, 1fr)); |
|
gap: 0.15rem; |
|
|
|
.analysis-item { |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
padding: 0.15rem; |
|
background: rgba(255, 255, 255, 0.05); |
|
border-radius: 0.06rem; |
|
|
|
.analysis-label { |
|
font-size: 0.13rem; |
|
color: #ffffff; |
|
opacity: 0.7; |
|
margin-bottom: 0.08rem; |
|
} |
|
|
|
.analysis-value { |
|
font-size: 0.18rem; |
|
font-weight: bold; |
|
margin-bottom: 0.05rem; |
|
|
|
&.up { |
|
color: #91CC75; |
|
} |
|
|
|
&.down { |
|
color: #EE6666; |
|
} |
|
} |
|
|
|
.analysis-percentage { |
|
font-size: 0.12rem; |
|
|
|
&.up { |
|
color: #91CC75; |
|
} |
|
|
|
&.down { |
|
color: #EE6666; |
|
} |
|
} |
|
} |
|
} |
|
|
|
.analysis-hint { |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
padding: 0.3rem; |
|
color: #ffffff; |
|
opacity: 0.6; |
|
|
|
.hint-icon { |
|
margin-right: 0.1rem; |
|
font-size: 0.18rem; |
|
width: 0.18rem; |
|
height: 0.18rem; |
|
fill: currentColor; |
|
} |
|
} |
|
} |
|
|
|
.warning-energy-analysis { |
|
background: rgba(255, 255, 255, 0.03); |
|
border-radius: 0.08rem; |
|
padding: 0.2rem; |
|
|
|
.section-header { |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
margin-bottom: 0.2rem; |
|
|
|
.section-title { |
|
font-size: 0.15rem; |
|
color: #ffffff; |
|
font-weight: bold; |
|
padding-left: 0.12rem; |
|
border-left: 0.04rem solid #15e1fd; |
|
} |
|
|
|
.section-actions { |
|
::v-deep .custom-select { |
|
.el-input__wrapper { |
|
background: rgba(255, 255, 255, 0.1); |
|
border: 1px solid rgba(255, 255, 255, 0.2); |
|
|
|
.el-input__inner { |
|
color: #ffffff; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
.warning-timeline-chart { |
|
.timeline-header { |
|
display: flex; |
|
gap: 0.3rem; |
|
padding: 0.15rem; |
|
background: rgba(255, 255, 255, 0.05); |
|
border-radius: 0.06rem; |
|
margin-bottom: 0.2rem; |
|
|
|
.header-item { |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
flex: 1; |
|
|
|
.label { |
|
font-size: 0.12rem; |
|
color: #ffffff; |
|
opacity: 0.7; |
|
margin-bottom: 0.05rem; |
|
} |
|
|
|
.value { |
|
font-size: 0.18rem; |
|
font-weight: bold; |
|
color: #15e1fd; |
|
|
|
&.warning-impact { |
|
color: #EE6666; |
|
} |
|
} |
|
} |
|
} |
|
|
|
.timeline-chart { |
|
height: 3.5rem; |
|
} |
|
} |
|
|
|
.warning-impact-table { |
|
margin-top: 0.2rem; |
|
|
|
.table-header { |
|
margin-bottom: 0.15rem; |
|
|
|
.table-title { |
|
font-size: 0.14rem; |
|
color: #ffffff; |
|
font-weight: bold; |
|
} |
|
} |
|
|
|
.table-container { |
|
overflow-x: auto; |
|
border-radius: 0.04rem; |
|
background: rgba(255, 255, 255, 0.02); |
|
|
|
.impact-table { |
|
width: 100%; |
|
border-collapse: collapse; |
|
min-width: 14rem; |
|
|
|
thead { |
|
position: sticky; |
|
top: 0; |
|
z-index: 10; |
|
|
|
tr { |
|
background: linear-gradient(135deg, rgba(21, 225, 253, 0.1) 0%, rgba(145, 204, 117, 0.1) 100%); |
|
|
|
th { |
|
padding: 0.12rem 0.1rem; |
|
text-align: left; |
|
font-size: 0.13rem; |
|
color: #15e1fd; |
|
font-weight: 600; |
|
border-bottom: 2px solid rgba(21, 225, 253, 0.3); |
|
white-space: nowrap; |
|
|
|
&:first-child { |
|
padding-left: 0.15rem; |
|
border-top-left-radius: 0.04rem; |
|
} |
|
|
|
&:last-child { |
|
padding-right: 0.15rem; |
|
border-top-right-radius: 0.04rem; |
|
} |
|
} |
|
} |
|
} |
|
|
|
tbody { |
|
tr { |
|
transition: all 0.3s ease; |
|
background: rgba(255, 255, 255, 0.02); |
|
|
|
&:nth-child(even) { |
|
background: rgba(255, 255, 255, 0.04); |
|
} |
|
|
|
&:hover { |
|
background: rgba(21, 225, 253, 0.1); |
|
transform: translateX(0.02rem); |
|
} |
|
|
|
td { |
|
padding: 0.12rem 0.1rem; |
|
font-size: 0.12rem; |
|
color: #ffffff; |
|
border-bottom: 1px solid rgba(255, 255, 255, 0.08); |
|
vertical-align: middle; |
|
|
|
&:first-child { |
|
padding-left: 0.15rem; |
|
} |
|
|
|
&:last-child { |
|
padding-right: 0.15rem; |
|
} |
|
|
|
&.energy-loss { |
|
color: #EE6666; |
|
} |
|
|
|
&.energy-save { |
|
color: #91CC75; |
|
} |
|
|
|
&.water-up { |
|
color: #4facfe; |
|
} |
|
|
|
&.water-down { |
|
color: #EE6666; |
|
} |
|
|
|
&.saving-drop { |
|
color: #EE6666; |
|
} |
|
|
|
&.saving-rise { |
|
color: #91CC75; |
|
} |
|
|
|
.title-cell { |
|
max-width: 2rem; |
|
overflow: hidden; |
|
text-overflow: ellipsis; |
|
white-space: nowrap; |
|
cursor: pointer; |
|
|
|
&:hover { |
|
color: #15e1fd; |
|
} |
|
} |
|
|
|
.level-badge { |
|
display: inline-block; |
|
padding: 0.03rem 0.1rem; |
|
border-radius: 0.03rem; |
|
font-size: 0.11rem; |
|
font-weight: 500; |
|
|
|
&.critical { |
|
background: rgba(238, 102, 102, 0.2); |
|
color: #EE6666; |
|
border: 1px solid rgba(238, 102, 102, 0.4); |
|
box-shadow: 0 0.04rem 0.08rem rgba(238, 102, 102, 0.2); |
|
} |
|
|
|
&.major { |
|
background: rgba(250, 200, 88, 0.2); |
|
color: #FAC858; |
|
border: 1px solid rgba(250, 200, 88, 0.4); |
|
box-shadow: 0 0.04rem 0.08rem rgba(250, 200, 88, 0.2); |
|
} |
|
|
|
&.minor { |
|
background: rgba(145, 204, 117, 0.2); |
|
color: #91CC75; |
|
border: 1px solid rgba(145, 204, 117, 0.4); |
|
box-shadow: 0 0.04rem 0.08rem rgba(145, 204, 117, 0.2); |
|
} |
|
} |
|
|
|
.status-badge { |
|
display: inline-block; |
|
padding: 0.03rem 0.1rem; |
|
border-radius: 0.03rem; |
|
font-size: 0.11rem; |
|
font-weight: 500; |
|
|
|
&.pending { |
|
background: rgba(238, 102, 102, 0.2); |
|
color: #EE6666; |
|
border: 1px solid rgba(238, 102, 102, 0.4); |
|
} |
|
|
|
&.processing { |
|
background: rgba(250, 200, 88, 0.2); |
|
color: #FAC858; |
|
border: 1px solid rgba(250, 200, 88, 0.4); |
|
} |
|
|
|
&.resolved { |
|
background: rgba(145, 204, 117, 0.2); |
|
color: #91CC75; |
|
border: 1px solid rgba(145, 204, 117, 0.4); |
|
} |
|
} |
|
|
|
.action-buttons { |
|
display: flex; |
|
gap: 0.06rem; |
|
|
|
.action-btn { |
|
font-size: 0.11rem; |
|
padding: 0.04rem 0.1rem; |
|
} |
|
|
|
.action-dropdown { |
|
::v-deep .el-dropdown-menu.custom-dropdown-menu { |
|
background: rgba(30, 30, 50, 0.95); |
|
border: 1px solid rgba(21, 225, 253, 0.3); |
|
|
|
.el-dropdown-menu__item { |
|
color: #ffffff; |
|
|
|
&:hover { |
|
background: rgba(21, 225, 253, 0.1); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
::v-deep .custom-dialog { |
|
.el-dialog { |
|
background: rgba(30, 30, 50, 0.95); |
|
border: 1px solid rgba(21, 225, 253, 0.3); |
|
} |
|
|
|
.el-dialog__header { |
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1); |
|
} |
|
|
|
.el-dialog__title { |
|
color: #ffffff; |
|
} |
|
|
|
.el-dialog__body { |
|
color: #ffffff; |
|
} |
|
|
|
.custom-btn { |
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|
border: none; |
|
color: #ffffff; |
|
} |
|
} |
|
|
|
.warning-detail-content { |
|
.detail-section { |
|
margin-bottom: 0.3rem; |
|
|
|
.section-title { |
|
font-size: 0.14rem; |
|
color: #ffffff; |
|
font-weight: bold; |
|
padding-left: 0.1rem; |
|
border-left: 0.03rem solid #15e1fd; |
|
margin-bottom: 0.15rem; |
|
} |
|
|
|
.info-grid { |
|
display: grid; |
|
grid-template-columns: repeat(2, 1fr); |
|
gap: 0.15rem; |
|
|
|
.info-item { |
|
display: flex; |
|
align-items: center; |
|
padding: 0.1rem; |
|
background: rgba(255, 255, 255, 0.03); |
|
border-radius: 0.04rem; |
|
|
|
&.full-width { |
|
grid-column: span 2; |
|
} |
|
|
|
.item-label { |
|
font-size: 0.12rem; |
|
color: #ffffff; |
|
opacity: 0.7; |
|
margin-right: 0.1rem; |
|
min-width: 0.8rem; |
|
} |
|
|
|
.item-value { |
|
font-size: 0.13rem; |
|
color: #ffffff; |
|
flex: 1; |
|
|
|
&.level-badge { |
|
display: inline-block; |
|
padding: 0.03rem 0.1rem; |
|
border-radius: 0.03rem; |
|
font-size: 0.11rem; |
|
font-weight: 500; |
|
|
|
&.critical { |
|
background: rgba(238, 102, 102, 0.2); |
|
color: #EE6666; |
|
} |
|
|
|
&.major { |
|
background: rgba(250, 200, 88, 0.2); |
|
color: #FAC858; |
|
} |
|
|
|
&.minor { |
|
background: rgba(145, 204, 117, 0.2); |
|
color: #91CC75; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
.impact-cards { |
|
display: grid; |
|
grid-template-columns: repeat(4, 1fr); |
|
gap: 0.15rem; |
|
|
|
.impact-card { |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
padding: 0.2rem; |
|
background: rgba(255, 255, 255, 0.03); |
|
border-radius: 0.06rem; |
|
|
|
.card-label { |
|
font-size: 0.12rem; |
|
color: #ffffff; |
|
opacity: 0.7; |
|
margin-bottom: 0.1rem; |
|
} |
|
|
|
.card-value { |
|
font-size: 0.2rem; |
|
font-weight: bold; |
|
margin-bottom: 0.05rem; |
|
|
|
&.energy-impact { |
|
color: #EE6666; |
|
} |
|
|
|
&.water-impact { |
|
color: #4facfe; |
|
} |
|
|
|
&.saving-impact { |
|
color: #EE6666; |
|
} |
|
|
|
&.cost-impact { |
|
color: #FAC858; |
|
} |
|
} |
|
|
|
.card-desc { |
|
font-size: 0.11rem; |
|
color: #ffffff; |
|
opacity: 0.6; |
|
} |
|
} |
|
} |
|
} |
|
|
|
.energy-comparison-chart { |
|
height: 3rem; |
|
} |
|
} |
|
|
|
@media (max-width: 1485px) { |
|
.indicator-cards { |
|
grid-template-columns: repeat(auto-fit, minmax(2rem, 1fr)); |
|
} |
|
|
|
.analysis-content { |
|
grid-template-columns: repeat(2, 1fr); |
|
} |
|
|
|
.impact-cards { |
|
grid-template-columns: repeat(2, 1fr); |
|
} |
|
} |
|
|
|
@media (max-width: 768px) { |
|
.indicator-cards { |
|
grid-template-columns: 1fr; |
|
} |
|
|
|
.analysis-content { |
|
grid-template-columns: 1fr; |
|
} |
|
|
|
.impact-cards { |
|
grid-template-columns: 1fr; |
|
} |
|
|
|
.info-grid { |
|
grid-template-columns: 1fr; |
|
} |
|
} |
|
</style>
|
|
|