修复代码增加统计,增加redis
This commit is contained in:
parent
07b3bd5eff
commit
e65f150df7
@ -6,7 +6,8 @@ namespace app\index\controller;
|
||||
use think\App;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use think\facade\Config;
|
||||
use think\facade\Db;
|
||||
use app\service\VisitStatsService;
|
||||
|
||||
/**
|
||||
* 前台控制器基础类
|
||||
@ -18,6 +19,7 @@ abstract class BaseController
|
||||
* @var \think\Request
|
||||
*/
|
||||
protected $request;
|
||||
protected $visitStats;
|
||||
|
||||
/**
|
||||
* 应用实例
|
||||
@ -34,6 +36,7 @@ abstract class BaseController
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->request = $this->app->request;
|
||||
$this->visitStats = new VisitStatsService();
|
||||
|
||||
// 控制器初始化
|
||||
$this->initialize();
|
||||
@ -44,20 +47,25 @@ abstract class BaseController
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
// 记录访问
|
||||
$this->visitStats->recordVisit($this->getControllerName());
|
||||
|
||||
// 获取配置
|
||||
$configList = Db::table('yz_admin_config')
|
||||
->where('config_status', 1)
|
||||
->order('config_sort DESC')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
// 将配置数据转换为键值对形式
|
||||
$config = [];
|
||||
foreach ($configList as $item) {
|
||||
$config[$item['config_name']] = $item['config_value'];
|
||||
}
|
||||
|
||||
// 设置通用变量
|
||||
View::assign([
|
||||
'site_name' => '网站名称',
|
||||
'site_description' => '网站描述',
|
||||
'site_keywords' => '网站关键词',
|
||||
'config' => [
|
||||
'admin_name' => Config::get('site.name', '云泽科技'),
|
||||
'admin_phone' => Config::get('site.phone', '400-123-4567'),
|
||||
'admin_email' => Config::get('site.email', 'admin@example.com'),
|
||||
'admin_wechat' => Config::get('site.wechat_qrcode', '/static/images/wechat_qrcode.jpg'),
|
||||
'logo' => Config::get('site.logo', '/static/images/logo.png'),
|
||||
'logo1' => Config::get('site.logo1', '/static/images/logo1.png'),
|
||||
'admin_route' => Config::get('site.admin_route', '/admin/')
|
||||
]
|
||||
'config' => $config
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ namespace app\service;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Request;
|
||||
use think\facade\Db;
|
||||
use think\facade\Log;
|
||||
|
||||
class VisitStatsService
|
||||
{
|
||||
@ -15,8 +16,14 @@ class VisitStatsService
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// 获取Redis处理器
|
||||
$this->redis = Cache::store('redis')->handler();
|
||||
try {
|
||||
// 获取Redis处理器
|
||||
$this->redis = Cache::store('redis')->handler();
|
||||
} catch (\Exception $e) {
|
||||
// Redis连接失败,使用文件缓存
|
||||
$this->redis = Cache::store('file')->handler();
|
||||
Log::error('Redis连接失败,已切换到文件缓存:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -24,45 +31,56 @@ class VisitStatsService
|
||||
*/
|
||||
public function recordVisit(string $page = 'home', string $userId = null): array
|
||||
{
|
||||
$date = date('Y-m-d');
|
||||
$hour = date('H');
|
||||
$userId = $userId ?? Request::ip();
|
||||
|
||||
// 使用管道提高性能
|
||||
$pipe = $this->redis->multi();
|
||||
|
||||
// 总访问量(PV)
|
||||
$pipe->incr($this->prefix.'total_visits');
|
||||
|
||||
// 每日访问量
|
||||
$pipe->incr($this->prefix.'daily:'.$date);
|
||||
|
||||
// 页面统计
|
||||
$pipe->zIncrBy($this->prefix.'page_views', 1, $page);
|
||||
|
||||
// UV统计(使用HyperLogLog节省内存)
|
||||
$pipe->pfAdd($this->prefix.'uv:'.$date, [$userId]);
|
||||
|
||||
// 时段统计
|
||||
$pipe->hIncrBy($this->prefix.'hourly:'.$date, $hour, 1);
|
||||
|
||||
// 执行所有命令
|
||||
$result = $pipe->exec();
|
||||
|
||||
// 更新数据库统计
|
||||
$this->updateDailyStats($date, [
|
||||
'total_visits' => $result[0],
|
||||
'daily_visits' => $result[1],
|
||||
'unique_visitors' => $this->getUniqueVisitors($date)
|
||||
]);
|
||||
|
||||
return [
|
||||
'total' => $result[0],
|
||||
'daily' => $result[1],
|
||||
'page' => $result[2],
|
||||
'uv' => $result[3],
|
||||
'hourly'=> $result[4]
|
||||
];
|
||||
try {
|
||||
$date = date('Y-m-d');
|
||||
$hour = date('H');
|
||||
$userId = $userId ?? Request::ip();
|
||||
|
||||
// 使用管道提高性能
|
||||
$pipe = $this->redis->multi();
|
||||
|
||||
// 总访问量(PV)
|
||||
$pipe->incr($this->prefix.'total_visits');
|
||||
|
||||
// 每日访问量
|
||||
$pipe->incr($this->prefix.'daily:'.$date);
|
||||
|
||||
// 页面统计
|
||||
$pipe->zIncrBy($this->prefix.'page_views', 1, $page);
|
||||
|
||||
// UV统计(使用HyperLogLog节省内存)
|
||||
$pipe->pfAdd($this->prefix.'uv:'.$date, [$userId]);
|
||||
|
||||
// 时段统计
|
||||
$pipe->hIncrBy($this->prefix.'hourly:'.$date, $hour, 1);
|
||||
|
||||
// 执行所有命令
|
||||
$result = $pipe->exec();
|
||||
|
||||
// 更新数据库统计
|
||||
$this->updateDailyStats($date, [
|
||||
'total_visits' => $result[0],
|
||||
'daily_visits' => $result[1],
|
||||
'unique_visitors' => $this->getUniqueVisitors($date)
|
||||
]);
|
||||
|
||||
return [
|
||||
'total' => $result[0],
|
||||
'daily' => $result[1],
|
||||
'page' => $result[2],
|
||||
'uv' => $result[3],
|
||||
'hourly'=> $result[4]
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
Log::error('访问统计失败:' . $e->getMessage());
|
||||
return [
|
||||
'total' => 0,
|
||||
'daily' => 0,
|
||||
'page' => 0,
|
||||
'uv' => 0,
|
||||
'hourly'=> 0
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,36 +88,63 @@ class VisitStatsService
|
||||
*/
|
||||
protected function updateDailyStats(string $date, array $stats)
|
||||
{
|
||||
// 获取其他统计数据
|
||||
$otherStats = [
|
||||
'total_users' => Db::name('users')->where('delete_time', null)->count(),
|
||||
'new_users' => Db::name('users')->whereDay('create_time', $date)->count(),
|
||||
'total_articles' => Db::name('articles')->where('delete_time', null)->count(),
|
||||
'daily_articles' => Db::name('articles')->whereDay('create_time', $date)->count(),
|
||||
'article_views' => Db::name('articles')->whereDay('update_time', $date)->sum('views'),
|
||||
'total_resources' => Db::name('resources')->where('delete_time', null)->count(),
|
||||
'daily_resources' => Db::name('resources')->whereDay('create_time', $date)->count(),
|
||||
'resource_downloads' => Db::name('resources')->whereDay('update_time', $date)->sum('downloads')
|
||||
];
|
||||
|
||||
// 合并统计数据
|
||||
$stats = array_merge($stats, $otherStats);
|
||||
|
||||
// 更新或插入统计数据
|
||||
Db::name('daily_stats')->insertOrUpdate([
|
||||
'date' => $date,
|
||||
'total_users' => $stats['total_users'],
|
||||
'new_users' => $stats['new_users'],
|
||||
'total_visits' => $stats['total_visits'],
|
||||
'daily_visits' => $stats['daily_visits'],
|
||||
'unique_visitors' => $stats['unique_visitors'],
|
||||
'total_articles' => $stats['total_articles'],
|
||||
'daily_articles' => $stats['daily_articles'],
|
||||
'article_views' => $stats['article_views'],
|
||||
'total_resources' => $stats['total_resources'],
|
||||
'daily_resources' => $stats['daily_resources'],
|
||||
'resource_downloads' => $stats['resource_downloads']
|
||||
], ['date']);
|
||||
try {
|
||||
// 获取其他统计数据
|
||||
$otherStats = [
|
||||
'total_users' => Db::name('users')->count(), // 移除 delete_time 条件
|
||||
'new_users' => Db::name('users')->whereDay('create_time', $date)->count(),
|
||||
'total_articles' => Db::name('articles')->where('delete_time', null)->count(),
|
||||
'daily_articles' => Db::name('articles')->whereDay('create_time', $date)->count(),
|
||||
'article_views' => Db::name('articles')->whereDay('update_time', $date)->sum('views'),
|
||||
'total_resources' => Db::name('resources')->where('delete_time', null)->count(),
|
||||
'daily_resources' => Db::name('resources')->whereDay('create_time', $date)->count(),
|
||||
'resource_downloads' => Db::name('resources')->whereDay('update_time', $date)->sum('downloads')
|
||||
];
|
||||
|
||||
// 记录日志,方便调试
|
||||
Log::info('统计数据:' . json_encode($otherStats, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
// 合并统计数据
|
||||
$stats = array_merge($stats, $otherStats);
|
||||
|
||||
// 检查记录是否存在
|
||||
$exists = Db::name('daily_stats')->where('date', $date)->find();
|
||||
|
||||
if ($exists) {
|
||||
// 更新已存在的记录
|
||||
Db::name('daily_stats')->where('date', $date)->update([
|
||||
'total_users' => $stats['total_users'],
|
||||
'new_users' => $stats['new_users'],
|
||||
'total_visits' => $stats['total_visits'],
|
||||
'daily_visits' => $stats['daily_visits'],
|
||||
'unique_visitors' => $stats['unique_visitors'],
|
||||
'total_articles' => $stats['total_articles'],
|
||||
'daily_articles' => $stats['daily_articles'],
|
||||
'article_views' => $stats['article_views'],
|
||||
'total_resources' => $stats['total_resources'],
|
||||
'daily_resources' => $stats['daily_resources'],
|
||||
'resource_downloads' => $stats['resource_downloads']
|
||||
]);
|
||||
} else {
|
||||
// 插入新记录
|
||||
Db::name('daily_stats')->insert([
|
||||
'date' => $date,
|
||||
'total_users' => $stats['total_users'],
|
||||
'new_users' => $stats['new_users'],
|
||||
'total_visits' => $stats['total_visits'],
|
||||
'daily_visits' => $stats['daily_visits'],
|
||||
'unique_visitors' => $stats['unique_visitors'],
|
||||
'total_articles' => $stats['total_articles'],
|
||||
'daily_articles' => $stats['daily_articles'],
|
||||
'article_views' => $stats['article_views'],
|
||||
'total_resources' => $stats['total_resources'],
|
||||
'daily_resources' => $stats['daily_resources'],
|
||||
'resource_downloads' => $stats['resource_downloads']
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('更新统计数据失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,7 +152,12 @@ class VisitStatsService
|
||||
*/
|
||||
public function getTotalVisits(): int
|
||||
{
|
||||
return (int)$this->redis->get($this->prefix.'total_visits');
|
||||
try {
|
||||
return (int)$this->redis->get($this->prefix.'total_visits');
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取总访问量失败:' . $e->getMessage());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,8 +165,13 @@ class VisitStatsService
|
||||
*/
|
||||
public function getDailyVisits(string $date = null): int
|
||||
{
|
||||
$date = $date ?? date('Y-m-d');
|
||||
return (int)$this->redis->get($this->prefix.'daily:'.$date);
|
||||
try {
|
||||
$date = $date ?? date('Y-m-d');
|
||||
return (int)$this->redis->get($this->prefix.'daily:'.$date);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取当日访问量失败:' . $e->getMessage());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,10 +179,13 @@ class VisitStatsService
|
||||
*/
|
||||
public function getUniqueVisitors(string $date = null): int
|
||||
{
|
||||
$date = $date ?? date('Y-m-d');
|
||||
return $this->redis->pfCount($this->prefix.'uv:'.$date);
|
||||
try {
|
||||
$date = $date ?? date('Y-m-d');
|
||||
return $this->redis->pfCount($this->prefix.'uv:'.$date);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取独立访客数失败:' . $e->getMessage());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取热门页面
|
||||
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ return [
|
||||
// 连接超时时间
|
||||
'timeout' => 0,
|
||||
// 是否持久化连接
|
||||
'persistent' => true,
|
||||
'persistent' => false,
|
||||
// 缓存前缀
|
||||
'prefix' => 'yz_:',
|
||||
],
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 6.7 KiB |
BIN
public/static/images/logo1.png
Normal file
BIN
public/static/images/logo1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
267
runtime/admin/temp/34d283a1bcbe58ecbdbcd3d1f0e36700.php
Normal file
267
runtime/admin/temp/34d283a1bcbe58ecbdbcd3d1f0e36700.php
Normal file
@ -0,0 +1,267 @@
|
||||
<?php /*a:2:{s:51:"E:\Demo\PHP\yunzer\app\admin\view\log\operation.php";i:1747589153;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">模块</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="module" placeholder="请输入模块" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<label class="layui-form-label">操作</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" name="operation" placeholder="请输入操作" 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="operationLogTable" lay-filter="operationLogTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/layui/layui.js"></script>
|
||||
<script>
|
||||
layui.use(['table', 'form', 'laydate', 'layer'], function(){
|
||||
var table = layui.table;
|
||||
var form = layui.form;
|
||||
var laydate = layui.laydate;
|
||||
var layer = layui.layer;
|
||||
|
||||
// 初始化时间范围选择器
|
||||
laydate.render({
|
||||
elem: '#timeRange',
|
||||
type: 'datetime',
|
||||
range: true
|
||||
});
|
||||
|
||||
// 初始化表格
|
||||
table.render({
|
||||
elem: '#operationLogTable',
|
||||
url: '<?php echo url("log/operation"); ?>',
|
||||
method: 'get',
|
||||
defaultToolbar: ['filter', 'exports', 'print'],
|
||||
parseData: function(res) {
|
||||
return {
|
||||
"code": 0,
|
||||
"msg": res.msg || '获取成功',
|
||||
"count": res.count || 0,
|
||||
"data": res.data || []
|
||||
};
|
||||
},
|
||||
cols: [[
|
||||
{field: 'id', title: 'ID', width: 80, sort: true, align: 'center'},
|
||||
{field: 'username', title: '操作人', width: 120, align: 'center'},
|
||||
{field: 'module', title: '模块', width: 120, align: 'center'},
|
||||
{field: 'operation', title: '操作', width: 150, align: 'center'},
|
||||
{field: 'request_method', title: '请求方法', width: 100, align: 'center'},
|
||||
{field: 'request_url', title: '请求地址', align: 'center'},
|
||||
{field: 'ip_address', title: 'IP地址', width: 120, align: 'center'},
|
||||
{field: 'status', title: '状态', width: 100, align: 'center', templet: function(d){
|
||||
return d.status == 1 ? '<span class="layui-badge layui-bg-green">成功</span>' : '<span class="layui-badge layui-bg-red">失败</span>';
|
||||
}},
|
||||
{field: 'operation_time', title: '操作时间', width: 180, align: 'center'},
|
||||
{field: 'execution_time', title: '执行时间(ms)', width: 120, align: 'center'},
|
||||
{title: '操作', width: 120, toolbar: '#operationBar', fixed: 'right', align: 'center'}
|
||||
]],
|
||||
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('operationLogTable', {
|
||||
where: data.field,
|
||||
page: {curr: 1}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// 监听工具条
|
||||
table.on('tool(operationLogTable)', function(obj){
|
||||
var data = obj.data;
|
||||
if(obj.event === 'detail'){
|
||||
// 获取详情
|
||||
$.ajax({
|
||||
url: '<?php echo url("log/getOperationDetail"); ?>',
|
||||
type: 'GET',
|
||||
data: {id: data.id},
|
||||
success: function(res){
|
||||
if(res.code === 0){
|
||||
var detail = res.data;
|
||||
var content = '<div class="layui-card">' +
|
||||
'<div class="layui-card-body">' +
|
||||
'<table class="layui-table" lay-skin="nob">' +
|
||||
'<colgroup><col width="100"><col></colgroup>' +
|
||||
'<tbody>' +
|
||||
'<tr><td>操作人:</td><td>' + detail.username + '</td></tr>' +
|
||||
'<tr><td>模块:</td><td>' + detail.module + '</td></tr>' +
|
||||
'<tr><td>操作:</td><td>' + detail.operation + '</td></tr>' +
|
||||
'<tr><td>请求方法:</td><td>' + detail.request_method + '</td></tr>' +
|
||||
'<tr><td>请求地址:</td><td>' + detail.request_url + '</td></tr>' +
|
||||
'<tr><td>请求参数:</td><td><pre>' + JSON.stringify(detail.request_params, null, 2) + '</pre></td></tr>' +
|
||||
'<tr><td>IP地址:</td><td>' + detail.ip_address + '</td></tr>' +
|
||||
'<tr><td>状态:</td><td>' + (detail.status == 1 ? '成功' : '失败') + '</td></tr>' +
|
||||
'<tr><td>错误信息:</td><td>' + (detail.error_message || '无') + '</td></tr>' +
|
||||
'<tr><td>操作时间:</td><td>' + detail.operation_time + '</td></tr>' +
|
||||
'<tr><td>执行时间:</td><td>' + detail.execution_time + 'ms</td></tr>' +
|
||||
'</tbody></table></div></div>';
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '操作日志详情',
|
||||
area: ['800px', '600px'],
|
||||
content: content
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- 表格工具栏模板 -->
|
||||
<script type="text/html" id="operationBar">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="detail">详情</a>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,4 +1,4 @@
|
||||
<?php /*a:3:{s:51:"E:\Demo\PHP\yunzer\app\admin\view\index\welcome.php";i:1747658497;s:51:"E:\Demo\PHP\yunzer\app\admin\view\public\header.php";i:1746890051;s:49:"E:\Demo\PHP\yunzer\app\admin\view\public\tail.php";i:1745855804;}*/ ?>
|
||||
<?php /*a:3:{s:51:"E:\Demo\PHP\yunzer\app\admin\view\index\welcome.php";i:1747663514;s:51:"E:\Demo\PHP\yunzer\app\admin\view\public\header.php";i:1746890051;s:49:"E:\Demo\PHP\yunzer\app\admin\view\public\tail.php";i:1745855804;}*/ ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user