425 lines
19 KiB
PHP
425 lines
19 KiB
PHP
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<title>理车</title>
|
||
<meta charset="utf-8">
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
<meta name="description" content="">
|
||
<meta name="keywords" content="">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="renderer" content="webkit">
|
||
|
||
<link rel="stylesheet" type="text/css" href="/AmazeUI/assets/css/amazeui.css">
|
||
<link rel="stylesheet" type="text/css" href="/static/css/common.css?t=7">
|
||
<link rel="stylesheet" type="text/css" href="/static/css/mobilemedia.css">
|
||
<link rel="stylesheet" type="text/css" href="/static/css/iconfont/iconfont.css">
|
||
<link rel="stylesheet" type="text/css" href="/static/js/plugin/bootstrap/css/bootstrap.css">
|
||
<link rel="stylesheet" type="text/css" href="/static/css/admin.css">
|
||
<link rel="stylesheet" type="text/css" href="/static/css/font-awesome.min.css?v=1581252500">
|
||
<!-- 滑动按钮css -->
|
||
<link rel="stylesheet" type="text/css" href="/static/css/switch.css">
|
||
<link rel="stylesheet" type="text/css" href="/static/js/plugin/viewer/viewer.css?t=3">
|
||
|
||
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap-select.min.css">
|
||
|
||
<script type="text/javascript" src="/static/js/plugin/bootstrap-select/popper.min.js"></script>
|
||
<script type="text/javascript" src="/static/js/common/jquery-3.0.0.js"></script>
|
||
<script type="text/javascript" src="/static/js/common/vue.min.js"></script>
|
||
<script type="text/javascript" src="/AmazeUI/assets/js/amazeui.js"></script>
|
||
<script type="text/javascript" src="/static/js/plugin/layer/layer.js"></script>
|
||
<script type="text/javascript" src="/static/js/common/admin.js?t=20210208"></script>
|
||
<script type="text/javascript" src="/static/js/plugin/layerpage/laypage.js"></script>
|
||
<script type="text/javascript" src="/static/js/plugin/gwm/gwm.js"></script>
|
||
<script type="text/javascript" src="/static/js/plugin/uploader/qiniu4js.js"></script>
|
||
|
||
<script type="text/javascript" src="/static/js/common/jquery-ui.min.js?t=2020221"></script>
|
||
<script type="text/javascript" src="/static/js/common/Sortable.min.js?t=2020221"></script>
|
||
<script type="text/javascript" src="/static/js/common/vuedraggable.umd.min.js?t=2020221"></script>
|
||
<script type="text/javascript" src="/static/js/common/jquery.form.js?t=2020410"></script>
|
||
<script type="text/javascript" src="/static/js/plugin/viewer/viewer.js?t=4"></script>
|
||
|
||
<link rel="stylesheet" href="/static/js/plugin/element-ui/index.css">
|
||
<script src="/static/js/plugin/element-ui/index.js"></script>
|
||
<script>window.ROOT_URL = '';</script>
|
||
</head>
|
||
<body>
|
||
<div class="coms-layout-container theme-default" id="index-vue-app">
|
||
<div class="coms-layout-header">
|
||
<div class="bars-nav"><i class="am-icon-bars"></i>导航</div>
|
||
<a href="" class="logo" style="">
|
||
<img src="https://img.liche.cn/spacestation/w-logo.png" style="height:40px">
|
||
</a>
|
||
<?php if ($menus) { ?>
|
||
<ul class="header-nav">
|
||
<? foreach ($menus as $v) { ?>
|
||
<?php if (!$v['sub']) { ?>
|
||
<li data-menu-node='m-<?= $v['id'] ?>' data-open="<?= $v['url'] ?>"><a
|
||
href="javascript:void (0);"><?= $v['name'] ?></a></li>
|
||
<?php } else { ?>
|
||
<li data-menu-node='m-<?= $v['id'] ?>'><a href="javascript:void (0);"><?= $v['name'] ?></a>
|
||
</li>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
</ul>
|
||
<?php } ?>
|
||
<div class="header-userinfo">
|
||
<a class="info-name" href="javascript:;"><?= $_username ?><span class="arrow"></span></a>
|
||
<ul class="dropdown-list">
|
||
<li><a href="javascript:void (0);" data-open="/expfile" data-title="导出文件">导出文件</a></li>
|
||
<li><a href="javascript:void (0);" data-modal="/login/reset_pwd" data-title="修改秘密">修改密码</a></li>
|
||
<li><a href="javascript:void (0);" data-load="/login/logout" data-confirm="确定要退出登录吗?">退出</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="header-notice">
|
||
<a class="tit" href="javascript:;">通知<b><i>{{ countNotice }}</i></b></a>
|
||
<ul class="dropdown-list" style="width: 180px">
|
||
<template v-if="notice.length > 0">
|
||
<li v-for="(item,index) in notice">
|
||
<a @click="setRead(item,index)" href="#"
|
||
style="overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">
|
||
{{ item.content}}
|
||
</a>
|
||
</li>
|
||
<!-- 按钮容器:使用Flex实现左右分栏 -->
|
||
<li style="display: flex; border-top: 1px solid #eee; margin-top: 4px;">
|
||
<a href="javascript:void(0);"
|
||
style="color: #ff4d4f; flex: 1; text-align: center; padding: 4px 0; text-decoration: none;"
|
||
@click="clearNotice">
|
||
<i class="fa"></i> 清除所有
|
||
</a>
|
||
<a data-open="/sys/notice" href="javascript:void(0);"
|
||
style="flex: 1; text-align: center; padding: 4px 0; text-decoration: none; color: inherit;">
|
||
<i class="fa"></i> 查看更多
|
||
</a>
|
||
</li>
|
||
<!--
|
||
<a href="javascript:void(0);" style="color: #ff4d4f; border-top: 1px solid #eee;">
|
||
<i class="fa"></i> 清除所有
|
||
</a>
|
||
<a href="javascript:void(0);">
|
||
<i class="fa"></i> 查看更多
|
||
</a>
|
||
-->
|
||
</template>
|
||
<li v-if="notice.length === 0">
|
||
<a href="javascript:void(0);" style="color: #999; cursor: default;">暂无通知</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="coms-layout-aside fold" id="J_coms-layout-aside" style="display: none">
|
||
<div class="aside-menu-scroll">
|
||
<?php if ($menus) { ?>
|
||
<div class="aside-unfold"><i class="iconfont f18"></i></div>
|
||
<?php foreach ($menus as $pmenu) { ?>
|
||
<?php if ($pmenu['sub']) { ?>
|
||
<ul class="aside-menu" data-menu-box="m-<?= $pmenu['id'] ?>">
|
||
<?php foreach ($pmenu['sub'] as $menu) { ?>
|
||
<?php if (!$menu['sub']) { ?>
|
||
<li class="treeview" data-menu-node='m-<?= $pmenu['id'] ?>-<?= $menu['id'] ?>'
|
||
data-open="<?= $menu['url'] ?>">
|
||
<a style="text-align: center" href="javascript:void(0)"><i class="iconfont f14"></i><span
|
||
class="txt"><?= $menu['name'] ?></span></a>
|
||
</li>
|
||
<?php } else { ?>
|
||
<li class="treeview">
|
||
<a href="javascript:void(0)" style="text-align: center">
|
||
|
||
<?php if ($menu['icon']) { ?>
|
||
<i class="<?= $menu['icon'] ?> "></i>
|
||
<?php } else { ?>
|
||
<i class="iconfont f14"></i>
|
||
<?php } ?>
|
||
<span class="txt"><?= $menu['name'] ?></span>
|
||
</a>
|
||
<ul class="list" style="display: none"
|
||
data-menu-box='m-<?= $pmenu['id'] ?>-<?= $menu['id'] ?>'>
|
||
<?php foreach ($menu['sub'] as $submenu) {
|
||
$url = $submenu['url'];
|
||
$node = "{$pmenu['id']}-{$menu['id']}-{$submenu['id']}";
|
||
if ((!$url || $url == '#') && $submenu['sub']) {
|
||
$url = $submenu['sub'][0]['url'];
|
||
$node .= "-{$submenu['sub'][0]['id']}";
|
||
}
|
||
?>
|
||
<li data-menu-node='m-<?= $node ?>' data-open="<?= $url ?>">
|
||
<a href="javascript:void (0);"><?= $submenu['name'] ?></a>
|
||
</li>
|
||
<?php } ?>
|
||
</ul>
|
||
</li>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
</ul>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
<div class="aside-menu-sub">
|
||
</div>
|
||
<?php } ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="coms-layout-body p15">
|
||
<div class="coms-layout-body-inner">
|
||
<article class="am-article" style="display: none">
|
||
<div class="am-article-hd">
|
||
<h1 class="am-article-title">欢迎 [<?= $_role ?>] <?= $_username ?></h1>
|
||
<p class="am-article-meta">
|
||
<?php
|
||
$no = date("H", time());
|
||
$week = array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日");
|
||
if ($no > 0 && $no <= 6) {
|
||
echo "凌晨好!";
|
||
} elseif ($no > 6 && $no < 12) {
|
||
echo "上午好!";
|
||
} elseif ($no >= 12 && $no <= 18) {
|
||
echo "下午好!";
|
||
} else {
|
||
echo "晚上好!";
|
||
}
|
||
?>
|
||
</p>
|
||
</div>
|
||
|
||
<div class="am-article-bd">
|
||
<p class="am-article-lead">
|
||
现在时间是:<?= date('Y年m月d日') ?> <?= $week[date('w')] ?> <?= date('H:i:s') ?>
|
||
当前IP:<?= get_client_ip() ?></p>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</body>
|
||
|
||
<script type="text/javascript" src="/static/js/plugin/require/require.js"></script>
|
||
<script type="text/javascript" src="/static/js/common/app.js?v=1"></script>
|
||
<script type="text/javascript">
|
||
//查看图片控件
|
||
function showViewer(obj) {
|
||
new Viewer(document.getElementById(obj));
|
||
}
|
||
|
||
var _index_vue_obj;
|
||
|
||
var log_data = {};
|
||
var heartbeatInterval = null;
|
||
var pongTimeout = null;
|
||
(function ($) {
|
||
_index_vue_obj = new Vue({
|
||
el: '#index-vue-app',
|
||
data: {
|
||
countNotice: <?=$_noticeCount?>,
|
||
notice: <?=json_encode($_notice)?>
|
||
},
|
||
mounted: function () {
|
||
},
|
||
methods: {
|
||
clearNotice() {
|
||
let that = this;
|
||
$.post('/common/set_notice', {}, function (data) {
|
||
if (data.code) {
|
||
layer.msg(data.msg, {icon: 1});
|
||
that.countNotice = 0;
|
||
that.notice = [];
|
||
} else {
|
||
layer.msg(data.msg, {icon: 2});
|
||
}
|
||
})
|
||
},
|
||
setRead(item, index) {
|
||
let that = this;
|
||
$.post('/common/set_notice', {id: item.id}, function (data) {
|
||
if (data.code) {
|
||
that.notice.splice(index, 1);
|
||
that.countNotice--;
|
||
let btn = ['关闭'];
|
||
if (item.url) {
|
||
btn = ['查看详情', '关闭'];
|
||
}
|
||
layer.confirm(item.content, {
|
||
btn: btn,
|
||
title: '通知详情'
|
||
}, function (index) {
|
||
// 点击查看详情
|
||
if (item.url) {
|
||
$.form.href(item.url);
|
||
}
|
||
layer.close(index);
|
||
}, function (index) {
|
||
// 点击关闭
|
||
layer.close(index);
|
||
});
|
||
} else {
|
||
layer.msg(data.msg, {icon: 2});
|
||
}
|
||
})
|
||
|
||
}
|
||
}
|
||
});
|
||
// 初始化 WebSocket 连接
|
||
initWebSocket();
|
||
|
||
$(".coms-layout-header .bars-nav").on("click", function (event) {
|
||
event.stopPropagation()
|
||
var $headNav = $(".header-nav");
|
||
if ($headNav.hasClass("active")) {
|
||
$headNav.removeClass("active")
|
||
} else {
|
||
$headNav.addClass("active")
|
||
}
|
||
});
|
||
$("body").on("touchstart", function (event) {
|
||
if ($(event.target).closest(".header-nav").length) {
|
||
return;
|
||
} else {
|
||
$(".header-nav").removeClass("active");
|
||
}
|
||
})
|
||
$(function () {
|
||
var $aside = $("#J_coms-layout-aside"),
|
||
$fold = $aside.find(".aside-unfold"),
|
||
$mainBody = $("#J_coms-layout-body");
|
||
$fold.on("click", function () {
|
||
|
||
if ($aside.hasClass('fold')) {
|
||
$aside.removeClass('fold');
|
||
$mainBody.removeClass('unfold');
|
||
$('.coms-layout-body').css('left', 220);
|
||
$(".coms-body-main-nav").css("left", 220)
|
||
} else {
|
||
$aside.addClass('fold');
|
||
$mainBody.addClass('unfold');
|
||
$('.coms-layout-body').css('left', 65);
|
||
$(".coms-body-main-nav").css("left", 65);
|
||
}
|
||
});
|
||
|
||
gwm.creation({
|
||
txt: '<?=$_username?>',
|
||
width: 200,
|
||
height: 150,
|
||
x: 10,
|
||
y: 60,
|
||
fontSize: 12,
|
||
color: '#000',
|
||
alpha: 0.03,
|
||
});
|
||
})
|
||
})(jQuery)
|
||
|
||
function initWebSocket() {
|
||
// 构建 WebSocket 连接 URL
|
||
var wsUrl = "<?=$wss_url?>";
|
||
|
||
try {
|
||
// 创建 WebSocket 实例
|
||
var websocket = new WebSocket(wsUrl);
|
||
|
||
// 连接打开事件
|
||
websocket.onopen = function (event) {
|
||
console.log('websocket 连接成功');
|
||
// 在websocket.onopen回调中添加:
|
||
heartbeatInterval = setInterval(function () {
|
||
if (window.adminWebsocket && window.adminWebsocket.readyState === WebSocket.OPEN) {
|
||
window.adminWebsocket.send(JSON.stringify({type: 'heartbeat', content: 'ping'}));
|
||
// 设置等待pong响应的超时
|
||
pongTimeout = setTimeout(function () {
|
||
console.warn('Heartbeat timeout - closing connection');
|
||
window.adminWebsocket.close();
|
||
}, 5000); // 5秒内等待pong响应
|
||
}
|
||
}, 30000); // 每30秒发送一次ping
|
||
};
|
||
|
||
// 接收消息事件
|
||
websocket.onmessage = function (event) {
|
||
try {
|
||
console.log('websocket 接收到消息:', event.data);
|
||
var data = JSON.parse(event.data);
|
||
handleWebSocketMessage(data);
|
||
} catch (e) {
|
||
console.error('websocket 解析消息错误:', e);
|
||
}
|
||
};
|
||
|
||
// 错误处理事件
|
||
websocket.onerror = function (error) {
|
||
console.error('websocket 错误信息:', error);
|
||
};
|
||
|
||
// 连接关闭事件
|
||
websocket.onclose = function (event) {
|
||
console.log('websocket 关闭连接', event);
|
||
if (heartbeatInterval) {
|
||
clearInterval(heartbeatInterval);
|
||
heartbeatInterval = null;
|
||
}
|
||
if (pongTimeout) {
|
||
clearTimeout(pongTimeout);
|
||
pongTimeout = null;
|
||
}
|
||
// 5秒后尝试重连
|
||
setTimeout(initWebSocket, 5000);
|
||
};
|
||
|
||
// 保存 WebSocket 实例供全局使用
|
||
window.adminWebsocket = websocket;
|
||
} catch (e) {
|
||
console.error('初始化 websocket 失败:', e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 消息处理
|
||
* @param data
|
||
*/
|
||
function handleWebSocketMessage(data) {
|
||
// 处理不同类型的消息
|
||
switch (data.type) {
|
||
case 'notice':
|
||
// 显示通知消息
|
||
showNotification("您收到一条新的系统通知,请及时查看");
|
||
_index_vue_obj.countNotice++;
|
||
_index_vue_obj.notice = [data.data].concat(_index_vue_obj.notice);
|
||
break;
|
||
case 'heartbeat':
|
||
// 收到pong响应时清除超时定时器
|
||
if (pongTimeout) {
|
||
clearTimeout(pongTimeout);
|
||
pongTimeout = null;
|
||
}
|
||
console.log('websocket 心跳检测正常');
|
||
break;
|
||
default:
|
||
console.log('Received message:', data);
|
||
}
|
||
}
|
||
|
||
function showNotification(message) {
|
||
layer.msg(message, {
|
||
time: 5000,
|
||
icon: 1,
|
||
offset: 't', // t表示顶部显示
|
||
anim: 0, // 使用淡入淡出动画
|
||
isOutAnim: false // 关闭移出动画
|
||
});
|
||
}
|
||
|
||
// 提供全局发送消息的方法
|
||
window.sendWebSocketMessage = function (message) {
|
||
if (window.adminWebsocket &&
|
||
window.adminWebsocket.readyState === WebSocket.OPEN) {
|
||
window.adminWebsocket.send(JSON.stringify(message));
|
||
} else {
|
||
console.warn('websocket 未连接');
|
||
}
|
||
};
|
||
</script>
|
||
|
||
</html>
|