<?php
/**
  * @method 验证码识别
  * @author soul
  */
class OthCodeOcr
{
	public function curl($url, $postArr)
	{
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_HEADER, FALSE);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_TIMEOUT, 60);
		curl_setopt($ch, CURLOPT_POST, TRUE);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $postArr);
		$data = curl_exec($ch);
		curl_close($ch);
		return $data;
	}

	/**
	  * @method 验证码识别
	  * @param $imgdata  图片内容 base64_encode(file_get_contents('D:\www/kaptcha.jpg'))
	  * @param $type  识别类型 默认 3 数英混合  1 : 纯数字
					$site =self 
					   dflzm:dflzm.com.cn/index.php/greenBill
					   vecc:info.vecc.org.cn/ve/vin/index
	  * @param $site  识别站点 默认 ttshitu || self：自己
	  * @author soul
	  * @copyright 2020/1/16
	  * @return 
	  */
	function getCodeOcr($imgdata, $type = 3, $site = 'ttshitu')
	{
		if(strlen($imgdata) < 100) return LibFc::ReturnData(false, $imgdata.'=>'.'验证码图片为空');
		$site = empty($site)? 'ttshitu': $site;
		if($site == 'ttshitu')
		{
			$type = empty($type)? 3: $type;
			$cof = mvc::$cfg['CODEOCR'][$site];
			$url = $cof['url'].'base64';
			$postArr = [
				'username' => $cof['username'],
				'password' => $cof['password'],
				'typeid' => $type,
				'image' => $imgdata
			];
			$html = $this->curl($url, $postArr);
			$htmlArr = json_decode($html, true);
			if (isset($htmlArr['data']['result']) && $htmlArr['data']['result'] != '')
			{
				$arr = [
					'id'=> $htmlArr['data']['id'],
					'imgcode'=>	$htmlArr['data']['result'],
					'site'=>$site
				];
				return LibFc::ReturnData(true, $arr);
			}
			else
			{
				return LibFc::ReturnData(false, $imgdata.'=>'.$htmlArr['message']);
			}
		}
		else if($site == 'self')
		{
			$cof = mvc::$cfg['CODEOCR'][$site];
			$url = $cof['url'].$type;
			$html = $this->curl($url, ['image_file'=>$imgdata]);
			$htmlArr = json_decode($html, true);
			if (is_array($htmlArr) && !empty($htmlArr['data']))
			{
				$arr = [
					'type'=> $type,
					'imgcode'=> $htmlArr['data'],
					'site'=> $site,
					'time'=> $htmlArr['time']
				];
				if(in_array($type, ['bmw', 'vecc2']))
				{
					$arr['jscode'] = $this->getJsByTxt($arr['imgcode']);
				}

				return LibFc::ReturnData(true, $arr);
			}
			return LibFc::ReturnData(false, '验证码识别失败'.$html);
		}
		return LibFc::ReturnData(false, $site.'识别站点不存在');
	}
	
	//8+2x0 返回计算结果
	public function getJsByTxt($txt)
	{
		$result = '';
		$re2 = ['X'=>'*','x'=>'*'];
		$txt = strtr($txt, $re2);
		if(preg_match('/(\d+[\+\-\*])+\d+/', $txt, $match))
		{
			$txt = $match[0];
			eval("\$result = $txt;");
		}
		return $result;
	}

	/**
	  * @method 识别错误的图片记录
	  * @param $imgdata  图片内容 base64_encode(file_get_contents('D:\www/kaptcha.jpg'))
	  * @param $result  array getCodeOcr 返回的结果['type'=>xxx, 'imgcode'=>xxx, 'site'=>xxx]
	  * @author soul
	  * @copyright 2020/1/16
	  * @return 
	  */
	public function logCodeOcrError($imgdata, $result)
	{
		$YpwBase = new YpwBase();
		$addArr = [
			'oie_img'=>$imgdata,
			'oie_orgcode'=>$result['imgcode'],
			'oie_sitetype'=>$result['type'],
			'oie_atime'=>time()
		];
		return $YpwBase->add('ocr_imgcode_error', $addArr);
	}

	/**
	  * @method 验证码识别 报错退款
	  * @param $id  类型 
	  * @param $site  类型 默认 ttshitu
	  * @author soul
	  * @copyright 2020/1/16
	  * @return 
	  */
	function refundCodeOcr($id, $site = 'ttshitu')
	{
		$site = empty($site)? 'ttshitu': $site;
		if($site == 'ttshitu')
		{
			$cof = mvc::$cfg['CODEOCR'][$site];
			$url = $cof['url'].'reporterror.json';
			$postArr = [
				'username' => $cof['username'],
				'password' => $cof['password'],
				'id' => $id
			];
			$html = $this->curl($url, $postArr);
			$htmlArr = json_decode($html, true);
			if (!empty($htmlArr['success']))
			{
				return LibFc::ReturnData(true, true);
			}
			else
			{
				return LibFc::ReturnData(false, $htmlArr['message']);
			}
		}
		return LibFc::ReturnData(false, $site.'识别站点不存在');
	}





	/**
	  * @method 验证码识别
	  * @param $type  类型  http://www.fateadm.com/price.html
	  * @param $imgdata  图片内容 base64_encode(file_get_contents('D:\www/kaptcha.jpg'))
	  * @author soul
	  * @copyright 2020/1/16
	  * @return 
	  */
	function getCode($type, $imgdata)
	{
		$rsp = $this->Predict($type, base64_decode($imgdata));
		//array(5) { ["RetCode"]=> string(1) "0" ["ErrMsg"]=> string(0) "" ["RequestId"]=> string(32) "20200605100050b1d95ef600056ad662" ["RspData"]=> string(19) "{"result": "a6fya"}" ["rsp"]=> array(1) { ["result"]=> string(5) "a6fya" } }
		$res = json_decode(json_encode($rsp), true);
		if(!empty($res['rsp']['result']))
		{
			$arr = [
				'RequestId'=> $res['RequestId'],
				'imgcode'=>	$res['rsp']['result'],
			];
			return LibFc::ReturnData(true, $arr);
		}
		else
		{
			return LibFc::ReturnData(false, $res['ErrMsg']);
		}
	}

  
    /**
     * 识别验证码
     * 参数： $predict_type：识别类型, $img_data：要识别的图片数据
     * 返回值：
     *      $json_rsp->RetCode：正常时返回0
     *      $json_rsp->ErrMsg：异常时显示异常详情
     *      $json_rsp->RequestId：唯一的订单号
     *      $json_rsp->rsp->result：识别结果
     */
    function Predict($predict_type, $img_data){
        $timestamp 		= time();
        $sign 			= GetSign( mvc::$cfg['CODEOCR']['fateadm']['PdID'], mvc::$cfg['CODEOCR']['fateadm']['PdKey'], $timestamp);
        $data 			= array(
            'user_id' => mvc::$cfg['CODEOCR']['fateadm']['PdID'],
            'timestamp' => $timestamp,
            'sign' => $sign,
            'predict_type' => $predict_type,
            'up_type' => "mt"
        );
        if( mvc::$cfg['CODEOCR']['fateadm']['AppID'] != ""){
            $asign      = GetSign( mvc::$cfg['CODEOCR']['fateadm']['AppID'], mvc::$cfg['CODEOCR']['fateadm']['AppKey'],  $timestamp);
            $data["appid"]  = mvc::$cfg['CODEOCR']['fateadm']['AppID'];
            $data["asign"]  = $asign;
        }
        $url 			= "http://pred.fateadm.com" . "/api/capreg";
        $rsp            = MFormPost($url,$data,$img_data);
        $json_rsp 		= json_decode( $rsp);
        if( $json_rsp->RetCode == 0){
            $result 			= json_decode($json_rsp->RspData);
            $json_rsp->rsp 		= $result;
        }
        return $json_rsp;
    }

    /**
     * 识别失败，进行退款请求
     * 参数：$request_id：需要退款的订单号
     * 返回值：
     *      $json_rsp->RetCode：正常时返回0
     *      $json_rsp->ErrMsg：异常时显示异常详情
     *
     * 注意：
     *      Predict识别接口，仅在ret_code == 0 时才会进行扣款，才需要进行退款请求，否则无需进行退款操作
     * 注意2：
     *      退款仅在正常识别出结果后，无法通过网站验证的情况，请勿非法或者滥用，否则可能进行封号处理
     */
    function Justice($request_id){
        $timestamp 	= time();
        $sign 		= GetSign( mvc::$cfg['CODEOCR']['fateadm']['PdID'], mvc::$cfg['CODEOCR']['fateadm']['PdKey'], $timestamp);
        $data 	= array(
            'user_id' => mvc::$cfg['CODEOCR']['fateadm']['PdID'],
            'timestamp'=> $timestamp,
            'sign' => $sign,
            'request_id' => $request_id,
        );
        $url 		= "http://pred.fateadm.com" . "/api/capjust";
        $post_data 	= ArrayToPostData($data);
        $rsp 		= Post($url, $post_data);
        $json_rsp 	= json_decode( $rsp);
        return $json_rsp;
    }

    /**
     * 查询余额
     * 参数：无
     * 返回值：
     *      $json_rsp->RetCode：正常时返回0
     *      $json_rsp->ErrMsg：异常时显示异常详情
     *      $json_rsp->cust_val：用户余额
     */
    function QueryBalanc(){
        $timestamp 	= time();
        $sign 		= GetSign( mvc::$cfg['CODEOCR']['fateadm']['PdID'], mvc::$cfg['CODEOCR']['fateadm']['PdKey'], $timestamp);
        $data 	= array(
            'user_id' => mvc::$cfg['CODEOCR']['fateadm']['PdID'],
            'timestamp'=> $timestamp,
            'sign' => $sign,
        );
        $url 		= "http://pred.fateadm.com" . "/api/custval";
        $post_data 	= ArrayToPostData($data);
        $rsp 		= Post($url, $post_data);
        $json_rsp 	= json_decode( $rsp);
        return $json_rsp;
    }

    /**
     * 充值接口
     * 参数：$cardid：充值卡号, $cardkey：充值卡签名串
     * 返回值：
     *      $json_rsp->RetCode：正常时返回0
     *      $json_rsp->ErrMsg：异常时显示异常详情
     */
    function Charge($cardid, $cardkey){
        $timestamp 		= time();
        $sign 			= GetSign( mvc::$cfg['CODEOCR']['fateadm']['PdID'], mvc::$cfg['CODEOCR']['fateadm']['PdKey'], $timestamp);
        $csign          = GetCardSign( $cardid, $cardkey, $timestamp, mvc::$cfg['CODEOCR']['fateadm']['PdKey']);
        $data 	= array(
            'user_id' => mvc::$cfg['CODEOCR']['fateadm']['PdID'],
            'timestamp'=> $timestamp,
            'sign' => $sign,
            'cardid' => $cardid,
            'csign' => $csign,
        );
        $url 		= "http://pred.fateadm.com" . "/api/charge";
        $post_data 	= ArrayToPostData($data);
        $rsp 		= Post($url, $post_data);
        $json_rsp 	= json_decode( $rsp);
        return $json_rsp;
    }

    /**
     * 查询网络延迟
     * 参数： $predict_type:识别类型
     * 返回值：
     *      $json_rsp->RetCode：正常时返回0
     *      $json_rsp->ErrMsg：异常时显示异常详情
     */
    function RTT($predict_type){
        $timestamp 		= time();
        $sign 			= GetSign( mvc::$cfg['CODEOCR']['fateadm']['PdID'], mvc::$cfg['CODEOCR']['fateadm']['PdKey'], $timestamp);
        $data 			= array(
            'user_id' => mvc::$cfg['CODEOCR']['fateadm']['PdID'],
            'timestamp' => $timestamp,
            'sign' => $sign,
            'predict_type' => $predict_type,
        );
        if( mvc::$cfg['CODEOCR']['fateadm']['AppID'] != ""){
            $asing      = GetSign( mvc::$cfg['CODEOCR']['fateadm']['AppID'], mvc::$cfg['CODEOCR']['fateadm']['AppKey'],  $timestamp);
            $data["appid"]  = mvc::$cfg['CODEOCR']['fateadm']['AppID'];
            $data["asign"]  = $asing;
        }
        $url 			= "http://pred.fateadm.com" . "/api/qcrtt";
        $post_data		= ArrayToPostData($data);
        $rsp 			= Post($url, $post_data);
        $json_rsp 		= json_decode( $rsp);
        if( $json_rsp->RetCode == 0){
            $result 			= json_decode($json_rsp->RspData);
            $json_rsp->rsp 		= $result;
        }
        return $json_rsp;
    }

    /***
     * 余额查询,只返回余额
     * 参数：无
     * 返回值:用户余额
     */
    function QueryBalancExtend(){
        $rsp = $this->QueryBalanc();
        return json_decode($rsp->RspData)->cust_val;
    }

    /***
     * 充值接口，成功返回0
     * 参数：$cardid：充值卡号, $cardkey：充值卡签名串
     * 返回值： 充值成功返回0
     */
    function ChargeExtend($cardid, $cardkey){
        $rsp = $this->Charge($cardid,$cardkey);
        return $rsp->RetCode;
    }

    /***
     * 退款接口，成功返回0
     * 参数：$request_id：需要退款的订单号
     * 返回值：退款成功时返回0
     */
    function JusticeExtend($request_id){
        $rsp = $this->Justice($request_id);
        return $rsp->RetCode;
    }

    /***
     * 识别接口，只返回识别结果
     * 参数： $predict_type：识别类型, $img_data：要识别的图片数据
     * 返回值： 识别的结果
     */
    function PredictExtend($predict_type, $img_data){
        $rsp = $this->Predict($predict_type,$img_data);
        return json_decode($rsp->RspData)->result;
    }
}


function GetSign($pd_id, $pd_key, $timestamp){
    $chk_sign1 	= md5( $timestamp . $pd_key);
    $chk_sign2	= md5( $pd_id . $timestamp . $chk_sign1);
    return $chk_sign2;
}
function GetCardSign($cardid, $cardkey, $timestamp, $pdkey){
    $sign = md5( $pdkey . $timestamp . $cardid . $cardkey);
    return $sign;
}
function Post($url, $post_data){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_TIMEOUT, 120);	//设置本机的post请求超时时间
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

function ArrayToPostData( $data){
    $post_data 		= "";
    $first_flag 	= true;
    foreach( $data as $key => $val){
        if( $first_flag == true){
            $first_flag = false;
        }else{
            $post_data = $post_data . "&";
        }
        $post_data = $post_data . $key . "=" . $val;
    }
    return $post_data;
}

function MFormPost($url,$post_data,$img_data){
    $uniq_id = uniqid();
    $upload_data = ArrayToMFormData($post_data,$img_data,$uniq_id);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_TIMEOUT, 120);	//设置本机的post请求超时时间
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $upload_data);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Content-Type: multipart/form-data; boundary=" . $uniq_id,
        "Content-Length: " . strlen($upload_data)
    ]);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

function ArrayToMFormData($post_data,$file,$uniq_id){
    $data = "";
    //拼接报头
    foreach ($post_data as $key => $val){
        $data .= "--". $uniq_id."\r\n"
            .'Content-Disposition: form-data; name="' .$key ."\"\r\n\r\n"
            .$val."\r\n";
    }
    //拼接文件
    $data .= "--".$uniq_id. "\r\n"
        . 'Content-Disposition: form-data; name="img_data"; filename="' ."img_data". "\"\r\n"
        . 'Content-Type:application/octet-stream'."\r\n\r\n";
    $data .= $file."\r\n";
    $data .= "--".$uniq_id."--\r\n";
    return $data;
}