AppOperateLogService.php 4.63 KB
<?php
/**
 * 项目操作日志
 *
 * @author zhangdongying
 * @date   2023-02-28
 */
declare(strict_types=1);

namespace Meibuyu\Common\GlobalLog;

use Hyperf\Contract\ConfigInterface;
use Hyperf\DbConnection\Model\Model;
use Hyperf\HttpServer\Contract\RequestInterface;
use Meibuyu\Common\GlobalLog\Service\OperateLogService;
use Meibuyu\Micro\Model\Auth;
use Psr\Container\ContainerInterface;

class AppOperateLogService
{
    /**
     * 配置
     */
    protected $config;

    /**
     * 队列服务
     */
    protected $operateLogService;

    /**
     * 初始化
     *
     * @param ContainerInterface $container 容器实例
     * @throws \Throwable
     */
    public function  __construct(ContainerInterface $container)
    {
        $this->config            = $container->get(ConfigInterface::class);
        $this->operateLogService = $container->get(OperateLogService::class);
    }

    /**
     * 将数组转换成JSON
     *
     * @param array $array 数组
     * @return string
     */
    public static function encodeArrayToJson(array $array): string
    {
        return json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    }

    /**
     * 获取客户端IP
     *
     * @return string
     */
    public function getClientIp(): string
    {
        $request = make(RequestInterface::class);
        $header  = $request->getHeaders();

        if (isset($header['http_client_ip'][0])) {
            return $header['http_client_ip'][0];
        } elseif (isset($header['x-real-ip'][0])) {
            return $header['x-real-ip'][0];
        } elseif (isset($header['x-forwarded-for'][0])) {
            return $header['x-forwarded-for'][0];
        } elseif (isset($header['http_x_forwarded_for'][0])) {
            return $header['http_x_forwarded_for'][0];
        } else {
            $server = $request->getServerParams();
            return $server['remote_addr'] ?? '';
        }
    }

    /**
     * 格式化原始数据
     *
     * @param mixed $data 原始数据
     * @return string
     */
    public function formatSourceData($data): string
    {
        if ($data instanceof Model) {
            return self::encodeArrayToJson($data->toArray());
        } elseif (is_array($data)) {
            return self::encodeArrayToJson($data);
        } else {
            return (string)$data;
        }
    }

    /**
     * 添加用户操作日志
     *
     * @param string $tableName 表名
     * @param string $recordId 记录ID
     * @param string $operateType 操作类型
     * @param string|array|Model $param 参数
     * @param string|array|Model $before 修改之前数据
     * @param string|array|Model $after 修改之后数据
     * @param string $remark 备注
     * @return bool
     * @throws \Exception
     */
    public function addUserOperateLog(
        string $tableName,
        string $recordId,
        string $operateType,
        $param,
        $before,
        $after,
        string $remark = ''
    ): bool
    {
        return $this->operateLogService->addOperateLog(
            make(RequestInterface::class)->header('hwq-request-id', ''),
            $this->config->get('app_name'),
            Auth::id() ?? 0,
            Auth::user()['name'] ?? '',
            $this->getClientIp(),
            make(RequestInterface::class)->url(),
            $tableName,
            $recordId,
            $operateType,
            $this->formatSourceData($param),
            $this->formatSourceData($before),
            $this->formatSourceData($after),
            $remark
        );
    }

    /**
     * 添加系统操作日志
     *
     * @param string $action 方法全路径
     * @param string $tableName 表名
     * @param string $recordId 记录ID
     * @param string $operateType 操作类型
     * @param string|array|Model $param 参数
     * @param string|array|Model $before 修改之前数据
     * @param string|array|Model $after 修改之后数据
     * @param string $remark 备注
     * @return bool
     * @throws \Exception
     */
    public function addSystemOperateLog(
        string $action,
        string $tableName,
        string $recordId,
        string $operateType,
        $param,
        $before,
        $after,
        string $remark = ''
    ): bool
    {
        return $this->operateLogService->addOperateLog(
            '',
            $this->config->get('app_name'),
            0,
            'system',
            '',
            $action,
            $tableName,
            $recordId,
            $operateType,
            $this->formatSourceData($param),
            $this->formatSourceData($before),
            $this->formatSourceData($after),
            $remark
        );
    }
}