<?php
/**
  * @method 物流
  * @author soul
  * @copyright 2016/3/31
  */
class MainExpress extends MainBase
{
	/**
	  * @method 创建并获取物流信息
	  * @param  $dataArr 已有物流跟踪ID['ext_id'=>xxx]
						 需要新建 [
								'ext_exp_code'=>物流代码,
								'ext_number'=>'物流单号'
							];
	  * @author soul
	  * @copyright 2017/8/16
	  * @return
			成功：['status'=>true, 'data'=>['ext_id'=>xxxx, 'ext_name'=>'', 'ext_track'=>''....]]
			失败：['status'=>false, 'data'=>'xxx', 'code'=>'xxx']
	  */
	public function getTrack($dataArr)
	{
		if(!empty($dataArr['ext_id']))
		{
			$res = $this->get('ex_express_track', ['ext_id', 'ext_exp_code', 'ext_number', 'ext_extnum', 'ext_track', 'ext_status'], sprintf(" and ext_id=%d", (int) $dataArr['ext_id']), true);
			if(empty($res['data']))
			{
				if(empty($dataArr['ext_exp_code']) || empty($dataArr['ext_number']))
				{
					return LibFc::ReturnData(true, '物流跟踪ext_id不存在');
				}
			}
			else
			{
				$dataArr = $res['data'];
			}
		}

		$res = $this->getExpress();
		$allExpress = $res['data'];
		$this->MainDb->Begin();
		if(empty($dataArr['ext_id']))
		{
			if(empty($allExpress[$dataArr['ext_exp_code']]))
			{
				return LibFc::ReturnData(true, []);
			}

			$res = $this->get('ex_express_track', ['ext_id', 'ext_exp_code', 'ext_number', 'ext_extnum', 'ext_track', 'ext_status'], sprintf(" and ext_exp_code='%s' AND ext_number='%s'", LibFc::Escape($dataArr['ext_exp_code']), LibFc::Escape($dataArr['ext_number'])), true);
			if(!empty($res['data']))
			{
				$dataArr = $res['data'];
			}
			else
			{
				$mustArr = ['ext_exp_code', 'ext_number', 'ext_from'];
				foreach($mustArr as $filed)
				{
					if(!isset($dataArr[$filed]))
					{
						return LibFc::ReturnData(false, $filed.'参数必填');
					}
				}
				$dataArr['ext_atime'] = time();
				$dataArr['ext_track'] = json_encode([]);
				$res = $this->add('ex_express_track', $dataArr);
				$dataArr['ext_id'] = $res['data'];
			}
		}

		//更新间隔1小时
		$minTime = 3600;
		if((empty($dataArr['ext_track']) && ($dataArr['ext_update_time']+$minTime) <= time()) || $dataArr['ext_update_end'])
		//if(!1)
		{
			//未到更新时间，或者已经不需要更新
		}
		else
		{
			$res = $this->getTrackByApi($dataArr);
			$trackArr = $res['data'];
			if(isset($trackArr['ext_track']))
			{
				$dataArr['ext_track'] = $trackArr['ext_track'];
				$setArr = [
					'ext_track'=>$dataArr['ext_track'],
					'ext_track_etime'=>$trackArr['ext_track_etime'],
					'ext_update_time'=>time(),
					'ext_update_end'=>$trackArr['ext_update_end'],
					'ext_status'=>$trackArr['ext_status'],
					'ext_update_api'=>$trackArr['ext_update_api']
				];
				$this->set('ex_express_track', $setArr, sprintf(" AND ext_id=%d", $dataArr['ext_id']));
			}
		}
		
		$this->MainDb->End();
		$expArr = isset($allExpress[$dataArr['ext_exp_code']]) ?  $allExpress[$dataArr['ext_exp_code']]: [];
		$dataArr = array_merge($dataArr, $expArr);
		
		//返回数据
		$returnArr = [];
		$returnFiled = ['ext_id', 'ext_exp_code', 'ext_number', 'ext_track', 'exp_name', 'ext_status'];
		foreach($returnFiled as $filed)
		{
			$returnArr[$filed] = $dataArr[$filed];
		}
		return LibFc::ReturnData(true, $returnArr);
	}

	/**
	  * @method 从各个API查询物流跟踪
	  * @param  $dataArr ['ext_exp_code'=>物流代码, 'ext_number'=>'物流单号'];
	  * @author soul
	  * @copyright 2017/8/16
	  * @return
			成功：['status'=>true, 'data'=>['ext_track'=>xxxx, 'ext_track_etime'=>'', 'ext_status'=>'', 'ext_update_api'=>'', 'ext_update_end'=>'']]
			失败：['status'=>false, 'data'=>'xxx', 'code'=>'xxx']
	  */
	public function getTrackByApi($dataArr)
	{
		if(empty($dataArr['ext_exp_code']) || empty($dataArr['ext_number']))
		{
			return LibFc::ReturnData(false, '必须提供ext_exp_code、ext_number');
		}
		$res = $this->getExpress();
		if(empty($res['data'][$dataArr['ext_exp_code']]))
		{
			return LibFc::ReturnData(false, '提供的ext_exp_code不存在');
		}
		
		$expArr = $res['data'];
		$dataArr['ext_track'] = [];
		$dataArr['ext_update_api'] = '';
		$dataArr['ext_track_etime'] = 0;
		$dataArr['ext_status'] = 0;
		$dataArr['ext_update_end'] = 0;
		$LibCurl = new LibCurl();
		$getFlag = false;

		$realCode = $dataArr['ext_number'];
		if($dataArr['ext_exp_code'] == 'SFSY' && !empty($dataArr['ext_extnum'])) $realCode .= $dataArr['ext_extnum'];
		foreach(mvc::$cfg['EXPRESS'] as $api=>$cfgArr)
		{
			if($getFlag) break;
			if($cfgArr['run'] && (!empty($expArr[$dataArr['ext_exp_code']]['exp_code_'.$api]) || $api == 'ali'))
			{
				$apiExp = $expArr[$dataArr['ext_exp_code']]['exp_code_'.$api];
				switch($api)
				{
					case 'ali':
						$headers = [];
						array_push($headers, "Authorization:APPCODE " . $cfgArr['AppCode']);
						$url = $cfgArr['url'].'kdi?no='.$realCode.'&type='.$apiExp;
						$curl = curl_init();
						curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
						curl_setopt($curl, CURLOPT_URL, $url);
						curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
						curl_setopt($curl, CURLOPT_FAILONERROR, false);
						curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
						//curl_setopt($curl, CURLOPT_HEADER, true);
						$html = curl_exec($curl);
						$res = json_decode($html,true);
						if($res['status'] == 0 && $res['msg'] == 'ok')
						{
							$getFlag = true;
							$dataArr['ext_update_api'] = $api;

							/*0无数据 1揽件 2在途 3派件 4签收 5退签 6退回 7疑难
							投递状态 1.在途中 2.正在派件 3.已签收 4.派送失败 */
							$statusArr = [
								0=>0,
								1=>2,
								2=>3,
								3=>4,
								4=>7
							];
							$dataArr['ext_status'] = (int) $statusArr[$res['result']['deliverystatus']];
							if(!empty($res['result']['list']) && is_array($res['result']['list']))
							{
								foreach ($res['result']['list'] as $value) 
								{
									$dataArr['ext_track_etime'] = strtotime($value['time']);
									$dataArr['ext_track'][] = ['time'=>strtotime($value['time']), 'context'=>$value['status']];
								}
							}
						}
					break;
					//http://192.168.1.115/www/API/home/index.php/express/getTrack?ext_exp_code=yuantong&ext_number=810655794160&token=81e8fd3d52a742593df0efb2476db7c7&ext_from=B2C
					case 'kuaidi100': 
						$cfgArr['url'] .= '?id='.$cfgArr['key'].'&com='.$apiExp.'&nu='.$realCode.'&show=0&muti=1&order=asc';
						$html = $LibCurl->fetch($cfgArr['url']);
						$res = json_decode($html,true);
						if($res['status'] == 1)
						{
							$getFlag = true;
							$dataArr['ext_update_api'] = $api;

							/*0无数据 1揽件 2在途 3派件 4签收 5退签 6退回 7疑难
								快递单当前的状态 ：　 
								0：在途，即货物处于运输过程中；
								1：揽件，货物已由快递公司揽收并且产生了第一条跟踪信息；
								2：疑难，货物寄送过程出了问题；
								3：签收，收件人已签收；
								4：退签，即货物由于用户拒签、超区等原因退回，而且发件人已经签收；
								5：派件，即快递正在进行同城派件；
								6：退回，货物正处于退回发件人的途中；
								该状态还在不断完善中，若您有更多的参数需求，欢迎发邮件至*/
							$statusArr = [
								0=>2,
								1=>1,
								2=>7,
								3=>4,
								4=>5,
								5=>3,
								6=>6,
							];
							$dataArr['ext_status'] = (int) $statusArr[$res['state']];
							if(!empty($res['data']) && is_array($res['data']))
							{
								foreach ($res['data'] as $key => $value) 
								{
									$dataArr['ext_track_etime'] = strtotime($value['time']);
									$dataArr['ext_track'][] = ['time'=>strtotime($value['time']), 'context'=>$value['context']];
								}
							}
						}
					break;
					case 'kuaidi1002': 
						//http://www.kuaidi100.com/query?type=shunfeng&postid=789552535623
						$cfgArr['url'] .= '?type='.$apiExp.'&postid='.$realCode.'&temp=0.0121';
						$html = $LibCurl->fetch($cfgArr['url']);
						$res = json_decode($html,true);
						if($res['message']=='ok' || $res['status']=='200')
						{
							$getFlag = true;
							$dataArr['ext_update_api'] = $api;
							/*0无数据 1揽件 2在途 3派件 4签收 5退签 6退回 7疑难
								快递单当前的状态 ：　 
								0：在途，即货物处于运输过程中；
								1：揽件，货物已由快递公司揽收并且产生了第一条跟踪信息；
								2：疑难，货物寄送过程出了问题；
								3：签收，收件人已签收；
								4：退签，即货物由于用户拒签、超区等原因退回，而且发件人已经签收；
								5：派件，即快递正在进行同城派件；
								6：退回，货物正处于退回发件人的途中；
								该状态还在不断完善中，若您有更多的参数需求，欢迎发邮件至*/
							$statusArr = [
								0=>2,
								1=>1,
								2=>7,
								3=>4,
								4=>5,
								5=>3,
								6=>6,
							];
							$dataArr['ext_status'] = (int) $statusArr[$res['state']];
							if(!empty($res['data']) && is_array($res['data']))
							{
								foreach ($res['data'] as $key => $value) 
								{
									$dataArr['ext_track_etime'] = strtotime($value['time']);
									$dataArr['ext_track'][] = ['time'=>strtotime($value['time']), 'context'=>$value['context']];
								}
							}
						}
					break;
					case 'kdniao':
						//http://www.kdniao.com/api-track
						$requestData= "{'OrderCode':'','ShipperCode':'".$apiExp."',"."'LogisticCode':'".$realCode."'}";
						$datas = [
							'EBusinessID' => $cfgArr['uid'],
							'RequestType' => '1002',
							'RequestData' => urlencode($requestData) ,
							'DataType' => '2',
							'DataSign' => urlencode(base64_encode(md5($requestData.$cfgArr['key'])))
						];
						$html = $LibCurl->fetch($cfgArr['url'], $datas);
						$res = json_decode($html,true);
						if(!empty($res['Success']))
						{
							$getFlag = true;
							$dataArr['ext_update_api'] = $api;
							//0无数据 1揽件 2在途 3派件 4签收 5退签 6退回 7疑难
							//2-在途中,3-签收,4-问题件
							$statusArr = [
								2=>2,
								3=>4,
								4=>7
							];
							$dataArr['ext_status'] = (int) $statusArr[$res['status']];
							if(!empty($res['Traces']) && is_array($res['Traces']))
							{
								foreach ($res['Traces'] as $key => $value) 
								{
									$dataArr['ext_track_etime'] = strtotime($value['AcceptTime']);
									$dataArr['ext_track'][] = ['time'=>strtotime($value['AcceptTime']), 'context'=>$value['AcceptStation']];
								}
							}
						}
					break;
				}
			}
		}
		//跟踪时间距离现在时间超过7天不再更新
		$dataArr['ext_track'] = json_encode($dataArr['ext_track']);
		$dataArr['ext_update_end'] = in_array($dataArr['ext_status'], [4,5]) || ($dataArr['ext_track_etime'] > 0 && (time() - $dataArr['ext_track_etime']) > 604800)? 1: 0;
		return LibFc::ReturnData(true, $dataArr);
	}

	/**
	  * @method 获取物流公司信息
	  * @param  $cache  true|false 默认true
	  * @author soul
	  * @copyright 2017/8/16
	  * @return
			成功：['status'=>true, 'data'=>['ext_track'=>xxxx, 'ext_track_etime'=>'', 'ext_status'=>'', 'ext_update_api'=>'', 'ext_update_end'=>'']]
			失败：['status'=>false, 'data'=>'xxx', 'code'=>'xxx']
	  */
	public function getExpress($cache = true)
	{
		$file = mvc::$cfg['AUTOLOAD']['Main']['path'].'cache/allExpress.php';
		$resArr = [];
		if(!file_exists($file) || !$cache || (filemtime($file) + mvc::$cfg['CACHE_TIME']['index'] ) > time())
		{
			$res = $this->get('ex_express', ['*'], sprintf(" ORDER BY exp_seq, exp_initial"));
			foreach($res['data'] as $v)
			{
				$resArr[$v['exp_code']] = $v;
			}
			LibFc::ArraySave($resArr, $file);
		}
		else
		{//括起来为了防止读取文件失败
			$resArr = include($file);
		}
		return LibFc::ReturnData(true, $resArr);
	}
}
