增加 laytable 支持

This commit is contained in:
邹景立 2021-07-20 17:59:06 +08:00
parent b24e9d4805
commit ef7bf55ecb
3 changed files with 119 additions and 66 deletions

View File

@ -16,8 +16,10 @@
namespace app\admin\controller; namespace app\admin\controller;
use Exception;
use think\admin\Controller; use think\admin\Controller;
use think\admin\service\AdminService; use think\admin\service\AdminService;
use think\exception\HttpResponseException;
/** /**
* 系统日志管理 * 系统日志管理
@ -47,21 +49,22 @@ class Oplog extends Controller
$this->isSupper = AdminService::instance()->isSuper(); $this->isSupper = AdminService::instance()->isSuper();
$this->actions = $this->app->db->name($this->table)->distinct(true)->column('action'); $this->actions = $this->app->db->name($this->table)->distinct(true)->column('action');
$query = $this->_query($this->table)->dateBetween('create_at')->order('id desc'); $query = $this->_query($this->table)->dateBetween('create_at')->order('id desc');
$query->like('action,node,content,username,geoip')->page(); $query->like('action,node,content,username,geoip')->layTable();
} }
/** /**
* 列表数据处理 * 列表数据处理
* @auth true * @auth true
* @param array $data * @param array $data
* @throws \Exception * @throws Exception
*/ */
protected function _index_page_filter(array &$data) protected function _index_page_filter(array &$data)
{ {
$ip = new \Ip2Region(); $region = new \Ip2Region();
foreach ($data as &$vo) { foreach ($data as &$vo) {
$isp = $ip->btreeSearch($vo['geoip']); $isp = $region->btreeSearch($vo['geoip']);
$vo['isp'] = str_replace(['内网IP', '0', '|'], '', $isp['region'] ?? ''); $vo['geoisp'] = str_replace(['内网IP', '0', '|'], '', $isp['region'] ?? '') ?: '-';
$vo['create_at'] = format_datetime($vo['create_at']);
} }
} }
@ -75,9 +78,9 @@ class Oplog extends Controller
$this->_query($this->table)->empty(); $this->_query($this->table)->empty();
sysoplog('系统运维管理', '成功清理所有日志数据'); sysoplog('系统运维管理', '成功清理所有日志数据');
$this->success('日志清理成功!'); $this->success('日志清理成功!');
} catch (\think\exception\HttpResponseException $exception) { } catch (HttpResponseException $exception) {
throw $exception; throw $exception;
} catch (\Exception $exception) { } catch (Exception $exception) {
$this->error("日志清理失败,{$exception->getMessage()}"); $this->error("日志清理失败,{$exception->getMessage()}");
} }
} }
@ -89,7 +92,6 @@ class Oplog extends Controller
*/ */
public function remove() public function remove()
{ {
$this->_applyFormToken();
$this->_delete($this->table); $this->_delete($this->table);
} }

View File

@ -4,60 +4,34 @@
<!--{if auth("clear")}--> <!--{if auth("clear")}-->
<button data-load='{:url("clear")}' data-confirm="确定要清理所有记录吗?" class='layui-btn layui-btn-sm layui-btn-primary'>清理所有日志</button> <button data-load='{:url("clear")}' data-confirm="确定要清理所有记录吗?" class='layui-btn layui-btn-sm layui-btn-primary'>清理所有日志</button>
<!--{/if}--> <!--{/if}-->
<!--{if auth("remove")}--> <!--{if auth("remove")}-->
<button data-action='{:url("remove")}' data-rule="id#{key}" data-csrf="{:systoken('remove')}" data-confirm="确定要删除这些记录吗?" class='layui-btn layui-btn-sm layui-btn-primary'>批量删除日志</button> <button data-action='{:url("remove")}' data-rule="id#{id}" data-table-id="oplog" data-confirm="确定要删除这些记录吗?" class='layui-btn layui-btn-sm layui-btn-primary'>批量删除日志</button>
<!--{/if}--> <!--{/if}-->
{/block} {/block}
{block name="content"} {block name="content"}
<div class="think-box-shadow"> <div class="think-box-shadow">
{include file='oplog/index_search'} {include file='oplog/index_search'}
<table class="layui-table margin-top-10" lay-skin="line"> <table id="oplog" data-url="{:sysuri()}" class="layui-hide" data-target-search="form.form-search"></table>
{notempty name='list'}
<thead>
<tr>
<th class='list-table-check-td think-checkbox'>
<label><input data-auto-none data-check-target='.list-check-box' type='checkbox'></label>
</th>
<th class='text-left nowrap'>操作权限</th>
<th class='text-left nowrap'>操作行为</th>
<th class='text-left nowrap'>地理位置</th>
<th class='text-left nowrap'>操作时间</th>
<th></th>
</tr>
</thead>
<tbody>
{foreach $list as $key=>$vo}
<tr>
<td class='list-table-check-td think-checkbox'>
<label><input class="list-check-box" value='{$vo.id}' type='checkbox'></label>
</td>
<td class="text-left nowrap">
操作账号:<span class="font-w7">{$vo.username|default='-'}</span><br>
操作节点:<span class="color-desc">{$vo.node|default='-'}</span>
</td>
<td class='text-left padding-row-0 padding-right-0'>
<p class="color-text layui-elip" style='max-width:600px'>{$vo.action|default='-'}</p>
<p class="color-desc layui-elip" style='max-width:600px'>{$vo.content|default='-'}</p>
</td>
<td class='text-left nowrap'>
<p class="color-text">{$vo.geoip|default='-'}</p>
<p class="color-desc">{$vo.isp|default='-'}</p>
</td>
<td class='text-left nowrap'>
日期:{$vo.create_at|format_datetime|str_replace=' ','<br><span class="color-desc">时间:',###|raw}</span>
</td>
<td class='text-left nowrap'>
<!--{if auth("remove")}-->
<a class="layui-btn layui-btn-sm layui-btn-danger" data-confirm="确定要删除该日志吗?" data-action="{:url('remove')}" data-value="id#{$vo.id}" data-csrf="{:systoken('remove')}"> </a>
<!--{/if}-->
</td>
</tr>
{/foreach}
</tbody>
{/notempty}
</table>
{empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty}
</div> </div>
{/block} {/block}
{block name='script'}
<script>
$(function () {
$('table').layTable({
sort: {field: 'id', type: 'desc'},
cols: [[
{checkbox: true},
{field: 'id', title: 'ID', width: 80, sort: true, align: 'center'},
{field: 'node', title: '操作节点', sort: true},
{field: 'action', title: '操作行为', sort: true},
{field: 'content', title: '操作描述', sort: false},
{field: 'geoip', title: '访问IP地址', sort: true},
{field: 'geoisp', title: '网络服务商', sort: false},
{field: 'create_at', title: '操作时间', sort: true},
]]
});
});
</script>
{/block}

View File

@ -102,16 +102,34 @@ $(function () {
/*! 读取 data-rule 绑定 table 值 */ /*! 读取 data-rule 绑定 table 值 */
function applyRuleValue(elem, data) { function applyRuleValue(elem, data) {
var rule = elem.dataset.value || (function (rule, array) { // 新 tableId 规则兼容处理
$(elem.dataset.target || 'input[type=checkbox].list-check-box').map(function () { if (elem.dataset.tableId && elem.dataset.rule) {
this.checked && array.push(this.value); var idx1, idx2, temp, regx, field, rule = {};
var json = layui.table.checkStatus(elem.dataset.tableId).data;
layui.each(elem.dataset.rule.split(';'), function (idx, item, attr) {
(attr = item.split('#', 2)), rule[attr[0]] = attr[1];
}); });
return array.length > 0 ? rule.replace('{key}', array.join(',')) : ''; for (idx1 in rule) {
})(elem.dataset.rule || '', []) || ''; temp = [], regx = new RegExp(/^{(.*?)}$/);
if (rule.length < 1) return $.msg.tips('请选择需要更改的数据!'), false; if (regx.test(rule[idx1]) && (field = rule[idx1].replace(regx, '$1'))) {
return rule.split(';').forEach(function (item) { for (idx2 in json) if (json[idx2][field]) temp.push(json[idx2][field]);
data[item.split('#')[0]] = item.split('#')[1]; if (temp.length < 1) return $.msg.tips('请选择需要更改的数据!'), false;
}), data; data[idx1] = temp.join(',');
}
}
return data;
} else {
var value = elem.dataset.value || (function (rule, array) {
$(elem.dataset.target || 'input[type=checkbox].list-check-box').map(function () {
this.checked && array.push(this.value);
});
return array.length > 0 ? rule.replace('{key}', array.join(',')) : '';
})(elem.dataset.rule || '', []) || '';
if (value.length < 1) return $.msg.tips('请选择需要更改的数据!'), false;
return value.split(';').forEach(function (item) {
data[item.split('#')[0]] = item.split('#')[1];
}), data;
}
} }
/*! 消息组件实例 */ /*! 消息组件实例 */
@ -633,6 +651,60 @@ $(function () {
}); });
} }
/*! 组件 LayUI table 功能封装 */
$.fn.layTable = function (options) {
return this.each(function (idx, elem) {
// 拦截异常标签对象
if (this.nodeName !== 'TABLE') return new Error('It is not a table tag.');
// 动态初始化数据表
this.id = this.id || 't' + Math.random().toString().replace('0.', '');
this.dataset.filter = this.getAttribute('lay-filter') || this.id;
this.setAttribute('lay-filter', this.dataset.filter);
// 标准化请求参数,初始化排序参数,表格插件初始化参数
var data = {}, sort = options.initSort || options.sort || {}, option = {
id: elem.id, elem: elem, url: options.url || elem.dataset.url || '', where: getWhere(),
limit: options.limit || 15, cols: options.cols || [[]], page: options.page !== false,
};
// 延用工具条配置
if (options.title) option.title = options.title;
if (options.toolbar) option.toolbar = options.toolbar;
if (options.defaultToolbar) option.defaultToolbar = top.defaultToolbar;
if (sort.field && sort.type) option.initSort = sort;
// 实例化表单组件
layui.table.render(option);
// 排序事件处理
layui.table.on('sort(' + this.dataset.filter + ')', function (object) {
(sort = object), $(elem).trigger('reload')
});
// 绑定选择项对象
var checked = options.checked || this.dataset.targetChecked;
if (checked) $body.find(checked).map(function () {
$(this).attr('data-table-id', elem.id);
});
// 搜索表单处理
var search = options.search || this.dataset.targetSearch;
if (search) $body.off('submit', 'form.form-search').on('submit', search, function () {
(data.page = 1), (data = $.extend(data, $(this).formToJson())), $(elem).trigger('reload');
});
// 绑定重载事件
$(this).bind('reload', function () {
var config = {where: getWhere()};
if (sort.field && sort.type) config.initSort = sort;
layui.table.reload(elem.id, config);
});
// 获取查询数据
function getWhere() {
data['output'] = 'layui.table';
if (sort.field && sort.type) {
data['_order_'] = sort.type;
data['_field_'] = sort.field;
}
return data;
}
});
}
/*! 注册 data-serach 表单搜索行为 */ /*! 注册 data-serach 表单搜索行为 */
onEvent('submit', 'form.form-search', function () { onEvent('submit', 'form.form-search', function () {
var url = $(this).attr('action').replace(/&?page=\d+/g, ''); var url = $(this).attr('action').replace(/&?page=\d+/g, '');
@ -723,7 +795,12 @@ $(function () {
(function (confirm, callable) { (function (confirm, callable) {
confirm ? $.msg.confirm(confirm, callable) : callable(); confirm ? $.msg.confirm(confirm, callable) : callable();
})(emap.confirm, function () { })(emap.confirm, function () {
$.form.load(emap.action, data, emap.method || 'post', false, load, tips, emap.time) var callable = !emap.tableId ? false : function (ret) {
if (ret.code > 0) return $.msg.success(ret.info, 3, function () {
$('#' + emap.tableId).trigger('reload');
}), false;
}
$.form.load(emap.action, data, emap.method || 'post', callable, load, tips, emap.time)
}); });
}); });