2026-01-16 14:13:44 +08:00
|
|
|
<%@ page language="java" pageEncoding="UTF-8" %>
|
|
|
|
|
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
|
|
|
|
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
|
|
|
|
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
|
|
|
|
|
<%@ page import="com.sipai.entity.base.ServerObject" %>
|
|
|
|
|
<%@ taglib uri="http://www.springsecurity.org/jsp" prefix="security" %>
|
|
|
|
|
|
|
|
|
|
<%@ page import="com.sipai.entity.base.MainConfig" %>
|
|
|
|
|
<% request.setAttribute("type_pro", MainConfig.type_pro); %>
|
|
|
|
|
<% request.setAttribute("type_safe", MainConfig.type_safe); %>
|
|
|
|
|
<% request.setAttribute("type_eff", MainConfig.type_eff); %>
|
|
|
|
|
<% request.setAttribute("type_pic", MainConfig.type_pic); %>
|
|
|
|
|
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
|
|
|
|
<head>
|
2026-03-22 22:36:01 +08:00
|
|
|
<title><%= ServerObject.atttable.get("TOPTITLE")%></title>
|
2026-01-16 14:13:44 +08:00
|
|
|
|
|
|
|
|
<!-- 引用页头及CSS页-->
|
|
|
|
|
<jsp:include page="/jsp/inc.jsp"></jsp:include>
|
|
|
|
|
<!-- echarts-->
|
2026-03-22 22:36:01 +08:00
|
|
|
<script type="text/javascript" src="<%=request.getContextPath()%>/plugins/echarts/echarts.4.1.0.min.js" charset="utf-8"></script>
|
2026-01-16 14:13:44 +08:00
|
|
|
|
|
|
|
|
<script type="text/javascript" src="<%=request.getContextPath()%>/JS/main/main_js.js" charset="utf-8"></script>
|
|
|
|
|
<style>
|
2026-03-22 22:36:01 +08:00
|
|
|
* {
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 0;
|
|
|
|
|
box-sizing: border-box;
|
2026-01-16 14:13:44 +08:00
|
|
|
}
|
2026-03-22 22:36:01 +08:00
|
|
|
|
|
|
|
|
body {
|
|
|
|
|
background: #f0f2f5;
|
|
|
|
|
font-family: 'Microsoft YaHei', sans-serif;
|
2026-01-16 14:13:44 +08:00
|
|
|
}
|
2026-03-22 22:36:01 +08:00
|
|
|
|
|
|
|
|
.page-container {
|
|
|
|
|
padding: 15px;
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 通用卡片样式 */
|
|
|
|
|
.card {
|
|
|
|
|
background: #fff;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-header {
|
|
|
|
|
height: 40px;
|
|
|
|
|
line-height: 40px;
|
|
|
|
|
padding: 0 15px;
|
2026-01-16 14:13:44 +08:00
|
|
|
font-weight: bold;
|
2026-03-22 22:36:01 +08:00
|
|
|
font-size: 14px;
|
|
|
|
|
color: #0c4377;
|
|
|
|
|
border-bottom: 2px solid #67aad7;
|
|
|
|
|
background: linear-gradient(to right, rgba(103, 170, 215, 0.1), transparent);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
2026-01-16 14:13:44 +08:00
|
|
|
}
|
2026-03-22 22:36:01 +08:00
|
|
|
|
|
|
|
|
.card-header::before {
|
|
|
|
|
content: "";
|
|
|
|
|
display: block;
|
|
|
|
|
width: 4px;
|
|
|
|
|
height: 16px;
|
|
|
|
|
background-color: #0c4377;
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card-body {
|
|
|
|
|
padding: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 上部分区域 */
|
|
|
|
|
.top-section {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 280px 1fr 200px;
|
|
|
|
|
gap: 15px;
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 进水累计卡片 - 美化样式 */
|
|
|
|
|
.inflow-card {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
padding: 15px;
|
|
|
|
|
/*background: linear-gradient(180deg, #f8fbfd 0%, #f0f5f9 100%);*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 15px;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
position: relative;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
|
|
|
|
|
transition: transform 0.2s, box-shadow 0.2s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-item:hover {
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
|
box-shadow: 0 6px 20px rgba(0,0,0,0.12);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-item.industrial {
|
|
|
|
|
background: linear-gradient(135deg, #667eea 0%, #1890ff 100%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-item.domestic {
|
|
|
|
|
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-item::before {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: -50%;
|
|
|
|
|
right: -50%;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
background: radial-gradient(circle, rgba(255,255,255,0.15) 0%, transparent 70%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-content {
|
|
|
|
|
flex: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-item .label {
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
color: rgba(255,255,255,0.85);
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
display: flex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-item .value-row {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: baseline;
|
|
|
|
|
gap: 4px;
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-item .value {
|
|
|
|
|
font-size: 26px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
color: #fff;
|
|
|
|
|
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.inflow-item .unit {
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: rgba(255,255,255,0.85);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 图表卡片 */
|
|
|
|
|
.chart-container {
|
|
|
|
|
height: 220px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 设备运行卡片 */
|
|
|
|
|
.device-list {
|
|
|
|
|
max-height: 220px;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 8px 12px;
|
|
|
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-item:last-child {
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-name {
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: #333;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-status {
|
|
|
|
|
padding: 2px 10px;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status-running {
|
|
|
|
|
background: #e6f7e6;
|
|
|
|
|
color: #52c41a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status-stopped {
|
|
|
|
|
background: #fff1f0;
|
|
|
|
|
color: #ff4d4f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status-warning {
|
|
|
|
|
background: #fffbe6;
|
|
|
|
|
color: #faad14;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 泵站详情 */
|
|
|
|
|
.pump-stations {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(4, 1fr);
|
|
|
|
|
gap: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pump-station {
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
padding: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pump-station-title {
|
2026-01-16 14:13:44 +08:00
|
|
|
font-size: 14px;
|
|
|
|
|
font-weight: bold;
|
2026-03-22 22:36:01 +08:00
|
|
|
color: #0c4377;
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
padding-bottom: 8px;
|
|
|
|
|
border-bottom: 1px solid #e8e8e8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pump-list {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pump-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
width: 50px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pump-icon {
|
|
|
|
|
width: 40px;
|
|
|
|
|
height: 40px;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: #fff;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pump-icon.on {
|
|
|
|
|
background: linear-gradient(135deg, #52c41a 0%, #389e0d 100%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pump-icon.off {
|
|
|
|
|
background: linear-gradient(135deg, #d9d9d9 0%, #bfbfbf 100%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pump-icon.error {
|
|
|
|
|
background: linear-gradient(135deg, #ff4d4f 0%, #cf1322 100%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pump-name {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #666;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 下部分区域 */
|
|
|
|
|
.bottom-section {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
|
gap: 15px;
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 泵站区域 */
|
|
|
|
|
.pump-section {
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 表格样式 */
|
|
|
|
|
.table-wrapper {
|
|
|
|
|
height: 280px;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.data-table {
|
|
|
|
|
width: 100%;
|
|
|
|
|
border-collapse: collapse;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.data-table thead {
|
|
|
|
|
position: sticky;
|
|
|
|
|
top: 0;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.data-table th {
|
|
|
|
|
background: #f5f7fa;
|
|
|
|
|
color: #0c4377;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
padding: 10px 8px;
|
|
|
|
|
text-align: left;
|
|
|
|
|
border-bottom: 2px solid #67aad7;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.data-table td {
|
|
|
|
|
padding: 10px 8px;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: #333;
|
|
|
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.data-table tr:hover {
|
|
|
|
|
background: #f5f7fa;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 告警状态 */
|
|
|
|
|
.alarm-badge {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
padding: 2px 8px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.alarm-badge.critical {
|
|
|
|
|
background: #fff1f0;
|
|
|
|
|
color: #ff4d4f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.alarm-badge.warning {
|
|
|
|
|
background: #fffbe6;
|
|
|
|
|
color: #faad14;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.alarm-badge.info {
|
|
|
|
|
background: #e6f7ff;
|
|
|
|
|
color: #1890ff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 分页样式 */
|
|
|
|
|
.pagination {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 10px 15px;
|
|
|
|
|
border-top: 1px solid #f0f0f0;
|
|
|
|
|
background: #fafafa;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pagination-info {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #666;
|
|
|
|
|
margin-right: 15px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pagination-btns {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 5px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pagination-btn {
|
|
|
|
|
padding: 4px 12px;
|
|
|
|
|
border: 1px solid #d9d9d9;
|
|
|
|
|
background: #fff;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #333;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pagination-btn:hover:not(:disabled) {
|
|
|
|
|
border-color: #378dcc;
|
|
|
|
|
color: #378dcc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pagination-btn:disabled {
|
|
|
|
|
color: #d9d9d9;
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.pagination-btn.active {
|
|
|
|
|
background: #378dcc;
|
|
|
|
|
border-color: #378dcc;
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 滚动条美化 */
|
|
|
|
|
.scroll-container::-webkit-scrollbar,
|
|
|
|
|
.table-wrapper::-webkit-scrollbar,
|
|
|
|
|
.device-list::-webkit-scrollbar {
|
|
|
|
|
width: 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.scroll-container::-webkit-scrollbar-thumb,
|
|
|
|
|
.table-wrapper::-webkit-scrollbar-thumb,
|
|
|
|
|
.device-list::-webkit-scrollbar-thumb {
|
|
|
|
|
background: #c1c1c1;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.scroll-container::-webkit-scrollbar-track,
|
|
|
|
|
.table-wrapper::-webkit-scrollbar-track,
|
|
|
|
|
.device-list::-webkit-scrollbar-track {
|
|
|
|
|
background: #f1f1f1;
|
2026-01-16 14:13:44 +08:00
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
<script type="text/javascript">
|
2026-03-22 22:36:01 +08:00
|
|
|
// 分页配置
|
|
|
|
|
var processPageSize = 10;
|
|
|
|
|
var processCurrentPage = 1;
|
|
|
|
|
var processData = [];
|
|
|
|
|
|
|
|
|
|
var alarmPageSize = 10;
|
|
|
|
|
var alarmCurrentPage = 1;
|
|
|
|
|
var alarmData = [];
|
|
|
|
|
|
2026-01-16 14:13:44 +08:00
|
|
|
$(function () {
|
2026-03-22 22:36:01 +08:00
|
|
|
initData();
|
|
|
|
|
initChart();
|
2026-01-16 14:13:44 +08:00
|
|
|
});
|
|
|
|
|
|
2026-03-22 22:36:01 +08:00
|
|
|
function initData() {
|
|
|
|
|
// 初始化工业进水累计
|
|
|
|
|
$('#industrial_value').text('12,580');
|
|
|
|
|
// 初始化生活进水累计
|
|
|
|
|
$('#domestic_value').text('8,650');
|
|
|
|
|
|
|
|
|
|
// 初始化设备运行列表
|
|
|
|
|
initDeviceList();
|
|
|
|
|
// 初始化泵站详情
|
|
|
|
|
initPumpStations();
|
|
|
|
|
// 初始化工艺列表
|
|
|
|
|
initProcessList();
|
|
|
|
|
// 初始化告警列表
|
|
|
|
|
initAlarmList();
|
2026-01-16 14:13:44 +08:00
|
|
|
}
|
2026-03-22 22:36:01 +08:00
|
|
|
|
|
|
|
|
function initDeviceList() {
|
|
|
|
|
var devices = [
|
|
|
|
|
{name: '进水泵1#', status: 'running'},
|
|
|
|
|
{name: '进水泵2#', status: 'running'},
|
|
|
|
|
{name: '鼓风机1#', status: 'running'},
|
|
|
|
|
{name: '鼓风机2#', status: 'stopped'},
|
|
|
|
|
{name: '回流泵1#', status: 'warning'},
|
|
|
|
|
{name: '回流泵2#', status: 'running'},
|
|
|
|
|
{name: '污泥泵1#', status: 'running'},
|
|
|
|
|
{name: '污泥泵2#', status: 'stopped'},
|
|
|
|
|
{name: '提升泵1#', status: 'running'},
|
|
|
|
|
{name: '提升泵2#', status: 'running'}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
var html = '';
|
|
|
|
|
devices.forEach(function(device) {
|
|
|
|
|
var statusClass = device.status === 'running' ? 'status-running' :
|
|
|
|
|
device.status === 'stopped' ? 'status-stopped' : 'status-warning';
|
|
|
|
|
var statusText = device.status === 'running' ? '运行中' :
|
|
|
|
|
device.status === 'stopped' ? '已停止' : '异常';
|
|
|
|
|
html += '<div class="device-item">';
|
|
|
|
|
html += '<span class="device-name">' + device.name + '</span>';
|
|
|
|
|
html += '<span class="device-status ' + statusClass + '">' + statusText + '</span>';
|
|
|
|
|
html += '</div>';
|
|
|
|
|
});
|
|
|
|
|
$('#device_list').html(html);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function initPumpStations() {
|
|
|
|
|
var stations = [
|
|
|
|
|
{name: '卫八泵站', pumps: ['on', 'on', 'off', 'on', 'error']},
|
|
|
|
|
{name: '九号泵站', pumps: ['on', 'off', 'on', 'on', 'off']},
|
|
|
|
|
{name: '春华泵站', pumps: ['on', 'on', 'on', 'off', 'on']},
|
|
|
|
|
{name: '厂内泵站', pumps: ['on', 'off', 'off', 'on', 'on']}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
var html = '';
|
|
|
|
|
stations.forEach(function(station) {
|
|
|
|
|
html += '<div class="pump-station">';
|
|
|
|
|
html += '<div class="pump-station-title">' + station.name + '</div>';
|
|
|
|
|
html += '<div class="pump-list">';
|
|
|
|
|
station.pumps.forEach(function(status, index) {
|
|
|
|
|
var iconClass = status === 'on' ? 'on' : status === 'off' ? 'off' : 'error';
|
|
|
|
|
var iconText = status === 'on' ? '启' : status === 'off' ? '关' : '异';
|
|
|
|
|
html += '<div class="pump-item">';
|
|
|
|
|
html += '<div class="pump-icon ' + iconClass + '">' + iconText + '</div>';
|
|
|
|
|
html += '<span class="pump-name">泵' + (index + 1) + '#</span>';
|
|
|
|
|
html += '</div>';
|
|
|
|
|
});
|
|
|
|
|
html += '</div></div>';
|
|
|
|
|
});
|
|
|
|
|
$('#pump_stations').html(html);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成工艺列表mock数据
|
|
|
|
|
function generateProcessData() {
|
|
|
|
|
var processNames = ['粗格栅间', '细格栅间', '曝气沉砂池', '厌氧池', '缺氧池', '好氧池', '二沉池', '消毒池', '污泥浓缩池', '污泥脱水间'];
|
|
|
|
|
var params1 = ['pH: 7.2', 'pH: 7.1', 'DO: 2.5mg/L', 'ORP: -200mV', 'DO: 0.5mg/L', 'DO: 3.5mg/L', 'SS: 15mg/L', '余氯: 0.3mg/L', 'MLSS: 4500mg/L', '含水率: 80%'];
|
|
|
|
|
var params2 = ['温度: 25°C', '温度: 24°C', 'MLSS: 3500mg/L', 'MLSS: 3200mg/L', 'MLSS: 3400mg/L', 'MLSS: 3800mg/L', '流量: 480m³/h', '流量: 470m³/h', '流量: 50m³/h', 'PAM: 2mg/L'];
|
|
|
|
|
var params3 = ['液位: 2.5m', '液位: 2.3m', '流量: 500m³/h', '温度: 26°C', 'ORP: -50mV', '温度: 27°C', '液位: 3.2m', 'pH: 7.0', '液位: 1.8m', '压力: 0.5MPa'];
|
|
|
|
|
|
|
|
|
|
var data = [];
|
|
|
|
|
for (var i = 0; i < 30; i++) {
|
|
|
|
|
data.push({
|
|
|
|
|
name: processNames[i % processNames.length] + (i >= 10 ? '-' + (Math.floor(i / 10) + 1) + '#' : ''),
|
|
|
|
|
param1: params1[i % params1.length],
|
|
|
|
|
param2: params2[i % params2.length],
|
|
|
|
|
param3: params3[i % params3.length],
|
|
|
|
|
deviceId: 'EQ-' + String(i + 1).padStart(3, '0')
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成告警列表mock数据
|
|
|
|
|
function generateAlarmData() {
|
|
|
|
|
var processNames = ['粗格栅间', '细格栅间', '曝气沉砂池', '厌氧池', '缺氧池', '好氧池', '二沉池', '消毒池', '污泥浓缩池', '污泥脱水间'];
|
|
|
|
|
var statuses = ['Critical', 'Warning', 'INFO'];
|
|
|
|
|
|
|
|
|
|
var data = [];
|
|
|
|
|
var baseTime = new Date('2026-03-22 14:30:00');
|
|
|
|
|
for (var i = 0; i < 30; i++) {
|
|
|
|
|
var time = new Date(baseTime.getTime() - i * 5 * 60000);
|
|
|
|
|
var timeStr = time.getFullYear() + '-' +
|
|
|
|
|
String(time.getMonth() + 1).padStart(2, '0') + '-' +
|
|
|
|
|
String(time.getDate()).padStart(2, '0') + ' ' +
|
|
|
|
|
String(time.getHours()).padStart(2, '0') + ':' +
|
|
|
|
|
String(time.getMinutes()).padStart(2, '0') + ':' +
|
|
|
|
|
String(time.getSeconds()).padStart(2, '0');
|
|
|
|
|
data.push({
|
|
|
|
|
process: processNames[i % processNames.length],
|
|
|
|
|
status: statuses[i % 3],
|
|
|
|
|
time: timeStr
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function initProcessList() {
|
|
|
|
|
processData = generateProcessData();
|
|
|
|
|
renderProcessTable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderProcessTable() {
|
|
|
|
|
var start = (processCurrentPage - 1) * processPageSize;
|
|
|
|
|
var end = Math.min(start + processPageSize, processData.length);
|
|
|
|
|
var pageData = processData.slice(start, end);
|
|
|
|
|
|
|
|
|
|
var html = '';
|
|
|
|
|
pageData.forEach(function(process) {
|
|
|
|
|
html += '<tr>';
|
|
|
|
|
html += '<td>' + process.name + '</td>';
|
|
|
|
|
html += '<td>' + process.param1 + '</td>';
|
|
|
|
|
html += '<td>' + process.param2 + '</td>';
|
|
|
|
|
html += '<td>' + process.param3 + '</td>';
|
|
|
|
|
html += '<td>' + process.deviceId + '</td>';
|
|
|
|
|
html += '</tr>';
|
|
|
|
|
});
|
|
|
|
|
$('#process_table tbody').html(html);
|
|
|
|
|
|
|
|
|
|
// 更新分页信息
|
|
|
|
|
var totalPages = Math.ceil(processData.length / processPageSize);
|
|
|
|
|
$('#process_page_info').text('第 ' + processCurrentPage + '/' + totalPages + ' 页,共 ' + processData.length + ' 条');
|
|
|
|
|
|
|
|
|
|
// 更新分页按钮
|
|
|
|
|
var btnHtml = '';
|
|
|
|
|
btnHtml += '<button class="pagination-btn" onclick="processGoToPage(1)" ' + (processCurrentPage === 1 ? 'disabled' : '') + '>首页</button>';
|
|
|
|
|
btnHtml += '<button class="pagination-btn" onclick="processGoToPage(' + (processCurrentPage - 1) + ')" ' + (processCurrentPage === 1 ? 'disabled' : '') + '>上一页</button>';
|
|
|
|
|
btnHtml += '<button class="pagination-btn" onclick="processGoToPage(' + (processCurrentPage + 1) + ')" ' + (processCurrentPage === totalPages ? 'disabled' : '') + '>下一页</button>';
|
|
|
|
|
// btnHtml += '<button class="pagination-btn" onclick="processGoToPage(' + totalPages + ')" ' + (processCurrentPage === totalPages ? 'disabled' : '') + '>末页</button>';
|
|
|
|
|
$('#process_page_btns').html(btnHtml);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function processGoToPage(page) {
|
|
|
|
|
var totalPages = Math.ceil(processData.length / processPageSize);
|
|
|
|
|
if (page < 1) page = 1;
|
|
|
|
|
if (page > totalPages) page = totalPages;
|
|
|
|
|
processCurrentPage = page;
|
|
|
|
|
renderProcessTable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function initAlarmList() {
|
|
|
|
|
alarmData = generateAlarmData();
|
|
|
|
|
renderAlarmTable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderAlarmTable() {
|
|
|
|
|
var start = (alarmCurrentPage - 1) * alarmPageSize;
|
|
|
|
|
var end = Math.min(start + alarmPageSize, alarmData.length);
|
|
|
|
|
var pageData = alarmData.slice(start, end);
|
|
|
|
|
|
|
|
|
|
var html = '';
|
|
|
|
|
pageData.forEach(function(alarm) {
|
|
|
|
|
var badgeClass = alarm.status === 'Critical' ? 'critical' :
|
|
|
|
|
alarm.status === 'Warning' ? 'warning' : 'info';
|
|
|
|
|
html += '<tr>';
|
|
|
|
|
html += '<td>' + alarm.process + '</td>';
|
|
|
|
|
html += '<td><span class="alarm-badge ' + badgeClass + '">' + alarm.status + '</span></td>';
|
|
|
|
|
html += '<td>' + alarm.time + '</td>';
|
|
|
|
|
html += '</tr>';
|
|
|
|
|
});
|
|
|
|
|
$('#alarm_table tbody').html(html);
|
|
|
|
|
|
|
|
|
|
// 更新分页信息
|
|
|
|
|
var totalPages = Math.ceil(alarmData.length / alarmPageSize);
|
|
|
|
|
$('#alarm_page_info').text('第 ' + alarmCurrentPage + '/' + totalPages + ' 页,共 ' + alarmData.length + ' 条');
|
|
|
|
|
|
|
|
|
|
// 更新分页按钮
|
|
|
|
|
var btnHtml = '';
|
|
|
|
|
btnHtml += '<button class="pagination-btn" onclick="alarmGoToPage(1)" ' + (alarmCurrentPage === 1 ? 'disabled' : '') + '>首页</button>';
|
|
|
|
|
btnHtml += '<button class="pagination-btn" onclick="alarmGoToPage(' + (alarmCurrentPage - 1) + ')" ' + (alarmCurrentPage === 1 ? 'disabled' : '') + '>上一页</button>';
|
|
|
|
|
btnHtml += '<button class="pagination-btn" onclick="alarmGoToPage(' + (alarmCurrentPage + 1) + ')" ' + (alarmCurrentPage === totalPages ? 'disabled' : '') + '>下一页</button>';
|
|
|
|
|
// btnHtml += '<button class="pagination-btn" onclick="alarmGoToPage(' + totalPages + ')" ' + (alarmCurrentPage === totalPages ? 'disabled' : '') + '>末页</button>';
|
|
|
|
|
$('#alarm_page_btns').html(btnHtml);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function alarmGoToPage(page) {
|
|
|
|
|
var totalPages = Math.ceil(alarmData.length / alarmPageSize);
|
|
|
|
|
if (page < 1) page = 1;
|
|
|
|
|
if (page > totalPages) page = totalPages;
|
|
|
|
|
alarmCurrentPage = page;
|
|
|
|
|
renderAlarmTable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function initChart() {
|
|
|
|
|
var chart = echarts.init(document.getElementById('flow_chart'));
|
|
|
|
|
var option = {
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'shadow'
|
|
|
|
|
}
|
2026-01-16 14:13:44 +08:00
|
|
|
},
|
2026-03-22 22:36:01 +08:00
|
|
|
legend: {
|
|
|
|
|
data: ['工业进水', '生活进水'],
|
|
|
|
|
top: 5,
|
|
|
|
|
textStyle: {
|
|
|
|
|
fontSize: 12
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
left: '5%',
|
|
|
|
|
right: '5%',
|
|
|
|
|
bottom: '8%',
|
|
|
|
|
top: '18%',
|
|
|
|
|
containLabel: true
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
type: 'category',
|
|
|
|
|
data: ['3/16', '3/17', '3/18', '3/19', '3/20', '3/21', '3/22'],
|
|
|
|
|
axisLine: {
|
|
|
|
|
lineStyle: {
|
|
|
|
|
color: '#e8e8e8'
|
2026-01-16 14:13:44 +08:00
|
|
|
}
|
2026-03-22 22:36:01 +08:00
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
color: '#666',
|
|
|
|
|
fontSize: 12
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
|
|
|
|
type: 'value',
|
|
|
|
|
name: 'm³/D',
|
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontSize: 12
|
|
|
|
|
},
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
color: '#666',
|
|
|
|
|
fontSize: 12
|
|
|
|
|
},
|
|
|
|
|
splitLine: {
|
|
|
|
|
lineStyle: {
|
|
|
|
|
color: '#f0f0f0'
|
2026-01-16 14:13:44 +08:00
|
|
|
}
|
|
|
|
|
}
|
2026-03-22 22:36:01 +08:00
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: '工业进水',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
barWidth: '30%',
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
|
|
{offset: 0, color: '#378dcc'},
|
|
|
|
|
{offset: 1, color: '#5ba3d9'}
|
|
|
|
|
])
|
|
|
|
|
},
|
|
|
|
|
data: [12000, 11500, 13000, 12500, 11800, 12200, 12580]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '生活进水',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
barWidth: '30%',
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
|
|
{offset: 0, color: '#52c41a'},
|
|
|
|
|
{offset: 1, color: '#73d13d'}
|
|
|
|
|
])
|
|
|
|
|
},
|
|
|
|
|
data: [8500, 8200, 9000, 8800, 8600, 8400, 8650]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
chart.setOption(option);
|
|
|
|
|
|
|
|
|
|
window.addEventListener('resize', function() {
|
|
|
|
|
chart.resize();
|
2026-01-16 14:13:44 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<body>
|
2026-03-22 22:36:01 +08:00
|
|
|
<div class="page-container">
|
|
|
|
|
<!-- 上部分区域 -->
|
|
|
|
|
<div class="top-section">
|
|
|
|
|
<!-- 进水累计(工业+生活合并,上下布局) -->
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="card-header">进水累计</div>
|
|
|
|
|
<div class="card-body" style="padding: 0;">
|
|
|
|
|
<div class="inflow-card">
|
|
|
|
|
<div class="inflow-item industrial">
|
|
|
|
|
<div class="inflow-content">
|
|
|
|
|
<span class="label">工业当日总量</span>
|
|
|
|
|
<div class="value-row">
|
|
|
|
|
<span class="value" id="industrial_value">--</span>
|
|
|
|
|
<span class="unit">m³</span>
|
2026-01-16 14:13:44 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-03-22 22:36:01 +08:00
|
|
|
</div>
|
|
|
|
|
<div class="inflow-item domestic">
|
|
|
|
|
<div class="inflow-content">
|
|
|
|
|
<span class="label">生活当日总量</span>
|
|
|
|
|
<div class="value-row">
|
|
|
|
|
<span class="value" id="domestic_value">--</span>
|
|
|
|
|
<span class="unit">m³</span>
|
2026-01-16 14:13:44 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-03-22 22:36:01 +08:00
|
|
|
|
|
|
|
|
<!-- 进水流量7天日趋势 -->
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="card-header">进水流量7天日趋势</div>
|
|
|
|
|
<div class="card-body">
|
|
|
|
|
<div id="flow_chart" class="chart-container"></div>
|
2026-02-08 01:02:58 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-03-22 22:36:01 +08:00
|
|
|
|
|
|
|
|
<!-- 设备运行 -->
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="card-header">设备运行</div>
|
|
|
|
|
<div class="card-body" style="padding: 0;">
|
|
|
|
|
<div class="device-list" id="device_list"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 下部分区域 -->
|
|
|
|
|
<div class="bottom-section">
|
|
|
|
|
<!-- 工艺列表展示 -->
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="card-header">工艺列表展示</div>
|
|
|
|
|
<div class="table-wrapper">
|
|
|
|
|
<table class="data-table" id="process_table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>工艺段名称</th>
|
|
|
|
|
<th>关键参数1</th>
|
|
|
|
|
<th>关键参数2</th>
|
|
|
|
|
<th>关键参数3</th>
|
|
|
|
|
<th>设备ID</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody></tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="pagination">
|
|
|
|
|
<span class="pagination-info" id="process_page_info"></span>
|
|
|
|
|
<div class="pagination-btns" id="process_page_btns"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 实时告警列表 -->
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="card-header">实时告警列表</div>
|
|
|
|
|
<div class="table-wrapper">
|
|
|
|
|
<table class="data-table" id="alarm_table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>报警工艺段名称</th>
|
|
|
|
|
<th>报警状态</th>
|
|
|
|
|
<th>时间</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody></tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="pagination">
|
|
|
|
|
<span class="pagination-info" id="alarm_page_info"></span>
|
|
|
|
|
<div class="pagination-btns" id="alarm_page_btns"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 泵站详情区域 -->
|
|
|
|
|
<div class="pump-section">
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="card-header">泵站详情</div>
|
|
|
|
|
<div class="card-body">
|
|
|
|
|
<div class="pump-stations" id="pump_stations"></div>
|
2026-01-16 14:13:44 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</body>
|
|
|
|
|
|
2026-03-22 22:36:01 +08:00
|
|
|
</html>
|