Files
energy_storage/bin/Release/assets/html/main.html
2025-05-19 09:54:33 +08:00

682 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>光储充站控系统</title>
<script src="./libs/jquery/jquery-3.7.1.min.js"></script>
<link rel="stylesheet" href="./libs/DataTables-2.1.8/css/dataTables.dataTables.css" />
<script src="./libs/DataTables-2.1.8/js/dataTables.js"></script>
<link rel="stylesheet" href="./libs/bootstrap-5.3.3-dist/css/bootstrap.min.css" />
<script src="./libs/bootstrap-5.3.3-dist/js/bootstrap.min.js"></script>
<script src="./libs/bootstrap-5.3.3-dist/js/bootstrap.bundle.min.js"></script>
<script src="./libs/echarts/echarts.min.js"></script>
<script src="./js/qwebchannel.js"></script>
<script src="./js/myecharts.js"></script>
<style>
body {
background-image: url('../ui/bkg01.png');
background-size: 100% 100%;
background-attachment: fixed;
}
a {
display: inline-block;
/* 添加间距,使链接之间不会紧贴 */
padding-right: 8px;
color: #ffffff;
}
table {
font-size: 16px;
font-weight: bold;
color: white;
width: 100%;
text-align: center;
border-collapse: separate;
border-spacing: 0;
border: solid 2px #1c797a;
}
table thead {
background-color: #125c70;
}
table thead tr {
height: 32px;
/* border: solid 2px red; */
}
table thead tr th {
border-right: solid 1px gray;
border-bottom: solid 1px gray;
}
table tbody tr {
height: 32px;
font-size: 13px;
font-weight: bold;
}
table tbody tr td {
border-right: solid 1px gray;
border-bottom: solid 1px gray;
}
td:last-child,
th:last-child {
border-right-color: transparent;
}
.dt-container {
color: white;
}
.dt-paging {
color: white;
}
td.details-control {
background: url('../assets/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('../assets/details_close.png') no-repeat center center;
}
.table-ext {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
margin-top: 10px;
}
.table-ext .item {
margin: 0px 20px 0px 10px;
}
#flex-sample {
display: flex;
/* 排列方向 flex-direction: row | row-reverse | column | column-reverse */
flex-direction: column;
/* 换行方式 flex-wrap: nowrap(不换行) | wrap换行第一行在上面 | wrap-reverse换行第一行在下面 */
flex-wrap: nowrap;
/* 是flex-direction属性和flex-wrap属性的简写形式默认值为row nowrap */
flex-flow: column nowrap;
/* 主轴上的对齐方式 justify-content: flex-start | flex-end | center | space-between | space-around */
justify-content: center;
align-items: stretch;
/* flex-start | flex-end | center | baseline | stretch */
align-content: flex-start;
/* flex-start | flex-end | center | space-between | space-around | stretch */
}
.mypanelstat {
width: 100%;
height: calc(90vh - 130px);
background-color: #052f4d;
/* margin-top: 10px; */
/* padding: 10px 10px 10px 10px; */
border-radius: 12px;
}
.mask {
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
font-size: 16px;
/* IE9以下不支持rgba模式 */
background-color: rgba(0, 0, 0, 0.3);
/* 兼容IE8及以下 */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7f000000, endColorstr=#7f000000);
/* 显示: block 不显示none overlay.style.display = 'block' */
display: none;
}
/* 弹出框主体 */
.pop {
background-color: #e0e0e0;
min-width: 200px;
max-width: 600px;
height: 300px;
border-radius: 10px;
margin: 200px auto;
text-align: center;
/* overflow: hidden; */
}
/* 弹出框的标题 */
.pop_title {
font-size: 28px;
font-weight: 1000;
height: 50px;
line-height: 50px;
background-color: #909090;
border-radius: 10px 10px 0 0;
/* border-bottom: solid 2px #8080ff; */
}
/* 弹出框的内容 */
.pop_content {
height: 50px;
line-height: 50px;
padding: 15px 20px;
color: #198754;
}
/* 弹出框的按钮栏 */
.pop_btn {
padding-bottom: 10px;
}
/* 弹出框的按钮 */
.pop_btn button {
color: #778899;
width: 40%;
height: 40px;
cursor: pointer;
border: solid 1px #cccccc;
border-radius: 5px;
margin: 5px 10px;
color: #ffffff;
background-color: #337ab7;
}
myrow {
color: white;
display: flex;
flex-direction: row;
align-content: flex-start;
}
mycolumn {
color: white;
display: flex;
flex-direction: column;
}
.myrow {
color: white;
display: flex;
flex-direction: row;
align-content: flex-start;
}
.mycolumn {
color: white;
display: flex;
flex-direction: column;
width: 100%;
}
.myblock {
background-color: chocolate;
width: 50px;
height: 50px;
margin: 10px 0px 0px 10px;
}
.mycardbtn {
background-color: #07486f;
border-radius: 10px;
margin: 0 10px 10px 10px;
padding: 10px 10px 10px 10px;
}
.mycardbtn-active {
background-color: #1d6466;
border-radius: 10px;
margin: 0 10px 10px 10px;
padding: 10px 10px 10px 10px;
border: 2px solid #01b7d1;
}
.mycardbtn:hover {
background-color: #1d6466;
cursor: pointer;
}
.mycard {
background-color: #08365b;
width: 300px;
height: 280px;
border-radius: 10px;
margin: 10px 0px 0px 10px;
padding: 10px;
}
.mycard-param {
display: flex;
font-size: 16px;
margin-left: 20px;
}
.mycard-param-title {
font-weight: 200;
color: #a6b8dd;
width: 70px;
}
.mycard-param-text {
font-weight: 500;
margin-left: 10px;
color: white;
}
.mychart {
background-color: #30303030;
}
.mypanel {
width: 100%;
height: 200px;
background-color: #07253f;
border-radius: 8px;
padding: 10px 10px 10px 10px;
margin: 0px 0px 10px 0px;
overflow: hidden;
}
.mypanel .mypanel-icon {
width: 5px;
height: 24px;
background-color: #21ffd2;
float: left;
}
.mypanel .mypanel-title {
height: 24px;
margin-left: 15px;
font-size: 16px;
font-weight: 1000;
color: #63c4d8;
}
.mypanel-title {
height: 24px;
margin-left: 15px;
font-size: 16px;
font-weight: 1000;
color: #63c4d8;
}
.mypanel .mypanel-line {
margin-top: 5px;
margin-bottom: 0px;
width: 100%;
height: 2px;
background: linear-gradient(to right, #21ffd2ff, #21ffd200);
}
.label-bkg {
border-radius: 5px;
background-color: #a0a0a010;
float: left;
/* margin-right: 10px; */
}
.label-key {
/* border: solid 1px white; */
width: 100%;
height: 50%;
font-size: 16px;
font-weight: 1000;
color: white;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.label-val-lg {
/* border: solid 1px white; */
width: 65%;
height: 50%;
font-size: 36px;
color: #4dd7f0;
float: left;
display: flex;
justify-content: flex-end;
align-items: flex-end;
text-align: right;
}
.label-val {
/* border: solid 1px white; */
width: 65%;
height: 50%;
font-size: 20px;
color: #4dd7f0;
float: left;
display: flex;
justify-content: flex-end;
align-items: flex-end;
}
.label-tail {
/* border: solid 1px white; */
padding-left: 10px;
width: 35%;
height: 45%;
font-size: 16px;
font-weight: 1000;
color: white;
display: flex;
justify-content: left;
align-items: flex-end;
}
#maskTest {
position: absolute;
z-index: 1;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
.page {
padding: 5px 8px 5px 8px;
}
.dt-container {
color: white;
}
div.dt-container .dt-paging .dt-paging-button {
line-height: 32px;
width: 32px;
padding: 0 0px 0 0;
border: 1px solid white;
margin-right: 10px;
}
div.dt-container .dt-paging .dt-paging-button.disabled,
div.dt-container .dt-paging .dt-paging-button.disabled:hover,
div.dt-container .dt-paging .dt-paging-button.disabled:active {
color: white !important;
border: 1px solid gray;
}
div.dt-container .dt-paging .dt-paging-button.current {
background: linear-gradient(to bottom, #1c797a 0%, #1c797a 100%);
}
div.dt-container .dt-paging .dt-paging-button.current:hover {
background: linear-gradient(to bottom, #1c797a 0%, #1c797a 100%);
}
div.dt-container .dt-paging .dt-paging-button:hover {
color: white !important;
border: 1px solid #111;
background-color: #111;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #585858 0%, #111 100%);
/* Chrome10+,Safari5.1+ */
background: -moz-linear-gradient(top, #585858 0%, #111 100%);
/* FF3.6+ */
background: -ms-linear-gradient(top, #585858 0%, #111 100%);
/* IE10+ */
background: -o-linear-gradient(top, #585858 0%, #111 100%);
/* Opera 11.10+ */
background: linear-gradient(to bottom, #1c797a 0%, #1c797a 100%);
/* W3C */
}
</style>
<script>
var G = {
loadPage: function (pagename) {
while (1) {
var script = document.querySelector("script[id='mytempfile']")
if (!script) break
script.remove()
}
var file = 'assets/html/pages/' + pagename + '.html'
G.cppNative.readFile(file).then(function (text) {
// 加载 html 页面内容文件
document.getElementById('mypage').innerHTML = text
// 加载 js 脚本文件
var jsUrl = './pages/' + pagename + '.js'
var element = document.createElement('script')
element.src = jsUrl + '?t=' + new Date().getTime()
element.async = false // 脚本按照加载先后顺序处理
element.setAttribute('id', 'mytempfile')
document.body.appendChild(element)
})
},
switchSetStatus: function (id1, id2, isOn, callback) {
var switch1 = document.getElementById(id1)
var switch2 = document.getElementById(id2)
switch2.checked = !(switch1.checked = isOn)
if (callback) callback(isOn)
},
switchGetStatus: function (id) { return document.getElementById(id).checked },
initTable: function (id, info) {
if (info.table) {
info.table.ajax.reload()
return;
}
var tableOption = G.tableGetOption()
tableOption.columns = info.columns
tableOption.ajax = function (req, callback, settings) {
if (info.query) {
info.query(1, 10).then(res => {
var result = []
res.data.forEach(function (item, index) {
var rowData = []
info.header.forEach(function (key, index) { rowData.push(item[key]) })
result.push(rowData)
})
G.cppNative.log("table ajax: " + JSON.stringify(result))
callback({ draw: req.draw, recordsTotal: result.length, recordsFiltered: result.length, data: result })
})
} else {
callback({ draw: req.draw, recordsTotal: 0, recordsFiltered: 0, data: [] })
}
}
// 初始化表格
info.table = $('#' + id + 'Table').DataTable(tableOption)
$('div.gotopage').html(
'<b style="color:#7f8fa4">跳转至 </b><input id="searchNumber" style="width:80px"/><b style="color:#7f8fa4;"> 页</b>'
)
},
initForm: function (id, funcPopConfirm) {
var form = document.getElementById(id + 'Form')
var formBtnOk = document.getElementById(id + 'FormOk')
if (form && formBtnOk) {
// 监听表单的输入事件,检查表单的必填项是否完成输入,如果未完成,则确认按钮不可用
form.addEventListener('input', function () { formBtnOk.disabled = !form.checkValidity() })
// 编辑弹窗的确定按钮监听点击事件
formBtnOk.addEventListener('click', function () { if (funcPopConfirm) { funcPopConfirm(id) } })
}
},
showElement: function (id, visible) {
var elemt = document.getElementById(id)
if (elemt) { elemt.style.display = visible ? 'block' : 'none' }
},
popSetParams: function (id, keys, rowdata, callback) {
keys.forEach(function (key, index) {
var val = ''
if (rowdata && rowdata.length > index) { val = rowdata[index] }
if (key == 'is_open') {
G.switchSetStatus(id + 'Form_on', id + 'Form_off', parseInt(val))
} else {
var myval = (callback) ? callback(id, key, val) : val
// 回调函数返回 undefined 时, 不需要设置参数值
if (myval != undefined) {
val = myval
var element = $('#' + id + 'Form_' + key)
if (element) {
if (element.prop("tagName") == "SELECT" && val == '') {
element.get(0).selectedIndex = 0;
} else {
element.val(val)
}
}
}
}
})
},
popGetParams: function (id, keys, rowdata, callback) {
var params = {}
keys.forEach(function (key, index) {
var val
if (key == 'is_open') {
val = G.switchGetStatus(id + 'Form_on') ? '1' : '0'
} else {
var myval = callback ? callback(id, key) : undefined
val = myval != undefined ? myval : $('#' + id + 'Form_' + key).val()
}
if (rowdata) {
if (rowdata.length > index && val != rowdata[index]) { params[key] = val }
} else {
if (val != '') { params[key] = val }
}
})
G.cppNative.log('POP get params id=' + id + ', params=' + JSON.stringify(params))
return params
},
popSetParamReadonly: function (id, key, isReadonly) {
$('#' + id + 'Form_' + key).attr('readonly', isReadonly)
},
tableGetOption: function () {
return {
data: [],
columns: [],
bSort: false,
aLengthMenu: [10, 20, 50, 100], //设置每页显示数据条数的下拉选项
displayLength: 10, //每页初始显示最大记录数量
// 设置表格t、分页数据条数l、搜索框f、表格信息i、分页p、加载信息r
dom: 'rt<"table-ext"<"item">p<"item"<"gotopage">><"item"i>>',
language: {
emptyTable: '无数据',
lengthMenu: '每页显示 _MENU_ 条记录',
zeroRecords: '对不起,查询不到任何相关数据',
info: '共 _TOTAL_ 条记录', // '当前显示 _START_ 到 _END_ 条,共 _TOTAL_ 条记录',
infoEmpty: '共 0 页',
infoFiltered: '数据表中共为 _MAX_ 条记录)',
processing: '正在加载中...',
search: '结果中搜索',
paginate: { previous: '<', next: '>' }, // first: '首页', last: '尾页'
},
columnDefs: [{ targets: '_all', className: 'dt-head-left' }, { targets: '_all', className: 'dt-body-left' }],
serverSide: true,
processing: false,
ajax: function (req, callback, settings) {
// 查询服务器获取数据, 同时获取总数据条数
callback({ draw: req.draw, recordsTotal: 0, recordsFiltered: 0, data: [] })
},
createdRow: function (row, data, dataIndex) {
if (dataIndex % 2 === 0) {
//$(row).css('background-color', '#ff000010')
} else {
//$(row).css('background-color', '#00ff0010')
}
$(row).on('mouseenter', function () {
//if (curEditRow && myTableApi.row(curEditRow).index() == myTableApi.row($(this)).index()) return
$(this).css('background-color', '#ff808050') // 高亮颜色
})
$(row).on('mouseleave', function () {
//if (curEditRow && myTableApi.row(curEditRow).index() == myTableApi.row($(this)).index()) return
$(this).css('background-color', '') // 恢复默认
})
},
}
},
clickSubpageBtn: function (id) {
if (G.curSubpageId == id) return
if (G.curSubpageId) {
var oldBtn = document.getElementById(G.curSubpageId + 'Btn')
if (oldBtn) { oldBtn.className = 'btn btn-primary' }
var oldSubpage = $('#' + G.curSubpageId)
if (oldSubpage) { oldSubpage.hide() }
}
if (id) {
var curBtn = document.getElementById(id + 'Btn')
if (curBtn) { curBtn.className = 'btn btn-success btn-lg' }
var curSubpage = $('#' + id)
if (curSubpage) { curSubpage.show() }
}
G.curSubpageId = id
}
}
</script>
</head>
<body>
<div style="height: calc(8vh); line-height: 100px; display: flex;">
<!-- <button style="height:50px; line-height: 50px;" onclick='window.location.reload()'>重新加载</button> -->
<div id="currentTime"
style="color:white; font-family: Cascadia Mono; font-size: 20px; font-weight: 1000; margin-left: 20px; float: left">
</div>
</div>
<div id="mypage" style="height: calc(92vh - 60px);display: flex;flex-direction: row;"> </div>
<div style="background-color: #00496e; display: flex; justify-content: center;">
<button class="btn btn-primary" style="margin: 10px" onclick="G.loadPage('系统总览')">系统总览</button>
<button class="btn btn-primary" style="margin: 10px" onclick="G.loadPage('运行监控')">运行监控</button>
<button class="btn btn-primary" style="margin: 10px" onclick="G.loadPage('预测管理')">预测管理</button>
<button class="btn btn-primary" style="margin: 10px" onclick="G.loadPage('统计分析')">统计分析</button>
<button class="btn btn-primary" style="margin: 10px" onclick="G.loadPage('系统管理')">系统管理</button>
<button class="btn btn-primary" style="margin: 10px" onclick="G.loadPage('安全管理')">安全管理</button>
</div>
<script>
//第一个参数是QtWebEngine 挂载到前端全局环境中的 window.qt.webChannelTransport
new QWebChannel(qt.webChannelTransport, function (channel) {
// 在C++侧注册的对象名称为cppNative所以channel.objects后面的名字是cppNative
G.cppNative = channel.objects.cppNative
// 连接WebObject类的signalNativeTextChanged信号
G.cppNative.signalNativeTextChanged.connect(function (text) { alert('signal: ' + text) })
})
document.addEventListener("keydown", function (e) {
if (e.keyCode == 116) { window.location.reload() }
});
// 查询用户权限,确定页面显示内容
$(document).ready(function () {
setInterval(() => {
var now = new Date()
var year = now.getFullYear();
var month = ('0' + (now.getMonth() + 1)).slice(-2);
var day = ('0' + now.getDate()).slice(-2);
var hours = ('0' + now.getHours()).slice(-2);
var minutes = ('0' + now.getMinutes()).slice(-2);
var seconds = ('0' + now.getSeconds()).slice(-2);
var currentT = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
document.getElementById('currentTime').innerHTML = currentT;
}, 1000);
//G.loadPage('系统总览')
})
</script>
</body>
</html>