Browse Source

定时任务BUG修正

bingo 7 years ago
parent
commit
c66ec8f61c

+ 7 - 5
.env.example

@@ -28,11 +28,13 @@ REDIS_PASSWORD=null
 REDIS_PORT=6379
 
 MAIL_DRIVER=smtp
-MAIL_HOST=smtp.mailtrap.io
-MAIL_PORT=2525
-MAIL_USERNAME=null
-MAIL_PASSWORD=null
-MAIL_ENCRYPTION=null
+MAIL_HOST=smtp.exmail.qq.com
+MAIL_PORT=465
[email protected]
+MAIL_PASSWORD=password
+MAIL_ENCRYPTION=ssl
[email protected]
+MAIL_FROM_NAME=SSRPanel
 
 PUSHER_APP_ID=
 PUSHER_APP_KEY=

+ 266 - 0
app/Console/Commands/AutoCheckNodeStatus.php

@@ -0,0 +1,266 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Components\ServerChan;
+use App\Http\Models\Config;
+use App\Http\Models\EmailLog;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeInfo;
+use App\Mail\nodeCrashWarning;
+use Cache;
+use Mail;
+use Log;
+
+class AutoCheckNodeStatus extends Command
+{
+    protected $signature = 'autoCheckNodeStatus';
+    protected $description = '自动检测节点状态';
+    protected static $config;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$config = $this->systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        // 监测节点状态
+        $this->checkNodeStatus();
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    // 监测节点状态
+    private function checkNodeStatus()
+    {
+        $title = "节点异常警告";
+
+        $nodeList = SsNode::query()->where('status', 1)->get();
+        foreach ($nodeList as $node) {
+            // TCP检测
+            $tcpCheck = $this->tcpCheck($node->ip, $node->ssh_port);
+            if (false !== $tcpCheck && $tcpCheck) {
+                $content = '节点无异常';
+                if ($tcpCheck === 1) {
+                    $content = "节点**{$node->name}【{$node->ip}】**异常:**服务器宕机**";
+                } else if ($tcpCheck === 2) {
+                    $content = "节点**{$node->name}【{$node->ip}】**异常:**海外不通**";
+                } else if ($tcpCheck === 3) {
+                    $content = "节点**{$node->name}【{$node->ip}】**异常:**TCP阻断**";
+                }
+
+                // 通知管理员
+                $this->notifyMaster($title, $content, $node->name, $node->server);
+            }
+
+            // 10分钟内无节点负载信息且TCP检测认为不是宕机则认为是SSR(R)后端炸了
+            $node_info = SsNodeInfo::query()->where('node_id', $node->id)->where('log_time', '>=', strtotime("-10 minutes"))->orderBy('id', 'desc')->first();
+            if ($tcpCheck !== 1 && (empty($node_info) || empty($node_info->load))) {
+                // 通知管理员
+                $this->notifyMaster($title, "节点**{$node->name}【{$node->ip}】**异常:**心跳异常**", $node->name, $node->server);
+            }
+        }
+    }
+
+    // 获取check-host的节点列表
+    private function getCheckHostServers()
+    {
+        $cacheKey = 'check_host_servers';
+        if (Cache::has($cacheKey)) {
+            return Cache::get($cacheKey);
+        }
+
+        $servers = $this->curlRequest("https://check-host.net/servers");
+        $servers = json_decode($servers, JSON_OBJECT_AS_ARRAY);
+        if (!$servers) {
+            // 删除这个缓存,防止异常
+            Cache::forget($cacheKey);
+
+            return [];
+        }
+
+        // 每7天更新一次check-host的节点列表
+        Cache::put($cacheKey, $servers['servers'], 10080);
+
+        return $servers;
+    }
+
+    // 随机获取一个check-host的海外检测节点
+    private function getRandomServer()
+    {
+        $servers = $this->getCheckHostServers();
+        if (!$servers) {
+            return 'us1.node.check-host.net'; // 没有数据时返回美国节点1,防止异常
+        }
+
+        if ($servers) {
+            //$servers = array_except($servers, 'cn1.node.check-host.net');
+            //$randServer = array_rand($servers);
+
+            $offset = array_search('cn1.node.check-host.net', $servers);
+            array_slice($servers, $offset, 1); // 剔除值
+
+            return array_rand($servers); // 取出一个随机值
+        }
+    }
+
+    // TCP检测
+    private function tcpCheck($ip, $sshPort)
+    {
+        try {
+            $overseasNode = $this->getRandomServer();
+            $result = $this->curlRequest("https://check-host.net/check-tcp?host={$ip}:{$sshPort}&node=cn1.node.check-host.net&node=" . $overseasNode);
+            $result = json_decode($result, JSON_OBJECT_AS_ARRAY);
+            if ($result['ok'] != 1) {
+                throw new \Exception("节点探测失败");
+            }
+
+            // 天若有情天亦老,我为长者续一秒
+            sleep(1);
+
+            // 拿到结果
+            $result = $this->curlRequest("https://check-host.net/check-result/" . $result['request_id']);
+            $result = json_decode($result, JSON_OBJECT_AS_ARRAY);
+            if (!$result['cn1.node.check-host.net'] && !$result[$overseasNode]) {
+                return 1; // 中美都不通,服务器宕机
+            } else if ($result['cn1.node.check-host.net'] && !$result[$overseasNode]) {
+                return 2; // 中通美不通,无法出国,可能是安全组策略限制(例如:阿里云、腾讯云)
+            } else if (!$result['cn1.node.check-host.net'] && $result[$overseasNode]) {
+                return 3; // 美通中不通,说明被墙进行TCP阻断
+            } else {
+                return 0; // 正常
+            }
+        } catch (\Exception $e) {
+            Log::error('节点监测请求失败:' . $e);
+
+            return false;
+        }
+    }
+
+
+    /**
+     * 通知管理员
+     *
+     * @param string $title      消息标题
+     * @param string $content    消息内容
+     * @param string $nodeName   节点名称
+     * @param string $nodeServer 节点域名
+     */
+    private function notifyMaster($title, $content, $nodeName, $nodeServer)
+    {
+        $this->notifyMasterByEmail($title, $content, $nodeName, $nodeServer);
+        $this->notifyMasterByServerchan($title, $content);
+    }
+
+    /**
+     * 发邮件通知管理员
+     *
+     * @param string $title      消息标题
+     * @param string $content    消息内容
+     * @param string $nodeName   节点名称
+     * @param string $nodeServer 节点域名
+     */
+    private function notifyMasterByEmail($title, $content, $nodeName, $nodeServer)
+    {
+        if (self::$config['is_node_crash_warning'] && self::$config['crash_warning_email']) {
+            try {
+                Mail::to(self::$config['crash_warning_email'])->send(new nodeCrashWarning(self::$config['website_name'], $nodeName, $nodeServer));
+                $this->addEmailLog(1, $title, $content);
+            } catch (\Exception $e) {
+                $this->addEmailLog(1, $title, $content, 0, $e->getMessage());
+            }
+        }
+    }
+
+    /**
+     * 通过ServerChan发微信消息提醒管理员
+     *
+     * @param string $title   消息标题
+     * @param string $content 消息内容
+     */
+    private function notifyMasterByServerchan($title, $content)
+    {
+        if (self::$config['is_server_chan'] && self::$config['server_chan_key']) {
+            $serverChan = new ServerChan();
+            $serverChan->send($title, $content);
+        }
+    }
+
+    /**
+     * 添加邮件发送日志
+     *
+     * @param int    $userId  接收者用户ID
+     * @param string $title   标题
+     * @param string $content 内容
+     * @param int    $status  投递状态
+     * @param string $error   投递失败时记录的异常信息
+     */
+    private function addEmailLog($userId, $title, $content, $status = 1, $error = '')
+    {
+        $emailLogObj = new EmailLog();
+        $emailLogObj->user_id = $userId;
+        $emailLogObj->title = $title;
+        $emailLogObj->content = $content;
+        $emailLogObj->status = $status;
+        $emailLogObj->error = $error;
+        $emailLogObj->created_at = date('Y-m-d H:i:s');
+        $emailLogObj->save();
+    }
+
+    // 系统配置
+    private function systemConfig()
+    {
+        $config = Config::query()->get();
+        $data = [];
+        foreach ($config as $vo) {
+            $data[$vo->name] = $vo->value;
+        }
+
+        return $data;
+    }
+
+    /**
+     * 发起一个CURL请求
+     *
+     * @param string $url  请求地址
+     * @param array  $data POST数据,留空则为GET
+     *
+     * @return mixed
+     */
+    private function curlRequest($url, $data = [])
+    {
+        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
+
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_TIMEOUT, 500);
+        // 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。
+        // 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, [
+            'Content-Type: application/json',
+            'Content-Length: ' . strlen($data)
+        ]);
+
+        // 如果data有数据,则用POST请求
+        if ($data) {
+            curl_setopt($ch, CURLOPT_POST, 1);
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        }
+
+        $result = curl_exec($ch);
+        curl_close($ch);
+
+        return $result;
+    }
+}

+ 4 - 0
app/Console/Commands/AutoClearLog.php

@@ -7,6 +7,7 @@ use App\Http\Models\Config;
 use App\Http\Models\SsNodeInfo;
 use App\Http\Models\SsNodeOnlineLog;
 use App\Http\Models\SsNodeTrafficHourly;
+use App\Http\Models\UserBanLog;
 use App\Http\Models\UserTrafficLog;
 use App\Http\Models\UserTrafficHourly;
 use Log;
@@ -42,6 +43,9 @@ class AutoClearLog extends Command
 
             // 自动清除60天以前的节点每小时流量数据日志
             SsNodeTrafficHourly::query()->where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-60 days')))->delete();
+
+            // 自动清除30天以前用户封禁日志
+            UserBanLog::query()->where('created_at', '<=', strtotime(date('Y-m-d H:i:s', strtotime("-30 days"))))->delete();
         }
 
         $jobEndTime = microtime(true);

+ 45 - 261
app/Console/Commands/AutoJob.php

@@ -3,25 +3,18 @@
 namespace App\Console\Commands;
 
 use Illuminate\Console\Command;
-use App\Components\ServerChan;
 use App\Http\Models\Coupon;
 use App\Http\Models\CouponLog;
-use App\Http\Models\EmailLog;
 use App\Http\Models\Invite;
 use App\Http\Models\Order;
 use App\Http\Models\Payment;
 use App\Http\Models\Config;
-use App\Http\Models\SsNode;
-use App\Http\Models\SsNodeInfo;
 use App\Http\Models\User;
 use App\Http\Models\UserLabel;
 use App\Http\Models\UserBanLog;
 use App\Http\Models\UserSubscribe;
 use App\Http\Models\UserSubscribeLog;
 use App\Http\Models\UserTrafficHourly;
-use App\Mail\nodeCrashWarning;
-use Cache;
-use Mail;
 use Log;
 use DB;
 
@@ -29,8 +22,6 @@ class AutoJob extends Command
 {
     protected $signature = 'autoJob';
     protected $description = '自动化任务';
-    protected $ssrCheckCacheKey = 'ssr_check_warning_';
-    protected $serverCheckCacheKey = 'server_check_warning_';
     protected static $config;
 
     public function __construct()
@@ -46,14 +37,11 @@ class AutoJob extends Command
     {
         $jobStartTime = microtime(true);
 
-        // SSR(R)被启用说明用户购买了流量,需要重置ban_time,防止异常
-        $this->resetBantime();
-
         // 优惠券到期自动置无效
         $this->expireCoupon();
 
         // 邀请码到期自动置无效
-        $this->exipreInvite();
+        $this->expireInvite();
 
         // 封禁访问异常的订阅链接
         $this->blockSubscribe();
@@ -73,21 +61,12 @@ class AutoJob extends Command
         // 关闭超时未支付订单
         $this->closeOrder();
 
-        // 监测节点状态
-        $this->checkNode();
-
         $jobEndTime = microtime(true);
         $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
 
         Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
     }
 
-    // 重置ban_time
-    private function resetBantime()
-    {
-        User::query()->where('enable', 1)->where('ban_time', -1)->update(['ban_time' => 0]);
-    }
-
     // 优惠券到期自动置无效
     private function expireCoupon()
     {
@@ -100,7 +79,7 @@ class AutoJob extends Command
     }
 
     // 邀请码到期自动置无效
-    private function exipreInvite()
+    private function expireInvite()
     {
         $inviteList = Invite::query()->where('status', 0)->where('dateline', '<=', date('Y-m-d H:i:s'))->get();
         if (!$inviteList->isEmpty()) {
@@ -133,16 +112,42 @@ class AutoJob extends Command
     // 封禁账号
     private function blockUsers()
     {
-        // 封禁24小时内流量异常账号
+        // 过期用户处理
+        $userList = User::query()->where('status', '>=', 0)->where('expire_time', '<=', date('Y-m-d'))->get();
+        if (!$userList->isEmpty()) {
+            foreach ($userList as $user) {
+                if (self::$config['is_ban_status']) {
+                    User::query()->where('id', $user->id)->update([
+                        'u'        => 0,
+                        'd'        => 0,
+                        'enable'   => 0,
+                        'ban_time' => 0,
+                        'status'   => -1
+                    ]);
+
+                    $this->addUserBanLog($user->id, 0, '【封禁账号】-账号已过期');
+                } else {
+                    User::query()->where('id', $user->id)->update([
+                        'u'        => 0,
+                        'd'        => 0,
+                        'enable'   => 0,
+                        'ban_time' => 0
+                    ]);
+
+                    $this->addUserBanLog($user->id, 0, '【封禁代理】-账号已过期');
+                }
+            }
+        }
+
+        // 封禁1小时内流量异常账号
         if (self::$config['is_traffic_ban']) {
-            $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->where('ban_time', '>=', 0)->get();
+            $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->where('ban_time', 0)->get();
             if (!$userList->isEmpty()) {
                 foreach ($userList as $user) {
-                    $time = date('Y-m-d H:i:s', time() - 24 * 60 * 60);
-                    $totalTraffic = UserTrafficHourly::query()->where('user_id', $user->id)->where('node_id', 0)->where('created_at', '>=', $time)->sum('total');
+                    // 多往前取5分钟,防止数据统计任务执行时间过长导致没有数据
+                    $totalTraffic = UserTrafficHourly::query()->where('user_id', $user->id)->where('node_id', 0)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))->sum('total');
                     if ($totalTraffic >= (self::$config['traffic_ban_value'] * 1024 * 1024 * 1024)) {
-                        $ban_time = strtotime(date('Y-m-d H:i:s', strtotime("+" . self::$config['traffic_ban_time'] . " minutes")));
-                        User::query()->where('id', $user->id)->update(['enable' => 0, 'ban_time' => $ban_time]);
+                        User::query()->where('id', $user->id)->update(['enable' => 0, 'ban_time' => strtotime(date('Y-m-d H:i:s', strtotime("+" . self::$config['traffic_ban_time'] . " minutes")))]);
 
                         // 写入日志
                         $this->addUserBanLog($user->id, self::$config['traffic_ban_time'], '【临时封禁代理】-24小时内流量异常');
@@ -152,29 +157,13 @@ class AutoJob extends Command
         }
 
         // 禁用流量超限用户
-        $userList = User::query()->where('enable', 1)->whereRaw("u + d >= transfer_enable")->get();
+        $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->where('ban_time', 0)->whereRaw("u + d >= transfer_enable")->get();
         if (!$userList->isEmpty()) {
             foreach ($userList as $user) {
-                User::query()->where('id', $user->id)->update(['enable' => 0, 'ban_time' => -1]);
+                User::query()->where('id', $user->id)->update(['enable' => 0]);
 
                 // 写入日志
-                $this->addUserBanLog($user->id, 0, '【完全封禁代理】-流量已用完');
-            }
-        }
-
-        // 自动禁用过期用户
-        $userList = User::query()->where('enable', 1)->where('expire_time', '<=', date('Y-m-d'))->get();
-        if (!$userList->isEmpty()) {
-            foreach ($userList as $user) {
-                if (self::$config['is_ban_status']) {
-                    User::query()->where('id', $user->id)->update(['enable' => 0, 'status' => -1, 'ban_time' => -1]);
-
-                    $this->addUserBanLog($user->id, 0, '【完全封禁账号及代理】-账号已过期');
-                } else {
-                    User::query()->where('id', $user->id)->update(['enable' => 0, 'ban_time' => -1]);
-
-                    $this->addUserBanLog($user->id, 0, '【完全封禁代理】-账号已过期');
-                }
+                $this->addUserBanLog($user->id, 0, '【封禁代理】-流量已用完');
             }
         }
     }
@@ -182,7 +171,7 @@ class AutoJob extends Command
     // 自动移除被封禁账号的标签
     private function removeUserLabels()
     {
-        $userList = User::query()->where('enable', 0)->where('ban_time', -1)->get();
+        $userList = User::query()->where('enable', 0)->get();
         if (!$userList->isEmpty()) {
             foreach ($userList as $user) {
                 UserLabel::query()->where('user_id', $user->id)->delete();
@@ -190,9 +179,10 @@ class AutoJob extends Command
         }
     }
 
-    // 解封被临时封禁的账号(ban_time > 0)
+    // 解封账号
     private function unblockUsers()
     {
+        // 解封被临时封禁的账号
         $userList = User::query()->where('status', '>=', 0)->where('ban_time', '>', 0)->get();
         foreach ($userList as $user) {
             if ($user->ban_time < time()) {
@@ -203,11 +193,11 @@ class AutoJob extends Command
             }
         }
 
-        // 用户购买了流量(可用大于已用)也解封
-        $userList = User::query()->where('status', '>=', 0)->where('enable', 0)->where('ban_time', -1)->whereRaw("u + d < transfer_enable")->get();
+        // 可用流量大于已用流量也解封(比如:邀请返利自动加了流量)
+        $userList = User::query()->where('status', '>=', 0)->where('enable', 0)->where('ban_time', 0)->whereRaw("u + d < transfer_enable")->get();
         if (!$userList->isEmpty()) {
             foreach ($userList as $user) {
-                User::query()->where('id', $user->id)->update(['enable' => 1, 'ban_time' => 0]);
+                User::query()->where('id', $user->id)->update(['enable' => 1]);
 
                 // 写入操作日志
                 $this->addUserBanLog($user->id, 0, '【自动解封】-有流量解封');
@@ -230,9 +220,9 @@ class AutoJob extends Command
             }
         }
 
-        // 被封禁账号自动释放端口
+        // 被封禁账号自动释放端口
         if (self::$config['auto_release_port']) {
-            $userList = User::query()->where('enable', 0)->where('ban_time', -1)->get();
+            $userList = User::query()->where('status', -1)->where('enable', 0)->get();
             if (!$userList->isEmpty()) {
                 foreach ($userList as $user) {
                     if ($user->port) {
@@ -275,142 +265,6 @@ class AutoJob extends Command
         }
     }
 
-    // 监测节点状态 TODO:需要改进,否则curl请求时间超长
-    private function checkNode()
-    {
-        $title = "节点异常警告";
-
-        $nodeList = SsNode::query()->where('status', 1)->get();
-        foreach ($nodeList as $node) {
-            // TCP检测
-            $tcpCheck = $this->tcpCheck($node->ip);
-            if (false !== $tcpCheck && $tcpCheck) {
-                // 10分钟内已发警告,则不再发
-                if (Cache::has($this->ssrCheckCacheKey . $node->id)) {
-                    continue;
-                }
-
-                $content = '节点无异常';
-                if ($tcpCheck === 1) {
-                    $content = "节点**{$node->name}【{$node->ip}】**异常:**宕机**";
-                } else if ($tcpCheck === 2) {
-                    $content = "节点**{$node->name}【{$node->ip}】**异常:**海外不通**";
-                } else if ($tcpCheck === 3) {
-                    $content = "节点**{$node->name}【{$node->ip}】**异常:**TCP阻断**";
-                }
-
-                // 通知管理员
-                $this->notifyMaster($title, $content, $node->name, $node->server);
-
-                // 写入发信缓存
-                Cache::put($this->ssrCheckCacheKey . $node->id, $node->name . '(' . $node->server . ')', 10);
-            }
-
-            // 10分钟内无节点负载信息且TCP检测认为不是宕机则认为是SSR(R)后端炸了
-            $node_info = SsNodeInfo::query()->where('node_id', $node->id)->where('log_time', '>=', strtotime("-10 minutes"))->orderBy('id', 'desc')->first();
-            if ($tcpCheck !== 1 && (empty($node_info) || empty($node_info->load))) {
-                // 10分钟内已发警告,则不再发
-                if (Cache::has($this->serverCheckCacheKey . $node->id)) {
-                    continue;
-                }
-
-                $content = "节点**{$node->name}【{$node->ip}】**异常:**心跳异常**";
-
-                // 通知管理员
-                $this->notifyMaster($title, $content, $node->name, $node->server);
-
-                // 写入发信缓存
-                Cache::put($this->serverCheckCacheKey . $node->id, $node->name . '(' . $node->server . ')', 10);
-            }
-        }
-    }
-
-    // TCP检测
-    private function tcpCheck($ip)
-    {
-        return 0;
-        try {
-            $tcpCN = $this->curlRequest("https://ipcheck.need.sh/api.php?location=cn&ip={$ip}&type=tcp");
-            $tcpUS = $this->curlRequest("https://ipcheck.need.sh/api.php?location=us&ip={$ip}&type=tcp");
-
-            if ($tcpCN['result'] != 'success' && $tcpUS['result'] != 'success') {
-                throw new \Exception("节点监测探测接口异常");
-            }
-
-            if (!$tcpCN['alive'] && !$tcpUS['alive']) {
-                return 1; // 中美都不通,服务器宕机
-            } else if ($tcpCN['alive'] && !$tcpUS['alive']) {
-                return 2; // 中通美不通,无法出国,可能是安全组策略限制(例如:阿里云、腾讯云)
-            } else if (!$tcpCN['alive'] && $tcpUS['alive']) {
-                return 3; // 美通中不通,说明被墙进行TCP阻断
-            } else {
-                return 0; // 正常
-            }
-        } catch (\Exception $e) {
-            Log::error('节点监测请求失败:' . $e);
-
-            return false;
-        }
-    }
-
-    // 检测服务
-//    private function checkHost()
-//    {
-//        $data =
-//        $header = [
-//            'Content-Type: application/json',
-//            'Content-Length: ' . strlen($data)
-//        ];
-//    }
-
-    /**
-     * 通知管理员
-     *
-     * @param string $title      消息标题
-     * @param string $content    消息内容
-     * @param string $nodeName   节点名称
-     * @param string $nodeServer 节点域名
-     */
-    private function notifyMaster($title, $content, $nodeName, $nodeServer)
-    {
-        $this->notifyMasterByEmail($title, $content, $nodeName, $nodeServer);
-        $this->notifyMasterByServerchan($title, $content);
-    }
-
-    /**
-     * 发邮件通知管理员
-     *
-     * @param string $title      消息标题
-     * @param string $content    消息内容
-     * @param string $nodeName   节点名称
-     * @param string $nodeServer 节点域名
-     */
-    private function notifyMasterByEmail($title, $content, $nodeName, $nodeServer)
-    {
-        if (self::$config['is_node_crash_warning'] && self::$config['crash_warning_email']) {
-            try {
-                Mail::to(self::$config['crash_warning_email'])->send(new nodeCrashWarning(self::$config['website_name'], $nodeName, $nodeServer));
-                $this->addEmailLog(1, $title, $content);
-            } catch (\Exception $e) {
-                $this->addEmailLog(1, $title, $content, 0, $e->getMessage());
-            }
-        }
-    }
-
-    /**
-     * 通过ServerChan发微信消息提醒管理员
-     *
-     * @param string $title   消息标题
-     * @param string $content 消息内容
-     */
-    private function notifyMasterByServerchan($title, $content)
-    {
-        if (self::$config['is_server_chan'] && self::$config['server_chan_key']) {
-            $serverChan = new ServerChan();
-            $serverChan->send($title, $content);
-        }
-    }
-
     /**
      * 添加用户封禁日志
      *
@@ -427,27 +281,6 @@ class AutoJob extends Command
         $log->save();
     }
 
-    /**
-     * 添加邮件发送日志
-     *
-     * @param int    $user_id 接收者用户ID
-     * @param string $title   标题
-     * @param string $content 内容
-     * @param int    $status  投递状态
-     * @param string $error   投递失败时记录的异常信息
-     */
-    private function addEmailLog($userId, $title, $content, $status = 1, $error = '')
-    {
-        $emailLogObj = new EmailLog();
-        $emailLogObj->user_id = $userId;
-        $emailLogObj->title = $title;
-        $emailLogObj->content = $content;
-        $emailLogObj->status = $status;
-        $emailLogObj->error = $error;
-        $emailLogObj->created_at = date('Y-m-d H:i:s');
-        $emailLogObj->save();
-    }
-
     /**
      * 添加优惠券操作日志
      *
@@ -509,53 +342,4 @@ class AutoJob extends Command
 
         return $port;
     }
-
-    /**
-     * 发起一个CURL请求
-     *
-     * @param string $url
-     * @param array  $data
-     * @param array  $header
-     *
-     * @return mixed
-     */
-    private function curlRequest($url, $data = [], $header = [])
-    {
-        $ch = curl_init();
-        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-        curl_setopt($ch, CURLOPT_TIMEOUT, 500);
-        // 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。
-        // 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。
-        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
-        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
-        curl_setopt($ch, CURLOPT_URL, $url);
-
-        // 如果设置了header
-        if ($header) {
-//            $header = [
-//                'Content-Type: application/json',
-//                'Content-Length: ' . strlen($data)
-//            ];
-//            $header = [
-//                'Content-Type: text/xml; charset=utf-8',
-//                'Content-Length: ' . strlen($data)
-//            ];
-//            $header = [
-//                'Content-type: text/plain',
-//                'Content-Length: ' . strlen($data)
-//            ];
-            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
-        }
-
-        // 如果data有数据,则用POST请求
-        if ($data) {
-            curl_setopt($ch, CURLOPT_POST, 1);
-            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
-        }
-
-        $result = curl_exec($ch);
-        curl_close($ch);
-
-        return json_decode($result, JSON_OBJECT_AS_ARRAY);
-    }
 }

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

@@ -29,7 +29,7 @@ class UserExpireAutoWarning extends Command
         $config = $this->systemConfig();
 
         if ($config['expire_warning']) {
-            $userList = User::query()->where('transfer_enable', '>', 0)->whereIn('status', [0, 1])->where('enable', 1)->get();
+            $userList = User::query()->where('transfer_enable', '>', 0)->where('status', '>=', 0)->where('enable', 1)->get();
             foreach ($userList as $user) {
                 // 用户名不是邮箱的跳过
                 if (false === filter_var($user->username, FILTER_VALIDATE_EMAIL)) {
@@ -39,7 +39,7 @@ class UserExpireAutoWarning extends Command
                 $lastCanUseDays = floor(round(strtotime($user->expire_time) - strtotime(date('Y-m-d H:i:s'))) / 3600 / 24);
                 if ($lastCanUseDays > 0 && $lastCanUseDays <= $config['expire_days']) {
                     $title = '账号过期提醒';
-                    $content = '账号还剩' . $lastCanUseDays . '天即将过期';
+                    $content = '您的账号还剩' . $lastCanUseDays . '天即将过期';
 
                     try {
                         Mail::to($user->username)->send(new userExpireWarning($config['website_name'], $lastCanUseDays));

+ 11 - 21
app/Console/Commands/UserTrafficAbnormalAutoWarning.php

@@ -24,33 +24,23 @@ class UserTrafficAbnormalAutoWarning extends Command
     {
         $jobStartTime = microtime(true);
 
-        $config = $this->systemConfig();
-
-        // 24小时内流量异常用户
-        $userTotalTrafficList = UserTrafficHourly::query()->where('node_id', 0)->where('total', '>', 104857600)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 24 * 60 * 60))->groupBy('user_id')->selectRaw("user_id, sum(total) as totalTraffic")->get(); // 只统计100M以上的记录,加快查询速度
+        // 1小时内流量异常用户(多往前取5分钟,防止数据统计任务执行时间过长导致没有数据)
+        $userTotalTrafficList = UserTrafficHourly::query()->where('node_id', 0)->where('total', '>', 104857600)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))->groupBy('user_id')->selectRaw("user_id, sum(total) as totalTraffic")->get(); // 只统计100M以上的记录,加快查询速度
         if (!$userTotalTrafficList->isEmpty()) {
+            $title = "流量异常用户提醒";
+            $config = $this->systemConfig();
+
             foreach ($userTotalTrafficList as $vo) {
                 $user = User::query()->where('id', $vo->user_id)->first();
-                $cacheKey = 'user_traffic_abnormal_warning_' . $user->id;
-
-                if ($vo->totalTraffic > ($config['traffic_ban_value'] * 1024 * 1024 * 1024)) {
-                    // 通过ServerChan发微信消息提醒管理员
-                    if ($config['is_server_chan'] && $config['server_chan_key'] && Cache::get($cacheKey) <= 3) {
-                        $traffic = UserTrafficHourly::query()->where('node_id', 0)->where('user_id', $vo->user_id)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 24 * 60 * 60))->selectRaw("user_id, sum(`u`) as totalU, sum(`d`) as totalD, sum(total) as totalTraffic")->first();
 
-                        $title = "流量异常用户警告";
-                        $content = "用户**{$user->username}(ID:{$user->id})**,24小时内上传流量:{$this->flowAutoShow($traffic->totalU)},下载流量:{$this->flowAutoShow($traffic->totalD)},共计:{$this->flowAutoShow($traffic->totalTraffic)},请及时关注。";
+                // 通过ServerChan发微信消息提醒管理员
+                if ($vo->totalTraffic > ($config['traffic_ban_value'] * 1024 * 1024 * 1024) && $config['is_server_chan'] && $config['server_chan_key']) {
+                    $traffic = UserTrafficHourly::query()->where('node_id', 0)->where('user_id', $vo->user_id)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))->selectRaw("user_id, sum(`u`) as totalU, sum(`d`) as totalD, sum(total) as totalTraffic")->first();
 
-                        $serverChan = new ServerChan();
-                        $serverChan->send($title, $content);
-                    }
+                    $content = "用户**{$user->username}(ID:{$user->id})**,最近1小时**上传流量:{$this->flowAutoShow($traffic->totalU)},下载流量:{$this->flowAutoShow($traffic->totalD)},共计:{$this->flowAutoShow($traffic->totalTraffic)}**。";
 
-                    // 写入发信缓存
-                    if (Cache::has($cacheKey)) {
-                        Cache::increment($cacheKey);
-                    } else {
-                        Cache::put($cacheKey, 1, 60);
-                    }
+                    $serverChan = new ServerChan();
+                    $serverChan->send($title, $content);
                 }
             }
         }

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

@@ -29,7 +29,7 @@ class UserTrafficAutoWarning extends Command
         $config = $this->systemConfig();
 
         if ($config['traffic_warning']) {
-            $userList = User::query()->where('transfer_enable', '>', 0)->whereIn('status', [0, 1])->where('enable', 1)->get();
+            $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->where('transfer_enable', '>', 0)->get();
             foreach ($userList as $user) {
                 // 用户名不是邮箱的跳过
                 if (false === filter_var($user->username, FILTER_VALIDATE_EMAIL)) {
@@ -38,8 +38,8 @@ class UserTrafficAutoWarning extends Command
 
                 $usedPercent = round(($user->d + $user->u) / $user->transfer_enable, 2) * 100; // 已使用流量百分比
                 if ($usedPercent >= $config['traffic_warning_percent']) {
-                    $title = '流量警告';
-                    $content = '流量已使用:' . $usedPercent . '%,超过设置的流量阈值' . $config['traffic_warning_percent'] . '%';
+                    $title = '流量提醒';
+                    $content = '流量已使用:' . $usedPercent . '%,请保持关注。';
 
                     try {
                         Mail::to($user->username)->send(new userTrafficWarning($config['website_name'], $usedPercent));

+ 5 - 9
app/Console/Kernel.php

@@ -15,15 +15,13 @@ class Kernel extends ConsoleKernel
     protected $commands = [
         \App\Console\Commands\AutoJob::class,
         \App\Console\Commands\AutoClearLog::class,
-
         \App\Console\Commands\AutoDecGoodsTraffic::class,
         \App\Console\Commands\AutoResetUserTraffic::class,
-
+        \App\Console\Commands\AutoCheckNodeStatus::class,
         \App\Console\Commands\AutoStatisticsNodeDailyTraffic::class,
         \App\Console\Commands\AutoStatisticsNodeHourlyTraffic::class,
         \App\Console\Commands\AutoStatisticsUserDailyTraffic::class,
         \App\Console\Commands\AutoStatisticsUserHourlyTraffic::class,
-
         \App\Console\Commands\UserTrafficAbnormalAutoWarning::class,
         \App\Console\Commands\UserExpireAutoWarning::class,
         \App\Console\Commands\UserTrafficAutoWarning::class,
@@ -40,18 +38,16 @@ class Kernel extends ConsoleKernel
     {
         $schedule->command('autoJob')->everyMinute();
         $schedule->command('autoClearLog')->everyThirtyMinutes();
-
         $schedule->command('autoDecGoodsTraffic')->everyTenMinutes();
         $schedule->command('autoResetUserTraffic')->everyFiveMinutes();
-
+        $schedule->command('autoCheckNodeStatus')->hourly();
         $schedule->command('autoStatisticsNodeDailyTraffic')->dailyAt('23:55');
         $schedule->command('autoStatisticsNodeHourlyTraffic')->hourly();
         $schedule->command('autoStatisticsUserDailyTraffic')->dailyAt('23:50');
         $schedule->command('autoStatisticsUserHourlyTraffic')->hourly();
-
-        $schedule->command('userTrafficAbnormalAutoWarning')->everyThirtyMinutes();
-        $schedule->command('userExpireAutoWarning')->daily();
-        $schedule->command('userTrafficAutoWarning')->daily();
+        $schedule->command('userTrafficAbnormalAutoWarning')->hourly();
+        $schedule->command('userExpireAutoWarning')->dailyAt('10:20');
+        $schedule->command('userTrafficAutoWarning')->dailyAt('10:30');
     }
 
     /**

+ 4 - 12
app/Http/Controllers/AdminController.php

@@ -2050,27 +2050,19 @@ EOF;
     public function handleUserBalance(Request $request)
     {
         if ($request->method() == 'POST') {
-            $user_id = $request->get('user_id');
+            $userId = $request->get('user_id');
             $amount = $request->get('amount');
 
-            if (empty($user_id) || empty($amount)) {
+            if (empty($userId) || empty($amount)) {
                 return Response::json(['status' => 'fail', 'data' => '', 'message' => '充值异常']);
             }
 
             DB::beginTransaction();
             try {
-                $user = User::query()->where('id', $user_id)->first();
+                $user = User::query()->where('id', $userId)->first();
 
                 // 写入余额变动日志
-                $userBalanceLog = new UserBalanceLog();
-                $userBalanceLog->user_id = $user_id;
-                $userBalanceLog->order_id = 0;
-                $userBalanceLog->before = $user->balance;
-                $userBalanceLog->after = $user->balance + $amount;
-                $userBalanceLog->amount = $amount;
-                $userBalanceLog->desc = '后台手动充值';
-                $userBalanceLog->created_at = date('Y-m-d H:i:s');
-                $userBalanceLog->save();
+                $this->addUserBalanceLog($userId, 0, $user->balance, $user->balance + $amount, $amount, '后台手动充值');
 
                 // 加减余额
                 if ($amount < 0) {

+ 97 - 14
app/Http/Controllers/Controller.php

@@ -3,6 +3,9 @@
 namespace App\Http\Controllers;
 
 use App\Http\Models\CouponLog;
+use App\Http\Models\ReferralLog;
+use App\Http\Models\UserBalanceLog;
+use App\Http\Models\UserScoreLog;
 use App\Http\Models\UserSubscribe;
 use Illuminate\Foundation\Bus\DispatchesJobs;
 use Illuminate\Routing\Controller as BaseController;
@@ -186,17 +189,20 @@ class Controller extends BaseController
      * @param string $content 内容
      * @param int    $status  投递状态
      * @param string $error   投递失败时记录的异常信息
+     *
+     * @return int
      */
     public function sendEmailLog($user_id, $title, $content, $status = 1, $error = '')
     {
-        $emailLogObj = new EmailLog();
-        $emailLogObj->user_id = $user_id;
-        $emailLogObj->title = $title;
-        $emailLogObj->content = $content;
-        $emailLogObj->status = $status;
-        $emailLogObj->error = $error;
-        $emailLogObj->created_at = date('Y-m-d H:i:s');
-        $emailLogObj->save();
+        $log = new EmailLog();
+        $log->user_id = $user_id;
+        $log->title = $title;
+        $log->content = $content;
+        $log->status = $status;
+        $log->error = $error;
+        $log->created_at = date('Y-m-d H:i:s');
+
+        return $log->save();
     }
 
     /**
@@ -206,15 +212,92 @@ class Controller extends BaseController
      * @param int    $goodsId  商品ID
      * @param int    $orderId  订单ID
      * @param string $desc     备注
+     *
+     * @return int
      */
     public function addCouponLog($couponId, $goodsId, $orderId, $desc = '')
     {
-        $couponLog = new CouponLog();
-        $couponLog->coupon_id = $couponId;
-        $couponLog->goods_id = $goodsId;
-        $couponLog->order_id = $orderId;
-        $couponLog->desc = $desc;
-        $couponLog->save();
+        $log = new CouponLog();
+        $log->coupon_id = $couponId;
+        $log->goods_id = $goodsId;
+        $log->order_id = $orderId;
+        $log->desc = $desc;
+
+        return $log->save();
+    }
+
+    /**
+     * 记录余额操作日志
+     *
+     * @param int    $userId 用户ID
+     * @param string $oid    订单ID
+     * @param int    $before 记录前余额
+     * @param int    $after  记录后余额
+     * @param int    $amount 发生金额
+     * @param string $desc   描述
+     *
+     * @return int
+     */
+    public function addUserBalanceLog($userId, $oid, $before, $after, $amount, $desc = '')
+    {
+        $log = new UserBalanceLog();
+        $log->user_id = $userId;
+        $log->order_id = $oid;
+        $log->before = $before;
+        $log->after = $after;
+        $log->amount = $amount;
+        $log->desc = $desc;
+        $log->created_at = date('Y-m-d H:i:s');
+
+        return $log->save();
+    }
+
+    /**
+     * 添加返利日志
+     *
+     * @param int $userId    用户ID
+     * @param int $refUserId 返利用户ID
+     * @param int $oid       订单ID
+     * @param int $amount    发生金额
+     * @param int $refAmount 返利金额
+     *
+     * @return int
+     */
+    public function addReferralLog($userId, $refUserId, $oid, $amount, $refAmount)
+    {
+        $log = new ReferralLog();
+        $log->user_id = $userId;
+        $log->ref_user_id = $refUserId;
+        $log->order_id = $oid;
+        $log->amount = $amount;
+        $log->ref_amount = $refAmount;
+        $log->status = 0;
+
+        return $log->save();
+    }
+
+    /**
+     * 添加积分日志
+     *
+     * @param int    $userId 用户ID
+     * @param int    $before 记录前余额
+     * @param int    $after  记录后余额
+     * @param int    $score  发生值
+     * @param string $desc   描述
+     *
+     * @return int
+     */
+    public function addUserScoreLog($userId, $before, $after, $score, $desc = '')
+    {
+        $log = new UserScoreLog();
+        $log->user_id = $userId;
+        $log->before = $before;
+        $log->after = $after;
+        $log->score = $score;
+        $log->desc = $desc;
+        $log->created_at = date('Y-m-d H:i:s');
+
+        return $log->save();
     }
 
     // 将Base64图片转换为本地图片并保存

+ 1 - 8
app/Http/Controllers/LoginController.php

@@ -75,14 +75,7 @@ class LoginController extends Controller
                     $score = mt_rand($this->systemConfig['min_rand_score'], $this->systemConfig['max_rand_score']);
                     $ret = User::query()->where('id', $user->id)->increment('score', $score);
                     if ($ret) {
-                        $obj = new UserScoreLog();
-                        $obj->user_id = $user->id;
-                        $obj->before = $user->score;
-                        $obj->after = $user->score + $score;
-                        $obj->score = $score;
-                        $obj->desc = '登录送积分';
-                        $obj->created_at = date('Y-m-d H:i:s');
-                        $obj->save();
+                        $this->addUserScoreLog($user->id, $user->score, $user->score + $score, $score, '登录送积分');
 
                         // 登录多久后再登录可以获取积分
                         $ttl = $this->systemConfig['login_add_score_range'] ? $this->systemConfig['login_add_score_range'] : 1440;

+ 5 - 38
app/Http/Controllers/UserController.php

@@ -5,7 +5,6 @@ namespace App\Http\Controllers;
 use App\Components\ServerChan;
 use App\Http\Models\Article;
 use App\Http\Models\Coupon;
-use App\Http\Models\CouponLog;
 use App\Http\Models\Goods;
 use App\Http\Models\GoodsLabel;
 use App\Http\Models\Invite;
@@ -19,9 +18,7 @@ use App\Http\Models\SsNodeInfo;
 use App\Http\Models\Ticket;
 use App\Http\Models\TicketReply;
 use App\Http\Models\User;
-use App\Http\Models\UserBalanceLog;
 use App\Http\Models\UserLabel;
-use App\Http\Models\UserScoreLog;
 use App\Http\Models\UserSubscribe;
 use App\Http\Models\UserTrafficDaily;
 use App\Http\Models\UserTrafficHourly;
@@ -919,15 +916,7 @@ class UserController extends Controller
                 User::query()->where('id', $user->id)->decrement('balance', $amount * 100);
 
                 // 记录余额操作日志
-                $userBalanceLog = new UserBalanceLog();
-                $userBalanceLog->user_id = $user->id;
-                $userBalanceLog->order_id = $order->oid;
-                $userBalanceLog->before = $user->balance;
-                $userBalanceLog->after = $user->balance - $amount;
-                $userBalanceLog->amount = -1 * $amount;
-                $userBalanceLog->desc = '购买服务:' . $goods->name;
-                $userBalanceLog->created_at = date('Y-m-d H:i:s');
-                $userBalanceLog->save();
+                $this->addUserBalanceLog($user->id, $order->oid, $user->balance, $user->balance - $amount, -1 * $amount, '购买服务:' . $goods->name);
 
                 // 优惠券置为已使用
                 if (!empty($coupon)) {
@@ -991,14 +980,7 @@ class UserController extends Controller
 
                 // 写入返利日志
                 if ($user->referral_uid) {
-                    $referralLog = new ReferralLog();
-                    $referralLog->user_id = $user->id;
-                    $referralLog->ref_user_id = $user->referral_uid;
-                    $referralLog->order_id = $order->oid;
-                    $referralLog->amount = $amount;
-                    $referralLog->ref_amount = $amount * $this->systemConfig['referral_percent'];
-                    $referralLog->status = 0;
-                    $referralLog->save();
+                    $this->addReferralLog($user->id, $user->referral_uid, $order->oid, $amount, $amount * $this->systemConfig['referral_percent']);
                 }
 
                 DB::commit();
@@ -1041,17 +1023,10 @@ class UserController extends Controller
         DB::beginTransaction();
         try {
             // 写入积分操作日志
-            $userScoreLog = new UserScoreLog();
-            $userScoreLog->user_id = $user['id'];
-            $userScoreLog->before = $user['score'];
-            $userScoreLog->after = 0;
-            $userScoreLog->score = -1 * $user['score'];
-            $userScoreLog->desc = '积分兑换流量';
-            $userScoreLog->created_at = date('Y-m-d H:i:s');
-            $userScoreLog->save();
+            $ret = $this->addUserScoreLog($user['id'], $user['score'], 0, -1 * $user['score'], '积分兑换流量');
 
             // 扣积分加流量
-            if ($userScoreLog->id) {
+            if ($ret) {
                 User::query()->where('id', $user['id'])->update(['score' => 0]);
                 User::query()->where('id', $user['id'])->increment('transfer_enable', $user['score'] * 1048576);
             }
@@ -1222,15 +1197,7 @@ class UserController extends Controller
             $user = User::query()->where('id', $user['id'])->first();
 
             // 写入日志
-            $log = new UserBalanceLog();
-            $log->user_id = $user->id;
-            $log->order_id = 0;
-            $log->before = $user->balance;
-            $log->after = $user->balance + $coupon->amount;
-            $log->amount = $coupon->amount;
-            $log->desc = '用户手动充值 - [充值券:' . $coupon_sn . ']';
-            $log->created_at = date('Y-m-d H:i:s');
-            $log->save();
+            $this->addUserBalanceLog($user->id, 0, $user->balance, $user->balance + $coupon->amount, $coupon->amount, '用户手动充值 - [充值券:' . $coupon_sn . ']');
 
             // 余额充值
             $user->balance = $user->balance + $coupon->amount;

+ 2 - 2
config/mail.php

@@ -56,8 +56,8 @@ return [
     */
 
     'from' => [
-        'address' => env('MAIL_FROM_ADDRESS', '[email protected]'),
-        'name'    => env('MAIL_FROM_NAME', 'Example'),
+        'address' => env('MAIL_FROM_ADDRESS'),
+        'name'    => env('MAIL_FROM_NAME'),
     ],
 
     /*

+ 11 - 32
readme.md

@@ -64,43 +64,22 @@ cd /home/wwwroot/
 git clone https://github.com/ssrpanel/SSRPanel.git
 ````
 
-#### 安装面板
-````
-cd SSRPanel/
-php composer.phar install
-cp .env.example .env
-php artisan key:generate
-chown -R www:www storage/
-chmod -R 777 storage/
-````
-
 #### 配置数据库
-
-##### 连接数据库
 ````
 1.创建一个utf8mb4的数据库
 2.编辑 .env 文件,修改 DB_ 开头的值
+3.导入 sql/db.sql 到数据库
 ````
 
-##### 自动部署
-
-###### 迁移(创建表结构)
-````
-php artisan migrate
-````
-
-###### 播种(填充数据)
-````
-php artisan db:seed --class=ConfigTableSeeder
-php artisan db:seed --class=CountryTableSeeder
-php artisan db:seed --class=LevelTableSeeder
-php artisan db:seed --class=SsConfigTableSeeder
-php artisan db:seed --class=UserTableSeeder
-````
-
-##### 手工部署
+#### 安装面板
 ````
-注意:迁移未经完整测试,存在BUG(主要是我懒得用),可以手动将sql/db.sql导入到创建好的数据库
+cd SSRPanel/
+cp .env.example .env
+(然后修改数据库连接信息)
+php artisan key:generate
+php composer.phar install
+chown -R www:www storage/
+chmod -R 777 storage/
 ````
 
 #### 加入NGINX的URL重写规则
@@ -173,7 +152,7 @@ crontab -e -u www
 
 ## 英文版
 ````
-修改 config/app.php 下的 locale 值为 en
+修改 .env 的 APP_LOCALE 值为 en
 欢迎提交其他语言的语言包,语言包在:resources/lang下
 ````
 
@@ -195,7 +174,7 @@ sh initcfg.sh
 配置 usermysql.json 里的数据库链接,NODE_ID就是节点ID,对应面板后台里添加的节点的自增ID,所以请先把面板搭好,搭好后进后台添加节点
 ````
 
-###### 一键自动部署(基于SSR3.4)
+###### 一键自动部署(基于SSR3.4)(不推荐,该版本有内存溢出BUG)
 ````
 wget -N --no-check-certificate https://raw.githubusercontent.com/ssrpanel/ssrpanel/master/server/deploy_ssr.sh;chmod +x deploy_ssr.sh;./deploy_ssr.sh
 

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

@@ -488,43 +488,43 @@
                                                     </div>
                                                     <div class="form-group">
                                                         <div class="col-md-6">
-                                                            <label for="is_server_chan" class="col-md-3 control-label">ServerChan</label>
+                                                            <label for="is_namesilo" class="col-md-3 control-label">Namesilo</label>
                                                             <div class="col-md-9">
-                                                                <input type="checkbox" class="make-switch" @if($is_server_chan) checked @endif id="is_server_chan" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
-                                                                <span class="help-block"> 推送节点宕机提醒、用户流量异常警告(<a href="http://sc.ftqq.com" target="_blank">绑定微信</a>) </span>
+                                                                <input type="checkbox" class="make-switch" @if($is_namesilo) checked @endif id="is_namesilo" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
+                                                                <span class="help-block"> 添加、编辑节点的绑定域名时自动更新域名DNS记录值为节点IP(<a href="https://www.namesilo.com/account_api.php" target="_blank">创建API KEY</a>) </span>
                                                             </div>
                                                         </div>
                                                         <div class="col-md-6">
-                                                            <label for="server_chan_key" class="col-md-3 control-label">SCKEY</label>
+                                                            <label for="namesilo_key" class="col-md-3 control-label">Namesilo API KEY</label>
                                                             <div class="col-md-9">
                                                                 <div class="input-group">
-                                                                    <input class="form-control" type="text" name="server_chan_key" value="{{$server_chan_key}}" id="server_chan_key" placeholder="请到ServerChan申请" />
+                                                                    <input class="form-control" type="text" name="namesilo_key" value="{{$namesilo_key}}" id="namesilo_key" placeholder="填入Namesilo上申请的API KEY" />
                                                                     <span class="input-group-btn">
-                                                                        <button class="btn btn-success" type="button" onclick="setServerChanKey()">修改</button>
+                                                                        <button class="btn btn-success" type="button" onclick="setNamesiloKey()">修改</button>
                                                                     </span>
                                                                 </div>
-                                                                <span class="help-block"> 启用ServerChan,请务必填入本值(<a href="http://sc.ftqq.com" target="_blank">申请SCKEY</a>) </span>
+                                                                <span class="help-block"> 域名必须是<a href="https://www.namesilo.com/?rid=326ec20pa" target="_blank">www.namesilo.com</a>上购买的 </span>
                                                             </div>
                                                         </div>
                                                     </div>
                                                     <div class="form-group">
                                                         <div class="col-md-6">
-                                                            <label for="is_namesilo" class="col-md-3 control-label">Namesilo</label>
+                                                            <label for="is_server_chan" class="col-md-3 control-label">ServerChan</label>
                                                             <div class="col-md-9">
-                                                                <input type="checkbox" class="make-switch" @if($is_namesilo) checked @endif id="is_namesilo" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
-                                                                <span class="help-block"> 添加、编辑节点的绑定域名时自动更新域名DNS记录值为节点IP(<a href="https://www.namesilo.com/account_api.php" target="_blank">创建API KEY</a>) </span>
+                                                                <input type="checkbox" class="make-switch" @if($is_server_chan) checked @endif id="is_server_chan" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
+                                                                <span class="help-block"> 推送节点宕机提醒、用户流量异常警告(<a href="http://sc.ftqq.com" target="_blank">绑定微信</a>) </span>
                                                             </div>
                                                         </div>
                                                         <div class="col-md-6">
-                                                            <label for="namesilo_key" class="col-md-3 control-label">Namesilo API KEY</label>
+                                                            <label for="server_chan_key" class="col-md-3 control-label">SCKEY</label>
                                                             <div class="col-md-9">
                                                                 <div class="input-group">
-                                                                    <input class="form-control" type="text" name="namesilo_key" value="{{$namesilo_key}}" id="namesilo_key" placeholder="填入Namesilo上申请的API KEY" />
+                                                                    <input class="form-control" type="text" name="server_chan_key" value="{{$server_chan_key}}" id="server_chan_key" placeholder="请到ServerChan申请" />
                                                                     <span class="input-group-btn">
-                                                                        <button class="btn btn-success" type="button" onclick="setNamesiloKey()">修改</button>
+                                                                        <button class="btn btn-success" type="button" onclick="setServerChanKey()">修改</button>
                                                                     </span>
                                                                 </div>
-                                                                <span class="help-block"> 域名必须是<a href="https://www.namesilo.com/?rid=326ec20pa" target="_blank">www.namesilo.com</a>上购买的 </span>
+                                                                <span class="help-block"> 启用ServerChan,请务必填入本值(<a href="http://sc.ftqq.com" target="_blank">申请SCKEY</a>) </span>
                                                             </div>
                                                         </div>
                                                     </div>
@@ -611,7 +611,7 @@
                                                             <label for="is_traffic_ban" class="col-md-3 control-label">异常自动封号</label>
                                                             <div class="col-md-9">
                                                                 <input type="checkbox" class="make-switch" @if($is_traffic_ban) checked @endif id="is_traffic_ban" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
-                                                                <span class="help-block"> 24小时内流量超过异常阈值则自动封号(仅禁用SSR(R)) </span>
+                                                                <span class="help-block"> 1小时内流量超过异常阈值则自动封号(仅禁用SSR(R)) </span>
                                                             </div>
                                                         </div>
                                                         <div class="col-md-6">
@@ -624,7 +624,7 @@
                                                                         <button class="btn btn-success" type="button" onclick="setTrafficBanValue()">修改</button>
                                                                     </span>
                                                                 </div>
-                                                                <span class="help-block"> 24小时内超过该值,则触发自动封号 </span>
+                                                                <span class="help-block"> 1小时内超过该值,则触发自动封号 </span>
                                                             </div>
                                                         </div>
                                                     </div>
@@ -646,14 +646,14 @@
                                                             <label for="auto_release_port" class="col-md-3 control-label">端口自动释放</label>
                                                             <div class="col-md-9">
                                                                 <input type="checkbox" class="make-switch" @if($auto_release_port) checked @endif id="auto_release_port" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
-                                                                <span class="help-block"> 被禁的用户端口自动释放,重新启用用户则需要手动分配端口并手动重启一次SSR(R) </span>
+                                                                <span class="help-block"> 被禁的用户端口自动释放 </span>
                                                             </div>
                                                         </div>
                                                         <div class="col-md-6">
-                                                            <label for="is_ban_status" class="col-md-3 control-label">过期自动封</label>
+                                                            <label for="is_ban_status" class="col-md-3 control-label">过期自动封</label>
                                                             <div class="col-md-9">
-                                                                <input type="checkbox" class="make-switch" @if($is_ban_status) checked @endif id="is_ban_status" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
-                                                                <span class="help-block"> 被禁用SSR(R)的用户在账号到期时同时封禁账号(账号将无法登录)</span>
+                                                                <input type="checkbox" class="make-switch" @if($is_ban_status) checked @endif id="is_ban_status" data-on-color="danger" data-off-color="danger" data-on-text="仅封禁代理" data-off-text="封禁整个账号">
+                                                                <span class="help-block"> (慎重)封禁整个账号会重置账号的所有数据且会导致用户无法登录 </span>
                                                             </div>
                                                         </div>
                                                     </div>
@@ -1192,8 +1192,8 @@
         function setTrafficBanValue() {
             var traffic_ban_value = $("#traffic_ban_value").val();
 
-            if (traffic_ban_value < 0) {
-                layer.msg('不能小于0', {time:1000});
+            if (traffic_ban_value < 1) {
+                layer.msg('不能小于1', {time:1000});
                 return ;
             }