Просмотр исходного кода

1.下载二维码
2.每日节点使用情况报告

admin 7 лет назад
Родитель
Сommit
5929f1ed17

+ 66 - 0
app/Console/Commands/AutoReportNode.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use App\Components\ServerChan;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeTrafficDaily;
+use Illuminate\Console\Command;
+use Log;
+
+class AutoReportNode extends Command
+{
+    protected $signature = 'autoReportNode';
+    protected $description = '自动报告节点使用情况';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        if (self::$systemConfig['node_daily_report']) {
+            $nodeList = SsNode::query()->where('status', 1)->get();
+            if (!empty($nodeList)) {
+                foreach ($nodeList as $node) {
+                    $log = SsNodeTrafficDaily::query()
+                        ->where('node_id', $node->id)
+                        ->where('created_at', '>=', date('Y-m-d 00:00:00', strtotime("-1 day")))
+                        ->where('created_at', '<=', date('Y-m-d 23:59:59', strtotime("-1 day")))
+                        ->first();
+
+                    if ($log) {
+                        $this->notifyMasterByServerchan('节点使用情况日报', '节点**' . $node->name . ',上行流量:' . flowAutoShow($node->u) . ',下行流量:' . flowAutoShow($node->d) . ',共计:' . $node->traffic . '**');
+                    }
+                }
+            }
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    /**
+     * 通过ServerChan发微信消息提醒管理员
+     *
+     * @param string $title   消息标题
+     * @param string $content 消息内容
+     *
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    private function notifyMasterByServerchan($title, $content)
+    {
+        if (self::$systemConfig['is_server_chan'] && self::$systemConfig['server_chan_key']) {
+            $serverChan = new ServerChan();
+            $serverChan->send($title, $content);
+        }
+    }
+}

+ 3 - 3
app/Console/Commands/upgradeUserVmess.php → app/Console/Commands/upgradeUserVmessId.php

@@ -5,10 +5,10 @@ namespace App\Console\Commands;
 use App\Http\Models\User;
 use Illuminate\Console\Command;
 
-class upgradeUserVmess extends Command
+class upgradeUserVmessId extends Command
 {
-    protected $signature = 'upgradeUserVmess';
-    protected $description = '更新用户的Vmess';
+    protected $signature = 'upgradeUserVmessId';
+    protected $description = '重新生成用户的vmess_id字段';
 
     public function __construct()
     {

+ 3 - 1
app/Console/Kernel.php

@@ -26,7 +26,8 @@ class Kernel extends ConsoleKernel
         \App\Console\Commands\UserExpireAutoWarning::class,
         \App\Console\Commands\UserTrafficAutoWarning::class,
         \App\Console\Commands\upgradeUserPassword::class,
-        \App\Console\Commands\upgradeUserVmess::class,
+        \App\Console\Commands\upgradeUserVmessId::class,
+        \App\Console\Commands\AutoReportNode::class,
     ];
 
     /**
@@ -50,6 +51,7 @@ class Kernel extends ConsoleKernel
         $schedule->command('userTrafficAbnormalAutoWarning')->hourly();
         $schedule->command('userExpireAutoWarning')->dailyAt('20:00');
         $schedule->command('userTrafficAutoWarning')->dailyAt('10:30');
+        $schedule->command('autoReportNode')->dailyAt('09:00');
     }
 
     /**

+ 74 - 39
app/Http/Controllers/AdminController.php

@@ -1328,46 +1328,81 @@ class AdminController extends Controller
             // 获取分组名称
             $group = SsGroup::query()->where('id', $node->group_id)->first();
 
-            // 生成ssr scheme
-            $obfs_param = $user->obfs_param ? $user->obfs_param : $node->obfs_param;
-            $protocol_param = $node->single ? $user->port . ':' . $user->passwd : $user->protocol_param;
-
-            $ssr_str = ($node->server ? $node->server : $node->ip) . ':' . ($node->single ? $node->single_port : $user->port);
-            $ssr_str .= ':' . ($node->single ? $node->single_protocol : $user->protocol) . ':' . ($node->single ? $node->single_method : $user->method);
-            $ssr_str .= ':' . ($node->single ? $node->single_obfs : $user->obfs) . ':' . ($node->single ? base64url_encode($node->single_passwd) : base64url_encode($user->passwd));
-            $ssr_str .= '/?obfsparam=' . base64url_encode($obfs_param);
-            $ssr_str .= '&protoparam=' . ($node->single ? base64url_encode($user->port . ':' . $user->passwd) : base64url_encode($protocol_param));
-            $ssr_str .= '&remarks=' . base64url_encode($node->name);
-            $ssr_str .= '&group=' . base64url_encode(empty($group) ? '' : $group->name);
-            $ssr_str .= '&udpport=0';
-            $ssr_str .= '&uot=0';
-            $ssr_str = base64url_encode($ssr_str);
-            $ssr_scheme = 'ssr://' . $ssr_str;
-
-            // 生成ss scheme
-            $ss_str = $user->method . ':' . $user->passwd . '@';
-            $ss_str .= ($node->server ? $node->server : $node->ip) . ':' . $user->port;
-            $ss_str = base64url_encode($ss_str) . '#' . 'VPN';
-            $ss_scheme = 'ss://' . $ss_str;
-
-            // 生成配置信息
-            $txt = "服务器:" . ($node->server ? $node->server : $node->ip) . "\r\n";
-            if ($node->ipv6) {
-                $txt .= "IPv6:" . $node->ipv6 . "\r\n";
+            if ($node->type == 1) {
+                // 生成ssr scheme
+                $obfs_param = $user->obfs_param ? $user->obfs_param : $node->obfs_param;
+                $protocol_param = $node->single ? $user->port . ':' . $user->passwd : $user->protocol_param;
+
+                $ssr_str = ($node->server ? $node->server : $node->ip) . ':' . ($node->single ? $node->single_port : $user->port);
+                $ssr_str .= ':' . ($node->single ? $node->single_protocol : $user->protocol) . ':' . ($node->single ? $node->single_method : $user->method);
+                $ssr_str .= ':' . ($node->single ? $node->single_obfs : $user->obfs) . ':' . ($node->single ? base64url_encode($node->single_passwd) : base64url_encode($user->passwd));
+                $ssr_str .= '/?obfsparam=' . base64url_encode($obfs_param);
+                $ssr_str .= '&protoparam=' . ($node->single ? base64url_encode($user->port . ':' . $user->passwd) : base64url_encode($protocol_param));
+                $ssr_str .= '&remarks=' . base64url_encode($node->name);
+                $ssr_str .= '&group=' . base64url_encode(empty($group) ? '' : $group->name);
+                $ssr_str .= '&udpport=0';
+                $ssr_str .= '&uot=0';
+                $ssr_str = base64url_encode($ssr_str);
+                $ssr_scheme = 'ssr://' . $ssr_str;
+
+                // 生成ss scheme
+                $ss_str = $user->method . ':' . $user->passwd . '@';
+                $ss_str .= ($node->server ? $node->server : $node->ip) . ':' . $user->port;
+                $ss_str = base64url_encode($ss_str) . '#' . 'VPN';
+                $ss_scheme = 'ss://' . $ss_str;
+
+                // 生成配置信息
+                $txt = "服务器:" . ($node->server ? $node->server : $node->ip) . "\r\n";
+                if ($node->ipv6) {
+                    $txt .= "IPv6:" . $node->ipv6 . "\r\n";
+                }
+                $txt .= "远程端口:" . ($node->single ? $node->single_port : $user->port) . "\r\n";
+                $txt .= "密码:" . ($node->single ? $node->single_passwd : $user->passwd) . "\r\n";
+                $txt .= "加密方法:" . ($node->single ? $node->single_method : $user->method) . "\r\n";
+                $txt .= "路由:绕过局域网及中国大陆地址\r\n\r\n";
+                $txt .= "协议:" . ($node->single ? $node->single_protocol : $user->protocol) . "\r\n";
+                $txt .= "协议参数:" . ($node->single ? $user->port . ':' . $user->passwd : $user->protocol_param) . "\r\n";
+                $txt .= "混淆方式:" . ($node->single ? $node->single_obfs : $user->obfs) . "\r\n";
+                $txt .= "混淆参数:" . ($user->obfs_param ? $user->obfs_param : $node->obfs_param) . "\r\n";
+                $txt .= "本地端口:1080\r\n";
+
+                $node->txt = $txt;
+                $node->ssr_scheme = $ssr_scheme;
+                $node->ss_scheme = $node->compatible ? $ss_scheme : ''; // 节点兼容原版才显示
+            } else {
+                // 生成v2ray scheme
+                $v2_json = [
+                    "v"    => "2",
+                    "ps"   => $node->name,
+                    "add"  => $node->server ? $node->server : $node->ip,
+                    "port" => $node->v2_port,
+                    "id"   => $user->vmess_id,
+                    "aid"  => $node->v2_alter_id,
+                    "net"  => $node->v2_net,
+                    "type" => $node->v2_type,
+                    "host" => $node->v2_host,
+                    "path" => $node->v2_path,
+                    "tls"  => $node->v2_tls == 1 ? "tls" : ""
+                ];
+                $v2_scheme = 'vmess://' . base64url_encode(json_encode($v2_json));
+
+                // 生成文本配置信息
+                $txt = "服务器:" . ($node->server ? $node->server : $node->ip) . "\r\n";
+                if ($node->ipv6) {
+                    $txt .= "IPv6:" . $node->ipv6 . "\r\n";
+                }
+                $txt .= "端口:" . $node->v2_port . "\r\n";
+                $txt .= "用户ID:" . $user->vmess_id . "\r\n";
+                $txt .= "额外ID:" . $node->v2_alter_id . "\r\n";
+                $txt .= "传输协议:" . $node->v2_net . "\r\n";
+                $txt .= "伪装类型:" . $node->v2_type . "\r\n";
+                $txt .= $node->v2_host ? "伪装域名:" . $node->v2_host . "\r\n" : "";
+                $txt .= $node->v2_path ? "路径:" . $node->v2_path . "\r\n" : "";
+                $txt .= $node->v2_tls == 1 ? "TLS:tls\r\n" : "";
+
+                $node->txt = $txt;
+                $node->v2_scheme = $v2_scheme;
             }
-            $txt .= "远程端口:" . ($node->single ? $node->single_port : $user->port) . "\r\n";
-            $txt .= "密码:" . ($node->single ? $node->single_passwd : $user->passwd) . "\r\n";
-            $txt .= "加密方法:" . ($node->single ? $node->single_method : $user->method) . "\r\n";
-            $txt .= "路由:绕过局域网及中国大陆地址\r\n\r\n";
-            $txt .= "协议:" . ($node->single ? $node->single_protocol : $user->protocol) . "\r\n";
-            $txt .= "协议参数:" . ($node->single ? $user->port . ':' . $user->passwd : $user->protocol_param) . "\r\n";
-            $txt .= "混淆方式:" . ($node->single ? $node->single_obfs : $user->obfs) . "\r\n";
-            $txt .= "混淆参数:" . ($user->obfs_param ? $user->obfs_param : $node->obfs_param) . "\r\n";
-            $txt .= "本地端口:1080\r\n";
-
-            $node->txt = $txt;
-            $node->ssr_scheme = $ssr_scheme;
-            $node->ss_scheme = $node->compatible ? $ss_scheme : ''; // 节点兼容原版才显示
         }
 
         $view['nodeList'] = $nodeList;

+ 38 - 16
resources/views/admin/export.blade.php

@@ -91,12 +91,17 @@
                                             <h4 class="modal-title">Scheme Links - {{$node->name}}</h4>
                                         </div>
                                         <div class="modal-body">
-                                            <textarea class="form-control" rows="5" readonly="readonly">{{$node->ssr_scheme}}</textarea>
-                                            <a href="{{$node->ssr_scheme}}" class="btn purple uppercase" style="display: block; width: 100%;margin-top: 10px;">打开SSR</a>
-                                            @if($node->ss_scheme)
-                                                <p></p>
-                                                <textarea class="form-control" rows="3" readonly="readonly">{{$node->ss_scheme}}</textarea>
-                                                <a href="{{$node->ss_scheme}}" class="btn blue uppercase" style="display: block; width: 100%;margin-top: 10px;">打开SS</a>
+                                            @if($node->type ==1)
+                                                <textarea class="form-control" rows="5" readonly="readonly">{{$node->ssr_scheme}}</textarea>
+                                                <a href="{{$node->ssr_scheme}}" class="btn purple uppercase" style="display: block; width: 100%;margin-top: 10px;">打开SSR</a>
+                                                @if($node->ss_scheme)
+                                                    <p></p>
+                                                    <textarea class="form-control" rows="3" readonly="readonly">{{$node->ss_scheme}}</textarea>
+                                                    <a href="{{$node->ss_scheme}}" class="btn blue uppercase" style="display: block; width: 100%;margin-top: 10px;">打开SS</a>
+                                                @endif
+                                            @else
+                                                <textarea class="form-control" rows="5" readonly="readonly">{{$node->v2_scheme}}</textarea>
+                                                <a href="{{$node->v2_scheme}}" class="btn purple uppercase" style="display: block; width: 100%;margin-top: 10px;">打开V2Ray</a>
                                             @endif
                                         </div>
                                     </div>
@@ -111,16 +116,26 @@
                                         </div>
                                         <div class="modal-body">
                                             <div class="row">
-                                                @if ($node->compatible)
-                                                    <div class="col-md-6">
-                                                        <div id="qrcode_ssr_img_{{$node->id}}" style="text-align: center;"></div>
-                                                    </div>
-                                                    <div class="col-md-6">
-                                                        <div id="qrcode_ss_img_{{$node->id}}" style="text-align: center;"></div>
-                                                    </div>
+                                                @if($node->type == 1)
+                                                    @if($node->compatible)
+                                                        <div class="col-md-6">
+                                                            <div id="qrcode_ssr_img_{{$node->id}}" style="text-align: center;"></div>
+                                                            <div style="text-align: center;"><a id="download_qrcode_ssr_img_{{$node->id}}">下载二维码</a></div>
+                                                        </div>
+                                                        <div class="col-md-6">
+                                                            <div id="qrcode_ss_img_{{$node->id}}" style="text-align: center;"></div>
+                                                            <div style="text-align: center;"><a id="download_qrcode_ss_img_{{$node->id}}">下载二维码</a></div>
+                                                        </div>
+                                                    @else
+                                                        <div class="col-md-12">
+                                                            <div id="qrcode_ssr_img_{{$node->id}}" style="text-align: center;"></div>
+                                                            <div style="text-align: center;"><a id="download_qrcode_ssr_img_{{$node->id}}">下载二维码</a></div>
+                                                        </div>
+                                                    @endif
                                                 @else
                                                     <div class="col-md-12">
-                                                        <div id="qrcode_ssr_img_{{$node->id}}" style="text-align: center;"></div>
+                                                        <div id="qrcode_v2_img_{{$node->id}}" style="text-align: center;"></div>
+                                                        <div style="text-align: center;"><a id="download_qrcode_v2_img_{{$node->id}}">下载二维码</a></div>
                                                     </div>
                                                 @endif
                                             </div>
@@ -165,8 +180,15 @@
 
         // 循环输出节点scheme用于生成二维码
         @foreach ($nodeList as $node)
-            $('#qrcode_ssr_img_{{$node->id}}').qrcode("{{$node->ssr_scheme}}");
-            $('#qrcode_ss_img_{{$node->id}}').qrcode("{{$node->ss_scheme}}");
+            @if($node->type == 1)
+                $('#qrcode_ssr_img_{{$node->id}}').qrcode("{{$node->ssr_scheme}}");
+                $('#download_qrcode_ssr_img_{{$node->id}}').attr({'download':'code','href':$('#qrcode_ssr_img_{{$node->id}} canvas')[0].toDataURL("image/png")})
+                $('#qrcode_ss_img_{{$node->id}}').qrcode("{{$node->ss_scheme}}");
+                $('#download_qrcode_ss_img_{{$node->id}}').attr({'download':'code','href':$('#qrcode_ss_img_{{$node->id}} canvas')[0].toDataURL("image/png")})
+            @else
+                $('#qrcode_v2_img_{{$node->id}}').qrcode("{{$node->v2_scheme}}");
+                $('#download_qrcode_v2_img_{{$node->id}}').attr({'download':'code','href':$('#qrcode_v2_img_{{$node->id}} canvas')[0].toDataURL("image/png")})
+            @endif
         @endforeach
     </script>
 @endsection

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

@@ -185,6 +185,27 @@
                                                             </div>
                                                         </div>
                                                     </div>
+                                                    <div class="form-group">
+                                                        <div class="col-md-6">
+                                                            <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_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?rid=326ec20pa" target="_blank">创建API KEY</a>) </span>
+                                                            </div>
+                                                        </div>
+                                                        <div class="col-md-6">
+                                                            <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="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="setNamesiloKey()">修改</button>
+                                                                    </span>
+                                                                </div>
+                                                                <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">
                                                         <label for="is_user_rand_port" class="col-md-2 control-label">自定义端口</label>
@@ -541,33 +562,12 @@
                                                             </div>
                                                         </div>
                                                     </div>
-                                                    <div class="form-group">
-                                                        <div class="col-md-6">
-                                                            <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_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?rid=326ec20pa" target="_blank">创建API KEY</a>) </span>
-                                                            </div>
-                                                        </div>
-                                                        <div class="col-md-6">
-                                                            <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="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="setNamesiloKey()">修改</button>
-                                                                    </span>
-                                                                </div>
-                                                                <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_server_chan" class="col-md-3 control-label">ServerChan</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>
+                                                                <span class="help-block"> 推送节点宕机提醒、用户流量异常警告、节点使用报告(<a href="http://sc.ftqq.com" target="_blank">绑定微信</a>) </span>
                                                             </div>
                                                         </div>
                                                         <div class="col-md-6">
@@ -705,6 +705,8 @@
                                                                 <span class="help-block"> 被封禁和过期一个月的用户端口自动释放 </span>
                                                             </div>
                                                         </div>
+                                                    </div>
+                                                    <div class="form-group">
                                                         <div class="col-md-6">
                                                             <label for="is_ban_status" class="col-md-3 control-label">过期自动封禁</label>
                                                             <div class="col-md-9">
@@ -712,6 +714,13 @@
                                                                 <span class="help-block"> (慎重)封禁整个账号会重置账号的所有数据且会导致用户无法登录 </span>
                                                             </div>
                                                         </div>
+                                                        <div class="col-md-6">
+                                                            <label for="node_daily_report" class="col-md-3 control-label">节点使用报告</label>
+                                                            <div class="col-md-9">
+                                                            <input type="checkbox" class="make-switch" @if($node_daily_report) checked @endif id="node_daily_report" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
+                                                            <span class="help-block"> 每天早上9点推送昨天节点的使用情况 </span>
+                                                        </div>
+                                                        </div>
                                                     </div>
 
                                                 </div>
@@ -1271,6 +1280,21 @@
             }
         });
 
+        // 启用、禁用节点使用报告
+        $('#node_daily_report').on({
+            'switchChange.bootstrapSwitch': function(event, state) {
+                var node_daily_report = state ? 1 : 0;
+
+                $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'node_daily_report', value:node_daily_report}, function (ret) {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
+                });
+            }
+        });
+
         // 过期封禁是否禁止账号
         $('#is_ban_status').on({
             'switchChange.bootstrapSwitch': function(event, state) {

+ 9 - 2
resources/views/user/index.blade.php

@@ -421,22 +421,26 @@
                         </div>
                         <div class="modal-body">
                             <div class="row">
-                                @if ($node->type == 1)
-                                    @if ($node->compatible)
+                                @if($node->type == 1)
+                                    @if($node->compatible)
                                         <div class="col-md-6">
                                             <div id="qrcode_ssr_img_{{$node->id}}" style="text-align: center;"></div>
+                                            <div style="text-align: center;"><a id="download_qrcode_ssr_img_{{$node->id}}">下载二维码</a></div>
                                         </div>
                                         <div class="col-md-6">
                                             <div id="qrcode_ss_img_{{$node->id}}" style="text-align: center;"></div>
+                                            <div style="text-align: center;"><a id="download_qrcode_ss_img_{{$node->id}}">下载二维码</a></div>
                                         </div>
                                     @else
                                         <div class="col-md-12">
                                             <div id="qrcode_ssr_img_{{$node->id}}" style="text-align: center;"></div>
+                                            <div style="text-align: center;"><a id="download_qrcode_ssr_img_{{$node->id}}">下载二维码</a></div>
                                         </div>
                                     @endif
                                 @else
                                     <div class="col-md-12">
                                         <div id="qrcode_v2_img_{{$node->id}}" style="text-align: center;"></div>
+                                        <div style="text-align: center;"><a id="download_qrcode_v2_img_{{$node->id}}">下载二维码</a></div>
                                     </div>
                                 @endif
                             </div>
@@ -558,11 +562,14 @@
         @foreach ($nodeList as $node)
             @if($node->type == 1)
                 $('#qrcode_ssr_img_{{$node->id}}').qrcode("{{$node->ssr_scheme}}");
+                $('#download_qrcode_ssr_img_{{$node->id}}').attr({'download':'code','href':$('#qrcode_ssr_img_{{$node->id}} canvas')[0].toDataURL("image/png")})
                 @if($node->ss_scheme)
                     $('#qrcode_ss_img_{{$node->id}}').qrcode("{{$node->ss_scheme}}");
+                    $('#download_qrcode_ss_img_{{$node->id}}').attr({'download':'code','href':$('#qrcode_ss_img_{{$node->id}} canvas')[0].toDataURL("image/png")})
                 @endif
             @else
                 $('#qrcode_v2_img_{{$node->id}}').qrcode("{{$node->v2_scheme}}");
+                $('#download_qrcode_v2_img_{{$node->id}}').attr({'download':'code','href':$('#qrcode_v2_img_{{$node->id}} canvas')[0].toDataURL("image/png")})
             @endif
         @endforeach
 

+ 1 - 0
sql/db.sql

@@ -358,6 +358,7 @@ INSERT INTO `config` VALUES ('68', 'tcp_check_warning_times', 3);
 INSERT INTO `config` VALUES ('69', 'is_forbid_china', 0);
 INSERT INTO `config` VALUES ('70', 'is_forbid_oversea', 0);
 INSERT INTO `config` VALUES ('71', 'is_verify_register', 0);
+INSERT INTO `config` VALUES ('72', 'node_daily_report', 0);
 
 
 -- ----------------------------

+ 2 - 0
sql/update/20181130.sql

@@ -0,0 +1,2 @@
+-- 节点每日报告
+INSERT INTO `config` values ('72', 'node_daily_report', 0);