This commit is contained in:
Rue Ji
2026-02-02 23:52:49 +08:00
parent b2973c6d28
commit 5133e4f983
15 changed files with 983 additions and 94 deletions

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# IntelliJ IDEA
.idea/
*.iml
# Eclipse
.settings/
.classpath
.project
# VS Code
.vscode/
# Mac
.DS_Store
# Maven
target/
# Node
node_modules/
npm-debug.log
# Logs
*.log

10
.idea/.gitignore generated vendored
View File

@ -1,10 +0,0 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 已忽略包含查询文件的默认文件夹
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/

14
.idea/compiler.xml generated
View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="BUILD_PROCESS_HEAP_SIZE" value="4096" />
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="SIPAIIS_WMS" />
</profile>
</annotationProcessing>
</component>
</project>

8
.idea/encodings.xml generated
View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@ -1,7 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JSHint" enabled="true" level="ERROR" enabled_by_default="true" />
</profile>
</component>

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JSHintConfiguration" version="2.13.6" use-config-file="true" use-custom-config-file="true" custom-config-file-path="$PROJECT_DIR$/src/main/webapp/plugins/jquery-ui/ui/.jshintrc">
<option bitwise="true" />
<option browser="true" />
<option curly="true" />
<option eqeqeq="true" />
<option forin="true" />
<option maxerr="50" />
<option noarg="true" />
<option noempty="true" />
<option nonew="true" />
<option strict="true" />
<option undef="true" />
</component>
</project>

12
.idea/misc.xml generated
View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" project-jdk-name="temurin-1.8" project-jdk-type="JavaSDK" />
</project>

6
.idea/vcs.xml generated
View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

3
commitlint.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
};

12
package.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "sipaiis-wms-root",
"private": true,
"scripts": {
"prepare": "husky install"
},
"devDependencies": {
"@commitlint/cli": "^17.6.6",
"@commitlint/config-conventional": "^17.6.6",
"husky": "^8.0.3"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 MiB

After

Width:  |  Height:  |  Size: 13 MiB

View File

@ -0,0 +1,599 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>水厂大屏展示</title>
<script type="text/javascript" src="<%=request.getContextPath()%>/node_modules/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/JS/echarts3.0.js"></script>
<style>
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background-color: #030829;
overflow: auto;
}
.screen-container {
width: 6500px;
height: 1800px;
background-image: url('<%=request.getContextPath()%>/IMG/screen1.png');
background-size: 100% 100%;
background-repeat: no-repeat;
position: absolute;
}
/* Common Text Styles */
.text-white { color: #ffffff; }
.text-blue { color: #00eaff; }
.text-yellow { color: #ffaa00; }
.text-green { color: #00ff00; }
/* Header */
.header {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 130px;
}
.header-weather {
position: absolute;
left: 100px;
top: 40px;
font-size: 48px;
color: #00eaff;
}
.header-title {
position: absolute;
left: 50%;
top: 20px;
transform: translateX(-50%);
font-size: 80px;
font-weight: bold;
color: #ffffff;
text-shadow: 0 0 20px #00aaff;
letter-spacing: 10px;
}
.header-time {
position: absolute;
right: 100px;
top: 40px;
font-size: 48px;
color: #00eaff;
}
/* --- LEFT COLUMN (0 - 1400) --- */
/* Section Titles */
.section-header-small {
position: absolute;
font-size: 32px;
color: #00eaff;
font-weight: bold;
padding-left: 20px;
border-left: 6px solid #00eaff;
height: 40px;
line-height: 40px;
}
/* Water Trend Circles */
.water-trend-row {
position: absolute;
left: 50px;
top: 220px;
width: 1350px;
display: flex;
justify-content: space-around;
}
.circle-metric {
text-align: center;
width: 300px;
}
.circle-metric .val { font-size: 64px; font-weight: bold; color: white; }
.circle-metric .label { font-size: 32px; color: #00eaff; margin-top: 10px; }
/* 7-Day Chart */
.chart-7day-container {
position: absolute;
left: 50px;
top: 550px;
width: 1350px;
height: 450px;
}
/* Sludge Metrics */
.sludge-metrics-row {
position: absolute;
left: 50px;
top: 1120px;
width: 1350px;
display: flex;
justify-content: space-around;
}
.sludge-metric {
text-align: center;
background: rgba(0, 50, 150, 0.2);
padding: 20px;
width: 30%;
border-radius: 10px;
}
.sludge-metric .val { font-size: 56px; color: white; }
.sludge-metric .label { font-size: 28px; color: #00eaff; }
/* Sludge Chart */
.chart-sludge-container {
position: absolute;
left: 50px;
top: 1350px;
width: 1350px;
height: 350px;
}
/* --- MID-LEFT COLUMN (1450 - 2850) --- */
/* Chemicals */
.chem-container {
position: absolute;
left: 1480px;
top: 220px;
width: 1350px;
height: 250px;
display: flex;
}
.chem-boxes {
width: 60%;
display: flex;
gap: 20px;
}
.chem-box {
flex: 1;
padding: 20px;
border-radius: 10px;
color: white;
}
.chem-box.yellow { border: 2px solid #ffaa00; background: rgba(255, 170, 0, 0.1); }
.chem-box.green { border: 2px solid #00ff00; background: rgba(0, 255, 0, 0.1); }
.chem-box.blue { border: 2px solid #00eaff; background: rgba(0, 234, 255, 0.1); }
.chem-val { font-size: 48px; font-weight: bold; }
.chem-label { font-size: 24px; margin-top: 10px; }
.chem-list {
width: 40%;
padding-left: 20px;
font-size: 24px;
color: #00eaff;
line-height: 1.8;
}
.chem-list-item { display: flex; justify-content: space-between; }
.chem-list-val { color: white; }
/* Quality Table */
.quality-table-container {
position: absolute;
left: 1480px;
top: 580px;
width: 1350px;
}
.q-table {
width: 100%;
border-collapse: collapse;
font-size: 28px;
text-align: center;
}
.q-table th { background: rgba(0, 80, 200, 0.4); color: #00eaff; padding: 15px; }
.q-table td { border-bottom: 1px solid rgba(0, 80, 200, 0.3); color: white; padding: 15px; }
/* Quality Chart */
.chart-quality-container {
position: absolute;
left: 1480px;
top: 1200px;
width: 1350px;
height: 500px;
}
/* --- CENTER COLUMN (2900 - 4600) --- */
/* Center Items (Scattered) */
.center-point {
position: absolute;
background: rgba(0, 20, 50, 0.6);
border: 1px solid #0055aa;
padding: 10px 20px;
border-radius: 5px;
}
.center-point::before {
content: '';
position: absolute;
width: 10px;
height: 10px;
background: #00eaff;
border-radius: 50%;
box-shadow: 0 0 10px #00eaff;
}
/* Connectors can be simulated or assumed in BG. Here we just position the boxes. */
.cp-label { font-size: 24px; color: #00eaff; }
.cp-val { font-size: 32px; color: white; font-weight: bold; }
/* Specific Positions */
.cp-1 { left: 2950px; top: 500px; } /* 泵房液位 */
.cp-2 { left: 2900px; top: 700px; } /* 进水泵房1#电流 */
.cp-3 { left: 2980px; top: 900px; } /* 进水泵房2#电流 */
.cp-4 { left: 3100px; top: 1100px; } /* 进水泵房3#流量 */
.cp-5 { left: 3200px; top: 1300px; } /* 外回流泵1#流量 */
.cp-6 { left: 4300px; top: 500px; } /* 外回流泵2#液位 */
.cp-7 { left: 4350px; top: 700px; } /* 生化池剩余污泥泵 */
.cp-8 { left: 4250px; top: 900px; } /* 沉淀池剩余污泥泵 */
.cp-9 { left: 4150px; top: 1100px; } /* PAC加药流量 */
.cp-10 { left: 4050px; top: 1300px; } /* PAC储罐液位 */
/* --- RIGHT DATA COLUMN (4650 - 5450) --- */
.right-data-col {
position: absolute;
left: 4680px;
top: 220px;
width: 800px;
}
.section-block {
margin-bottom: 40px;
background: rgba(0, 20, 50, 0.3);
padding: 20px;
border-left: 5px solid #00eaff;
}
.section-title {
font-size: 36px;
color: #00eaff;
margin-bottom: 20px;
font-weight: bold;
}
.data-grid-2col {
display: flex;
flex-wrap: wrap;
}
.data-item {
width: 50%;
margin-bottom: 15px;
}
.data-item-label { font-size: 24px; color: #aaaaff; }
.data-item-val { font-size: 32px; color: #00eaff; }
/* --- RIGHT VIDEO COLUMN (5500 - 6450) --- */
.video-container {
position: absolute;
left: 5520px;
top: 220px;
width: 950px;
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.video-box {
width: 460px;
height: 280px;
background: black;
border: 2px solid #0055aa;
position: relative;
}
.play-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 48px;
color: rgba(255,255,255,0.5);
}
</style>
</head>
<body>
<div class="screen-container">
<!-- Header -->
<div class="header">
<div class="header-weather">上海 ☁️ 大雨 17-28℃</div>
<div class="header-title">金山卫污水厂数据大屏</div>
<div class="header-time" id="headerTime">2021.12.02 星期三 15:20:33</div>
</div>
<!-- Left Column -->
<div class="section-header-small" style="top: 150px; left: 50px;">水量趋势</div>
<div class="water-trend-row">
<div class="circle-metric">
<div class="val">6040</div>
<div class="label">今日处理</div>
</div>
<div class="circle-metric">
<div class="val">4197</div>
<div class="label">昨日处理</div>
</div>
<div class="circle-metric">
<div class="val">12356</div>
<div class="label">本月累计</div>
</div>
</div>
<div class="section-header-small" style="top: 480px; left: 50px;">七日水量处理情况</div>
<div class="chart-7day-container" id="chartWater"></div>
<div class="section-header-small" style="top: 1050px; left: 50px;">污泥处理指标</div>
<div class="sludge-metrics-row">
<div class="sludge-metric">
<div class="val">0 m³</div>
<div class="label">昨日产泥量</div>
</div>
<div class="sludge-metric">
<div class="val">253 m³</div>
<div class="label">今日产泥量</div>
</div>
<div class="sludge-metric">
<div class="val">4.89 m</div>
<div class="label">今日泥位</div>
</div>
</div>
<div class="chart-sludge-container" id="chartSludge"></div>
<!-- Mid-Left Column -->
<div class="section-header-small" style="top: 150px; left: 1480px;">药耗</div>
<div class="chem-container">
<div class="chem-boxes">
<div class="chem-box yellow">
<div class="chem-label">PAC投加药耗</div>
<div class="chem-val text-yellow">39.54</div>
</div>
<div class="chem-box green">
<div class="chem-label">乙酸钠投加药耗</div>
<div class="chem-val text-green">56.98</div>
</div>
<div class="chem-box blue">
<div class="chem-label">次氯酸钠投加</div>
<div class="chem-val text-blue">0</div>
</div>
</div>
<div class="chem-list">
<div class="chem-list-item"><span>厌氧池ORP</span><span class="chem-list-val">-370 mV</span></div>
<div class="chem-list-item"><span>缺氧池溶解氧1</span><span class="chem-list-val">0.05 mg/L</span></div>
<div class="chem-list-item"><span>1#好氧池溶解氧</span><span class="chem-list-val">0.52 mg/L</span></div>
<div class="chem-list-item"><span>2#好氧池溶解氧</span><span class="chem-list-val">0.40 mg/L</span></div>
<div class="chem-list-item"><span>污泥浓度MLSS</span><span class="chem-list-val">1921 mg/L</span></div>
<div class="chem-list-item"><span>混合液回流泵</span><span class="chem-list-val">8340 mg/L</span></div>
</div>
</div>
<div class="section-header-small" style="top: 520px; left: 1480px;">质量指标</div>
<div class="quality-table-container">
<table class="q-table">
<thead>
<tr><th>参数</th><th>当前值</th><th>平均值</th><th>最高</th><th>最低</th><th>指标</th></tr>
</thead>
<tbody>
<tr><td>COD (mg/L)</td><td>13.106</td><td>12.996</td><td>14.656</td><td>11.92</td><td>0.000-20.000</td></tr>
<tr><td>TP (mg/L)</td><td>13.106</td><td>12.996</td><td>14.656</td><td>11.92</td><td>0.000-20.000</td></tr>
<tr><td>NH3-N (mg/L)</td><td>13.106</td><td>12.996</td><td>14.656</td><td>11.92</td><td>0.000-20.000</td></tr>
<tr><td>TN (mg/L)</td><td>13.106</td><td>12.996</td><td>14.656</td><td>11.92</td><td>0.000-20.000</td></tr>
<tr><td>PH (mg/L)</td><td>13.106</td><td>12.996</td><td>14.656</td><td>11.92</td><td>0.000-20.000</td></tr>
<tr><td>SS</td><td>13.106</td><td>12.996</td><td>14.656</td><td>11.92</td><td></td></tr>
<tr><td>温度(°C)</td><td>13.106</td><td>12.996</td><td>14.656</td><td>11.92</td><td></td></tr>
</tbody>
</table>
</div>
<div class="chart-quality-container" id="chartQuality"></div>
<!-- Center Column -->
<div class="center-point cp-1">
<div class="cp-label">泵房液位</div>
<div class="cp-val">6.13 m</div>
</div>
<div class="center-point cp-2">
<div class="cp-label">进水泵房1#电流</div>
<div class="cp-val">66.6 A</div>
</div>
<div class="center-point cp-3">
<div class="cp-label">进水泵房2#电流</div>
<div class="cp-val">63.1 A</div>
</div>
<div class="center-point cp-4">
<div class="cp-label">进水泵房3#流量</div>
<div class="cp-val">2.84 L/s</div>
</div>
<div class="center-point cp-5">
<div class="cp-label">外回流泵1#流量</div>
<div class="cp-val">13.02 L/s</div>
</div>
<div class="center-point cp-6">
<div class="cp-label">外回流泵2#液位</div>
<div class="cp-val">0.75 m</div>
</div>
<div class="center-point cp-7">
<div class="cp-label">生化池剩余污泥泵</div>
<div class="cp-val">0 m</div>
</div>
<div class="center-point cp-8">
<div class="cp-label">沉淀池剩余污泥泵</div>
<div class="cp-val">9.01 L/s</div>
</div>
<div class="center-point cp-9">
<div class="cp-label">PAC加药流量</div>
<div class="cp-val">1.03 L/s</div>
</div>
<div class="center-point cp-10">
<div class="cp-label">PAC储罐液位</div>
<div class="cp-val">4.2 m</div>
</div>
<!-- Right Data Column -->
<div class="right-data-col">
<div class="section-block">
<div class="section-title">进水</div>
<div class="data-grid-2col">
<div class="data-item"><div class="data-item-label">进水流量</div><div class="data-item-val">1360 m³/h</div></div>
<div class="data-item"><div class="data-item-label">进水PH</div><div class="data-item-val">6.75</div></div>
<div class="data-item"><div class="data-item-label">进水COD</div><div class="data-item-val">82.4 mg/L</div></div>
<div class="data-item"><div class="data-item-label">进水氨氮</div><div class="data-item-val">15.30 mg/L</div></div>
<div class="data-item"><div class="data-item-label">进水温度</div><div class="data-item-val">25.87 °C</div></div>
<div class="data-item"><div class="data-item-label">进水累计流量</div><div class="data-item-val">1761406 m³</div></div>
</div>
</div>
<div class="section-block">
<div class="section-title">出水</div>
<div class="data-grid-2col">
<div class="data-item"><div class="data-item-label">出水流量</div><div class="data-item-val">2451.64 m³/h</div></div>
<div class="data-item"><div class="data-item-label">出水PH</div><div class="data-item-val">6.95</div></div>
<div class="data-item"><div class="data-item-label">出水COD</div><div class="data-item-val">62.4 mg/L</div></div>
<div class="data-item"><div class="data-item-label">出水氨氮</div><div class="data-item-val">15.18 mg/L</div></div>
<div class="data-item"><div class="data-item-label">出水温度</div><div class="data-item-val">25.87 °C</div></div>
<div class="data-item"><div class="data-item-label">出水总磷</div><div class="data-item-val">25.87</div></div>
<div class="data-item"><div class="data-item-label">出水总氮</div><div class="data-item-val">25.87</div></div>
<div class="data-item"><div class="data-item-label">出水累计流量</div><div class="data-item-val">1761406 m³</div></div>
</div>
</div>
<div class="section-block">
<div class="section-title">其他</div>
<div class="data-grid-2col">
<div class="data-item"><div class="data-item-label">反冲洗泵1#电流</div><div class="data-item-val">6.72 m³/h</div></div>
<div class="data-item"><div class="data-item-label">反冲洗泵2#压力</div><div class="data-item-val">66.67 MPa</div></div>
<div class="data-item"><div class="data-item-label">剩余污泥泵1#流量</div><div class="data-item-val">71.34 m³/h</div></div>
</div>
</div>
<div class="section-block">
<div class="section-title">液位</div>
<div class="data-grid-2col">
<div class="data-item"><div class="data-item-label">清水池液位</div><div class="data-item-val">5.05 m</div></div>
<div class="data-item"><div class="data-item-label">深床滤池液位</div><div class="data-item-val">4.03 m</div></div>
</div>
</div>
</div>
<!-- Video Column -->
<div class="video-container">
<div class="video-box"><div class="play-icon">▶</div></div>
<div class="video-box"><div class="play-icon">▶</div></div>
<div class="video-box"><div class="play-icon">▶</div></div>
<div class="video-box"><div class="play-icon">▶</div></div>
<div class="video-box"><div class="play-icon">▶</div></div>
<div class="video-box"><div class="play-icon">▶</div></div>
<div class="video-box"><div class="play-icon">▶</div></div>
<div class="video-box"><div class="play-icon">▶</div></div>
</div>
</div>
<script>
window.onload = function() {
initCharts();
updateTime();
setInterval(updateTime, 1000);
document.ondblclick = function() {
var docElm = document.documentElement;
if (docElm.requestFullscreen) {
docElm.requestFullscreen();
}
}
};
function updateTime() {
var now = new Date();
var timeStr = now.getFullYear() + '.' + (now.getMonth()+1) + '.' + now.getDate() + ' 星期三 ' +
now.getHours() + ':' + (now.getMinutes()<10?'0':'') + now.getMinutes() + ':' + (now.getSeconds()<10?'0':'') + now.getSeconds();
document.getElementById('headerTime').innerHTML = timeStr;
}
function initCharts() {
// Water Chart (7-Day)
var waterChart = echarts.init(document.getElementById('chartWater'));
var waterOption = {
color: ['#00eaff'],
tooltip: { trigger: 'axis' },
grid: { top: '10%', left: '3%', right: '4%', bottom: '3%', containLabel: true },
xAxis: {
type: 'category',
data: ['11-10', '11-11', '11-12', '11-13', '11-14', '11-15', '11-16'],
axisLabel: { color: '#fff', fontSize: 24 },
axisLine: { lineStyle: { color: '#0055aa' } }
},
yAxis: {
type: 'value',
axisLabel: { color: '#fff', fontSize: 24 },
splitLine: { show: false },
axisLine: { show: false }
},
series: [{
data: [3000, 4200, 3500, 3800, 5000, 4800, 5200],
type: 'bar',
barWidth: '20px',
itemStyle: { normal: { barBorderRadius: [10, 10, 0, 0] } }
}]
};
waterChart.setOption(waterOption);
// Sludge Chart (Area)
var sludgeChart = echarts.init(document.getElementById('chartSludge'));
var sludgeOption = {
color: ['#00ffaa'],
tooltip: { trigger: 'axis' },
grid: { top: '10%', left: '3%', right: '4%', bottom: '3%', containLabel: true },
xAxis: {
type: 'category',
boundaryGap: false,
data: ['2:00', '4:00', '6:00', '8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00'],
axisLabel: { color: '#fff', fontSize: 20 },
axisLine: { lineStyle: { color: '#0055aa' } }
},
yAxis: {
type: 'value',
axisLabel: { color: '#fff', fontSize: 20 },
splitLine: { show: false },
axisLine: { show: false }
},
series: [{
data: [50, 80, 60, 120, 150, 140, 130, 160, 180, 100],
type: 'line',
smooth: true,
areaStyle: { opacity: 0.3 }
}]
};
sludgeChart.setOption(sludgeOption);
// Quality Chart (Line)
var qualityChart = echarts.init(document.getElementById('chartQuality'));
var qualityOption = {
color: ['#00aaff'],
tooltip: { trigger: 'axis' },
grid: { top: '10%', left: '3%', right: '4%', bottom: '3%', containLabel: true },
xAxis: {
type: 'category',
boundaryGap: false,
data: ['11', '12', '13', '14', '15', '16', '17', '18', '19'],
axisLabel: { color: '#fff', fontSize: 20 },
axisLine: { lineStyle: { color: '#0055aa' } }
},
yAxis: {
type: 'value',
axisLabel: { color: '#fff', fontSize: 20 },
splitLine: { show: false },
axisLine: { show: false }
},
series: [{
data: [15, 18, 16, 20, 22, 21, 25, 24, 23],
type: 'line',
smooth: true,
areaStyle: { opacity: 0.3 }
}]
};
qualityChart.setOption(qualityOption);
}
</script>
</body>
</html>

View File

@ -20,11 +20,49 @@
background-repeat: no-repeat;
position: relative;
}
/* Specific Position for Data 6040 */
.val-6040 {
position: absolute;
top: 335px;
left: 209px;
width: 121px;
height: 62px;
color: rgba(255, 255, 255, 1);
font-family: 'Gilroy', 'DIN Alternate', 'Arial Narrow', sans-serif;
font-weight: 900;
font-size: 50px;
z-index: 10;
text-align: center;
line-height: 62px;
}
.val-4197 {
top: 335px;
left: 592px;
width: fit-content;
height: fit-content;
display: inline-flex;
place-content: flex-start;
place-items: flex-end;
gap: 8px;
}
.val-12356 {
top: 335px;
left: 975px;
width: fit-content;
height: fit-content;
display: inline-flex;
place-content: flex-start;
place-items: flex-end;
gap: 8px;
}
</style>
</head>
<body>
<div class="screen-container">
<!-- Content placeholder -->
<div class="val-6040">6040</div>
<div class="val-4197">4197</div>
<div class="val-12356">12356</div>
</div>
</body>
</html>

View File

@ -4,6 +4,8 @@
<head>
<meta charset="UTF-8">
<title>区域管线大屏展示</title>
<script type="text/javascript" src="<%=request.getContextPath()%>/node_modules/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/JS/echarts3.0.js"></script>
<style>
body, html {
margin: 0;
@ -11,6 +13,8 @@
width: 100%;
height: 100%;
overflow: auto;
background-color: #030829;
font-family: "Microsoft YaHei", sans-serif;
}
.screen-container {
width: 6500px;
@ -20,10 +24,312 @@
background-repeat: no-repeat;
position: relative;
}
/* Module Container */
.rank-module-container {
position: absolute;
top: 356px;
left: 198px;
width: 1900px;
height: 1400px;
/* background: rgba(255, 0, 0, 0.1); Debugging background */
display: flex;
flex-direction: column;
padding: 20px;
box-sizing: border-box;
}
/* Statistics Header */
.stats-header {
width: 100%;
height: 180px;
display: flex;
justify-content: space-around;
align-items: center;
background: rgba(0, 20, 50, 0.3);
border: 1px solid rgba(0, 234, 255, 0.2);
border-radius: 12px;
margin-bottom: 30px;
backdrop-filter: blur(10px);
}
.stat-item {
text-align: center;
}
.stat-label {
font-size: 32px;
color: #00eaff;
margin-bottom: 10px;
}
.stat-value {
font-size: 64px;
font-weight: bold;
color: #ffffff;
font-family: 'DIN Alternate', 'Arial Narrow', sans-serif;
text-shadow: 0 0 20px rgba(0, 234, 255, 0.5);
}
.stat-unit {
font-size: 24px;
color: #aaaaaa;
margin-left: 5px;
}
/* Charts Area */
.charts-wrapper {
flex: 1;
display: flex;
gap: 40px;
}
.chart-box {
flex: 1;
background: rgba(0, 20, 50, 0.3);
border: 1px solid rgba(0, 234, 255, 0.2);
border-radius: 12px;
padding: 20px;
display: flex;
flex-direction: column;
backdrop-filter: blur(10px);
}
.chart-title {
font-size: 36px;
color: #ffffff;
text-align: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid rgba(0, 234, 255, 0.2);
}
.chart-content {
flex: 1;
width: 100%;
}
</style>
</head>
<body>
<div class="screen-container">
<div class="rank-module-container">
<!-- Statistics -->
<div class="stats-header">
<div class="stat-item">
<div class="stat-label">辖区排污企业总数</div>
<div class="stat-value" id="totalCount">0<span class="stat-unit">家</span></div>
</div>
<div class="stat-item">
<div class="stat-label">已接入监控</div>
<div class="stat-value" style="color: #00ff00;" id="connectedCount">0<span class="stat-unit">家</span></div>
</div>
<div class="stat-item">
<div class="stat-label">正在接入中</div>
<div class="stat-value" style="color: #ffaa00;" id="connectingCount">0<span class="stat-unit">家</span></div>
</div>
</div>
<!-- Charts -->
<div class="charts-wrapper">
<div class="chart-box">
<div class="chart-title">近30日排污量 TOP 10 (最大)</div>
<div id="chartMax" class="chart-content"></div>
</div>
<div class="chart-box">
<div class="chart-title">近30日排污量 TOP 10 (最小)</div>
<div id="chartMin" class="chart-content"></div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
initData();
});
function initData() {
// Mock Data Generation
var enterprises = [];
var total = 158;
var connected = 124;
var connecting = 34;
// Update Stats
$('#totalCount').html(total + '<span class="stat-unit">家</span>');
$('#connectedCount').html(connected + '<span class="stat-unit">家</span>');
$('#connectingCount').html(connecting + '<span class="stat-unit">家</span>');
// Generate random enterprise data
for (var i = 1; i <= 50; i++) {
enterprises.push({
name: '企业-' + i,
value: Math.floor(Math.random() * 10000) + 500
});
}
// Sort for Max
var sortedMax = [...enterprises].sort((a, b) => b.value - a.value).slice(0, 10);
// Sort for Min
var sortedMin = [...enterprises].sort((a, b) => a.value - b.value).slice(0, 10);
renderCharts(sortedMax, sortedMin);
}
function renderCharts(maxData, minData) {
var chartMax = echarts.init(document.getElementById('chartMax'));
var chartMin = echarts.init(document.getElementById('chartMin'));
// Max Option
var optionMax = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value',
axisLabel: { color: '#fff', fontSize: 16 },
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }
},
yAxis: {
type: 'category',
data: maxData.map(item => item.name).reverse(),
axisLabel: { color: '#fff', fontSize: 18 },
axisLine: { lineStyle: { color: '#00eaff' } }
},
series: [{
name: '排污量',
type: 'bar',
data: maxData.map(item => item.value).reverse(),
label: { show: true, position: 'right', color: '#fff', fontSize: 16 },
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
offset: 0, color: '#ff5500'
}, {
offset: 1, color: '#ffbb00'
}]),
barBorderRadius: [0, 10, 10, 0]
}
},
barWidth: 40,
animationDuration: 2000,
animationEasing: 'cubicOut'
}]
};
// Min Option
var optionMin = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value',
axisLabel: { color: '#fff', fontSize: 16 },
splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }
},
yAxis: {
type: 'category',
data: minData.map(item => item.name).reverse(),
axisLabel: { color: '#fff', fontSize: 18 },
axisLine: { lineStyle: { color: '#00eaff' } }
},
series: [{
name: '排污量',
type: 'bar',
data: minData.map(item => item.value).reverse(),
label: { show: true, position: 'right', color: '#fff', fontSize: 16 },
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
offset: 0, color: '#00aa00'
}, {
offset: 1, color: '#00ff00'
}]),
barBorderRadius: [0, 10, 10, 0]
}
},
barWidth: 40,
animationDuration: 2000,
animationEasing: 'cubicOut'
}]
};
chartMax.setOption(optionMax);
chartMin.setOption(optionMin);
// Dynamic Sort Simulation (Update every 3 seconds)
setInterval(function() {
// Randomly change values slightly
maxData.forEach(item => {
item.value += Math.floor(Math.random() * 200) - 100;
if(item.value < 0) item.value = 0;
});
// Re-sort
maxData.sort((a, b) => a.value - b.value); // For horizontal bar, small index is bottom. ECharts draws category 0 at bottom.
// Actually in my code I used reverse() so data is Top to Bottom visually if array is Descending.
// Let's keep data array as Ascending (Small -> Large) so index 0 is at bottom (or top depending on axis inverse).
// Default category axis: index 0 at bottom.
// If I want Top 1 at top, I need index 0 to be the smallest value (if not inverse) or configure axis.
// In previous code: data: maxData.map(item => item.name).reverse()
// If maxData was sorted Descending (Large -> Small), then reverse makes it Small -> Large.
// So index 0 (bottom) is Smallest of the top 10. Index 9 (top) is Largest. Correct.
// Let's just re-sort the source array Descending
maxData.sort((a, b) => b.value - a.value);
// Update chart
chartMax.setOption({
yAxis: {
data: maxData.map(item => item.name).reverse()
},
series: [{
data: maxData.map(item => item.value).reverse()
}]
});
// Do same for Min? Min usually doesn't fluctuate as much to swap "Top Min", but let's simulate.
minData.forEach(item => {
item.value += Math.floor(Math.random() * 50) - 25;
if(item.value < 0) item.value = 0;
});
minData.sort((a, b) => a.value - b.value); // Small -> Large.
// Display: I want Smallest at Top? Or Largest of the Smallest at Top?
// Usually "Top 10 Min" means the 10 smallest values.
// Visualizing: Smallest bar at Top.
// If data is [1, 2, 3...], and I reverse it -> [..., 3, 2, 1].
// Index 0 (bottom) = 10. Index 9 (top) = 1.
// So I need the array to be sorted Small -> Large.
// Then reverse it -> Large -> Small.
// Then bottom (index 0) is Large. Top (index 9) is Small.
// Correct.
chartMin.setOption({
yAxis: {
data: minData.map(item => item.name).reverse()
},
series: [{
data: minData.map(item => item.value).reverse()
}]
});
}, 3000);
}
</script>
</body>
</html>