'array', 'response_data' => 'array', 'execution_time' => 'float', 'created_at' => 'datetime', ]; /** * 关联用户 */ public function user(): BelongsTo { return $this->belongsTo(User::class); } /** * 记录操作日志 */ public static function log($data) { return self::create(array_merge([ 'user_id' => auth()->id(), 'user_name' => auth()->user()->name ?? '系统', ], $data)); } /** * 记录API请求日志 */ public static function logApiRequest($request, $response, $executionTime) { $path = $request->path(); $method = $request->method(); // 排除日志查询本身,避免无限递归 if (strpos($path, 'operation-logs') !== false) { return; } $data = [ 'module' => self::getModuleFromPath($path), 'action' => self::getActionFromMethod($method), 'method' => $method, 'path' => $path, 'ip' => $request->ip(), 'user_agent' => $request->userAgent(), 'request_data' => self::filterSensitiveData($request->all()), 'response_data' => self::filterSensitiveData($response->getData(true)), 'response_code' => $response->getStatusCode(), 'execution_time' => $executionTime, ]; return self::log($data); } /** * 根据路径获取模块 */ private static function getModuleFromPath($path) { $segments = explode('/', $path); if (count($segments) >= 2) { $module = $segments[1]; $modules = [ 'auth' => '认证', 'goods' => '商品', 'suppliers' => '供应商', 'brands' => '品牌', 'warehouses' => '仓库', 'purchase-orders' => '采购单', 'receiving-orders' => '收货单', 'templates' => '模板', 'warehouse-bindings' => '仓库绑定', 'orders' => '订单', 'shop-auths' => '店铺授权', 'system-configs' => '系统配置', 'operation-logs' => '操作日志', ]; return $modules[$module] ?? '其他'; } return '其他'; } /** * 根据请求方法获取操作 */ private static function getActionFromMethod($method) { $actions = [ 'GET' => '查询', 'POST' => '创建', 'PUT' => '更新', 'PATCH' => '更新', 'DELETE' => '删除', ]; return $actions[$method] ?? '其他'; } /** * 过滤敏感数据 */ private static function filterSensitiveData($data) { if (!is_array($data)) { return $data; } $sensitiveKeys = [ 'password', 'password_confirmation', 'token', 'access_token', 'refresh_token', 'app_key', 'app_secret', 'session_key', 'api_key', 'secret', ]; foreach ($sensitiveKeys as $key) { if (isset($data[$key])) { $data[$key] = '***FILTERED***'; } } // 递归处理嵌套数组 foreach ($data as $key => $value) { if (is_array($value)) { $data[$key] = self::filterSensitiveData($value); } } return $data; } /** * 获取操作统计 */ public static function getStatistics($startDate = null, $endDate = null) { $query = self::query(); if ($startDate) { $query->where('created_at', '>=', $startDate); } if ($endDate) { $query->where('created_at', '<=', $endDate); } $total = $query->count(); $success = $query->where('response_code', '<', 400)->count(); $error = $query->where('response_code', '>=', 400)->count(); $modules = $query->selectRaw('module, COUNT(*) as count') ->groupBy('module') ->orderBy('count', 'desc') ->limit(10) ->get() ->mapWithKeys(function ($item) { return [$item->module => $item->count]; }) ->toArray(); $users = $query->selectRaw('user_name, COUNT(*) as count') ->groupBy('user_name') ->orderBy('count', 'desc') ->limit(10) ->get() ->mapWithKeys(function ($item) { return [$item->user_name => $item->count]; }) ->toArray(); return [ 'total' => $total, 'success' => $success, 'error' => $error, 'success_rate' => $total > 0 ? round($success / $total * 100, 2) : 0, 'modules' => $modules, 'users' => $users, ]; } }