BaseController.php 7.99 KB
<?php

namespace App\Http\Controllers\Release;

use App\Helper\CacheKeyTools;
use App\Helper\Response;
use App\Http\Controllers\Controller;
use App\Models\Legal\Channel;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class BaseController extends Controller
{
    /**
     * 基础变量
     * @var string
     */
    protected $domain, $appId;
    private $appSecret;

    public function __construct()
    {
        $this->domain = env('TME_DOMAIN','https://openapi-sit.tencentmusic.com');
        $this->appId = env('TME_APPID','47820741');
        $this->appSecret = env('TME_APPSECRET','nPWFDDHKYCP4bUzoq9zyaJQx4ltQqMSs');
    }

    /**获取accessToken
     *
     */
    function getToken()
    {
        $url = rtrim($this->domain,'/').'/oauth2/token';
        $data = ['appId'=>$this->appId,'appSecret'=>$this->appSecret];
        try {
            $client = new Client(['verify'=>false]); //实体公钥['verify'=>'/path/to/public.pem']
            $response = $client->request('POST', $url, ['json' => $data]);

            $respArr = json_decode($response->getBody()->getContents(), true);
            Log::channel('api')->info(__METHOD__, $respArr);
            if (0 !== (int)$respArr['code']) {
                return null;
            } else {
                $res = $respArr['data'];
                Cache::put(CacheKeyTools::tmeAccessToken(), $res['accessToken'], ($res['expire'] ?? 900) - 100);  // 加入缓存
                return $res['accessToken'];
            }
        } catch (\Exception $e) {
            Log::channel('api')->error(__METHOD__, ['msg'=>$e->getMessage()]);
            return null;
        }

    }

    /** ascii码从小到大排序
     * @param array $params
     * @return bool|string
     */
    function ascSort($params = array())
    {
        if (!empty($params)) {
            $p = ksort($params);
            if ($p) {
                $str = '';
                foreach ($params as $k => $val) {
                    $str .= $k . '=' . $val . '&';
                }
                $strs = rtrim($str, '&');
                return $strs;
            }
        }
        return false;
    }

    /**
     * 重组请求数据,返回headers和json
     * @param string $uri
     * @param array $reqData
     * @param bool $isLocal
     * @return array
     */
    private function parseData(string $uri, array $reqData, bool $isLocal = true)
    {
        if (!$accessToken = Cache::get(CacheKeyTools::tmeAccessToken())) {
            $accessToken = $this->getToken();
        }
        if ($isLocal) {
            $data_file = database_path('Release/'.last(explode("/",$uri)).'.query.php');
            $params = include("$data_file");
            $params['tmeBrandId'] = 105737;
        } else {
            $params = $reqData;
        }
        $heaers['appId'] = $this->appId;
        $heaers['accessToken'] = $accessToken;
        $heaers['timestamp'] = (string)date('YmdHis');
        $heaers['traceId'] = 'md5';

        return $this->signData($params);
    }

    /**
     * 请求接口
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    protected function doApi(string $uri, array $reqData = [], string $method = 'POST')
    {
        $this->getSign();
        $url = rtrim($this->domain,'/').'/'.ltrim($uri,'/');
        $data = $this->parseData($uri, $reqData);
        try {
            $client = new Client(['verify'=>false]); //实体公钥['verify'=>'/path/to/public.pem']
            switch (strtoupper($method)) {
                case 'GET':
                    $response = $client->request('GET', $url, ['query' => $data]);
                    break;
                case 'POST':
                default:
                    $response = $client->request('POST', $url, ['json' => $data]);
                    break;
            }
            $respArr = json_decode($response->getBody()->getContents(), true);
            Log::channel('api')->info(__METHOD__, $respArr);
            if (0 !== (int)$respArr['code']) {
                return Response::error(-1,$respArr['msg'] ?? '操作失败');
            } else {
                $response_file = database_path('release/' . $uri . '.resp');
                file_put_contents($response_file, var_export($respArr['data'],true));
                return Response::success($respArr['data']);
            }
        } catch (\Exception $e) {
            Log::channel('api')->error(__METHOD__, ['msg'=>$e->getMessage()]);
            return Response::error(-1,'接口请求失败!');
        }
    }


    /**
     * 获取签名和去空的参数
     * @param array $array
     * @return array
     */
    protected function getSign()
    {
        $accessToken = $this->getToken();
        if (!$accessToken = Cache::get(CacheKeyTools::tmeAccessToken())) {
            $accessToken = $this->getToken();
        }
//        if ($isLocal) {
//            $data_file = database_path('Release/'.last(explode("/",$uri)).'.query.php');
//            $params = include("$data_file");
//        } else {
//            $params = $reqData;
//        }
        $heaers['appId'] = $this->appId;
        $heaers['accessToken'] = $accessToken;
        $heaers['timestamp'] = (string)date('YmdHis');
        $heaers['traceId'] = 'md5';

        $common_params = [
            "batchId"   => "8934234012312323235",
            "phone"     => "130****0815",
            "templateId" => "M000198",
            "bizType"=> 1,
            "templateVariable"=> [
                "titleMap"=> ["k"=>"v"],
                "contentMap"=> ["k"=>"v"],
            ],
            "waterId"=> "8934234012312323234",
            "platformType"=>"musician",
            "tenant"=>"musician",
            "accountId"=>6793497
        ];
        $common_params = array_merge($common_params,$heaers);
        ksort($common_params);
        $params = '';
        foreach ($common_params as $k=>$v)
        {
            if ('' === $v || null === $v || [] === $v) {
                continue;
            }
            if (is_array($v)) {
                $params .= $k . json_encode($this->handleSubArrayNumber($v));
            } else {
                $params .= $k . $v;
            }
        }
        $result = $this->str_to_utf8('appSecret' .$this->appSecret. $params);
        echo '拼装好的utf8字符串:'.$result;

        $result = md5($result);
        echo '摘要后的sign结果(16位):' . substr(md5($result), 8, 16);
        dd($result);
        return $result;
    }

    function str_to_utf8($str = '') {
        $current_encode = mb_detect_encoding($str, array("ASCII","GB2312","GBK",'BIG5','UTF-8'));
        $encoded_str = mb_convert_encoding($str, 'UTF-8', $current_encode);
        return $encoded_str;
    }

    /**
     * 签名需要,递归处理子数组中Int型数字转换成字符串
     * @param array $array
     * @return array
     */
    private function handleSubArrayNumber(array $array)
    {
        foreach ($array as $k=>$v) {
            if (is_array($v)) {
                $array[$k] = $this->handleSubArrayNumber($v);
            } else {
                if (is_numeric($v) && is_int($v)) {
                    $array[$k] = (string)$v;
                }
            }
        }
        return $array;
    }

    /**
     * 获取签名和去空的参数
     * @param array $array
     * @return array
     */
    protected function signData(array $array)
    {
        $common_params = [
            'cp_id' => $this->cp_id
        ];
        $param_arr = array_merge($common_params,$array);
        ksort($param_arr);
        $params = '';
        $signData = [];
        foreach ($param_arr as $k=>$v)
        {
            if ('' === $v || null === $v || [] === $v) {
                continue;
            } if (is_array($v)) {
            $params .= $k . '=' . json_encode($this->handleSubArrayNumber($v)) . '&';
        } else {
            $params .= $k . '=' . $v . '&';
        }
            $signData[$k] = $v;
        }
        $params = trim($params,'&');
        $signData['sign'] = strtoupper(md5($params.$this->key));
        return $signData;
    }

}