<?php
/**
  * @method 短信发送
  * @author soul
  * @copyright 2016/3/31
  */
class SendSms extends SendBase
{
	/**
	  * @method 短信发送
	  * @param  $dataArr
				1、['sms_type'=>xxx, 'sms_from'=>xxxx....] 无sms_id将会入库
				2、['sms_id'=>xxx] 有sms_id 则自动查询数据库数据
	  * @param  $account 发送账号，可选
	  * @author soul
	  * @copyright 2017/4/14
	  * @return 
		成功 [ ["status"]=> true ["data"]=> ["sms_id":"32","sms_status":"ok","sms_error_msg":""] ["code"]=> '' ]
		失败 [ ["status"]=> false ["data"]=> 错误原因 ["code"]=> '' ]
	  */
	public function send($dataArr, $account =  null)
	{
		if(mvc::$cfg['SMS'][$account])
		{
			$account = mvc::$cfg['SMS'][$account];
		}
		else
		{
			$res = $this->getAccount($dataArr);
			$account = $res['data'];
		}

		//入库
		if(empty($dataArr['sms_id']))
		{
			if((empty($dataArr['sms_type']) || empty($dataArr['sms_type']) || empty($dataArr['sms_from']) || empty($dataArr['sms_to_mobile'])|| empty($dataArr['sms_text'])))
			{
				return LibFc::ReturnData(false, '短信的参数不完整');
			}
			$dataArr['sms_sign'] = '宜配网';
			$dataArr['sms_add_time'] = time();
			$temp = $dataArr;
			unset($temp['again']);
			$Res = $this->Add('sc_sms', $temp);
			$dataArr['sms_id'] = $Res['data'];
		}
		else
		{
			$res = $this->Get('sc_sms', ['*'], sprintf(" AND sms_id =%d", $dataArr['sms_id']), true);
			if(empty($res['data']))
			{
				return LibFc::ReturnData(false, '短信ID不存在');
			}
			$dataArr = $res['data'];

			//已成功 或者过有效期的不再发送
			if($dataArr['sms_status'] == 'ok')
			{
				return LibFc::ReturnData(true, ['sms_id'=>$dataArr['sms_id'], 'sms_status'=>$dataArr['sms_status']]);
			}
			else if(!empty($dataArr['sms_expire_time']) && $dataArr['sms_expire_time'] < time() )
			{
				$dataArr['sms_error_msg'] = '已过发送有效期！';
				$this->Set('sc_sms', ['sms_error_msg'=>$dataArr['sms_error_msg']], sprintf(" AND sms_id =%d", $dataArr['sms_id']));
				return LibFc::ReturnData(true, ['sms_id'=>$dataArr['sms_id'], 'sms_status'=>$dataArr['sms_status'], 'sms_error_msg'=>$dataArr['sms_error_msg']]);
			}
		}
		
		$SetArr = ['sms_last_time'=>time()];
		switch($account['api'])
		{
			//短信验证码
			case 'ali':
				$smsTplArr = [
					'default'=>'SMS_168415680',
					'logintg'=>'SMS_141596613',
					'login'=>'SMS_141596613',
					'bind'=>'SMS_123292408',
					'unbind'=>'SMS_123292409',
					'password'=>'SMS_123292410',
					'paypassword'=>'SMS_142953050',
					'orderStatus'=>'SMS_137689788',
					'baccount'=>'SMS_143860784',
					'ubaccount'=>'SMS_143865736',
					'pjlShopOk'=>'SMS_152857649',
					'pjlShopError'=>'SMS_152857653',
					'pjlOrderStatus'=>'SMS_157275044',
					'pjlShoprOk'=>'SMS_202560720',
					'pjlShoprError'=>'SMS_202560727',
					'pjlOrderRefund'=>'SMS_203676307',
					'bindShopUser'=>'SMS_213540324',
					'unbindShopUser'=>'SMS_213530352',
					'noticeRefundPjlSearchMoney'=>'SMS_217405915',
					'delaccount'=>'SMS_246250491',
				];
				include_once('lib/aliyun-dysms-php-sdk/api_demo/SmsDemo.php');
				$msgArr = [
					'sms_to_mobile'=>$dataArr['sms_to_mobile'],	
					'sms_text'=>$dataArr['sms_text'],	
					'sms_sign'=>$dataArr['sms_sign'],	
					'sms_tpl'=>$smsTplArr[$dataArr['sms_style']]	
				];
				$response = SmsDemo::sendSms($msgArr);
				if($response->Message == 'OK')
				{
					$SetArr['sms_status'] = 'ok';
					$SetArr['sms_error_msg'] = '';
				}
				else
				{
					$SetArr['sms_status'] = 'error';
					$SetArr['sms_error_count'] = $dataArr['sms_error_count']+1;
					$SetArr['sms_error_msg'] = $response->Message;
				}
			break;
			case 'baidu':
				include_once('lib/BaiduSms.php');
				$smsTplArr = [
					'default'=>'sms-tmpl-YwSNFo94430',
					'logintg'=>'sms-tmpl-QJcMYq65573',
					'login'=>'sms-tmpl-QJcMYq65573',
					'bind'=>'sms-tmpl-XdCtvk92674',
					'unbind'=>'sms-tmpl-ceKgoB37261',
					'password'=>'sms-tmpl-oLqksQ94260',
					'paypassword'=>'sms-tmpl-XCmVeo57814',
					'orderStatus'=>'sms-tmpl-bhMCJH00453',
					'baccount'=>'sms-tmpl-TYTSmE65256',
					'ubaccount'=>'sms-tmpl-AuncYc60285',
					'pjlShopOk'=>'sms-tmpl-qeBzmr59977',
					'pjlShopnError'=>'sms-tmpl-bESKgF25197',
					'pjlOrderStatus'=>'sms-tmpl-XWEjBC14026',
					'bindShopUser'=>'sms-tmpl-rbArfh40938',
					'unbindShopUser'=>'sms-tmpl-rLjanD32678',
				];
				$msgArr = [
					'signatureId'=>$account['signatureId'],
					'mobile'=>$dataArr['sms_to_mobile'],	
					'contentVar'=>json_decode($dataArr['sms_text'], true),
					'template'=>$smsTplArr[$dataArr['sms_style']]
				];
				$response = BaiduSms::sms($msgArr, $account);
				if($response->code == 1000)
				{
					$SetArr['sms_status'] = 'ok';
					$SetArr['sms_error_msg'] = '';
				}
				else
				{
					$SetArr['sms_status'] = 'error';
					$SetArr['sms_error_count'] = $dataArr['sms_error_count']+1;
					$SetArr['sms_error_msg'] = $response->message;
				}
			break;
			case 'yuqi': 
				//旧平台
				$smsTplArr = [	
					'default'=>'您的验证码${status}，该验证码5分钟内有效，请勿泄漏于他人！',
					'orderStatus'=>'您的（跑街的）店铺有新订单啦，订单号：${ordId}，当前状态：${status}，请及时处理。',
					'pjlShopOk'=>'掌柜的，您好！您在跑街令中提交的商家申请，审核已通过。',
					'pjlShopnError'=>'掌柜的，您好！您在跑街令中提交的商家申请不通过，请登录跑街令查看详情。',
					'pjlOrderStatus'=>'掌柜的，您的跑街令有新订单啦，订单号：${ordId}，当前状态：${status}，请及时处理',
				];
				
				$content = $dataArr['sms_text'];
				if(!empty($smsTplArr[$dataArr['sms_style']]))
				{
					$tpl = $smsTplArr[$dataArr['sms_style']];
					$tempArr = json_decode($content, true);
					foreach($tempArr as $tk=>$tv)
					{
						$tpl = str_replace('${'.$tk.'}', $tv, $tpl);
					}
					$content = $tpl;
				}
				$Data = $account;
				$Data['mobiles'] = $dataArr['sms_to_mobile'];
				$Data['content'] =  '【'.$dataArr['sms_sign'].'】'.$content;
				$LibCurl = new LibCurl(false, false);
				$Res = $LibCurl->fetch($account['url'], $Data);
				$Res = simplexml_load_string($Res);
				$Res = json_decode(json_encode($Res),true);
				if($Res['errorcode'] == 1)
				{
					$SetArr['sms_status'] = 'ok';
					$SetArr['sms_error_msg'] = '';
				}
				else
				{
					$SetArr['sms_status'] = 'error';
					$SetArr['sms_error_count'] = $dataArr['sms_error_count']+1;
					$SetArr['sms_error_msg'] = $Res['message'];
				}
			break;
		}
	
		$SetArr['sms_account'] = $account['key'];
		$this->Set('sc_sms', $SetArr, sprintf(" AND sms_id = %d", $dataArr['sms_id']));

		$dataArr = array_merge($dataArr, $SetArr);

		$ResArr = [];
		$ReturnKey = ['sms_id', 'sms_status', 'sms_error_msg', 'sms_last_time'];
		foreach($ReturnKey as $V)
		{
			$ResArr[$V] = $dataArr[$V];
		}
		return LibFc::ReturnData(true, $ResArr);
	}


	/**
	  * @method 根据站点获取发送签名
	  * @param  $dataArr ['sms_from'=>'主站', 'sms_type'=>'紧急']
	  * @author soul
	  * @copyright 2017/4/14
	  * @return [ ["status"]=> bool(true) ["data"]=> 签名 ["code"]=> '' ]
	  */
	public function getAccount($dataArr)
	{
		//@soul 2017/7/28
		$key = 'yuqi';
		if($dataArr['sms_type'] == '紧急') $key = 'ali';
		if($dataArr['again']) $key = 'baidu';
		if(empty(mvc::$cfg['SMS'][$key]))
		{
			foreach(mvc::$cfg['SMS'] as $k=>$v)
			{
				if(in_array($dataArr['sms_type'], $v['sms_type']))
				{
					$key = $k;
					break;
				}
			}
		}
		$account = mvc::$cfg['SMS'][$key];
		$account['key'] = $key;
		return LibFc::ReturnData(true, $account);
	}



	/**
	  * @method 发送手机验证码
	  * @http  get
	  * @param  $dataArr  [
			'mobile'=>手机号码,
			'style'=>'default', 'bind', 'unbind', 'password', 'login', 'paypassword', 'baccount', 'ubaccount', 'delaccount',
			'from'=>YP|YPAPP|YPGZG|YPIM|YPYPC|PJD|PJDGZH|PJDSGZH(商城店铺公众号)|CRM|BMTSR|CLIENT(客户网)
		];
	  * @author soul
	  * @copyright 2018/1/25
	  * @return 
		{"status":true,"data": , "code":0}
		{"status":false,"data":'失败原因',"code":0}
	  */
	function sendMobileCode($dataArr)
	{
		$dataArr['mobile'] = trim($dataArr['mobile']);
		$styleArr = ['default','bind', 'unbind', 'password', 'login', 'paypassword', 'baccount', 'ubaccount', 'logintg', 'bindShopUser', 'unbindShopUser', 'delaccount'];
		if(!preg_match('/^1\d{10}$/', $dataArr['mobile'])) return LibFc::ReturnData(false, '手机号码不正确');
		if(!in_array($dataArr['style'], $styleArr)) return LibFc::ReturnData(false, 'style参数不正确');
		if(empty($dataArr['from'])) return LibFc::ReturnData(false, 'from参数不正确');
		//查询上一次的发送时间
		$where = sprintf(" and smc_mobile='%s' and smc_style='%s' and smc_from='%s' and smc_expire_time > 0 ", $dataArr['mobile'], $dataArr['style'], $dataArr['from']);
		$res = $this->Get('sc_mobile_code', ['smc_send_time'], $where.'  order by smc_send_time desc limit 1', true);
		$pertime = 120;
		$hasSendTime = time() - (int)$res['data']['smc_send_time'];

		//发送频繁
		if($hasSendTime < $pertime)
			return LibFc::ReturnData(false, '手机验证码发送过于频繁，请'.($pertime-$hasSendTime).'秒后重试', 'send_wait');
	
		if(!in_array($dataArr['style'], ['logintg']) && (stripos($dataArr['from'], 'YP') === 0 || stripos($dataArr['from'], 'PJ') === 0))
		{
			$YpwUser = new YpwUser();
			$Res = $YpwUser->GetUser(['u_id', 'u_status'], sprintf(" AND u_mobile_check='Y' AND u_mobile='%s'", $dataArr['mobile']), true);
			if(!empty($Res['data']) && $Res['data']['u_status'] != 1)
			{
				$Return = ['status'=>false, 'data'=>'监控系统检测到账号使用异常，已被停用！', 'code'=>'discontinued'];
				echo json_encode($Return);exit;
			}
			switch($dataArr['style'])
			{
				case 'bind':
					if(!empty($Res['data']))
					{
						$Return = ['status'=>false, 'data'=>'此手机号已绑定宜配账号【注：宜配网、跑街商城、跑街令均使用同一通用的用户系统（宜配通行证）】', 'code'=>'has_bind'];
						echo json_encode($Return);exit;
					}
				break;
				case 'unbind':
					if(empty($Res['data']))
					{
						$Return = ['status'=>false, 'data'=>'此手机号尚未注册，请先注册', 'code'=>'no_bind'];
						echo json_encode($Return);exit;
					}
				break;
				case 'password':
				case 'paypassword':
				case 'login':
				case 'baccount':
				case 'ubaccount':
				case 'delaccount':
					if(empty($Res['data']))
					{
						$Return = ['status'=>false, 'data'=>'此手机号尚未注册，请先注册', 'code'=>'no_bind'];
						echo json_encode($Return);exit;
					}
				break;
			}
		}
		
		$randCode = LibFc::RandNum(100000, 999999);
		$sendArr = [
			'sms_type'=>'紧急',
			'sms_from'=>$dataArr['from'],
			'sms_style'=>$dataArr['style'],
			'sms_to_mobile'=>$dataArr['mobile'],
			'sms_text'=>'{"code":"'.$randCode.'"}'
		];
		$this->SendDb->Begin();
		//5分钟内重复发送
		$sendArr['again'] = ($hasSendTime - $pertime) < 300 ? true: false;
		$res = $this->send($sendArr);
		$addData = [
			'smc_mobile'=>$dataArr['mobile'],
			'smc_style'=>$dataArr['style'],
			'smc_from'=>$dataArr['from'],
			'smc_code'=>$randCode,
			'smc_send_time'=>time(),	
			'smc_expire_time'=>time()+600,
			'smc_sms'=>$res['data']['sms_id']
		];
		$this->Set('sc_mobile_code', ['smc_expire_time'=>0], $where);
		$res = $this->Add('sc_mobile_code', $addData);
		$this->SendDb->End();
		$addData['smc_id'] = $res['data'];
		return LibFc::ReturnData(true, $addData);
	}


	/**
	  * @method 验证手机验证码
	  * @http  get
	  * @param  $dataArr  [
			'mobile'=>手机号码,
			'style'=>bind unbind password login,
			'from'=>B2C 主站 客户网 CRM BMTSR,
			'code'=>xxxx
		];
	  * @author soul
	  * @copyright 2018/1/25
	  * @return 
		{"status":true,"data": , "code":0}
		{"status":false,"data":'失败原因',"code":0}
	  */
	function checkMobileCode($dataArr)
	{
		$dataArr['mobile'] = trim($dataArr['mobile']);
		if(!preg_match('/^1\d{10}$/', $dataArr['mobile'])) return LibFc::ReturnData(false, '手机号码不正确');
		if(empty($dataArr['from'])) return LibFc::ReturnData(false, '请提供手机验证码from参数');
		if(empty($dataArr['style'])) return LibFc::ReturnData(false, '请提供验证码的style参数');
		if(empty($dataArr['code'])) return LibFc::ReturnData(false, '手机验证码不能为空');
		$styleArr = [];
		foreach(explode(',', $dataArr['style']) as $style)
		{
			$styleArr[] = sprintf("'%s'", LibFc::Escape($style));
		}
		$where = sprintf(" and smc_mobile='%s' and smc_from='%s' and smc_code='%s' and smc_style in (%s)", 
			LibFc::Escape($dataArr['mobile']), LibFc::Escape($dataArr['from']), LibFc::Escape($dataArr['code']), implode(',', $styleArr));
		$res = $this->Get('sc_mobile_code', ['smc_id', 'smc_expire_time'], $where.' order by smc_send_time desc limit 1', true);
		if(!empty($res['data']) && $res['data']['smc_expire_time'] > time())
		{
			return LibFc::ReturnData(true, $res['data']);
		}
		return LibFc::ReturnData(false, '手机验证码不正确', 'code_error');
	}


	/**
	  * @method 将手机验证码失效
	  * @http  get
	  * @param  $dataArr  [
			'mobile'=>手机号码,
			'style'=>bind unbind password login,
			'from'=>B2C 主站 客户网 CRM BMTSR,
		];
	  * @author soul
	  * @copyright 2018/1/25
	  * @return 
		{"status":true,"data": , "code":0}
		{"status":false,"data":'失败原因',"code":0}
	  */
	function outMobileCode($dataArr)
	{
		$dataArr['mobile'] = trim($dataArr['mobile']);
		if(!preg_match('/^1\d{10}$/', $dataArr['mobile'])) return LibFc::ReturnData(false, '手机号码不正确');
		if(empty($dataArr['from'])) return LibFc::ReturnData(false, '请提供手机验证码from参数');
		if(empty($dataArr['style'])) return LibFc::ReturnData(false, '请提供验证码的style参数');
		$styleArr = [];
		foreach(explode(',', $dataArr['style']) as $style)
		{
			$styleArr[] = sprintf("'%s'", LibFc::Escape($style));
		}
		$where = sprintf(" and smc_mobile='%s' and smc_style in(%s) and smc_from='%s'", LibFc::Escape($dataArr['mobile']), implode(',', $styleArr), LibFc::Escape($dataArr['from']));
		$this->Set('sc_mobile_code', ['smc_expire_time'=>0], $where);
		return LibFc::ReturnData(true, true);
	}
}