Browse Source

update:分享登录日志方法

aiden 3 months ago
parent
commit
0f66821394

+ 212 - 0
app/controller/LoginLog.php

@@ -0,0 +1,212 @@
+<?php
+declare (strict_types = 1);
+
+namespace app\controller;
+
+use app\BaseController;
+use think\facade\Request;
+use app\model\UserLoginLogModel;
+use app\model\UserModel;
+
+/**
+ * 登录日志控制器
+ */
+class LoginLog extends BaseController
+{
+    /**
+     * 获取登录日志列表
+     */
+    public function list()
+    {
+        $userInfo = $this->request->userInfo;
+        
+        // 获取查询参数
+        $page = Request::get('page', 1, 'intval');
+        $limit = Request::get('limit', 20, 'intval');
+        $userId = Request::get('user_id', 0, 'intval');
+        
+        // 过滤条件
+        $filters = [
+            'login_status' => Request::get('login_status', ''),
+            'login_ip' => Request::get('login_ip', '', 'trim'),
+            'start_time' => Request::get('start_time', '', 'trim'),
+            'end_time' => Request::get('end_time', '', 'trim'),
+        ];
+        
+        try {
+            $result = UserLoginLogModel::getLoginLogs($userInfo['merchant_id'], $userId, $page, $limit, $filters);
+            return json_success($result, '获取成功');
+        } catch (\Exception $e) {
+            return json_error([], '获取登录日志失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 获取登录统计信息
+     */
+    public function statistics()
+    {
+        $userInfo = $this->request->userInfo;
+        
+        $userId = Request::get('user_id', 0, 'intval');
+        $startDate = Request::get('start_date', '', 'trim');
+        $endDate = Request::get('end_date', '', 'trim');
+        
+        // 如果没有指定日期范围,默认获取最近30天
+        if (empty($startDate)) {
+            $startDate = date('Y-m-d', strtotime('-30 days'));
+        }
+        if (empty($endDate)) {
+            $endDate = date('Y-m-d');
+        }
+        
+        try {
+            $statistics = UserLoginLogModel::getLoginStatistics($userInfo['merchant_id'], $userId, $startDate, $endDate);
+            
+            return json_success([
+                'statistics' => $statistics,
+                'date_range' => [
+                    'start_date' => $startDate,
+                    'end_date' => $endDate
+                ]
+            ], '获取成功');
+        } catch (\Exception $e) {
+            return json_error([], '获取登录统计失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 获取用户最近登录记录
+     */
+    public function recentLogs()
+    {
+        $userInfo = $this->request->userInfo;
+        
+        $userId = Request::get('user_id', 0, 'intval');
+        $limit = Request::get('limit', 10, 'intval');
+        
+        // 如果没有指定用户ID,则获取当前用户的登录记录
+        if ($userId == 0) {
+            $userId = $userInfo['user_id'];
+        } else {
+            // 验证用户是否属于当前商户
+            $user = UserModel::where('user_id', $userId)
+                ->where('merchant_id', $userInfo['merchant_id'])
+                ->find();
+            
+            if (!$user) {
+                return json_error([], '用户不存在');
+            }
+        }
+        
+        try {
+            $logs = UserLoginLogModel::getRecentLogs($userId, $limit);
+            
+            // 格式化日志数据
+            foreach ($logs as &$log) {
+                $log['status_text'] = $log['login_status'] == UserLoginLogModel::STATUS_SUCCESS ? '成功' : '失败';
+                $log['login_time_text'] = date('Y-m-d H:i:s', $log['login_time']);
+            }
+            
+            return json_success([
+                'logs' => $logs,
+                'user_id' => $userId
+            ], '获取成功');
+        } catch (\Exception $e) {
+            return json_error([], '获取最近登录记录失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 导出登录日志
+     */
+    public function export()
+    {
+        $userInfo = $this->request->userInfo;
+        
+        // 获取查询参数
+        $userId = Request::get('user_id', 0, 'intval');
+        
+        // 过滤条件
+        $filters = [
+            'login_status' => Request::get('login_status', ''),
+            'login_ip' => Request::get('login_ip', '', 'trim'),
+            'start_time' => Request::get('start_time', '', 'trim'),
+            'end_time' => Request::get('end_time', '', 'trim'),
+        ];
+        
+        try {
+            // 获取所有符合条件的数据(不分页)
+            $result = UserLoginLogModel::getLoginLogs($userInfo['merchant_id'], $userId, 1, 100000, $filters);
+            
+            // 生成CSV数据
+            $csvData = "ID,用户名,昵称,登录设备,登录IP,登录时间,登录状态\n";
+            
+            foreach ($result['list'] as $log) {
+                // 格式化登录时间
+                $loginTime = date('Y-m-d H:i:s', $log['login_time']);
+                
+                // 处理设备信息,移除换行符
+                $device = str_replace(["\r", "\n"], ' ', $log['login_device']);
+                
+                $csvData .= sprintf(
+                    "%d,%s,%s,%s,%s,%s,%s\n",
+                    $log['id'],
+                    $log['user_name'],
+                    $log['nick_name'],
+                    $device,
+                    $log['login_ip'],
+                    $loginTime,
+                    $log['status_text']
+                );
+            }
+            
+            // 返回CSV数据
+            return response($csvData)
+                ->header(['Content-Type' => 'text/csv; charset=utf-8'])
+                ->header(['Content-Disposition' => 'attachment; filename="login_logs_' . date('YmdHis') . '.csv"'])
+                ->header(['Cache-Control' => 'no-cache, must-revalidate']);
+                
+        } catch (\Exception $e) {
+            return json_error([], '导出登录日志失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 获取登录日志详情
+     */
+    public function detail()
+    {
+        $userInfo = $this->request->userInfo;
+        
+        $id = Request::get('id', 0, 'intval');
+        if (!$id) {
+            return json_error([], '日志ID不能为空');
+        }
+        
+        try {
+            $log = UserLoginLogModel::where('id', $id)
+                ->where('merchant_id', $userInfo['merchant_id'])
+                ->find();
+                
+            if (!$log) {
+                return json_error([], '日志不存在');
+            }
+            
+            // 获取用户信息
+            $user = UserModel::where('user_id', $log->user_id)->find();
+            if ($user) {
+                $log->user_name = $user->user_name;
+                $log->nick_name = $user->nick_name;
+            }
+            
+            // 格式化数据
+            $log->status_text = $log->login_status == UserLoginLogModel::STATUS_SUCCESS ? '成功' : '失败';
+            $log->login_time_text = date('Y-m-d H:i:s', $log->login_time);
+            
+            return json_success($log, '获取成功');
+        } catch (\Exception $e) {
+            return json_error([], '获取日志详情失败:' . $e->getMessage());
+        }
+    }
+}

+ 0 - 104
app/controller/User.php

@@ -377,110 +377,6 @@ class User extends BaseController
         }
     }
     
-    /**
-     * 获取登录日志列表
-     */
-    public function loginLogs()
-    {
-        $userInfo = $this->request->userInfo;
-        
-        // 获取查询参数
-        $page = Request::get('page', 1, 'intval');
-        $limit = Request::get('limit', 20, 'intval');
-        $userId = Request::get('user_id', 0, 'intval');
-        
-        // 过滤条件
-        $filters = [
-            'login_status' => Request::get('login_status', ''),
-            'login_ip' => Request::get('login_ip', '', 'trim'),
-            'start_time' => Request::get('start_time', '', 'trim'),
-            'end_time' => Request::get('end_time', '', 'trim'),
-        ];
-        
-        try {
-            $result = UserLoginLogModel::getLoginLogs($userInfo['merchant_id'], $userId, $page, $limit, $filters);
-            return json_success($result, '获取成功');
-        } catch (\Exception $e) {
-            return json_error([], '获取登录日志失败:' . $e->getMessage());
-        }
-    }
-    
-    /**
-     * 获取登录统计信息
-     */
-    public function loginStatistics()
-    {
-        $userInfo = $this->request->userInfo;
-        
-        $userId = Request::get('user_id', 0, 'intval');
-        $startDate = Request::get('start_date', '', 'trim');
-        $endDate = Request::get('end_date', '', 'trim');
-        
-        // 如果没有指定日期范围,默认获取最近30天
-        if (empty($startDate)) {
-            $startDate = date('Y-m-d', strtotime('-30 days'));
-        }
-        if (empty($endDate)) {
-            $endDate = date('Y-m-d');
-        }
-        
-        try {
-            $statistics = UserLoginLogModel::getLoginStatistics($userInfo['merchant_id'], $userId, $startDate, $endDate);
-            
-            return json_success([
-                'statistics' => $statistics,
-                'date_range' => [
-                    'start_date' => $startDate,
-                    'end_date' => $endDate
-                ]
-            ], '获取成功');
-        } catch (\Exception $e) {
-            return json_error([], '获取登录统计失败:' . $e->getMessage());
-        }
-    }
-    
-    /**
-     * 获取用户最近登录记录
-     */
-    public function recentLoginLogs()
-    {
-        $userInfo = $this->request->userInfo;
-        
-        $userId = Request::get('user_id', 0, 'intval');
-        $limit = Request::get('limit', 10, 'intval');
-        
-        // 如果没有指定用户ID,则获取当前用户的登录记录
-        if ($userId == 0) {
-            $userId = $userInfo['user_id'];
-        } else {
-            // 验证用户是否属于当前商户
-            $user = UserModel::where('user_id', $userId)
-                ->where('merchant_id', $userInfo['merchant_id'])
-                ->find();
-            
-            if (!$user) {
-                return json_error([], '用户不存在');
-            }
-        }
-        
-        try {
-            $logs = UserLoginLogModel::getRecentLogs($userId, $limit);
-            
-            // 格式化日志数据
-            foreach ($logs as &$log) {
-                $log['status_text'] = $log['login_status'] == UserLoginLogModel::STATUS_SUCCESS ? '成功' : '失败';
-                $log['login_time_text'] = date('Y-m-d H:i:s', $log['login_time']);
-            }
-            
-            return json_success([
-                'logs' => $logs,
-                'user_id' => $userId
-            ], '获取成功');
-        } catch (\Exception $e) {
-            return json_error([], '获取最近登录记录失败:' . $e->getMessage());
-        }
-    }
-    
     /**
      * 验证输入数据
      */

+ 5 - 4
app/middleware/BehaviorLogMiddleware.php

@@ -16,10 +16,7 @@ class BehaviorLogMiddleware
     private $excludeActions = [
         // 查询类操作(不改变数据的操作)
         'User/list',
-        'User/detail', 
-        'User/loginLogs',
-        'User/loginStatistics',
-        'User/recentLoginLogs',
+        'User/detail',
         'UserRole/list',
         'UserRole/detail',
         'Game/list',
@@ -31,6 +28,10 @@ class BehaviorLogMiddleware
         'Player/statistics',
         'Menu/list',
         'Menu/getUserMenus',
+        'LoginLog/list',
+        'LoginLog/detail',
+        'LoginLog/statistics',
+        'LoginLog/recentLogs',
         'BehaviorLog/list',
         'BehaviorLog/detail',
         'BehaviorLog/statistics',

+ 38 - 2
config/database.php

@@ -2,7 +2,7 @@
 
 return [
     // 默认使用的数据库连接配置
-    'default'         => env('DB_DRIVER', 'mysql'),
+    'default'         => env('DB_DRIVER', 'merchant_admin'),
 
     // 自定义时间查询规则
     'time_query_rule' => [],
@@ -20,7 +20,7 @@ return [
 
     // 数据库连接配置信息
     'connections'     => [
-        'mysql' => [
+        'merchant_admin' => [
             // 数据库类型
             'type'            => env('DB_TYPE', 'mysql'),
             // 服务器地址
@@ -57,7 +57,43 @@ return [
             // 开启字段缓存
             'fields_cache'    => false,
         ],
+        'fortue_tiger' => [
+            // 数据库类型
+            'type'            => env('DB_TYPE', 'mysql'),
+            // 服务器地址
+            'hostname'        => env('DB_HOST', '47.238.245.98'),
+            // 数据库名
+            'database'        => env('DB_NAME', 'fortue_tiger'),
+            // 用户名
+            'username'        => env('DB_USER', 'root'),
+            // 密码
+            'password'        => env('DB_PASS', '9ab5e8139b5425c2'),
+            // 端口
+            'hostport'        => env('DB_PORT', '10086'),
+            // 数据库连接参数
+            'params'          => [],
+            // 数据库编码
+            'charset'         => env('DB_CHARSET', 'utf8'),
+            // 数据库表前缀
+            'prefix'          => env('DB_PREFIX', 'tp_'),
 
+            // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
+            'deploy'          => 0,
+            // 数据库读写是否分离 主从式有效
+            'rw_separate'     => false,
+            // 读写分离后 主服务器数量
+            'master_num'      => 1,
+            // 指定从服务器序号
+            'slave_no'        => '',
+            // 是否严格检查字段是否存在
+            'fields_strict'   => true,
+            // 是否需要断线重连
+            'break_reconnect' => true,
+            // 监听SQL
+            'trigger_sql'     => env('APP_DEBUG', true),
+            // 开启字段缓存
+            'fields_cache'    => false,
+        ],        
         // 更多的数据库配置信息
     ],
 ];

+ 12 - 3
config/permission.php

@@ -79,9 +79,18 @@ return [
                 'update' => '编辑账号',
                 'delete' => '删除账号',
                 'detail' => '查看账号详情',
-                'loginLogs' => '查看登录日志',
-                'loginStatistics' => '查看登录统计',
-                'recentLoginLogs' => '查看最近登录记录',
+            ]
+        ],
+        
+        // 登录日志管理模块
+        'LoginLog' => [
+            'module' => '登录日志',
+            'actions' => [
+                'list' => '查看登录日志列表',
+                'detail' => '查看登录日志详情',
+                'statistics' => '查看登录统计',
+                'recentLogs' => '查看最近登录记录',
+                'export' => '导出登录日志',
             ]
         ],
         

+ 9 - 4
route/app.php

@@ -19,10 +19,6 @@ Route::group('user', function () {
     Route::get('detail', 'User/detail');
     Route::post('update', 'User/update');
     Route::post('delete', 'User/delete');
-    // 登录日志相关
-    Route::get('login_logs', 'User/loginLogs');
-    Route::get('login_statistics', 'User/loginStatistics');
-    Route::get('recent_login_logs', 'User/recentLoginLogs');
 })->middleware([\app\middleware\AuthMiddleware::class, \app\middleware\BehaviorLogMiddleware::class]);
 
 // 角色相关路由
@@ -61,6 +57,15 @@ Route::group('game', function () {
     Route::get('export', 'Game/export');
 })->middleware([\app\middleware\AuthMiddleware::class, \app\middleware\BehaviorLogMiddleware::class]);
 
+// 登录日志相关路由
+Route::group('login_log', function () {
+    Route::get('list', 'LoginLog/list');
+    Route::get('detail', 'LoginLog/detail');
+    Route::get('statistics', 'LoginLog/statistics');
+    Route::get('recent_logs', 'LoginLog/recentLogs');
+    Route::get('export', 'LoginLog/export');
+})->middleware([\app\middleware\AuthMiddleware::class, \app\middleware\BehaviorLogMiddleware::class]);
+
 // 操作日志相关路由
 Route::group('behavior_log', function () {
     Route::get('list', 'BehaviorLog/list');