<?php

namespace app\abutment\middleware;

use app\abutment\model\SupplierRelationUser;
use app\abutment\model\SupplierUser;
use think\facade\Cache;
use think\facade\Config;
use think\facade\Validate;
use think\Response;
use app\abutment\model\RequestLog as RequestLogModel;

//中间件
class homeMiddleware
{

    //白名单
    private $white_list = ['login', 'getuserinfo'];

    //请求入口
    public function handle($request, \Closure $next)
    {

        //请求的唯一标识
        $request->request_id = date('YmdHis') . mt_rand(100000, 999999);

        //1.接收参数
        $param = $request->post();

        //判断白名单
        if (!in_array(strtolower(request()->pathinfo()), $this->white_list)) {

            //请求头部是否有相关信息
            $header = $request->header();
            $val_header = Validate::rule([
                'uid' => 'require|number|gt:0',
                'nickname' => 'require|max:255',
                'mobile' => 'require|number|length:11|mobile',
                'email' => 'email|max:255',
                'supplierno' => 'require|alphaNum|length:18',
                'suppliername' => 'require|max:255',//header自动把大写字母转换成小写的了
            ]);

            if ($val_header->check($header)) {
                $request->user = [
                    'uid' => $header['uid'],
                    'nickname' => $header['nickname'],
                    'mobile' => $header['mobile'],
                    'email' => '',
                    'supplierNo' => $header['supplierno'],
                    'supplierName' => $header['suppliername']
                ];

            } else {
                //获取用户信息
                $user = $this->getUserInfo($param);
                if (is_array($user)) $request->user = $user;
                else return $user;//响应信息,说明报错,直接返回给请求方
            }
        }

        //3.记录日志
        RequestLogModel::add($request->request_id, $param);

        return $next($request);

    }


    //请求结束的回调(如果返回数据用的是app_show/error_show,即直接echo,则不会触发该方法)
    public function end(Response $response)
    {
        //只做记录,不做输出
        RequestLogModel::where('request_id', request()->request_id)->save([
            'response' => $response->getContent(),
            'supplierNo' => request()->user['supplierNo'] ?? '',
            'uid' => request()->user['uid'] ?? 0,
            //如果是白名单接口(例如登录接口),这个时候是没有supplierNo和uid字段的
        ]);
    }

    /**
     * //校验相关参数
     * private function checkHeader(array $header = [])
     * {
     * $val = Validate::rule([
     * 'clientid' => 'require',
     * 'timestamp|时间戳' => 'require|number|length:10',
     * 'randomstring|随机字符串' => 'require|alphaNum|length:20',
     * 'sign|签名' => 'require',
     * 'token' => 'require|length:40|alphaNum',
     * ]);
     *
     * if (!$val->check($header)) throw new ValidateException('请求基础参数有误:' . $val->getError());
     *
     * }
     *
     *
     * //获取供应商的信息
     * private function getSupplierInfoByClientID(string $clientID = '')
     * {
     *
     * $key .= $clientID;
     *
     * $data = Cache::get($key);
     *
     * if (!$data) {
     *
     * $data = Db::name('abutment_supplier_development')
     * ->alias('a')
     * ->field('a.id,a.supplierNo,a.supplier,a.clientID,a.clientSecret,s.person,s.personid')
     * ->leftJoin('supplier s', 's.code=a.supplierNo AND s.is_del=0')
     * ->where(['a.clientID' => $clientID, 'a.is_del' => 0])
     * ->findOrEmpty();
     *
     * Cache::set($key, $data, 3600 * 24);
     * }
     *
     * return $data;
     * }
     *
     *
     * //校验签名
     * private function checkSign(array $header = [], string $clientSecret = '')
     * {
     *
     * $str = substr($header['randomstring'], 0, 10) . $header['clientid'] . $header['timestamp'] . $header['token'] . substr($header['randomstring'], 10) . $clientSecret;
     *
     * //签名 = md5(随机字符串前10位 . clientID .时间戳 . token . 随机字符串后10位 . $clientSecret, 时间戳);
     * $sign = md5($str);
     *
     * if ($sign != $header['sign']) throw new ValidateException('签名错误');
     *
     * }
     **/

    //获取用户信息
    public function getUserInfo(array $param = [])
    {
        //101 < code < 104 ,表示用户鉴权错误,需要用户重新登录
        //code==101 token不存在
        //code==102 token已失效
        //code==103 未找到对应的账户
        //code==104 token无效
        //code==105 供应商编码错误
        //code==106 你尚未绑定当前供应商
        $val = Validate::rule(['token|用户token' => 'require|length:40|alphaNum']);
        if (!$val->check($param)) return json_show(101, '参数错误,' . $val->getError());

        $val2 = Validate::rule(['supplierNo|供应商编码' => 'require|length:18|alphaNum']);
        if (!$val2->check($param)) return json_show(105, '参数错误,' . $val2->getError());

        $data = SupplierUser::field('uid,nickname,mobile,email')
            ->alias('a')
            ->where(['is_del' => SupplierUser::$is_del_normal, 'status' => SupplierUser::$status_normal, 'token' => $param['token']])
            ->where('expire_time', '>=', date('Y-m-d H:i:s'))
            ->findOrEmpty()
            ->toArray();

        if (empty($data)) return json_show(102, 'token不存在或已过期');

        $res = SupplierRelationUser::field('id,supplierNo,supplierName')
            ->where(['is_del' => SupplierUser::$is_del_normal, 'supplierNo' => $param['supplierNo'], 'uid' => $data['uid']])
            ->findOrEmpty()
            ->toArray();

        if (empty($res)) return json_show(106, '你尚未绑定当前供应商');

        return array_merge($data, ['supplierNo' => $param['supplierNo'], 'supplierName' => $res['supplierName']]);
    }

}