| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>能耗监控大屏</title>
- <style>
- * { box-sizing: border-box; }
- body {
- margin: 0;
- width: 100vw;
- height: 100vh;
- overflow: hidden;
- color: #e9f7ff;
- font-family: "Microsoft YaHei", Arial, sans-serif;
- background: #07121f;
- }
- .screen {
- width: 100vw;
- height: 100vh;
- padding: 18px 22px;
- display: grid;
- grid-template-rows: 74px 118px 280px 1fr;
- gap: 14px;
- background: linear-gradient(135deg, #07121f 0%, #102234 48%, #081522 100%);
- }
- .header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- border-bottom: 1px solid rgba(108, 214, 255, .28);
- }
- .title { font-size: 30px; font-weight: 700; letter-spacing: 0; }
- .time { text-align: right; color: #9fd8ff; font-size: 16px; line-height: 26px; }
- .summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
- .metric, .panel, .device-card {
- border: 1px solid rgba(95, 201, 255, .28);
- background: rgba(7, 25, 41, .76);
- box-shadow: inset 0 0 22px rgba(49, 163, 220, .08);
- border-radius: 6px;
- }
- .metric { padding: 14px 20px; display: flex; flex-direction: column; justify-content: center; }
- .metric-label { color: #9fb6c7; font-size: 15px; }
- .metric-value { margin-top: 6px; font-size: 32px; font-weight: 700; color: #44e0c2; }
- .metric-unit { margin-left: 6px; font-size: 16px; color: #a8cfe7; }
- .metric-sub { margin-top: 6px; color: #8fb3ca; font-size: 14px; }
- .metric-sub strong { color: #79d9ff; font-size: 16px; }
- .main { min-height: 0; }
- .device-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; min-height: 0; }
- .device-card { padding: 16px; min-height: 0; }
- .device-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
- .device-name { font-size: 20px; font-weight: 700; }
- .badge { padding: 4px 10px; border-radius: 4px; font-size: 13px; background: rgba(68, 224, 194, .18); color: #44e0c2; }
- .badge.offline { background: rgba(255, 103, 103, .14); color: #ff8686; }
- .device-sn { margin-left: 10px; color: #8fb3ca; font-size: 13px; font-weight: 400; }
- .kv-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
- .kv { padding: 10px; border-radius: 4px; background: rgba(255,255,255,.04); }
- .kv span { display: block; color: #92a9bb; font-size: 13px; margin-bottom: 5px; }
- .kv strong {
- display: block;
- width: 100%;
- font-size: 20px;
- color: #ffffff;
- line-height: 1.25;
- white-space: normal;
- overflow-wrap: anywhere;
- }
- .kv strong.small { font-size: 16px; }
- .chart-wrap { display: grid; grid-template-columns: 1fr 1.2fr 0.8fr; gap: 14px; min-height: 0; }
- .panel { min-height: 0; padding: 14px; display: flex; flex-direction: column; }
- .panel-title { height: 30px; line-height: 30px; font-size: 18px; font-weight: 700; color: #79d9ff; }
- .chart { flex: 1; min-height: 0; }
- </style>
- </head>
- <body>
- <div class="screen">
- <div class="header">
- <div class="title">能源消耗监控大屏</div>
- <div class="time"><div id="dateText">--</div><div id="timeText">--</div></div>
- </div>
- <div class="summary">
- <div class="metric"><div class="metric-label" id="meter1PowerLabel">电表1 当前功率</div><div class="metric-value"><span id="meter1Power">0</span><span class="metric-unit">kW</span></div></div>
- <div class="metric">
- <div class="metric-label" id="meter1EnergyLabel">电表1 今日用电</div>
- <div class="metric-value"><span id="meter1Energy">0</span><span class="metric-unit">kWh</span></div>
- <div class="metric-sub">本月 <strong><span id="meter1MonthEnergy">0</span></strong> kWh</div>
- </div>
- <div class="metric"><div class="metric-label" id="meter2PowerLabel">电表2 当前功率</div><div class="metric-value"><span id="meter2Power">0</span><span class="metric-unit">kW</span></div></div>
- <div class="metric">
- <div class="metric-label" id="meter2EnergyLabel">电表2 今日用电</div>
- <div class="metric-value"><span id="meter2Energy">0</span><span class="metric-unit">kWh</span></div>
- <div class="metric-sub">本月 <strong><span id="meter2MonthEnergy">0</span></strong> kWh</div>
- </div>
- </div>
- <div class="main">
- <div class="device-list" id="deviceList"></div>
- </div>
- <div class="chart-wrap">
- <div class="panel"><div class="panel-title">今日累计用电趋势</div><div id="trendChart" class="chart"></div></div>
- <div class="panel"><div class="panel-title">本月每日用电</div><div id="monthChart" class="chart"></div></div>
- <div class="panel"><div class="panel-title">实时功率对比</div><div id="powerChart" class="chart"></div></div>
- </div>
- </div>
- <script src="${ctxStatic}/jquery-1.11.3.min.js"></script>
- <script src="${ctxStatic}/echarts/4.2/echarts.min.js"></script>
- <script>
- var trendChart = echarts.init(document.getElementById('trendChart'));
- var monthChart = echarts.init(document.getElementById('monthChart'));
- var powerChart = echarts.init(document.getElementById('powerChart'));
- function fmt(value) {
- var num = Number(value || 0);
- return Number.isFinite(num) ? num.toFixed(2) : '0.00';
- }
- function deviceTitle(device, index) {
- return device.deviceName || device.deviceSn || ('电表' + (index + 1));
- }
- function formatTime(value) {
- if (!value) {
- return '-';
- }
- if (typeof value === 'string') {
- return value.replace('T', ' ').replace(/\.\d+.*$/, '');
- }
- return value;
- }
- function updateClock() {
- var now = new Date();
- $('#dateText').text(now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0'));
- $('#timeText').text(String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') + ':' + String(now.getSeconds()).padStart(2, '0'));
- }
- function renderDevices(devices) {
- var html = '';
- devices.forEach(function (d, index) {
- var title = deviceTitle(d, index);
- html += '<div class="device-card">' +
- '<div class="device-head"><div class="device-name">' + title + '<span class="device-sn">' + (d.deviceSn || '-') + '</span></div>' +
- '<div class="badge ' + (d.online ? '' : 'offline') + '">' + (d.online ? '在线' : '离线') + '</div></div>' +
- '<div class="kv-grid">' +
- '<div class="kv"><span>当前功率</span><strong>' + fmt(d.power) + ' kW</strong></div>' +
- '<div class="kv"><span>今日用电</span><strong>' + fmt(d.todayEnergy) + ' kWh</strong></div>' +
- '<div class="kv"><span>本月用电</span><strong>' + fmt(d.monthEnergy) + ' kWh</strong></div>' +
- '<div class="kv"><span>A/B/C电压</span><strong class="small">' + fmt(d.ua) + ' / ' + fmt(d.ub) + ' / ' + fmt(d.uc) + ' V</strong></div>' +
- '<div class="kv"><span>A/B/C电流</span><strong class="small">' + fmt(d.ia) + ' / ' + fmt(d.ib) + ' / ' + fmt(d.ic) + ' A</strong></div>' +
- '<div class="kv"><span>上报时间</span><strong class="small">' + formatTime(d.reportTimeText || d.reportTime) + '</strong></div>' +
- '</div></div>';
- });
- $('#deviceList').html(html || '<div class="device-card"><div class="device-name">暂无电表数据</div></div>');
- }
- function renderTopMeters(devices) {
- for (var i = 0; i < 2; i++) {
- var device = devices[i] || {};
- var title = deviceTitle(device, i);
- $('#meter' + (i + 1) + 'PowerLabel').text(title + ' 当前功率');
- $('#meter' + (i + 1) + 'EnergyLabel').text(title + ' 今日用电');
- $('#meter' + (i + 1) + 'Power').text(fmt(device.power));
- $('#meter' + (i + 1) + 'Energy').text(fmt(device.todayEnergy));
- $('#meter' + (i + 1) + 'MonthEnergy').text(fmt(device.monthEnergy));
- }
- }
- function renderCharts(data) {
- var devices = data.devices || [];
- trendChart.setOption({
- color: ['#44e0c2', '#79d9ff', '#ffcc66'],
- tooltip: { trigger: 'axis' },
- legend: { top: 0, right: 10, textStyle: { color: '#b8d9ee' } },
- grid: { left: 45, right: 25, bottom: 34, top: 42 },
- xAxis: { type: 'category', data: data.hours || [], axisLabel: { color: '#9fb6c7' }, axisLine: { lineStyle: { color: '#31536a' } } },
- yAxis: { type: 'value', name: 'kWh', nameTextStyle: { color: '#9fb6c7' }, axisLabel: { color: '#9fb6c7' }, splitLine: { lineStyle: { color: 'rgba(100,160,190,.16)' } } },
- series: (data.hourlySeries || []).map(function (item) {
- return { name: item.name, type: 'line', smooth: true, symbol: 'circle', symbolSize: 5, data: item.data || [] };
- })
- });
- monthChart.setOption({
- color: ['#44e0c2', '#79d9ff', '#ffcc66'],
- tooltip: { trigger: 'axis' },
- legend: { top: 0, right: 10, textStyle: { color: '#b8d9ee' } },
- grid: { left: 50, right: 20, bottom: 34, top: 42 },
- xAxis: {
- type: 'category',
- data: data.days || [],
- axisLabel: { color: '#9fb6c7', interval: 0, rotate: 40 },
- axisLine: { lineStyle: { color: '#31536a' } }
- },
- yAxis: {
- type: 'value',
- name: 'kWh',
- nameTextStyle: { color: '#9fb6c7' },
- axisLabel: { color: '#9fb6c7' },
- splitLine: { lineStyle: { color: 'rgba(100,160,190,.16)' } }
- },
- series: (data.dailySeries || []).map(function (item) {
- return { name: item.name, type: 'bar', barMaxWidth: 14, data: item.data || [] };
- })
- });
- powerChart.setOption({
- color: ['#44e0c2'],
- tooltip: {},
- grid: { left: 45, right: 25, bottom: 34, top: 20 },
- xAxis: { type: 'category', data: devices.map(function (d, index) { return deviceTitle(d, index); }), axisLabel: { color: '#9fb6c7' }, axisLine: { lineStyle: { color: '#31536a' } } },
- yAxis: { type: 'value', name: 'kW', nameTextStyle: { color: '#9fb6c7' }, axisLabel: { color: '#9fb6c7' }, splitLine: { lineStyle: { color: 'rgba(100,160,190,.16)' } } },
- series: [{ type: 'bar', barWidth: 36, data: devices.map(function (d) { return Number(d.power || 0); }) }]
- });
- }
- function loadData() {
- $.get('${ctx}/mes/mesProduct/energyScreenData', function (resp) {
- if (!resp || resp.result !== 'true') { return; }
- var data = resp.data || {};
- var devices = data.devices || [];
- renderTopMeters(devices);
- renderDevices(devices);
- renderCharts(data);
- });
- }
- updateClock();
- loadData();
- setInterval(updateClock, 1000);
- setInterval(loadData, 10000);
- window.addEventListener('resize', function () {
- trendChart.resize();
- monthChart.resize();
- powerChart.resize();
- });
- </script>
- </body>
- </html>
|