|
|
|
|
@ -1,507 +1,365 @@
|
|
|
|
|
<template>
|
|
|
|
|
|
|
|
|
|
<div class="board-wrap">
|
|
|
|
|
|
|
|
|
|
<div class="bg">
|
|
|
|
|
|
|
|
|
|
<div class="header">
|
|
|
|
|
|
|
|
|
|
<div class="title">车间能源看板</div>
|
|
|
|
|
|
|
|
|
|
<div class="toolbar">
|
|
|
|
|
<el-select v-model="typeData" size="mini" @change="getData" class="type-select">
|
|
|
|
|
<el-option v-for="item in energyOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="time">{{ clockText }}</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="content">
|
|
|
|
|
<div class="panel trend-panel">
|
|
|
|
|
<div class="panel-title">近24小时{{ currentTypeMeta.label }}耗量曲线</div>
|
|
|
|
|
<Chart class="trend-chart" ref="trendChart"></Chart>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="columns">
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
class="energy-col"
|
|
|
|
|
:class="{
|
|
|
|
|
'power-col': String(col.monitorType) === '2',
|
|
|
|
|
'steam-col': String(col.monitorType) === '4'
|
|
|
|
|
}"
|
|
|
|
|
v-for="col in columns"
|
|
|
|
|
:key="col.monitorType"
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
<div class="col-head">
|
|
|
|
|
|
|
|
|
|
<div class="energy-name">{{ col.name }}</div>
|
|
|
|
|
|
|
|
|
|
<div class="panel data-panel" ref="dataPanel">
|
|
|
|
|
<div class="col-head" ref="colHead">
|
|
|
|
|
<div class="energy-name">{{ column.name || currentTypeMeta.label }}</div>
|
|
|
|
|
<div class="today">
|
|
|
|
|
|
|
|
|
|
当日能耗:
|
|
|
|
|
|
|
|
|
|
<span class="num">{{ formatNumber(col.todayConsumption) }}</span>
|
|
|
|
|
|
|
|
|
|
<span class="unit">{{ col.todayUnit }}</span>
|
|
|
|
|
|
|
|
|
|
<span class="num">{{ formatNumber(column.todayConsumption) }}</span>
|
|
|
|
|
<span class="unit">{{ column.todayUnit || currentTypeMeta.unit }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="table-head">
|
|
|
|
|
|
|
|
|
|
<div class="table-head" ref="tableHead">
|
|
|
|
|
<span>计量设备</span>
|
|
|
|
|
|
|
|
|
|
<span>{{ String(col.monitorType) === '2' ? '电流电压' : '实时数据' }}</span>
|
|
|
|
|
|
|
|
|
|
<span>{{ typeData === '2' ? '实时数据' : '实时数据' }}</span>
|
|
|
|
|
<span>当日耗量</span>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="rows">
|
|
|
|
|
|
|
|
|
|
<div class="row" v-for="row in col.rows" :key="col.monitorType + '-' + rowKey(row)">
|
|
|
|
|
|
|
|
|
|
<div class="row" v-for="row in pagedRows" :key="typeData + '-' + rowKey(row)">
|
|
|
|
|
<span :title="row.monitorName">{{ row.monitorName || row.monitorCode }}</span>
|
|
|
|
|
|
|
|
|
|
<span class="realtime">{{ displayRealtime(row) }}</span>
|
|
|
|
|
|
|
|
|
|
<span>{{ formatNumber(rowTodayVal(row)) }} {{ col.todayUnit }}</span>
|
|
|
|
|
|
|
|
|
|
<span>{{ formatNumber(rowTodayVal(row)) }} {{ column.todayUnit || currentTypeMeta.unit }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="empty" v-if="!col.rows || col.rows.length === 0">暂无数据</div>
|
|
|
|
|
|
|
|
|
|
<div class="empty" v-if="totalRows === 0">暂无数据</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="pager-wrap" v-if="totalRows > pageSize">
|
|
|
|
|
<el-pagination
|
|
|
|
|
:current-page.sync="currentPage"
|
|
|
|
|
:page-size="pageSize"
|
|
|
|
|
layout="prev, pager, next"
|
|
|
|
|
:total="totalRows"
|
|
|
|
|
small
|
|
|
|
|
@current-change="onPageChange"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
|
|
|
|
import { workshopColumns } from '@/api/board'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import Chart from '@/components/Charts/Chart.vue'
|
|
|
|
|
import { workshopEnergyBoard } from '@/api/board'
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
|
|
|
|
name: 'WorkshopIndex',
|
|
|
|
|
|
|
|
|
|
components: { Chart },
|
|
|
|
|
data() {
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
|
|
clockText: '',
|
|
|
|
|
|
|
|
|
|
timer: null,
|
|
|
|
|
|
|
|
|
|
dataTimer: null,
|
|
|
|
|
|
|
|
|
|
columns: []
|
|
|
|
|
|
|
|
|
|
typeData: '2',
|
|
|
|
|
energyOptions: [
|
|
|
|
|
{ label: '电', value: '2', unit: 'kWh' },
|
|
|
|
|
{ label: '水', value: '3', unit: 'm³' },
|
|
|
|
|
{ label: '蒸汽', value: '4', unit: 't' },
|
|
|
|
|
{ label: '压缩空气', value: '5', unit: 'm³' },
|
|
|
|
|
{ label: '氮气', value: '6', unit: 'm³' }
|
|
|
|
|
],
|
|
|
|
|
column: { rows: [] },
|
|
|
|
|
trend24h: [],
|
|
|
|
|
currentPage: 1,
|
|
|
|
|
pageSize: 8,
|
|
|
|
|
dataReqSeq: 0
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
currentTypeMeta() {
|
|
|
|
|
return this.energyOptions.find(v => v.value === this.typeData) || this.energyOptions[0]
|
|
|
|
|
},
|
|
|
|
|
totalRows() {
|
|
|
|
|
return (this.column.rows || []).length
|
|
|
|
|
},
|
|
|
|
|
pagedRows() {
|
|
|
|
|
const rows = this.column.rows || []
|
|
|
|
|
const start = (this.currentPage - 1) * this.pageSize
|
|
|
|
|
return rows.slice(start, start + this.pageSize)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
mounted() {
|
|
|
|
|
|
|
|
|
|
this.tickClock()
|
|
|
|
|
|
|
|
|
|
this.timer = setInterval(this.tickClock, 1000)
|
|
|
|
|
|
|
|
|
|
this.getData()
|
|
|
|
|
|
|
|
|
|
this.dataTimer = setInterval(this.getData, 2 * 60 * 1000)
|
|
|
|
|
|
|
|
|
|
window.addEventListener('resize', this.updatePageSize)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
beforeDestroy() {
|
|
|
|
|
|
|
|
|
|
if (this.timer) clearInterval(this.timer)
|
|
|
|
|
|
|
|
|
|
if (this.dataTimer) clearInterval(this.dataTimer)
|
|
|
|
|
|
|
|
|
|
window.removeEventListener('resize', this.updatePageSize)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
|
|
|
|
tickClock() {
|
|
|
|
|
|
|
|
|
|
const d = new Date()
|
|
|
|
|
|
|
|
|
|
const pad = n => (n < 10 ? '0' + n : '' + n)
|
|
|
|
|
|
|
|
|
|
this.clockText = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getData() {
|
|
|
|
|
|
|
|
|
|
workshopColumns().then(res => {
|
|
|
|
|
|
|
|
|
|
this.columns = (res.data && res.data.columns) || []
|
|
|
|
|
|
|
|
|
|
const reqSeq = ++this.dataReqSeq
|
|
|
|
|
const requestType = this.typeData
|
|
|
|
|
this.trend24h = []
|
|
|
|
|
this.$nextTick(() => this.renderTrendChart())
|
|
|
|
|
workshopEnergyBoard({ monitorType: requestType }).then(res => {
|
|
|
|
|
if (reqSeq !== this.dataReqSeq || requestType !== this.typeData) return
|
|
|
|
|
this.column = (res.data && (res.data.column || (res.data.columns || [])[0])) || { rows: [] }
|
|
|
|
|
this.currentPage = 1
|
|
|
|
|
const rawTrend = (res.data && res.data.trend24h) || []
|
|
|
|
|
const monitorCodeSet = new Set((this.column.rows || []).map(v => String(v.monitorCode || '')))
|
|
|
|
|
const filteredTrend = rawTrend.filter(v => monitorCodeSet.has(String(v.monitorCode || '')))
|
|
|
|
|
this.trend24h = filteredTrend.length > 0 ? filteredTrend : rawTrend
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.updatePageSize()
|
|
|
|
|
this.renderTrendChart()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
updatePageSize() {
|
|
|
|
|
this.pageSize = 8
|
|
|
|
|
const maxPage = Math.max(1, Math.ceil(this.totalRows / this.pageSize))
|
|
|
|
|
if (this.currentPage > maxPage) {
|
|
|
|
|
this.currentPage = maxPage
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
renderTrendChart() {
|
|
|
|
|
if (!this.$refs.trendChart) return
|
|
|
|
|
const normalized = this.normalizeTrend(this.trend24h || [])
|
|
|
|
|
const xData = normalized.xData
|
|
|
|
|
const series = normalized.series
|
|
|
|
|
const safeSeries = series.length > 0
|
|
|
|
|
? series
|
|
|
|
|
: [{
|
|
|
|
|
name: `${this.currentTypeMeta.label}耗量`,
|
|
|
|
|
type: 'line',
|
|
|
|
|
smooth: true,
|
|
|
|
|
showSymbol: false,
|
|
|
|
|
data: (xData || []).map(() => 0)
|
|
|
|
|
}]
|
|
|
|
|
const safeXData = xData.length > 0 ? xData : this.buildRecentHourLabels()
|
|
|
|
|
this.$refs.trendChart.setData({
|
|
|
|
|
grid: { left: '4%', right: '3%', top: '16%', bottom: '10%', containLabel: true },
|
|
|
|
|
tooltip: { trigger: 'axis' },
|
|
|
|
|
legend: {
|
|
|
|
|
type: 'scroll',
|
|
|
|
|
top: 0,
|
|
|
|
|
textStyle: { color: '#bcdfff', fontSize: 11 }
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
type: 'category',
|
|
|
|
|
data: safeXData,
|
|
|
|
|
axisLabel: { color: '#cde7ff', interval: 2, fontSize: 10 },
|
|
|
|
|
axisLine: { lineStyle: { color: 'rgba(145,198,255,0.4)' } }
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
|
|
|
|
type: 'value',
|
|
|
|
|
name: `单位(${this.column.todayUnit || this.currentTypeMeta.unit})`,
|
|
|
|
|
nameTextStyle: { color: '#9fc4e8' },
|
|
|
|
|
axisLabel: { color: '#cde7ff' },
|
|
|
|
|
splitLine: { lineStyle: { color: 'rgba(145,198,255,0.2)', type: 'dashed' } }
|
|
|
|
|
},
|
|
|
|
|
series: safeSeries
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
onPageChange(page) {
|
|
|
|
|
this.currentPage = page
|
|
|
|
|
},
|
|
|
|
|
normalizeTrend(rawTrend) {
|
|
|
|
|
const first = rawTrend[0]
|
|
|
|
|
const isDeviceSeries = first && (Array.isArray(first.points) || Array.isArray(first.data))
|
|
|
|
|
if (isDeviceSeries) {
|
|
|
|
|
const series = []
|
|
|
|
|
let xData = []
|
|
|
|
|
rawTrend.forEach((device, index) => {
|
|
|
|
|
const points = Array.isArray(device.points) ? device.points : (Array.isArray(device.data) ? device.data : [])
|
|
|
|
|
const currentXData = points.map(v => v.time || v.timeKey || '')
|
|
|
|
|
if (currentXData.length > xData.length) {
|
|
|
|
|
xData = currentXData
|
|
|
|
|
}
|
|
|
|
|
series.push({
|
|
|
|
|
name: device.monitorName || device.monitorCode || `设备${index + 1}`,
|
|
|
|
|
type: 'line',
|
|
|
|
|
smooth: true,
|
|
|
|
|
showSymbol: false,
|
|
|
|
|
data: points.map(v => this.toChartNumber(v.expend))
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
return { xData, series }
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
xData: rawTrend.map(v => v.time || v.timeKey || ''),
|
|
|
|
|
series: [{
|
|
|
|
|
name: `${this.currentTypeMeta.label}耗量`,
|
|
|
|
|
type: 'line',
|
|
|
|
|
smooth: true,
|
|
|
|
|
showSymbol: false,
|
|
|
|
|
data: rawTrend.map(v => this.toChartNumber(v.expend))
|
|
|
|
|
}]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
buildRecentHourLabels() {
|
|
|
|
|
const list = []
|
|
|
|
|
const now = new Date()
|
|
|
|
|
for (let i = 23; i >= 0; i--) {
|
|
|
|
|
const d = new Date(now.getTime() - i * 60 * 60 * 1000)
|
|
|
|
|
const m = d.getMonth() + 1
|
|
|
|
|
const day = d.getDate()
|
|
|
|
|
const h = d.getHours()
|
|
|
|
|
const mm = m < 10 ? `0${m}` : `${m}`
|
|
|
|
|
const dd = day < 10 ? `0${day}` : `${day}`
|
|
|
|
|
const hh = h < 10 ? `0${h}` : `${h}`
|
|
|
|
|
list.push(`${mm}-${dd} ${hh}:00`)
|
|
|
|
|
}
|
|
|
|
|
return list
|
|
|
|
|
},
|
|
|
|
|
toChartNumber(value) {
|
|
|
|
|
if (value === null || value === undefined || value === '') return 0
|
|
|
|
|
const num = Number(value)
|
|
|
|
|
return Number.isFinite(num) ? num : 0
|
|
|
|
|
},
|
|
|
|
|
rowKey(row) {
|
|
|
|
|
|
|
|
|
|
return row.monitorCode != null ? String(row.monitorCode) : ''
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
rowTodayVal(row) {
|
|
|
|
|
|
|
|
|
|
const v = row.rowTodayConsumption != null ? row.rowTodayConsumption : row.rowtodayconsumption
|
|
|
|
|
|
|
|
|
|
return v
|
|
|
|
|
|
|
|
|
|
return row.rowTodayConsumption != null ? row.rowTodayConsumption : row.rowtodayconsumption
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
displayRealtime(row) {
|
|
|
|
|
|
|
|
|
|
const type = String(row.monitorType != null ? row.monitorType : '')
|
|
|
|
|
|
|
|
|
|
if (type === '2') {
|
|
|
|
|
|
|
|
|
|
const u = this.joinPhases(row, ['vA', 'vB', 'vC'], 'V')
|
|
|
|
|
|
|
|
|
|
const i = this.joinPhases(row, ['iA', 'iB', 'iC'], 'A')
|
|
|
|
|
|
|
|
|
|
if (!u && !i) return '--'
|
|
|
|
|
|
|
|
|
|
if (!u) return i
|
|
|
|
|
|
|
|
|
|
if (!i) return u
|
|
|
|
|
|
|
|
|
|
return `${u} / ${i}`
|
|
|
|
|
|
|
|
|
|
const vA = this.valueText(row, 'vA')
|
|
|
|
|
const iA = this.valueText(row, 'iA')
|
|
|
|
|
const zxyg = this.valueText(row, 'zxyg')
|
|
|
|
|
return `电压A:${vA}V\n电流A:${iA}A\n正向有功:${zxyg}kWh`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const instant = row.instantFlow != null ? row.instantFlow : row.instantflow
|
|
|
|
|
|
|
|
|
|
const cum =
|
|
|
|
|
|
|
|
|
|
row.cumulativeFlow != null
|
|
|
|
|
|
|
|
|
|
? row.cumulativeFlow
|
|
|
|
|
|
|
|
|
|
: row.cumulativeflow != null
|
|
|
|
|
|
|
|
|
|
? row.cumulativeflow
|
|
|
|
|
|
|
|
|
|
: null
|
|
|
|
|
|
|
|
|
|
const cum = row.cumulativeFlow != null ? row.cumulativeFlow : (row.cumulativeflow != null ? row.cumulativeflow : null)
|
|
|
|
|
const instantUnit = row.instantUnit || row.instantunit || ''
|
|
|
|
|
|
|
|
|
|
const unit = row.realtimeUnit || row.realtimeunit || ''
|
|
|
|
|
|
|
|
|
|
const instantNum = this.formatNumber(instant)
|
|
|
|
|
|
|
|
|
|
const num = this.formatNumber(cum)
|
|
|
|
|
|
|
|
|
|
if (instantNum === '--' && num === '--') return '--'
|
|
|
|
|
|
|
|
|
|
const instantText = instantNum === '--' ? '--' : (instantUnit ? `${instantNum} ${instantUnit}` : instantNum)
|
|
|
|
|
|
|
|
|
|
const cumText = num === '--' ? '--' : (unit ? `${num} ${unit}` : num)
|
|
|
|
|
|
|
|
|
|
return `瞬时:${instantText}\n累计:${cumText}`
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
joinPhases(row, keys, suffix) {
|
|
|
|
|
|
|
|
|
|
const parts = []
|
|
|
|
|
|
|
|
|
|
for (const k of keys) {
|
|
|
|
|
|
|
|
|
|
const raw = row[k] != null ? row[k] : row[k.toLowerCase()]
|
|
|
|
|
|
|
|
|
|
if (raw === null || raw === undefined || raw === '') continue
|
|
|
|
|
|
|
|
|
|
const n = Number(raw)
|
|
|
|
|
|
|
|
|
|
if (Number.isNaN(n)) continue
|
|
|
|
|
|
|
|
|
|
parts.push(`${n.toFixed(2)}${suffix}`)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parts.length ? parts.join('/') : ''
|
|
|
|
|
|
|
|
|
|
valueText(row, key) {
|
|
|
|
|
const raw = row[key] != null ? row[key] : row[key.toLowerCase()]
|
|
|
|
|
if (raw === null || raw === undefined || raw === '') return '--'
|
|
|
|
|
const num = Number(raw)
|
|
|
|
|
return Number.isNaN(num) ? '--' : num.toFixed(2)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
formatNumber(val) {
|
|
|
|
|
|
|
|
|
|
if (val === null || val === undefined || val === '') return '--'
|
|
|
|
|
|
|
|
|
|
const num = Number(val)
|
|
|
|
|
|
|
|
|
|
if (Number.isNaN(num)) return '--'
|
|
|
|
|
|
|
|
|
|
return num.toFixed(2)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="less">
|
|
|
|
|
|
|
|
|
|
.board-wrap {
|
|
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.board-wrap { width: 100%; height: 100%; }
|
|
|
|
|
|
|
|
|
|
.bg {
|
|
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
|
|
|
|
|
background: #061223 url('~@/assets/board/bg1.jpg') no-repeat center;
|
|
|
|
|
|
|
|
|
|
background-size: cover;
|
|
|
|
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
|
|
color: #d8ecff;
|
|
|
|
|
|
|
|
|
|
overflow-x: auto;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.header {
|
|
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.title { font-size: 28px; font-weight: 600; letter-spacing: 2px; text-align: center; }
|
|
|
|
|
.time { position: absolute; right: 0; font-size: 14px; color: #9fc4e8; }
|
|
|
|
|
.toolbar { position: absolute; left: 0; }
|
|
|
|
|
|
|
|
|
|
.type-select /deep/ .el-input__inner {
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.25);
|
|
|
|
|
border: 1px solid rgba(120, 180, 255, 0.45);
|
|
|
|
|
color: #d8ecff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.title {
|
|
|
|
|
.content {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 58% 42%;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
height: calc(100vh - 84px);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
font-size: 28px;
|
|
|
|
|
.panel {
|
|
|
|
|
background: linear-gradient(180deg, rgba(8, 30, 56, 0.9), rgba(4, 21, 42, 0.86));
|
|
|
|
|
border: 1px solid rgba(120, 180, 255, 0.28);
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
.trend-panel { padding: 10px; }
|
|
|
|
|
.panel-title { color: #9ec6ef; font-size: 15px; margin-bottom: 8px; }
|
|
|
|
|
.panel-subtitle { color: #6fa4d8; font-size: 12px; margin-top: -4px; margin-bottom: 6px; }
|
|
|
|
|
.trend-chart { width: 100%; height: calc(100% - 28px); min-height: 300px; }
|
|
|
|
|
|
|
|
|
|
letter-spacing: 2px;
|
|
|
|
|
.data-panel { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }
|
|
|
|
|
.col-head { padding: 10px; border-bottom: 1px solid rgba(120, 180, 255, 0.22); text-align: center; }
|
|
|
|
|
.energy-name { font-size: 18px; font-weight: 600; margin-bottom: 4px; }
|
|
|
|
|
.today { font-size: 13px; color: #9ec6ef; }
|
|
|
|
|
.today .num { color: #ffd166; font-weight: 600; }
|
|
|
|
|
|
|
|
|
|
.table-head,
|
|
|
|
|
.row {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 1.3fr 1.3fr 0.8fr;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
padding: 8px 10px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.time {
|
|
|
|
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
|
|
|
|
right: 0;
|
|
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
|
|
|
|
color: #9fc4e8;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.columns {
|
|
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
|
|
|
|
min-width: 1500px;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.energy-col {
|
|
|
|
|
|
|
|
|
|
width: calc((100% - 40px) / 5);
|
|
|
|
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
|
|
|
|
background: rgba(7, 24, 45, 0.82);
|
|
|
|
|
|
|
|
|
|
border: 1px solid rgba(120, 180, 255, 0.25);
|
|
|
|
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
|
|
|
|
min-height: calc(100vh - 96px);
|
|
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.col-head {
|
|
|
|
|
|
|
|
|
|
padding: 10px 10px 8px;
|
|
|
|
|
|
|
|
|
|
border-bottom: 1px solid rgba(120, 180, 255, 0.22);
|
|
|
|
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.energy-name {
|
|
|
|
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.today {
|
|
|
|
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
|
|
|
|
color: #9ec6ef;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.today .num {
|
|
|
|
|
|
|
|
|
|
color: #ffd166;
|
|
|
|
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.table-head {
|
|
|
|
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
|
|
|
|
grid-template-columns: 1.45fr 1.05fr 0.7fr;
|
|
|
|
|
|
|
|
|
|
gap: 6px;
|
|
|
|
|
|
|
|
|
|
padding: 8px 10px;
|
|
|
|
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
|
|
|
|
color: #7faad5;
|
|
|
|
|
|
|
|
|
|
border-bottom: 1px solid rgba(120, 180, 255, 0.18);
|
|
|
|
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.rows {
|
|
|
|
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
|
|
|
overflow: auto;
|
|
|
|
|
|
|
|
|
|
.rows { flex: 1; min-height: 0; overflow: hidden; }
|
|
|
|
|
.row { border-bottom: 1px dashed rgba(120, 180, 255, 0.12); }
|
|
|
|
|
.row span:first-child { white-space: normal; word-break: break-all; line-height: 1.35; }
|
|
|
|
|
.realtime { white-space: pre-line; word-break: break-all; line-height: 1.2; font-size: 11px; }
|
|
|
|
|
.empty { padding: 12px 10px; color: #7098c2; font-size: 12px; text-align: center; }
|
|
|
|
|
.pager-wrap { padding: 4px 10px; display: flex; justify-content: center; border-top: 1px solid rgba(120, 180, 255, 0.12); }
|
|
|
|
|
.pager-wrap /deep/ .el-pagination button,
|
|
|
|
|
.pager-wrap /deep/ .el-pager li {
|
|
|
|
|
background: transparent;
|
|
|
|
|
color: #9ec6ef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.row {
|
|
|
|
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
|
|
|
|
grid-template-columns: 1.45fr 1.05fr 0.7fr;
|
|
|
|
|
|
|
|
|
|
gap: 6px;
|
|
|
|
|
|
|
|
|
|
padding: 8px 10px;
|
|
|
|
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
|
|
|
|
border-bottom: 1px dashed rgba(120, 180, 255, 0.12);
|
|
|
|
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.row span:first-child {
|
|
|
|
|
white-space: normal;
|
|
|
|
|
word-break: break-all;
|
|
|
|
|
line-height: 1.35;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.row .realtime {
|
|
|
|
|
white-space: pre-line;
|
|
|
|
|
word-break: break-all;
|
|
|
|
|
line-height: 1.2;
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.power-col .table-head,
|
|
|
|
|
.power-col .row {
|
|
|
|
|
grid-template-columns: 1fr 1.15fr 0.85fr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.steam-col .table-head,
|
|
|
|
|
.steam-col .row {
|
|
|
|
|
grid-template-columns: 1.75fr 0.95fr 0.65fr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.empty {
|
|
|
|
|
|
|
|
|
|
padding: 12px 10px;
|
|
|
|
|
|
|
|
|
|
color: #7098c2;
|
|
|
|
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pager-wrap /deep/ .el-pager li.active { color: #ffd166; }
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|