Files
SIPAIIS_WMS_JSSW/src/main/webapp/jsp/visual/newSourceGISPage.jsp
2026-03-01 23:40:06 +08:00

1745 lines
90 KiB
Plaintext

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>源头GIS管理</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="../../node_modules/bootstrap/dist/css/bootstrap.min.css">
<!-- DateRangePicker CSS -->
<link rel="stylesheet" href="../../plugins/bootstrap-daterangepicker/daterangepicker.css">
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#map-container {
width: 100%;
height: 100%;
}
.control-panel {
position: absolute;
top: 20px;
left: 20px;
z-index: 1000;
background-color: rgba(255, 255, 255, 0.9);
padding: 15px;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
width: 250px;
}
.legend-item {
margin-bottom: 5px;
display: flex;
align-items: center;
}
.legend-color {
width: 20px;
height: 20px;
margin-right: 10px;
border-radius: 50%;
}
.status-normal { background-color: green; }
.status-warning { background-color: #FFCC00; }
.status-alarm { background-color: red; }
/* Right Drawer Styles */
.drawer-container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 480px;
background-color: #fff;
z-index: 2000;
box-shadow: -2px 0 5px rgba(0,0,0,0.1);
display: flex;
transition: transform 0.3s ease;
}
.drawer-collapsed {
transform: translateX(100%);
}
.drawer-resizer {
width: 5px;
cursor: col-resize;
background-color: transparent;
position: absolute;
left: 0;
top: 0;
bottom: 0;
z-index: 2001;
}
.drawer-resizer:hover {
background-color: #007bff;
}
.drawer-toggle {
position: absolute;
left: -20px;
top: 50%;
width: 20px;
height: 60px;
margin-top: -30px;
background: #fff;
border: 1px solid #ddd;
border-right: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px 0 0 4px;
color: #007bff;
box-shadow: -2px 0 5px rgba(0,0,0,0.05);
}
.drawer-sidebar {
width: 80px;
background-color: #f0f4f7;
border-right: 1px solid #ddd;
display: flex;
flex-direction: column;
overflow-y: auto;
}
.drawer-nav-item {
padding: 15px 5px;
text-align: center;
cursor: pointer;
font-size: 13px;
border-bottom: 1px solid #e1e4e8;
color: #666;
transition: all 0.2s;
}
.drawer-nav-item:hover {
background-color: #e1e8ed;
color: #007bff;
}
.drawer-nav-item.active {
background-color: #fff;
color: #007bff;
border-left: 3px solid #007bff;
font-weight: bold;
margin-right: -1px; /* Cover border */
}
.drawer-nav-icon {
width: 15px;
height: 15px;
margin: 0 auto 5px auto;
display: block;
}
.drawer-content {
flex: 1;
padding: 15px;
overflow-y: auto;
background: #fff;
}
.tab-pane {
display: none;
}
.tab-pane.active {
display: block;
}
/* Table Styles */
.table-custom th {
background-color: #f8f9fa;
font-weight: 600;
}
.table-custom td {
vertical-align: middle;
}
.query-form-group {
margin-bottom: 15px;
}
.query-form-group label {
font-weight: normal;
margin-bottom: 5px;
display: block;
}
/* Pulse Animation for Map Marker */
@keyframes pulse-ring {
0% {
transform: scale(0.33);
opacity: 1;
}
80%, 100% {
transform: scale(2.5);
opacity: 0;
}
}
.pulse-ring {
position: relative;
width: 30px;
height: 30px;
}
.pulse-ring::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 123, 255, 0.7);
border-radius: 50%;
animation: pulse-ring 1.5s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}
</style>
</head>
<body>
<!-- Right Drawer -->
<div class="drawer-container" id="rightDrawer">
<div class="drawer-resizer" id="drawerResizer"></div>
<div class="drawer-toggle" onclick="toggleDrawer()" title="收起/展开">
<span id="drawer-toggle-icon">&gt;</span>
</div>
<div class="drawer-sidebar">
<div class="drawer-nav-item active" onclick="switchTab('tab-sewage', this)">
<img src="../../IMG/icon_wsc.png" class="drawer-nav-icon">污水厂
</div>
<div class="drawer-nav-item" onclick="switchTab('tab-pump', this)">
<img src="../../IMG/icon_bz.png" class="drawer-nav-icon">泵站
</div>
<div class="drawer-nav-item" onclick="switchTab('tab-company', this)">
<img src="../../IMG/icon_qy.png" class="drawer-nav-icon">企业
</div>
<div class="drawer-nav-item" onclick="switchTab('tab-pipeline', this)">
<img src="../../IMG/icon_gd.png" class="drawer-nav-icon">管道
</div>
<div class="drawer-nav-item" onclick="switchTab('tab-well', this)">
<img src="../../IMG/icon_gj.png" class="drawer-nav-icon">管井
</div>
<div class="drawer-nav-item" onclick="switchTab('tab-plan', this)">
<img src="../../IMG/icon_jh.png" class="drawer-nav-icon">巡检计划
</div>
<div class="drawer-nav-item" onclick="switchTab('tab-record', this)">
<img src="../../IMG/icon_jl.png" class="drawer-nav-icon">巡检记录
</div>
</div>
<div class="drawer-content">
<!-- 污水厂 Content -->
<div id="tab-sewage" class="tab-pane active">
<h5 style="border-bottom: 1px solid #eee; padding-bottom: 10px; margin-top: 0;">污水厂查询</h5>
<div class="well well-sm" style="background: white; border: none; box-shadow: none; padding: 0;">
<div class="query-form-group">
<label>时间范围</label>
<div style="display: flex; align-items: center;">
<div class="input-group date">
<input type="text" class="form-control input-sm" id="sewage-time-start" value="2026-02-02 16:47">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
<span style="margin: 0 5px;">~</span>
<div class="input-group date">
<input type="text" class="form-control input-sm" id="sewage-time-end" value="2026-02-09 16:47">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
</div>
</div>
<div class="query-form-group">
<label>流量范围 (m³/h)</label>
<div style="display: flex; align-items: center;">
<input type="number" class="form-control input-sm" placeholder="最小值">
<span style="margin: 0 5px;">~</span>
<input type="number" class="form-control input-sm" placeholder="最大值">
</div>
</div>
<div class="query-form-group">
<label>厂站名称</label>
<div class="input-group">
<input type="text" class="form-control" placeholder="请输入厂站名称">
<span class="input-group-btn">
<button class="btn btn-primary" type="button"><i class="glyphicon glyphicon-search"></i> 查询</button>
<button class="btn btn-default" type="button" style="margin-left: 5px;">校准</button>
</span>
</div>
</div>
</div>
<div style="margin-bottom: 10px;">
<label><input type="checkbox" checked> 显示标注</label>
</div>
<table class="table table-bordered table-hover table-condensed table-custom" style="font-size: 12px;">
<thead>
<tr>
<th width="40">序号</th>
<th width="40">选择</th>
<th>名称</th>
<th>出口流量<br>(m³/h)</th>
<th>入口流量<br>(m³/h)</th>
<th>状态</th>
<th>设计能力<br>(万吨/天)</th>
<th>详细地址</th>
<th>监测时间</th>
</tr>
</thead>
<tbody id="sewage-table-body">
<!-- Populated by initSewageTable -->
</tbody>
</table>
</div>
<!-- 泵站 Content -->
<div id="tab-pump" class="tab-pane">
<h5 style="border-bottom: 1px solid #eee; padding-bottom: 10px; margin-top: 0;">泵站查询</h5>
<div class="well well-sm" style="background: white; border: none; box-shadow: none; padding: 0;">
<div class="query-form-group">
<label>时间范围</label>
<div style="display: flex; align-items: center;">
<div class="input-group date">
<input type="text" class="form-control input-sm" id="pump-time-start" value="2026-01-09 00:00">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
<span style="margin: 0 5px;">~</span>
<div class="input-group date">
<input type="text" class="form-control input-sm" id="pump-time-end" value="2026-02-09 17:15">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
</div>
</div>
<div class="query-form-group">
<label>泵站名称</label>
<div class="input-group">
<input type="text" class="form-control" placeholder="请输入泵站名称">
<span class="input-group-btn">
<button class="btn btn-primary" type="button"><i class="glyphicon glyphicon-search"></i> 查询</button>
</span>
</div>
</div>
</div>
<div style="margin-bottom: 10px;">
<label><input type="checkbox" checked> 显示标注</label>
</div>
<div style="max-height: 500px; overflow-y: auto;">
<table class="table table-bordered table-hover table-condensed table-custom" style="font-size: 12px;">
<thead>
<tr>
<th width="40">序号</th>
<th>泵站名称</th>
<th>液位(m)</th>
<th>流量(m³/h)</th>
<th>状态</th>
<th>监测时间</th>
</tr>
</thead>
<tbody id="pump-table-body">
<!-- Mock Data populated by JS -->
</tbody>
</table>
</div>
</div>
<!-- Company Content -->
<div id="tab-company" class="tab-pane">
<h5 style="border-bottom: 1px solid #eee; padding-bottom: 10px; margin-top: 0;">企业查询</h5>
<div class="well well-sm" style="background: white; border: none; box-shadow: none; padding: 0;">
<div class="query-form-group">
<label>时间范围</label>
<div style="display: flex; align-items: center;">
<div class="input-group date">
<input type="text" class="form-control input-sm" id="company-time-start" value="2026-01-09 00:00">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
<span style="margin: 0 5px;">~</span>
<div class="input-group date">
<input type="text" class="form-control input-sm" id="company-time-end" value="2026-02-09 17:15">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
</div>
</div>
<div class="query-form-group">
<label>企业名称</label>
<div class="input-group">
<input type="text" class="form-control" placeholder="请输入企业名称">
<span class="input-group-btn">
<button class="btn btn-primary" type="button"><i class="glyphicon glyphicon-search"></i> 查询</button>
</span>
</div>
</div>
</div>
<div style="margin-bottom: 10px;">
<label><input type="checkbox" checked> 显示标注</label>
</div>
<div style="max-height: 500px; overflow-y: auto;">
<table class="table table-bordered table-hover table-condensed table-custom" style="font-size: 12px; white-space: nowrap;">
<thead>
<tr>
<th width="40">序号</th>
<th>编号</th>
<th>名称</th>
<th>地址</th>
<th>污水厂编号</th>
<th>排放编号</th>
<th>日排放量</th>
<th>日排放点位</th>
</tr>
</thead>
<tbody id="company-table-body">
</tbody>
</table>
</div>
</div>
<!-- Pipeline Content -->
<div id="tab-pipeline" class="tab-pane">
<h5 style="border-bottom: 1px solid #eee; padding-bottom: 10px; margin-top: 0;">管道查询</h5>
<div class="well well-sm" style="background: white; border: none; box-shadow: none; padding: 0;">
<div class="row">
<div class="col-xs-6" style="padding-right: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="管道名称">
</div>
</div>
<div class="col-xs-6" style="padding-left: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="管道材质">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6" style="padding-right: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="管道管长">
</div>
</div>
<div class="col-xs-6" style="padding-left: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="管道管径">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6" style="padding-right: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="起点埋深">
</div>
</div>
<div class="col-xs-6" style="padding-left: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="终点埋深">
</div>
</div>
</div>
<div class="form-group">
<select class="form-control input-sm">
<option>所属厂站: 全部</option>
</select>
</div>
<div style="margin-top: 10px;">
<button class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> 查询</button>
</div>
</div>
<div style="max-height: 400px; overflow-y: auto; overflow-x: auto;">
<table class="table table-bordered table-hover table-condensed table-custom" style="font-size: 12px; white-space: nowrap; min-width: 800px;">
<thead>
<tr>
<th width="40">选择</th>
<th width="40">序号</th>
<th>管道名称</th>
<th>管径(mm)</th>
<th>管长(m)</th>
<th>起点埋深(m)</th>
<th>终点埋深(m)</th>
<th>起点地面高程(m)</th>
<th>终点地面高程(m)</th>
<th>管线内底标高(m)</th>
</tr>
</thead>
<tbody id="pipeline-table-body">
</tbody>
<tfoot>
<tr style="background-color: #e9ecef; font-weight: bold; color: blue;">
<td colspan="2">汇总:</td>
<td>--</td>
<td id="pipe-total-diameter">2561416.00</td>
<td id="pipe-total-length">109253.23</td>
<td colspan="5">--</td>
</tr>
</tfoot>
</table>
</div>
</div>
<!-- Well Content -->
<div id="tab-well" class="tab-pane">
<h5 style="border-bottom: 1px solid #eee; padding-bottom: 10px; margin-top: 0;">管井查询</h5>
<div class="well well-sm" style="background: white; border: none; box-shadow: none; padding: 0;">
<div class="row">
<div class="col-xs-6" style="padding-right: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="管井名称">
</div>
</div>
<div class="col-xs-6" style="padding-left: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="管井材质">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6" style="padding-right: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="管井埋深">
</div>
</div>
<div class="col-xs-6" style="padding-left: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="井底高程">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6" style="padding-right: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="地面高程">
</div>
</div>
<div class="col-xs-6" style="padding-left: 5px;">
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="管井规格">
</div>
</div>
</div>
<div class="form-group">
<select class="form-control input-sm">
<option>所属厂站: 全部</option>
</select>
</div>
<div style="margin-top: 10px;">
<button class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> 查询</button>
</div>
</div>
<div style="max-height: 400px; overflow-y: auto; overflow-x: auto;">
<table class="table table-bordered table-hover table-condensed table-custom" style="font-size: 12px; white-space: nowrap; min-width: 800px;">
<thead>
<tr>
<th width="40">选择</th>
<th width="40">序号</th>
<th>管井名称</th>
<th>埋深(m)</th>
<th>井底标高(m)</th>
<th>地面高程(m)</th>
<th>规格(mm)</th>
<th>经度</th>
<th>纬度</th>
</tr>
</thead>
<tbody id="well-table-body">
</tbody>
</table>
</div>
</div>
<div id="tab-plan" class="tab-pane">
<h5 style="border-bottom: 1px solid #eee; padding-bottom: 10px; margin-top: 0;">巡检计划</h5>
<div class="well well-sm" style="background: white; border: none; box-shadow: none; padding: 0;">
<div class="form-group form-inline" style="margin-bottom: 10px;">
<label>所属厂站 </label>
<select class="form-control input-sm" style="width: 150px;">
<option>金山排海一车间</option>
<option>金山排海二车间</option>
</select>
</div>
<div style="margin-bottom: 5px;">
<button class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> 查询</button>
</div>
</div>
<div style="max-height: 400px; overflow-y: auto;">
<table class="table table-bordered table-hover table-condensed table-custom" style="font-size: 12px; white-space: nowrap;">
<thead>
<tr>
<th width="40">选择</th>
<th width="40">序号</th>
<th>任务名称</th>
<th>启用状态</th>
<th>巡检时长</th>
<th>巡检间隔</th>
<th>开始时间</th>
<th>结束时间</th>
</tr>
</thead>
<tbody id="plan-table-body">
</tbody>
</table>
</div>
</div>
<div id="tab-record" class="tab-pane">
<h5 style="border-bottom: 1px solid #eee; padding-bottom: 10px; margin-top: 0;">巡检记录</h5>
<div class="well well-sm" style="background: white; border: none; box-shadow: none; padding: 0;">
<div class="row" style="margin-bottom: 10px;">
<div class="col-xs-12">
<form class="form-inline">
<div class="form-group" style="margin-right: 10px;">
<label>所属厂站</label>
<select class="form-control input-sm" style="width: 150px;">
<option>金山排海一车间</option>
<option>金山排海二车间</option>
</select>
</div>
<div class="form-group">
<label>巡检日期</label>
<div class="input-group date">
<input type="text" class="form-control input-sm" id="record-date" value="2026-02-11" style="width: 120px;">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</div>
</div>
</form>
</div>
</div>
<div class="row" style="margin-bottom: 5px;">
<div class="col-xs-12">
<button class="btn btn-primary btn-sm" style="background-color: #0099ff; border-color: #0099ff;"><i class="glyphicon glyphicon-search"></i> 查询</button>
</div>
</div>
</div>
<div style="max-height: 400px; overflow-y: auto; position: relative; min-height: 300px;">
<div id="record-loading" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; display: none;">
<i class="glyphicon glyphicon-refresh" style="font-size: 32px; color: #ccc; animation: spin 1s infinite linear;"></i>
<p style="margin-top: 10px; color: #666; font-size: 12px;">数据载入中,请稍后......</p>
<style>@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }</style>
</div>
<table class="table table-bordered table-hover table-condensed table-custom" style="font-size: 12px; white-space: nowrap;">
<thead>
<tr style="background-color: #f0f0f0;">
<th width="40">选择</th>
<th width="40">序号</th>
<th>任务名称</th>
<th>完成状态</th>
<th>计划开始时间</th>
<th>计划结束时间</th>
<th>实际完成时间</th>
</tr>
</thead>
<tbody id="record-table-body">
</tbody>
</table>
</div>
</div>
</div>
</div>
<div id="map-container"></div>
<!-- Scripts -->
<script src="../../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Tianditu Map API -->
<!-- 704ebaecb29ce869b41f7d64a88919bc -->
<script type="text/javascript" src="http://api.tianditu.gov.cn/api?v=4.0&tk=f423193014cde7bf44b224c6ab2b1210"></script>
<script type="text/javascript">
// 坐标转换工具 (百度 BD-09 <-> 火星 GCJ-02 <-> 天地图/GPS WGS-84)
var CoordTransform = {
x_pi: 3.14159265358979324 * 3000.0 / 180.0,
pi: 3.1415926535897932384626,
a: 6378245.0,
ee: 0.00669342162296594323,
// 百度坐标 (BD-09) 转 火星坐标 (GCJ-02)
bd09_to_gcj02: function (bd_lon, bd_lat) {
var x = bd_lon - 0.0065;
var y = bd_lat - 0.006;
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi);
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi);
var gg_lng = z * Math.cos(theta);
var gg_lat = z * Math.sin(theta);
return [gg_lng, gg_lat];
},
// 火星坐标 (GCJ-02) 转 GPS 坐标 (WGS-84)
gcj02_to_wgs84: function (lng, lat) {
if (this.out_of_china(lng, lat)) {
return [lng, lat];
}
var dlat = this.transformlat(lng - 105.0, lat - 35.0);
var dlng = this.transformlng(lng - 105.0, lat - 35.0);
var radlat = lat / 180.0 * this.pi;
var magic = Math.sin(radlat);
magic = 1 - this.ee * magic * magic;
var sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.pi);
dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.pi);
var mglat = lat + dlat;
var mglng = lng + dlng;
return [lng * 2 - mglng, lat * 2 - mglat];
},
// 百度坐标 (BD-09) 直接转 天地图/GPS 坐标 (WGS-84)
bd09_to_wgs84: function (bd_lon, bd_lat) {
var gcj = this.bd09_to_gcj02(bd_lon, bd_lat);
var wgs = this.gcj02_to_wgs84(gcj[0], gcj[1]);
return wgs;
},
transformlat: function (lng, lat) {
var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * this.pi) + 20.0 * Math.sin(2.0 * lng * this.pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * this.pi) + 40.0 * Math.sin(lat / 3.0 * this.pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * this.pi) + 320 * Math.sin(lat * this.pi / 30.0)) * 2.0 / 3.0;
return ret;
},
transformlng: function (lng, lat) {
var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * this.pi) + 20.0 * Math.sin(2.0 * lng * this.pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * this.pi) + 40.0 * Math.sin(lng / 3.0 * this.pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * this.pi) + 300.0 * Math.sin(lng / 30.0 * this.pi)) * 2.0 / 3.0;
return ret;
},
out_of_china: function (lng, lat) {
return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
}
};
// Initialize Map
// Tianditu uses CGCS2000/WGS84 coordinates.
// Center on Shanghai Jinshan District
var map = new T.Map('map-container');
map.centerAndZoom(new T.LngLat(121.340000, 30.740000), 13);
map.enableScrollWheelZoom();
// Controls
var scale = new T.Control.Scale();
map.addControl(scale);
var zoom = new T.Control.Zoom();
map.addControl(zoom);
var mapType = new T.Control.MapType();
map.addControl(mapType);
// var mousePosition = new T.Control.MousePosition({position: T_ANCHOR_BOTTOM_RIGHT});
// map.addControl(mousePosition);
// Data Containers
var sources = [];
var pumpStations = [];
var companies = [];
var wells = [];
var pipelines = [];
var plans = [];
var records = [];
var markers = [];
// Mock API Function
function mockApiRequest(url, params) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('API Request:', url, params);
if (url === '/api/sewage/list') {
resolve([
{ id: 1, name: "金山水卫污水厂", lng: 121.345000, lat: 30.725000, status: 0, address: "上海金山区金山水卫污水厂", inFlow: 4774, outFlow: 4536, designCapacity: 10, time: "02-25 17:24" },
]);
} else if (url === '/api/pump/list') {
resolve([
{ id: 1, name: "亭林泵站", level: 4.17, flow: 240, status: "关", time: "02-11 18:02", lng: 121.320000, lat: 30.760000 },
{ id: 2, name: "天工路泵站", level: 3.87, flow: 0, status: "关", time: "02-11 18:02", lng: 121.350000, lat: 30.735000 },
{ id: 3, name: "月工路泵站", level: 6.66, flow: 0, status: "关", time: "02-11 18:02", lng: 121.340000, lat: 30.745000 },
]);
} else if (url === '/api/company/list') {
// Re-generate companies data here or move it inside
var comps = [];
for(var i=1; i<=10; i++) {
comps.push({
id: i,
code: "C" + (1000 + i),
name: "企业" + i,
address: "金山区某工业园路" + i + "号",
plantCode: "P" + (Math.floor(Math.random() * 2) + 1),
dischargeCode: "D" + (100 + i),
discharge: (Math.random() * 500 + 100).toFixed(2),
dischargePoint: "点位" + i,
lng: 121.300000 + Math.random() * 0.1,
lat: 30.700000 + Math.random() * 0.1
});
}
resolve(comps);
} else if (url === '/api/pipeline/list') {
// Re-generate pipelines
var pipes = [];
for(var i=1; i<=10; i++) {
var startLng = 121.320000 + Math.random() * 0.05;
var startLat = 30.720000 + Math.random() * 0.05;
var endLng = startLng + (Math.random() - 0.5) * 0.02;
var endLat = startLat + (Math.random() - 0.5) * 0.02;
pipes.push({
id: i,
name: "管道" + i,
diameter: [300, 400, 500, 600, 800][Math.floor(Math.random()*5)],
length: (Math.random() * 1000 + 100).toFixed(2),
startDepth: (Math.random() * 3 + 1).toFixed(2),
endDepth: (Math.random() * 3 + 1).toFixed(2),
startElev: (Math.random() * 5 + 2).toFixed(2),
endElev: (Math.random() * 5 + 2).toFixed(2),
bottomElev: (Math.random() * 2).toFixed(2),
path: [[startLng, startLat], [endLng, endLat]]
});
}
resolve(pipes);
} else if (url === '/api/well/list') {
var wls = [
{ id: 130, name: "WS80", depth: 5.4, bottomElev: -0.274, groundElev: 0, spec: "", lng: "3408260.03783626", lat: "342326.74725384", mapLng: 121.3205, mapLat: 30.7455 },
{ id: 131, name: "WS81", depth: 5.7, bottomElev: -0.217, groundElev: 0, spec: "", lng: "3408346.17691665", lat: "342317.71747325", mapLng: 121.3212, mapLat: 30.7448 },
{ id: 132, name: "WS82", depth: 5.0, bottomElev: 0.111, groundElev: 0, spec: "", lng: "3408547.22830375", lat: "342292.9836457", mapLng: 121.3222, mapLat: 30.7439 },
{ id: 133, name: "WS83", depth: 5.0, bottomElev: -0.085, groundElev: 0, spec: "", lng: "3408608.20411712", lat: "342283.77255922", mapLng: 121.3231, mapLat: 30.7432 },
];
wls = wls.map(function(item) {
return {
id: item.id,
name: item.name,
code: item.name,
pipeName: "",
pipeCode: "",
depth: item.depth,
nature: "",
attachment: "",
bottomElev: item.bottomElev,
lng: item.lng,
lat: item.lat,
mapLng: item.mapLng,
mapLat: item.mapLat,
road: "",
town: "",
zone: "",
surveyor: "",
angle: "",
calLng: "",
calLat: "",
spec: item.spec,
groundElev: item.groundElev
};
});
resolve(wls);
} else if (url === '/api/plan/list') {
resolve([
{ id: 1, name: "金山一车间周检", status: "启用", duration: "2小时", interval: "每周", start: "2026-02-01", end: "2026-12-31" },
{ id: 2, name: "泵站日常巡检", status: "启用", duration: "4小时", interval: "每日", start: "2026-02-01", end: "2026-12-31" },
{ id: 3, name: "管网全面排查", status: "停用", duration: "3天", interval: "每季度", start: "2026-01-01", end: "2026-03-31" }
]);
} else if (url === '/api/record/list') {
resolve([
{ id: 1, name: "金山一车间周检", status: "已完成", planStart: "2026-02-03 09:00", planEnd: "2026-02-03 11:00", actualEnd: "2026-02-03 10:45" },
{ id: 2, name: "泵站日常巡检", status: "已完成", planStart: "2026-02-08 08:00", planEnd: "2026-02-08 12:00", actualEnd: "2026-02-08 11:30" },
{ id: 3, name: "泵站日常巡检", status: "进行中", planStart: "2026-02-11 08:00", planEnd: "2026-02-11 12:00", actualEnd: "-" }
]);
} else {
reject("Unknown API Endpoint");
}
}, 500); // Simulate network delay
});
}
// Initialize Data
function loadData() {
Promise.all([
mockApiRequest('/api/sewage/list'),
mockApiRequest('/api/pump/list'),
mockApiRequest('/api/company/list'),
mockApiRequest('/api/pipeline/list'),
mockApiRequest('/api/well/list'),
mockApiRequest('/api/plan/list'),
mockApiRequest('/api/record/list'),
]).then(function(results) {
sources = results[0];
pumpStations = results[1];
companies = results[2];
pipelines = results[3];
wells = results[4];
plans = results[5];
records = results[6];
// Initialize View with default tab (Sewage)
initSewageTable();
initMarkers('sewage');
// Initialize other tables but they are hidden
initPumpTable();
initCompanyTable();
initPipelineTable();
initWellTable();
initPlanTable();
initRecordTable();
}).catch(function(err) {
console.error("Failed to load data:", err);
alert("数据加载失败,请重试");
});
}
// Call loadData instead of inline data definitions
loadData();
function initMarkers(dataType) {
// Close any open info window on the map
map.closeInfoWindow();
// Clear existing markers
markers.forEach(function(m) {
if (m.marker) map.removeOverLay(m.marker);
if (m.label) map.removeOverLay(m.label);
if (m.infoWindow) {
if (m.marker.closeInfoWindow) m.marker.closeInfoWindow();
}
});
markers = [];
if (currentPulse) {
map.removeOverLay(currentPulse);
currentPulse = null;
}
var type = dataType || 'sewage';
var layers = [];
if (type === 'sewage') layers.push({type: 'sewage', data: sources});
else if (type === 'pump') layers.push({type: 'pump', data: pumpStations});
else if (type === 'company') layers.push({type: 'company', data: companies});
else if (type === 'well') layers.push({type: 'well', data: wells});
else if (type === 'pipeline') {
layers.push({type: 'pipeline', data: pipelines});
layers.push({type: 'well', data: wells});
}
layers.forEach(function(layer) {
var currentType = layer.type;
console.log('currentType',currentType);
if (layer.data && layer.data.length > 0) {
layer.data.forEach(function(item) {
// Handle Pipelines (Polyline)
if (currentType === 'pipeline') {
if (!item.path || item.path.length < 2) return;
var points = item.path.map(function(p) { return new T.LngLat(p[0], p[1]); });
var polyline = new T.Polyline(points, {color: "blue", weight: 4, opacity: 0.8});
map.addOverLay(polyline);
var infoContent = "<div style='font-size:13px; line-height:1.5;'>";
infoContent += "<strong style='color:#007bff; font-size:14px;'>管线 #" + item.id + "</strong><br>";
infoContent += "管径: " + item.diameter + "mm<br>";
infoContent += "长度: " + item.length + "m<br>";
infoContent += "</div>";
var infoWindow = new T.InfoWindow(infoContent, {offset: new T.Point(0, 0)});
polyline.addEventListener("click", function(e) {
var point = e.lnglat; // Get click position
map.openInfoWindow(infoWindow, point);
});
markers.push({marker: polyline, data: item, infoWindow: infoWindow, label: null});
return;
}
// Use mapLng/mapLat if available (for wells with projected coords in table), otherwise standard lng/lat
var lng = item.mapLng || item.lng;
var lat = item.mapLat || item.lat;
if (!lng || !lat) return;
var point = new T.LngLat(lng, lat);
// Create Marker
var marker;
console.log('currentType', currentType)
if (currentType === 'well') {
var icon = new T.Icon({
iconUrl: "../../IMG/wsgj.png",
iconSize: new T.Point(10, 10),
iconAnchor: new T.Point(15, 15)
});
marker = new T.Marker(point, {icon: icon});
} else if (currentType === 'pipeline-node') {
var icon = new T.Icon({
iconUrl: "../../IMG/icon_gd.png",
iconSize: new T.Point(18, 18),
iconAnchor: new T.Point(15, 15)
});
marker = new T.Marker(point, {icon: icon});
} else if (currentType === 'pump') {
var icon = new T.Icon({
iconUrl: "../../IMG/icon_bz.png",
iconSize: new T.Point(18, 18),
iconAnchor: new T.Point(15, 15)
});
marker = new T.Marker(point, {icon: icon});
} else if (currentType === 'company') {
var icon = new T.Icon({
iconUrl: "../../IMG/icon_qy.png",
iconSize: new T.Point(18, 18),
iconAnchor: new T.Point(15, 15)
});
marker = new T.Marker(point, {icon: icon});
} else if (currentType === 'sewage') {
var icon = new T.Icon({
iconUrl: "../../IMG/icon_wsc.png",
iconSize: new T.Point(18, 18),
iconAnchor: new T.Point(15, 15)
});
marker = new T.Marker(point, {icon: icon});
} else {
marker = new T.Marker(point);
}
map.addOverLay(marker);
var labelColor = "green";
// Simple status logic for demo
if (currentType === 'sewage') {
if (item.status === 1) labelColor = "#FFCC00";
else if (item.status === 2) labelColor = "red";
} else if (currentType === 'pump') {
labelColor = "blue";
} else if (currentType === 'company') {
labelColor = "#9932CC";
} else if (currentType === 'well') {
labelColor = "#666";
}
if (currentType!== 'well') {
// Set label
var labelContent = "<div style='border:1px solid #ccc; border-radius:4px; padding:2px 5px; font-size:12px; background-color:white; font-weight:bold; color:" + labelColor + ";'>" + item.name + "</div>";
var label = new T.Label({
text: labelContent,
position: point,
offset: new T.Point(-30, -30)
});
label.setBackgroundColor("transparent");
label.setBorderLine(0);
map.addOverLay(label);
}
// InfoWindow Content Construction
var infoContent = "<div style='font-size:13px; line-height:1.5;'>";
infoContent += "<strong style='color:#007bff; font-size:14px;'>" + item.name + "</strong><br>";
if (currentType === 'sewage') {
var sewageStatusText = item.status === 0 ? '在线' : (item.status === 1 ? '告警' : '离线');
infoContent += "出口流量: " + (item.outFlow || 0) + "m³/h<br>";
infoContent += "入口流量: " + (item.inFlow || 0) + "m³/h<br>";
infoContent += "状态: " + sewageStatusText + "<br>";
infoContent += "设计能力: " + (item.designCapacity || '-') + "万吨/天<br>";
infoContent += "详细地址: " + (item.address || '-') + "<br>";
infoContent += "监测时间: " + (item.time || '-') + "<br>";
} else if (currentType === 'pump') {
infoContent += "泵站名称: " + item.name + "<br>";
infoContent += "流量: " + item.flow + "m³/h<br>";
infoContent += "监测时间: " + item.time + "<br>";
} else if (currentType === 'company') {
infoContent += "企业编号: " + (item.code || '-') + "<br>";
infoContent += "企业名称: " + (item.name || '-') + "<br>";
infoContent += "日排放量: " + (item.discharge || '-') + "<br>";
} else if (currentType === 'well') {
infoContent += "深度: " + item.depth + "<br>";
infoContent += "规格: " + item.spec + "<br>";
}
infoContent += "</div>";
var infoWindow = new T.InfoWindow(infoContent, {
offset: new T.Point(0, 0)
});
// if (currentType === 'well') {
// marker.addEventListener('click', function() {
// document.getElementById('well_id').value = item.id;
// document.getElementById('well_name').value = item.name || '';
// document.getElementById('well_code').value = item.code || '';
// document.getElementById('well_pipe_name').value = item.pipeName || '';
// document.getElementById('well_pipe_code').value = item.pipeCode || '';
// document.getElementById('well_depth').value = item.depth || '';
// document.getElementById('well_nature').value = item.nature || '';
// document.getElementById('well_attachment').value = item.attachment || '';
// document.getElementById('well_bottom_elev').value = item.bottomElev || '';
// document.getElementById('well_lng').value = item.lng || '';
// document.getElementById('well_lat').value = item.lat || '';
// document.getElementById('well_road').value = item.road || '';
// document.getElementById('well_town').value = item.town || '';
// document.getElementById('well_zone').value = item.zone || '';
// document.getElementById('well_surveyor').value = item.surveyor || '';
// document.getElementById('well_angle').value = item.angle || '';
// document.getElementById('well_cal_lng').value = item.calLng || '';
// document.getElementById('well_cal_lat').value = item.calLat || '';
// document.getElementById('well_spec').value = item.spec || '';
// document.getElementById('well_ground_elev').value = item.groundElev || '';
// $('#wellEditModal').modal('show');
// });
// } else {
marker.addEventListener('click', function() {
this.openInfoWindow(infoWindow);
});
// }
markers.push({marker: marker, data: item, infoWindow: infoWindow, label: label});
});
}
});
}
// Selection Logic
var currentPulse = null; // Track the pulse overlay
function selectSource(name) {
var target = markers.find(function(m) { return m.data.name === name; });
if (target) {
// 1. Center Map (Pan to target)
map.panTo(target.marker.getLngLat());
// 2. Open InfoWindow
target.marker.openInfoWindow(target.infoWindow);
// 3. Selection Effect
// B. Dynamic Blue Pulse Circle at Marker Location
if (currentPulse) {
map.removeOverLay(currentPulse);
}
var pulseContent = "<div class='pulse-ring'></div>";
var pulseLabel = new T.Label({
text: pulseContent,
position: target.marker.getLngLat(),
offset: new T.Point(-15, -15) // Half of width/height (30px)
});
pulseLabel.setBackgroundColor("transparent");
pulseLabel.setBorderLine(0);
map.addOverLay(pulseLabel);
currentPulse = pulseLabel;
// 4. Update Radio Button in List (Generic attempt)
var radios = document.getElementsByName('sewage-select');
if (radios.length > 0) {
for (var i = 0; i < radios.length; i++) {
if (radios[i].value === name) {
radios[i].checked = true;
break;
}
}
}
}
}
function initSewageTable() {
var sewagePlants = sources;
var tbody = document.getElementById('sewage-table-body');
var html = '';
sewagePlants.forEach(function(item, index) {
var rowClass = index % 2 === 0 ? '' : 'info';
var statusText = item.status === 0 ? '在线' : (item.status === 1 ? '告警' : '离线');
html += '<tr class="' + rowClass + '" onclick="selectSource(\'' + item.name + '\')" style="cursor: pointer;">';
html += '<td class="text-center">' + (index + 1) + '</td>';
html += '<td class="text-center"><input type="radio" name="sewage-select" value="' + item.name + '"></td>';
html += '<td><a href="javascript:void(0);" style="color: #007bff;">' + item.name + '</a></td>';
html += '<td class="text-right">' + (item.outFlow || 0) + 'm³/h</td>';
html += '<td class="text-right">' + (item.inFlow || 0) + 'm³/h</td>';
html += '<td class="text-center">' + statusText + '</td>';
html += '<td class="text-center">' + (item.designCapacity || '-') + '</td>';
html += '<td>' + (item.address || '-') + '</td>';
html += '<td class="text-center">' + (item.time || '-') + '</td>';
html += '</tr>';
});
tbody.innerHTML = html;
}
function initPumpTable() {
var tbody = document.getElementById('pump-table-body');
var html = '';
pumpStations.forEach(function(station, index) {
var rowClass = index % 2 === 0 ? '' : 'active'; // stripe effect
// Add soft blue background for some rows as in screenshot
if (index % 2 !== 0) {
// bootstrap 'active' class adds a grey background, let's use custom style if needed,
// but 'active' or 'info' class is standard bootstrap.
// The screenshot shows light blue stripes.
rowClass = 'info';
}
html += '<tr class="' + rowClass + '">';
html += '<td class="text-center">' + (index + 1) + '</td>';
html += '<td style="font-weight:bold;">' + station.name + '</td>';
html += '<td class="text-right">' + station.level + '</td>';
html += '<td class="text-right">' + station.flow + '</td>';
html += '<td class="text-center">' + station.status + '</td>';
html += '<td class="text-center">' + station.time + '</td>';
html += '</tr>';
});
tbody.innerHTML = html;
}
function saveWellData() {
var id = document.getElementById('well_id').value;
var wellIndex = wells.findIndex(function(w) { return w.id == id; });
if (wellIndex > -1) {
// Update properties
wells[wellIndex].name = document.getElementById('well_name').value;
wells[wellIndex].code = document.getElementById('well_code').value;
wells[wellIndex].pipeName = document.getElementById('well_pipe_name').value;
wells[wellIndex].pipeCode = document.getElementById('well_pipe_code').value;
wells[wellIndex].depth = document.getElementById('well_depth').value;
wells[wellIndex].nature = document.getElementById('well_nature').value;
wells[wellIndex].attachment = document.getElementById('well_attachment').value;
wells[wellIndex].bottomElev = document.getElementById('well_bottom_elev').value;
wells[wellIndex].lng = document.getElementById('well_lng').value;
wells[wellIndex].lat = document.getElementById('well_lat').value;
wells[wellIndex].road = document.getElementById('well_road').value;
wells[wellIndex].town = document.getElementById('well_town').value;
wells[wellIndex].zone = document.getElementById('well_zone').value;
wells[wellIndex].surveyor = document.getElementById('well_surveyor').value;
wells[wellIndex].angle = document.getElementById('well_angle').value;
wells[wellIndex].calLng = document.getElementById('well_cal_lng').value;
wells[wellIndex].calLat = document.getElementById('well_cal_lat').value;
wells[wellIndex].spec = document.getElementById('well_spec').value;
wells[wellIndex].groundElev = document.getElementById('well_ground_elev').value;
// Update map coordinates if calibration values are provided
var calLng = document.getElementById('well_cal_lng').value;
var calLat = document.getElementById('well_cal_lat').value;
if (calLng && calLat) {
wells[wellIndex].mapLng = calLng;
wells[wellIndex].mapLat = calLat;
}
// Re-render markers if currently on well tab
// Check if current active tab is well tab
if (document.getElementById('tab-well').classList.contains('active')) {
initMarkers('well');
}
$('#wellEditModal').modal('hide');
// Optional: Show success message
// alert('保存成功!');
}
}
initMarkers();
initPumpTable();
initSewageTable();
// Mock Data for Companies
var companies = [
{ id: 1, code: "JSALQY01", name: "福达(上海)食品有限公司", address: "上海市金山区工业区金...", sewageNo: "JS2C", dischargeNo: "AL9654501", discharge: "717m³", point: "AL9654501_CSLL", lng: 121.320000, lat: 30.730000 },
{ id: 2, code: "JSALQY02", name: "上海嘉乐股份有限公司", address: "上海市金山区亭林镇...", sewageNo: "MM_AL11_C", dischargeNo: "AL9654502", discharge: "1010m³", point: "AL9654502_CSLL", lng: 121.330000, lat: 30.740000 },
];
// Mock Data for Pipelines
var pipelines = [
{ id: 1, name: "", diameter: "0", length: "0", startDepth: "0", endDepth: "0", startElev: "0", endElev: "0", invertElev: "0", path: [[121.3400, 30.7400], [121.3410, 30.7410]] },
{ id: 2, name: "", diameter: "1600", length: "72.0223546", startDepth: "0.149", endDepth: "0.251", startElev: "5.649", endElev: "5.451", invertElev: "0.2", path: [[121.3410, 30.7410], [121.3430, 30.7430]] },
{ id: 3, name: "", diameter: "200", length: "11.1513874", startDepth: "0.251", endDepth: "3.035", startElev: "5.451", endElev: "5.335", invertElev: "1.643", path: [[121.3430, 30.7430], [121.3440, 30.7440]] },
];
// Mock Data for Wells
var wells = [
{ id: 1, name: "BWS1", depth: "8.15", bottomElev: "-3.963", groundElev: "0", spec: "", lng: "3420414.23109246", lat: "340424.84811152", mapLng: "121.3410", mapLat: "30.7410" },
{ id: 2, name: "BWS2", depth: "8.15", bottomElev: "-3.619", groundElev: "0", spec: "", lng: "3420475.77946245", lat: "340408.18952986", mapLng: "121.3420", mapLat: "30.7420" },
{ id: 3, name: "BWS3", depth: "7.15", bottomElev: "-2.414", groundElev: "0", spec: "", lng: "3420467.51573462", lat: "340548.72770082", mapLng: "121.3430", mapLat: "30.7430" },
];
// ---------------------------------------------------------
// 坐标转换处理
// 如果源数据是百度坐标(BD-09),需要转换为天地图坐标(WGS-84)
// ---------------------------------------------------------
// 默认不转换 (false),如果您确认源数据是百度坐标,请将此变量设置为 true
var IS_SOURCE_BAIDU = false;
if (IS_SOURCE_BAIDU) {
console.log("正在将百度坐标转换为天地图坐标...");
pipelines.forEach(function(p) {
if (p.path) {
p.path = p.path.map(function(pt) {
return CoordTransform.bd09_to_wgs84(pt[0], pt[1]);
});
}
});
wells.forEach(function(w) {
if (w.mapLng && w.mapLat) {
var converted = CoordTransform.bd09_to_wgs84(parseFloat(w.mapLng), parseFloat(w.mapLat));
w.mapLng = converted[0];
w.mapLat = converted[1];
}
});
}
function initCompanyTable() {
var tbody = document.getElementById('company-table-body');
var html = '';
companies.forEach(function(item, index) {
var rowClass = index % 2 === 0 ? '' : 'active';
if (index % 2 !== 0) rowClass = 'info';
html += '<tr class="' + rowClass + '">';
html += '<td class="text-center">' + (index + 1) + '</td>';
html += '<td>' + item.code + '</td>';
html += '<td>' + item.name + '</td>';
html += '<td>' + item.address + '</td>';
html += '<td class="text-center">' + item.sewageNo + '</td>';
html += '<td class="text-center">' + item.dischargeNo + '</td>';
html += '<td class="text-right">' + item.discharge + '</td>';
html += '<td>' + item.point + '</td>';
html += '</tr>';
});
tbody.innerHTML = html;
}
function initPipelineTable() {
var tbody = document.getElementById('pipeline-table-body');
var html = '';
var totalDiameter = 0;
var totalLength = 0;
pipelines.forEach(function(item, index) {
var rowClass = index % 2 === 0 ? '' : 'info';
html += '<tr class="' + rowClass + '">';
html += '<td class="text-center"><input type="radio" name="pipe-select"></td>';
html += '<td class="text-center">' + (index + 1) + '</td>';
html += '<td>' + item.name + '</td>';
html += '<td class="text-center">' + item.diameter + '</td>';
html += '<td class="text-right">' + item.length + '</td>';
html += '<td class="text-right">' + item.startDepth + '</td>';
html += '<td class="text-right">' + item.endDepth + '</td>';
html += '<td class="text-right">' + item.startElev + '</td>';
html += '<td class="text-right">' + item.endElev + '</td>';
html += '<td class="text-right">' + item.invertElev + '</td>';
html += '</tr>';
// Calculate totals
var d = parseFloat(item.diameter) || 0;
var l = parseFloat(item.length) || 0;
totalDiameter += d;
totalLength += l;
});
tbody.innerHTML = html;
// Update Summary
var diamElem = document.getElementById('pipe-total-diameter');
var lenElem = document.getElementById('pipe-total-length');
if (diamElem) diamElem.innerText = totalDiameter.toFixed(2);
if (lenElem) lenElem.innerText = totalLength.toFixed(2);
}
function initWellTable() {
var tbody = document.getElementById('well-table-body');
var html = '';
wells.forEach(function(item, index) {
var rowClass = index % 2 === 0 ? '' : 'info';
html += '<tr class="' + rowClass + '">';
html += '<td class="text-center"><input type="radio" name="well-select"></td>';
html += '<td class="text-center">' + (index + 1) + '</td>';
html += '<td>' + item.name + '</td>';
html += '<td class="text-right">' + item.depth + '</td>';
html += '<td class="text-right">' + item.bottomElev + '</td>';
html += '<td class="text-right">' + item.groundElev + '</td>';
html += '<td class="text-center">' + item.spec + '</td>';
html += '<td class="text-right">' + item.lng + '</td>';
html += '<td class="text-right">' + item.lat + '</td>';
html += '</tr>';
});
tbody.innerHTML = html;
}
initCompanyTable();
initPipelineTable();
initWellTable();
// Mock Data for Plans
var plans = [
{ id: 1, name: "金山一车间日常巡检", status: "启用", duration: "2小时", interval: "1天", startTime: "2026-01-01", endTime: "2026-12-31" },
{ id: 2, name: "泵站设备专项检查", status: "启用", duration: "4小时", interval: "7天", startTime: "2026-02-01", endTime: "2026-06-30" },
{ id: 3, name: "管网防汛排查", status: "停用", duration: "8小时", interval: "30天", startTime: "2026-05-01", endTime: "2026-09-30" },
{ id: 4, name: "排污口突击检查", status: "启用", duration: "3小时", interval: "15天", startTime: "2026-03-15", endTime: "2026-09-15" }
];
// Mock Data for Records
var records = [
{ id: 1, taskName: "金山一车间日常巡检", status: "已完成", planStartTime: "09:00", planEndTime: "11:00", actualTime: "10:45" },
{ id: 2, taskName: "泵站设备专项检查", status: "未完成", planStartTime: "14:00", planEndTime: "17:30", actualTime: "--" },
{ id: 3, taskName: "金山一车间日常巡检", status: "已完成", planStartTime: "09:00", planEndTime: "10:50", actualTime: "10:30" },
{ id: 4, taskName: "管网防汛排查", status: "进行中", planStartTime: "10:00", planEndTime: "16:00", actualTime: "--" }
];
function initPlanTable() {
var tbody = document.getElementById('plan-table-body');
var html = '';
plans.forEach(function(item, index) {
var rowClass = index % 2 === 0 ? '' : 'info';
html += '<tr class="' + rowClass + '">';
html += '<td class="text-center"><input type="checkbox" name="plan-select"></td>';
html += '<td class="text-center">' + (index + 1) + '</td>';
html += '<td>' + item.name + '</td>';
var statusColor = item.status === '启用' ? 'green' : 'red';
html += '<td class="text-center" style="color:' + statusColor + ';">' + item.status + '</td>';
html += '<td class="text-center">' + item.duration + '</td>';
html += '<td class="text-center">' + item.interval + '</td>';
html += '<td class="text-center">' + item.startTime + '</td>';
html += '<td class="text-center">' + item.endTime + '</td>';
html += '</tr>';
});
tbody.innerHTML = html;
}
function initRecordTable() {
var tbody = document.getElementById('record-table-body');
var html = '';
records.forEach(function(item, index) {
var rowClass = index % 2 === 0 ? '' : 'info';
html += '<tr class="' + rowClass + '">';
html += '<td class="text-center"><input type="checkbox" name="record-select"></td>';
html += '<td class="text-center">' + (index + 1) + '</td>';
html += '<td>' + item.taskName + '</td>';
var statusColor = 'black';
if (item.status === '已完成') statusColor = 'green';
else if (item.status === '未完成') statusColor = 'red';
else if (item.status === '进行中') statusColor = 'blue';
html += '<td class="text-center" style="color:' + statusColor + ';">' + item.status + '</td>';
html += '<td class="text-center">' + item.planStartTime + '</td>';
html += '<td class="text-center">' + item.planEndTime + '</td>';
html += '<td class="text-center">' + item.actualTime + '</td>';
html += '</tr>';
});
tbody.innerHTML = html;
}
initPlanTable();
initRecordTable();
// Drawer Logic
function toggleDrawer() {
var drawer = document.getElementById('rightDrawer');
var icon = document.getElementById('drawer-toggle-icon');
if (drawer.classList.contains('drawer-collapsed')) {
drawer.classList.remove('drawer-collapsed');
icon.innerHTML = '&gt;';
} else {
drawer.classList.add('drawer-collapsed');
icon.innerHTML = '&lt;';
}
}
// Drawer Resizer Logic
var resizer = document.getElementById('drawerResizer');
var drawer = document.getElementById('rightDrawer');
var startX, startWidth;
resizer.addEventListener('mousedown', function(e) {
startX = e.clientX;
startWidth = parseInt(document.defaultView.getComputedStyle(drawer).width, 10);
// Disable transition during drag
drawer.style.transition = 'none';
document.documentElement.addEventListener('mousemove', doDrag, false);
document.documentElement.addEventListener('mouseup', stopDrag, false);
// Prevent text selection
e.preventDefault();
});
function doDrag(e) {
// Calculate new width (dragging left increases width)
var newWidth = startWidth + (startX - e.clientX);
// Min/Max width constraints
if (newWidth < 300) newWidth = 300;
if (newWidth > 1000) newWidth = 1000;
drawer.style.width = newWidth + 'px';
}
function stopDrag(e) {
// Restore transition
drawer.style.transition = 'transform 0.3s ease';
document.documentElement.removeEventListener('mousemove', doDrag, false);
document.documentElement.removeEventListener('mouseup', stopDrag, false);
}
function switchTab(tabId, navItem) {
// Update Nav Items
var navItems = document.querySelectorAll('.drawer-nav-item');
navItems.forEach(function(item) {
item.classList.remove('active');
});
navItem.classList.add('active');
// Update Content Panes
var panes = document.querySelectorAll('.tab-pane');
panes.forEach(function(pane) {
pane.classList.remove('active');
});
document.getElementById(tabId).classList.add('active');
// Update Map Markers based on Tab ID
var type = 'sewage';
if (tabId === 'tab-pump') type = 'pump';
else if (tabId === 'tab-company') type = 'company';
else if (tabId === 'tab-well') type = 'well';
else if (tabId === 'tab-pipeline') type = 'pipeline';
initMarkers(type);
}
</script>
<!-- jQuery -->
<script src="../../node_modules/jquery-ui/external/jquery/jquery.js"></script>
<!-- Bootstrap JS -->
<script src="../../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Moment.js -->
<script src="../../plugins/bootstrap-daterangepicker/moment.min.js"></script>
<!-- DateRangePicker -->
<script src="../../plugins/bootstrap-daterangepicker/daterangepicker.js"></script>
<script>
$(document).ready(function() {
// Initialize DateRangePicker for time range inputs
$('#sewage-time-start, #sewage-time-end, #pump-time-start, #pump-time-end, #company-time-start, #company-time-end').daterangepicker({
singleDatePicker: true,
timePicker: true,
timePicker24Hour: true,
timePickerIncrement: 1,
locale: {
format: 'YYYY-MM-DD HH:mm',
applyLabel: '确定',
cancelLabel: '取消',
fromLabel: '从',
toLabel: '到',
weekLabel: 'W',
customRangeLabel: 'Custom Range',
daysOfWeek: ["日", "一", "二", "三", "四", "五", "六"],
monthNames: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
firstDay: 1
}
});
// Initialize DateRangePicker for Record Date (Single Date, No Time)
$('#record-date').daterangepicker({
singleDatePicker: true,
showDropdowns: true,
locale: {
format: 'YYYY-MM-DD',
applyLabel: '确定',
cancelLabel: '取消',
daysOfWeek: ["日", "一", "二", "三", "四", "五", "六"],
monthNames: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
firstDay: 1
}
});
});
</script>
<!-- Well Edit Modal -->
<div class="modal fade" id="wellEditModal" tabindex="-1" role="dialog" aria-labelledby="wellEditModalLabel" data-backdrop="static">
<div class="modal-dialog modal-lg" role="document" style="width: 1000px;">
<div class="modal-content">
<div class="modal-header" style="background-color: #fff; border-bottom: 1px solid #e5e5e5; padding: 15px;">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true" style="color: #007bff; font-size: 24px;">&times;</span></button>
<h4 class="modal-title" id="wellEditModalLabel" style="font-weight: bold; border-left: 4px solid #007bff; padding-left: 10px; font-size: 16px;">管井编辑</h4>
</div>
<div class="modal-body" style="padding: 30px;">
<form id="wellEditForm" class="form-horizontal">
<input type="hidden" id="well_id" name="id">
<div class="container-fluid">
<!-- Row 1 -->
<div class="row" style="margin-bottom: 20px;">
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管井名称:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_name" name="name">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管井编码:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_code" name="code">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管道名称:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_pipe_name" name="pipeName" placeholder="请输入管道名称">
</div>
</div>
</div>
</div>
<!-- Row 2 -->
<div class="row" style="margin-bottom: 20px;">
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管道编码:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_pipe_code" name="pipeCode" placeholder="请输入管道编码">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管井埋深:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_depth" name="depth">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管井性质:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_nature" name="nature" placeholder="请输入管井性质">
</div>
</div>
</div>
</div>
<!-- Row 3 -->
<div class="row" style="margin-bottom: 20px;">
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管井附属物:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_attachment" name="attachment" placeholder="请输入附属物">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">井底标高:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_bottom_elev" name="bottomElev">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管井经度:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_lng" name="lng">
</div>
</div>
</div>
</div>
<!-- Row 4 -->
<div class="row" style="margin-bottom: 20px;">
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管井纬度:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_lat" name="lat">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">所在路名:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_road" name="road" placeholder="请输入所在路名">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">所在乡镇:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_town" name="town" placeholder="请输入所在乡镇">
</div>
</div>
</div>
</div>
<!-- Row 5 -->
<div class="row" style="margin-bottom: 20px;">
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">所属分区:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_zone" name="zone" placeholder="请输入所属分区">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">探测人员:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_surveyor" name="surveyor" placeholder="请输入探测人员">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管井角度:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_angle" name="angle" placeholder="请输入角度">
</div>
</div>
</div>
</div>
<!-- Row 6 -->
<div class="row" style="margin-bottom: 20px;">
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">经度校准:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_cal_lng" name="calLng" placeholder="请输入需要校准的经度值">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">纬度校准:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_cal_lat" name="calLat" placeholder="请输入需要校准的纬度值">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">管井规格:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_spec" name="spec" placeholder="请输入规格">
</div>
</div>
</div>
</div>
<!-- Row 7 -->
<div class="row" style="margin-bottom: 0px;">
<div class="col-md-4">
<div class="form-group" style="margin-bottom: 0;">
<label class="col-sm-4 control-label" style="text-align: right; font-weight: normal; color: #333;">地面高程:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="well_ground_elev" name="groundElev">
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer" style="text-align: center; border-top: none; padding-bottom: 30px;">
<button type="button" class="btn btn-primary" style="width: 150px; height: 40px; background-color: #0099ff; border-color: #0099ff;" onclick="saveWellData()">确定</button>
<button type="button" class="btn btn-default" style="width: 150px; height: 40px; background-color: #aebdc6; color: white; border: none;" data-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
</body>
</html>