123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>天府机坪图</title>
- <link rel="stylesheet" href="/static/css/bootstrap.min.css">
- <link rel="stylesheet" href="/static/css/moveitem.css">
- <style>
- .one {
- width: 400px;
- height: 400px;
- border: 1px solid #000;
- }
- .two {
- border: 1px solid #000;
- position: absolute;
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
- z-index: 1;
- }
- .map-tooltip {
- list-style: none;
- padding: 0;
- margin: 0;
- font-size: 14px;
- }
- .map-tooltip .title {
- display: flex;
- align-items: center;
- margin-bottom: 8px;
- font-weight: bold;
- }
- .map-tooltip .circle {
- width: 8px;
- height: 8px;
- border-radius: 50%;
- background: #ff4444;
- margin-right: 8px;
- }
- .map-tooltip li {
- margin-bottom: 6px;
- line-height: 1.4;
- }
- </style>
- <script src="/static/js/jquery.min.js"></script>
- <script src="/static/js/echarts.min.js"></script>
- <script src="/static/js/bootstrap.min.js"></script>
- <script src="/static/js/moveitem.js"></script>
- </head>
- <body>
- <div class="two">
- <div id="main" style="width: 100vw; height: 100vh;"></div>
- </div>
- <div id="moveitem" class="myMoveItem" style="top: 50px; left: 10px; width: 384px; height: 612px; z-index: 23; display: none;">
- <div class="moveItem_header">
- <p id="moveitemtittle" class="moveItem_title"></p>
- <div class="moveItem_oper">
- <button type="button" class="moveItem_fullScreen"><></button>
- <button type="button" class="moveItem_normalScreen">><</button>
- <button type="button" class="moveItem_close">X</button>
- </div>
- </div>
- <div id="moveItem_body" class="moveItem_body" style="background-color: #FFF; height: calc(100% - 30px); overflow-y: auto;">
- <p>测试1</p>
- </div>
- <span class="moveItem_resize"></span>
- </div>
- <div id="moveitemDigital" class="myMoveItem" style="top: 800px; left: 10px; width: 1500px; height: 480px; z-index: 33; display: none;">
- <div class="moveItem_header">
- <p id="moveitemDigitaltittle" class="moveItem_title"></p>
- <div class="moveItem_oper">
- <button type="button" class="moveItem_fullScreen"><></button>
- <button type="button" class="moveItem_normalScreen">><</button>
- <button type="button" class="moveItem_close">X</button>
- </div>
- </div>
- <div id="moveItemDigital_body" class="moveItem_body" style="background-color: #FFF; height: calc(100% - 30px); overflow-y: auto;">
- <p>测试1</p>
- </div>
- <span class="moveItem_resize"></span>
- </div>
- <script type="text/javascript">
- // 全局变量
- let myChart = null;
- const REFRESH_INTERVAL = 60000;
- let refreshTimer = null;
- // DOM加载完成初始化
- $(document).ready(function() {
- initEcharts();
- startRequest(); // 传入token启动
- initRefreshTimer(); // 传入token初始化刷新
- initPopupEvent();
- });
- // 初始化ECharts
- function initEcharts() {
- const chartDom = document.getElementById('main');
- if (!chartDom) {
- console.error('ECharts容器不存在');
- return;
- }
- myChart = echarts.init(chartDom);
- window.addEventListener('resize', () => myChart.resize());
- }
- // 首次加载数据(带token参数)
- function startRequest( ) {
- const requestHeaders = {
- 'Content-Type': 'application/json',
- 'Authorization': `{{token}}`
- };
- // 加载SVG地图
- $.get('/static/svg/maptest.svg')
- .done(function(svg) {
- echarts.registerMap('map-tf', { svg: svg });
- // 加载机坪数据(POST请求)
- const requestData = {
- selectedtime: '{{selectedtime}}'
- };
- $.ajax({
- url: '/static/mapDispaly',
- type: 'POST',
- headers: requestHeaders,
- data: JSON.stringify(requestData),
- dataType: 'json',
- success: function(data) {
- renderEcharts(data);
- },
- error: function(xhr) {
- console.error('机位数据加载失败:', xhr.responseText);
- alert(`加载失败(${xhr.status}):${xhr.responseJSON?.error || '未知错误'}`);
- }
- });
- })
- .fail(function(err) {
- console.error('SVG地图加载失败:', err);
- alert('地图资源加载异常');
- });
- }
- // 渲染图表
- function renderEcharts(data) {
- if (!myChart) return;
- const option = {
- tooltip: {
- backgroundColor: 'white',
- padding: 10,
- extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3); border-radius: 24px; opacity: 0.8; border: 2px solid white; width: 274px; height: 270px;',
- textStyle: {
- color: 'black',
- fontSize: 14
- },
- formatter: function(params) {
- const spotData = data[params.name] || {};
- if (spotData.机号 !== "") {
- return `
- <ul class="map-tooltip">
- <li class="title">
- <p class="circle"></p>
- <p class="province">机位:${params.name || '未知'} ${spotData.航班类型 || ''}</p>
- </li>
- <li><p class="name">机号: ${spotData.机号 || '无'}</p></li>
- <li><p class="name">机型:${spotData.机型 || '无'} ${spotData.发动机 || '无'}</p></li>
- <li>
- <p class="name">航班号:${spotData.航班号 || ''}<br>
- ${spotData.进港机场 || ''}-天府-${spotData.出港机场 || ''}</p>
- </li>
- <li><p class="name">放行人员: ${spotData.放行 || '无'}</p></li>
- <li><p class="name">维修人员: ${spotData.维修人员 || '无'}</p></li>
- <li><p class="name">二送人员: ${spotData.二送人员 || '无'}</p></li>
- </ul>
- `;
- }
- return '';
- }
- },
- geo: {
- map: 'map-tf',
- roam: true,
- selectedMode: 'multiple',
- itemStyle: {
- color: 'rgba(0, 0, 0, 0)',
- borderColor: 'rgba(0, 0, 0, 0)'
- },
- emphasis: {
- itemStyle: {
- color: 'rgba(0, 0, 0, 0)',
- borderColor: 'rgba(0, 0, 0, 0)'
- },
- label: { show: false }
- },
- select: {
- itemStyle: {
- color: 'rgba(0, 0, 0, 0)',
- borderColor: 'rgba(0, 0, 0, 0)'
- },
- label: { show: false }
- },
- regions: makeRegions(data)
- },
- series: [{
- type: 'map',
- mapType: 'map-tf',
- geoIndex: 0
- }]
- };
- myChart.setOption(option);
- bindEchartsEvent();
- }
- // 生成区域配置
- function makeRegions(data) {
- const regions = [];
- if (typeof data !== 'object' || data === null) return regions;
- for (const key in data) {
- const spotData = data[key];
- const region = {
- name: key,
- silent: true,
- itemStyle: {
- color: spotData.color || 'rgba(0, 0, 0, 0)',
- borderWidth: 1
- },
- emphasis: {
- itemStyle: {
- color: spotData.color || 'rgba(0, 0, 0, 0)',
- borderWidth: 1
- },
- label: { show: false }
- },
- select: {
- itemStyle: {
- color: spotData.color || 'rgba(0, 0, 0, 0)',
- borderWidth: 1
- }
- }
- };
- if (spotData.南航 === '1') {
- region.itemStyle.borderColor = 'red';
- region.emphasis.itemStyle.borderColor = 'red';
- region.select.itemStyle.borderColor = 'red';
- } else {
- region.itemStyle.borderColor = spotData.color || 'rgba(0, 0, 0, 0)';
- region.emphasis.itemStyle.borderColor = spotData.color || 'rgba(0, 0, 0, 0)';
- region.select.itemStyle.borderColor = spotData.color || 'rgba(0, 0, 0, 0)';
- }
- regions.push(region);
- }
- return regions;
- }
- // 绑定ECharts事件
- function bindEchartsEvent() {
- if (!myChart) return;
- myChart.on('click', function(params) {
- console.log('点击机位:', params.name);
- sendSelect(params.name);
- });
- myChart.on('georoam', function(params) {
- if (params.dy || params.dx) return;
- const option = myChart.getOption();
- const zoom = option.geo[0].zoom || 1;
- const fontSize = 15 / (1 + Math.exp(-zoom + 2));
- option.geo[0].label.textStyle.fontSize = fontSize;
- myChart.setOption(option);
- });
- myChart.on('geoselectchanged', function(params) {
- console.log('选中机位:', params.name);
- });
- myChart.on('mousemove', function(params) {
- console.log('鼠标悬停:', params.name);
- });
- myChart.on('mouseup', function(params) {
- console.log('鼠标抬起:', params.name);
- });
- }
- // 初始化刷新定时器
- function initRefreshTimer() {
- if (refreshTimer) clearInterval(refreshTimer);
- refreshTimer = setInterval(() => RefreshRequest(), REFRESH_INTERVAL);
- window.addEventListener('beforeunload', () => {
- clearInterval(refreshTimer);
- });
- }
- // 刷新数据请求(带token参数)
- function RefreshRequest() {
- const requestHeaders = {
- 'Content-Type': 'application/json',
- 'Authorization': `{{token}}`
- };
- const requestData = {
- selectedtime: '{{selectedtime}}'
- };
- $.ajax({
- url: '/static/mapDispaly',
- type: 'POST',
- headers: requestHeaders,
- data: JSON.stringify(requestData),
- dataType: 'json',
- success: function(data) {
- console.log('数据刷新成功');
- const option = {
- tooltip: {
- formatter: function(params) {
- const spotData = data[params.name] || {};
- if (spotData.机号 !== "") {
- return `
- <ul class="map-tooltip">
- <li class="title">
- <p class="circle"></p>
- <p class="province">机位:${params.name || '未知'} ${spotData.航班类型 || ''}</p>
- </li>
- <li><p class="name">机号: ${spotData.机号 || '无'}</p></li>
- <li><p class="name">机型:${spotData.机型 || '无'} ${spotData.发动机 || '无'}</p></li>
- <li>
- <p class="name">航班号:${spotData.航班号 || ''}<br>
- ${spotData.进港机场 || ''}-天府-${spotData.出港机场 || ''}</p>
- </li>
- <li><p class="name">放行人员: ${spotData.放行 || '无'}</p></li>
- <li><p class="name">维修人员: ${spotData.维修人员 || '无'}</p></li>
- <li><p class="name">二送人员: ${spotData.二送人员 || '无'}</p></li>
- </ul>
- `;
- }
- return '';
- }
- },
- geo: {
- regions: makeRegions(data)
- }
- };
- myChart.setOption(option);
- },
- error: function(xhr) {
- console.error('刷新失败:', xhr.responseText);
- setTimeout(() => RefreshRequest(), 5000);
- }
- });
- }
- // 获取字体大小
- function getFontSize() {
- try {
- const option = myChart.getOption();
- const zoom = option.geo[0].zoom || 1;
- return 15 / (1 + Math.exp(-zoom + 2));
- } catch (err) {
- console.error('获取字体大小失败:', err);
- return 10;
- }
- }
- // 发送选中机位请求
- function sendSelect(bay) {
- // 构造请求头,包含token认证信息
- const requestHeaders = {
- 'Content-Type': 'application/json' ,
- 'Authorization': `{{token}}`
- };
- const requestData = {
- selectedtime: '{{selectedtime}}',
- bay: bay
- };
- // 使用$.ajax而非$.post,以便添加headers配置
- $.ajax({
- url: `/map/getSelectInf`,
- type: 'POST',
- headers: requestHeaders, // 添加token头信息
- data: JSON.stringify(requestData), // 保持原有机位参数
- //dataType: 'json',// 预期返回HTML内容
- dataType: 'html', // 预期返回HTML内容
- success: function(data) {
- $("#moveitemtittle").text(bay);
- $("#moveItem_body").html(data);
- $("#moveitem").show();
- },
- });
- }
- // 发送通知
- function sendMsg() {
- const bay = $("#moveitemtittle").text();
- if (!bay) {
- alert('未选中任何机位');
- return;
- }
- $.post("/sendMsgBay", { 'bay': bay })
- .done(function(data) {
- console.log("发送通知成功:", data);
- alert('通知发送成功');
- })
- .fail(function(err) {
- console.error('发送通知失败:', err);
- alert('通知发送失败,请重试');
- });
- }
- // 获取数字详情
- function getDigital() {
- $.get('/getDigital')
- .done(function(data) {
- $("#moveitemDigitaltittle").text('详细数据');
- $("#moveItemDigital_body").html(data);
- $("#moveitemDigital").show();
- })
- .fail(function(err) {
- console.error('获取数字详情失败:', err);
- alert('无法获取数字详情,请重试');
- });
- }
- // 初始化弹窗事件
- function initPopupEvent() {
- $('.moveItem_close').on('click', function() {
- $(this).closest('.myMoveItem').hide();
- });
- $('.moveItem_fullScreen').on('click', function() {
- const popup = $(this).closest('.myMoveItem');
- popup.css({
- 'top': '0',
- 'left': '0',
- 'width': '100vw',
- 'height': '100vh',
- 'z-index': '9999'
- });
- });
- $('.moveItem_normalScreen').on('click', function() {
- const popup = $(this).closest('.myMoveItem');
- if (popup.attr('id') === 'moveitem') {
- popup.css({
- 'top': '50px',
- 'left': '10px',
- 'width': '384px',
- 'height': '612px',
- 'z-index': '23'
- });
- } else if (popup.attr('id') === 'moveitemDigital') {
- popup.css({
- 'top': '800px',
- 'left': '10px',
- 'width': '1500px',
- 'height': '480px',
- 'z-index': '33'
- });
- }
- });
- }
- </script>
- </body>
- </html>
|