|
@@ -0,0 +1,215 @@
|
|
|
+<?php
|
|
|
+// +----------------------------------------------------------------------
|
|
|
+// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
|
|
+// +----------------------------------------------------------------------
|
|
|
+// | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
|
|
|
+// +----------------------------------------------------------------------
|
|
|
+// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
|
|
+// +----------------------------------------------------------------------
|
|
|
+// | Author: 萤火科技 <admin@yiovo.com>
|
|
|
+// +----------------------------------------------------------------------
|
|
|
+declare (strict_types=1);
|
|
|
+
|
|
|
+namespace app\api\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;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送邮件验证码
|
|
|
+ * @param array $data
|
|
|
+ * @return bool
|
|
|
+ * @throws BaseException
|
|
|
+ */
|
|
|
+ public function handle(array $data): bool
|
|
|
+ {
|
|
|
+ // 数据验证
|
|
|
+ $this->validate($data);
|
|
|
+ // 执行发送短信
|
|
|
+ if (!$this->sendCaptcha($data['email'])) {
|
|
|
+ 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);
|
|
|
+
|
|
|
+ $mail = new PHPMailer(true);
|
|
|
+ try {
|
|
|
+ //Server settings
|
|
|
+ $mail->SMTPDebug = SMTP::DEBUG_SERVER;//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
|
|
|
+ $mail->Host = 'smtp.163.com'; //Set the SMTP server to send through
|
|
|
+ $mail->SMTPAuth = true; //Enable SMTP authentication
|
|
|
+ $mail->Username = 'zhangdehua814@163.com'; //SMTP username
|
|
|
+ $mail->Password = 'SGPMIQCKVKGIJUGQ'; //SMTP password
|
|
|
+ $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
|
|
|
+ $mail->Port = 465; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
|
|
|
+
|
|
|
+ //Recipients
|
|
|
+ $mail->setFrom('zhangdehua814@163.com', 'Mailer');
|
|
|
+ $mail->addAddress($email, 'Gold'); //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 = 'Captcha';
|
|
|
+ $mail->Body = 'Your captcha is ' . $smsCaptcha['code'] . '.Please use it in 15 minutes';
|
|
|
+ $mail->AltBody = 'This is the Your captcha for 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__, ['errMsg' => $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_SERVER; //Enable verbose debug output
|
|
|
+ $mail->isSMTP(); //Send using SMTP
|
|
|
+ $mail->Host = 'smtp.163.com'; //Set the SMTP server to send through
|
|
|
+ $mail->SMTPAuth = true; //Enable SMTP authentication
|
|
|
+ $mail->Username = 'zhangdehua814@163.com'; //SMTP username
|
|
|
+ $mail->Password = 'SGPMIQCKVKGIJUGQ'; //SMTP password
|
|
|
+ $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
|
|
|
+ $mail->Port = 465; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
|
|
|
+
|
|
|
+ //Recipients
|
|
|
+ $mail->setFrom('zhangdehua814@163.com', 'Mailer');
|
|
|
+ $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__, ['errMsg' => $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 = '很抱歉,已超出今日最大发送次数限制';
|
|
|
+ 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 = '')
|
|
|
+ {
|
|
|
+ $localCode = Cache::get('captchaSMS.' . $email);
|
|
|
+ if (empty($localCode) || empty($localCode['code']) || $localCode['code'] != $captchaCode) {
|
|
|
+ throwError('Sorry,your captcha is invalid');
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|