getAppType($request); // 从token中获取所有用户信息 $userInfo = $this->getUserInfoFromToken($request); $userId = $userInfo['userId'] ?? 0; $merchantId = $userInfo['merchantId'] ?? 0; $adminId = $userInfo['adminId'] ?? 0; // 记录请求日志 ApiRequestLog::record([ 'app_type' => $appType, 'request_method' => $request->method(), 'request_url' => $request->url(), 'request_params' => $this->getRequestParams($request), 'request_headers' => $this->getRequestHeaders($request), 'request_ip' => $request->ip(), 'user_agent' => $request->header('user-agent', ''), 'user_id' => $userId, 'merchant_id' => $merchantId, 'admin_id' => $adminId, 'response_code' => $response->getCode(), 'response_data' => $this->getResponseData($response), 'response_time' => $responseTime, 'error_message' => $this->getErrorMessage($response), ]); } catch (\Exception $e) { // 记录日志失败时不中断主流程 // 可以在这里添加日志记录失败的日志 } return $response; } /** * 获取应用类型 * @param \think\Request $request * @return string */ private function getAppType($request): string { // 获取请求路径 $path = $request->pathinfo(); $position = strpos($path, '/'); if ($position === false) { return 'unknown'; } return substr($path, 0, $position); } /** * 获取请求参数 * @param \think\Request $request * @return array */ private function getRequestParams($request): array { $params = $request->param(); // 过滤敏感信息 $sensitiveFields = ['password', 'pwd', 'token', 'secret', 'key', 'authorization']; foreach ($sensitiveFields as $field) { if (isset($params[$field])) { $params[$field] = '***'; } } return $params; } /** * 获取请求头信息 * @param \think\Request $request * @return array */ private function getRequestHeaders($request): array { $headers = $request->header(); // 过滤敏感头信息 $sensitiveHeaders = ['authorization', 'cookie', 'token']; foreach ($sensitiveHeaders as $header) { if (isset($headers[$header])) { $headers[$header] = '***'; } } return $headers; } /** * 获取响应数据 * @param Response $response * @return array|null */ private function getResponseData(Response $response): ?array { $content = $response->getContent(); try { $data = json_decode($content, true); if (json_last_error() === JSON_ERROR_NONE) { return $data; } } catch (\Exception $e) { // JSON解析失败,返回原始内容的前1000个字符 return ['raw_content' => substr($content, 0, 1000)]; } return null; } /** * 获取错误信息 * @param Response $response * @return string */ private function getErrorMessage(Response $response): string { if ($response->getCode() >= 400) { $content = $response->getContent(); try { $data = json_decode($content, true); if (json_last_error() === JSON_ERROR_NONE && isset($data['msg'])) { return $data['msg']; } } catch (\Exception $e) { return substr($content, 0, 500); } } return ''; } /** * 从token中解析adminId * @param \think\Request $request * @return int */ private function getAdminIdFromToken($request): int { try { $token = $this->getTokenFromRequest($request); if (!$token) { return 0; } $jwtService = new JwtTokenService(); try { // 尝试解析token $payload = $jwtService->parseToken($token); } catch (\Exception $e) { // 如果解析失败,尝试解码(不验证签名) $payload = $jwtService->decode($token); } // 检查token类型是否为admin,并且包含有效的ID if (isset($payload->jti) && is_array($payload->jti) && count($payload->jti) >= 2) { if ($payload->jti[1] === 'admin') { return (int)$payload->jti[0]; } } } catch (\Exception $e) { // token解析失败,返回0 return 0; } return 0; } /** * 从请求中获取token * @param \think\Request $request * @return string|null */ private function getTokenFromRequest($request): ?string { // 从header中获取token $token = $request->header('X-Token'); if ($token && strpos($token, 'Bearer ') === 0) { $token = substr($token, 7); } // 如果header中没有,尝试从参数中获取 if (!$token) { $token = $request->param('token'); } return $token ? trim($token) : null; } /** * 从token中获取所有用户信息 * @param \think\Request $request * @return array */ private function getUserInfoFromToken($request): array { $result = [ 'userId' => 0, 'merchantId' => 0, 'adminId' => 0 ]; try { $token = $this->getTokenFromRequest($request); if (!$token) { return $result; } $jwtService = new JwtTokenService(); try { // 尝试解析token $payload = $jwtService->parseToken($token); } catch (\Exception $e) { // 如果解析失败,尝试解码(不验证签名) $payload = $jwtService->decode($token); } // 检查token类型并获取对应的ID if (isset($payload->jti) && is_array($payload->jti) && count($payload->jti) >= 2) { $userId = (int)$payload->jti[0]; $userType = $payload->jti[1]; switch ($userType) { case 'user': $result['userId'] = $userId; break; case 'mer': $result['merchantId'] = $userId; break; case 'admin': $result['adminId'] = $userId; break; } } } catch (\Exception $e) { // token解析失败,返回默认值 } return $result; } }