* * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ declare(strict_types=1); /** * This file is part of Hyperf. * * @link https://www.hyperf.io * @document https://hyperf.wiki * @contact group@hyperf.io * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ namespace App\Service; use App\Context\QueueContext; use App\Context\UserContext; use Hyperf\Collection\Arr; use Hyperf\HttpServer\Contract\RequestInterface; use Hyperf\HttpServer\Router\Dispatched; use function Hyperf\Support\make; /** * Author: ykxiao * Date: 2024/12/25 * Time: 上午9:37 * Description: 操作日志服务类。 * * (c) ykxiao * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ class OpLogsService { /** * 记录操作日志。 * * 该方法用于记录与请求相关联的操作日志,包括操作动作、路由、参数、IP地址、用户代理等信息。 * 允许通过$logStream参数传递额外的备注信息,并可选择指定日志的来源。 * * @param string $logStream 日志流或额外的备注信息,默认为空字符串 * @param null|int $source 日志来源的标识,默认为0 */ public function operatorLogs(string $logStream = '', ?int $source = 0): void { // 创建请求对象 $request = make(RequestInterface::class); // 尝试从请求中获取调度信息 $dispatched = $request->getAttribute(Dispatched::class); // 如果不存在调度信息,则不记录日志 if (! $dispatched instanceof Dispatched) { return; } // 解析路由处理器信息 $handler = $dispatched->handler->callback ?? null; [$routeControllerName, $routeActionName] = $handler; // 提取控制器名称 $controllerName = Arr::last(explode('\\', $routeControllerName)); // 组装当前执行的动作字符串 $currAction = $controllerName . '@' . $routeActionName; // 过滤敏感参数后收集请求信息 $params = $this->filterSensitiveParams($request->all()); $clientIP = $this->getClientIP($request); $agent = $request->getHeaderLine('User-Agent'); // 准备日志数据 $data = [ 'action' => $currAction, 'route' => $request->path(), 'params' => $params, 'ip' => $clientIP, 'agent' => $agent, 'remark' => $logStream, 'source' => $source, ]; // 将日志数据加入队列,以便后续处理 make(QueueService::class)->make($data)->opLogs(); } /** * 过滤敏感参数. */ protected function filterSensitiveParams(array $params): array { $sensitiveKeys = ['password', 'pwd', 'pwd_conf', 'original_pwd', 'old_pwd', 'new_pwd', 'conf_pwd']; foreach ($sensitiveKeys as $key) { Arr::forget($params, $key); } return $params; } /** * 获取客户端 IP. */ protected function getClientIP(RequestInterface $request): string { $realIP = $request->getHeaderLine('x-real-ip'); $forwardedFor = $request->getHeaderLine('x-forwarded-for'); $clientIP = $realIP ?: $forwardedFor; return $clientIP ?: '127.0.0.1'; } }