336 lines
14 KiB
HTML
336 lines
14 KiB
HTML
|
|
<title>操作日志</title>
|
|
|
|
<div class="layui-card layadmin-header">
|
|
<div class="layui-breadcrumb" lay-filter="breadcrumb">
|
|
<a lay-href="">主页</a>
|
|
<a><cite>系统</cite></a>
|
|
<a><cite>操作日志</cite></a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-fluid">
|
|
<div class="layui-form layui-card-header layuiadmin-card-header-auto" lay-filter="layadmin-log-formlist">
|
|
<div class="layui-form-item">
|
|
<div class="layui-inline">
|
|
<label class="layui-form-label">管理员</label>
|
|
<div class="layui-input-block">
|
|
<select name="adminId" id="adminSelect" lay-search>
|
|
<option value="">全部</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-inline">
|
|
<label class="layui-form-label">操作模块</label>
|
|
<div class="layui-input-block">
|
|
<select name="module" id="moduleSelect">
|
|
<option value="">全部</option>
|
|
<option value="1">用户管理</option>
|
|
<option value="2">系统用户</option>
|
|
<option value="3">角色管理</option>
|
|
<option value="4">菜单管理</option>
|
|
<option value="5">字典管理</option>
|
|
<option value="6">游戏配置</option>
|
|
<option value="7">房间管理</option>
|
|
<option value="8">客服管理</option>
|
|
<option value="9">靓号管理</option>
|
|
<option value="10">公告管理</option>
|
|
<option value="11">任务管理</option>
|
|
<option value="99">其他</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-inline">
|
|
<label class="layui-form-label">操作时间</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" name="timeRange" id="timeRange" placeholder="选择时间范围" autocomplete="off" class="layui-input">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-inline">
|
|
<button class="layui-btn layuiadmin-btn-list" lay-submit lay-filter="LAY-log-front-search">
|
|
<i class="layui-icon layui-icon-search layuiadmin-button-btn"></i> 搜索
|
|
</button>
|
|
<button class="layui-btn layui-btn-primary" lay-filter="LAY-log-front-reset">
|
|
<i class="layui-icon layui-icon-refresh layuiadmin-button-btn"></i> 重置
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-card">
|
|
<div class="layui-card-body">
|
|
<table id="LAY-log-manage" lay-filter="LAY-log-manage"></table>
|
|
|
|
<script type="text/html" id="table-log-toolbar">
|
|
<div class="layui-btn-container">
|
|
<button class="layui-btn layui-btn-sm layui-btn-primary" lay-event="refresh">
|
|
<i class="layui-icon layui-icon-refresh"></i> 刷新
|
|
</button>
|
|
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="batchdel">
|
|
<i class="layui-icon layui-icon-delete"></i> 批量删除
|
|
</button>
|
|
</div>
|
|
</script>
|
|
|
|
<script type="text/html" id="table-log-bar">
|
|
<a class="layui-btn layui-btn-xs" lay-event="detail"><i class="layui-icon layui-icon-about"></i>详情</a>
|
|
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i>删除</a>
|
|
</script>
|
|
|
|
<script type="text/html" id="moduleTpl">
|
|
{{# var moduleNames = {1:'用户管理',2:'系统用户',3:'角色管理',4:'菜单管理',5:'字典管理',6:'游戏配置',7:'房间管理',8:'客服管理',9:'靓号管理',10:'公告管理',11:'任务管理',99:'其他'}; }}
|
|
{{# return moduleNames[d.module] || '未知'; }}
|
|
</script>
|
|
|
|
<script type="text/html" id="statusTpl">
|
|
{{# if(d.status === 1){ }}
|
|
<span class="layui-badge layui-bg-green">成功</span>
|
|
{{# } else { }}
|
|
<span class="layui-badge layui-bg-red">失败</span>
|
|
{{# } }}
|
|
</script>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
layui.use(['admin', 'table', 'form', 'laydate'], function () {
|
|
var $ = layui.$,
|
|
admin = layui.admin,
|
|
view = layui.view,
|
|
table = layui.table,
|
|
setter = layui.setter,
|
|
form = layui.form,
|
|
laydate = layui.laydate;
|
|
|
|
// 时间范围选择器
|
|
laydate.render({
|
|
elem: '#timeRange',
|
|
type: 'datetime',
|
|
range: '~'
|
|
});
|
|
|
|
// 加载管理员下拉
|
|
function loadAdmins() {
|
|
admin.req({
|
|
url: setter.baseurl + 'adminapi/OperationLog/admins',
|
|
done: function (res) {
|
|
var html = '<option value="">全部</option>';
|
|
layui.each(res.data, function (index, item) {
|
|
html += '<option value="' + item.value + '">' + item.label + '</option>';
|
|
});
|
|
$('#adminSelect').html(html);
|
|
form.render('select');
|
|
}
|
|
});
|
|
}
|
|
loadAdmins();
|
|
|
|
form.render(null, 'layadmin-log-formlist');
|
|
|
|
// 监听搜索
|
|
form.on('submit(LAY-log-front-search)', function (data) {
|
|
var field = data.field;
|
|
if (field.timeRange) {
|
|
var times = field.timeRange.split('~');
|
|
field.startTime = new Date(times[0].trim()).getTime();
|
|
field.endTime = new Date(times[1].trim()).getTime();
|
|
}
|
|
delete field.timeRange;
|
|
|
|
table.reload('LAY-log-manage', {
|
|
where: field,
|
|
page: { curr: 1 }
|
|
});
|
|
});
|
|
|
|
// 监听重置
|
|
form.on('submit(LAY-log-front-reset)', function (data) {
|
|
$('#adminSelect').val('');
|
|
$('#moduleSelect').val('');
|
|
$('#timeRange').val('');
|
|
form.render('select');
|
|
table.reload('LAY-log-manage', {
|
|
where: {},
|
|
page: { curr: 1 }
|
|
});
|
|
});
|
|
|
|
// 刷新按钮
|
|
$('.layui-btn-container').on('click', '[lay-event="refresh"]', function () {
|
|
table.reload('LAY-log-manage');
|
|
});
|
|
|
|
table.render({
|
|
elem: "#LAY-log-manage",
|
|
url: setter.baseurl + "adminapi/OperationLog/list",
|
|
method: "post",
|
|
contentType: "application/json",
|
|
headers: {
|
|
'token': layui.data(setter.tableName)[setter.request.tokenName]
|
|
},
|
|
page: true,
|
|
toolbar: '#table-log-toolbar',
|
|
defaultToolbar: ['filter', 'exports', 'print'],
|
|
where: {},
|
|
request: {
|
|
pageName: 'pageIndex',
|
|
limitName: 'pageSize'
|
|
},
|
|
limit: 10,
|
|
cols: [[
|
|
{ type: 'checkbox', fixed: 'left' },
|
|
{ type: 'numbers', title: '序号', width: 60 },
|
|
{ field: "adminName", title: "管理员", width: 120 },
|
|
{ field: "module", title: "模块", width: 100, templet: '#moduleTpl' },
|
|
{ field: "actionType", title: "操作类型", width: 120 },
|
|
{ field: "description", title: "操作描述", minWidth: 200 },
|
|
{ field: "httpMethod", title: "请求方式", width: 100, templet: function(d) {
|
|
var color = d.httpMethod === 'GET' ? 'layui-bg-blue' : (d.httpMethod === 'POST' ? 'layui-bg-green' : 'layui-bg-orange');
|
|
return '<span class="layui-badge ' + color + '">' + d.httpMethod + '</span>';
|
|
}},
|
|
{ field: "ip", title: "IP地址", width: 130 },
|
|
{ field: "status", title: "状态", width: 80, templet: '#statusTpl' },
|
|
{ field: "operateTime", title: "操作时间", width: 160, templet: function(d) {
|
|
return formatDateTime(d.operateTime);
|
|
}},
|
|
{ width: 120, title: "操作", align: "center", fixed: "right", toolbar: "#table-log-bar" }
|
|
]],
|
|
text: "对不起,加载出现异常!",
|
|
response: {
|
|
statusName: 'code',
|
|
statusCode: 0,
|
|
msgName: 'info',
|
|
countName: 'count',
|
|
dataName: 'data'
|
|
}
|
|
});
|
|
|
|
// 监听工具条
|
|
table.on("tool(LAY-log-manage)", function (e) {
|
|
var l = e.data;
|
|
|
|
if ("detail" === e.event) {
|
|
showLogDetail(l);
|
|
} else if ("del" === e.event) {
|
|
layer.confirm('确定删除该日志吗?', function (idx) {
|
|
admin.req({
|
|
url: setter.baseurl + 'adminapi/OperationLog/Delete',
|
|
data: { id: l.id },
|
|
done: function (res) {
|
|
layer.close(idx);
|
|
if (res.code === 0) {
|
|
layer.msg('删除成功');
|
|
table.reload('LAY-log-manage');
|
|
} else {
|
|
layer.msg(res.info || '删除失败');
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
// 批量删除
|
|
table.on('toolbar(LAY-log-manage)', function (obj) {
|
|
if (obj.event === 'batchdel') {
|
|
var checkStatus = table.checkStatus('LAY-log-manage');
|
|
var data = checkStatus.data;
|
|
if (data.length === 0) return layer.msg('请选择要删除的数据');
|
|
|
|
layer.confirm('确定删除选中的 ' + data.length + ' 条日志吗?', function (idx) {
|
|
var ids = data.map(function (item) { return item.id; });
|
|
admin.req({
|
|
url: setter.baseurl + 'adminapi/OperationLog/BatchDelete',
|
|
contentType: 'application/json',
|
|
method: 'post',
|
|
data: JSON.stringify(ids),
|
|
done: function (res) {
|
|
layer.close(idx);
|
|
if (res.code === 0) {
|
|
layer.msg('删除成功');
|
|
table.reload('LAY-log-manage');
|
|
} else {
|
|
layer.msg(res.info || '删除失败');
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
// 显示日志详情
|
|
function showLogDetail(log) {
|
|
var content =
|
|
'<div style="padding: 20px;">' +
|
|
'<fieldset class="layui-elem-field">' +
|
|
'<legend>基本信息</legend>' +
|
|
'<div class="layui-field-box">' +
|
|
'<p><strong>管理员:</strong>' + (log.adminName || '-') + '</p>' +
|
|
'<p><strong>模块:</strong>' + getModuleName(log.module) + '</p>' +
|
|
'<p><strong>操作类型:</strong>' + (log.actionType || '-') + '</p>' +
|
|
'<p><strong>操作描述:</strong>' + (log.description || '-') + '</p>' +
|
|
'<p><strong>操作时间:</strong>' + formatDateTime(log.operateTime) + '</p>' +
|
|
'<p><strong>IP地址:</strong>' + (log.ip || '-') + '</p>' +
|
|
'<p><strong>状态:</strong>' + (log.status === 1 ? '成功' : '失败') + '</p>' +
|
|
'</div>' +
|
|
'</fieldset>' +
|
|
'<fieldset class="layui-elem-field">' +
|
|
'<legend>请求信息</legend>' +
|
|
'<div class="layui-field-box">' +
|
|
'<p><strong>请求方式:</strong>' + (log.httpMethod || '-') + '</p>' +
|
|
'<p><strong>请求参数:</strong></p>' +
|
|
'<pre style="background:#f5f5f5;padding:10px;border-radius:4px;max-height:200px;overflow:auto;">' + formatJson(log.requestParams) + '</pre>' +
|
|
'</div>' +
|
|
'</fieldset>' +
|
|
'<fieldset class="layui-elem-field">' +
|
|
'<legend>响应信息</legend>' +
|
|
'<div class="layui-field-box">' +
|
|
'<pre style="background:#f5f5f5;padding:10px;border-radius:4px;max-height:200px;overflow:auto;">' + formatJson(log.response) + '</pre>' +
|
|
'</div>' +
|
|
'</fieldset>' +
|
|
'</div>';
|
|
layer.open({
|
|
type: 1,
|
|
title: '操作日志详情',
|
|
area: ['700px', '600px'],
|
|
content: content
|
|
});
|
|
}
|
|
|
|
function getModuleName(module) {
|
|
var moduleNames = {
|
|
1: '用户管理', 2: '系统用户', 3: '角色管理', 4: '菜单管理',
|
|
5: '字典管理', 6: '游戏配置', 7: '房间管理', 8: '客服管理',
|
|
9: '靓号管理', 10: '公告管理', 11: '任务管理', 99: '其他'
|
|
};
|
|
return moduleNames[module] || '未知';
|
|
}
|
|
|
|
function formatDateTime(date) {
|
|
if (!date) return '-';
|
|
var d = new Date(date);
|
|
var year = d.getFullYear();
|
|
var month = ('0' + (d.getMonth() + 1)).slice(-2);
|
|
var day = ('0' + d.getDate()).slice(-2);
|
|
var hour = ('0' + d.getHours()).slice(-2);
|
|
var minute = ('0' + d.getMinutes()).slice(-2);
|
|
var second = ('0' + d.getSeconds()).slice(-2);
|
|
return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
|
|
}
|
|
|
|
function formatJson(str) {
|
|
if (!str) return '无';
|
|
try {
|
|
var obj = typeof str === 'string' ? JSON.parse(str) : str;
|
|
return JSON.stringify(obj, null, 2);
|
|
} catch (e) {
|
|
return str;
|
|
}
|
|
}
|
|
});
|
|
</script>
|