<?php
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
/**
  * @method 消息队列
  * @author soul
  * @copyright 2018/10/31
  */
class MainRabbit
{
	protected $actName = null;
	protected $conn = null;
	protected $config = null;
	protected $PjltjMain = null;
	protected $AdsBase = null;
	protected $YpwVin = null;
	protected $tjRegArr = null;
	public function __construct($actName)
	{
		if(!isset(mvc::$cfg['RABBIT']['act'][$actName]))
			return LibFc::ReturnData(false, $actName.'参数act不存在！');

		$this->config = mvc::$cfg['RABBIT']['act'][$actName];
		$this->actName = $actName;
		$this->config['exchange'] = 'ex_'.$this->actName;
		$this->config['route'] = 'route_'.$this->actName;
		$this->config['queue'] = 'queue_'.$this->actName;
		$connCfg = mvc::$cfg['RABBIT']['conn'];
		$this->conn = new AMQPStreamConnection($connCfg['host'], $connCfg['port'], $connCfg['login'], $connCfg['password']);
		if (!$this->conn->isConnected())
			return LibFc::ReturnData(false, '消息队列无法连接', 'rabbit');
	}

	/**
	 * @method 根据类型发送消息
	 * @param $msgArr   array   [必填]  ['{"tj_uid":0,"tj_ip":"192.168.1.115","tj_from":"PJLH5"....}', ....]
	 * @author soul 2018/10/31
	 * @return 
	 	成功：['status'=>bool, 'data'=>['send'=>$count]]
		失败：["status"=>false,"data"=>"错误信息","code"=>"apitoken"]
	 */
	public function send($msgArr)
	{
		if(empty($msgArr)) return LibFc::ReturnData(false, 'msg参数不正确！', 'param');
		$channel = $this->conn->channel();
		$channel->exchange_declare($this->config['exchange'], 'direct', false, true, false);
		$channel->queue_declare($this->config['queue'], false, true, false, false);
		$channel->queue_bind($this->config['queue'], $this->config['exchange'], $this->config['route']);

		// 发送消息
		foreach ($msgArr as $message) {
			//队列持久化
			$msg = new AMQPMessage($message, ['delivery_mode'=>2]);
			$channel->basic_publish($msg, $this->config['exchange'], $this->config['route']);
		}

		// 关闭通道和连接
		$channel->close();
		$this->conn->close();
		return LibFc::ReturnData(true, ['send'=>$count]);
		
	}

	/**
	 * @method 接收消息
	 * @author soul 2018/10/31
	 * @return 
	 	成功：['status'=>bool, 'data'=>true]
		失败：["status"=>false,"data"=>"错误信息","code"=>"apitoken"]
	 */
	public function receive()
	{
		$runtime = 3600*4;
		set_time_limit($runtime);
		$channel = $this->conn->channel();

		$channel->exchange_declare($this->config['exchange'], 'direct', false, true, false);
		$channel->queue_declare($this->config['queue'], false, true, false, false);
		$channel->queue_bind($this->config['queue'], $this->config['exchange'], $this->config['route']);

		$this->PjltjMain = new PjltjMain();
		$this->AdsBase = new AdsBase();
		$this->YpwVin = new YpwVin();
		$res = $this->PjltjMain->getTjReg();
		$this->tjRegArr = $res['data'];
		
		// 定义回调函数来处理收到的消息
		$callback = function ($msg) use ($channel) {
			//echo '收到消息: ', $msg->body, "\n";
			$this->processMessage($msg->body);
			$channel->basic_ack($msg->delivery_info['delivery_tag']);
		};
		// 消费队列中的消息  $no_ack = false 需要进行消息确认（ACK）。
		$channel->basic_consume($queue, '', false, false, false, false, $callback);
		$etime = time() + $runtime;
		while (count($channel->callbacks)) {
			if(time() > $etime) break;
			$channel->wait();
		}
		$channel->close();
		$this->conn->close();
	}

	/**
	  * @method 回调，数据处理
	  * @author soul
	  * @copyright 2016/3/30
	  * @return 
	  */
	public function processMessage($msg) 
	{
		if($this->PjltjMain === null) $this->PjltjMain = new PjltjMain();
		if($this->YpwVin === null) $this->YpwVin = new YpwVin();
		if($this->AdsBase === null) $this->AdsBase = new AdsBase();
		if(!is_array($this->tjRegArr)){
			$res = $this->PjltjMain->getTjReg();
			$this->tjRegArr = $res['data'];
		}
		$ignoreKeys = ['password','repassword','unitag','unionid','mobile_code'];
		$now = time();
		switch($this->actName)
		{
			case 'TJ_MAIN':
				$dataArr =  json_decode($msg, true);
				if(!empty($dataArr['tj_ip']) 
					&& !empty($dataArr['tj_site']) 
					&& !empty($dataArr['tj_from']) 
					&& !empty($dataArr['tj_devcode']) 
					&& !empty($dataArr['tj_act']))
				{
					$dataArr['tj_uid'] = (int) $dataArr['tj_uid'];
					$dataArr['tj_shopid'] = (int) $dataArr['tj_shopid'];
					if(empty($dataArr['tj_time'])) $dataArr['tj_time'] = time();
					$dataArr['tj_date'] = date('Ymd', $dataArr['tj_time']);

					$uact = trim(strtoupper($dataArr['tj_act']));
					if(!empty($this->tjRegArr[$dataArr['tj_site']][$uact]))
					{
						$regArr = $this->tjRegArr[$dataArr['tj_site']][$uact];
						$dataArr['tj_act'] = $regArr['tr_act'];
						//转成统一标准的参数
						$dataArr['tj_param'] = json_decode($dataArr['tj_param'], true);
						if(empty($dataArr['tj_shopid']) && $dataArr['tj_param']['shopid']) $dataArr['tj_shopid'] = (int) $dataArr['tj_param']['shopid'];
						switch($regArr['tr_act_group'])
						{
							case 'VIN':
								if(!isset($dataArr['tj_param']['vin']))
								{
									if(!empty($dataArr['tj_param']['word'])) $dataArr['tj_param']['vin'] = $dataArr['tj_param']['word'];
									else if(!empty($dataArr['tj_param']['keyword'])) $dataArr['tj_param']['vin'] = $dataArr['tj_param']['keyword'];
								}
								$dataArr['tj_param']['vin'] = LibFc::FormatVin($dataArr['tj_param']['vin']);
							break;
							case 'NUMBER':
								if(!isset($dataArr['tj_param']['number']))
								{
									if(!empty($dataArr['tj_param']['word'])) $dataArr['tj_param']['number'] = $dataArr['tj_param']['word'];
									else if(!empty($dataArr['tj_param']['keyword'])) $dataArr['tj_param']['number'] = $dataArr['tj_param']['keyword'];
								}
								$dataArr['tj_param']['number'] = LibFc::FormatNum($dataArr['tj_param']['number']);
							break;
						}
						//处理超长
						$count = 0;
						foreach($dataArr['tj_param'] as $pk=>$pv)
						{
							if(in_array($pk, $ignoreKeys) || stripos($pk, 'password') !== false){
								unset($dataArr['tj_param'][$pk]);
								continue;
							}
							if(!is_array($pv) && strlen($pv) > 50) $dataArr['tj_param'][$pk] = LibFc::msubstr($pv, 0, 50, "utf-8", false);
							$count++;
							if($count > 20 || strlen($pk) > 30) unset($dataArr['tj_param'][$pk]);
						}
						if(!empty($dataArr['tj_param']['mobile']) && !empty($dataArr['tj_param']['code']))
							unset($dataArr['tj_param']['code']);

						$dataArr['tj_param'] = json_encode($dataArr['tj_param'], JSON_UNESCAPED_UNICODE);
						$reArr = ['\t'=>'', "\r\n"=>'', "\r"=>'', "\n"=>''];
						$dataArr['tj_param'] = strtr($dataArr['tj_param'], $reArr);
						$this->PjltjMain->add('at_tongji', $dataArr);
					}
				}
			break;
			//目录访问明细
			case 'TJ_SUPER':
				$dataArr =  json_decode($msg, true);
				if(!empty($dataArr['su_ip']) && !empty($dataArr['su_from']) && !empty($dataArr['su_devcode']))
				{
					$OthB2cDb = new BaseDb(mvc::$cfg['DB']['B2COTH']);
					$addArr = [];
					foreach($dataArr as $k=>$v)
					{
						if(stripos($k, 'su_') === 0)
						{
							$addArr[$k] = $v;
						}
					}
					$addArr['su_unicode'] = md5($addArr['su_uid'].'@'.$addArr['su_devcode'].'@'.$addArr['su_ip'].'@'.$addArr['su_word'].'@'.$addArr['su_from']);
					if(!empty($dataArr['shopids']))
					{
						$shopIdArr = array_unique(json_decode($dataArr['shopids'], true));
						foreach($shopIdArr as $shopid)
						{
							$addArr['su_shop_id'] = (int) $shopid;
							$OthB2cDb->add('tj_super', $addArr);
						}
					}
					else if(!empty($addArr['su_shop_id']))
					{
						$OthB2cDb->add('tj_super', $addArr);
					}
				}
			break;
			//跑街令商家访问明细
			case 'TJ_PJL_SHOP':
				$dataArr =  json_decode($msg, true);
				if(!empty($dataArr['tps_act']) && !empty($dataArr['tps_devcode']))
				{
					$addArr = [];
					foreach($dataArr as $k=>$v)
					{
						if(stripos($k, 'tps_') === 0)
						{
							$addArr[$k] = $v;
						}
					}
					$addArr['tps_uid'] = (int) $addArr['tps_uid'];
					$shopIdArr = array_unique(explode(',', $dataArr['shopids']));
					foreach($shopIdArr as $shopid)
					{
						if($shopid > 0)
						{
							$addArr['tps_shop_id'] = (int) $shopid;
							$this->PjltjMain->add('tj_pjl_shop', $addArr);
						}
					}
				}
			break;
			//其他通道
			case 'TJ_OTH':
				$dataArr =  json_decode($msg, true);
				//广告统计
				if($dataArr['DTYPE'] == 'ADS_SHOW'){
					//广告展示
					$addArr = [];
					foreach($dataArr as $k=>$v)
					{
						if(stripos($k, 'as_') === 0)
						{
							$addArr[$k] = $v;
						}
					}
					if(!empty($addArr)) $this->AdsBase->add('pj_ads_show', $addArr);
				}else if($dataArr['DTYPE'] == 'ADS_CLICK'){
					//广告点击
					$addArr = [];
					foreach($dataArr as $k=>$v)
					{
						if(stripos($k, 'ac_') === 0)
						{
							$addArr[$k] = $v;
						}
					}
					if(!empty($addArr)) $this->AdsBase->add('pj_ads_click', $addArr);
				}else if($dataArr['DTYPE'] == 'VINIMG'){
					//vin图
					$othArr = $dataArr['othdata'];
					if($dataArr['atime']) $othArr['atime'] = $dataArr['atime'];
					$this->YpwVin->addCollVinImg($dataArr['vin'], $dataArr['imgdata'], $othArr);
				}else if($dataArr['DTYPE'] == 'ZS_SHOW'){
					$dparam = $dataArr['param'];
					$dparam['uid'] = (int) $dparam['uid'];
					$pctArr = [];
					$PjlBase = new PjlBase();
					if(empty($dparam['pct_ids']) && !empty($dparam['uid']))
					{
						$res = $PjlBase->get('pl_user', ['pu_pct_ids'], sprintf(" and pu_uid=%d limit 1", $dparam['uid']), true);
						if(!empty($res['data']['pu_pct_ids'])) $dparam['pct_ids'] = $res['data']['pu_pct_ids'];
					}

					if(!empty($dparam['pct_ids']))
					{
						$pctArr = [];
						foreach(explode(',', $dparam['pct_ids']) as $k=>$v)
						{
							$pctArr[$k] = (int) $v;
						}
					}
					if(empty($pctArr) && !empty($dparam['Ip']))
					{
						$OthPct = new OthPct();
						$res = $OthPct->getIpPCT($dparam['Ip']);
						$pctArr = $res['data']['pctids'];
					}
					$zs_pcts = json_encode(['pid'=>(int) $pctArr[0], 'cid'=>(int) $pctArr[1]], JSON_UNESCAPED_UNICODE);
					$addAny = [];
					foreach(explode(',', $dparam['zsl_id']) as $zslId)
					{
						$zslId = (int) $zslId;
						if($zslId > 0)
						{
							$addAny[] = [
								'zs_date'=>date('Ymd'),
								'zs_zsl_id'=> $zslId,
								'zs_view_uid'=> $dparam['uid'],
								'zs_ip'=>$dparam['Ip'],
								'zs_pcts'=>$zs_pcts,
								'zs_atime'=>!empty($dataArr['zs_atime'])? $dataArr['zs_atime']: time(),
							];
						}
					}
					if(!empty($addAny)) $PjlBase->addAny('zs_zhaoshang_show', array_keys($addAny[0]), $addAny);
				}else if($dataArr['DTYPE'] == 'PJLVIP'){//商家入驻VIP合同
					if(!empty($dataArr['uvl_id'])){
						$CrmMain = new CrmMain();
						$CrmMain->addContractByPjlVipOrder($dataArr['uvl_id']);
					}
				}
			break;
		}
	}
}