260 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			260 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php /*a:2:{s:47:"E:\Demo\PHP\yunzer\app\admin\view\log\login.php";i:1747584845;s:51:"E:\Demo\PHP\yunzer\app\admin\view\public\header.php";i:1746890051;}*/ ?>
 | |
| <!DOCTYPE html>
 | |
| <html>
 | |
| 	<head>
 | |
| 		<title><?php echo htmlentities((string) $config['admin_name']); ?></title>
 | |
| 		<meta name="renderer" content="webkit">
 | |
| 		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
 | |
| 		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
 | |
| 		<link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css" media="all"/>
 | |
| 		<link rel="stylesheet" type="text/css" href="/static/css/moban.css" media="all"/>
 | |
| 		<link rel="stylesheet" type="text/css" href="/static/css/wangeditor.css" media="all"/>
 | |
| 		<style type="text/css">
 | |
| 			.header span{background:#009688;margin-left:30px;padding:10px;color:#ffffff;}
 | |
| 			.header div{border-bottom:solid 2px #009688;margin-top: 8px;}
 | |
| 			.header button{float:right;margin-top:-5px;}
 | |
| 			.pagination {
 | |
| 				display: inline-block;
 | |
| 				padding-left: 0;
 | |
| 				margin: 20px 0;
 | |
| 				border-radius: 4px;
 | |
| 			}
 | |
| 			.pagination > li {
 | |
| 				display: inline;
 | |
| 			}
 | |
| 			.pagination > li > a,
 | |
| 			.pagination > li > span {
 | |
| 				position: relative;
 | |
| 				float: left;
 | |
| 				padding: 6px 12px;
 | |
| 				margin-left: -1px;
 | |
| 				line-height: 1.42857143;
 | |
| 				color: #337ab7;
 | |
| 				text-decoration: none;
 | |
| 				background-color: #fff;
 | |
| 				border: 1px solid #ddd;
 | |
| 			}
 | |
| 			.pagination > li:first-child > a,
 | |
| 			.pagination > li:first-child > span {
 | |
| 				margin-left: 0;
 | |
| 				border-top-left-radius: 4px;
 | |
| 				border-bottom-left-radius: 4px;
 | |
| 			}
 | |
| 			.pagination > li:last-child > a,
 | |
| 			.pagination > li:last-child > span {
 | |
| 				border-top-right-radius: 4px;
 | |
| 				border-bottom-right-radius: 4px;
 | |
| 			}
 | |
| 			.pagination > li > a:hover,
 | |
| 			.pagination > li > span:hover,
 | |
| 			.pagination > li > a:focus,
 | |
| 			.pagination > li > span:focus {
 | |
| 				z-index: 2;
 | |
| 				color: #23527c;
 | |
| 				background-color: #eee;
 | |
| 				border-color: #ddd;
 | |
| 			}
 | |
| 			.pagination > .active > a,
 | |
| 			.pagination > .active > span,
 | |
| 			.pagination > .active > a:hover,
 | |
| 			.pagination > .active > span:hover,
 | |
| 			.pagination > .active > a:focus,
 | |
| 			.pagination > .active > span:focus {
 | |
| 				z-index: 3;
 | |
| 				color: #fff;
 | |
| 				cursor: default;
 | |
| 				background-color: #337ab7;
 | |
| 				border-color: #337ab7;
 | |
| 			}
 | |
| 			.pagination > .disabled > span,
 | |
| 			.pagination > .disabled > span:hover,
 | |
| 			.pagination > .disabled > span:focus,
 | |
| 			.pagination > .disabled > a,
 | |
| 			.pagination > .disabled > a:hover,
 | |
| 			.pagination > .disabled > a:focus {
 | |
| 				color: #777;
 | |
| 				cursor: not-allowed;
 | |
| 				background-color: #fff;
 | |
| 				border-color: #ddd;
 | |
| 			}
 | |
| 			.close-img { background: url(/static/images/close_img.png); background-size: 20px 20px; width:20px; height: 20px; position: absolute; right: 5px; top: 5px; z-index: 2;}
 | |
| 		</style>
 | |
| 		<script type="text/javascript" src="/static/layui/layui.js"></script>
 | |
| 		<script type="text/javascript">
 | |
| 			layui.use(['layer','form','table','laydate','element','upload'],function(){
 | |
| 				layer = layui.layer;		// layui 弹框
 | |
| 				form = layui.form;			// layui form表单
 | |
| 				table = layui.table;		// layui 表格
 | |
| 				laydate = layui.laydate;	// layui 时间框
 | |
| 				element = layui.element;	// layui element
 | |
| 				upload = layui.upload;		// layui 上传
 | |
| 				$ = layui.jquery;			// layui jquery
 | |
| 			})
 | |
| 		</script>
 | |
| 	</head>
 | |
| 	<body style="padding:10px; box-sizing: border-box;">
 | |
|     <div class="layui-card">
 | |
|         <div class="layui-card-header">
 | |
|             <span class="layui-badge layui-bg-blue">登录日志</span>
 | |
|         </div>
 | |
|         <div class="layui-card-body">
 | |
|             <form class="layui-form layui-form-pane" action="">
 | |
|                 <div class="layui-form-item">
 | |
|                     <div class="layui-inline">
 | |
|                         <label class="layui-form-label">用户名</label>
 | |
|                         <div class="layui-input-inline">
 | |
|                             <input type="text" name="username" placeholder="请输入用户名" autocomplete="off" class="layui-input">
 | |
|                         </div>
 | |
|                     </div>
 | |
|                     <div class="layui-inline">
 | |
|                         <label class="layui-form-label">IP地址</label>
 | |
|                         <div class="layui-input-inline">
 | |
|                             <input type="text" name="ip" placeholder="请输入IP地址" autocomplete="off" class="layui-input">
 | |
|                         </div>
 | |
|                     </div>
 | |
|                     <div class="layui-inline">
 | |
|                         <label class="layui-form-label">状态</label>
 | |
|                         <div class="layui-input-inline">
 | |
|                             <select name="status">
 | |
|                                 <option value="">全部</option>
 | |
|                                 <option value="1">成功</option>
 | |
|                                 <option value="0">失败</option>
 | |
|                             </select>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                     <div class="layui-inline">
 | |
|                         <label class="layui-form-label">时间范围</label>
 | |
|                         <div class="layui-input-inline" style="width: 300px;">
 | |
|                             <input type="text" name="time_range" class="layui-input" id="timeRange" placeholder="请选择时间范围">
 | |
|                         </div>
 | |
|                     </div>
 | |
|                     <div class="layui-inline">
 | |
|                         <button class="layui-btn" lay-submit lay-filter="searchForm">
 | |
|                             <i class="layui-icon layui-icon-search"></i> 搜索
 | |
|                         </button>
 | |
|                         <button type="reset" class="layui-btn layui-btn-primary">重置</button>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </form>
 | |
| 
 | |
|             <table id="loginLogTable" lay-filter="loginLogTable"></table>
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     <script type="text/html" id="tableToolbar">
 | |
|         <div class="layui-btn-container">
 | |
|             <button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="clearAll">
 | |
|                 <i class="layui-icon layui-icon-delete"></i> 清空日志
 | |
|             </button>
 | |
|         </div>
 | |
|     </script>
 | |
| 
 | |
|     <script type="text/html" id="tableBar">
 | |
|         <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a>
 | |
|     </script>
 | |
| 
 | |
|     <script src="/static/layui/layui.js"></script>
 | |
|     <script>
 | |
|     layui.use(['table', 'form', 'laydate'], function(){
 | |
|         var table = layui.table;
 | |
|         var form = layui.form;
 | |
|         var laydate = layui.laydate;
 | |
|         
 | |
|         // 初始化时间范围选择器
 | |
|         laydate.render({
 | |
|             elem: '#timeRange',
 | |
|             type: 'datetime',
 | |
|             range: true
 | |
|         });
 | |
|         
 | |
|         // 初始化表格
 | |
|         table.render({
 | |
|             elem: '#loginLogTable',
 | |
|             url: '<?php echo url("log/login"); ?>',
 | |
|             method: 'post',
 | |
|             toolbar: '#tableToolbar',
 | |
|             defaultToolbar: ['filter', 'exports', 'print'],
 | |
|             parseData: function(res) {
 | |
|                 return {
 | |
|                     "code": res.code === 0 ? 0 : 1,
 | |
|                     "msg": res.msg,
 | |
|                     "count": res.count,
 | |
|                     "data": res.data
 | |
|                 };
 | |
|             },
 | |
|             cols: [[
 | |
|                 {field: 'id', title: 'ID', width: 80, sort: true},
 | |
|                 {field: 'username', title: '用户名', width: 120},
 | |
|                 {field: 'ip_address', title: 'IP地址', width: 130},
 | |
|                 {field: 'location', title: '登录地点', width: 120},
 | |
|                 {field: 'device_type', title: '设备类型', width: 100},
 | |
|                 {field: 'user_agent', title: '浏览器', width: 200},
 | |
|                 {field: 'login_status', title: '状态', width: 100, templet: function(d){
 | |
|                     return d.login_status == 1 ? 
 | |
|                         '<span class="layui-badge layui-bg-green">成功</span>' : 
 | |
|                         '<span class="layui-badge layui-bg-red">失败</span>';
 | |
|                 }},
 | |
|                 {field: 'failure_reason', title: '失败原因', width: 150},
 | |
|                 {field: 'login_time', title: '登录时间', width: 180, sort: true},
 | |
|                 {title: '操作', toolbar: '#tableBar', width: 80, fixed: 'right'}
 | |
|             ]],
 | |
|             page: true,
 | |
|             limit: 10,
 | |
|             limits: [10, 20, 50, 100]
 | |
|         });
 | |
|         
 | |
|         // 监听搜索表单提交
 | |
|         form.on('submit(searchForm)', function(data){
 | |
|             var timeRange = data.field.time_range;
 | |
|             if(timeRange){
 | |
|                 var times = timeRange.split(' - ');
 | |
|                 data.field.start_time = times[0];
 | |
|                 data.field.end_time = times[1];
 | |
|             }
 | |
|             delete data.field.time_range;
 | |
|             
 | |
|             table.reload('loginLogTable', {
 | |
|                 where: data.field,
 | |
|                 page: {curr: 1}
 | |
|             });
 | |
|             return false;
 | |
|         });
 | |
|         
 | |
|         // 监听工具条
 | |
|         table.on('tool(loginLogTable)', function(obj){
 | |
|             var data = obj.data;
 | |
|             if(obj.event === 'del'){
 | |
|                 layer.confirm('确定删除这条日志吗?', function(index){
 | |
|                     $.post('<?php echo url("log/deleteLogin"); ?>', {id: data.id}, function(res){
 | |
|                         if(res.code === 0){
 | |
|                             layer.msg(res.msg, {icon: 1});
 | |
|                             obj.del();
 | |
|                         }else{
 | |
|                             layer.msg(res.msg, {icon: 2});
 | |
|                         }
 | |
|                     });
 | |
|                     layer.close(index);
 | |
|                 });
 | |
|             }
 | |
|         });
 | |
|         
 | |
|         // 监听头工具栏事件
 | |
|         table.on('toolbar(loginLogTable)', function(obj){
 | |
|             if(obj.event === 'clearAll'){
 | |
|                 layer.confirm('确定要清空所有登录日志吗?', function(index){
 | |
|                     $.post('<?php echo url("log/clearLogin"); ?>', function(res){
 | |
|                         if(res.code === 0){
 | |
|                             layer.msg(res.msg, {icon: 1});
 | |
|                             table.reload('loginLogTable');
 | |
|                         }else{
 | |
|                             layer.msg(res.msg, {icon: 2});
 | |
|                         }
 | |
|                     });
 | |
|                     layer.close(index);
 | |
|                 });
 | |
|             }
 | |
|         });
 | |
|     });
 | |
|     </script>
 | |
| </body>
 | |
| </html> 
 | 
