Ems.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <?php
  2. namespace app\api\controller;
  3. use Throwable;
  4. use ba\Captcha;
  5. use ba\ClickCaptcha;
  6. use think\facade\Validate;
  7. use app\common\model\User;
  8. use app\common\library\Email;
  9. use app\common\controller\Frontend;
  10. use PHPMailer\PHPMailer\Exception as PHPMailerException;
  11. class Ems extends Frontend
  12. {
  13. protected array $noNeedLogin = ['send'];
  14. public function initialize(): void
  15. {
  16. parent::initialize();
  17. }
  18. /**
  19. * 发送邮件
  20. * event 事件:user_register=用户注册,user_change_email=用户修改邮箱,user_retrieve_pwd=用户找回密码,user_email_verify=验证账户
  21. * 不同的事件,会自动做各种必要检查,其中 验证账户 要求用户输入当前密码才能发送验证码邮件
  22. * @throws Throwable
  23. */
  24. public function send(): void
  25. {
  26. $params = $this->request->post(['email', 'event', 'captchaId', 'captchaInfo']);
  27. $mail = new Email();
  28. if (!$mail->configured) {
  29. $this->error(__('Mail sending service unavailable'));
  30. }
  31. $validate = Validate::rule([
  32. 'email' => 'require|email',
  33. 'event' => 'require',
  34. 'captchaId' => 'require',
  35. 'captchaInfo' => 'require'
  36. ])->message([
  37. 'email' => 'email format error',
  38. 'event' => 'Parameter error',
  39. 'captchaId' => 'Captcha error',
  40. 'captchaInfo' => 'Captcha error'
  41. ]);
  42. if (!$validate->check($params)) {
  43. $this->error(__($validate->getError()));
  44. }
  45. // 检查验证码
  46. $captchaObj = new Captcha();
  47. $clickCaptcha = new ClickCaptcha();
  48. if (!$clickCaptcha->check($params['captchaId'], $params['captchaInfo'])) {
  49. $this->error(__('Captcha error'));
  50. }
  51. // 检查频繁发送
  52. $captcha = $captchaObj->getCaptchaData($params['email'] . $params['event']);
  53. if ($captcha && time() - $captcha['create_time'] < 60) {
  54. $this->error(__('Frequent email sending'));
  55. }
  56. // 检查邮箱
  57. $userInfo = User::where('email', $params['email'])->find();
  58. if ($params['event'] == 'user_register' && $userInfo) {
  59. $this->error(__('Email has been registered, please log in directly'));
  60. } elseif ($params['event'] == 'user_change_email' && $userInfo) {
  61. $this->error(__('The email has been occupied'));
  62. } elseif (in_array($params['event'], ['user_retrieve_pwd', 'user_email_verify']) && !$userInfo) {
  63. $this->error(__('Email not registered'));
  64. }
  65. // 通过邮箱验证账户
  66. if ($params['event'] == 'user_email_verify') {
  67. if (!$this->auth->isLogin()) {
  68. $this->error(__('Please login first'));
  69. }
  70. if ($this->auth->email != $params['email']) {
  71. $this->error(__('Please use the account registration email to send the verification code'));
  72. }
  73. // 验证账户密码
  74. $password = $this->request->post('password');
  75. if ($this->auth->password != encrypt_password($password, $this->auth->salt)) {
  76. $this->error(__('Password error'));
  77. }
  78. }
  79. // 生成一个验证码
  80. $code = $captchaObj->create($params['email'] . $params['event']);
  81. $subject = __($params['event']) . '-' . get_sys_config('site_name');
  82. $body = __('Your verification code is: %s', [$code]);
  83. try {
  84. $mail->isSMTP();
  85. $mail->addAddress($params['email']);
  86. $mail->isHTML();
  87. $mail->setSubject($subject);
  88. $mail->Body = $body;
  89. $mail->send();
  90. } catch (PHPMailerException) {
  91. $this->error($mail->ErrorInfo);
  92. }
  93. $this->success(__('Mail sent successfully~'));
  94. }
  95. }