Commit 02863d7d authored by Administrator's avatar Administrator
Browse files

Merge branch 'feature-global_log-zdy' into 'master'

feat: 全局操作日志

See merge request without_auth/meibuyu-common!4
parents 7ab3e0e0 f7058748
Loading
Loading
Loading
Loading

.gitignore

0 → 100644
+3 −0
Original line number Diff line number Diff line
.idea
/vendor
composer.lock

composer.json

0 → 100644
+25 −0
Original line number Diff line number Diff line
{
    "name": "meibuyu/common",
    "description": "美不语微服务公共库",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Rain",
            "email": "823773695@qq.com"
        }
    ],
    "require": {
        "php": ">=7.2"
    },
    "autoload": {
        "psr-4": {
            "Meibuyu\\Common\\": "src/"
        }
    },
    "extra": {
        "hyperf": {
            "config": "Meibuyu\\Rpc\\ConfigProvider"
        }
    }
}
+11 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Meibuyu\Common\Exceptions;


class HttpResponseException extends \Exception
{

}
 No newline at end of file
+224 −0
Original line number Diff line number Diff line
<?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|int $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,
        $recordId,
        string $operateType,
        $param,
        $before,
        $after,
        string $remark = ''
    ): bool
    {
        return $this->addOperateLog(
            make(RequestInterface::class)->header('hwq-request-id', ''),
            Auth::id() ?? 0,
            Auth::user()['name'] ?? '',
            $this->getClientIp(),
            make(RequestInterface::class)->url(),
            $tableName,
            $recordId,
            $operateType,
            $param,
            $before,
            $after,
            $remark
        );
    }

    /**
     * 添加系统操作日志
     *
     * @param string $action 方法全路径
     * @param string $tableName 表名
     * @param string|int $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,
        $recordId,
        string $operateType,
        $param,
        $before,
        $after,
        string $remark = ''
    ): bool
    {
        return $this->addOperateLog(
            '',
            0,
            'system',
            '',
            $action,
            $tableName,
            $recordId,
            $operateType,
            $param,
            $before,
            $after,
            $remark
        );
    }

    /**
     * 添加系统操作日志
     *
     * @param string $requestId 请求ID
     * @param string|int $operatorId 操作人ID
     * @param string $operatorName 操作人名称
     * @param string $clientIp 请求IP
     * @param string $url 请求URL或者请求方法
     * @param string $tableName 表名
     * @param string|int $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 addOperateLog(
        string $requestId,
        $operatorId,
        string $operatorName,
        string $clientIp,
        string $url,
        string $tableName,
        $recordId,
        string $operateType,
        $param,
        $before,
        $after,
        string $remark
    ): bool
    {
        return $this->operateLogService->addOperateLog(
            $requestId,
            $this->config->get('app_name'),
            (int)$operatorId,
            $operatorName,
            $clientIp,
            $url,
            $tableName,
            (string)$recordId,
            $operateType,
            $this->formatSourceData($param),
            $this->formatSourceData($before),
            $this->formatSourceData($after),
            $remark
        );
    }
}
 No newline at end of file
+69 −0
Original line number Diff line number Diff line
<?php
/**
 * 操作日志示例
 *
 * @author zhangdongying
 * @date   2023-03-01
 */
declare(strict_types=1);

namespace Meibuyu\Common\GlobalLog\Example;

use Meibuyu\Common\GlobalLog\AppOperateLogService;
use Psr\Container\ContainerInterface;

class AppOperateLogExample
{
    /**
     * 容器实例
     */
    protected $container;

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

    /**
     * addUserOperateLog 调用示例
     *
     * @return void
     * @throws \Throwable
     */
    public function addUserOperateLogExample()
    {
        $this->container->get(AppOperateLogService::class)->addUserOperateLog(
            'products',
            '1',
            '产品管理-产品列表-产品编辑',
            ['product_id' => 1, 'name' => 'bbb'],
            ['id' => 1, 'name' => 'aaa'],
            ['id' => 2, 'name' => 'bbb']
        );
    }

    /**
     * addSystemOperateLog 调用示例
     *
     * @return void
     * @throws \Throwable
     */
    public function addSystemOperateLogExample()
    {
        $this->container->get(AppOperateLogService::class)->addSystemOperateLog(
            'AppOperateLogExample@addSystemOperateLogExample',
            'products',
            '1',
            '物流运单推送物流服务商',
            ['product_id' => 1, 'name' => 'bbb'],
            ['id' => 1, 'name' => 'aaa'],
            ['id' => 2, 'name' => 'bbb']
        );
    }
}
 No newline at end of file
Loading