123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- <?php
- // +----------------------------------------------------------------------
- // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
- // +----------------------------------------------------------------------
- // | Author: 萤火科技 <admin@yiovo.com>
- // +----------------------------------------------------------------------
- declare (strict_types=1);
- namespace app\index\service\passport;
- use think\facade\Log;
- use yiovo\cache\facade\Cache;
- use yiovo\captcha\facade\CaptchaApi;
- use app\api\validate\passport\EmailCaptcha as ValidateEmailCaptcha;
- use app\common\service\BaseService;
- use cores\exception\BaseException;
- use PHPMailer\PHPMailer\PHPMailer;
- use PHPMailer\PHPMailer\SMTP;
- use PHPMailer\PHPMailer\Exception;
- /**
- * 服务类:发送邮箱验证码
- * Class MailCaptcha
- * @package app\api\service\passport
- */
- class MailCaptcha extends BaseService
- {
- // 最大发送次数,默认10次
- protected int $sendTimes = 10;
- // 发送限制间隔时间,默认24小时
- protected int $safeTime = 86400;
- //验证码过期时间
- protected int $expireTime = 300;
- //可重复使用次数
- protected int $checkTimes = 5;
- /**
- * 发送邮件验证码
- * @param array $data
- * @return bool
- * @throws BaseException
- */
- public function handle(array $data): bool
- {
- // 数据验证
- $this->validate($data);
- // 执行发送短信
- if (!$this->sendCaptcha($data['mobile'])) {
- return false;
- }
- return true;
- }
- /**
- * 执行发送邮箱验证码
- * @param string $email
- * @return bool
- */
- public function sendCaptcha(string $email): bool
- {
- // 缓存发送记录并判断次数
- if (!$this->record($email)) {
- return false;
- }
- // 生成验证码
- //$smsCaptcha = CaptchaApi::createSMS($email);
- $smsCaptcha = (string)mt_rand(100000, 999999);
- Cache::set("captchaSMS.{$email}", ['code' => $smsCaptcha, 'times' => $this->checkTimes], $this->expireTime);
- $mail = new PHPMailer(true);
- //dd(config('smtp'));
- try {
- //Server settings
- $mail->SMTPDebug = SMTP::DEBUG_OFF;//DEBUG_OFF,DEBUG_SERVER //Enable verbose debug output
- $mail->SMTPOptions = array(
- 'ssl' => array(
- 'verify_peer' => false,
- 'verify_peer_name' => false,
- 'allow_self_signed' => true
- )
- );
- $mail->isSMTP(); //Send using SMTP
- $mail->Host = config('smtp.host'); //Set the SMTP server to send through
- $mail->SMTPAuth = true; //Enable SMTP authentication
- $mail->Username = config('smtp.username'); //SMTP username
- $mail->Password = config('smtp.password'); //SMTP password
- $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
- $mail->Port = config('smtp.port'); //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
- //Recipients
- $mail->setFrom(config('smtp.from_address'), config('smtp.from_name'));
- $mail->addAddress($email, 'FSV'); //Add a recipient
- //$mail->addAddress('ellen@example.com'); //Name is optional
- //$mail->addReplyTo('info@example.com', 'Information');
- //$mail->addCC('cc@example.com');
- //$mail->addBCC('bcc@example.com');
- //Attachments
- //$mail->addAttachment('/var/tmp/file.tar.gz'); //Add attachments
- //$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); //Optional name
- //Content
- //$mail->isHTML(true); //Set email format to HTML
- $mail->Subject = 'Password';
- $mail->Body = 'Your code is ' . $smsCaptcha . '.Please use it in 15 minutes';
- $mail->AltBody = 'This is the Your Code for Free Shipping Vapes';
- $mail->send();
- //echo 'Message has been sent';
- } catch (Exception $e) {
- //echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
- Log::error(__CLASS__ . ':' . __METHOD__ . $e->getMessage() . '---' . $mail->ErrorInfo);
- Log::error(__CLASS__ . ':' . __METHOD__ . ',error:' . $e->getMessage() . ',mailError:' . $mail->ErrorInfo);
- return false;
- }
- return true;
- }
- /**
- * 发送营销文本邮件
- * @param string $email
- * @param string $subject
- * @param string $body
- * @param string $altBody
- * @param bool $isHtml
- * @param string $name
- * @return bool
- */
- public function sendText(string $email, string $subject = '', string $body = '', string $altBody = '', bool $isHtml = false, string $name = 'vip'): bool
- {
- $mail = new PHPMailer(true);
- try {
- //Server settings
- $mail->SMTPDebug = SMTP::DEBUG_OFF; //Enable verbose debug output
- $mail->SMTPOptions = array(
- 'ssl' => array(
- 'verify_peer' => false,
- 'verify_peer_name' => false,
- 'allow_self_signed' => true
- )
- );
- $mail->isSMTP(); //Send using SMTP //SMTP password
- $mail->Host = config('smtp.host'); //Set the SMTP server to send through
- $mail->SMTPAuth = true; //Enable SMTP authentication
- $mail->Username = config('smtp.username'); //SMTP username
- $mail->Password = config('smtp.password');
- $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
- $mail->Port = config('smtp.port'); //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
- //Recipients
- $mail->setFrom(config('smtp.from_address'), config('smtp.from_name'));
- $mail->addAddress($email, $name); //Add a recipient
- //Content
- if ($isHtml) {
- $mail->isHTML(true); //Set email format to HTML
- }
- $mail->Subject = $subject;
- $mail->Body = $body;
- if (!empty($altBody)) {
- $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
- }
- $mail->send();
- //echo 'Message has been sent';
- } catch (Exception $e) {
- //echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
- Log::error(__CLASS__ . ':' . __METHOD__ . ',error:' . $e->getMessage() . ',mailError:' . $mail->ErrorInfo);
- return false;
- }
- return true;
- }
- /**
- * 记录短信验证码发送记录并判断是否超出发送限制
- * @param string $mobile
- * @return bool
- */
- private function record(string $email): bool
- {
- // 获取发送记录缓存
- $record = Cache::get("sendCaptchaEmail.$email");
- // 写入缓存:记录剩余发送次数
- if (empty($record)) {
- Cache::set("sendCaptchaEmail.$email", ['times' => $this->sendTimes - 1], $this->safeTime);
- return true;
- }
- // 判断发送次数是否合法
- if ($record['times'] <= 0) {
- $this->error = 'Sorry,up to the limit today.';
- return false;
- }
- // 发送次数递减
- Cache::update("sendCaptchaEmail.$email", ['times' => $record['times'] - 1]);
- return true;
- }
- /**
- * 数据验证
- * @param array $data
- * @throws BaseException
- */
- public function validate(array $data)
- {
- // 数据验证
- $validate = new ValidateEmailCaptcha;
- if (!$validate->check($data)) {
- throwError($validate->getError());
- }
- // 验证图形验证码
- // if (!CaptchaApi::check($data['captchaCode'], $data['captchaKey'])) {
- // throwError('很抱歉,图形验证码不正确');
- // }
- }
- public function checkCaptcha($captchaCode = '', $email = '')
- {
- // if ($captchaCode == '888888') {
- // return true;
- // }
- $localCode = Cache::get('captchaSMS.' . $email);
- if (empty($localCode) || empty($localCode['code']) || $localCode['code'] != $captchaCode) {
- throwError('Sorry, the code is invalid!');
- }
- return true;
- }
- }
|