<?php
declare (strict_types = 1);

namespace app\admin\middleware\v1;

use app\admin\model\v1\SysOperateLog;
use app\admin\model\v1\SysRestfulApiModel;
use think\facade\Cache;

class OperateLog
{
    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        $response = $next($request);
        
        $restful_api_name_map = Cache::get('sys_restful_api:map:name');
        if (empty($restful_api_name_map)) {
            $restful_api_name_map = [];
            $restful_api          = SysRestfulApiModel::cache('sys_restful_api')->select();
            foreach ($restful_api as $item) {
                $restful_api_name_map[$item['method'] . '-' . $item['layer'] . '.' . $item['controller'] . '/' . $item['action']] = $item['name'];
            }
            Cache::set('sys_restful_api:map:name', $restful_api_name_map);
        }

        // 忽略日志记录的Api
        $ignore_apis = env('ADMIN_API.IGNORE_LOGGING_LIST');
        $current_api = sprintf("%s/%s/%s", $request->layer(), $request->controller(base:true), $request->action());
        if (in_array($current_api, $ignore_apis)) {
            return $response;
        }

        $log = [
            'user_id'    => $request->uid,
            'title'      => $restful_api_name_map[$request->method() . '-' . $request->controller() . '/' . $request->action()] ?? '',
            'version'    => $request->layer(),
            'method'     => $request->method(),
            'controller' => $request->controller(base: true),
            'action'     => $request->action(),
            'url'        => $request->url(),
            'ip'         => $request->ip(),
            'params'     => json_encode($request->param()),
            'status'     => $response->getCode()
        ];
        
        if (empty($request->exception_info)) {
            // 记录正常返回信息
            $contentDisposition = $response->getHeader('Content-Disposition');
            if (!empty($contentDisposition) && \think\helper\Str::startsWith($contentDisposition, 'attachment')) {
                $log['message'] = $contentDisposition;
            } else {
                $log['message'] = $response->getData();
                if (is_array($log['message'])) {
                    $log['message'] = json_encode($log['message'], JSON_UNESCAPED_UNICODE);
                }
            }
        } else {
            // 记录异常返回信息
            $log['message'] = (string)$request->exception_info;
        }
        SysOperateLog::create($log);

        return $response;
    }
}
