瀏覽代碼

通知系统统合 Alpha

兔姬桑 4 年之前
父節點
當前提交
bfd3b0c5c6
共有 87 個文件被更改,包括 1697 次插入3021 次删除
  1. 35 0
      app/Channels/BarkChannel.php
  2. 38 0
      app/Channels/PushBearChannel.php
  3. 52 0
      app/Channels/ServerChanChannel.php
  4. 78 14
      app/Components/Helpers.php
  5. 0 98
      app/Components/PushNotification.php
  6. 5 2
      app/Console/Commands/AutoJob.php
  7. 27 16
      app/Console/Commands/AutoReportNode.php
  8. 15 15
      app/Console/Commands/DailyJob.php
  9. 7 21
      app/Console/Commands/NodeBlockedDetection.php
  10. 3 22
      app/Console/Commands/UserExpireAutoWarning.php
  11. 9 6
      app/Console/Commands/UserTrafficAbnormalAutoWarning.php
  12. 3 6
      app/Console/Commands/UserTrafficAutoWarning.php
  13. 3 3
      app/Http/Controllers/Admin/LogsController.php
  14. 5 45
      app/Http/Controllers/Admin/MarketingController.php
  15. 23 87
      app/Http/Controllers/Admin/SystemController.php
  16. 7 23
      app/Http/Controllers/Admin/TicketController.php
  17. 15 25
      app/Http/Controllers/AuthController.php
  18. 16 0
      app/Http/Controllers/Gateway/AbstractPayment.php
  19. 15 18
      app/Http/Controllers/Gateway/BitpayX.php
  20. 13 15
      app/Http/Controllers/Gateway/CodePay.php
  21. 13 15
      app/Http/Controllers/Gateway/EPay.php
  22. 16 21
      app/Http/Controllers/Gateway/F2Fpay.php
  23. 1 1
      app/Http/Controllers/Gateway/Local.php
  24. 8 12
      app/Http/Controllers/Gateway/PayBeaver.php
  25. 9 11
      app/Http/Controllers/Gateway/PayJs.php
  26. 4 6
      app/Http/Controllers/Gateway/PayPal.php
  27. 11 19
      app/Http/Controllers/Gateway/Stripe.php
  28. 1 6
      app/Http/Controllers/PaymentController.php
  29. 16 28
      app/Http/Controllers/UserController.php
  30. 0 36
      app/Mail/activeUser.php
  31. 0 41
      app/Mail/closeTicket.php
  32. 0 41
      app/Mail/newTicket.php
  33. 0 34
      app/Mail/nodeCrashWarning.php
  34. 0 40
      app/Mail/replyTicket.php
  35. 0 35
      app/Mail/resetPassword.php
  36. 0 35
      app/Mail/sendUserInfo.php
  37. 0 35
      app/Mail/sendVerifyCode.php
  38. 0 35
      app/Mail/userExpireWarning.php
  39. 0 33
      app/Mail/userExpireWarningToday.php
  40. 0 35
      app/Mail/userTrafficWarning.php
  41. 34 0
      app/Notifications/AccountActivation.php
  42. 48 0
      app/Notifications/AccountExpire.php
  43. 51 0
      app/Notifications/Custom.php
  44. 44 0
      app/Notifications/DataAnomaly.php
  45. 41 0
      app/Notifications/DataExhaust.php
  46. 40 0
      app/Notifications/NodeBlocked.php
  47. 44 0
      app/Notifications/NodeDailyReport.php
  48. 41 0
      app/Notifications/NodeOffline.php
  49. 41 0
      app/Notifications/PasswordReset.php
  50. 42 0
      app/Notifications/PaymentReceived.php
  51. 46 0
      app/Notifications/TicketClosed.php
  52. 45 0
      app/Notifications/TicketCreated.php
  53. 45 0
      app/Notifications/TicketReplied.php
  54. 39 0
      app/Notifications/Verification.php
  55. 2 0
      composer.json
  56. 246 1
      composer.lock
  57. 70 0
      database/migrations/2021_01_15_065207_create_notifications_table.php
  58. 0 1
      resources/lang/en/auth.php
  59. 34 0
      resources/lang/en/notification.php
  60. 26 0
      resources/lang/zh-CN.json
  61. 0 1
      resources/lang/zh-CN/auth.php
  62. 1 1
      resources/lang/zh-CN/common.php
  63. 34 0
      resources/lang/zh-CN/notification.php
  64. 5 5
      resources/lang/zh-CN/user.php
  65. 130 32
      resources/views/admin/config/system.blade.php
  66. 1 1
      resources/views/admin/logs/callback.blade.php
  67. 3 3
      resources/views/admin/logs/order.blade.php
  68. 3 3
      resources/views/auth/resetPassword.blade.php
  69. 0 109
      resources/views/emails/activeUser.blade.php
  70. 0 105
      resources/views/emails/closeTicket.blade.php
  71. 0 105
      resources/views/emails/newTicket.blade.php
  72. 0 105
      resources/views/emails/nodeCrashWarning.blade.php
  73. 0 105
      resources/views/emails/replyTicket.blade.php
  74. 0 934
      resources/views/emails/resetPassword.blade.php
  75. 0 152
      resources/views/emails/sendUserInfo.blade.php
  76. 0 105
      resources/views/emails/sendVerifyCode.blade.php
  77. 0 105
      resources/views/emails/userExpireWarning.blade.php
  78. 0 105
      resources/views/emails/userExpireWarningToday.blade.php
  79. 0 105
      resources/views/emails/userTrafficWarning.blade.php
  80. 5 0
      resources/views/mail/custom.blade.php
  81. 7 0
      resources/views/mail/node/dailyReport.blade.php
  82. 51 0
      resources/views/user/components/notification.blade.php
  83. 13 0
      resources/views/user/components/notifications/accountExpire.blade.php
  84. 13 0
      resources/views/user/components/notifications/paymentReceived.blade.php
  85. 1 1
      resources/views/user/invoiceDetail.blade.php
  86. 1 1
      resources/views/user/invoices.blade.php
  87. 2 1
      resources/views/user/layouts.blade.php

+ 35 - 0
app/Channels/BarkChannel.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace App\Channels;
+
+use Helpers;
+use Http;
+use Illuminate\Notifications\Notification;
+use Log;
+
+class BarkChannel
+{
+    public function send($notifiable, Notification $notification)
+    {
+        $message = $notification->toCustom($notifiable);
+        $response = Http::timeout(15)->get('https://api.day.app/'.sysConfig('bark_key').'/'.$message['title'].'/'.$message['content']);
+
+        if ($response->ok()) {
+            $ret = $response->json();
+            // 发送成功
+            if ($ret['code'] === 200) {
+                Helpers::addNotificationLog($message['title'], $message['content'], 3);
+
+                return $ret;
+            }
+            // 发送失败
+            Helpers::addNotificationLog($message['title'], $message['content'], 3, 'admin', -1, $message);
+
+            return false;
+        }
+        // 发送错误
+        Log::error('Bark消息推送异常:'.var_export($response, true));
+
+        return false;
+    }
+}

+ 38 - 0
app/Channels/PushBearChannel.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace App\Channels;
+
+use Helpers;
+use Http;
+use Illuminate\Notifications\Notification;
+use Log;
+
+class PushBearChannel
+{
+    public function send($notifiable, Notification $notification)
+    {
+        $message = $notification->toCustom($notifiable);
+        $response = Http::timeout(15)->get('https://pushbear.ftqq.com/sub', [
+            'sendkey' => sysConfig('push_bear_send_key'),
+            'text'    => $message['title'],
+            'desp'    => $message['content'],
+        ]);
+        if ($response->ok()) {
+            $ret = $response->json();
+            // 发送成功
+            if ($ret) {
+                Helpers::addMarketing(2, $message['title'], $message['content']);
+
+                return $ret;
+            }
+            // 发送失败
+            Helpers::addMarketing(2, $message['title'], $message['content'], -1, $ret['message']);
+
+            return false;
+        }
+        // 发送错误
+        Log::error('Bark消息推送异常:'.var_export($response, true));
+
+        return false;
+    }
+}

+ 52 - 0
app/Channels/ServerChanChannel.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Channels;
+
+use Cache;
+use Helpers;
+use Http;
+use Illuminate\Notifications\Notification;
+use Log;
+
+class ServerChanChannel
+{
+    public function send($notifiable, Notification $notification)
+    {
+        $message = $notification->toCustom($notifiable);
+
+        $cacheKey = 'serverChanCount'.date('d');
+        if (Cache::has($cacheKey)) {
+            Cache::increment($cacheKey);
+        } else {
+            Cache::put($cacheKey, 1, Day); // 24小时
+        }
+
+        // 一天仅可发送不超过500条
+        if (Cache::get($cacheKey) < 500) {
+            $response = Http::timeout(15)
+                ->get('https://sc.ftqq.com/'.sysConfig('server_chan_key').'.send?text='.$message['title'].'&desp='.urlencode($message['content']));
+        } else {
+            Log::error('ServerChan消息推送异常:今日500条限额已耗尽!');
+
+            return false;
+        }
+
+        // 发送成功
+        if ($response->ok()) {
+            $ret = $response->json();
+            if (! $ret['errno']) {
+                Helpers::addNotificationLog($message['title'], $message['content'], 2);
+
+                return $ret;
+            }
+            // 发送失败
+            Helpers::addNotificationLog($message['title'], $message['content'], 2, 'admin', -1, $ret ? $ret['errmsg'] : '未知');
+
+            return false;
+        }
+        // 发送错误
+        Log::error('ServerChan消息推送异常:'.var_export($response, true));
+
+        return false;
+    }
+}

+ 78 - 14
app/Components/Helpers.php

@@ -2,8 +2,11 @@
 
 namespace App\Components;
 
+use App\Channels\BarkChannel;
+use App\Channels\ServerChanChannel;
 use App\Models\Config;
 use App\Models\CouponLog;
+use App\Models\Marketing;
 use App\Models\NotificationLog;
 use App\Models\SsConfig;
 use App\Models\User;
@@ -13,6 +16,8 @@ use App\Models\UserDataModifyLog;
 use App\Models\UserSubscribe;
 use Cache;
 use DateTime;
+use NotificationChannels\BearyChat\BearyChatChannel;
+use NotificationChannels\Telegram\TelegramChannel;
 use Str;
 
 class Helpers
@@ -65,20 +70,20 @@ class Helpers
     public static function addUser(string $email, string $password, int $transfer_enable, int $date = null, int $inviter_id = null, string $username = null): User
     {
         return User::create([
-            'username' => $username ?? $email,
-            'email' => $email,
-            'password' => $password,
-            'port' => self::getPort(), // 生成一个可用端口
-            'passwd' => Str::random(),
-            'vmess_id' => Str::uuid(),
-            'method' => self::getDefaultMethod(),
-            'protocol' => self::getDefaultProtocol(),
-            'obfs' => self::getDefaultObfs(),
+            'username'        => $username ?? $email,
+            'email'           => $email,
+            'password'        => $password,
+            'port'            => self::getPort(), // 生成一个可用端口
+            'passwd'          => Str::random(),
+            'vmess_id'        => Str::uuid(),
+            'method'          => self::getDefaultMethod(),
+            'protocol'        => self::getDefaultProtocol(),
+            'obfs'            => self::getDefaultObfs(),
             'transfer_enable' => $transfer_enable,
-            'expired_at' => date('Y-m-d', strtotime('+'.$date.' days')),
-            'user_group_id' => null,
-            'reg_ip' => IP::getClientIp(),
-            'inviter_id' => $inviter_id,
+            'expired_at'      => date('Y-m-d', strtotime('+'.$date.' days')),
+            'user_group_id'   => null,
+            'reg_ip'          => IP::getClientIp(),
+            'inviter_id'      => $inviter_id,
         ]);
     }
 
@@ -142,17 +147,52 @@ class Helpers
     // 获取系统配置
     public static function cacheSysConfig($name)
     {
+        $notifications = [
+            'account_expire_notification',
+            'data_anomaly_notification',
+            'data_exhaust_notification',
+            'node_blocked_notification',
+            'node_daily_notification',
+            'node_offline_notification',
+            'password_reset_notification',
+            'payment_received_notification',
+            'ticket_closed_notification',
+            'ticket_created_notification',
+            'ticket_replied_notification',
+        ];
+
         if ($name === 'is_onlinePay') {
             $value = sysConfig('is_AliPay') || sysConfig('is_QQPay') || sysConfig('is_WeChatPay') || sysConfig('is_otherPay');
             Cache::tags('sysConfig')->put('is_onlinePay', $value);
         } else {
-            $value = Config::find($name)->value;
+            if (in_array($name, $notifications, true)) {
+                $value = self::setChannel(Config::find($name)->value);
+            } else {
+                $value = Config::find($name)->value;
+            }
             Cache::tags('sysConfig')->put($name, $value ?? false);
         }
 
         return $value;
     }
 
+    private static function setChannel(array $channels)
+    {
+        $options = [
+            'telegram'   => TelegramChannel::class,
+            'beary'      => BearyChatChannel::class,
+            'bark'       => BarkChannel::class,
+            'serverChan' => ServerChanChannel::class,
+        ];
+        foreach ($options as $option => $str) {
+            if (($key = array_search($option, $channels, true)) !== false) {
+                $channels[$key] = $str;
+            }
+        }
+
+        return $channels;
+    }
+
     public static function daysToNow($date): int
     {
         return (new DateTime())->diff(new DateTime($date))->days;
@@ -272,4 +312,28 @@ class Helpers
 
         return $log->save();
     }
+
+    /**
+     * 推销信息推送
+     *
+     * @param  int  $type  渠道类型
+     * @param  string  $title  标题
+     * @param  string  $content  内容
+     * @param  int  $status  状态
+     * @param  string  $error  报错
+     * @param  string  $receiver  收件人
+     * @return int
+     */
+    public static function addMarketing(int $type, string $title, string $content, int $status = 1, string $error = '', string $receiver = ''): int
+    {
+        $marketing = new Marketing();
+        $marketing->type = $type;
+        $marketing->receiver = $receiver;
+        $marketing->title = $title;
+        $marketing->content = $content;
+        $marketing->error = $error;
+        $marketing->status = $status;
+
+        return $marketing->save();
+    }
 }

+ 0 - 98
app/Components/PushNotification.php

@@ -1,98 +0,0 @@
-<?php
-
-namespace App\Components;
-
-use Cache;
-use Http;
-use Log;
-
-class PushNotification
-{
-    public static function send(string $title, string $content)
-    {
-        switch (sysConfig('is_notification')) {
-            case 'serverChan':
-                return self::ServerChan($title, $content);
-            case 'bark':
-                return self::Bark($title, $content);
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * ServerChan推送消息.
-     *
-     * @param  string  $title  消息标题
-     * @param  string  $content  消息内容
-     *
-     * @return mixed
-     */
-    private static function ServerChan(string $title, string $content)
-    {
-        $cacheKey = 'serverChanCount'.date('d');
-        if (Cache::has($cacheKey)) {
-            Cache::increment($cacheKey);
-        } else {
-            Cache::put($cacheKey, 1, Day); // 24小时
-        }
-
-        // 一天仅可发送不超过500条
-        if (Cache::get($cacheKey) < 500) {
-            $response = Http::timeout(15)->get('https://sc.ftqq.com/'.sysConfig('server_chan_key').'.send?text='.$title.'&desp='.urlencode($content));
-        } else {
-            Log::error('ServerChan消息推送异常:今日500条限额已耗尽!');
-
-            return false;
-        }
-
-        // 发送成功
-        if ($response->ok()) {
-            $message = $response->json();
-            if (! $message['errno']) {
-                Helpers::addNotificationLog($title, $content, 2);
-
-                return $message;
-            }
-            // 发送失败
-            Helpers::addNotificationLog($title, $content, 2, 'admin', -1, $message ? $message['errmsg'] : '未知');
-
-            return false;
-        }
-        // 发送错误
-        Log::error('ServerChan消息推送异常:'.var_export($response, true));
-
-        return false;
-    }
-
-    /**
-     * Bark推送消息.
-     *
-     * @param  string  $title  消息标题
-     * @param  string  $content  消息内容
-     *
-     * @return mixed
-     */
-    private static function Bark(string $title, string $content)
-    {
-        $response = Http::timeout(15)->get('https://api.day.app/'.sysConfig('bark_key').'/'.$title.'/'.$content);
-
-        if ($response->ok()) {
-            $message = $response->json();
-            // 发送成功
-            if ($message['code'] === 200) {
-                Helpers::addNotificationLog($title, $content, 3);
-
-                return $message;
-            }
-            // 发送失败
-            Helpers::addNotificationLog($title, $content, 3, 'admin', -1, $message);
-
-            return false;
-        }
-        // 发送错误
-        Log::error('Bark消息推送异常:'.var_export($response, true));
-
-        return false;
-    }
-}

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

@@ -3,7 +3,6 @@
 namespace App\Console\Commands;
 
 use App\Components\Helpers;
-use App\Components\PushNotification;
 use App\Models\Config;
 use App\Models\Coupon;
 use App\Models\Invite;
@@ -12,9 +11,11 @@ use App\Models\NodeHeartbeat;
 use App\Models\Order;
 use App\Models\User;
 use App\Models\VerifyCode;
+use App\Notifications\NodeOffline;
 use Cache;
 use Illuminate\Console\Command;
 use Log;
+use Notification;
 
 class AutoJob extends Command
 {
@@ -196,7 +197,9 @@ class AutoJob extends Command
 
                     if ($times < $offlineCheckTimes) {
                         Cache::increment($cacheKey);
-                        PushNotification::send('节点异常警告', "节点**{$node->name}【{$node->ip}】**异常:**心跳异常,可能离线了**");
+                        Notification::send(User::permission('admin.node.edit,update')->orWhere(function ($query) {
+                            return $query->role('Super Admin');
+                        })->get(), new NodeOffline($node->name, $node->ip));
                     }
                 }
             }

+ 27 - 16
app/Console/Commands/AutoReportNode.php

@@ -2,11 +2,12 @@
 
 namespace App\Console\Commands;
 
-use App\Components\PushNotification;
 use App\Models\Node;
-use App\Models\NodeDailyDataFlow;
+use App\Models\User;
+use App\Notifications\NodeDailyReport;
 use Illuminate\Console\Command;
 use Log;
+use Notification;
 
 class AutoReportNode extends Command
 {
@@ -17,23 +18,33 @@ class AutoReportNode extends Command
     {
         $jobStartTime = microtime(true);
 
-        if (sysConfig('node_daily_report')) {
-            $nodeList = Node::whereStatus(1)->get();
+        if (sysConfig('node_daily_notification')) {
+            $nodeList = Node::whereStatus(1)->with('dailyDataFlows')->get();
             if ($nodeList->isNotEmpty()) {
-                $msg = "|节点|上行流量|下行流量|合计|\r\n| :------ | :------ | :------ |\r\n";
+                $data = [];
+                $upload = 0;
+                $download = 0;
                 foreach ($nodeList as $node) {
-                    $log = NodeDailyDataFlow::whereNodeId($node->id)
-                        ->whereDate('created_at', date('Y-m-d', strtotime('-1 days')))
-                        ->first();
-
-                    if ($log) {
-                        $msg .= '|'.$node->name.'|'.flowAutoShow($log->u).'|'.flowAutoShow($log->d).'|'.$log->traffic."\r\n";
-                    } else {
-                        $msg .= '|'.$node->name.'|'.flowAutoShow(0).'|'.flowAutoShow(0)."|0B\r\n";
-                    }
+                    $log = $node->dailyDataFlows()->whereDate('created_at', date('Y-m-d', strtotime('-1 days')))->first();
+                    $data[] = [
+                        'name'     => $node->name,
+                        'upload'   => flowAutoShow($log->u ?? 0),
+                        'download' => flowAutoShow($log->d ?? 0),
+                        'total'    => $log->traffic ?? '',
+                    ];
+                    $upload += $log->u ?? 0;
+                    $download += $log->d ?? 0;
+                }
+                if ($data) {
+                    $data[] = [
+                        'name'     => trans('notification.node.total'),
+                        'total'    => flowAutoShow($upload + $download),
+                        'upload'   => flowAutoShow($upload),
+                        'download' => flowAutoShow($download),
+                    ];
+
+                    Notification::send(User::role('Super Admin')->get(), new NodeDailyReport($data));
                 }
-
-                PushNotification::send('节点昨日使用情况', $msg);
             }
         }
 

+ 15 - 15
app/Console/Commands/DailyJob.php

@@ -3,10 +3,10 @@
 namespace App\Console\Commands;
 
 use App\Components\Helpers;
-use App\Components\PushNotification;
 use App\Models\Order;
 use App\Models\Ticket;
 use App\Models\User;
+use App\Notifications\TicketClosed;
 use App\Services\OrderService;
 use Illuminate\Console\Command;
 use Log;
@@ -45,14 +45,14 @@ class DailyJob extends Command
         foreach ($userList as $user) {
             if ($isBanStatus) {
                 $user->update([
-                    'u' => 0,
-                    'd' => 0,
+                    'u'               => 0,
+                    'd'               => 0,
                     'transfer_enable' => 0,
-                    'enable' => 0,
-                    'level' => 0,
-                    'reset_time' => null,
-                    'ban_time' => null,
-                    'status' => -1,
+                    'enable'          => 0,
+                    'level'           => 0,
+                    'reset_time'      => null,
+                    'ban_time'        => null,
+                    'status'          => -1,
                 ]);
 
                 Helpers::addUserBanLog($user->id, 0, '【禁止登录,清空账户】-账号已过期');
@@ -64,13 +64,13 @@ class DailyJob extends Command
                 Helpers::addUserTrafficModifyLog($user->id, null, $user->transfer_enable, 0, '[定时任务]账号已过期(禁止登录,清空账户)');
             } else {
                 $user->update([
-                    'u' => 0,
-                    'd' => 0,
+                    'u'               => 0,
+                    'd'               => 0,
                     'transfer_enable' => 0,
-                    'enable' => 0,
-                    'level' => 0,
-                    'reset_time' => null,
-                    'ban_time' => null,
+                    'enable'          => 0,
+                    'level'           => 0,
+                    'reset_time'      => null,
+                    'ban_time'        => null,
                 ]);
 
                 Helpers::addUserBanLog($user->id, 0, '【封禁代理,清空账户】-账号已过期');
@@ -86,7 +86,7 @@ class DailyJob extends Command
     {
         foreach (Ticket::where('updated_at', '<=', date('Y-m-d', strtotime('-3 days')))->whereStatus(1)->get() as $ticket) {
             if ($ticket->close()) {
-                PushNotification::send('工单关闭提醒', '工单:ID'.$ticket->id.'超过72小时未处理,系统已自动关闭');
+                $ticket->user->notify(new TicketClosed($ticket->id, $ticket->title, route('replyTicket', ['id' => $ticket->id]), __('You have not responded this ticket in :num hours, System has auto closed your ticket.', ['num' => '72'])));
             }
         }
     }

+ 7 - 21
app/Console/Commands/NodeBlockedDetection.php

@@ -2,15 +2,14 @@
 
 namespace App\Console\Commands;
 
-use App\Components\Helpers;
 use App\Components\NetworkDetection;
-use App\Components\PushNotification;
-use App\Mail\nodeCrashWarning;
 use App\Models\Node;
+use App\Models\User;
+use App\Notifications\NodeBlocked;
 use Cache;
 use Illuminate\Console\Command;
 use Log;
-use Mail;
+use Notification;
 
 class NodeBlockedDetection extends Command
 {
@@ -55,7 +54,6 @@ class NodeBlockedDetection extends Command
                     $node->ip = $ip;
                 } else {
                     Log::warning('【节点阻断检测】检测'.$node->server.'时,IP获取失败'.$ip.' | '.$node->server);
-                    $this->notifyMaster("{$node->name}动态IP获取失败", "节点 {$node->name} : IP获取失败 ");
                 }
             }
             if ($node->detection_type !== 1) {
@@ -100,26 +98,14 @@ class NodeBlockedDetection extends Command
 
         //只有在出现阻断线路时,才会发出警报
         if ($sendText) {
-            $this->notifyMaster('节点阻断警告', "阻断日志: \r\n\r\n".$message.$additionalMessage);
+            Notification::send(User::permission('admin.node.edit,update')->orWhere(function ($query) {
+                return $query->role('Super Admin');
+            })->get(), new NodeBlocked($message.$additionalMessage));
+
             Log::info("阻断日志: \r\n".$message.$additionalMessage);
         }
 
         // 随机生成下次检测时间
         Cache::put('LastCheckTime', time() + random_int(3000, Hour), 3700);
     }
-
-    /**
-     * 通知管理员.
-     *
-     * @param  string  $title  消息标题
-     * @param  string  $content  消息内容
-     */
-    private function notifyMaster(string $title, string $content): void
-    {
-        $result = PushNotification::send($title, $content);
-        if (! $result && sysConfig('webmaster_email')) {
-            $logId = Helpers::addNotificationLog($title, $content, 1, sysConfig('webmaster_email'));
-            Mail::to(sysConfig('webmaster_email'))->send(new nodeCrashWarning($logId));
-        }
-    }
 }

+ 3 - 22
app/Console/Commands/UserExpireAutoWarning.php

@@ -2,13 +2,10 @@
 
 namespace App\Console\Commands;
 
-use App\Components\Helpers;
-use App\Mail\userExpireWarning;
-use App\Mail\userExpireWarningToday;
 use App\Models\User;
+use App\Notifications\AccountExpire;
 use Illuminate\Console\Command;
 use Log;
-use Mail;
 
 class UserExpireAutoWarning extends Command
 {
@@ -20,7 +17,7 @@ class UserExpireAutoWarning extends Command
         $jobStartTime = microtime(true);
 
         // 用户临近到期自动发邮件提醒
-        if (sysConfig('expire_warning')) {
+        if (sysConfig('account_expire_notification')) {
             $this->userExpireWarning();
         }
 
@@ -32,29 +29,13 @@ class UserExpireAutoWarning extends Command
 
     private function userExpireWarning(): void
     {
-        $expireDays = sysConfig('expire_days');
         // 只取SSR没被禁用的用户,其他不用管
         foreach (User::whereEnable(1)->where('expired_at', '<', date('Y-m-d', strtotime(sysConfig('expire_days').' days')))->get() as $user) {
             // 用户名不是邮箱的跳过
             if (filter_var($user->email, FILTER_VALIDATE_EMAIL) === false) {
                 continue;
             }
-
-            // 计算剩余可用时间
-            $lastCanUseDays = Helpers::daysToNow($user->expired_at);
-            if ($lastCanUseDays === 0) {
-                $title = '账号过期提醒';
-                $content = '您的账号将于今天晚上【24:00】过期。';
-
-                $logId = Helpers::addNotificationLog($title, $content, 1, $user->email);
-                Mail::to($user->email)->send(new userExpireWarningToday($logId));
-            } elseif ($lastCanUseDays > 0) {
-                $title = '账号过期提醒';
-                $content = '您的账号还剩'.$lastCanUseDays.'天即将过期。';
-
-                $logId = Helpers::addNotificationLog($title, $content, 1, $user->email);
-                Mail::to($user->email)->send(new userExpireWarning($logId, $lastCanUseDays));
-            }
+            $user->notify(new AccountExpire($user->expired_at));
         }
     }
 }

+ 9 - 6
app/Console/Commands/UserTrafficAbnormalAutoWarning.php

@@ -2,10 +2,12 @@
 
 namespace App\Console\Commands;
 
-use App\Components\PushNotification;
+use App\Models\User;
 use App\Models\UserHourlyDataFlow;
+use App\Notifications\DataAnomaly;
 use Illuminate\Console\Command;
 use Log;
+use Notification;
 
 class UserTrafficAbnormalAutoWarning extends Command
 {
@@ -17,7 +19,9 @@ class UserTrafficAbnormalAutoWarning extends Command
         $jobStartTime = microtime(true);
 
         // 用户流量异常警告
-        $this->userTrafficAbnormalWarning();
+        if (sysConfig('data_anomaly_notification')) {
+            $this->userTrafficAbnormalWarning();
+        }
 
         $jobEndTime = microtime(true);
         $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
@@ -45,10 +49,9 @@ class UserTrafficAbnormalAutoWarning extends Command
                     ->selectRaw('user_id, sum(`u`) as totalU, sum(`d`) as totalD, sum(total) as totalTraffic')
                     ->first();
 
-                PushNotification::send(
-                    '流量异常用户提醒',
-                    "用户**{$user->email}(ID:{$user->id})**,最近1小时**上行流量:".flowAutoShow($traffic->totalU).',下行流量:'.flowAutoShow($traffic->totalD).',共计:'.flowAutoShow($traffic->totalTraffic).'**。'
-                );
+                Notification::send(User::permission('admin.user.edit,update')->orWhere(function ($query) {
+                    return $query->role('Super Admin');
+                })->get(), new DataAnomaly($user->id, flowAutoShow($traffic->totalU), flowAutoShow($traffic->totalD), flowAutoShow($traffic->totalTraffic)));
             }
         }
     }

+ 3 - 6
app/Console/Commands/UserTrafficAutoWarning.php

@@ -2,12 +2,10 @@
 
 namespace App\Console\Commands;
 
-use App\Components\Helpers;
-use App\Mail\userTrafficWarning;
 use App\Models\User;
+use App\Notifications\DataExhaust;
 use Illuminate\Console\Command;
 use Log;
-use Mail;
 
 class UserTrafficAutoWarning extends Command
 {
@@ -19,7 +17,7 @@ class UserTrafficAutoWarning extends Command
         $jobStartTime = microtime(true);
 
         // 用户流量超过警告阈值自动发邮件提醒
-        if (sysConfig('traffic_warning')) {
+        if (sysConfig('data_exhaust_notification')) {
             $this->userTrafficWarning();
         }
 
@@ -41,8 +39,7 @@ class UserTrafficAutoWarning extends Command
 
             $usedPercent = $user->used_traffic_percentage * 100; // 已使用流量百分比
             if ($usedPercent >= $trafficWarningPercent) {
-                $logId = Helpers::addNotificationLog('流量提醒', '流量已使用:'.$usedPercent.'%,请保持关注。', 1, $user->email);
-                Mail::to($user->email)->send(new userTrafficWarning($logId, $usedPercent));
+                $user->notify(new DataExhaust($usedPercent));
             }
         }
     }

+ 3 - 3
app/Http/Controllers/Admin/LogsController.php

@@ -22,7 +22,7 @@ class LogsController extends Controller
     public function orderList(Request $request)
     {
         $email = $request->input('email');
-        $order_sn = $request->input('order_sn');
+        $sn = $request->input('sn');
         $is_coupon = $request->input('is_coupon');
         $is_expire = $request->input('is_expire');
         $pay_way = $request->input('pay_way');
@@ -38,8 +38,8 @@ class LogsController extends Controller
                 $q->where('email', 'like', '%'.$email.'%');
             });
         }
-        if (isset($order_sn)) {
-            $query->where('order_sn', 'like', '%'.$order_sn.'%');
+        if (isset($sn)) {
+            $query->where('sn', 'like', '%'.$sn.'%');
         }
 
         if (isset($is_coupon)) {

+ 5 - 45
app/Http/Controllers/Admin/MarketingController.php

@@ -2,15 +2,13 @@
 
 namespace App\Http\Controllers\Admin;
 
+use App\Channels\PushBearChannel;
 use App\Http\Controllers\Controller;
 use App\Models\Marketing;
-use DB;
-use Exception;
-use Http;
+use App\Notifications\Custom;
 use Illuminate\Http\Request;
-use Log;
+use Notification;
 use Response;
-use RuntimeException;
 
 class MarketingController extends Controller
 {
@@ -52,46 +50,8 @@ class MarketingController extends Controller
             return Response::json(['status' => 'fail', 'message' => '推送失败:请先启用并配置PushBear']);
         }
 
-        try {
-            DB::beginTransaction();
+        Notification::send(PushBearChannel::class, new Custom($title, $content));
 
-            $response = Http::timeout(15)->get('https://pushbear.ftqq.com/sub', [
-                'sendkey' => sysConfig('push_bear_send_key'),
-                'text' => $title,
-                'desp' => $content,
-            ]);
-
-            $message = $response->json();
-            if (! $message || ! $message['code'] === 0 || $response->failed()) { // 失败
-                $this->addMarketing(2, $title, $content, -1, $message['message']);
-
-                throw new RuntimeException($message['message']);
-            }
-
-            $this->addMarketing(2, $title, $content);
-
-            DB::commit();
-
-            return Response::json(['status' => 'success', 'message' => '推送成功']);
-        } catch (Exception $e) {
-            Log::error('PushBear消息推送失败:'.$e->getMessage());
-
-            DB::rollBack();
-
-            return Response::json(['status' => 'fail', 'message' => '推送失败:'.$e->getMessage()]);
-        }
-    }
-
-    private function addMarketing($type = 1, $title = '', $content = '', $status = 1, $error = '', $receiver = ''): bool
-    {
-        $marketing = new Marketing();
-        $marketing->type = $type;
-        $marketing->receiver = $receiver;
-        $marketing->title = $title;
-        $marketing->content = $content;
-        $marketing->error = $error;
-        $marketing->status = $status;
-
-        return $marketing->save();
+        return Response::json(['status' => 'success', 'message' => '推送成功']);
     }
 }

+ 23 - 87
app/Http/Controllers/Admin/SystemController.php

@@ -2,12 +2,16 @@
 
 namespace App\Http\Controllers\Admin;
 
-use App\Components\PushNotification;
+use App\Channels\BarkChannel;
+use App\Channels\ServerChanChannel;
 use App\Http\Controllers\Controller;
 use App\Http\Requests\Admin\SystemRequest;
 use App\Models\Config;
+use App\Notifications\Custom;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\RedirectResponse;
+use Notification;
+use Request;
 use Response;
 
 class SystemController extends Controller
@@ -18,7 +22,7 @@ class SystemController extends Controller
         return view('admin.config.system', array_merge(['payments' => $this->getPayment(), 'captcha' => $this->getCaptcha()], Config::pluck('value', 'name')->toArray()));
     }
 
-    private function getPayment()
+    private function getPayment() // 获取已经完成配置的支付渠道
     {
         if (sysConfig('f2fpay_app_id') && sysConfig('f2fpay_private_key') && sysConfig('f2fpay_public_key')) {
             $payment[] = 'f2fpay';
@@ -63,8 +67,7 @@ class SystemController extends Controller
         return $captcha ?? [];
     }
 
-    // 设置系统扩展信息,例如客服、统计代码
-    public function setExtend(SystemRequest $request): RedirectResponse
+    public function setExtend(Request $request): RedirectResponse  // 设置系统扩展信息,例如客服、统计代码
     {
         if ($request->hasFile('website_home_logo')) {
             $validator = validator()->make($request->all(), ['website_home_logo' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048']);
@@ -96,69 +99,14 @@ class SystemController extends Controller
         return redirect()->route('admin.system.index', '#other')->withErrors('更新失败');
     }
 
-    // 设置某个配置项
-    public function setConfig(SystemRequest $request): JsonResponse
+    public function setConfig(SystemRequest $request): JsonResponse // 设置某个配置项
     {
         $name = $request->input('name');
         $value = $request->input('value');
 
-        // 如果开启用户邮件重置密码,则先设置网站名称和网址
-        if ($value !== '0' && in_array($name, ['is_reset_password', 'is_activate_account', 'expire_warning', 'traffic_warning'], true)) {
-            if (! Config::find('website_url')->value) {
-                return Response::json(['status' => 'fail', 'message' => '设置失败:启用该配置需要先设置【网站名称】']);
-            }
-
-            if (! Config::find('website_url')->value) {
-                return Response::json(['status' => 'fail', 'message' => '设置失败:启用该配置需要先设置【网站地址】']);
-            }
-        }
-
         // 支付设置判断
-        if ($value !== null && in_array($name, ['is_AliPay', 'is_QQPay', 'is_WeChatPay', 'is_otherPay'], true)) {
-            switch ($value) {
-                case 'f2fpay':
-                    if (! sysConfig('f2fpay_app_id') || ! sysConfig('f2fpay_private_key') || ! sysConfig('f2fpay_public_key')) {
-                        return Response::json(['status' => 'fail', 'message' => '请先设置【支付宝F2F】必要参数']);
-                    }
-                    break;
-                case 'codepay':
-                    if (! sysConfig('codepay_url') || ! sysConfig('codepay_id') || ! sysConfig('codepay_key')) {
-                        return Response::json(['status' => 'fail', 'message' => '请先设置【码支付】必要参数']);
-                    }
-                    break;
-                case 'epay':
-                    if (! sysConfig('epay_url') || ! sysConfig('epay_mch_id') || ! sysConfig('epay_key')) {
-                        return Response::json(['status' => 'fail', 'message' => '请先设置【易支付】必要参数']);
-                    }
-                    break;
-                case 'payjs':
-                    if (! sysConfig('payjs_mch_id') || ! sysConfig('payjs_key')) {
-                        return Response::json(['status' => 'fail', 'message' => '请先设置【PayJs】必要参数']);
-                    }
-                    break;
-                case 'bitpayx':
-                    if (! sysConfig('bitpay_secret')) {
-                        return Response::json(['status' => 'fail', 'message' => '请先设置【麻瓜宝】必要参数']);
-                    }
-                    break;
-                case 'paypal':
-                    if (! sysConfig('paypal_username') || ! sysConfig('paypal_password') || ! sysConfig('paypal_secret')) {
-                        return Response::json(['status' => 'fail', 'message' => '请先设置【PayPal】必要参数']);
-                    }
-                    break;
-                case 'stripe':
-                    if (! sysConfig('stripe_public_key') || ! sysConfig('stripe_secret_key')) {
-                        return Response::json(['status' => 'fail', 'message' => '请先设置【Stripe】必要参数']);
-                    }
-                    break;
-                case 'paybeaver':
-                    if (! sysConfig('paybeaver_app_id') || ! sysConfig('paybeaver_app_secret')) {
-                        return Response::json(['status' => 'fail', 'message' => '请先设置【PayBeaver】必要参数']);
-                    }
-                    break;
-                default:
-                    return Response::json(['status' => 'fail', 'message' => '未知支付渠道']);
-            }
+        if ($value !== null && in_array($name, ['is_AliPay', 'is_QQPay', 'is_WeChatPay', 'is_otherPay'], true) && ! in_array($value, $this->getPayment(), true)) {
+            return Response::json(['status' => 'fail', 'message' => '请先完善该支付渠道的必要参数!']);
         }
 
         // 演示环境禁止修改特定配置项
@@ -192,31 +140,19 @@ class SystemController extends Controller
         return Response::json(['status' => 'fail', 'message' => trans('common.update_action', ['action' => trans('common.failed')])]);
     }
 
-    // 推送通知测试
-    public function sendTestNotification(): JsonResponse
+    public function sendTestNotification(): JsonResponse  // 推送通知测试
     {
-        if (sysConfig('is_notification')) {
-            $result = PushNotification::send('这是测试的标题', 'ProxyPanel测试内容');
-            if ($result === false) {
-                return Response::json(['status' => 'fail', 'message' => '发送失败,请重新尝试!']);
-            }
-            switch (sysConfig('is_notification')) {
-                case 'serverChan':
-                    if (! $result['errno']) {
-                        return Response::json(['status' => 'success', 'message' => '发送成功,请查看手机是否收到推送消息']);
-                    }
-
-                    return Response::json(['status' => 'fail', 'message' => $result ? $result['errmsg'] : '未知']);
-                case 'bark':
-                    if ($result['code'] === 200) {
-                        return Response::json(['status' => 'success', 'message' => '发送成功,请查看手机是否收到推送消息']);
-                    }
-
-                    return Response::json(['status' => 'fail', 'message' => $result['message']]);
-                default:
-            }
-        }
-
-        return Response::json(['status' => 'fail', 'message' => '请先选择【日志通知】渠道']);
+        switch (request('channel')) {
+            case 'serverChan':
+                Notification::sendNow(ServerChanChannel::class, new Custom('这是测试的标题', 'ProxyPanel测试内容'));
+                break;
+            case 'bark':
+                Notification::sendNow(BarkChannel::class, new Custom('这是测试的标题', 'ProxyPanel测试内容'));
+                break;
+            default:
+                return Response::json(['status' => 'fail', 'message' => '未知渠道']);
+        }
+
+        return Response::json(['status' => 'success', 'message' => '发送成功,请查看手机是否收到推送消息']);
     }
 }

+ 7 - 23
app/Http/Controllers/Admin/TicketController.php

@@ -2,23 +2,16 @@
 
 namespace App\Http\Controllers\Admin;
 
-use App\Components\Helpers;
 use App\Http\Controllers\Controller;
 use App\Http\Requests\Admin\TicketRequest;
-use App\Mail\closeTicket;
-use App\Mail\replyTicket;
 use App\Models\Ticket;
 use App\Models\User;
+use App\Notifications\TicketClosed;
+use App\Notifications\TicketReplied;
 use Auth;
 use Illuminate\Http\Request;
-use Mail;
 use Response;
 
-/**
- * 工单控制器.
- *
- * Class TicketController
- */
 class TicketController extends Controller
 {
     // 工单列表
@@ -58,7 +51,7 @@ class TicketController extends Controller
     public function edit(Ticket $ticket)
     {
         return view('admin.ticket.reply', [
-            'ticket' => $ticket,
+            'ticket'    => $ticket,
             'replyList' => $ticket->reply()->oldest()->get(),
         ]);
     }
@@ -72,12 +65,8 @@ class TicketController extends Controller
             // 将工单置为已回复
             $ticket->update(['status' => 1]);
 
-            $title = '工单回复提醒';
-            $content = '标题:'.$ticket->title.'<br>管理员回复:'.$content;
-
-            // 发通知邮件
-            $logId = Helpers::addNotificationLog($title, $content, 1, $ticket->user->email);
-            Mail::to($ticket->user->email)->send(new replyTicket($logId, $title, $content));
+            // 通知用户
+            $ticket->user->notify(new TicketReplied($ticket->title, $content, route('replyTicket', $ticket)));
 
             return Response::json(['status' => 'success', 'message' => '回复成功']);
         }
@@ -91,13 +80,8 @@ class TicketController extends Controller
         if (! $ticket->close()) {
             return Response::json(['status' => 'fail', 'message' => '关闭失败']);
         }
-
-        $title = '工单关闭提醒';
-        $content = '工单【'.$ticket->title.'】已关闭';
-
-        // 发邮件通知用户
-        $logId = Helpers::addNotificationLog($title, $content, 1, $ticket->user->email);
-        Mail::to($ticket->user->email)->send(new closeTicket($logId, $title, $content));
+        // 通知用户
+        $ticket->user->notify(new TicketClosed($ticket->id, $ticket->title, route('replyTicket', $ticket), \request('reason')));
 
         return Response::json(['status' => 'success', 'message' => '关闭成功']);
     }

+ 15 - 25
app/Http/Controllers/AuthController.php

@@ -5,15 +5,15 @@ namespace App\Http\Controllers;
 use App\Components\Helpers;
 use App\Components\IP;
 use App\Http\Requests\Auth\RegisterRequest;
-use App\Mail\activeUser;
-use App\Mail\resetPassword;
-use App\Mail\sendVerifyCode;
 use App\Models\EmailFilter;
 use App\Models\Invite;
 use App\Models\User;
 use App\Models\UserLoginLog;
 use App\Models\Verify;
 use App\Models\VerifyCode;
+use App\Notifications\AccountActivation;
+use App\Notifications\PasswordReset;
+use App\Notifications\Verification;
 use Auth;
 use Cache;
 use Captcha;
@@ -22,18 +22,13 @@ use Hash;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
 use Log;
-use Mail;
+use Notification;
 use Redirect;
 use Response;
 use Session;
 use Str;
 use Validator;
 
-/**
- * 认证控制器.
- *
- * Class AuthController
- */
 class AuthController extends Controller
 {
     // 登录
@@ -316,11 +311,10 @@ class AuthController extends Controller
             $token = $this->addVerifyUrl($user->id, $user->email);
             $activeUserUrl = route('activeAccount', $token);
 
-            $logId = Helpers::addNotificationLog(trans('common.active_item', ['attribute' => trans('auth.register.attribute')]),
-                trans('common.request_url').':'.$activeUserUrl, 1, $user->email);
-            Mail::to($user->email)->send(new activeUser($logId, $activeUserUrl));
+            $user->notifyNow(new AccountActivation($activeUserUrl));
 
-            Session::flash('successMsg', trans('auth.active.sent'));
+            Session::flash('successMsg',
+                __("Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn't receive the email, we will gladly send you another."));
         } else {
             // 则直接给推荐人加流量
             if ($inviter_id) {
@@ -440,12 +434,12 @@ class AuthController extends Controller
             $email = $request->input('email');
 
             // 是否开启重设密码
-            if (! sysConfig('is_reset_password')) {
+            if (! sysConfig('password_reset_notification')) {
                 return Redirect::back()->withErrors(trans('auth.password.reset.error.disabled', ['email' => sysConfig('webmaster_email')]));
             }
 
             // 查找账号
-            $user = User::whereEmail($email)->first();
+            $user = User::whereEmail($email)->firstOrFail();
 
             // 24小时内重设密码次数限制
             $resetTimes = 0;
@@ -460,10 +454,8 @@ class AuthController extends Controller
             $token = $this->addVerifyUrl($user->id, $email);
 
             // 发送邮件
-            $resetPasswordUrl = route('resettingPasswd', $token);
-
-            $logId = Helpers::addNotificationLog(trans('auth.password.reset.attribute'), trans('common.request_url').':'.$resetPasswordUrl, 1, $email);
-            Mail::to($email)->send(new resetPassword($logId, $resetPasswordUrl));
+            $resetUrl = route('resettingPasswd', $token);
+            $user->notifyNow(new PasswordReset($resetUrl));
 
             Cache::put('resetPassword_'.md5($email), $resetTimes + 1, Day);
 
@@ -577,8 +569,7 @@ class AuthController extends Controller
             // 发送邮件
             $activeUserUrl = route('activeAccount', $token);
 
-            $logId = Helpers::addNotificationLog(trans('common.active_item', ['attribute' => trans('common.account')]), trans('common.request_url').':'.$activeUserUrl, 1, $email);
-            Mail::to($email)->send(new activeUser($logId, $activeUserUrl));
+            Notification::route('mail', $email)->notifyNow(new AccountActivation($activeUserUrl));
 
             Cache::put('activeUser_'.md5($email), $activeTimes + 1, Day);
 
@@ -677,10 +668,9 @@ class AuthController extends Controller
 
         // 发送邮件
         $code = Str::random(6);
-        $logId = Helpers::addNotificationLog(trans('auth.register.code'), trans('auth.captcha.attribute').':'.$code, 1, $email);
-        Mail::to($email)->send(new sendVerifyCode($logId, $code));
-
-        VerifyCode::create(['address' => $email, 'code' => $code]); // 生成注册验证码
+        if (VerifyCode::create(['address' => $email, 'code' => $code])) { // 生成注册验证码
+            Notification::route('mail', $email)->notifyNow(new Verification($code));
+        }
 
         Cache::put('send_verify_code_'.md5($ip), $ip, Minute);
 

+ 16 - 0
app/Http/Controllers/Gateway/AbstractPayment.php

@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Gateway;
 
 use App\Models\Payment;
 use App\Models\PaymentCallback;
+use App\Notifications\PaymentReceived;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
 use Str;
@@ -72,4 +73,19 @@ abstract class AbstractPayment
 
         return md5(urldecode(http_build_query($data)).$key);
     }
+
+    protected function paymentReceived(string $tradeNo)
+    {
+        $payment = Payment::whereTradeNo($tradeNo)->with('order')->first();
+        if ($payment) {
+            $ret = $payment->order->complete();
+            if ($ret) {
+                $payment->user->notify(new PaymentReceived($payment->order->sn, $payment->amount));
+            }
+
+            return $ret;
+        }
+
+        return false;
+    }
 }

+ 15 - 18
app/Http/Controllers/Gateway/BitpayX.php

@@ -2,7 +2,6 @@
 
 namespace App\Http\Controllers\Gateway;
 
-use App\Models\Payment;
 use Auth;
 use Http;
 use Illuminate\Http\JsonResponse;
@@ -17,14 +16,14 @@ class BitpayX extends AbstractPayment
 
         $data = [
             'merchant_order_id' => $payment->trade_no,
-            'price_amount' => $payment->amount,
-            'price_currency' => 'CNY',
-            'title' => '支付单号:'.$payment->trade_no,
-            'description' => sysConfig('subject_name') ?: sysConfig('website_name'),
-            'callback_url' => route('payment.notify', ['method' => 'bitpayx']),
-            'success_url' => route('invoice'),
-            'cancel_url' => route('invoice'),
-            'token' => $this->sign($payment->trade_no),
+            'price_amount'      => $payment->amount,
+            'price_currency'    => 'CNY',
+            'title'             => '支付单号:'.$payment->trade_no,
+            'description'       => sysConfig('subject_name') ?: sysConfig('website_name'),
+            'callback_url'      => route('payment.notify', ['method' => 'bitpayx']),
+            'success_url'       => route('invoice'),
+            'cancel_url'        => route('invoice'),
+            'token'             => $this->sign($payment->trade_no),
         ];
         $result = $this->sendRequest($data);
 
@@ -44,8 +43,8 @@ class BitpayX extends AbstractPayment
     {
         $data = [
             'merchant_order_id' => $tradeNo,
-            'secret' => sysConfig('bitpay_secret'),
-            'type' => 'FIAT',
+            'secret'            => sysConfig('bitpay_secret'),
+            'type'              => 'FIAT',
         ];
 
         return $this->aliStyleSign($data, sysConfig('bitpay_secret'));
@@ -56,7 +55,7 @@ class BitpayX extends AbstractPayment
         $client = Http::baseUrl('https://api.mugglepay.com/v1/')
             ->timeout(15)
             ->withHeaders([
-                'token' => sysConfig('bitpay_secret'),
+                'token'        => sysConfig('bitpay_secret'),
                 'content-type' => 'application/json',
             ]);
 
@@ -77,13 +76,11 @@ class BitpayX extends AbstractPayment
     {
         $tradeNo = $request->input(['merchant_order_id']);
         if ($request->input(['status']) === 'PAID' && hash_equals($this->sign($tradeNo), $request->input(['token']))) {
-            $payment = Payment::whereTradeNo($tradeNo)->first();
-            if ($payment) {
-                $ret = $payment->order->update(['status' => 2]);
-                if ($ret) {
-                    exit(json_encode(['status' => 200]));
-                }
+            if ($this->paymentReceived($tradeNo)) {
+                exit(json_encode(['status' => 200]));
             }
+        } else {
+            Log::info('BitpayX:交易失败');
         }
         exit(json_encode(['status' => 400]));
     }

+ 13 - 15
app/Http/Controllers/Gateway/CodePay.php

@@ -2,9 +2,9 @@
 
 namespace App\Http\Controllers\Gateway;
 
-use App\Models\Payment;
 use Auth;
 use Illuminate\Http\JsonResponse;
+use Log;
 use Response;
 
 class CodePay extends AbstractPayment
@@ -14,12 +14,12 @@ class CodePay extends AbstractPayment
         $payment = $this->creatNewPayment(Auth::id(), $request->input('id'), $request->input('amount'));
 
         $data = [
-            'id' => sysConfig('codepay_id'),
-            'pay_id' => $payment->trade_no,
-            'type' => $request->input('type'),            //1支付宝支付 2QQ钱包 3微信支付
-            'price' => $payment->amount,
-            'page' => 1,
-            'outTime' => 900,
+            'id'         => sysConfig('codepay_id'),
+            'pay_id'     => $payment->trade_no,
+            'type'       => $request->input('type'),            //1支付宝支付 2QQ钱包 3微信支付
+            'price'      => $payment->amount,
+            'page'       => 1,
+            'outTime'    => 900,
             'notify_url' => route('payment.notify', ['method' => 'codepay']),
             'return_url' => route('invoice'),
         ];
@@ -33,16 +33,14 @@ class CodePay extends AbstractPayment
 
     public function notify($request): void
     {
-        $trade_no = $request->input('pay_id');
-        if ($trade_no && $request->input('pay_no')
+        $tradeNo = $request->input('pay_id');
+        if ($tradeNo && $request->input('pay_no')
             && $this->verify($request->except('method'), sysConfig('codepay_key'), $request->input('sign'), false)) {
-            $payment = Payment::whereTradeNo($trade_no)->first();
-            if ($payment) {
-                $ret = $payment->order->complete();
-                if ($ret) {
-                    exit('success');
-                }
+            if ($this->paymentReceived($tradeNo)) {
+                exit('success');
             }
+        } else {
+            Log::info('码支付:交易失败');
         }
         exit('fail');
     }

+ 13 - 15
app/Http/Controllers/Gateway/EPay.php

@@ -2,11 +2,11 @@
 
 namespace App\Http\Controllers\Gateway;
 
-use App\Models\Payment;
 use Auth;
 use Http;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
+use Log;
 use Response;
 
 class EPay extends AbstractPayment
@@ -29,14 +29,14 @@ class EPay extends AbstractPayment
         }
 
         $data = [
-            'pid' => sysConfig('epay_mch_id'),
-            'type' => $type,
-            'notify_url' => route('payment.notify', ['method' => 'epay']),
-            'return_url' => route('invoice'),
+            'pid'          => sysConfig('epay_mch_id'),
+            'type'         => $type,
+            'notify_url'   => route('payment.notify', ['method' => 'epay']),
+            'return_url'   => route('invoice'),
             'out_trade_no' => $payment->trade_no,
-            'name' => sysConfig('subject_name') ?: sysConfig('website_name'),
-            'money' => $payment->amount,
-            'sign_type' => 'MD5',
+            'name'         => sysConfig('subject_name') ?: sysConfig('website_name'),
+            'money'        => $payment->amount,
+            'sign_type'    => 'MD5',
         ];
         $data['sign'] = $this->aliStyleSign($data, sysConfig('epay_key'));
 
@@ -48,15 +48,13 @@ class EPay extends AbstractPayment
 
     public function notify(Request $request): void
     {
-        if ($request->input('trade_status') === 'TRADE_SUCCESS'
+        if ($request->input('trade_status') === 'TRADE_SUCCESS' && $request->has('out_trade_no')
             && $this->verify($request->except('method'), sysConfig('epay_key'), $request->input('sign'))) {
-            $payment = Payment::whereTradeNo($request->input('out_trade_no'))->first();
-            if ($payment) {
-                $ret = $payment->order->complete();
-                if ($ret) {
-                    exit('SUCCESS');
-                }
+            if ($this->paymentReceived($request->input('out_trade_no'))) {
+                exit('SUCCESS');
             }
+        } else {
+            Log::info('易支付:交易失败');
         }
         exit('FAIL');
     }

+ 16 - 21
app/Http/Controllers/Gateway/F2Fpay.php

@@ -2,7 +2,6 @@
 
 namespace App\Http\Controllers\Gateway;
 
-use App\Models\Payment;
 use Auth;
 use Exception;
 use Illuminate\Http\JsonResponse;
@@ -19,15 +18,15 @@ class F2Fpay extends AbstractPayment
     public function __construct()
     {
         self::$aliConfig = [
-            'use_sandbox' => false,
-            'app_id' => sysConfig('f2fpay_app_id'),
-            'sign_type' => 'RSA2',
-            'ali_public_key' => sysConfig('f2fpay_public_key'),
+            'use_sandbox'     => false,
+            'app_id'          => sysConfig('f2fpay_app_id'),
+            'sign_type'       => 'RSA2',
+            'ali_public_key'  => sysConfig('f2fpay_public_key'),
             'rsa_private_key' => sysConfig('f2fpay_private_key'),
-            'limit_pay' => [],
-            'notify_url' => route('payment.notify', ['method' => 'f2fpay']),
-            'return_url' => route('invoice'),
-            'fee_type' => 'CNY',
+            'limit_pay'       => [],
+            'notify_url'      => route('payment.notify', ['method' => 'f2fpay']),
+            'return_url'      => route('invoice'),
+            'fee_type'        => 'CNY',
         ];
     }
 
@@ -36,11 +35,11 @@ class F2Fpay extends AbstractPayment
         $payment = $this->creatNewPayment(Auth::id(), $request->input('id'), $request->input('amount'));
 
         $data = [
-            'body' => '',
-            'subject' => sysConfig('subject_name') ?: sysConfig('website_name'),
-            'trade_no' => $payment->trade_no,
+            'body'        => '',
+            'subject'     => sysConfig('subject_name') ?: sysConfig('website_name'),
+            'trade_no'    => $payment->trade_no,
             'time_expire' => time() + 900, // 必须 15分钟 内付款
-            'amount' => $payment->amount,
+            'amount'      => $payment->amount,
         ];
 
         try {
@@ -64,7 +63,7 @@ class F2Fpay extends AbstractPayment
     public function notify($request): void
     {
         $data = [
-            'trade_no' => $request->input('out_trade_no'),
+            'trade_no'       => $request->input('out_trade_no'),
             'transaction_id' => $request->input('trade_no'),
         ];
 
@@ -83,13 +82,9 @@ class F2Fpay extends AbstractPayment
         }
 
         if ($result['code'] == 10000 && $result['msg'] === 'Success') {
-            if ($_POST['trade_status'] === 'TRADE_FINISHED' || $_POST['trade_status'] === 'TRADE_SUCCESS') {
-                $payment = Payment::whereTradeNo($request->input('out_trade_no'))->first();
-                if ($payment) {
-                    $ret = $payment->order->update(['status' => 2]);
-                    if ($ret) {
-                        exit('success');
-                    }
+            if (($_POST['trade_status'] === 'TRADE_FINISHED' || $_POST['trade_status'] === 'TRADE_SUCCESS') && $request->has('out_trade_no')) {
+                if ($this->paymentReceived($request->input('out_trade_no'))) {
+                    exit('success');
                 }
             } else {
                 Log::info('支付宝当面付-POST:交易失败');

+ 1 - 1
app/Http/Controllers/Gateway/Local.php

@@ -23,7 +23,7 @@ class Local extends AbstractPayment
             Helpers::addUserCreditLog($user->id, $order->id, $user->credit + $order->amount, $user->credit, -1 * $order->amount, '购买商品'.$goods->name);
         }
 
-        $order->update(['status' => 2]);
+        $order->complete();
 
         return Response::json(['status' => 'success', 'message' => '购买完成!']);
     }

+ 8 - 12
app/Http/Controllers/Gateway/PayBeaver.php

@@ -7,7 +7,6 @@
 
 namespace App\Http\Controllers\Gateway;
 
-use App\Models\Payment;
 use Auth;
 use Http;
 use Illuminate\Http\JsonResponse;
@@ -31,11 +30,11 @@ class PayBeaver extends AbstractPayment
         $payment = $this->creatNewPayment(Auth::id(), $request->input('id'), $request->input('amount'));
 
         $result = $this->createOrder([
-            'app_id' => $this->appId,
+            'app_id'            => $this->appId,
             'merchant_order_id' => $payment->trade_no,
-            'price_amount' => $payment->amount * 100,
-            'notify_url' => route('payment.notify', ['method' => 'paybeaver']),
-            'return_url' => route('invoice'),
+            'price_amount'      => $payment->amount * 100,
+            'notify_url'        => route('payment.notify', ['method' => 'paybeaver']),
+            'return_url'        => route('invoice'),
         ]);
 
         if (isset($result['message'])) {
@@ -85,15 +84,12 @@ class PayBeaver extends AbstractPayment
             exit(json_encode(['status' => 400]));
         }
 
-        $tradeNo = $request->input(['merchant_order_id']);
-        $payment = Payment::whereTradeNo($tradeNo)->first();
-        if ($payment) {
-            $ret = $payment->order->update(['status' => 2]);
-            if ($ret) {
-                exit(json_encode(['status' => 200]));
-            }
+        if ($request->has(['merchant_order_id']) && $this->paymentReceived($request->input(['merchant_order_id']))) {
+            exit(json_encode(['status' => 200]));
         }
 
+        Log::info('海狸支付:交易失败');
+
         exit(json_encode(['status' => 500]));
     }
 

+ 9 - 11
app/Http/Controllers/Gateway/PayJs.php

@@ -2,9 +2,9 @@
 
 namespace App\Http\Controllers\Gateway;
 
-use App\Models\Payment;
 use Auth;
 use Illuminate\Http\JsonResponse;
+use Log;
 use Response;
 use Xhat\Payjs\Payjs as Pay;
 
@@ -16,7 +16,7 @@ class PayJs extends AbstractPayment
     {
         self::$config = [
             'mchid' => sysConfig('payjs_mch_id'),   // 配置商户号
-            'key' => sysConfig('payjs_key'),   // 配置通信密钥
+            'key'   => sysConfig('payjs_key'),   // 配置通信密钥
         ];
     }
 
@@ -25,10 +25,10 @@ class PayJs extends AbstractPayment
         $payment = $this->creatNewPayment(Auth::id(), $request->input('id'), $request->input('amount'));
 
         $result = (new Pay($this::$config))->cashier([
-            'body' => sysConfig('subject_name') ?: sysConfig('website_name'),
-            'total_fee' => $payment->amount * 100,
+            'body'         => sysConfig('subject_name') ?: sysConfig('website_name'),
+            'total_fee'    => $payment->amount * 100,
             'out_trade_no' => $payment->trade_no,
-            'notify_url' => route('payment.notify', ['method' => 'payjs']),
+            'notify_url'   => route('payment.notify', ['method' => 'payjs']),
         ]);
 
         // 获取收款二维码内容
@@ -43,13 +43,11 @@ class PayJs extends AbstractPayment
         $data = (new Pay($this::$config))->notify();
 
         if ($data['return_code'] == 1) {
-            $payment = Payment::whereTradeNo($data['out_trade_no'])->first();
-            if ($payment) {
-                $ret = $payment->order->complete();
-                if ($ret) {
-                    exit('success');
-                }
+            if ($this->paymentReceived($data['out_trade_no'])) {
+                exit('success');
             }
+        } else {
+            Log::info('PayJs:交易失败');
         }
         exit('fail');
     }

+ 4 - 6
app/Http/Controllers/Gateway/PayPal.php

@@ -124,13 +124,11 @@ class PayPal extends AbstractPayment
         $response = (string) $this->provider->verifyIPN($post);
 
         if ($response === 'VERIFIED' && $request['invoice']) {
-            $payment = Payment::whereTradeNo($request['invoice'])->first();
-            if ($payment && $payment->status === 0) {
-                $ret = $payment->order->complete();
-                if ($ret) {
-                    exit('success');
-                }
+            if ($this->paymentReceived($request['invoice'])) {
+                exit('success');
             }
+        } else {
+            Log::info('Paypal:交易失败');
         }
         exit('fail');
     }

+ 11 - 19
app/Http/Controllers/Gateway/Stripe.php

@@ -45,21 +45,21 @@ class Stripe extends AbstractPayment
 
         return [
             'payment_method_types' => ['card', 'alipay'],
-            'line_items' => [
+            'line_items'           => [
                 [
                     'price_data' => [
-                        'currency' => 'usd',
+                        'currency'     => 'usd',
                         'product_data' => ['name' => sysConfig('subject_name') ?: sysConfig('website_name')],
-                        'unit_amount' => $unitAmount,
+                        'unit_amount'  => $unitAmount,
                     ],
-                    'quantity' => 1,
+                    'quantity'   => 1,
                 ],
             ],
-            'mode' => 'payment',
-            'success_url' => route('invoice'),
-            'cancel_url' => route('invoice'),
-            'client_reference_id' => $tradeNo,
-            'customer_email' => Auth::getUser()->email,
+            'mode'                 => 'payment',
+            'success_url'          => route('invoice'),
+            'cancel_url'           => route('invoice'),
+            'client_reference_id'  => $tradeNo,
+            'customer_email'       => Auth::getUser()->email,
         ];
     }
 
@@ -103,13 +103,13 @@ class Stripe extends AbstractPayment
                 // account.
                 if ($session->payment_status == 'paid') {
                     // Fulfill the purchase
-                    $this->fulfillOrder($session);
+                    $this->paymentReceived($session->client_reference_id);
                 }
                 break;
             case 'checkout.session.async_payment_succeeded':
                 $session = $event->data->object;
                 // Fulfill the purchase
-                $this->fulfillOrder($session);
+                $this->paymentReceived($session->client_reference_id);
                 break;
             case 'checkout.session.async_payment_failed':
                 $session = $event->data->object;
@@ -122,14 +122,6 @@ class Stripe extends AbstractPayment
         exit();
     }
 
-    public function fulfillOrder(Session $session)
-    {
-        $payment = Payment::whereTradeNo($session->client_reference_id)->first();
-        if ($payment) {
-            $payment->order->complete();
-        }
-    }
-
     // 未支付成功则关闭订单
     public function failedPayment(Session $session)
     {

+ 1 - 6
app/Http/Controllers/PaymentController.php

@@ -23,11 +23,6 @@ use Illuminate\Http\Request;
 use Log;
 use Response;
 
-/**
- * 支付控制器.
- *
- * Class PaymentController
- */
 class PaymentController extends Controller
 {
     private static $method;
@@ -168,7 +163,7 @@ class PaymentController extends Controller
         // 生成订单
         try {
             $newOrder = Order::create([
-                'order_sn' => date('ymdHis').random_int(100000, 999999),
+                'sn' => date('ymdHis').random_int(100000, 999999),
                 'user_id' => auth()->id(),
                 'goods_id' => $credit ? null : $goods_id,
                 'coupon_id' => $coupon->id ?? null,

+ 16 - 28
app/Http/Controllers/UserController.php

@@ -3,9 +3,6 @@
 namespace App\Http\Controllers;
 
 use App\Components\Helpers;
-use App\Components\PushNotification;
-use App\Mail\newTicket;
-use App\Mail\replyTicket;
 use App\Models\Article;
 use App\Models\Coupon;
 use App\Models\Goods;
@@ -14,6 +11,9 @@ use App\Models\Node;
 use App\Models\NodeHeartbeat;
 use App\Models\Order;
 use App\Models\Ticket;
+use App\Models\User;
+use App\Notifications\TicketCreated;
+use App\Notifications\TicketReplied;
 use Cache;
 use DB;
 use Exception;
@@ -22,7 +22,7 @@ use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
 use Illuminate\Validation\Rule;
 use Log;
-use Mail;
+use Notification;
 use Redirect;
 use Response;
 use Session;
@@ -266,7 +266,7 @@ class UserController extends Controller
     // 订单明细
     public function invoiceDetail($sn)
     {
-        return view('user.invoiceDetail', ['order' => Order::uid()->whereOrderSn($sn)->with(['goods', 'coupon', 'payment'])->firstOrFail()]);
+        return view('user.invoiceDetail', ['order' => Order::uid()->whereSn($sn)->with(['goods', 'coupon', 'payment'])->firstOrFail()]);
     }
 
     // 添加工单
@@ -283,17 +283,12 @@ class UserController extends Controller
             ]);
         }
 
-        if ($user->tickets()->create(compact('title', 'content'))) {
-            $emailTitle = trans('common.new').trans('user.ticket.attribute');
-            $content = trans('validation.attributes.title').':【'.$title.'】<br>'.trans('validation.attributes.email').':'.$user->email.'<br>'.trans('validation.attributes.content').':'.$content;
-
-            // 发邮件通知管理员
-            if (sysConfig('webmaster_email')) {
-                $logId = Helpers::addNotificationLog($emailTitle, $content, 1, sysConfig('webmaster_email'));
-                Mail::to(sysConfig('webmaster_email'))->send(new newTicket($logId, $emailTitle, $content));
-            }
-
-            PushNotification::send($emailTitle, $content);
+        if ($ticket = $user->tickets()->create(compact('title', 'content'))) {
+            // 通知相关管理员
+            Notification::send(User::permission('admin.ticket.edit,update')->orWhere(function ($query) {
+                return $query->role('Super Admin');
+            })->get(),
+                new TicketCreated($ticket->title, $ticket->content, route('admin.ticket.edit', $ticket)));
 
             return Response::json(['status' => 'success', 'message' => trans('common.submit_item', ['attribute' => trans('common.success')])]);
         }
@@ -326,16 +321,11 @@ class UserController extends Controller
                 $ticket->status = 0;
                 $ticket->save();
 
-                $title = trans('user.ticket.attribute').trans('user.ticket.reply');
-                $content = trans('validation.attributes.title').':【'.$ticket->title.'】<br>'.trans('user.ticket.reply').':'.$content;
-
-                // 发邮件通知管理员
-                if (sysConfig('webmaster_email')) {
-                    $logId = Helpers::addNotificationLog($title, $content, 1, sysConfig('webmaster_email'));
-                    Mail::to(sysConfig('webmaster_email'))->send(new replyTicket($logId, $title, $content));
-                }
-
-                PushNotification::send($title, $content);
+                // 通知相关管理员
+                Notification::send(User::permission('admin.ticket.edit,update')->orWhere(function ($query) {
+                    return $query->role('Super Admin');
+                })->get(),
+                    new TicketReplied($ticket->title, $content, route('admin.ticket.edit', $ticket)));
 
                 return Response::json(['status' => 'success', 'message' => trans('user.ticket.reply').trans('common.success')]);
             }
@@ -355,8 +345,6 @@ class UserController extends Controller
         $id = $request->input('id');
 
         if (Ticket::uid()->whereId($id)->close()) {
-            PushNotification::send(trans('common.close_item', ['attribute' => trans('user.ticket.attribute')]), trans('user.ticket.close_msg', ['id' => $id]));
-
             return Response::json(['status' => 'success', 'message' => trans('common.close_item', ['attribute' => trans('common.success')])]);
         }
 

+ 0 - 36
app/Mail/activeUser.php

@@ -1,36 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class activeUser extends Mailable implements ShouldQueue
-{
-    use Queueable;
-    use SerializesModels;
-
-    protected $id; // 邮件记录ID
-    protected $activeUserUrl; // 激活用户URL
-
-    public function __construct($id, $activeUserUrl)
-    {
-        $this->id = $id;
-        $this->activeUserUrl = $activeUserUrl;
-    }
-
-    public function build(): activeUser
-    {
-        return $this->view('emails.activeUser')->subject('激活账号')->with(['activeUserUrl' => $this->activeUserUrl]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 41
app/Mail/closeTicket.php

@@ -1,41 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class closeTicket extends Mailable implements ShouldQueue
-{
-    use Queueable;
-    use SerializesModels;
-
-    protected $id; // 邮件记录ID
-    protected $title; // 工单标题
-    protected $content; // 工单内容
-
-    public function __construct($id, $title, $content)
-    {
-        $this->id = $id;
-        $this->title = $title;
-        $this->content = $content;
-    }
-
-    public function build(): closeTicket
-    {
-        return $this->view('emails.closeTicket')->subject('工单关闭提醒')->with([
-            'title' => $this->title,
-            'content' => $this->content,
-        ]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 41
app/Mail/newTicket.php

@@ -1,41 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class newTicket extends Mailable implements ShouldQueue
-{
-    use Queueable;
-    use SerializesModels;
-
-    protected $id; // 邮件记录ID
-    protected $title; // 工单标题
-    protected $content; // 工单内容
-
-    public function __construct($id, $title, $content)
-    {
-        $this->id = $id;
-        $this->title = $title;
-        $this->content = $content;
-    }
-
-    public function build(): newTicket
-    {
-        return $this->view('emails.newTicket')->subject('新工单提醒')->with([
-            'title' => $this->title,
-            'content' => $this->content,
-        ]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 34
app/Mail/nodeCrashWarning.php

@@ -1,34 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class nodeCrashWarning extends Mailable implements ShouldQueue
-{
-    use Queueable;
-    use SerializesModels;
-
-    protected $id; // 邮件记录ID
-
-    public function __construct($id)
-    {
-        $this->id = $id;
-    }
-
-    public function build(): nodeCrashWarning
-    {
-        return $this->view('emails.nodeCrashWarning')->subject('节点阻断警告')->with(['content' => NotificationLog::find($this->id)->content]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 40
app/Mail/replyTicket.php

@@ -1,40 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class replyTicket extends Mailable implements ShouldQueue
-{
-    use Queueable, SerializesModels;
-
-    protected $id; // 邮件记录ID
-    protected $title; // 工单标题
-    protected $content; // 工单内容
-
-    public function __construct($id, $title, $content)
-    {
-        $this->id = $id;
-        $this->title = $title;
-        $this->content = $content;
-    }
-
-    public function build(): replyTicket
-    {
-        return $this->view('emails.replyTicket')->subject('工单回复提醒')->with([
-            'title' => $this->title,
-            'content' => $this->content,
-        ]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 35
app/Mail/resetPassword.php

@@ -1,35 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class resetPassword extends Mailable implements ShouldQueue
-{
-    use Queueable, SerializesModels;
-
-    protected $id; // 邮件记录ID
-    protected $resetPasswordUrl; // 重置密码URL
-
-    public function __construct($id, $resetPasswordUrl)
-    {
-        $this->id = $id;
-        $this->resetPasswordUrl = $resetPasswordUrl;
-    }
-
-    public function build(): resetPassword
-    {
-        return $this->view('emails.resetPassword')->subject('重置密码')->with(['resetPasswordUrl' => $this->resetPasswordUrl]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 35
app/Mail/sendUserInfo.php

@@ -1,35 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class sendUserInfo extends Mailable implements ShouldQueue
-{
-    use Queueable, SerializesModels;
-
-    protected $id; // 邮件记录ID
-    protected $content; // 账号信息
-
-    public function __construct($id, $content)
-    {
-        $this->id = $id;
-        $this->content = $content;
-    }
-
-    public function build(): sendUserInfo
-    {
-        return $this->view('emails.sendUserInfo')->subject('发送账号信息')->with(['content' => $this->content]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 35
app/Mail/sendVerifyCode.php

@@ -1,35 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class sendVerifyCode extends Mailable implements ShouldQueue
-{
-    use Queueable, SerializesModels;
-
-    protected $id; // 邮件记录ID
-    protected $code; // 要发送的验证码
-
-    public function __construct($id, $code)
-    {
-        $this->id = $id;
-        $this->code = $code;
-    }
-
-    public function build(): sendVerifyCode
-    {
-        return $this->view('emails.sendVerifyCode')->subject(trans('auth.register.code'))->with(['code' => $this->code]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 35
app/Mail/userExpireWarning.php

@@ -1,35 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class userExpireWarning extends Mailable implements ShouldQueue
-{
-    use Queueable, SerializesModels;
-
-    protected $id; // 邮件记录ID
-    protected $lastCanUseDays; // 剩余可用天数
-
-    public function __construct($id, $lastCanUseDays)
-    {
-        $this->id = $id;
-        $this->lastCanUseDays = $lastCanUseDays;
-    }
-
-    public function build(): userExpireWarning
-    {
-        return $this->view('emails.userExpireWarning')->subject('账号过期提醒')->with(['lastCanUseDays' => $this->lastCanUseDays]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 33
app/Mail/userExpireWarningToday.php

@@ -1,33 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class userExpireWarningToday extends Mailable implements ShouldQueue
-{
-    use Queueable, SerializesModels;
-
-    protected $id; // 邮件记录ID
-
-    public function __construct($id)
-    {
-        $this->id = $id;
-    }
-
-    public function build(): userExpireWarningToday
-    {
-        return $this->view('emails.userExpireWarningToday')->subject('账号过期提醒');
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 0 - 35
app/Mail/userTrafficWarning.php

@@ -1,35 +0,0 @@
-<?php
-
-namespace App\Mail;
-
-use App\Models\NotificationLog;
-use Exception;
-use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
-use Illuminate\Mail\Mailable;
-use Illuminate\Queue\SerializesModels;
-
-class userTrafficWarning extends Mailable implements ShouldQueue
-{
-    use Queueable, SerializesModels;
-
-    protected $id; // 邮件记录ID
-    protected $usedPercent; // 已使用百分比
-
-    public function __construct($id, $usedPercent)
-    {
-        $this->id = $id;
-        $this->usedPercent = $usedPercent;
-    }
-
-    public function build(): userTrafficWarning
-    {
-        return $this->view('emails.userTrafficWarning')->subject('流量警告')->with(['usedPercent' => $this->usedPercent]);
-    }
-
-    // 发件失败处理
-    public function failed(Exception $e): void
-    {
-        NotificationLog::whereId($this->id)->update(['status' => -1, 'error' => $e->getMessage()]);
-    }
-}

+ 34 - 0
app/Notifications/AccountActivation.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class AccountActivation extends Notification
+{
+    use Queueable;
+
+    private $url;
+
+    public function __construct($url)
+    {
+        $this->url = $url;
+    }
+
+    public function via($notifiable)
+    {
+        return ['mail'];
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(__('Verify Email Address'))
+            ->line(__('Please click the button below to verify your email address.'))
+            ->action(__('Verify Your Email Address'), $this->url)
+            ->line(__('If you did not create an account, no further action is required.'));
+    }
+}

+ 48 - 0
app/Notifications/AccountExpire.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class AccountExpire extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $days;
+
+    public function __construct($expired_at)
+    {
+        $this->days = now()->diffInDays($expired_at);
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('account_expire_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(trans('notification.account_expired'))
+            ->line(trans('notification.account_expired_content', ['days' => $this->days]))
+            ->action(trans('notification.view_web'), url('/'));
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            'days' => $this->days,
+        ];
+    }
+
+    public function toCustom($notifiable)
+    {
+        return [
+            'title'   => trans('notification.account_expired'),
+            'content' => trans('notification.account_expired_content', ['days' => $this->days]),
+        ];
+    }
+}

+ 51 - 0
app/Notifications/Custom.php

@@ -0,0 +1,51 @@
+<?php
+
+namespace App\Notifications;
+
+use App\Channels\BarkChannel;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class Custom extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $title;
+    private $content;
+
+    public function __construct($title, $content)
+    {
+        $this->title = $title;
+        $this->content = $content;
+    }
+
+    public function via($notifiable)
+    {
+        return $notifiable ?? ['mail', BarkChannel::class];
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject($this->title)
+            ->markdown('mail.custom', ['content' => $this->content]);
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            'title'   => $this->title,
+            'content' => $this->content,
+        ];
+    }
+
+    public function toCustom($notifiable)
+    {
+        return [
+            'title'   => $this->title,
+            'content' => $this->content,
+        ];
+    }
+}

+ 44 - 0
app/Notifications/DataAnomaly.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class DataAnomaly extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $upload;
+    private $download;
+    private $total;
+
+    public function __construct($id, $upload, $download, $total)
+    {
+        $this->id = $id;
+        $this->upload = $upload;
+        $this->download = $download;
+        $this->total = $total;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('data_anomaly_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(trans('notification.data_anomaly'))
+            ->line(trans('notification.data_anomaly', ['id' => $this->id, 'upload' => $this->upload, 'download' => $this->download, 'total' => $this->total]));
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            //
+        ];
+    }
+}

+ 41 - 0
app/Notifications/DataExhaust.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class DataExhaust extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $percent;
+
+    public function __construct($percent)
+    {
+        $this->percent = $percent;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('data_exhaust_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(trans('notification.traffic_warning'))
+            ->line(trans('notification.traffic_remain', ['num' => $this->percent]))
+            ->line(trans('notification.traffic_tips'))
+            ->action(trans('notification.view_web'), url('/'));
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            //
+        ];
+    }
+}

+ 40 - 0
app/Notifications/NodeBlocked.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class NodeBlocked extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $content;
+
+    public function __construct($content)
+    {
+        $this->content = $content;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('node_blocked_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(trans('notification.node_block'))
+            ->line(trans('notification.block_report'))
+            ->line($this->content);
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            //
+        ];
+    }
+}

+ 44 - 0
app/Notifications/NodeDailyReport.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class NodeDailyReport extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $content;
+
+    public function __construct($nodes)
+    {
+        $temp = '| '.trans('user.attribute.node').' | '.trans('notification.node.upload').' | '.trans('notification.node.download').' | '.trans('notification.node.total')." |\r\n| ------ | :------: | :------: | ------: |\r\n";
+        foreach ($nodes as $node) {
+            $temp .= "| {$node['name']} | {$node['upload']} | {$node['download']} | {$node['total']} |\r\n";
+        }
+        $this->content = $temp;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('node_daily_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(__('Nodes Daily Report'))
+            ->markdown('mail.node.dailyReport', ['content' => $this->content]);
+    }
+
+    public function toCustom($notifiable)
+    {
+        return [
+            'title'   => __('Nodes Daily Report'),
+            'content' => $this->content,
+        ];
+    }
+}

+ 41 - 0
app/Notifications/NodeOffline.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class NodeOffline extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $name;
+    private $ip;
+
+    public function __construct($name, $ip)
+    {
+        $this->name = $name;
+        $this->ip = $ip;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('node_offline_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(trans('notification.node_offline', ['name' => $this->name]))
+            ->line(trans('notification.node_offline_content', ['name' => $this->name, 'ip' => $this->ip]));
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            //
+        ];
+    }
+}

+ 41 - 0
app/Notifications/PasswordReset.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class PasswordReset extends Notification
+{
+    use Queueable;
+
+    private $url;
+
+    public function __construct($url)
+    {
+        $this->url = $url;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('password_reset_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(__('Reset Password Notification'))
+            ->line(__('Please click the button below to reset your password.'))
+            ->action(__('Reset Password'), $this->url)
+            ->line(__('You are receiving this email because we received a password reset request for your account.'))
+            ->line(__('If you did not request a password reset, no further action is required.'));
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            //
+        ];
+    }
+}

+ 42 - 0
app/Notifications/PaymentReceived.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class PaymentReceived extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $amount;
+    private $sn;
+
+    public function __construct($sn, $amount)
+    {
+        $this->amount = $amount;
+        $this->sn = $sn;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('payment_received_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->line(__('Payment for #:sn has been received! Total amount: ¥:amount.', ['sn' => $this->sn, 'amount' => $this->amount]))
+            ->action(__('Invoice Detail'), route('invoiceInfo', $this->sn));
+    }
+
+    public function toDataBase($notifiable)
+    {
+        return [
+            'sn'     => $this->sn,
+            'amount' => $this->amount,
+        ];
+    }
+}

+ 46 - 0
app/Notifications/TicketClosed.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class TicketClosed extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $title;
+    private $url;
+    private $reason;
+
+    public function __construct($id, $title, $url, $reason)
+    {
+        $this->id = $id;
+        $this->title = $title;
+        $this->url = $url;
+        $this->reason = $reason;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('ticket_closed_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(trans('close_ticket', ['id' => $this->id, 'title' => $this->title]))
+            ->line($this->reason)
+            ->action(trans('notification.view_ticket'), $this->url)
+            ->line(__('If your problem has not been solved, Feel free to open other one.'));
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+
+        ];
+    }
+}

+ 45 - 0
app/Notifications/TicketCreated.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class TicketCreated extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $title;
+    private $content;
+    private $url;
+
+    public function __construct($title, $content, $url)
+    {
+        $this->title = $title;
+        $this->content = $content;
+        $this->url = $url;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('ticket_created_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(trans('notification.new_ticket', ['title' => $this->title]))
+            ->line(trans('notification.ticket_content'))
+            ->line($this->content)
+            ->action(trans('notification.view_ticket'), $this->url);
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            //
+        ];
+    }
+}

+ 45 - 0
app/Notifications/TicketReplied.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class TicketReplied extends Notification implements ShouldQueue
+{
+    use Queueable;
+
+    private $title;
+    private $content;
+    private $url;
+
+    public function __construct($title, $content, $url)
+    {
+        $this->title = $title;
+        $this->content = $content;
+        $this->url = $url;
+    }
+
+    public function via($notifiable)
+    {
+        return sysConfig('ticket_replied_notification');
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(trans('notification.reply_ticket', ['title' => $this->title]))
+            ->line(trans('notification.ticket_content'))
+            ->line($this->content)
+            ->action(trans('notification.view_ticket'), $this->url);
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            //
+        ];
+    }
+}

+ 39 - 0
app/Notifications/Verification.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Notifications\Messages\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class Verification extends Notification
+{
+    use Queueable;
+
+    private $code;
+
+    public function __construct($code)
+    {
+        $this->code = $code;
+    }
+
+    public function via($notifiable)
+    {
+        return ['mail'];
+    }
+
+    public function toMail($notifiable)
+    {
+        return (new MailMessage)
+            ->subject(trans('notification.verification_account'))
+            ->line(trans('notification.verification'))
+            ->line($this->code);
+    }
+
+    public function toArray($notifiable)
+    {
+        return [
+            //
+        ];
+    }
+}

+ 2 - 0
composer.json

@@ -21,6 +21,8 @@
     "ip2location/ip2location-laravel": "^1.2",
     "ipip/db": "^1.0",
     "jenssegers/agent": "^2.6",
+    "laravel-notification-channels/bearychat": "^1.4",
+    "laravel-notification-channels/telegram": "^0.5.1",
     "laravel/framework": "^7.29",
     "laravel/tinker": "^2.5",
     "mews/captcha": "^3.1",

+ 246 - 1
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "04879cdf04f34417c35aebbabc2229f6",
+    "content-hash": "e54f2dd2cc06b1714a2a49ba599c5449",
     "packages": [
         {
             "name": "asm89/stack-cors",
@@ -842,6 +842,137 @@
             ],
             "time": "2020-12-29T14:50:06+00:00"
         },
+        {
+            "name": "elfsundae/bearychat",
+            "version": "1.3.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ElfSundae/bearychat.git",
+                "reference": "b3c7437d0e24463504679931a482e9b642d93024"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ElfSundae/bearychat/zipball/b3c7437d0e24463504679931a482e9b642d93024",
+                "reference": "b3c7437d0e24463504679931a482e9b642d93024",
+                "shasum": ""
+            },
+            "require": {
+                "ext-mbstring": "*",
+                "guzzlehttp/guzzle": "~5.3|~6.0",
+                "php": ">=5.4.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "0.9.*",
+                "phpunit/phpunit": "~5.7"
+            },
+            "suggest": {
+                "elfsundae/laravel-bearychat": "Required for Laravel integration.",
+                "laravel-notification-channels/bearychat": "BearyChat notifications channel for Laravel 5."
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "ElfSundae\\BearyChat\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Elf Sundae",
+                    "email": "elf.sundae@gmail.com",
+                    "homepage": "https://0x123.com"
+                }
+            ],
+            "description": "An elegant way of interacting with BearyChat webhooks.",
+            "homepage": "https://github.com/ElfSundae/bearychat",
+            "keywords": [
+                "bearychat",
+                "incoming",
+                "outgoing",
+                "robot",
+                "webhook"
+            ],
+            "support": {
+                "issues": "https://github.com/ElfSundae/bearychat/issues",
+                "source": "https://github.com/ElfSundae/bearychat/tree/master"
+            },
+            "time": "2017-09-04T05:54:05+00:00"
+        },
+        {
+            "name": "elfsundae/laravel-bearychat",
+            "version": "1.6.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ElfSundae/laravel-bearychat.git",
+                "reference": "417a15868e46c9d664a437532c5ddd9be3fe9b04"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ElfSundae/laravel-bearychat/zipball/417a15868e46c9d664a437532c5ddd9be3fe9b04",
+                "reference": "417a15868e46c9d664a437532c5ddd9be3fe9b04",
+                "shasum": ""
+            },
+            "require": {
+                "elfsundae/bearychat": "^1.3.1",
+                "illuminate/support": "~5.0|~6.0|~7.0|~8.0",
+                "php": ">=5.6.4"
+            },
+            "require-dev": {
+                "mockery/mockery": "~0.9|~1.0",
+                "phpunit/phpunit": "~5.7|~6.0|~7.0|~8.0|~9.0"
+            },
+            "suggest": {
+                "laravel-notification-channels/bearychat": "BearyChat notifications channel for Laravel 5."
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "ElfSundae\\BearyChat\\Laravel\\ServiceProvider"
+                    ],
+                    "aliases": {
+                        "BearyChat": "ElfSundae\\BearyChat\\Laravel\\BearyChat"
+                    }
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "ElfSundae\\BearyChat\\Laravel\\": "src/"
+                },
+                "files": [
+                    "src/helpers.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Elf Sundae",
+                    "email": "elf.sundae@gmail.com",
+                    "homepage": "https://0x123.com"
+                }
+            ],
+            "description": "Laravel integration for BearyChat.",
+            "homepage": "https://github.com/ElfSundae/laravel-bearychat",
+            "keywords": [
+                "bearychat",
+                "incoming",
+                "laravel",
+                "outgoing",
+                "robot",
+                "webhook"
+            ],
+            "support": {
+                "issues": "https://github.com/ElfSundae/laravel-bearychat/issues",
+                "source": "https://github.com/ElfSundae/laravel-bearychat/tree/1.6.0"
+            },
+            "time": "2020-09-13T14:19:31+00:00"
+        },
         {
             "name": "ezyang/htmlpurifier",
             "version": "v4.13.0",
@@ -1685,6 +1816,120 @@
             },
             "time": "2020-11-30T20:35:41+00:00"
         },
+        {
+            "name": "laravel-notification-channels/bearychat",
+            "version": "1.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel-notification-channels/bearychat.git",
+                "reference": "b04ac9bad37cd08cf177a342b3e2b831c87b2a96"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel-notification-channels/bearychat/zipball/b04ac9bad37cd08cf177a342b3e2b831c87b2a96",
+                "reference": "b04ac9bad37cd08cf177a342b3e2b831c87b2a96",
+                "shasum": ""
+            },
+            "require": {
+                "elfsundae/laravel-bearychat": "~1.4",
+                "illuminate/notifications": "~5.3|~6.0|~7.0|~8.0",
+                "php": ">=5.6.4"
+            },
+            "require-dev": {
+                "mockery/mockery": "~1.0",
+                "phpunit/phpunit": "~5.7|~6.0|~7.0|~8.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "NotificationChannels\\BearyChat\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Elf Sundae",
+                    "email": "elf.sundae@gmail.com",
+                    "homepage": "https://github.com/ElfSundae",
+                    "role": "Developer"
+                }
+            ],
+            "description": "BearyChat notifications channel for Laravel.",
+            "homepage": "https://github.com/laravel-notification-channels/bearychat",
+            "support": {
+                "issues": "https://github.com/laravel-notification-channels/bearychat/issues",
+                "source": "https://github.com/laravel-notification-channels/bearychat/tree/1.4.0"
+            },
+            "time": "2020-09-13T14:32:13+00:00"
+        },
+        {
+            "name": "laravel-notification-channels/telegram",
+            "version": "0.5.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel-notification-channels/telegram.git",
+                "reference": "2cedb10b78219cc91a285eaa5a3de0db405cc207"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel-notification-channels/telegram/zipball/2cedb10b78219cc91a285eaa5a3de0db405cc207",
+                "reference": "2cedb10b78219cc91a285eaa5a3de0db405cc207",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "guzzlehttp/guzzle": "^6.2 || ^7.0",
+                "illuminate/notifications": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+                "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+                "php": "^7.1 || ^8.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.3",
+                "phpunit/phpunit": "^7.0 || ^8.0"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "NotificationChannels\\Telegram\\TelegramServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "NotificationChannels\\Telegram\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Irfaq Syed",
+                    "email": "syed@lukonet.com",
+                    "homepage": "https://lukonet.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Telegram Notifications Channel for Laravel",
+            "homepage": "https://github.com/laravel-notification-channels/telegram",
+            "keywords": [
+                "laravel",
+                "notification",
+                "telegram",
+                "telegram notification",
+                "telegram notifications channel"
+            ],
+            "support": {
+                "issues": "https://github.com/laravel-notification-channels/telegram/issues",
+                "source": "https://github.com/laravel-notification-channels/telegram/tree/0.5.1"
+            },
+            "time": "2020-12-06T19:00:18+00:00"
+        },
         {
             "name": "laravel/framework",
             "version": "v7.30.1",

+ 70 - 0
database/migrations/2021_01_15_065207_create_notifications_table.php

@@ -0,0 +1,70 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateNotificationsTable extends Migration
+{
+    private $configs = [
+        'account_expire_notification',
+        'data_anomaly_notification',
+        'data_exhaust_notification',
+        'node_blocked_notification',
+        'node_daily_notification',
+        'node_offline_notification',
+        'password_reset_notification',
+        'payment_received_notification',
+        'ticket_closed_notification',
+        'ticket_created_notification',
+        'ticket_replied_notification',
+    ];
+
+    private $dropConfigs = [
+        'is_reset_password',
+        'expire_warning',
+        'traffic_warning',
+        'is_node_offline',
+        'node_daily_report',
+        'nodes_detection',
+        'is_notification',
+    ];
+
+    public function up()
+    {
+        Schema::create('notifications', function (Blueprint $table) {
+            $table->uuid('id')->primary();
+            $table->string('type');
+            $table->morphs('notifiable');
+            $table->text('data');
+            $table->timestamp('read_at')->nullable();
+            $table->timestamps();
+        });
+        Schema::table('order', function (Blueprint $table) {
+            $table->renameColumn('order_sn', 'sn');
+        });
+
+        foreach ($this->configs as $config) {
+            \App\Models\Config::insert(['name' => $config]);
+        }
+        \App\Models\Config::whereIn('name', $this->dropConfigs)->delete();
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('notifications');
+        Schema::table('order', function (Blueprint $table) {
+            $table->renameColumn('sn', 'order_sn');
+        });
+
+        foreach ($this->dropConfigs as $config) {
+            \App\Models\Config::insert(['name' => $config]);
+        }
+        \App\Models\Config::whereIn('name', $this->configs)->delete();
+    }
+}

+ 0 - 1
resources/lang/en/auth.php

@@ -10,7 +10,6 @@ return [
             'throttle'  => 'Anti-bots Shield Active! Please do not send multiple activate from at short amount of times! If you have any questions, please contact :email',
         ],
         'promotion' => ['0' => 'Account has not been activated,Please', '1' => 'before login!'],
-        'sent'      => 'Email has been sent! Please check your mailbox! (Email may be in the Trash)',
     ],
     'aup'             => 'Acceptable Use Policy',
     'captcha'         => [

+ 34 - 0
resources/lang/en/notification.php

@@ -0,0 +1,34 @@
+<?php
+
+return [
+    'attribute'               => 'NOTIFICATIONS',
+    'new'                     => ':num new message|:num new messages',
+    'empty'                   => 'No new message',
+    'payment_received'        => 'Order has paid, Amount:¥:amount! Click me to view the detail',
+    'account_expired'         => 'Account Going to Expired',
+    'account_expired_content' => 'Your account will be expired after【:days】days. For your server experience, please renew your account ahead of time.',
+    'account_expired_blade'   => 'Account will be expired after【:days】days, Please renew',
+    'active_email'            => 'Please completed this action under 30 minutes',
+    'close_ticket'            => 'Ticket #【:id】 - :title Closed',
+    'view_web'                => 'View Our Website',
+    'view_ticket'             => 'View The Ticket',
+    'new_ticket'              => 'New Ticket Opened: :title',
+    'reply_ticket'            => 'New Ticket Replied: :title',
+    'ticket_content'          => 'Ticket Content: ',
+    'node_block'              => 'Node Blocked Warning',
+    'node_offline'            => 'Node [:name] maybe offline!',
+    'node_offline_content'    => 'Node :name 【:ip】abnormal: return heartbeats information are abnormal, Please pay attention.',
+    'block_report'            => 'Blocked Report: ',
+    'traffic_warning'         => 'Data Traffic Waring: ',
+    'traffic_remain'          => 'Data Traffic Consumption: :num%',
+    'traffic_tips'            => 'Please pay attention on the service reset day. You may also cloud consider reset your data before the reset day.',
+    'verification_account'    => 'Account Verification',
+    'verification'            => 'Your verification code: ',
+    'data_anomaly'            => 'User Data Traffic Abnormal Warning',
+    'data_anomaly_content'    => 'User :id:Recent Hourly Data Usage [Upload: :upload | Download: :download | Total: :total]',
+    'node'                    => [
+        'upload'   => 'Upload',
+        'download' => 'download',
+        'total'    => 'Total',
+    ],
+];

+ 26 - 0
resources/lang/zh-CN.json

@@ -0,0 +1,26 @@
+{
+  "All rights reserved.": "版本所有。",
+  "Hello!": "您好:",
+  "If you did not create an account, no further action is required.": "如果您未注册帐号,请忽略此邮件。",
+  "If you did not request a password reset, no further action is required.": "如果您未申请重设密码,请忽略此邮件。",
+  "If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser:": "如果您点击「:actionText」按钮时出现问题,请复制下方链接到浏览器中开启:",
+  "If your problem has not been solved, Feel free to open other one.": "如果您的问题尚未解决,请另开工单解决。",
+  "Invoice Detail": "订单明细",
+  "Nodes Daily Report": "线路每日流量报告",
+  "Payment for #:sn has been received! Total amount: ¥:amount.": "您成功支付了订单#:sn,总金额为 ¥:amount。",
+  "Please click the button below to verify your email address.": "请点击下面按钮验证您的 E-mail:",
+  "Please click the button below to reset your password.": "请点击下面按钮重置您的密码:",
+  "Regards": "致敬",
+  "Reset Password Notification": "重设密码通知",
+  "Reset Password": "重设密码",
+  "Send Password Reset Link": "发送重设密码链接",
+  "Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn't receive the email, we will gladly send you another.": "感谢您的注册! 在开始之前,您需要通过点击我们刚刚发送至您邮箱中的链接来验证您的电子邮件! 如果您没有收到电子邮件,我们很乐意再发送一封给您。",
+  "Too Many Attempts.": "尝试次数过多",
+  "Too Many Requests": "请求次数过多",
+  "Verify Email Address": "验证 E-mail",
+  "Verify Your Email Address": "验证 您的E-mail",
+  "We won't ask for your password again for a few hours.": "确认完成后,接下来几个小时内您不需再输入密码。",
+  "You are receiving this email because we received a password reset request for your account.": "您收到此电子邮件是因为我们收到了您帐户的密码重设请求。",
+  "Your email address is not verified.": "您的电子邮件尚未验证通过",
+  "You have not responded this ticket in :num hours, System has closed your ticket.": "超过:num小时未回复工单,系统已自动关闭了您的工单"
+}

+ 0 - 1
resources/lang/zh-CN/auth.php

@@ -10,7 +10,6 @@ return [
             'throttle'  => '您已触发本站激活请求限制机制,请勿频繁操作!如有问题,请联系:email',
         ],
         'promotion' => ['0' => '账号尚未激活,请点击', '1' => '启动激活程序!'],
-        'sent'      => '激活邮件已发送! 请查看注册所用邮箱(邮件可能在垃圾箱中)',
     ],
     'aup'             => '可接受使用条款',
     'captcha'         => [

+ 1 - 1
resources/lang/zh-CN/common.php

@@ -28,7 +28,7 @@ return [
     'generate'       => '生 成',
     'generate_item'  => '生成:attribute',
     'to_safari'      => ['0' => '点击右上角', '1' => ',选择在', '2' => 'Safari 中打开', '3' => '就可以正常访问本站了哟!'],
-    'update_browser' => ['0' => '您正在使用', '1' => '过时', '2' => ' 的浏览器。 请', '3' => '升级您的浏览器', '4'=>'来获得最佳的浏览体验'],
+    'update_browser' => ['0' => '您正在使用', '1' => '过时', '2' => ' 的浏览器。 请', '3' => '升级您的浏览器', '4' => '来获得最佳的浏览体验'],
     'apply'          => '应 用',
     'avatar'         => '头像',
     'customize'      => '自定义',

+ 34 - 0
resources/lang/zh-CN/notification.php

@@ -0,0 +1,34 @@
+<?php
+
+return [
+    'attribute'               => '通知',
+    'new'                     => ':num条新消息',
+    'empty'                   => '目前未收到新消息',
+    'payment_received'        => '订单支付成功,金额:¥:amount,查看详情',
+    'account_expired'         => '账号过期提醒',
+    'account_expired_content' => '您的账号将在【:days】天后过期,为了确保您可以继续正常使用我们的服务,请及时续费。',
+    'account_expired_blade'   => '账号将于【:days天】后过期,请及时续费',
+    'active_email'            => '请在30分钟内完成操作',
+    'close_ticket'            => '工单【:id】:title关闭',
+    'view_web'                => '访问官网',
+    'view_ticket'             => '访问工单',
+    'new_ticket'              => '收到新工单::title',
+    'reply_ticket'            => '工单回复::title',
+    'ticket_content'          => '工单内容:',
+    'node_block'              => '节点阻断警告',
+    'node_offline'            => '节点[:name]异常警告',
+    'node_offline_content'    => '节点:name【:ip】异常:心跳异常,可能离线了',
+    'block_report'            => '阻断日志:',
+    'traffic_warning'         => '流量提醒',
+    'traffic_remain'          => '流量已使用::num%,请保持关注。',
+    'traffic_tips'            => '请注意套餐流量重置日,合理分配流量使用或在流量耗尽后,付费重置套餐流量',
+    'verification_account'    => '账号验证',
+    'verification'            => '您的验证码:',
+    'data_anomaly'            => '流量异常用户提醒',
+    'data_anomaly_content'    => '用户:id:最近1小时 [上行流量::upload | 下行流量::download | 共计::total]',
+    'node'                    => [
+        'upload'   => '上传',
+        'download' => '下载',
+        'total'    => '总计',
+    ],
+];

+ 5 - 5
resources/lang/zh-CN/user.php

@@ -57,11 +57,11 @@ return [
     'purchase_required'   => '本功能对非付费用户禁用!请',
     'more'                => '更多',
     'attribute'           => [
-        'node'    => '线路',
-        'data'    => '流量',
-        'ip'      => 'IP地址',
-        'isp'     => '运营商',
-        'address' => '地区',
+        'node'     => '线路',
+        'data'     => '流量',
+        'ip'       => 'IP地址',
+        'isp'      => '运营商',
+        'address'  => '地区',
     ],
     'purchase_promotion'  => '快 来 购 买 服 务 吧!',
     'menu'                => [

+ 130 - 32
resources/views/admin/config/system.blade.php

@@ -271,11 +271,13 @@
                                     </div>
                                     <div class="form-group col-lg-6">
                                         <div class="row">
-                                            <label class="col-md-3 col-form-label" for="is_reset_password">重置密码</label>
+                                            <label class="col-md-3 col-form-label" for="password_reset_notification">重置密码</label>
                                             <div class="col-md-9">
-                                                <input type="checkbox" id="is_reset_password" data-plugin="switchery" @if($is_reset_password) checked
-                                                       @endif onchange="updateFromOther('switch','is_reset_password')">
-                                                <span class="text-help"> 启用后用户可以通过邮件重置密码 </span>
+                                                <select id="password_reset_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','password_reset_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                </select>
+                                                <span class="text-help"> 启用后用户可以重置密码 </span>
                                             </div>
                                         </div>
                                     </div>
@@ -862,10 +864,13 @@
                                 <div class="row">
                                     <div class="form-group col-lg-6">
                                         <div class="row">
-                                            <label class="col-md-3 col-form-label" for="expire_warning">用户过期警告</label>
+                                            <label class="col-md-3 col-form-label" for="account_expire_notification">用户过期警告</label>
                                             <div class="col-md-9">
-                                                <input type="checkbox" id="expire_warning" data-plugin="switchery" @if($expire_warning) checked
-                                                       @endif onchange="updateFromOther('switch','expire_warning')">
+                                                <select id="account_expire_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','account_expire_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="database">站内通知</option>
+                                                </select>
                                                 <span class="text-help"> 启用后账号距到期还剩阈值设置的值时自动发邮件提醒用户 </span>
                                             </div>
                                         </div>
@@ -888,10 +893,13 @@
                                     </div>
                                     <div class="form-group col-lg-6">
                                         <div class="row">
-                                            <label class="col-md-3 col-form-label" for="traffic_warning">用户流量警告</label>
+                                            <label class="col-md-3 col-form-label" for="data_exhaust_notification">用户流量警告</label>
                                             <div class="col-md-9">
-                                                <input type="checkbox" id="traffic_warning" data-plugin="switchery" @if($traffic_warning) checked
-                                                       @endif onchange="updateFromOther('switch','traffic_warning')">
+                                                <select id="data_exhaust_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','data_exhaust_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="database">站内通知</option>
+                                                </select>
                                                 <span class="text-help"> 启用后账号已使用流量超过警告阈值时自动发邮件提醒用户 </span>
                                             </div>
                                         </div>
@@ -914,10 +922,16 @@
                                     </div>
                                     <div class="form-group col-lg-6">
                                         <div class="row">
-                                            <label class="col-md-3 col-form-label" for="is_node_offline">节点离线提醒</label>
+                                            <label class="col-md-3 col-form-label" for="node_offline_notification">节点离线提醒</label>
                                             <div class="col-md-9">
-                                                <input type="checkbox" id="is_node_offline" data-plugin="switchery" @if($is_node_offline) checked
-                                                       @endif onchange="updateFromOther('switch','is_node_offline')">
+                                                <select id="node_offline_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','node_offline_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="telegram">Telegram</option>
+                                                    <option value="beary">BearyChat</option>
+                                                    <option value="bark">Bark</option>
+                                                    <option value="serverChan">ServerChan</option>
+                                                </select>
                                                 <span class="text-help"> 启用后如果节点离线会推送提醒 </span>
                                             </div>
                                         </div>
@@ -940,10 +954,16 @@
                                     </div>
                                     <div class="form-group col-lg-6">
                                         <div class="row">
-                                            <label class="col-md-3 col-form-label" for="nodes_detection">节点阻断检测</label>
+                                            <label class="col-md-3 col-form-label" for="node_blocked_notification">节点阻断检测</label>
                                             <div class="col-md-9">
-                                                <input type="checkbox" id="nodes_detection" data-plugin="switchery" @if($nodes_detection) checked
-                                                       @endif onchange="updateFromOther('switch','nodes_detection')">
+                                                <select id="node_blocked_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','node_blocked_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="telegram">Telegram</option>
+                                                    <option value="beary">BearyChat</option>
+                                                    <option value="bark">Bark</option>
+                                                    <option value="serverChan">ServerChan</option>
+                                                </select>
                                                 <span class="text-help"> 每小时检测节点是否被阻断并提醒 </span>
                                             </div>
                                         </div>
@@ -966,16 +986,65 @@
                                     </div>
                                     <div class="form-group col-lg-6">
                                         <div class="row">
-                                            <label class="col-md-3 col-form-label" for="is_notification">推送通知</label>
+                                            <label class="col-md-3 col-form-label" for="payment_received_notification">支付成功通知</label>
                                             <div class="col-md-9">
-                                                <select id="is_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
-                                                        onchange="updateFromOther('select','is_notification')">
-                                                    <option value="">关闭</option>
+                                                <select id="payment_received_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','payment_received_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="database">站内通知</option>
+                                                </select>
+                                                <span class="text-help"> 用户支付订单后通知用户订单状态 </span>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="form-group col-lg-6">
+                                        <div class="row">
+                                            <label class="col-md-3 col-form-label" for="ticket_closed_notification">工单关闭通知</label>
+                                            <div class="col-md-9">
+                                                <select id="ticket_closed_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','ticket_closed_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="database">站内通知</option>
+                                                    <option value="telegram">Telegram</option>
+                                                    <option value="beary">BearyChat</option>
+                                                    <option value="bark">Bark</option>
+                                                    <option value="serverChan">ServerChan</option>
+                                                </select>
+                                                <span class="text-help"> 工单关闭通知 </span>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="form-group col-lg-6">
+                                        <div class="row">
+                                            <label class="col-md-3 col-form-label" for="ticket_created_notification">新工单通知</label>
+                                            <div class="col-md-9">
+                                                <select id="ticket_created_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','ticket_created_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="database">站内通知</option>
+                                                    <option value="telegram">Telegram</option>
+                                                    <option value="beary">BearyChat</option>
+                                                    <option value="bark">Bark</option>
                                                     <option value="serverChan">ServerChan</option>
+                                                </select>
+                                                <span class="text-help"> 新工单通知 </span>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="form-group col-lg-6">
+                                        <div class="row">
+                                            <label class="col-md-3 col-form-label" for="ticket_replied_notification">工单回复通知</label>
+                                            <div class="col-md-9">
+                                                <select id="ticket_replied_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','ticket_replied_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="database">站内通知</option>
+                                                    <option value="telegram">Telegram</option>
+                                                    <option value="beary">BearyChat</option>
                                                     <option value="bark">Bark</option>
+                                                    <option value="serverChan">ServerChan</option>
                                                 </select>
-                                                <span class="text-help">推送节点离线提醒、用户流量异常警告、节点使用报告 @can('admin.test.notify')(<a href="javascript:sendTestNotification();
-">发送测试消息</a>)@endcan </span>
+                                                <span class="text-help"> 工单回复通知 </span>
                                             </div>
                                         </div>
                                     </div>
@@ -989,7 +1058,9 @@
                                                         <button class="btn btn-primary" type="button" onclick="update('server_chan_key')">{{trans('common.update')}}</button>
                                                     </span>
                                                 </div>
-                                                <span class="text-help">启用ServerChan,请务必填入本值(<a href="http://sc.ftqq.com" target="_blank">申请SCKEY</a>)</span>
+                                                <span class="text-help">启用ServerChan,请务必填入本值(<a href="http://sc.ftqq.com" target="_blank">申请SCKEY</a>) @can('admin.test.notify')(<a
+                                                            href="javascript:sendTestNotification('serverChan');
+">发送测试消息</a>)@endcan</span>
                                             </div>
                                         </div>
                                     </div>
@@ -1003,7 +1074,8 @@
                                                         <button class="btn btn-primary" type="button" onclick="update('bark_key')">{{trans('common.update')}}</button>
                                                     </span>
                                                 </div>
-                                                <span class="text-help">推送消息到iOS设备,需要在iOS设备里装一个名为Bark的应用,取网址后的一长串代码,启用Bark,请务必填入本值 </span>
+                                                <span class="text-help">推送消息到iOS设备,需要在iOS设备里装一个名为Bark的应用,取网址后的一长串代码,启用Bark,请务必填入本值 @can('admin.test.notify')(<a href="javascript:sendTestNotification('bark');
+">发送测试消息</a>)@endcan </span>
                                             </div>
                                         </div>
                                     </div>
@@ -1106,6 +1178,19 @@
                                             </div>
                                         </div>
                                     </div>
+                                    <div class="form-group col-lg-6">
+                                        <div class="row">
+                                            <label class="col-md-3 col-form-label" for="data_anomaly_notification">流量异常通知</label>
+                                            <div class="col-md-9">
+                                                <select id="data_anomaly_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','data_anomaly_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="database">站内通知</option>
+                                                </select>
+                                                <span class="text-help"> 1小时内流量超过异常阈值通知 </span>
+                                            </div>
+                                        </div>
+                                    </div>
                                     <div class="form-group col-lg-6">
                                         <div class="row">
                                             <label class="col-md-3 col-form-label" for="traffic_ban_value">流量异常阈值</label>
@@ -1160,11 +1245,15 @@
                                     </div>
                                     <div class="form-group col-lg-6">
                                         <div class="row">
-                                            <label class="col-md-3 col-form-label" for="node_daily_report">节点使用报告</label>
+                                            <label class="col-md-3 col-form-label" for="node_daily_notification">节点使用报告</label>
                                             <div class="col-md-9">
-                                                <input type="checkbox" id="node_daily_report" data-plugin="switchery" @if($node_daily_report) checked
-                                                       @endif onchange="updateFromOther('switch','node_daily_report')">
-                                                <span class="text-help"> 每天早上9点推送昨天节点的使用情况 </span>
+                                                <select id="node_daily_notification" data-plugin="selectpicker" data-style="btn-outline btn-primary"
+                                                        onchange="updateFromOther('select','node_daily_notification')" multiple>
+                                                    <option value="mail">邮箱</option>
+                                                    <option value="telegram">Telegram</option>
+                                                    <option value="beary">BearyChat</option>
+                                                    <option value="serverChan">ServerChan</option>
+                                                </select>
                                             </div>
                                         </div>
                                     </div>
@@ -1698,11 +1787,21 @@
         $('#is_captcha').selectpicker('val', '{{$is_captcha}}');
         $('#referral_type').selectpicker('val', '{{$referral_type}}');
         $('#is_email_filtering').selectpicker('val', '{{$is_email_filtering}}');
-        $('#is_notification').selectpicker('val', '{{$is_notification}}');
         $('#is_AliPay').selectpicker('val', '{{$is_AliPay}}');
         $('#is_QQPay').selectpicker('val', '{{$is_QQPay}}');
         $('#is_WeChatPay').selectpicker('val', '{{$is_WeChatPay}}');
         $('#is_otherPay').selectpicker('val', '{{$is_otherPay}}');
+        $('#account_expire_notification').selectpicker('val', {!! $account_expire_notification !!});
+        $('#data_anomaly_notification').selectpicker('val', {!! $data_anomaly_notification !!});
+        $('#data_exhaust_notification').selectpicker('val', {!! $data_exhaust_notification !!});
+        $('#node_blocked_notification').selectpicker('val', {!! $node_blocked_notification !!});
+        $('#node_daily_notification').selectpicker('val', {!! $node_daily_notification !!});
+        $('#node_offline_notification').selectpicker('val', {!! $node_offline_notification !!});
+        $('#password_reset_notification').selectpicker('val', {!! $password_reset_notification !!});
+        $('#payment_received_notification').selectpicker('val', {!! $payment_received_notification !!});
+        $('#ticket_closed_notification').selectpicker('val', {!! $ticket_closed_notification !!});
+        $('#ticket_created_notification').selectpicker('val', {!! $ticket_created_notification !!});
+        $('#ticket_replied_notification').selectpicker('val', {!! $ticket_replied_notification !!});
 
         // Get all options within select
         disablePayment(document.getElementById('is_AliPay').getElementsByTagName('option'));
@@ -1722,7 +1821,6 @@
       }
 
       function disableCaptcha(op) {
-        console.log(@json($captcha))
         for (let i = 2; i < op.length; i++) {
             @json($captcha).
           includes(op[i].value)
@@ -1787,8 +1885,8 @@
 
       // 发送Bark测试消息
       @can('admin.test.notify')
-      function sendTestNotification() {
-        $.post('{{route('admin.test.notify')}}', {_token: '{{csrf_token()}}'}, function(ret) {
+      function sendTestNotification(channel) {
+        $.post('{{route('admin.test.notify')}}', {_token: '{{csrf_token()}}', channel: channel}, function(ret) {
           if (ret.status === 'success') {
             swal.fire({title: ret.message, icon: 'success', timer: 1500, showConfirmButton: false});
           } else {

+ 1 - 1
resources/views/admin/logs/callback.blade.php

@@ -62,7 +62,7 @@
                             <td> {{$log->trade_no}} </td>
                             <td>
                                 @can('admin.order')
-                                    <a href="{{route('admin.order', ['order_sn' => $log->out_trade_no])}}" target="_blank"> {{$log->out_trade_no}} </a>
+                                    <a href="{{route('admin.order', ['sn' => $log->out_trade_no])}}" target="_blank"> {{$log->out_trade_no}} </a>
                                 @else
                                     {{$log->out_trade_no}}
                                 @endcan

+ 3 - 3
resources/views/admin/logs/order.blade.php

@@ -15,7 +15,7 @@
                         <input type="text" class="form-control" name="email" id="email" value="{{Request::input('email')}}" placeholder="用户名"/>
                     </div>
                     <div class="form-group col-lg-2 col-sm-6">
-                        <input type="number" class="form-control" name="order_sn" id="order_sn" value="{{Request::input('order_sn')}}" placeholder="订单号"/>
+                        <input type="number" class="form-control" name="sn" id="sn" value="{{Request::input('sn')}}" placeholder="订单号"/>
                     </div>
                     <div class="form-group col-lg-6 col-sm-12">
                         <div class="input-group input-daterange" data-plugin="datepicker">
@@ -113,7 +113,7 @@
                                     @endcan
                                 @endif
                             </td>
-                            <td> {{$order->order_sn}}</td>
+                            <td> {{$order->sn}}</td>
                             <td> {{$order->goods->name  ?? trans('user.recharge_credit')}} </td>
                             <td> {{$order->is_expire ? '已过期' : $order->expired_at}} </td>
                             <td> {{$order->coupon ? $order->coupon->name . ' - ' . $order->coupon->sn : ''}} </td>
@@ -182,7 +182,7 @@
 
       // 搜索
       function Search() {
-        window.location.href = '{{route('admin.order')}}?email=' + $('#email').val() + '&order_sn=' + $('#order_sn').val() +
+        window.location.href = '{{route('admin.order')}}?email=' + $('#email').val() + '&sn=' + $('#sn').val() +
             '&is_expire=' + $('#is_expire').val() + '&is_coupon=' + $('#is_coupon').val() + '&pay_way=' +
             $('#pay_way').val() + '&status=' + $('#status').val() + '&sort=' +
             $('input:radio[name=\'sort\']:checked').val() + '&range_time=' + [$('#start').val(), $('#end').val()];

+ 3 - 3
resources/views/auth/resetPassword.blade.php

@@ -9,7 +9,7 @@
     @endif
     <form method="post" action="{{route('resetPasswd')}}">
         @csrf
-        @if(sysConfig('is_reset_password'))
+        @if(sysConfig('password_reset_notification'))
             <div class="form-title">
                 {{trans('auth.password.reset.attribute')}}
             </div>
@@ -20,10 +20,10 @@
         @else
             <x-alert type="danger" :message="trans('auth.password.reset.error.disabled' ,['email' => sysConfig('webmaster_email')])"/>
         @endif
-        <a href="{{route('login')}}" class="btn btn-danger btn-lg {{sysConfig('is_reset_password')? 'float-left':'btn-block'}}">
+        <a href="{{route('login')}}" class="btn btn-danger btn-lg {{sysConfig('password_reset_notification')? 'float-left':'btn-block'}}">
             {{trans('common.back')}}
         </a>
-        @if(sysConfig('is_reset_password'))
+        @if(sysConfig('password_reset_notification'))
             <button type="submit" class="btn btn-primary btn-lg float-right">{{trans('common.submit')}}</button>
         @endif
     </form>

+ 0 - 109
resources/views/emails/activeUser.blade.php

@@ -1,109 +0,0 @@
-<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">
-                                                            {{sysConfig('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">
-                                                            {{trans('common.active_item', ['attribute' => trans('common.account')])}}
-                                                        </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>点击这里去<a href="{{$activeUserUrl}}" target="_blank">【{{trans('common.active_item', ['attribute' => trans('common.account')])}}】</a>,或者点击下面的链接(30分钟内有效)。
-                                            </p>
-                                            <p>
-                                                <a href="{{$activeUserUrl}}" target="_blank">{{$activeUserUrl}}</a>
-                                            </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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </center>
-        </td>
-    </tr>
-    </tbody>
-</table>

+ 0 - 105
resources/views/emails/closeTicket.blade.php

@@ -1,105 +0,0 @@
-<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">
-                                                            {{sysConfig('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;">
-                                            <p>{{$content}}</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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </center>
-        </td>
-    </tr>
-    </tbody>
-</table>

+ 0 - 105
resources/views/emails/newTicket.blade.php

@@ -1,105 +0,0 @@
-<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">
-                                                            {{sysConfig('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;">
-                                            {!! $content !!}
-                                        </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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </center>
-        </td>
-    </tr>
-    </tbody>
-</table>

+ 0 - 105
resources/views/emails/nodeCrashWarning.blade.php

@@ -1,105 +0,0 @@
-<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">
-            <div data-parsed="" style="min-width:580px;width:100%; text-align: center;">
-                <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">
-                                                            {{sysConfig('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;">
-                                            <p>{!! $content !!}</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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </div>
-        </td>
-    </tr>
-    </tbody>
-</table>

+ 0 - 105
resources/views/emails/replyTicket.blade.php

@@ -1,105 +0,0 @@
-<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">
-                                                            {{sysConfig('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;">
-                                            {!! $content !!}
-                                        </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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </center>
-        </td>
-    </tr>
-    </tbody>
-</table>

+ 0 - 934
resources/views/emails/resetPassword.blade.php

@@ -1,934 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN"
-        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><!--[if IE]>
-<html xmlns="http://www.w3.org/1999/xhtml" class="ie"><![endif]--><!--[if !IE]><!-->
-<html style="margin: 0;padding: 0;" xmlns="http://www.w3.org/1999/xhtml"><!--<![endif]-->
-<head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-    <title></title>
-    <!--[if !mso]><!-->
-    <meta http-equiv="X-UA-Compatible" content="IE=edge"/><!--<![endif]-->
-    <meta name="viewport" content="width=device-width"/>
-    <style type="text/css">
-        @media only screen and (min-width: 620px) {
-            .wrapper {
-                min-width: 600px !important
-            }
-
-            .wrapper h1 {
-            }
-
-            .wrapper h1 {
-                font-size: 36px !important;
-                line-height: 43px !important
-            }
-
-            .wrapper h2 {
-            }
-
-            .wrapper h2 {
-                font-size: 22px !important;
-                line-height: 31px !important
-            }
-
-            .wrapper h3 {
-            }
-
-            .wrapper h3 {
-                font-size: 18px !important;
-                line-height: 26px !important
-            }
-
-            .column {
-            }
-
-            .wrapper .size-8 {
-                font-size: 8px !important;
-                line-height: 14px !important
-            }
-
-            .wrapper .size-9 {
-                font-size: 9px !important;
-                line-height: 16px !important
-            }
-
-            .wrapper .size-10 {
-                font-size: 10px !important;
-                line-height: 18px !important
-            }
-
-            .wrapper .size-11 {
-                font-size: 11px !important;
-                line-height: 19px !important
-            }
-
-            .wrapper .size-12 {
-                font-size: 12px !important;
-                line-height: 19px !important
-            }
-
-            .wrapper .size-13 {
-                font-size: 13px !important;
-                line-height: 21px !important
-            }
-
-            .wrapper .size-14 {
-                font-size: 14px !important;
-                line-height: 21px !important
-            }
-
-            .wrapper .size-15 {
-                font-size: 15px !important;
-                line-height: 23px !important
-            }
-
-            .wrapper .size-16 {
-                font-size: 16px !important;
-                line-height: 24px !important
-            }
-
-            .wrapper .size-17 {
-                font-size: 17px !important;
-                line-height: 26px !important
-            }
-
-            .wrapper .size-18 {
-                font-size: 18px !important;
-                line-height: 26px !important
-            }
-
-            .wrapper .size-20 {
-                font-size: 20px !important;
-                line-height: 28px !important
-            }
-
-            .wrapper .size-22 {
-                font-size: 22px !important;
-                line-height: 31px !important
-            }
-
-            .wrapper .size-24 {
-                font-size: 24px !important;
-                line-height: 32px !important
-            }
-
-            .wrapper .size-26 {
-                font-size: 26px !important;
-                line-height: 34px !important
-            }
-
-            .wrapper .size-28 {
-                font-size: 28px !important;
-                line-height: 36px !important
-            }
-
-            .wrapper .size-30 {
-                font-size: 30px !important;
-                line-height: 38px !important
-            }
-
-            .wrapper .size-32 {
-                font-size: 32px !important;
-                line-height: 40px !important
-            }
-
-            .wrapper .size-34 {
-                font-size: 34px !important;
-                line-height: 43px !important
-            }
-
-            .wrapper .size-36 {
-                font-size: 36px !important;
-                line-height: 43px !important
-            }
-
-            .wrapper
-            .size-40 {
-                font-size: 40px !important;
-                line-height: 47px !important
-            }
-
-            .wrapper .size-44 {
-                font-size: 44px !important;
-                line-height: 50px !important
-            }
-
-            .wrapper .size-48 {
-                font-size: 48px !important;
-                line-height: 54px !important
-            }
-
-            .wrapper .size-56 {
-                font-size: 56px !important;
-                line-height: 60px !important
-            }
-
-            .wrapper .size-64 {
-                font-size: 64px !important;
-                line-height: 63px !important
-            }
-        }
-    </style>
-    <style type="text/css">
-        body {
-            margin: 0;
-            padding: 0;
-        }
-
-        table {
-            border-collapse: collapse;
-            table-layout: fixed;
-        }
-
-        * {
-            line-height: inherit;
-        }
-
-        [x-apple-data-detectors],
-        [href^="tel"],
-        [href^="sms"] {
-            color: inherit !important;
-            text-decoration: none !important;
-        }
-
-        .wrapper .footer__share-button a:hover,
-        .wrapper .footer__share-button a:focus {
-            color: #ffffff !important;
-        }
-
-        .btn a:hover,
-        .btn a:focus,
-        .footer__share-button a:hover,
-        .footer__share-button a:focus,
-        .email-footer__links a:hover,
-        .email-footer__links a:focus {
-            opacity: 0.8;
-        }
-
-        .preheader,
-        .header,
-        .layout,
-        .column {
-            transition: width 0.25s ease-in-out, max-width 0.25s ease-in-out;
-        }
-
-        .preheader td {
-            padding-bottom: 8px;
-        }
-
-        .layout,
-        div.header {
-            max-width: 400px !important;
-            -fallback-width: 95% !important;
-            width: calc(100% - 20px) !important;
-        }
-
-        div.preheader {
-            max-width: 360px !important;
-            -fallback-width: 90% !important;
-            width: calc(100% - 60px) !important;
-        }
-
-        .snippet,
-        .webversion {
-            Float: none !important;
-        }
-
-        .column {
-            max-width: 400px !important;
-            width: 100% !important;
-        }
-
-        .fixed-width.has-border {
-            max-width: 402px !important;
-        }
-
-        .fixed-width.has-border .layout__inner {
-            box-sizing: border-box;
-        }
-
-        .snippet,
-        .webversion {
-            width: 50% !important;
-        }
-
-        .ie .btn {
-            width: 100%;
-        }
-
-        [owa] .column div,
-        [owa] .column button {
-            display: block !important;
-        }
-
-        .ie .column,
-        [owa] .column,
-        .ie .gutter,
-        [owa] .gutter {
-            display: table-cell;
-            float: none !important;
-            vertical-align: top;
-        }
-
-        .ie div.preheader,
-        [owa] div.preheader,
-        .ie .email-footer,
-        [owa] .email-footer {
-            max-width: 560px !important;
-            width: 560px !important;
-        }
-
-        .ie .snippet,
-        [owa] .snippet,
-        .ie .webversion,
-        [owa] .webversion {
-            width: 280px !important;
-        }
-
-        .ie div.header,
-        [owa] div.header,
-        .ie .layout,
-        [owa] .layout,
-        .ie .one-col .column,
-        [owa] .one-col .column {
-            max-width: 600px !important;
-            width: 600px !important;
-        }
-
-        .ie .fixed-width.has-border,
-        [owa] .fixed-width.has-border,
-        .ie .has-gutter.has-border,
-        [owa] .has-gutter.has-border {
-            max-width: 602px !important;
-            width: 602px !important;
-        }
-
-        .ie .two-col .column,
-        [owa] .two-col .column {
-            max-width: 300px !important;
-            width: 300px !important;
-        }
-
-        .ie .three-col .column,
-        [owa] .three-col .column,
-        .ie .narrow,
-        [owa] .narrow {
-            max-width: 200px !important;
-            width: 200px !important;
-        }
-
-        .ie .wide,
-        [owa] .wide {
-            width: 400px !important;
-        }
-
-        .ie .two-col.has-gutter .column,
-        [owa] .two-col.x_has-gutter .column {
-            max-width: 290px !important;
-            width: 290px !important;
-        }
-
-        .ie .three-col.has-gutter .column,
-        [owa] .three-col.x_has-gutter .column,
-        .ie .has-gutter .narrow,
-        [owa] .has-gutter .narrow {
-            max-width: 188px !important;
-            width: 188px !important;
-        }
-
-        .ie .has-gutter .wide,
-        [owa] .has-gutter .wide {
-            max-width: 394px !important;
-            width: 394px !important;
-        }
-
-        .ie .two-col.has-gutter.has-border .column,
-        [owa] .two-col.x_has-gutter.x_has-border .column {
-            max-width: 292px !important;
-            width: 292px !important;
-        }
-
-        .ie .three-col.has-gutter.has-border .column,
-        [owa] .three-col.x_has-gutter.x_has-border .column,
-        .ie .has-gutter.has-border .narrow,
-        [owa] .has-gutter.x_has-border .narrow {
-            max-width: 190px !important;
-            width: 190px !important;
-        }
-
-        .ie .has-gutter.has-border .wide,
-        [owa] .has-gutter.x_has-border .wide {
-            max-width: 396px !important;
-            width: 396px !important;
-        }
-
-        .ie .fixed-width .layout__inner {
-            border-left: 0 none white !important;
-            border-right: 0 none white !important;
-        }
-
-        .ie .layout__edges {
-            display: none;
-        }
-
-        .mso .layout__edges {
-            font-size: 0;
-        }
-
-        .layout-fixed-width,
-        .mso .layout-full-width {
-            background-color: #ffffff;
-        }
-
-        @media only screen and (min-width: 620px) {
-            .column,
-            .gutter {
-                display: table-cell;
-                Float: none !important;
-                vertical-align: top;
-            }
-
-            div.preheader,
-            .email-footer {
-                max-width: 560px !important;
-                width: 560px !important;
-            }
-
-            .snippet,
-            .webversion {
-                width: 280px !important;
-            }
-
-            div.header,
-            .layout,
-            .one-col .column {
-                max-width: 600px !important;
-                width: 600px !important;
-            }
-
-            .fixed-width.has-border,
-            .fixed-width.ecxhas-border,
-            .has-gutter.has-border,
-            .has-gutter.ecxhas-border {
-                max-width: 602px !important;
-                width: 602px !important;
-            }
-
-            .two-col .column {
-                max-width: 300px !important;
-                width: 300px !important;
-            }
-
-            .three-col .column,
-            .column.narrow {
-                max-width: 200px !important;
-                width: 200px !important;
-            }
-
-            .column.wide {
-                width: 400px !important;
-            }
-
-            .two-col.has-gutter .column,
-            .two-col.ecxhas-gutter .column {
-                max-width: 290px !important;
-                width: 290px !important;
-            }
-
-            .three-col.has-gutter .column,
-            .three-col.ecxhas-gutter .column,
-            .has-gutter .narrow {
-                max-width: 188px !important;
-                width: 188px !important;
-            }
-
-            .has-gutter .wide {
-                max-width: 394px !important;
-                width: 394px !important;
-            }
-
-            .two-col.has-gutter.has-border .column,
-            .two-col.ecxhas-gutter.ecxhas-border .column {
-                max-width: 292px !important;
-                width: 292px !important;
-            }
-
-            .three-col.has-gutter.has-border .column,
-            .three-col.ecxhas-gutter.ecxhas-border .column,
-            .has-gutter.has-border .narrow,
-            .has-gutter.ecxhas-border .narrow {
-                max-width: 190px !important;
-                width: 190px !important;
-            }
-
-            .has-gutter.has-border .wide,
-            .has-gutter.ecxhas-border .wide {
-                max-width: 396px !important;
-                width: 396px !important;
-            }
-        }
-
-        @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
-            .fblike {
-                background-image: url(https://i10.createsend1.com/static/eb/master/13-the-blueprint-3/images/fblike@2x.png) !important;
-            }
-
-            .tweet {
-                background-image: url(https://i7.createsend1.com/static/eb/master/13-the-blueprint-3/images/tweet@2x.png) !important;
-            }
-
-            .linkedinshare {
-                background-image: url(https://i8.createsend1.com/static/eb/master/13-the-blueprint-3/images/lishare@2x.png) !important;
-            }
-
-            .forwardtoafriend {
-                background-image: url(https://i9.createsend1.com/static/eb/master/13-the-blueprint-3/images/forward@2x.png) !important;
-            }
-        }
-
-        @media (max-width: 321px) {
-            .fixed-width.has-border .layout__inner {
-                border-width: 1px 0 !important;
-            }
-
-            .layout,
-            .column {
-                min-width: 320px !important;
-                width: 320px !important;
-            }
-
-            .border {
-                display: none;
-            }
-        }
-
-        .mso div {
-            border: 0 none white !important;
-        }
-
-        .mso .w560 .divider {
-            Margin-left: 260px !important;
-            Margin-right: 260px !important;
-        }
-
-        .mso .w360 .divider {
-            Margin-left: 160px !important;
-            Margin-right: 160px !important;
-        }
-
-        .mso .w260 .divider {
-            Margin-left: 110px !important;
-            Margin-right: 110px !important;
-        }
-
-        .mso .w160 .divider {
-            Margin-left: 60px !important;
-            Margin-right: 60px !important;
-        }
-
-        .mso .w354 .divider {
-            Margin-left: 157px !important;
-            Margin-right: 157px !important;
-        }
-
-        .mso .w250 .divider {
-            Margin-left: 105px !important;
-            Margin-right: 105px !important;
-        }
-
-        .mso .w148 .divider {
-            Margin-left: 54px !important;
-            Margin-right: 54px !important;
-        }
-
-        .mso .size-8,
-        .ie .size-8 {
-            font-size: 8px !important;
-            line-height: 14px !important;
-        }
-
-        .mso .size-9,
-        .ie .size-9 {
-            font-size: 9px !important;
-            line-height: 16px !important;
-        }
-
-        .mso .size-10,
-        .ie .size-10 {
-            font-size: 10px !important;
-            line-height: 18px !important;
-        }
-
-        .mso .size-11,
-        .ie .size-11 {
-            font-size: 11px !important;
-            line-height: 19px !important;
-        }
-
-        .mso .size-12,
-        .ie .size-12 {
-            font-size: 12px !important;
-            line-height: 19px !important;
-        }
-
-        .mso .size-13,
-        .ie .size-13 {
-            font-size: 13px !important;
-            line-height: 21px !important;
-        }
-
-        .mso .size-14,
-        .ie .size-14 {
-            font-size: 14px !important;
-            line-height: 21px !important;
-        }
-
-        .mso .size-15,
-        .ie .size-15 {
-            font-size: 15px !important;
-            line-height: 23px !important;
-        }
-
-        .mso .size-16,
-        .ie .size-16 {
-            font-size: 16px !important;
-            line-height: 24px !important;
-        }
-
-        .mso .size-17,
-        .ie .size-17 {
-            font-size: 17px !important;
-            line-height: 26px !important;
-        }
-
-        .mso .size-18,
-        .ie .size-18 {
-            font-size: 18px !important;
-            line-height: 26px !important;
-        }
-
-        .mso .size-20,
-        .ie .size-20 {
-            font-size: 20px !important;
-            line-height: 28px !important;
-        }
-
-        .mso .size-22,
-        .ie .size-22 {
-            font-size: 22px !important;
-            line-height: 31px !important;
-        }
-
-        .mso .size-24,
-        .ie .size-24 {
-            font-size: 24px !important;
-            line-height: 32px !important;
-        }
-
-        .mso .size-26,
-        .ie .size-26 {
-            font-size: 26px !important;
-            line-height: 34px !important;
-        }
-
-        .mso .size-28,
-        .ie .size-28 {
-            font-size: 28px !important;
-            line-height: 36px !important;
-        }
-
-        .mso .size-30,
-        .ie .size-30 {
-            font-size: 30px !important;
-            line-height: 38px !important;
-        }
-
-        .mso .size-32,
-        .ie .size-32 {
-            font-size: 32px !important;
-            line-height: 40px !important;
-        }
-
-        .mso .size-34,
-        .ie .size-34 {
-            font-size: 34px !important;
-            line-height: 43px !important;
-        }
-
-        .mso .size-36,
-        .ie .size-36 {
-            font-size: 36px !important;
-            line-height: 43px !important;
-        }
-
-        .mso .size-40,
-        .ie .size-40 {
-            font-size: 40px !important;
-            line-height: 47px !important;
-        }
-
-        .mso .size-44,
-        .ie .size-44 {
-            font-size: 44px !important;
-            line-height: 50px !important;
-        }
-
-        .mso .size-48,
-        .ie .size-48 {
-            font-size: 48px !important;
-            line-height: 54px !important;
-        }
-
-        .mso .size-56,
-        .ie .size-56 {
-            font-size: 56px !important;
-            line-height: 60px !important;
-        }
-
-        .mso .size-64,
-        .ie .size-64 {
-            font-size: 64px !important;
-            line-height: 63px !important;
-        }
-    </style>
-
-    <!--[if !mso]><!-->
-    <style type="text/css">
-        @import url(//fonts.googleapis.com/css?family=Ubuntu:400,700,400italic,700italic);
-    </style>
-    <link href="//fonts.googleapis.com/css?family=Ubuntu:400,700,400italic,700italic" rel="stylesheet" type="text/css"/>
-    <!--<![endif]-->
-    <style type="text/css">
-        body {
-            background-color: #f0f0f0
-        }
-
-        .logo a:hover, .logo a:focus {
-            color: #859bb1 !important
-        }
-
-        .mso .layout-has-border {
-            border-top: 1px solid #bdbdbd;
-            border-bottom: 1px solid #bdbdbd
-        }
-
-        .mso .layout-has-bottom-border {
-            border-bottom: 1px solid #bdbdbd
-        }
-
-        .mso .border, .ie .border {
-            background-color: #bdbdbd
-        }
-
-        .mso h1, .ie h1 {
-        }
-
-        .mso h1, .ie h1 {
-            font-size: 36px !important;
-            line-height: 43px !important
-        }
-
-        .mso h2, .ie h2 {
-        }
-
-        .mso h2, .ie h2 {
-            font-size: 22px !important;
-            line-height: 31px !important
-        }
-
-        .mso h3, .ie h3 {
-        }
-
-        .mso h3, .ie h3 {
-            font-size: 18px !important;
-            line-height: 26px !important
-        }
-
-        .mso .layout__inner, .ie .layout__inner {
-        }
-
-        .mso .footer__share-button p {
-        }
-
-        .mso .footer__share-button p {
-            font-family: Ubuntu, sans-serif
-        }
-    </style>
-    <meta name="robots" content="noindex,nofollow"/>
-    <meta property="og:title" content="My First Campaign"/>
-</head>
-<!--[if mso]>
-<body class="mso">
-<![endif]-->
-<!--[if !mso]><!-->
-<body class="full-padding" style="margin: 0;padding: 0;-webkit-text-size-adjust: 100%;">
-<!--<![endif]-->
-<table class="wrapper"
-       style="border-collapse: collapse;table-layout: fixed;min-width: 320px;width: 100%;background-color: #f0f0f0;"
-       cellpadding="0" cellspacing="0" role="presentation">
-    <tbody>
-    <tr>
-        <td>
-            <div role="banner">
-                <div class="preheader"
-                     style="Margin: 0 auto;max-width: 560px;min-width: 280px; width: 280px;width: calc(28000% - 167440px);">
-                    <div style="border-collapse: collapse;display: table;width: 100%;">
-                        <!--[if (mso)|(IE)]>
-                        <table align="center" class="preheader" cellpadding="0" cellspacing="0" role="presentation">
-                            <tr>
-                                <td style="width: 280px" valign="top"><![endif]-->
-                        <div class="snippet"
-                             style="display: table-cell;Float: left;font-size: 12px;line-height: 19px;max-width: 280px;min-width: 140px; width: 140px;width: calc(14000% - 78120px);padding: 10px 0 5px 0;color: #bdbdbd;font-family: Ubuntu,sans-serif;">
-
-                        </div>
-                        <!--[if (mso)|(IE)]></td>
-                        <td style="width: 280px" valign="top"><![endif]-->
-                        <div class="webversion"
-                             style="display: table-cell;Float: left;font-size: 12px;line-height: 19px;max-width: 280px;min-width: 139px; width: 139px;width: calc(14100% - 78680px);padding: 10px 0 5px 0;text-align: right;color: #bdbdbd;font-family: Ubuntu,sans-serif;">
-
-                        </div>
-                        <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
-                    </div>
-                </div>
-
-            </div>
-            <div role="section">
-                <div class="layout one-col fixed-width"
-                     style="Margin: 0 auto;max-width: 600px;min-width: 320px; width: 320px;width: calc(28000% - 167400px);overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;">
-                    <div class="layout__inner"
-                         style="border-collapse: collapse;display: table;width: 100%;background-color: #ffffff;"
-                         emb-background-style>
-                        <!--[if (mso)|(IE)]>
-                        <table align="center" cellpadding="0" cellspacing="0" role="presentation">
-                            <tr class="layout-fixed-width" emb-background-style>
-                                <td style="width: 600px" class="w560"><![endif]-->
-                        <div class="column"
-                             style="text-align: left;color: #787778;font-size: 16px;line-height: 24px;font-family: Ubuntu,sans-serif;max-width: 600px;min-width: 320px; width: 320px;width: calc(28000% - 167400px);">
-
-                            <div style="Margin-left: 20px;Margin-right: 20px;Margin-top: 24px;">
-                                <div style="mso-line-height-rule: exactly;line-height: 20px;font-size: 1px;">&nbsp;
-                                </div>
-                            </div>
-
-                            <div style="Margin-left: 20px;Margin-right: 20px;">
-                                <div style="mso-line-height-rule: exactly;mso-text-raise: 4px;">
-                                    <h1 style="Margin-top: 0;Margin-bottom: 0;font-style: normal;font-weight: normal;color: #565656;font-size: 30px;line-height: 38px;text-align: center;">
-                                        <strong>&#37325;&#32622;&#23494;&#30721;</strong></h1>
-                                    <p style="Margin-top: 20px;Margin-bottom: 20px;">&#33509;&#35201;&#24320;&#22987;&#37325;&#32622;&#23494;&#30721;,&#35831;&#28857;&#20987;&#20197;&#19979;&#25353;&#38062;/&#38142;&#25509;&#65306;</p>
-                                </div>
-                            </div>
-
-                            <div style="Margin-left: 20px;Margin-right: 20px;">
-                                <div style="mso-line-height-rule: exactly;line-height: 10px;font-size: 1px;">&nbsp;
-                                </div>
-                            </div>
-
-                            <div style="Margin-left: 20px;Margin-right: 20px;">
-                                <div class="btn btn--flat btn--large" style="Margin-bottom: 20px;text-align: center;">
-                                    <![if !mso]><a
-                                            style="border-radius: 4px;display: inline-block;font-size: 14px;font-weight: bold;line-height: 24px;padding: 12px 24px;text-align: center;text-decoration: none !important;transition: opacity 0.1s ease-in;color: #ffffff !important;background-color: #2e74bf;font-family: Ubuntu, sans-serif;"
-                                            href="{{$resetPasswordUrl}}">&#37325;&#32622;&#23494;&#30721;</a><![endif]>
-                                <!--[if mso]><p style="line-height:0;margin:0;">&nbsp;</p>
-									<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" href="{{$resetPasswordUrl}}" style="width:104px" arcsize="9%" fillcolor="#2E74BF" stroke="f">
-										<v:textbox style="mso-fit-shape-to-text:t" inset="0px,11px,0px,11px">
-											<center style="font-size:14px;line-height:24px;color:#FFFFFF;font-family:Ubuntu,sans-serif;font-weight:bold;mso-line-height-rule:exactly;mso-text-raise:4px">&#37325;&#32622;&#23494;&#30721;</center>
-										</v:textbox>
-									</v:roundrect><![endif]--></div>
-                            </div>
-
-                            <div style="Margin-left: 20px;Margin-right: 20px;">
-                                <div style="mso-line-height-rule: exactly;line-height: 10px;font-size: 1px;">&nbsp;
-                                </div>
-                            </div>
-
-                            <div style="Margin-left: 20px;Margin-right: 20px;">
-                                <div style="mso-line-height-rule: exactly;mso-text-raise: 4px;">
-                                    <p class="size-14"
-                                       style="Margin-top: 0;Margin-bottom: 20px;font-size: 14px;line-height: 21px;"
-                                       lang="x-size-14">&nbsp;&#24744;&#25910;&#21040;&#27492;&#37038;&#20214;&#26159;&#22240;&#20026;&#24744;&#22312;{{sysConfig('website_name')}}
-                                        &#30003;&#35831;&#20102;&#23494;&#30721;&#37325;&#32622;,&#22914;&#26524;&#19981;&#26159;&#24744;&#30003;&#35831;&#30340;,&#35831;&#24573;&#30053;&#27492;&#37038;&#20214;.</p>
-                                </div>
-                            </div>
-
-                            <div style="Margin-left: 20px;Margin-right: 20px;Margin-bottom: 24px;">
-                                <div style="mso-line-height-rule: exactly;line-height: 5px;font-size: 1px;">&nbsp;</div>
-                            </div>
-
-                        </div>
-                        <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
-                    </div>
-                </div>
-
-                <div style="mso-line-height-rule: exactly;line-height: 10px;font-size: 10px;">&nbsp;</div>
-
-
-                <div style="mso-line-height-rule: exactly;" role="contentinfo">
-                    <div class="layout email-footer"
-                         style="Margin: 0 auto;max-width: 600px;min-width: 320px; width: 320px;width: calc(28000% - 167400px);overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;">
-                        <div class="layout__inner" style="border-collapse: collapse;display: table;width: 100%;">
-                            <!--[if (mso)|(IE)]>
-                            <table align="center" cellpadding="0" cellspacing="0" role="presentation">
-                                <tr class="layout-email-footer">
-                                    <td style="width: 400px;" valign="top" class="w360"><![endif]-->
-                            <div class="column wide"
-                                 style="text-align: left;font-size: 12px;line-height: 19px;color: #bdbdbd;font-family: Ubuntu,sans-serif;Float: left;max-width: 400px;min-width: 320px; width: 320px;width: calc(8000% - 47600px);">
-                                <div style="Margin-left: 20px;Margin-right: 20px;Margin-top: 10px;Margin-bottom: 10px;">
-                                    <table class="email-footer__links emb-web-links"
-                                           style="border-collapse: collapse;table-layout: fixed;" role="presentation">
-                                        <tbody>
-                                        <tr role="navigation">
-
-                                        </tr>
-                                        </tbody>
-                                    </table>
-                                    <div style="font-size: 12px;line-height: 19px;Margin-top: 20px;">
-                                        <div>{{sysConfig('website_name')}}</div>
-                                    </div>
-                                    <div style="font-size: 12px;line-height: 19px;Margin-top: 18px;">
-                                        <div>&#23562;&#25964;&#30340;&#20351;&#29992;&#32773;&#65292;&#24744;&#20250;&#40664;&#35748;&#22312;&#25105;&#20204;&#30340;&#37038;&#20214;&#21457;&#36865;&#21015;&#34920;&#37324;</div>
-                                    </div>
-                                    <!--[if mso]>&nbsp;<![endif]-->
-                                </div>
-                            </div>
-                            <!--[if (mso)|(IE)]></td>
-                            <td style="width: 200px;" valign="top" class="w160"><![endif]-->
-                            <div class="column narrow"
-                                 style="text-align: left;font-size: 12px;line-height: 19px;color: #bdbdbd;font-family: Ubuntu,sans-serif;Float: left;max-width: 320px;min-width: 200px; width: 320px;width: calc(72200px - 12000%);">
-                                <div style="Margin-left: 20px;Margin-right: 20px;Margin-top: 10px;Margin-bottom: 10px;">
-
-                                </div>
-                            </div>
-                            <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
-                        </div>
-                    </div>
-                    <div class="layout one-col email-footer"
-                         style="Margin: 0 auto;max-width: 600px;min-width: 320px; width: 320px;width: calc(28000% - 167400px);overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;">
-                        <div class="layout__inner" style="border-collapse: collapse;display: table;width: 100%;">
-                            <!--[if (mso)|(IE)]>
-                            <table align="center" cellpadding="0" cellspacing="0" role="presentation">
-                                <tr class="layout-email-footer">
-                                    <td style="width: 600px;" class="w560"><![endif]-->
-                            <div class="column"
-                                 style="text-align: left;font-size: 12px;line-height: 19px;color: #bdbdbd;font-family: Ubuntu,sans-serif;max-width: 600px;min-width: 320px; width: 320px;width: calc(28000% - 167400px);">
-                                <div style="Margin-left: 20px;Margin-right: 20px;Margin-top: 10px;Margin-bottom: 10px;">
-                                    <div style="font-size: 12px;line-height: 19px;">
-                                        <span>
-                                            <preferences style="text-decoration: underline;"
-                                                         lang="en">Preferences
-                                            </preferences>&nbsp;&nbsp;|&nbsp;&nbsp;</span>
-                                        <unsubscribe style="text-decoration: underline;">Unsubscribe</unsubscribe>
-                                    </div>
-                                </div>
-                            </div>
-                            <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
-                        </div>
-                    </div>
-                </div>
-                <div style="mso-line-height-rule: exactly;line-height: 40px;font-size: 40px;">&nbsp;</div>
-            </div>
-        </td>
-    </tr>
-    </tbody>
-</table>
-
-</body>
-</html>

+ 0 - 152
resources/views/emails/sendUserInfo.blade.php

@@ -1,152 +0,0 @@
-<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">
-                                                            {{sysConfig('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;">
-                                            <table>
-                                                <tr>
-                                                    <td>订单编号</td>
-                                                    <td>{{$content['order_sn']}}</td>
-                                                </tr>
-                                                <tr>
-                                                    <td>服务</td>
-                                                    <td>{{$content['goods_name']}}</td>
-                                                </tr>
-                                                <tr>
-                                                    <td>流量</td>
-                                                    <td>{{$content['goods_traffic']}}</td>
-                                                </tr>
-                                                <tr>
-                                                    <td>端口</td>
-                                                    <td>{{$content['port']}}</td>
-                                                </tr>
-                                                <tr>
-                                                    <td>密码</td>
-                                                    <td>{{$content['passwd']}}</td>
-                                                </tr>
-                                                <tr>
-                                                    <td>加密方式</td>
-                                                    <td>{{$content['method']}}</td>
-                                                </tr>
-                                                <tr>
-                                                    <td>创建时间</td>
-                                                    <td>{{$content['created_at']}}</td>
-                                                </tr>
-                                                <tr>
-                                                    <td>过期时间</td>
-                                                    <td>{{$content['expired_at']}}</td>
-                                                </tr>
-                                                @if($content['serverList'])
-                                                    <tr>
-                                                        <td colspan="2">------------------------------------------</td>
-                                                    </tr>
-                                                    <tr>
-                                                        <td colspan="2" style="text-align: left;">节点列表</td>
-                                                    </tr>
-                                                    @foreach($content['serverList'] as $vo)
-                                                        <tr>
-                                                            <td>{{$vo['name']}}</td>
-                                                            <td>{{$vo['server'] ? $vo['server'] : $vo['ip']}}</td>
-                                                        </tr>
-                                                    @endforeach
-                                                @endif
-                                            </table>
-                                        </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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </center>
-        </td>
-    </tr>
-    </tbody>
-</table>

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

@@ -1,105 +0,0 @@
-<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">
-                                                            {{sysConfig('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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </center>
-        </td>
-    </tr>
-    </tbody>
-</table>

+ 0 - 105
resources/views/emails/userExpireWarning.blade.php

@@ -1,105 +0,0 @@
-<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">
-                                                            {{sysConfig('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;">
-                                            <p>您的账号【{{$lastCanUseDays}}】天后即将过期,为了确保您可以继续正常使用我们的服务,请及时续费。</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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </center>
-        </td>
-    </tr>
-    </tbody>
-</table>

+ 0 - 105
resources/views/emails/userExpireWarningToday.blade.php

@@ -1,105 +0,0 @@
-<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">
-                                                            {{sysConfig('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;">
-                                            <p>您的账号将于今天晚上【24:00】过期,为了确保您可以继续正常使用我们的服务,请及时续费。</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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </center>
-        </td>
-    </tr>
-    </tbody>
-</table>

+ 0 - 105
resources/views/emails/userTrafficWarning.blade.php

@@ -1,105 +0,0 @@
-<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">
-                                                            {{sysConfig('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;">
-                                            <p>您的流量已使用【{{$usedPercent}}%】,为了确保您可以继续正常使用我们的服务,请及时续费或者购买流量包。</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>
-                            </table>
-                        </td>
-                    </tr>
-                    </tbody>
-                </table>
-            </center>
-        </td>
-    </tr>
-    </tbody>
-</table>

+ 5 - 0
resources/views/mail/custom.blade.php

@@ -0,0 +1,5 @@
+@component('mail::message')
+
+{!! $content !!}
+
+@endcomponent

+ 7 - 0
resources/views/mail/node/dailyReport.blade.php

@@ -0,0 +1,7 @@
+@component('mail::message')
+# {{__('Nodes Daily Report')}}
+{!! $content !!}
+@component('mail::button', ['url' => route('admin.node.index')])
+    {{trans('notification.view_web')}}
+@endcomponent
+@endcomponent

+ 51 - 0
resources/views/user/components/notification.blade.php

@@ -0,0 +1,51 @@
+<li class="nav-item dropdown">
+    <a class="nav-link" data-toggle="dropdown" href="javascript:void(0)" title="Notifications"
+       aria-expanded="false" data-animation="scale-up" role="button">
+        <i class="icon wb-bell" aria-hidden="true"></i>
+        @if ($unreadCount = auth()->user()->unreadNotifications->count())
+            <span class="badge badge-pill badge-danger up">{{$unreadCount}}</span>
+        @endif
+    </a>
+    <div class="dropdown-menu dropdown-menu-right dropdown-menu-media" role="menu">
+        <div class="dropdown-menu-header">
+            <h5>{{trans('notification.attribute')}}</h5>
+            @if ($unreadCount)
+                <span class="badge badge-round badge-danger">{{trans_choice('notification.new', $unreadCount, ['num' => $unreadCount])}}</span>
+            @endif
+        </div>
+        @if ($unreadCount)
+            <div class="list-group">
+                <div data-role="container">
+                    <div data-role="content">
+                        @foreach(auth()->user()->unreadNotifications as $notification)
+                            @include('user.components.notifications.'.Str::camel(class_basename($notification->type)))
+                        @endforeach
+                    </div>
+                </div>
+            </div>
+        @else
+            <div class="list-group bg-grey-100">
+                <div class="dropdown-item" role="menuitem">
+                    <div class="media">
+                        <div class="pr-10">
+                            <i class="icon wb-inbox bg-grey-600 white icon-circle" aria-hidden="true"></i>
+                        </div>
+                        <div class="media-body">
+                            <h6 class="media-heading">{{trans('notification.empty')}}</h6>
+
+                            <time class="media-meta" datetime="{{now()}}">{{now()}}</time>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        @endif
+        <div class="dropdown-menu-footer">
+            <a class="dropdown-menu-footer-btn" href="javascript:void(0)" role="button">
+                <i class="icon wb-settings" aria-hidden="true"></i>
+            </a>
+            <a class="dropdown-item" href="javascript:void(0)" role="menuitem">
+                All notifications
+            </a>
+        </div>
+    </div>
+</li>

+ 13 - 0
resources/views/user/components/notifications/accountExpire.blade.php

@@ -0,0 +1,13 @@
+<a class="list-group-item dropdown-item" href="javascript:void(0)" role="menuitem">
+    <div class="media">
+        <div class="pr-10">
+            <i class="icon wb-order bg-primary-600 white icon-circle" aria-hidden="true"></i>
+        </div>
+        <div class="media-body">
+            <h6 class="media-heading text-break">
+                {{trans('notification.account_expired_blade', ['days' => $notification->data['days']])}}
+            </h6>
+            <time class="media-meta" datetime="{{$notification->created_at}}">{{$notification->created_at->diffForHumans()}}</time>
+        </div>
+    </div>
+</a>

+ 13 - 0
resources/views/user/components/notifications/paymentReceived.blade.php

@@ -0,0 +1,13 @@
+<a class="list-group-item dropdown-item" href="{{route('invoiceInfo', $notification->data['sn'])}}" role="menuitem">
+    <div class="media">
+        <div class="pr-10">
+            <i class="icon wb-order bg-primary-600 white icon-circle" aria-hidden="true"></i>
+        </div>
+        <div class="media-body">
+            <h6 class="media-heading text-break">
+                {{trans('notification.payment_received', ['order' => '#'.$notification->data['sn'], 'amount'=>$notification->data['amount']])}}
+            </h6>
+            <time class="media-meta" datetime="{{$notification->created_at}}">{{$notification->created_at->diffForHumans()}}</time>
+        </div>
+    </div>
+</a>

+ 1 - 1
resources/views/user/invoiceDetail.blade.php

@@ -16,7 +16,7 @@
                     <div class="col-lg-3 offset-lg-6 text-right">
                         <h4>{{trans('user.invoice.detail')}}</h4>
                         <p>{{trans('user.invoice.id')}}:
-                            <a class="font-size-20" href="javascript:void(0)">{{$order->order_sn}}</a>
+                            <a class="font-size-20" href="javascript:void(0)">{{$order->sn}}</a>
                         </p>
                         <p>{{trans('user.payment_method')}}
                             :{{$order->pay_way === 1 ? trans('user.shop.pay_credit') : trans('user.shop.pay_online')}}</p>

+ 1 - 1
resources/views/user/invoices.blade.php

@@ -32,7 +32,7 @@
                     @foreach($orderList as $order)
                         <tr>
                             <td>{{$loop->iteration}}</td>
-                            <td><a href="/invoice/{{$order->order_sn}}" target="_blank">{{$order->order_sn}}</a></td>
+                            <td><a href="/invoice/{{$order->sn}}" target="_blank">{{$order->sn}}</a></td>
                             <td>{{$order->goods->name ?? trans('user.recharge_credit')}}</td>
                             <td>{{$order->pay_way === 1 ? trans('user.shop.pay_credit') : trans('user.shop.pay_online')}}</td>
                             <td>¥{{$order->amount}}</td>

+ 2 - 1
resources/views/user/layouts.blade.php

@@ -40,6 +40,7 @@
                     </li>
                 </ul>
                 <ul class="nav navbar-toolbar navbar-right navbar-toolbar-right">
+                    @include('user.components.notification')
                     <li class="nav-item dropdown">
                         <a href="javascript:void(0)" class="nav-link" data-toggle="dropdown" data-animation="scale-up"
                            aria-expanded="false" role="button">
@@ -159,7 +160,7 @@
     </div>
     <footer class="site-footer">
         <div class="site-footer-legal">
-            Copyright ©️2017 - 2020 <a href="https://github.com/ProxyPanel/ProxyPanel" target="_blank">{{config('version.name')}}</a>
+            © 2017 - 2021 <a href="https://github.com/ProxyPanel/ProxyPanel" target="_blank">{{config('version.name')}} {{__('All rights reserved.')}}</a>
             🚀 Version: <code> {{config('version.number')}} </code>
         </div>
         <div class="site-footer-right">