Browse Source

1.通过邮件发送验证码进行注册
2.优化邮件投递记录

admin 7 years ago
parent
commit
7f063155e0

+ 29 - 4
app/Components/Helpers.php

@@ -109,9 +109,9 @@ class Helpers
     }
 
     /**
-     * 写入邮件发送日志
+     * 添加邮件投递日志
      *
-     * @param int    $user_id 用户ID
+     * @param string $address 收信地址
      * @param string $title   标题
      * @param string $content 内容
      * @param int    $status  投递状态
@@ -119,10 +119,35 @@ class Helpers
      *
      * @return int
      */
-    public static function addEmailLog($user_id, $title, $content, $status = 1, $error = '')
+    public static function addEmailLog($address, $title, $content, $status = 1, $error = '')
     {
         $log = new EmailLog();
-        $log->user_id = $user_id;
+        $log->type = 1;
+        $log->address = $address;
+        $log->title = $title;
+        $log->content = $content;
+        $log->status = $status;
+        $log->error = $error;
+        $log->created_at = date('Y-m-d H:i:s');
+
+        return $log->save();
+    }
+
+    /**
+     * 添加serverChan投递日志
+     *
+     * @param string $title   标题
+     * @param string $content 内容
+     * @param int    $status  投递状态
+     * @param string $error   投递失败时记录的异常信息
+     *
+     * @return int
+     */
+    public static function addServerChanLog($title, $content, $status = 1, $error = '')
+    {
+        $log = new EmailLog();
+        $log->type = 2;
+        $log->address = 'admin';
         $log->title = $title;
         $log->content = $content;
         $log->status = $status;

+ 2 - 2
app/Components/Namesilo.php

@@ -89,13 +89,13 @@ class Namesilo
 
             // 出错
             if (empty($result['namesilo']) || $result['namesilo']['reply']['code'] != 300 || $result['namesilo']['reply']['detail'] != 'success') {
-                Helpers::addEmailLog(1, '[Namesilo API] - [' . $operation . ']', $content, 0, $result['namesilo']['reply']['detail']);
+                Helpers::addServerChanLog('[Namesilo API] - [' . $operation . ']', $content, 0, $result['namesilo']['reply']['detail']);
             }
 
             return $result['namesilo']['reply'];
         } catch (\Exception $e) {
             Log::error('CURL请求失败:' . $e->getMessage() . ' --- ' . $e->getLine());
-            Helpers::addEmailLog(1, '[Namesilo API] - [' . $operation . ']', $content, 0, $e->getMessage());
+            Helpers::addServerChanLog('[Namesilo API] - [' . $operation . ']', $content, 0, $e->getMessage());
 
             return false;
         }

+ 2 - 2
app/Components/ServerChan.php

@@ -39,9 +39,9 @@ class ServerChan
 
             $result = json_decode($response->getBody());
             if (!$result->errno) {
-                Helpers::addEmailLog(1, '[ServerChan]' . $title, $content);
+                Helpers::addServerChanLog($title, $content);
             } else {
-                Helpers::addEmailLog(1, '[ServerChan]' . $title, $content, 0, $result->errmsg);
+                Helpers::addServerChanLog($title, $content, 0, $result->errmsg);
             }
         } catch (RequestException $e) {
             Log::error(Psr7\str($e->getRequest()));

+ 2 - 2
app/Console/Commands/AutoCheckNodeStatus.php

@@ -167,9 +167,9 @@ class AutoCheckNodeStatus extends Command
         if (self::$systemConfig['is_node_crash_warning'] && self::$systemConfig['crash_warning_email']) {
             try {
                 Mail::to(self::$systemConfig['crash_warning_email'])->send(new nodeCrashWarning(self::$systemConfig['website_name'], $nodeName, $nodeServer));
-                Helpers::addEmailLog(1, $title, $content);
+                Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $title, $content);
             } catch (\Exception $e) {
-                Helpers::addEmailLog(1, $title, $content, 0, $e->getMessage());
+                Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $title, $content, 0, $e->getMessage());
             }
         }
     }

+ 12 - 2
app/Console/Commands/AutoJob.php

@@ -10,6 +10,7 @@ use App\Http\Models\ReferralLog;
 use App\Http\Models\SsNode;
 use App\Http\Models\SsNodeLabel;
 use App\Http\Models\UserBalanceLog;
+use App\Http\Models\VerifyCode;
 use App\Mail\sendUserInfo;
 use Illuminate\Console\Command;
 use App\Http\Models\Coupon;
@@ -45,6 +46,9 @@ class AutoJob extends Command
     {
         $jobStartTime = microtime(true);
 
+        // 注册验证码自动置无效
+        $this->expireVerifyCode();
+
         // 优惠券到期自动置无效
         $this->expireCoupon();
 
@@ -78,6 +82,12 @@ class AutoJob extends Command
         Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
     }
 
+    // 注册验证码自动置无效
+    private function expireVerifyCode()
+    {
+        VerifyCode::query()->where('status', 0)->where('created_at', '>=', date('Y-m-d H:i:s', strtotime("-10 minutes")))->update(['status' => 2]);
+    }
+
     // 优惠券到期自动置无效
     private function expireCoupon()
     {
@@ -454,9 +464,9 @@ class AutoJob extends Command
 
                             try {
                                 Mail::to($order->email)->send(new sendUserInfo(self::$systemConfig['website_name'], $content));
-                                Helpers::addEmailLog($order->user_id, $title, json_encode($content));
+                                Helpers::addEmailLog($order->email, $title, json_encode($content));
                             } catch (\Exception $e) {
-                                Helpers::addEmailLog($order->user_id, $title, json_encode($content), 0, $e->getMessage());
+                                Helpers::addEmailLog($order->email, $title, json_encode($content), 0, $e->getMessage());
                             }
                         }
 

+ 4 - 4
app/Console/Commands/UserExpireAutoWarning.php

@@ -55,9 +55,9 @@ class UserExpireAutoWarning extends Command
 
                 try {
                     Mail::to($user->username)->send(new userExpireWarningToday(self::$systemConfig['website_name']));
-                    Helpers::addEmailLog($user->id, $title, $content);
+                    Helpers::addEmailLog($user->username, $title, $content);
                 } catch (\Exception $e) {
-                    Helpers::addEmailLog($user->id, $title, $content, 0, $e->getMessage());
+                    Helpers::addEmailLog($user->username, $title, $content, 0, $e->getMessage());
                 }
             } elseif ($lastCanUseDays > 0 && $lastCanUseDays <= self::$systemConfig['expire_days']) {
                 $title = '账号过期提醒';
@@ -65,9 +65,9 @@ class UserExpireAutoWarning extends Command
 
                 try {
                     Mail::to($user->username)->send(new userExpireWarning(self::$systemConfig['website_name'], $lastCanUseDays));
-                    Helpers::addEmailLog($user->id, $title, $content);
+                    Helpers::addEmailLog($user->username, $title, $content);
                 } catch (\Exception $e) {
-                    Helpers::addEmailLog($user->id, $title, $content, 0, $e->getMessage());
+                    Helpers::addEmailLog($user->username, $title, $content, 0, $e->getMessage());
                 }
             }
         }

+ 2 - 2
app/Console/Commands/UserTrafficAutoWarning.php

@@ -53,9 +53,9 @@ class UserTrafficAutoWarning extends Command
 
                 try {
                     Mail::to($user->username)->send(new userTrafficWarning(self::$systemConfig['website_name'], $usedPercent));
-                    Helpers::addEmailLog($user->id, $title, $content);
+                    Helpers::addEmailLog($user->username, $title, $content);
                 } catch (\Exception $e) {
-                    Helpers::addEmailLog($user->id, $title, $content, 0, $e->getMessage());
+                    Helpers::addEmailLog($user->username, $title, $content, 0, $e->getMessage());
                 }
             }
         }

+ 9 - 0
app/Http/Controllers/AdminController.php

@@ -6,6 +6,7 @@ use App\Components\Helpers;
 use App\Http\Models\Article;
 use App\Http\Models\Config;
 use App\Http\Models\Country;
+use App\Http\Models\EmailLog;
 use App\Http\Models\Invite;
 use App\Http\Models\Label;
 use App\Http\Models\Level;
@@ -2328,4 +2329,12 @@ EOF;
             return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败:' . $e->getMessage()]);
         }
     }
+
+    // 邮件发送日志列表
+    public function emailLog(Request $request)
+    {
+        $view['list'] = EmailLog::query()->orderBy('id', 'desc')->paginate(15);
+
+        return Response::view('admin.emailLog', $view);
+    }
 }

+ 2 - 2
app/Http/Controllers/Api/YzyController.php

@@ -289,9 +289,9 @@ class YzyController extends Controller
 
                 try {
                     Mail::to($order->email)->send(new sendUserInfo(self::$systemConfig['website_name'], $content));
-                    Helpers::addEmailLog($order->user_id, $title, json_encode($content));
+                    Helpers::addEmailLog($order->email, $title, json_encode($content));
                 } catch (\Exception $e) {
-                    Helpers::addEmailLog($order->user_id, $title, json_encode($content), 0, $e->getMessage());
+                    Helpers::addEmailLog($order->email, $title, json_encode($content), 0, $e->getMessage());
                 }
             }
 

+ 120 - 31
app/Http/Controllers/AuthController.php

@@ -9,8 +9,10 @@ use App\Http\Models\User;
 use App\Http\Models\UserLoginLog;
 use App\Http\Models\UserLabel;
 use App\Http\Models\Verify;
+use App\Http\Models\VerifyCode;
 use App\Mail\activeUser;
 use App\Mail\resetPassword;
+use App\Mail\sendVerifyCode;
 use Illuminate\Http\Request;
 use Response;
 use Redirect;
@@ -140,6 +142,7 @@ class AuthController extends Controller
             $repassword = trim($request->get('repassword'));
             $captcha = trim($request->get('captcha'));
             $code = trim($request->get('code'));
+            $verify_code = trim($request->get('verify_code'));
             $register_token = $request->get('register_token');
             $aff = intval($request->get('aff', 0));
 
@@ -191,15 +194,6 @@ class AuthController extends Controller
                 return Redirect::back()->withInput();
             }
 
-            // 是否校验验证码
-            if (self::$systemConfig['is_captcha']) {
-                if (!Captcha::check($captcha)) {
-                    Session::flash('errorMsg', '验证码错误,请重新输入');
-
-                    return Redirect::back()->withInput();
-                }
-            }
-
             // 如果需要邀请注册
             if (self::$systemConfig['is_invite_register']) {
                 // 必须使用邀请码
@@ -220,6 +214,31 @@ class AuthController extends Controller
                 }
             }
 
+            // 如果开启注册发送验证码
+            if (self::$systemConfig['is_verify_register']) {
+                if (!$verify_code) {
+                    Session::flash('errorMsg', '请输入验证码');
+
+                    return Redirect::back()->withInput($request->except(['verify_code']));
+                } else {
+                    $verifyCode = VerifyCode::query()->where('username', $username)->where('code', $verify_code)->where('status', 0)->first();
+                    if (!$verifyCode) {
+                        Session::flash('errorMsg', '验证码不合法,可能已过期,请重试');
+
+                        return Redirect::back()->withInput($request->except(['verify_code']));
+                    }
+
+                    $verifyCode->status = 1;
+                    $verifyCode->save();
+                }
+            } elseif (self::$systemConfig['is_captcha']) { // 是否校验验证码
+                if (!Captcha::check($captcha)) {
+                    Session::flash('errorMsg', '验证码错误,请重新输入');
+
+                    return Redirect::back()->withInput($request->except(['captcha']));
+                }
+            }
+
             // 24小时内同IP注册限制
             if (self::$systemConfig['register_ip_limit']) {
                 if (Cache::has($cacheKey)) {
@@ -299,22 +318,7 @@ class AuthController extends Controller
                 \Cookie::unqueue('register_aff');
             }
 
-            // 发送邮件
-            if (self::$systemConfig['is_active_register']) {
-                // 生成激活账号的地址
-                $token = md5(self::$systemConfig['website_name'] . $username . microtime());
-                $activeUserUrl = self::$systemConfig['website_url'] . '/active/' . $token;
-                $this->addVerify($user->id, $token);
-
-                try {
-                    Mail::to($username)->send(new activeUser(self::$systemConfig['website_name'], $activeUserUrl));
-                    Helpers::addEmailLog($user->id, '注册激活', '请求地址:' . $activeUserUrl);
-                } catch (\Exception $e) {
-                    Helpers::addEmailLog($user->id, '注册激活', '请求地址:' . $activeUserUrl, 0, $e->getMessage());
-                }
-
-                Session::flash('regSuccessMsg', '注册成功:激活邮件已发送,如未收到,请查看垃圾邮箱');
-            } else {
+            if (self::$systemConfig['is_verify_register']) {
                 // 如果不需要激活,则直接给推荐人加流量
                 if ($referral_uid) {
                     $transfer_enable = self::$systemConfig['referral_traffic'] * 1048576;
@@ -324,6 +328,33 @@ class AuthController extends Controller
                 }
 
                 Session::flash('regSuccessMsg', '注册成功');
+            } else {
+                // 发送激活邮件
+                if (self::$systemConfig['is_active_register']) {
+                    // 生成激活账号的地址
+                    $token = md5(self::$systemConfig['website_name'] . $username . microtime());
+                    $activeUserUrl = self::$systemConfig['website_url'] . '/active/' . $token;
+                    $this->addVerify($user->id, $token);
+
+                    try {
+                        Mail::to($username)->send(new activeUser(self::$systemConfig['website_name'], $activeUserUrl));
+                        Helpers::addEmailLog($username, '注册激活', '请求地址:' . $activeUserUrl);
+                    } catch (\Exception $e) {
+                        Helpers::addEmailLog($username, '注册激活', '请求地址:' . $activeUserUrl, 0, $e->getMessage());
+                    }
+
+                    Session::flash('regSuccessMsg', '注册成功:激活邮件已发送,如未收到,请查看垃圾邮箱');
+                } else {
+                    // 如果不需要激活,则直接给推荐人加流量
+                    if ($referral_uid) {
+                        $transfer_enable = self::$systemConfig['referral_traffic'] * 1048576;
+
+                        User::query()->where('id', $referral_uid)->increment('transfer_enable', $transfer_enable);
+                        User::query()->where('id', $referral_uid)->update(['enable' => 1]);
+                    }
+
+                    Session::flash('regSuccessMsg', '注册成功');
+                }
             }
 
             return Redirect::to('login');
@@ -388,10 +419,10 @@ class AuthController extends Controller
             $content = '请求地址:' . $resetPasswordUrl;
 
             try {
-                Mail::to($user->username)->send(new resetPassword(self::$systemConfig['website_name'], $resetPasswordUrl));
-                Helpers::addEmailLog($user->id, $title, $content);
+                Mail::to($username)->send(new resetPassword(self::$systemConfig['website_name'], $resetPasswordUrl));
+                Helpers::addEmailLog($username, $title, $content);
             } catch (\Exception $e) {
-                Helpers::addEmailLog($user->id, $title, $content, 0, $e->getMessage());
+                Helpers::addEmailLog($username, $title, $content, 0, $e->getMessage());
             }
 
             Cache::put('resetPassword_' . md5($username), $resetTimes + 1, 1440);
@@ -537,10 +568,10 @@ class AuthController extends Controller
             $content = '请求地址:' . $activeUserUrl;
 
             try {
-                Mail::to($user->username)->send(new activeUser(self::$systemConfig['website_name'], $activeUserUrl));
-                Helpers::addEmailLog($user->id, $title, $content);
+                Mail::to($username)->send(new activeUser(self::$systemConfig['website_name'], $activeUserUrl));
+                Helpers::addEmailLog($username, $title, $content);
             } catch (\Exception $e) {
-                Helpers::addEmailLog($user->id, $title, $content, 0, $e->getMessage());
+                Helpers::addEmailLog($username, $title, $content, 0, $e->getMessage());
             }
 
             Cache::put('activeUser_' . md5($username), $activeTimes + 1, 1440);
@@ -609,6 +640,54 @@ class AuthController extends Controller
         return Response::view('auth.active');
     }
 
+    // 发送注册验证码
+    public function sendCode(Request $request)
+    {
+        $username = trim($request->get('username'));
+
+        if (!$username) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '请输入用户名']);
+        }
+
+        // 校验账号合法性
+        if (false === filter_var($username, FILTER_VALIDATE_EMAIL)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '用户名必须是合法邮箱,请重新输入']);
+        }
+
+        $user = User::query()->where('username', $username)->first();
+        if ($user) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '用户已存在,无需注册,如果忘记密码请找回密码']);
+        }
+
+        // 是否开启注册发送验证码
+        if (!self::$systemConfig['is_verify_register']) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '系统未启用通过验证码注册']);
+        }
+
+        // 防刷机制
+        if (Cache::has('send_verify_code_' . md5(getClientIP()))) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '系统已开启防刷机制,请勿频繁请求']);
+        }
+
+        // 发送邮件
+        $code = makeRandStr(6, true);
+        $title = '发送注册验证码';
+        $content = '验证码:' . $code;
+
+        try {
+            Mail::to($username)->send(new sendVerifyCode($code));
+            Helpers::addEmailLog($username, $title, $content);
+        } catch (\Exception $e) {
+            Helpers::addEmailLog($username, $title, $content, 0, $e->getMessage());
+        }
+
+        $this->addVerifyCode($username, $code);
+
+        Cache::put('send_verify_code_' . md5(getClientIP()), getClientIP(), 1);
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '验证码已发送']);
+    }
+
     // 公开的邀请码列表
     public function free(Request $request)
     {
@@ -711,4 +790,14 @@ class AuthController extends Controller
         $verify->status = 0;
         $verify->save();
     }
+
+    // 生成注册验证码
+    private function addVerifyCode($username, $code)
+    {
+        $verify = new VerifyCode();
+        $verify->username = $username;
+        $verify->code = $code;
+        $verify->status = 0;
+        $verify->save();
+    }
 }

+ 0 - 25
app/Http/Controllers/EmailLogController.php

@@ -1,25 +0,0 @@
-<?php
-
-namespace App\Http\Controllers;
-
-use App\Http\Models\EmailLog;
-use Illuminate\Http\Request;
-use Response;
-
-/**
- * 邮件发送日志控制器
- * Class LoginController
- *
- * @package App\Http\Controllers
- */
-class EmailLogController extends Controller
-{
-    // 邮件发送日志列表
-    public function logList(Request $request)
-    {
-        $view['list'] = EmailLog::query()->with('user')->orderBy('id', 'desc')->paginate(15);
-
-        return Response::view('emailLog.logList', $view);
-    }
-
-}

+ 6 - 6
app/Http/Controllers/TicketController.php

@@ -68,17 +68,17 @@ class TicketController extends Controller
                     if (self::$systemConfig['crash_warning_email']) {
                         try {
                             Mail::to(self::$systemConfig['crash_warning_email'])->send(new replyTicket(self::$systemConfig['website_name'], $title, $content));
-                            Helpers::addEmailLog(1, $title, $content);
+                            Helpers::addServerChanLog($title, $content);
                         } catch (\Exception $e) {
-                            Helpers::addEmailLog(1, $title, $content, 0, $e->getMessage());
+                            Helpers::addServerChanLog($title, $content, 0, $e->getMessage());
                         }
                     }
                 } else {
                     try {
                         Mail::to($ticket->user->username)->send(new replyTicket(self::$systemConfig['website_name'], $title, $content));
-                        Helpers::addEmailLog($ticket->user_id, $title, $content);
+                        Helpers::addEmailLog($ticket->user->username, $title, $content);
                     } catch (\Exception $e) {
-                        Helpers::addEmailLog($ticket->user_id, $title, $content, 0, $e->getMessage());
+                        Helpers::addEmailLog($ticket->user->username, $title, $content, 0, $e->getMessage());
                     }
                 }
 
@@ -122,9 +122,9 @@ class TicketController extends Controller
         // 发邮件通知用户
         try {
             Mail::to($ticket->user->username)->send(new closeTicket(self::$systemConfig['website_name'], $title, $content));
-            Helpers::addEmailLog($ticket->user_id, $title, $content);
+            Helpers::addEmailLog($ticket->user->username, $title, $content);
         } catch (\Exception $e) {
-            Helpers::addEmailLog($ticket->user_id, $title, $content, 0, $e->getMessage());
+            Helpers::addEmailLog($ticket->user->username, $title, $content, 0, $e->getMessage());
         }
 
         return Response::json(['status' => 'success', 'data' => '', 'message' => '关闭成功']);

+ 4 - 4
app/Http/Controllers/UserController.php

@@ -422,9 +422,9 @@ class UserController extends Controller
             if (self::$systemConfig['crash_warning_email']) {
                 try {
                     Mail::to(self::$systemConfig['crash_warning_email'])->send(new newTicket(self::$systemConfig['website_name'], $emailTitle, $content));
-                    Helpers::addEmailLog(1, $emailTitle, $content);
+                    Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $emailTitle, $content);
                 } catch (\Exception $e) {
-                    Helpers::addEmailLog(1, $emailTitle, $content, 0, $e->getMessage());
+                    Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $emailTitle, $content, 0, $e->getMessage());
                 }
             }
 
@@ -471,9 +471,9 @@ class UserController extends Controller
                 if (self::$systemConfig['crash_warning_email']) {
                     try {
                         Mail::to(self::$systemConfig['crash_warning_email'])->send(new replyTicket(self::$systemConfig['website_name'], $title, $content));
-                        Helpers::addEmailLog(1, $title, $content);
+                        Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $title, $content);
                     } catch (\Exception $e) {
-                        Helpers::addEmailLog(1, $title, $content, 0, $e->getMessage());
+                        Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $title, $content, 0, $e->getMessage());
                     }
                 }
 

+ 0 - 4
app/Http/Models/EmailLog.php

@@ -18,8 +18,4 @@ class EmailLog extends Model
     protected $primaryKey = 'id';
     public $timestamps = false;
 
-    function user()
-    {
-        return $this->hasOne(User::class, 'id', 'user_id');
-    }
 }

+ 1 - 1
app/Http/Models/Verify.php

@@ -5,7 +5,7 @@ namespace App\Http\Models;
 use Illuminate\Database\Eloquent\Model;
 
 /**
- * 验证
+ * 注册时的验证激活地址
  * Class Verify
  *
  * @package App\Http\Models

+ 19 - 0
app/Http/Models/VerifyCode.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 注册时的激活验证码
+ * Class VerifyCode
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class VerifyCode extends Model
+{
+    protected $table = 'verify_code';
+    protected $primaryKey = 'id';
+
+}

+ 27 - 0
app/Mail/sendVerifyCode.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Mail;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Mail\Mailable;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Contracts\Queue\ShouldQueue;
+
+class sendVerifyCode extends Mailable
+{
+    use Queueable, SerializesModels;
+
+    protected $code;
+
+    public function __construct($code)
+    {
+        $this->code = $code;
+    }
+
+    public function build()
+    {
+        return $this->view('emails.sendVerifyCode')->subject('发送注册验证码')->with([
+            'code' => $this->code
+        ]);
+    }
+}

+ 12 - 10
resources/views/emailLog/logList.blade.php → resources/views/admin/emailLog.blade.php

@@ -27,25 +27,27 @@
                         <div class="table-scrollable table-scrollable-borderless">
                             <table class="table table-hover table-light">
                                 <thead>
-                                <tr>
-                                    <th> # </th>
-                                    <th> 接收者 </th>
-                                    <th> 邮件类型 </th>
-                                    <th> 投递内容 </th>
-                                    <th> 投递时间 </th>
-                                    <th> 投递状态 </th>
-                                </tr>
+                                    <tr>
+                                        <th> # </th>
+                                        <th> 类型 </th>
+                                        <th> 收信地址 </th>
+                                        <th> 标题 </th>
+                                        <th> 内容 </th>
+                                        <th> 投递时间 </th>
+                                        <th> 投递状态 </th>
+                                    </tr>
                                 </thead>
                                 <tbody>
                                 @if($list->isEmpty())
                                     <tr>
-                                        <td colspan="6" style="text-align: center;">暂无数据</td>
+                                        <td colspan="7" style="text-align: center;">暂无数据</td>
                                     </tr>
                                 @else
                                     @foreach($list as $vo)
                                         <tr class="odd gradeX">
                                             <td> {{$vo->id}} </td>
-                                            <td> {{empty($vo->user) ? '【账号已删除】' : $vo->user->username}} </td>
+                                            <td> {{$vo->type == 1 ? 'Email' : 'serverChan'}} </td>
+                                            <td> {{$vo->address}} </td>
                                             <td> {{$vo->title}} </td>
                                             <td> {{$vo->content}} </td>
                                             <td> {{$vo->created_at}} </td>

+ 3 - 3
resources/views/admin/layouts.blade.php

@@ -245,7 +245,7 @@
                         </li>
                     </ul>
                 </li>
-                <li class="nav-item {{in_array(Request::path(), ['admin/decompile', 'admin/convert', 'admin/import', 'admin/trafficLog', 'admin/analysis', 'emailLog/logList', 'payment/callbackList', 'sensitiveWords/list', 'sensitiveWords/add']) ? 'active open' : ''}}">
+                <li class="nav-item {{in_array(Request::path(), ['admin/decompile', 'admin/convert', 'admin/import', 'admin/trafficLog', 'admin/analysis', 'admin/emailLog', 'payment/callbackList', 'sensitiveWords/list', 'sensitiveWords/add']) ? 'active open' : ''}}">
                     <a href="javascript:;" class="nav-link nav-toggle">
                         <i class="fa fa-wrench"></i>
                         <span class="title">工具箱</span>
@@ -282,8 +282,8 @@
                                 <span class="title">日志分析</span>
                             </a>
                         </li>
-                        <li class="nav-item {{in_array(Request::path(), ['emailLog/logList']) ? 'active open' : ''}}">
-                            <a href="{{url('emailLog/logList')}}" class="nav-link">
+                        <li class="nav-item {{in_array(Request::path(), ['admin/emailLog']) ? 'active open' : ''}}">
+                            <a href="{{url('admin/emailLog')}}" class="nav-link">
                                 <i class="fa fa-envelope-o"></i>
                                 <span class="title">邮件投递记录</span>
                             </a>

+ 22 - 0
resources/views/admin/system.blade.php

@@ -154,6 +154,13 @@
                                                                 <span class="help-block"> 如果是机器人、爬虫、代理访问网站则会抛出403错误 </span>
                                                             </div>
                                                         </div>
+                                                        <div class="col-md-6">
+                                                            <label for="is_verify_register" class="col-md-3 control-label">注册校验验证码</label>
+                                                            <div class="col-md-9">
+                                                                <input type="checkbox" class="make-switch" @if($is_verify_register) checked @endif id="is_verify_register" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
+                                                                <span class="help-block"> 注册时需要先通过邮件获取验证码方可注册,‘激活账号’失效 </span>
+                                                            </div>
+                                                        </div>
                                                     </div>
                                                 </div>
                                             </form>
@@ -940,6 +947,21 @@
             }
         });
 
+        // 启用、禁用注册校验验证码
+        $('#is_verify_register').on({
+            'switchChange.bootstrapSwitch': function(event, state) {
+                var is_verify_register = state ? 1 : 0;
+
+                $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_verify_register', value:is_verify_register}, function (ret) {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
+                });
+            }
+        });
+
         // 启用、禁用自定义端口
         $('#is_user_rand_port').on({
             'switchChange.bootstrapSwitch': function(event, state) {

+ 51 - 2
resources/views/auth/register.blade.php

@@ -81,7 +81,7 @@
             @endif
             <div class="form-group">
                 <label class="control-label visible-ie8 visible-ie9">{{trans('register.username')}}</label>
-                <input class="form-control placeholder-no-fix" type="text" autocomplete="off" placeholder="{{trans('register.username_placeholder')}}" name="username" value="{{Request::old('username')}}" required />
+                <input class="form-control placeholder-no-fix" type="text" autocomplete="off" placeholder="{{trans('register.username_placeholder')}}" name="username" id="username" value="{{Request::old('username')}}" required />
                 <input type="hidden" name="register_token" value="{{Session::get('register_token')}}" />
                 <input type="hidden" name="_token" value="{{csrf_token()}}" />
                 <input type="hidden" name="aff" value="{{Session::get('register_aff')}}" />
@@ -103,7 +103,13 @@
                     <p class="hint"> <a href="{{url('free')}}" target="_blank">{{trans('register.get_free_code')}}</a> </p>
                 @endif
             @endif
-            @if(\App\Components\Helpers::systemConfig()['is_captcha'])
+            @if(\App\Components\Helpers::systemConfig()['is_verify_register'])
+                <div class="form-group" style="margin-bottom:75px;">
+                    <label class="control-label visible-ie8 visible-ie9">验证码</label>
+                    <input class="form-control placeholder-no-fix" style="width:60%;float:left;" type="text" autocomplete="off" placeholder="验证码" name="verify_code" value="" required />
+                    <input type="button" class="btn grey" id="sendCode" value="发送" style="float:right;" onclick="sendVerifyCode()" >
+                </div>
+            @elseif(\App\Components\Helpers::systemConfig()['is_captcha'])
                 <div class="form-group" style="margin-bottom:75px;">
                     <label class="control-label visible-ie8 visible-ie9">{{trans('register.captcha')}}</label>
                     <input class="form-control placeholder-no-fix" style="width:60%;float:left;" type="text" autocomplete="off" placeholder="{{trans('register.captcha')}}" name="captcha" value="" required />
@@ -171,6 +177,49 @@
             }
         });
     }
+
+    // 发送注册验证码
+    function sendVerifyCode() {
+        var flag = true; // 请求成功与否标记
+        var token = '{{csrf_token()}}';
+        var username = $("#username").val();
+        $.ajax({
+            type: "POST",
+            url: "{{url('sendCode')}}",
+            async: false,
+            data: {_token: token, username: username},
+            dataType: 'json',
+            success: function (ret) {
+                if (ret.status == 'fail') {
+                    layer.msg(ret.message, {time: 1000});
+                    $("#sendCode").attr('disabled', false);
+                    flag = false;
+                } else {
+                    $("#sendCode").attr('disabled', true);
+                    flag = true;
+                }
+            },
+            error: function (ret) {
+                layer.msg('请求异常,请重试', {time: 1000});
+                flag = false;
+            }
+        });
+
+        // 请求成功才开始倒计时
+        if (flag) {
+            // 60秒后重新发送
+            var left_time = 60;
+            var tt = window.setInterval(function () {
+                left_time = left_time - 1;
+                if (left_time <= 0) {
+                    window.clearInterval(tt);
+                    $("#sendCode").attr('disabled', false).val('发送');
+                } else {
+                    $("#sendCode").val(left_time);
+                }
+            }, 1000);
+        }
+    }
 </script>
 
 <!-- Global site tag (gtag.js) - Google Analytics -->

+ 87 - 0
resources/views/emails/sendVerifyCode.blade.php

@@ -0,0 +1,87 @@
+<table class="body" style="Margin:0;background:#FAFAFA;border-collapse:collapse;border-spacing:0;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:19px;margin:0;padding:0;text-align:left;vertical-align:top;width:100%">
+    <tbody>
+    <tr style="padding:0;text-align:left;vertical-align:top">
+        <td class="center" align="center" valign="top" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:19px;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+            <center data-parsed="" style="min-width:580px;width:100%">
+                <table align="center" class="container no-bg float-center" style="Margin:0 auto;background:0 0;border:0;border-collapse:collapse;border-radius:3px;border-spacing:0;box-shadow:none;float:none;margin:0 auto;margin-top:20px;padding:0;text-align:center;vertical-align:top;width:580px">
+                    <tbody>
+                    <tr style="padding:0;text-align:left;vertical-align:top">
+                        <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:19px;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                            <table class="row" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+                                <tbody>
+                                <tr style="padding:0;text-align:left;vertical-align:top">
+
+                                    <th class="small-11 large-11 columns last" style="Margin:0 auto;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:19px;margin:0 auto;padding:0;padding-bottom:0;padding-left:8px;padding-right:16px;text-align:left;width:515.67px">
+                                        <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                            <tbody>
+                                            <tr style="padding:0;text-align:left;vertical-align:top">
+                                                <th style="Margin:0;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:19px;margin:0;padding:0;text-align:left">
+                                                    <h3 style="Margin:0;Margin-bottom:10px;color:inherit;font-family:Helvetica,Arial,sans-serif;font-size:28px;font-weight:400;line-height:1.3;margin:0;margin-bottom:0;padding:0;text-align:left;word-wrap:normal">
+                                                        <a href="#" style="Margin:0;color:#40253b;font-family:Helvetica,Arial,sans-serif;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left;text-decoration:none" target="_blank">
+                                                            {{\App\Components\Helpers::systemConfig()['website_name']}}
+                                                        </a>
+                                                    </h3>
+                                                </th>
+                                            </tr>
+                                            </tbody>
+                                        </table>
+                                    </th>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </td>
+                    </tr>
+                    </tbody>
+                </table>
+                <table align="center" class="container float-center" style="Margin:0 auto;background:#fefefe;border:1px solid #cdcdcd;border-collapse:collapse;border-radius:3px;border-spacing:0;float:none;margin:0 auto;margin-top:20px;padding:0;text-align:center;vertical-align:top;width:580px">
+                    <tbody>
+                    <tr style="padding:0;text-align:left;vertical-align:top">
+                        <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:19px;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                            <table class="row container-header-row" style="background-color:#5c97bd;border-collapse:collapse;border-spacing:0;color:#f3f3f3;display:table;padding:0;padding-bottom:8px;padding-top:8px;position:relative;text-align:left;vertical-align:top;width:100%">
+                                <tbody>
+                                <tr style="padding:0;text-align:left;vertical-align:top">
+                                    <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:19px;margin:0 auto;padding:0;padding-bottom:0;padding-left:16px;padding-right:16px;text-align:left;width:564px">
+                                        <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                            <tbody>
+                                            <tr style="padding:0;text-align:left;vertical-align:top">
+                                                <th style="Margin:0;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:19px;margin:0;padding:0;text-align:left">
+                                                    <h6 style="Margin:0;Margin-bottom:10px;color:#f3f3f3;font-family:Helvetica,Arial,sans-serif;font-size:18px;font-weight:400;line-height:1.3;margin:0;margin-bottom:8px;margin-top:8px;padding:0;text-align:left;word-wrap:normal">
+                                                        <a href="#" style="Margin:0;color:#f3f3f3;font-family:Helvetica,Arial,sans-serif;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left;text-decoration:none" target="_blank">
+                                                            注册账号
+                                                        </a>
+                                                    </h6>
+                                                </th>
+                                                <th class="expander" style="Margin:0;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:19px;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                                            </tr>
+                                            </tbody>
+                                        </table>
+                                    </th>
+                                </tr>
+                                </tbody>
+                            </table>
+                            <table class="row" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+                                <tbody>
+                                <tr style="padding:0;text-align:left;vertical-align:top">
+                                    <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:19px;margin:0 auto;padding:0;padding-bottom:0;padding-left:16px;padding-right:16px;text-align:left;width:564px">
+                                        <p style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%"></p>
+                                <tbody>
+                                <tr style="padding:0;text-align:left;vertical-align:top">
+                                    <th style="Margin:0;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:19px;margin:0;padding:0;text-align:left">
+                                        <div class="release" style="padding-top:5px;padding-left:20px;padding-bottom:20px;padding-right:20px;">
+                                            <p>您的验证码:<b>{{$code}}</b> (10分钟内有效)</p>
+                                        </div>
+                                    </th>
+                                    <th class="expander" style="Margin:0;color:#333;font-family:Helvetica,Arial,sans-serif;font-size:16px;font-weight:400;line-height:19px;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                                </tr>
+                                </tbody>
+                                </th></tr></tbody>
+                            </table>
+                        </td>
+                    </tr>
+                    </tbody>
+                </table>
+            </center>
+        </td>
+    </tr>
+    </tbody>
+</table>

+ 2 - 1
routes/web.php

@@ -11,6 +11,7 @@ Route::group(['middleware' => ['forbidden', 'affiliate']], function () {
     Route::any('reset/{token}', 'AuthController@reset'); // 重设密码
     Route::any('activeUser', 'AuthController@activeUser'); // 激活账号
     Route::get('active/{token}', 'AuthController@active'); // 激活账号
+    Route::post('sendCode', 'AuthController@sendCode'); // 发送注册验证码
     Route::get('free', 'AuthController@free'); // 免费邀请码
     Route::get('makePasswd', 'Controller@makePasswd'); // 生成密码
     Route::get('makeVmessId', 'Controller@makeVmessId'); // 生成VmessId
@@ -92,7 +93,7 @@ Route::group(['middleware' => ['forbidden', 'user', 'admin']], function () {
     Route::any('admin/import', 'AdminController@import'); // 数据导入
     Route::get('admin/trafficLog', 'AdminController@trafficLog'); // 流量日志
     Route::get('admin/analysis', 'AdminController@analysis'); // 日志分析
-    Route::get('emailLog/logList', 'EmailLogController@logList'); // 邮件发送日志
+    Route::get('admin/emailLog', 'AdminController@emailLog'); // 邮件发送日志
     Route::get("payment/callbackList", "PaymentController@callbackList"); // 有赞云支付回调日志
     Route::get("sensitiveWords/list", "SensitiveWordsController@sensitiveWordslist"); // 敏感词列表
     Route::post("sensitiveWords/add", "SensitiveWordsController@addSensitiveWords"); // 添加敏感词

+ 23 - 7
sql/db.sql

@@ -359,6 +359,7 @@ INSERT INTO `config` VALUES ('67', 'is_tcp_check', 0);
 INSERT INTO `config` VALUES ('68', 'tcp_check_warning_times', 3);
 INSERT INTO `config` VALUES ('69', 'is_forbid_china', 0);
 INSERT INTO `config` VALUES ('70', 'is_forbid_oversea', 0);
+INSERT INTO `config` VALUES ('71', 'is_verify_register', 0);
 
 
 -- ----------------------------
@@ -428,7 +429,21 @@ CREATE TABLE `verify` (
   `created_at` datetime DEFAULT NULL COMMENT '创建时间',
   `updated_at` datetime DEFAULT NULL COMMENT '最后更新时间',
   PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='邮件地址';
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='账号激活邮件地址';
+
+
+-- ----------------------------
+-- Table structure for `verify_code`
+-- ----------------------------
+CREATE TABLE `verify_code` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `username` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户邮箱',
+  `code` char(6) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '验证码',
+  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态:0-未使用、1-已使用、2-已失效',
+  `created_at` datetime DEFAULT NULL COMMENT '创建时间',
+  `updated_at` datetime DEFAULT NULL COMMENT '最后更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='账号激活验证码';
 
 
 -- ----------------------------
@@ -674,9 +689,10 @@ CREATE TABLE `referral_log` (
 -- ----------------------------
 CREATE TABLE `email_log` (
   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '接收者ID',
-  `title` varchar(255) DEFAULT '' COMMENT '邮件标题',
-  `content` text COMMENT '邮件内容',
+  `type` TINYINT(4) NOT NULL DEFAULT '1' COMMENT '类型:1-邮件、2-serverChan',
+  `address` VARCHAR(255) NOT NULL COMMENT '收信地址',
+  `title` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '标题',
+  `content` TEXT NOT NULL COMMENT '内容',
   `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态:1-发送成功、2-发送失败',
   `error` text COMMENT '发送失败抛出的异常信息',
   `created_at` datetime DEFAULT NULL COMMENT '创建时间',
@@ -688,9 +704,9 @@ CREATE TABLE `email_log` (
 -- Table structure for `sensitive_words`
 -- ----------------------------
 CREATE TABLE `sensitive_words` (
-	`id` INT(11) NOT NULL AUTO_INCREMENT,
-	`words` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '敏感词',
-	PRIMARY KEY (`id`)
+  `id` INT(11) NOT NULL AUTO_INCREMENT,
+  `words` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '敏感词',
+  PRIMARY KEY (`id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='敏感词';
 
 

+ 10 - 0
sql/update/20181106.sql

@@ -0,0 +1,10 @@
+-- 增加‘验证注册验证码’开关
+INSERT INTO `config` values ('71', 'is_verify_register', 0);
+
+-- user_id 字段改为 type 字段
+ALTER TABLE `email_log`
+	CHANGE COLUMN `user_id` `type` TINYINT(4) NOT NULL DEFAULT '1' COMMENT '类型:1-邮件、2-serverChan' AFTER `id`;
+
+-- 增加address字段
+ALTER TABLE `email_log`
+  ADD COLUMN `address` VARCHAR(255) NOT NULL COMMENT '收信地址' AFTER `type`;