Sfoglia il codice sorgente

Fix 通知系统设置异常,完善部分通知渠道

兔姬桑 4 anni fa
parent
commit
2f97e7b877

+ 1 - 1
app/Components/Helpers.php

@@ -166,7 +166,7 @@ class Helpers
             Cache::tags('sysConfig')->put('is_onlinePay', $value);
         } else {
             if (in_array($name, $notifications, true)) {
-                $value = self::setChannel(Config::find($name)->value);
+                $value = self::setChannel(json_decode(Config::find($name)->value, true));
             } else {
                 $value = Config::find($name)->value;
             }

+ 0 - 39
app/Console/Commands/AutoJob.php

@@ -6,16 +6,11 @@ use App\Components\Helpers;
 use App\Models\Config;
 use App\Models\Coupon;
 use App\Models\Invite;
-use App\Models\Node;
-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
 {
@@ -49,9 +44,6 @@ class AutoJob extends Command
             $this->dispatchPort();
         }
 
-        // 检测节点是否离线
-        $this->checkNodeStatus();
-
         // 检查维护模式
         if (sysConfig('maintenance_mode') && sysConfig('maintenance_time') && sysConfig('maintenance_time') <= date('c')) {
             Config::whereIn('name', ['maintenance_mode', 'maintenance_content', 'maintenance_time'])->update(['value' => null]);
@@ -174,35 +166,4 @@ class AutoJob extends Command
             ->orWhere('expired_at', '<=', date('Y-m-d', strtotime('-1 months')))
             ->update(['port' => 0]);
     }
-
-    // 检测节点是否离线
-    private function checkNodeStatus(): void
-    {
-        if (sysConfig('is_node_offline')) {
-            $offlineCheckTimes = sysConfig('offline_check_times');
-            $onlineNode = NodeHeartbeat::recently()->distinct()->pluck('node_id')->toArray();
-            foreach (Node::whereIsRelay(0)->whereStatus(1)->get() as $node) {
-                // 10分钟内无节点负载信息则认为是后端炸了
-                $nodeTTL = ! in_array($node->id, $onlineNode, true);
-                if ($nodeTTL && $offlineCheckTimes) {
-                    // 已通知次数
-                    $cacheKey = 'offline_check_times'.$node->id;
-                    if (Cache::has($cacheKey)) {
-                        $times = Cache::get($cacheKey);
-                    } else {
-                        // 键将保留24小时
-                        Cache::put($cacheKey, 1, Day);
-                        $times = 1;
-                    }
-
-                    if ($times < $offlineCheckTimes) {
-                        Cache::increment($cacheKey);
-                        Notification::send(User::permission('admin.node.edit,update')->orWhere(function ($query) {
-                            return $query->role('Super Admin');
-                        })->get(), new NodeOffline($node->name, $node->ip));
-                    }
-                }
-            }
-        }
-    }
 }

+ 48 - 8
app/Console/Commands/NodeBlockedDetection.php → app/Console/Commands/NodeStatusDetection.php

@@ -4,26 +4,34 @@ namespace App\Console\Commands;
 
 use App\Components\NetworkDetection;
 use App\Models\Node;
+use App\Models\NodeHeartbeat;
 use App\Models\User;
 use App\Notifications\NodeBlocked;
+use App\Notifications\NodeOffline;
 use Cache;
 use Illuminate\Console\Command;
 use Log;
 use Notification;
 
-class NodeBlockedDetection extends Command
+class NodeStatusDetection extends Command
 {
-    protected $signature = 'nodeBlockedDetection';
-    protected $description = '节点阻断检测';
+    protected $signature = 'nodeStatusDetection';
+    protected $description = '节点状态检测';
 
     public function handle(): void
     {
         $jobStartTime = microtime(true);
-        if (sysConfig('nodes_detection')) {
+        // 检测节点心跳是否异常
+        if (sysConfig('node_offline_notification')) {
+            $this->checkNodeStatus();
+        }
+
+        // 监测节点网络状态
+        if (sysConfig('node_blocked_notification')) {
             if (! Cache::has('LastCheckTime')) {
-                $this->checkNodes();
+                $this->checkNodeNetwork();
             } elseif (Cache::get('LastCheckTime') <= time()) {
-                $this->checkNodes();
+                $this->checkNodeNetwork();
             } else {
                 Log::info('下次节点阻断检测时间:'.date('Y-m-d H:i:s', Cache::get('LastCheckTime')));
             }
@@ -35,8 +43,40 @@ class NodeBlockedDetection extends Command
         Log::info("---【{$this->description}】完成---,耗时 {$jobUsedTime} 秒");
     }
 
-    // 监测节点状态
-    private function checkNodes(): void
+    private function checkNodeStatus(): void
+    {
+        $offlineCheckTimes = sysConfig('offline_check_times');
+        $onlineNode = NodeHeartbeat::recently()->distinct()->pluck('node_id')->toArray();
+        foreach (Node::whereIsRelay(0)->whereStatus(1)->whereNotIn('id', $onlineNode)->get() as $node) {
+            // 10分钟内无节点负载信息则认为是后端炸了
+            if ($offlineCheckTimes) {
+                // 已通知次数
+                $cacheKey = 'offline_check_times'.$node->id;
+                $times = 1;
+                if (Cache::has($cacheKey)) {
+                    $times = Cache::get($cacheKey);
+                } else {
+                    Cache::put($cacheKey, 1, Day); // 键将保留24小时
+                }
+                if ($times > $offlineCheckTimes) {
+                    continue;
+                }
+                Cache::increment($cacheKey);
+            }
+            $data[] = [
+                'name' => $node->name,
+                'ip'   => $node->ip,
+            ];
+        }
+
+        if (isset($data)) {
+            Notification::send(User::permission('admin.node.edit,update')->orWhere(function ($query) {
+                return $query->role('Super Admin');
+            })->get(), new NodeOffline($data));
+        }
+    }
+
+    private function checkNodeNetwork(): void
     {
         $detectionCheckTimes = sysConfig('detection_check_times');
         $sendText = false;

+ 3 - 3
app/Console/Kernel.php

@@ -10,7 +10,7 @@ use App\Console\Commands\AutoStatisticsNodeHourlyTraffic;
 use App\Console\Commands\AutoStatisticsUserDailyTraffic;
 use App\Console\Commands\AutoStatisticsUserHourlyTraffic;
 use App\Console\Commands\DailyJob;
-use App\Console\Commands\NodeBlockedDetection;
+use App\Console\Commands\NodeStatusDetection;
 use App\Console\Commands\ServiceTimer;
 use App\Console\Commands\UserExpireAutoWarning;
 use App\Console\Commands\UserTrafficAbnormalAutoWarning;
@@ -34,7 +34,7 @@ class Kernel extends ConsoleKernel
         AutoStatisticsUserDailyTraffic::class,
         AutoStatisticsUserHourlyTraffic::class,
         DailyJob::class,
-        NodeBlockedDetection::class,
+        NodeStatusDetection::class,
         ServiceTimer::class,
         UserExpireAutoWarning::class,
         UserTrafficAbnormalAutoWarning::class,
@@ -52,7 +52,7 @@ class Kernel extends ConsoleKernel
         $schedule->command('autoJob')->everyMinute();
         $schedule->command('serviceTimer')->everyTenMinutes();
         $schedule->command('autoClearLog')->everyThirtyMinutes();
-        $schedule->command('nodeBlockedDetection')->everyTenMinutes();
+        $schedule->command('nodeStatusDetection')->everyTenMinutes();
         $schedule->command('autoStatisticsNodeHourlyTraffic')->hourly();
         $schedule->command('autoStatisticsUserHourlyTraffic')->hourly();
         $schedule->command('userTrafficAbnormalAutoWarning')->hourly();

+ 3 - 2
app/Notifications/DataAnomaly.php

@@ -35,10 +35,11 @@ class DataAnomaly extends Notification implements ShouldQueue
             ->line(trans('notification.data_anomaly', ['id' => $this->id, 'upload' => $this->upload, 'download' => $this->download, 'total' => $this->total]));
     }
 
-    public function toArray($notifiable)
+    public function toCustom($notifiable)
     {
         return [
-            //
+            'title'   => trans('notification.data_anomaly'),
+            'content' => trans('notification.data_anomaly', ['id' => $this->id, 'upload' => $this->upload, 'download' => $this->download, 'total' => $this->total]),
         ];
     }
 }

+ 3 - 2
app/Notifications/NodeBlocked.php

@@ -31,10 +31,11 @@ class NodeBlocked extends Notification implements ShouldQueue
             ->line($this->content);
     }
 
-    public function toArray($notifiable)
+    public function toCustom($notifiable)
     {
         return [
-            //
+            'title'   => trans('notification.node_block'),
+            'content' => $this->content,
         ];
     }
 }

+ 3 - 3
app/Notifications/NodeDailyReport.php

@@ -15,11 +15,11 @@ class NodeDailyReport extends Notification implements ShouldQueue
 
     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";
+        $content = '| '.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";
+            $content .= "| {$node['name']} | {$node['upload']} | {$node['download']} | {$node['total']} |\r\n";
         }
-        $this->content = $temp;
+        $this->content = $content;
     }
 
     public function via($notifiable)

+ 12 - 9
app/Notifications/NodeOffline.php

@@ -11,13 +11,15 @@ class NodeOffline extends Notification implements ShouldQueue
 {
     use Queueable;
 
-    private $name;
-    private $ip;
+    private $content;
 
-    public function __construct($name, $ip)
+    public function __construct($nodes)
     {
-        $this->name = $name;
-        $this->ip = $ip;
+        $content = '### '.trans('notification.node_offline_content')."\r\n";
+        foreach ($nodes as $node) {
+            $content .= "- {$node['name']} [{$node['ip']}]\r\n";
+        }
+        $this->content = $content;
     }
 
     public function via($notifiable)
@@ -28,14 +30,15 @@ class NodeOffline extends Notification implements ShouldQueue
     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]));
+            ->subject(trans('notification.node_offline'))
+            ->markdown('mail.node.offline', ['content' => $this->content]);
     }
 
-    public function toArray($notifiable)
+    public function toCustom($notifiable)
     {
         return [
-            //
+            'title'   => trans('notification.node_offline'),
+            'content' => $this->content,
         ];
     }
 }

+ 4 - 5
app/Observers/ConfigObserver.php

@@ -11,12 +11,11 @@ class ConfigObserver
 {
     public function updated(Config $config): void
     {
-        // 更新系统参数缓存
-        Cache::tags('sysConfig')->put($config->name, $config->value ?? 0);
-
-        // 如果在线支付方式出现变动,改变 在线支付 设置状态
         if (in_array($config->name, ['is_AliPay', 'is_QQPay', 'is_WeChatPay', 'is_otherPay']) && Cache::tags('sysConfig')->has('is_onlinePay')) {
-            Helpers::cacheSysConfig('is_onlinePay');
+            Cache::tags('sysConfig')->put($config->name, $config->value);
+            Helpers::cacheSysConfig('is_onlinePay'); // 如果在线支付方式出现变动,改变 在线支付 设置状态
+        } else {
+            Helpers::cacheSysConfig($config->name); // 更新系统参数缓存
         }
 
         // 域名出现变动,更新路由设定

+ 2 - 2
resources/lang/en/notification.php

@@ -16,8 +16,8 @@ return [
     '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.',
+    'node_offline'            => 'Node maybe offline!',
+    'node_offline_content'    => 'Following Nodes abnormal: return heartbeats information are abnormal, Please pay attention.',
     'block_report'            => 'Blocked Report: ',
     'traffic_warning'         => 'Data Traffic Waring: ',
     'traffic_remain'          => 'Data Traffic Consumption: :num%',

+ 2 - 2
resources/lang/zh-CN/notification.php

@@ -16,8 +16,8 @@ return [
     'reply_ticket'            => '工单回复::title',
     'ticket_content'          => '工单内容:',
     'node_block'              => '节点阻断警告',
-    'node_offline'            => '节点[:name]异常警告',
-    'node_offline_content'    => '节点:name【:ip】异常:心跳异常,可能离线了',
+    'node_offline'            => '节点离线警告',
+    'node_offline_content'    => '以下节点存在异常:心跳异常,可能离线了:',
     'block_report'            => '阻断日志:',
     'traffic_warning'         => '流量提醒',
     'traffic_remain'          => '流量已使用::num%,请保持关注。',

+ 19 - 17
resources/views/admin/config/system.blade.php

@@ -864,14 +864,14 @@
                                 <div class="row">
                                     <div class="form-group col-lg-6">
                                         <div class="row">
-                                            <label class="col-md-3 col-form-label" for="account_expire_notification">用户过期警告</label>
+                                            <label class="col-md-3 col-form-label" for="account_expire_notification">账号过期通知</label>
                                             <div class="col-md-9">
                                                 <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>
+                                                <span class="text-help"> 通知用户账号即将到期 </span>
                                             </div>
                                         </div>
                                     </div>
@@ -887,20 +887,20 @@
                                                                 onclick="updateFromInput('expire_days','0')">{{trans('common.update')}}</button>
                                                     </div>
                                                 </div>
-                                                <span class="text-help"> 账号距离过期还差多少天时发警告邮件 </span>
+                                                <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="data_exhaust_notification">用户流量警告</label>
+                                            <label class="col-md-3 col-form-label" for="data_exhaust_notification">流量耗尽通知</label>
                                             <div class="col-md-9">
                                                 <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>
+                                                <span class="text-help"> 通知用户流量即将耗尽 </span>
                                             </div>
                                         </div>
                                     </div>
@@ -916,7 +916,7 @@
                                                                 onclick="updateFromInput('traffic_warning_percent','0')">{{trans('common.update')}}</button>
                                                     </div>
                                                 </div>
-                                                <span class="text-help"> 建议设置在70%~90% </span>
+                                                <span class="text-help"> 【流量耗尽通知】开始阈值,每日通知用户 </span>
                                             </div>
                                         </div>
                                     </div>
@@ -932,7 +932,7 @@
                                                     <option value="bark">Bark</option>
                                                     <option value="serverChan">ServerChan</option>
                                                 </select>
-                                                <span class="text-help"> 启用后如果节点离线会推送提醒 </span>
+                                                <span class="text-help"> 每10分钟检测节点离线并提醒管理员 </span>
                                             </div>
                                         </div>
                                     </div>
@@ -945,26 +945,25 @@
                                                     <div class="input-group-append">
                                                         <span class="input-group-text">次</span>
                                                         <button class="btn btn-primary" type="button"
-                                                                onclick="updateFromInput('offline_check_times','0','60')">{{trans('common.update')}}</button>
+                                                                onclick="updateFromInput('offline_check_times','0')">{{trans('common.update')}}</button>
                                                     </div>
                                                 </div>
-                                                <span class="text-help"> 提醒几次后不再提醒,为0时不限制,不超过60 </span>
+                                                <span class="text-help"> 24小时内提醒n次后不再提醒 </span>
                                             </div>
                                         </div>
                                     </div>
                                     <div class="form-group col-lg-6">
                                         <div class="row">
-                                            <label class="col-md-3 col-form-label" for="node_blocked_notification">节点阻断检测</label>
+                                            <label class="col-md-3 col-form-label" for="node_blocked_notification">节点阻断提醒</label>
                                             <div class="col-md-9">
                                                 <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>
+                                                <span class="text-help"> 每小时检测节点是否被阻断并提醒管理员 </span>
                                             </div>
                                         </div>
                                     </div>
@@ -1010,7 +1009,7 @@
                                                     <option value="bark">Bark</option>
                                                     <option value="serverChan">ServerChan</option>
                                                 </select>
-                                                <span class="text-help"> 工单关闭通知 </span>
+                                                <span class="text-help"> 工单关闭通知用户 </span>
                                             </div>
                                         </div>
                                     </div>
@@ -1027,7 +1026,7 @@
                                                     <option value="bark">Bark</option>
                                                     <option value="serverChan">ServerChan</option>
                                                 </select>
-                                                <span class="text-help"> 新工单通知 </span>
+                                                <span class="text-help"> 新工单通知管理/用户,取决于谁创建了新工单, </span>
                                             </div>
                                         </div>
                                     </div>
@@ -1044,7 +1043,7 @@
                                                     <option value="bark">Bark</option>
                                                     <option value="serverChan">ServerChan</option>
                                                 </select>
-                                                <span class="text-help"> 工单回复通知 </span>
+                                                <span class="text-help"> 工单回复通知对方 </span>
                                             </div>
                                         </div>
                                     </div>
@@ -1185,9 +1184,12 @@
                                                 <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>
+                                                    <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"> 1小时内流量超过异常阈值通知 </span>
+                                                <span class="text-help"> 1小时内流量超过异常阈值通知超管 </span>
                                             </div>
                                         </div>
                                     </div>

+ 1 - 1
resources/views/mail/node/dailyReport.blade.php

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

+ 8 - 0
resources/views/mail/node/offline.blade.php

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