diff --git a/app/admin/controller/BaseController.php b/app/admin/controller/BaseController.php index 66a929f..d83fcf2 100644 --- a/app/admin/controller/BaseController.php +++ b/app/admin/controller/BaseController.php @@ -128,4 +128,5 @@ abstract class BaseController extends Base return $v->failException(true)->check($data); } + } \ No newline at end of file diff --git a/app/index/controller/BaseController.php b/app/index/controller/BaseController.php index 96ee0e7..9aed009 100644 --- a/app/index/controller/BaseController.php +++ b/app/index/controller/BaseController.php @@ -8,6 +8,8 @@ use think\facade\View; use think\facade\Request; use think\facade\Db; use app\service\VisitStatsService; +use PHPMailer\PHPMailer\PHPMailer; +use app\index\model\MailConfig; /** * 前台控制器基础类 @@ -144,4 +146,76 @@ abstract class BaseController 'wait' => $wait ]); } + + + protected function sendEmail($to, $content, $title) + { + // 获取邮件配置 + $mailConfig = MailConfig::where('id', 1)->find(); + if (!$mailConfig) { + return '邮件配置不存在'; + } + + //实例化PHPMailer核心类 + $mail = new PHPMailer(); + + //是否启用smtp的debug进行调试 开发环境建议开启 生产环境注释掉即可 默认关闭debug调试模式 + $mail->SMTPDebug = 0; + + //使用smtp鉴权方式发送邮件 + $mail->isSMTP(); + + //smtp需要鉴权 这个必须是true + $mail->SMTPAuth = true; + + //链接qq域名邮箱的服务器地址 + $mail->Host = $mailConfig['smtp_host']; + + //设置使用ssl加密方式登录鉴权 + $mail->SMTPSecure = 'ssl'; + + //设置ssl连接smtp服务器的远程服务器端口号 + $mail->Port = $mailConfig['smtp_port']; + + //设置发件人的主机域 + $mail->Hostname = $mailConfig['smtp_email']; + + //设置发送的邮件的编码 + $mail->CharSet = 'UTF-8'; + + //设置发件人姓名(昵称) + $mail->FromName = $mailConfig['smtp_name']; + + //smtp登录的账号 + $mail->Username = $mailConfig['smtp_email']; + + //smtp登录的密码 + $mail->Password = $mailConfig['smtp_password']; + + //设置发件人邮箱地址 + $mail->setFrom($mailConfig['smtp_email'], $mailConfig['smtp_name']); + + //邮件正文是否为html编码 + $mail->isHTML(true); + + //设置收件人邮箱地址 + $mail->addAddress($to); + + //添加该邮件的主题 + $mail->Subject = $title; + + //添加邮件正文 + $mail->Body = $content; + + try { + $status = $mail->send(); + if ($status) { + return '发送成功'; + } else { + return '发送失败'; + } + } catch (\Exception $e) { + return '发送失败:' . $e->getMessage(); + } + } } \ No newline at end of file diff --git a/app/index/controller/IndexController.php b/app/index/controller/IndexController.php index 993fd9c..a9e2e56 100644 --- a/app/index/controller/IndexController.php +++ b/app/index/controller/IndexController.php @@ -13,7 +13,7 @@ use app\index\model\Resources\ResourcesCategory; use app\index\model\Articles\ArticlesCategory; use app\index\model\Resources\Resources; use app\index\model\Articles\Articles; -use PHPMailer\PHPMailer\PHPMailer; +use app\index\model\MailConfig; class IndexController extends BaseController @@ -343,79 +343,5 @@ class IndexController extends BaseController ]); } - function sendEmail($email, $to, $content, $title) - { - - // 邮件内容 - - //实例化PHPMailer核心类 - $mail = new PHPMailer(); - - //是否启用smtp的debug进行调试 开发环境建议开启 生产环境注释掉即可 默认关闭debug调试模式 - $mail->SMTPDebug = 1; - - //使用smtp鉴权方式发送邮件 - $mail->isSMTP(); - - //smtp需要鉴权 这个必须是true - $mail->SMTPAuth = true; - - //链接qq域名邮箱的服务器地址 - $mail->Host = 'smtp.qq.com';//如果是163邮箱 就把qq换成163 - - //设置使用ssl加密方式登录鉴权 - $mail->SMTPSecure = 'ssl'; - - //设置ssl连接smtp服务器的远程服务器端口号,以前的默认是25,但是现在新的好像已经不可用了 可选465或587 - $mail->Port = 465; - - //设置smtp的helo消息头 这个可有可无 内容任意 - // $mail->Helo = 'Hello smtp.qq.com Server'; - - //设置发件人的主机域 可有可无 默认为localhost 内容任意,建议使用你的域名 - $mail->Hostname = $email; - - //设置发送的邮件的编码 可选GB2312 我喜欢utf-8 据说utf8在某些客户端收信下会乱码 - $mail->CharSet = 'UTF-8'; - - //设置发件人姓名(昵称) 任意内容,显示在收件人邮件的发件人邮箱地址前的发件人姓名 - $mail->FromName = '学创网络'; - - //smtp登录的账号 这里填入字符串格式的qq号即可 - $mail->Username = $email; - - //smtp登录的密码 使用qq邮箱生成的授权码(qq邮箱生成授权码参考网址:http://www.huochewu.com/show_1609305/) - $mail->Password = ''; - - //设置发件人邮箱地址 这里填入上述提到的“发件人邮箱” - $mail->From = $email; - - //邮件正文是否为html编码 注意此处是一个方法 不再是属性 true或false - $mail->isHTML(true); - - //设置收件人邮箱地址 该方法有两个参数 第一个参数为收件人邮箱地址 第二参数为给该地址设置的昵称 不同的邮箱系统会自动进行处理变动 这里第二个参数的意义不大 - $mail->addAddress($to, '666'); - - //添加多个收件人 则多次调用方法即可 - // $mail->addAddress('xxx@163.com',''); - - //添加该邮件的主题 - $mail->Subject = $title; - - //添加邮件正文 上方将isHTML设置成了true,则可以是完整的html字符串 如:使用file_get_contents函数读取本地的html文件 - $mail->Body = $content; - - //为该邮件添加附件 该方法也有两个参数 第一个参数为附件存放的目录(相对目录、或绝对目录均可) 第二参数为在邮件附件中该附件的名称 - // $mail->addAttachment('./d.jpg','mm.jpg'); - //同样该方法可以多次调用 上传多个附件 - // $mail->addAttachment('./Jlib-1.1.0.js','Jlib.js'); - $status = $mail->send(); - //简单的判断与提示信息 - if ($status) { - return '发送成功'; - } else { - return '发送失败'; - } - - } + } diff --git a/app/index/controller/UserController.php b/app/index/controller/UserController.php index c183164..3bbfcb4 100644 --- a/app/index/controller/UserController.php +++ b/app/index/controller/UserController.php @@ -2,10 +2,12 @@ namespace app\index\controller; use think\Controller; -use app\index\model\User; +use app\index\model\Users; use think\facade\Redirect; use \think\facade\Log; use \think\facade\Cache; +use PHPMailer\PHPMailer\PHPMailer; +use think\Response; class UserController extends BaseController { @@ -37,105 +39,57 @@ class UserController extends BaseController { if ($this->request->isPost()) { $data = $this->request->post(); - $type = $data['type'] ?? 'account'; // 注册类型:account-账号密码,phone-手机号,wechat-微信 try { - switch ($type) { - case 'account': - // 账号密码注册 - $validate = validate([ - 'username' => 'require|min:3|max:20|unique:user', - 'password' => 'require|min:6|max:20', - 'confirm_password' => 'require|confirm:password' - ], [ - 'username.require' => '用户名不能为空', - 'username.min' => '用户名长度不能小于3个字符', - 'username.max' => '用户名长度不能超过20个字符', - 'username.unique' => '用户名已存在', - 'password.require' => '密码不能为空', - 'password.min' => '密码长度不能小于6个字符', - 'password.max' => '密码长度不能超过20个字符', - 'confirm_password.require' => '确认密码不能为空', - 'confirm_password.confirm' => '两次输入的密码不一致' - ]); + // 验证数据 + $validate = validate([ + 'account' => 'require|email|unique:users', + 'code' => 'require|number|length:6', + 'password' => 'require|min:6|max:20', + 'repassword' => 'require|confirm:password' + ], [ + 'account.require' => '账户不能为空', + 'account.email' => '邮箱格式不正确', + 'account.unique' => '该邮箱已注册', + 'code.require' => '验证码不能为空', + 'code.number' => '验证码必须为数字', + 'code.length' => '验证码长度必须为6位', + 'password.require' => '密码不能为空', + 'password.min' => '密码长度不能小于6个字符', + 'password.max' => '密码长度不能超过20个字符', + 'repassword.require' => '确认密码不能为空', + 'repassword.confirm' => '两次输入的密码不一致' + ]); - if (!$validate->check($data)) { - return json(['code' => 0, 'msg' => $validate->getError()]); - } - - $user = new UserModel; - $user->username = $data['username']; - $user->password = password_hash($data['password'], PASSWORD_DEFAULT); - $user->create_time = time(); - $user->save(); - - return json(['code' => 1, 'msg' => '注册成功']); - - case 'phone': - // 手机号注册 - $validate = validate([ - 'phone' => 'require|mobile|unique:user', - 'code' => 'require|number|length:6' - ], [ - 'phone.require' => '手机号不能为空', - 'phone.mobile' => '手机号格式不正确', - 'phone.unique' => '该手机号已注册', - 'code.require' => '验证码不能为空', - 'code.number' => '验证码必须为数字', - 'code.length' => '验证码长度必须为6位' - ]); - - if (!$validate->check($data)) { - return json(['code' => 0, 'msg' => $validate->getError()]); - } - - // 验证短信验证码 - $smsCode = cache('sms_code_' . $data['phone']); - if (!$smsCode || $smsCode != $data['code']) { - return json(['code' => 0, 'msg' => '验证码错误或已过期']); - } - - $user = new UserModel; - $user->phone = $data['phone']; - $user->create_time = time(); - $user->save(); - - // 清除验证码缓存 - cache('sms_code_' . $data['phone'], null); - - return json(['code' => 1, 'msg' => '注册成功']); - - case 'wechat': - // 微信注册 - $validate = validate([ - 'openid' => 'require|unique:user' - ], [ - 'openid.require' => '微信授权失败', - 'openid.unique' => '该微信账号已注册' - ]); - - if (!$validate->check($data)) { - return json(['code' => 0, 'msg' => $validate->getError()]); - } - - $user = new UserModel; - $user->openid = $data['openid']; - $user->nickname = $data['nickname'] ?? ''; - $user->avatar = $data['avatar'] ?? ''; - $user->create_time = time(); - $user->save(); - - return json(['code' => 1, 'msg' => '注册成功']); - - default: - return json(['code' => 0, 'msg' => '注册类型错误']); + if (!$validate->check($data)) { + return json(['code' => 1, 'msg' => $validate->getError()]); } + + // 验证邮箱验证码 + $emailCode = cache('email_code_' . $data['account']); + if (!$emailCode || $emailCode != $data['code']) { + return json(['code' => 1, 'msg' => '验证码错误或已过期']); + } + + // 创建用户 + $user = new Users; + $user->account = $data['account']; + $user->password = md5($data['password']); + $user->name = $this->generateRandomName(); + $user->create_time = time(); + $user->save(); + + // 清除验证码缓存 + cache('email_code_' . $data['account'], null); + + return json(['code' => 0, 'msg' => '注册成功']); + } catch (\Exception $e) { - return json(['code' => 0, 'msg' => '注册失败:' . $e->getMessage()]); + return json(['code' => 1, 'msg' => '注册失败:' . $e->getMessage()]); } } - return $this->fetch(); + return view('register'); } /** @@ -156,12 +110,18 @@ class UserController extends BaseController return redirect('login'); } + // 生成随机用户名 + private function generateRandomName() + { + return '云朵_' . mt_rand(100000, 999999); + } + // 发送短信验证码 public function sendSmsCode() { if ($this->request->isPost()) { $phone = $this->request->post('phone'); - + // 验证手机号 $validate = validate([ 'phone' => 'require|mobile|unique:user' @@ -177,22 +137,22 @@ class UserController extends BaseController // 生成6位随机验证码 $code = mt_rand(100000, 999999); - + // 这里应该调用短信服务商API发送验证码 // 示例代码,实际使用时需要替换为真实的短信发送逻辑 try { // TODO: 调用短信服务商API发送验证码 // $result = sendSms($phone, $code); - + // 将验证码保存到缓存,有效期5分钟 cache('sms_code_' . $phone, $code, 300); - + return json(['code' => 1, 'msg' => '验证码发送成功']); } catch (\Exception $e) { return json(['code' => 0, 'msg' => '验证码发送失败:' . $e->getMessage()]); } } - + return json(['code' => 0, 'msg' => '非法请求']); } @@ -208,7 +168,7 @@ class UserController extends BaseController // 这里应该调用微信API获取用户信息 // 示例代码,实际使用时需要替换为真实的微信API调用逻辑 // $wechatUser = getWechatUserInfo($code); - + // 模拟获取到的微信用户信息 $wechatUser = [ 'openid' => 'test_openid_' . time(), @@ -217,7 +177,7 @@ class UserController extends BaseController ]; // 检查用户是否已注册 - $user = UserModel::where('openid', $wechatUser['openid'])->find(); + $user = Users::where('openid', $wechatUser['openid'])->find(); if ($user) { // 已注册,直接登录 session('user_id', $user->id); @@ -234,4 +194,45 @@ class UserController extends BaseController return json(['code' => 0, 'msg' => '微信授权失败:' . $e->getMessage()]); } } + + // 发送邮箱验证码 + public function sendEmailCode() + { + // 设置响应头 + header('Content-Type: application/json; charset=utf-8'); + + if (!$this->request->isPost()) { + return json(['code' => 1, 'msg' => '请求方法无效']); + } + + $email = $this->request->post('account'); + if (empty($email)) { + return json(['code' => 1, 'msg' => '邮箱不能为空']); + } + + // 验证邮箱格式 + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + return json(['code' => 1, 'msg' => '邮箱格式不正确']); + } + + // 检查邮箱是否已注册 + $exists = Users::where('account', $email)->find(); + if ($exists) { + return json(['code' => 1, 'msg' => '该邮箱已注册']); + } + + // 生成6位随机验证码 + $code = mt_rand(100000, 999999); + + // 发送验证码邮件 + $result = parent::sendEmail($email, "您的注册验证码是:{$code},有效期为5分钟。", '注册验证码'); + + if ($result === '发送成功') { // 修改这里的判断条件 + // 将验证码存入缓存,有效期5分钟 + cache('email_code_' . $email, $code, 300); + return json(['code' => 0, 'msg' => '验证码已发送']); + } else { + return json(['code' => 1, 'msg' => '发送失败:' . $result]); + } + } } diff --git a/app/index/model/MailConfig.php b/app/index/model/MailConfig.php new file mode 100644 index 0000000..2ced56a --- /dev/null +++ b/app/index/model/MailConfig.php @@ -0,0 +1,8 @@ + -
-
+
+
+
or
+
+ 注册 +
@@ -236,6 +240,15 @@ }); }); + + \ No newline at end of file diff --git a/app/index/view/user/register.php b/app/index/view/user/register.php index 6da29d4..93ea72f 100644 --- a/app/index/view/user/register.php +++ b/app/index/view/user/register.php @@ -124,13 +124,7 @@
- -
-
-
-
-
@@ -163,7 +157,7 @@
@@ -171,23 +165,76 @@ layui.use(['form', 'layer'], function () { var form = layui.form; var layer = layui.layer; + var $ = layui.$; + // 注册表单提交 form.on('submit(register)', function (data) { - console.log(data.field); + $.ajax({ + url: '{:url("index/user/register")}', + type: 'POST', + data: data.field, + success: function (res) { + if (res.code === 0) { + layer.msg('注册成功', { + icon: 1, + time: 1000 + }, function () { + window.location.href = '{:url("index/user/login")}'; + }); + } else { + layer.msg(res.msg); + } + }, + error: function () { + layer.msg('网络错误,请稍后重试'); + } + }); return false; }); + // 获取验证码按钮点击事件 document.getElementById('getCode').addEventListener('click', function () { - var email = document.querySelector('input[name="email"]').value; - if (!email) { + var account = document.querySelector('input[name="account"]').value; + if (!account) { layer.msg('请先输入邮箱地址'); return; } + // 发送邮箱验证码请求 - console.log('发送邮箱验证码到:' + email); + $.ajax({ + url: '{:url("index/user/sendEmailCode")}', + type: 'POST', + data: { account: account }, + dataType: 'json', // 添加这行 + success: function (res) { + if (res.code === 0) { + layer.msg('验证码已发送,请查收邮件'); + // 禁用按钮60秒 + var btn = document.getElementById('getCode'); + var countdown = 60; + btn.disabled = true; + var timer = setInterval(function () { + if (countdown > 0) { + btn.innerHTML = countdown + '秒后重试'; + countdown--; + } else { + btn.disabled = false; + btn.innerHTML = '获取验证码'; + clearInterval(timer); + } + }, 1000); + } else { + layer.msg(res.msg); + } + }, + error: function (xhr, status, error) { + console.log(xhr.responseText); // 添加调试信息 + layer.msg('网络错误,请稍后重试'); + } + }); }); }); - + \ No newline at end of file