亲爱的会员:%username% 您好!

您使用了本站提供的邮箱验证功能,如果您确认此功能是您启用的,请点击下面的链接,
该链接在30分钟内有效,请在有效时间内操作:

确认找回密码

如果上述文字点击无效,请把下面网页地址复制到浏览器地址栏中打开: %url%

此为系统邮件,请勿回复
请保管好您的邮箱,避免%BRAND_NAME%账户被他人盗用

如有任何疑问,可查看 %BRAND_NAME%相关规则访问%BRAND_NAME%
Copyright © %YEAR% All Right Reserved

EOF; // 验证邮箱邮件内容模板 protected $_template2 = <<
亲爱的会员:%username% 您好!

您使用了本站提供的邮箱验证功能,如果您确认此功能是您启用的,请点击下面的链接,
该链接在30分钟内有效,请在有效时间内操作:

确认验证邮箱

如果上述文字点击无效,请把下面网页地址复制到浏览器地址栏中打开: %url%

此为系统邮件,请勿回复
请保管好您的邮箱,避免%BRAND_NAME%账户被他人盗用

如有任何疑问,可查看 %BRAND_NAME%相关规则访问%BRAND_NAME%
Copyright © %YEAR% All Right Reserved

EOF; // 申述编码内容模板 protected $_template3 = <<
尊敬的麻花网络互娱用户,您好!

您正在进行麻花网络账号申述的联系方式验证验证码为%code%,此码30分钟内有效

若非本人操作,请忽略此邮件。如有任何疑问可查看帮助中心,此邮件为系统自动发送,请勿回复。

EOF; // 申述验证码邮件内容模板 protected $_template4 = <<
尊敬的麻花网络用户,您好!

您的帐号[%username%]的申诉已受理,申诉编码为[%code%],请妥善保管此申诉编码,以备后续使用。申诉结果将在%day%个工作日内发送至您的邮箱,结果未给出前请勿重复申诉!

您可以随时访问客服中心内的申诉查询[http://www.weilongwl.com/kefu/sscx/]了解您账号当前的申诉处理进度。

如有任何问题请联系麻花网络客服。

客服QQ:%qq%;

微信公众号:%wechat%;

客服电话:%servicephone%。

工作时间:%servicetime%。

EOF; // 申述结果失败邮件内容模板 protected $_template5 = <<
尊敬的麻花网络用户,您好!

很抱歉,您申诉的账号:[%username%]因提供的资料不完善而未通过,申诉编码为:[%code%]。

建议您查看是否申诉错帐号。若帐号无误,建议您稍后重新进行申诉,并提供更为详情的信息。

如有任何问题请联系麻花网络客服。

客服QQ:%qq%;

微信公众号:%wechat%;

客服电话:%servicephone%。

工作时间:%servicetime%。

EOF; // 申述结果成功邮件内容模板 protected $_template6 = <<
尊敬的麻花网络用户,您好!

恭喜您,您申诉的账号:[%username%]的申诉已通过,申诉编码号为:[%code%], 成功凭证为:[%certificate%]。

请进入,麻花网络客服中心内的“申诉查询”[http://www.weilongwl.com/kefu/sscx/],输入申诉编码和成功凭证后,即可重置密码。

EOF; // 忘记密码-邮箱验证身份 protected $_template7 = <<
亲爱的麻花网络用户:%username% 您好!

您正在找回密码,验证码:%code%,验证码有效期为30分钟,请及时输入。

 为保证账号安全,请勿向任何人提供此验证码。

EOF; // 绑定手机-邮箱验证身份(没绑过手机) protected $_template8 = <<
亲爱的麻花网络用户:%username% 您好!

您正在绑定手机,验证码:%code%,验证码有效期为30分钟,请及时输入。

 为保证账号安全,请勿向任何人提供此验证码。

EOF; // 绑定邮箱--验证码 protected $_template9 = <<
亲爱的麻花网络用户:%username% 您好!

您正在绑定邮箱,验证码:%code%,验证码有效期为30分钟,请及时输入。

 为保证账号安全,请勿向任何人提供此验证码。

EOF; // 账号申诉-邮件验证身份 protected $_template10 = <<
亲爱的麻花网络用户:%username% 您好!

您正在账号申诉,验证码:%code%,有效期为30分钟,请及时输入。

 为保证账号安全,请勿向任何人提供此验证码。

EOF; // 绑定邮箱--验证邮箱 protected $_template11 = <<
亲爱的麻花网络用户:%username% 您好!

您正在换绑邮箱,验证码:%code%,验证码有效期为30分钟,请及时输入。

 为保证账号安全,请勿向任何人提供此验证码。

EOF; // 绑定手机-邮箱验证身份(换绑手机) protected $_template12 = <<
亲爱的麻花网络用户:%username% 您好!

您正在换绑手机,验证码:%code%,验证码有效期为30分钟,请及时输入。

 为保证账号安全,请勿向任何人提供此验证码。

EOF; // 绑定邮箱--验证邮箱 protected $_template15 = <<
亲爱的麻花网络用户:%username% 您好!

您正在通过邮箱找回密码,验证码:%code%,验证码有效期为30分钟,请及时输入。

 为保证账号安全,请勿向任何人提供此验证码。

EOF; public function __construct() { $this->_redis = Cache::store('redis'); } /** * 发送找回密码邮件 * @param string $username 玩家用户名 * @param string $mail 邮箱地址 */ public function sendFindMail($username, $mail) { $this->_instantiate(); $token = array('username' => $username, 'email' => $mail, 'time' => $this->_now_time); $token = json_encode($token); $token = auth_code($token, 'ENCODE', Env::get('auth_key')); $token = urlencode($token); $this->_url = $this->_website . "/user/findpwd.php?u={$token}"; $this->_template = $this->_template1; $this->_keywordReplace($username, $this->_url); $this->_phpmailer->AddAddress($mail, $username); // 收件人邮箱和姓名 $this->_phpmailer->Body = $this->_template; $result = $this->_phpmailer->Send(); if (!$result) { $this->_is_error = true; $this->_error_msg = $this->_phpmailer->ErrorInfo; } if (!$this->_is_error) { $this->_insertLog($mail, $this->_template, 'mail'); $this->_status = true; } return array('status' => $this->_status, 'msg' => $this->_status ? '' : $this->_error_msg); } /** * 发送验证邮件(带url供用户直接跳转) * @param string $username 玩家用户名 * @param string $mail 要送到的邮箱地址 * @param string $url 邮件中的回跳链接,不需要传入后面的t参数,例如 http://www.weilongwl.com/user/mail.php?action=xxx */ public function sendCheckMail($username, $mail, $url) { $this->_username = $username; $this->_instantiate(); $key = $this->_makeKey(); if (false === strstr($url, '?')) { $this->_url = $url . '?t=' . $key; } else { $this->_url = $url . '&t=' . $key; } $this->_template = $this->_template2; $this->_keywordReplace($username, $this->_url); $this->_phpmailer->AddAddress($mail, $username); // 收件人邮箱和姓名 $this->_phpmailer->Body = $this->_template; $result = $this->_phpmailer->Send(); if (!$result) { $this->_is_error = true; $this->_error_msg = $this->_phpmailer->ErrorInfo; } if (!$this->_is_error) { // 写入redis $res = $this->_insertLog($mail, $this->_template, 'mail'); $data = array('username' => $username, 'mail' => $mail, 't' => $key, 'create_time' => $this->_now_time); $this->_redis->set($this->_cache_key, json_encode($data), $this->_expire_time); $this->_status = true; } return array('status' => $this->_status, 'msg' => $this->_status ? '' : $this->_error_msg); } /** * 发送验证邮件(带数字验证码) * @param string $mail 要送到的邮箱地址 */ public function sendCodeMail($mail) { $this->_mail = $mail; $this->_makeCode(); $this->_makeMailKey(); $res = $this->_sendCodeRuler(); if (!$res['status']) return $res; $this->_instantiate(); $key = $this->_makeKey(); $this->_template = $this->_template3; $this->_template = str_replace('%code%', $this->_code, $this->_template); $this->_phpmailer->AddAddress($mail); // 收件人邮箱和姓名 $this->_phpmailer->Body = $this->_template; $result = $this->_phpmailer->Send(); if (!$result) { $this->_is_error = true; $this->_error_msg = $this->_phpmailer->ErrorInfo; } if (!$this->_is_error) { // 写入redis $res = $this->_insertLog($mail, $this->_template, 'mail'); $data = array('mail' => $mail, 'create_time' => $this->_now_time, 'code' => $this->_code);//now-here $this->_redis->set($this->_cache_key, json_encode($data), $this->_expire_time); $this->_setSendCodeRedisData(); $this->_status = true; } return array('status' => $this->_status, 'msg' => $this->_status ? '' : $this->_error_msg); } /** * 发送申诉编码/通知邮件 * @param string $mail 要送到的邮箱地址 */ public function sendAppealCodeMail($username, $code, $mail, $day, $certificate, $status) { $this->_instantiate(); if ($status == 1) { $this->_template = $this->_template6; $this->_template = str_replace('%username%', $username, $this->_template); $this->_template = str_replace('%code%', $code, $this->_template); $this->_template = str_replace('%certificate%', $certificate, $this->_template); } elseif ($status == 2 || $status == 4) { $this->_template = $this->_template5; $this->_template = str_replace('%username%', $username, $this->_template); $this->_template = str_replace('%code%', $code, $this->_template); } else { $this->_template = $this->_template4; $this->_template = str_replace('%username%', $username, $this->_template); $this->_template = str_replace('%code%', $code, $this->_template); $this->_template = str_replace('%day%', $day, $this->_template); } if ($status != 1){ $qqArr = model('Common/Kefu')->column('qq'); $qq = implode('、',$qqArr); $this->_template = str_replace('%qq%', $qq, $this->_template); $time = model('Setting')->where('name','CUSTOMER_SERVICE_TIME')->value('value'); $this->_template = str_replace('%servicetime%', $time, $this->_template); $phone = model('Setting')->where('name','CUSTOMER_SERVICE_PHONE')->value('value'); $this->_template = str_replace('%servicephone%', $phone, $this->_template); $wechat = model('Setting')->where('name','WECHAT_NUMBER')->value('value'); $this->_template = str_replace('%wechat%', $wechat, $this->_template); } $this->_phpmailer->AddAddress($mail); // 收件人邮箱和姓名 $this->_phpmailer->Body = $this->_template; $result = $this->_phpmailer->Send(); if (!$result) { $this->_is_error = true; $this->_error_msg = $this->_phpmailer->ErrorInfo; } if (!$this->_is_error) { // 写入redis $res = $this->_insertLog($mail, $this->_template, 'mail'); $data = array('mail' => $mail, 'create_time' => $this->_now_time); $this->_redis->set($this->_cache_key, json_encode($data), $this->_expire_time); $this->_status = true; } return array('status' => $this->_status, 'msg' => $this->_status ? '' : $this->_error_msg); } /** * 自定义发送内容 * @param $template 模板 * @param $address 邮件地址 * @return array 发送状态和信息 */ public function sendMail($template, $address) { $this->_instantiate(); if (is_array($address)) { foreach ($address as $mail) { $this->_phpmailer->AddAddress($mail); // 批量收件 } } else { $this->_phpmailer->AddAddress($address); // 单个收件人 } $this->_phpmailer->Body = $template; $result = $this->_phpmailer->Send(); if (!$result) { $this->_is_error = true; $this->_error_msg = $this->_phpmailer->ErrorInfo; } if (!$this->_is_error) { $this->_insertLog(implode(',', $address), $template, 'mail'); $this->_status = true; } return array('status' => $this->_status, 'msg' => $this->_status ? '' : $this->_error_msg); } /** * 校验邮箱验证码是否正确,同时判断是否发送过 * */ public function checkMail($username, $mail) { $this->_username = $username; $key = $this->_makeKey(); if (!$this->isMail($mail)) { $this->_is_error = true; $this->_error_msg = '邮箱号码错误'; } $this->_username = $username; if (!$this->_is_error && !$res = $this->queryKey($key)) { $this->_is_error = true; $this->_error_msg = '验证码不存在,请先发送'; } if (!$this->_is_error && ($this->_now_time - $res['create_time'] > $this->_expire_time)) { // 判断是否过期 $this->_is_error = true; $this->_error_msg = '验证码已过期'; } if (!$this->_is_error) { $this->_status = true; } return array('status' => $this->_status, 'msg' => $this->_error_msg); } /** * 校验邮箱验证码是否正确,同时判断是否发送过 * */ public function checkMailToken($username, $token) { $this->_username = $username; $key = $this->_makeKey(); $res = $this->queryKey($key); if (!$this->_is_error && !$res) { $this->_is_error = true; $this->_error_msg = '邮箱验证链接不存在,请先发送'; } if (!$this->_is_error && ($this->_now_time - $res['create_time'] > $this->_expire_time)) { // 判断是否过期 $this->_is_error = true; $this->_error_msg = '邮箱验证链接已过期'; } if ($res['t'] !== $token) { $this->_is_error = true; $this->_error_msg = '邮箱验证链接已失效'; } if (!$this->_is_error) { $this->_status = true; } return array('status' => $this->_status, 'msg' => $this->_error_msg ,'data'=>$res); } /** * 校验邮箱验证码是否正确,同时判断是否发送过 * */ public function checkCode($username, $mail, $code) { $this->_username = $username; $key = $this->_makeKey(); if (!$this->isMail($mail)) { $this->_is_error = true; $this->_error_msg = '邮箱号码错误'; } if (!$this->_is_error && (empty($this->_getLastTime()) || empty($this->_getCode()))) { $this->_is_error = true; $this->_error_msg = '验证码不存在,请先发送'; } if (!$this->_is_error && ($this->_now_time - $this->_last_time > $this->_expire_time)) { // 判断是否过期 $this->_is_error = true; $this->_error_msg = '验证码已失效'; } if (!$this->_is_error && $code != $this->_code) { $this->_is_error = true; $this->_error_msg = '验证码输入错误'; } if (!$this->_is_error) { $this->_status = true; } return array('status' => $this->_status, 'msg' => $this->_error_msg); } /** * 根据key查询出缓存中的数据 * @param string $key */ public function queryKey($key) { $this->_cache_key = $this->_cache_key_prefix . $key; if ($this->_redis->has($this->_cache_key)) { $result = $this->_redis->get($this->_cache_key); return json_decode($result, true); } return null; } /** * 删除key(邮件中传递来的key) * @param string $key */ public function clearKey($key) { $this->_cache_key = $this->_cache_key_prefix . $key; $this->_redis->rm($this->_cache_key); } /** * 通过username查询出key,并删除 */ public function clearKeyByUsername($username) { $this->_username = $username; $this->_makeKey(); $this->_redis->rm($this->_cache_key); } /** * 邮箱格式验证 * @param string $mail 邮箱地址 */ public function isMail($mail) { return preg_match($this->_preg_mail, $mail); } /** * 设置以当前用户名创建的redis记录的数组指定key的value * @param unknown $key * @param unknown $value */ public function setValue($username, $key, $value) { $this->_username = $username; $this->_makeKey(); if ($cache_data = $this->_redis->get($this->_cache_key)) { $cache_data = json_decode($cache_data, true); } else { $cache_data = array(); } $cache_data[ $key ] = $value; $this->_redis->set($this->_cache_key, json_encode($data), $this->_expire_time); } /** * 生成redis的缓存key,使用用户名+当前日期的规则生成,确保当天生成的链接一致 * @return string $key 生成的key,这是用于发送邮件中带的key,不是redis中存储的key */ protected function _makeKey() { $key = md5($this->_username . date('Ymd')); $this->_cache_key = $this->_cache_key_prefix . $key; return $key; } /** * 替换掉模板中的关键字符串 * @param string $username 玩家账号 * @param string $url 跳转链接 */ protected function _keywordReplace($username, $url) { $this->_template = str_replace('%BRAND_NAME%', $this->_brand_name, $this->_template); $this->_template = str_replace('%WEBSITE%', $this->_website, $this->_template); $this->_template = str_replace('%YEAR%', date('Y'), $this->_template); $this->_template = str_replace('%url%', $url, $this->_template); $this->_template = str_replace('%username%', $username, $this->_template); } /** * 实例化对象并加载通用配置 */ protected function _instantiate() { $this->_phpmailer = new PHPMailer\PHPMailer(); $this->_configuration(); } /** * phpmailer通用配置 */ protected function _configuration() { $this->_phpmailer->Mailer = 'SMTP'; $this->_phpmailer->SMTPDebug = 0; $this->_phpmailer->SMTPSecure = 'ssl'; $this->_phpmailer->SMTPAuth = true; $this->_phpmailer->Host = config('mail.host'); $this->_phpmailer->Port = config('mail.port'); $this->_phpmailer->Username = config('mail.username'); $this->_phpmailer->Password = config('mail.password'); $this->_phpmailer->From = config('mail.username'); // 发件人邮箱 $this->_phpmailer->FromName = '麻花网络游戏'; // 发件人 $this->_phpmailer->CharSet = 'utf-8'; // 这里指定字符集! $this->_phpmailer->Encoding = 'base64'; $this->_phpmailer->Subject = $this->_brand_name . '官方邮箱验证'; $this->_phpmailer->IsHTML(true); $this->_phpmailer->AddReplyTo(config('mail.username'), ''); // 回复地址 $this->_phpmailer->AltBody = $this->_brand_name; } /** * 生成验证码 * @return null */ protected function _makeCode() { $code = rand(111111, 999999); $this->_code = $code; } /** * 获取最后一次发送时间 * @return string */ protected function _getLastTime() { $this->_last_time = $this->_getValue('create_time'); return $this->_last_time; } /** * 获取redis中该邮箱的某个key的值 */ protected function _getValue($key) { $response = null; if ($this->_redis->has($this->_cache_key)) { // 存在这个key $data = $this->_redis->get($this->_cache_key); $data = json_decode($data, true); if (isset($data)) { // 该号码已经有发送记录 $response = $data[ $key ]; } } return $response; } /** * 获取redis中保存的该邮箱号的验证码 */ protected function _getCode() { $this->_code = $this->_getValue('code'); return $this->_code; } /** * 写入发送日志 * @param string $email * @param string $content * @param string $type * @return null */ protected function _insertLog($email, $content, $type = 'mail') { $data = []; $data['content'] = addslashes($content); $data['type'] = $type; $data['target'] = $email; $data['create_time']= NOW_TIMESTAMP; model('MailLog')->save($data); } /** * 发送验证邮件(带数字验证码 和 用户名的) * @param string $mail 要送到的邮箱地址 */ public function sendCodeMailByType($username,$mail,$type = 'fogetpwd') { $this->_mail = $mail; if (!$this->isMail($mail)) { $this->_error_msg = '邮箱号码错误'; return array('status' => false, 'msg' => $this->_error_msg); } $this->_makeCode(); $this->_makeMailKey(); $res = $this->_sendCodeRuler(); if (!$res['status']) return $res; $this->_username = $username; $this->_instantiate(); $key = $this->_makeKey(); if ($type == 'fogetpwd'){ // 忘记密码-邮箱验证身份 $this->_template = $this->_template7; }elseif ($type == 'bindMobilVLEmail'){ // 绑定手机-邮箱验证身份(换绑手机) $this->_template = $this->_template12; }elseif ($type == 'bindEmail'){ // 绑定邮箱 $this->_template = $this->_template9; }elseif ($type == 'appeal'){ // 账号申诉-邮件验证身份 $this->_template = $this->_template10; }elseif ($type == 'bindEmailVLEmail'){ // 绑定邮箱-邮箱验证身份 $this->_template = $this->_template11; }elseif ($type == 'bindMobil'){ // 绑定手机-邮箱验证身份(没绑手机) $this->_template = $this->_template8; }elseif ($type == 'resetPasswordByEmail'){ // 通过邮箱找回密码 $this->_template = $this->_template15; } $this->_template = str_replace('%code%', $this->_code, $this->_template); $this->_template = str_replace('%username%', $username, $this->_template); $this->_phpmailer->AddAddress($mail); // 收件人邮箱和姓名 $this->_phpmailer->Body = $this->_template; $result = $this->_phpmailer->Send(); if (!$result) { $this->_is_error = true; $this->_error_msg = $this->_phpmailer->ErrorInfo; } if (!$this->_is_error) { // 写入redis $res = $this->_insertLog($mail, $this->_template, 'mail'); $data = array('mail' => $mail, 'create_time' => $this->_now_time, 'code' => $this->_code);//now-here $this->_redis->set($this->_cache_key, json_encode($data), $this->_expire_time); $this->_setSendCodeRedisData(); $this->_status = true; } return array('status' => $this->_status, 'msg' => $this->_status ? '' : $this->_error_msg); } /** * 生成redis的缓存key,使用邮箱+当前日期的规则生成,确保当天生成的链接一致 * @return string $key 生成的key,这是用于发送邮件中带的key,不是redis中存储的key */ protected function _makeMailKey() { $key = md5($this->_mail . date('Ymd')); $this->_cache_mail_key = $this->_cache_key_prefix . $key; return $key; } /** * 写入redis数据 * @return null */ protected function _setSendCodeRedisData(){ // 存在这个key if ($this->_redis->has($this->_cache_mail_key)) { $data = $this->_redis->get($this->_cache_mail_key); $data = json_decode($data, true); if (!isset($data)) { $data = array( 'times' => 1, 'sendtime' => $this->_now_time, 'code' => $this->_code, ); } else { $data['times'] = ++$data['times']; $data['sendtime'] = $this->_now_time; $data['code'] = $this->_code; } } else { // 不存在这个key,新建 $data = array( 'times' => 1, 'sendtime' => time(), 'code' => $this->_code, ); //now-here } $this->_redis->set($this->_cache_mail_key, json_encode($data), $this->_expire_time); } /** * 判断该邮箱是否在一定时间内,一直发验证码 * @return array */ protected function _sendCodeRuler(){ // 存在这个key if ($this->_redis->has($this->_cache_mail_key)) { $data = $this->_redis->get($this->_cache_mail_key); $data = json_decode($data, true); if (isset($data)) { if ( ($this->_now_time - $data['sendtime']) < $this->_interval) { $this->_error_msg = '发送验证码操作太频繁,请稍后再试'; return array('status' => false, 'msg' => $this->_error_msg); } } } return array('status' => true, 'msg' => ''); } }