Răsfoiți Sursa

Modify 节点数据结构改版

节点结构修改;
更多小改动;
兔姬桑 3 ani în urmă
părinte
comite
92a376f942

+ 2 - 2
app/Components/DDNS.php

@@ -58,7 +58,7 @@ class DDNS
         if (self::dnsProvider($domain)->update($ip, $type)) {
             Log::info("【DDNS】更新:{$ip} => {$domain} 类型:{$type} 成功");
         } else {
-            Log::info("【DDNS】更新:{$ip} => {$domain} 类型:{$type} 失败,请手动设置!");
+            Log::warning("【DDNS】更新:{$ip} => {$domain} 类型:{$type} 失败,请手动设置!");
         }
     }
 
@@ -74,7 +74,7 @@ class DDNS
         if (self::dnsProvider($domain)->store($ip, $type)) {
             Log::info("【DDNS】添加:{$ip} => {$domain} 类型:{$type} 成功");
         } else {
-            Log::info("【DDNS】添加:{$ip} => {$domain} 类型:{$type} 失败,请手动设置!");
+            Log::warning("【DDNS】添加:{$ip} => {$domain} 类型:{$type} 失败,请手动设置!");
         }
     }
 }

+ 1 - 1
app/Components/IP.php

@@ -24,7 +24,7 @@ class IP
         } else {
             $ipInfo = self::ip2Region($ip);
             if (! $ipInfo) {
-                Log::info('无法识别,尝试使用【IPIP库】库解析:'.$ip);
+                Log::warning('无法识别,尝试使用【IPIP库】库解析:'.$ip);
                 $ipInfo = self::ip2Location($ip);
             }
         }

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

@@ -79,13 +79,13 @@ class NodeStatusDetection extends Command
             // 使用DDNS的node先通过gethostbyname获取ipv4地址
             foreach ($node->ips() as $ip) {
                 if ($node->detection_type !== 1) {
-                    $icmpCheck = (new NetworkDetection)->networkCheck($ip, true, $node->single ? $node->port : 22);
+                    $icmpCheck = (new NetworkDetection)->networkCheck($ip, true, $node->port ?? 22);
                     if ($icmpCheck !== false && $icmpCheck !== 1) {
                         $data[$node_id][$ip]['icmp'] = config('common.network_status')[$icmpCheck];
                     }
                 }
                 if ($node->detection_type !== 2) {
-                    $tcpCheck = (new NetworkDetection)->networkCheck($ip, false, $node->single ? $node->port : 22);
+                    $tcpCheck = (new NetworkDetection)->networkCheck($ip, false, $node->port ?? 22);
                     if ($tcpCheck !== false && $tcpCheck !== 1) {
                         $data[$node_id][$ip]['tcp'] = config('common.network_status')[$tcpCheck];
                     }
@@ -123,7 +123,7 @@ class NodeStatusDetection extends Command
         if (isset($data)) { //只有在出现阻断线路时,才会发出警报
             Notification::send(User::find(1), new NodeBlocked($data));
 
-            Log::info("节点状态日志: \r\n".var_export($data, true));
+            Log::notice("节点状态日志: \r\n".var_export($data, true));
         }
 
         Cache::put('LastCheckTime', time() + random_int(3000, Hour), 3700); // 随机生成下次检测时间

+ 83 - 23
app/Http/Controllers/Admin/NodeController.php

@@ -12,7 +12,6 @@ use App\Models\Level;
 use App\Models\Node;
 use App\Models\NodeCertificate;
 use App\Models\RuleGroup;
-use Arr;
 use Exception;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
@@ -38,33 +37,19 @@ class NodeController extends Controller
             $node->online_users = $online_log->online_user ?? 0;
             $node->transfer = flowAutoShow($node->dailyDataFlows()->sum('total')); // 已产生流量
             $node_info = $node->heartbeats()->recently()->first(); // 近期负载
-            $node->isOnline = empty($node_info) || empty($node_info->load) ? 0 : 1;
-            $node->load = $node->isOnline ? $node_info->load : '离线';
+            $node->isOnline = ! empty($node_info) && ! empty($node_info->load);
+            $node->load = $node_info->load ?? false;
             $node->uptime = empty($node_info) ? 0 : seconds2time($node_info->uptime);
         }
 
         return view('admin.node.index', ['nodeList' => $nodeList]);
     }
 
-    // 添加节点页面
-    public function create()
-    {
-        return view('admin.node.info', [
-            'countries'  => Country::orderBy('code')->get(),
-            'levels'     => Level::orderBy('level')->get(),
-            'ruleGroups' => RuleGroup::orderBy('id')->get(),
-            'labels'     => Label::orderByDesc('sort')->orderBy('id')->get(),
-            'certs'      => NodeCertificate::orderBy('id')->get(),
-        ]);
-    }
-
     // 添加节点
     public function store(NodeRequest $request): JsonResponse
     {
-        $array = $request->validated();
-        Arr::forget($array, ['labels']);
         try {
-            if ($node = Node::create($array)) {
+            if ($node = Node::create($this->nodeStore($request->validated()))) {
                 // 生成节点标签
                 if ($request->has('labels')) {
                     $node->labels()->attach($request->input('labels'));
@@ -81,11 +66,88 @@ class NodeController extends Controller
         return Response::json(['status' => 'fail', 'message' => '添加线路失败']);
     }
 
+    public function create()
+    {
+        return view('admin.node.info', [
+            'nodes'      => Node::orderBy('id')->pluck('id', 'name'),
+            'countries'  => Country::orderBy('code')->get(),
+            'levels'     => Level::orderBy('level')->get(),
+            'ruleGroups' => RuleGroup::orderBy('id')->get(),
+            'labels'     => Label::orderByDesc('sort')->orderBy('id')->get(),
+            'certs'      => NodeCertificate::orderBy('id')->get(),
+        ]);
+    }
+
+    // 添加节点信息
+    private function nodeStore(array $info): array
+    {
+        switch ($info['type']) {
+            case 0:
+                $profile = [
+                    'method' => $info['method'],
+                ];
+                break;
+            case 2:
+                $profile = [
+                    'method'      => $info['v2_method'],
+                    'v2_alter_id' => $info['v2_alter_id'],
+                    'v2_net'      => $info['v2_net'],
+                    'v2_type'     => $info['v2_type'],
+                    'v2_host'     => $info['v2_host'],
+                    'v2_path'     => $info['v2_path'],
+                    'v2_tls'      => $info['v2_tls'] ? 'tls' : '',
+                    'v2_sni'      => $info['v2_sni'],
+                ];
+                break;
+            case 3:
+                $profile = [
+                    'allow_insecure' => false,
+                ];
+                break;
+            case 1:
+            case 4:
+                $profile = [
+                    'method'         => $info['method'],
+                    'protocol'       => $info['protocol'],
+                    'obfs'           => $info['obfs'],
+                    'obfs_param'     => $info['obfs_param'],
+                    'protocol_param' => $info['protocol_param'],
+                    'passwd'         => $info['passwd'],
+                ];
+                break;
+        }
+
+        return [
+            'type'           => $info['type'],
+            'name'           => $info['name'],
+            'country_code'   => $info['country_code'],
+            'server'         => $info['server'],
+            'ip'             => $info['ip'],
+            'ipv6'           => $info['ipv6'],
+            'level'          => $info['level'],
+            'rule_group_id'  => $info['rule_group_id'],
+            'speed_limit'    => $info['speed_limit'],
+            'client_limit'   => $info['client_limit'],
+            'description'    => $info['description'],
+            'profile'        => $profile ?? [],
+            'traffic_rate'   => $info['traffic_rate'],
+            'is_udp'         => $info['is_udp'],
+            'is_subscribe'   => $info['is_subscribe'],
+            'is_ddns'        => $info['is_ddns'],
+            'relay_node_id'  => $info['relay_node_id'],
+            'push_port'      => $info['push_port'],
+            'detection_type' => $info['detection_type'],
+            'sort'           => $info['sort'],
+            'status'         => $info['status'],
+        ];
+    }
+
     // 编辑节点页面
     public function edit(Node $node)
     {
         return view('admin.node.info', [
             'node'       => $node,
+            'nodes'      => Node::whereNotIn('id', [$node->id])->orderBy('id')->pluck('id', 'name'),
             'countries'  => Country::orderBy('code')->get(),
             'levels'     => Level::orderBy('level')->get(),
             'ruleGroups' => RuleGroup::orderBy('id')->get(),
@@ -98,9 +160,7 @@ class NodeController extends Controller
     public function update(NodeRequest $request, Node $node): JsonResponse
     {
         try {
-            $array = $request->validated();
-            Arr::forget($array, ['labels']);
-            if ($node->update($array)) {
+            if ($node->update($this->nodeStore($request->validated()))) {
                 // 更新节点标签
                 $node->labels()->sync($request->input('labels'));
 
@@ -135,8 +195,8 @@ class NodeController extends Controller
     public function checkNode(Node $node): JsonResponse
     {
         foreach ($node->ips() as $ip) {
-            $icmp = (new NetworkDetection)->networkCheck($ip, true, $node->single ? $node->port : 22); // ICMP
-            $tcp = (new NetworkDetection)->networkCheck($ip, false, $node->single ? $node->port : 22); // TCP
+            $icmp = (new NetworkDetection)->networkCheck($ip, true, $node->port ?? 22); // ICMP
+            $tcp = (new NetworkDetection)->networkCheck($ip, false, $node->port ?? 22); // TCP
             if ($icmp) {
                 $data[$ip][0] = config('common.network_status')[$icmp];
             } else {

+ 1 - 1
app/Http/Controllers/Admin/UserController.php

@@ -301,7 +301,7 @@ class UserController extends Controller
 
     public function exportProxyConfig(Request $request, User $user): JsonResponse
     {
-        $server = Node::findOrFail($request->input('id'))->config($user); // 提取节点信息
+        $server = Node::findOrFail($request->input('id'))->getConfig($user); // 提取节点信息
 
         return Response::json(['status' => 'success', 'data' => $this->getUserNodeInfo($server, $request->input('type') !== 'text'), 'title' => $server['type']]);
     }

+ 15 - 14
app/Http/Controllers/Api/WebApi/BaseController.php → app/Http/Controllers/Api/WebApi/CoreController.php

@@ -6,10 +6,11 @@ use App\Models\Node;
 use App\Models\User;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
+use Illuminate\Routing\Controller;
 use Response;
 use Validator;
 
-class BaseController
+class CoreController extends Controller
 {
     // 上报节点心跳信息
     public function setNodeStatus(Request $request, Node $node): JsonResponse
@@ -27,14 +28,14 @@ class BaseController
             'load'     => implode(' ', [$data['cpu'] / 100, $data['mem'] / 100, $data['disk'] / 100]),
             'log_time' => time(),
         ])) {
-            return $this->returnData('上报节点心跳信息成功', 'success', 200);
+            return $this->returnData('上报节点心跳信息成功', 200, 'success');
         }
 
-        return $this->returnData('生成节点心跳信息失败');
+        return $this->returnData('生成节点心跳信息失败', 400);
     }
 
     // 返回数据
-    public function returnData(string $message, string $status = 'fail', int $code = 400, array $data = [], array $addition = null): JsonResponse
+    public function returnData(string $message, int $code = 422, string $status = 'fail', array $data = [], array $addition = null): JsonResponse
     {
         $etag = self::abortIfNotModified($data);
         $data = compact('status', 'code', 'data', 'message');
@@ -79,14 +80,14 @@ class BaseController
         }
 
         if (isset($formattedData) && ! $node->onlineIps()->createMany($formattedData)) {  // 生成节点在线IP数据
-            return $this->returnData('生成节点在线用户IP信息失败');
+            return $this->returnData('生成节点在线用户IP信息失败', 400);
         }
 
         if ($node->onlineLogs()->create(['online_user' => $onlineCount, 'log_time' => time()])) { // 生成节点在线人数数据
-            return $this->returnData('上报节点在线情况成功', 'success', 200);
+            return $this->returnData('上报节点在线情况成功', 200, 'success');
         }
 
-        return $this->returnData('生成节点在线情况失败');
+        return $this->returnData('生成节点在线情况失败', 400);
     }
 
     // 上报用户流量日志
@@ -112,10 +113,10 @@ class BaseController
                 $user->update(['u' => $user->u + $log->u, 'd' => $user->d + $log->d, 't' => time()]);
             }
 
-            return $this->returnData('上报用户流量日志成功', 'success', 200);
+            return $this->returnData('上报用户流量日志成功', 200, 'success');
         }
 
-        return $this->returnData('生成用户流量日志失败');
+        return $this->returnData('生成用户流量日志失败', 400);
     }
 
     // 获取节点的审计规则
@@ -131,11 +132,11 @@ class BaseController
                 ];
             }
 
-            return $this->returnData('获取节点审计规则成功', 'success', 200, ['mode' => $ruleGroup->type ? 'reject' : 'allow', 'rules' => $data ?? []]);
+            return $this->returnData('获取节点审计规则成功', 200, 'success', ['mode' => $ruleGroup->type ? 'reject' : 'allow', 'rules' => $data ?? []]);
         }
 
         // 放行
-        return $this->returnData('获取节点审计规则成功', 'success', 200, ['mode' => 'all', 'rules' => $data ?? []]);
+        return $this->returnData('获取节点审计规则成功', 200, 'success', ['mode' => 'all', 'rules' => $data ?? []]);
     }
 
     // 上报用户触发审计规则记录
@@ -144,13 +145,13 @@ class BaseController
         $validator = Validator::make($request->all(), ['uid' => 'required|numeric|exists:user,id', 'rule_id' => 'required|numeric|exists:rule,id', 'reason' => 'required']);
 
         if ($validator->fails()) {
-            return $this->returnData('上报用户触发审计规则日志失败,请检查字段');
+            return $this->returnData('上报日志失败,请检查字段');
         }
         $data = $validator->validated();
         if ($node->ruleLogs()->create(['user_id' => $data['uid'], 'rule_id' => $data['rule_id'], 'reason' => $data['reason']])) {
-            return $this->returnData('上报用户触发审计规则日志成功', 'success', 200);
+            return $this->returnData('上报日志成功', 200, 'success');
         }
 
-        return $this->returnData('上报用户触发审计规则日志失败');
+        return $this->returnData('上报用户触发审计规则日志失败', 400);
     }
 }

+ 5 - 5
app/Http/Controllers/Api/WebApi/SSController.php

@@ -5,24 +5,24 @@ namespace App\Http\Controllers\Api\WebApi;
 use App\Models\Node;
 use Illuminate\Http\JsonResponse;
 
-class SSController extends BaseController
+class SSController extends CoreController
 {
     // 获取节点信息
     public function getNodeInfo(Node $node): JsonResponse
     {
         $data = [
             'id'           => $node->id,
-            'method'       => $node->method,
+            'method'       => $node->profile['method'],
             'speed_limit'  => $node->getRawOriginal('speed_limit'),
             'client_limit' => $node->client_limit,
             'redirect_url' => sysConfig('redirect_url'),
         ];
 
-        if ($node->single) {
+        if ($node->profile['passwd']) {
             $data['port'] = $node->port;
         }
 
-        return $this->returnData('获取节点信息成功', 'success', 200, $data);
+        return $this->returnData('获取节点信息成功', 200, 'success', $data);
     }
 
     // 获取节点可用的用户列表
@@ -38,6 +38,6 @@ class SSController extends BaseController
             ];
         }
 
-        return $this->returnData('获取用户列表成功', 'success', 200, $data ?? [], ['updateTime' => time()]);
+        return $this->returnData('获取用户列表成功', 200, 'success', $data ?? [], ['updateTime' => time()]);
     }
 }

+ 10 - 10
app/Http/Controllers/Api/WebApi/SSRController.php

@@ -5,23 +5,23 @@ namespace App\Http\Controllers\Api\WebApi;
 use App\Models\Node;
 use Illuminate\Http\JsonResponse;
 
-class SSRController extends BaseController
+class SSRController extends CoreController
 {
     // 获取节点信息
     public function getNodeInfo(Node $node): JsonResponse
     {
-        return $this->returnData('获取节点信息成功', 'success', 200, [
+        return $this->returnData('获取节点信息成功', 200, 'success', [
             'id'           => $node->id,
-            'method'       => $node->method,
-            'protocol'     => $node->protocol,
-            'obfs'         => $node->obfs,
-            'obfs_param'   => $node->obfs_param ?? '',
+            'method'       => $node->profile['method'],
+            'protocol'     => $node->profile['protocol'],
+            'obfs'         => $node->profile['obfs'],
+            'obfs_param'   => $node->profile['obfs_param'] ?? '',
             'is_udp'       => $node->is_udp,
             'speed_limit'  => $node->getRawOriginal('speed_limit'),
             'client_limit' => $node->client_limit,
-            'single'       => $node->single,
+            'single'       => isset($node->profile['passwd']) ? 1 : 0,
             'port'         => (string) $node->port,
-            'passwd'       => $node->passwd ?? '',
+            'passwd'       => $node->profile['passwd'] ?? '',
             'push_port'    => $node->push_port,
             'secret'       => $node->auth->secret,
             'redirect_url' => sysConfig('redirect_url'),
@@ -39,12 +39,12 @@ class SSRController extends BaseController
                 'method'      => $user->method,
                 'protocol'    => $user->protocol,
                 'obfs'        => $user->obfs,
-                'obfs_param'  => $node->obfs_param,
+                'obfs_param'  => $node->profile['obfs_param'],
                 'speed_limit' => $user->getRawOriginal('speed_limit'),
                 'enable'      => $user->enable,
             ];
         }
 
-        return $this->returnData('获取用户列表成功', 'success', 200, $data ?? [], ['updateTime' => time()]);
+        return $this->returnData('获取用户列表成功', 200, 'success', $data ?? [], ['updateTime' => time()]);
     }
 }

+ 3 - 3
app/Http/Controllers/Api/WebApi/TrojanController.php

@@ -5,12 +5,12 @@ namespace App\Http\Controllers\Api\WebApi;
 use App\Models\Node;
 use Illuminate\Http\JsonResponse;
 
-class TrojanController extends BaseController
+class TrojanController extends CoreController
 {
     // 获取节点信息
     public function getNodeInfo(Node $node): JsonResponse
     {
-        return $this->returnData('获取节点信息成功', 'success', 200, [
+        return $this->returnData('获取节点信息成功', 200, 'success', [
             'id' => $node->id,
             'is_udp' => (bool) $node->is_udp,
             'speed_limit' => $node->getRawOriginal('speed_limit'),
@@ -34,6 +34,6 @@ class TrojanController extends BaseController
             ];
         }
 
-        return $this->returnData('获取用户列表成功', 'success', 200, $data ?? [], ['updateTime' => time()]);
+        return $this->returnData('获取用户列表成功', 200, 'success', $data ?? [], ['updateTime' => time()]);
     }
 }

+ 26 - 26
app/Http/Controllers/Api/WebApi/V2RayController.php

@@ -6,36 +6,36 @@ use App\Models\Node;
 use App\Models\NodeCertificate;
 use Illuminate\Http\JsonResponse;
 
-class V2RayController extends BaseController
+class V2RayController extends CoreController
 {
     // 获取节点信息
     public function getNodeInfo(Node $node): JsonResponse
     {
-        $cert = NodeCertificate::whereDomain($node->v2_host)->first();
-        $tlsProvider = $node->tls_provider ?: sysConfig('v2ray_tls_provider');
+        $cert = NodeCertificate::whereDomain($node->profile['v2_host'])->first();
+        $tlsProvider = $node->profile['tls_provider'] ?: sysConfig('v2ray_tls_provider');
         if (! $tlsProvider) {
             $tlsProvider = null;
         }
 
-        return $this->returnData('获取节点信息成功', 'success', 200, [
-            'id' => $node->id,
-            'is_udp' => (bool) $node->is_udp,
-            'speed_limit' => $node->getRawOriginal('speed_limit'),
-            'client_limit' => $node->client_limit,
-            'push_port' => $node->push_port,
-            'redirect_url' => (string) sysConfig('redirect_url'),
-            'secret' => $node->auth->secret,
-            'key' => $cert ? $cert->key : '',
-            'pem' => $cert ? $cert->pem : '',
-            'v2_license' => (string) sysConfig('v2ray_license'),
-            'v2_alter_id' => $node->v2_alter_id,
-            'v2_port' => $node->port,
-            'v2_method' => $node->v2_method,
-            'v2_net' => $node->v2_net,
-            'v2_type' => $node->v2_type,
-            'v2_host' => $node->v2_host,
-            'v2_path' => $node->v2_path,
-            'v2_tls' => (bool) $node->v2_tls,
+        return $this->returnData('获取节点信息成功', 200, 'success', [
+            'id'              => $node->id,
+            'is_udp'          => (bool) $node->is_udp,
+            'speed_limit'     => $node->getRawOriginal('speed_limit'),
+            'client_limit'    => $node->client_limit,
+            'push_port'       => $node->push_port,
+            'redirect_url'    => (string) sysConfig('redirect_url'),
+            'secret'          => $node->auth->secret,
+            'key'             => $cert ? $cert->key : '',
+            'pem'             => $cert ? $cert->pem : '',
+            'v2_license'      => (string) sysConfig('v2ray_license'),
+            'v2_alter_id'     => $node->profile['v2_alter_id'],
+            'v2_port'         => $node->port,
+            'v2_method'       => $node->profile['v2_method'],
+            'v2_net'          => $node->profile['v2_net'],
+            'v2_type'         => $node->profile['v2_type'],
+            'v2_host'         => $node->profile['v2_host'],
+            'v2_path'         => $node->profile['v2_path'],
+            'v2_tls'          => (bool) $node->profile['v2_tls'],
             'v2_tls_provider' => $tlsProvider,
         ]);
     }
@@ -45,13 +45,13 @@ class V2RayController extends BaseController
     {
         foreach ($node->users() as $user) {
             $data[] = [
-                'uid' => $user->id,
-                'vmess_uid' => $user->vmess_id,
+                'uid'         => $user->id,
+                'vmess_uid'   => $user->vmess_id,
                 'speed_limit' => $user->getRawOriginal('speed_limit'),
             ];
         }
 
-        return $this->returnData('获取用户列表成功', 'success', 200, $data ?? [], ['updateTime' => time()]);
+        return $this->returnData('获取用户列表成功', 200, 'success', $data ?? [], ['updateTime' => time()]);
     }
 
     // 上报节点伪装域名证书信息
@@ -60,7 +60,7 @@ class V2RayController extends BaseController
         if (request()->has(['key', 'pem'])) {
             $cert = NodeCertificate::whereDomain($node->v2_host)->firstOrCreate(['domain' => $node->server]);
             if ($cert && $cert->update(['key' => request('key'), 'pem' => request('pem')])) {
-                return $this->returnData('上报节点伪装域名证书成功', 'success', 200);
+                return $this->returnData('上报节点伪装域名证书成功', 200, 'success');
             }
         }
 

+ 4 - 6
app/Http/Controllers/Controller.php

@@ -49,16 +49,14 @@ class Controller extends BaseController
     {
         if ($is_node) {
             $currentFlow = UserDataFlowLog::whereNodeId($id);
-            $hourlyFlow = NodeHourlyDataFlow::whereNodeId($id);
-            $dailyFlow = NodeDailyDataFlow::whereNodeId($id);
+            $hourlyFlow = NodeHourlyDataFlow::whereNodeId($id)->whereDate('created_at', date('Y-m-d'))->selectRaw('(DATE_FORMAT(node_hourly_data_flow.created_at, "%k")) as date, total')->pluck('total', 'date');
+            $dailyFlow = NodeDailyDataFlow::whereNodeId($id)->whereMonth('created_at', date('n'))->selectRaw('(DATE_FORMAT(node_daily_data_flow.created_at, "%e")) as date, total')->pluck('total', 'date');
         } else {
             $currentFlow = UserDataFlowLog::whereUserId($id);
-            $hourlyFlow = UserHourlyDataFlow::userHourly($id);
-            $dailyFlow = UserDailyDataFlow::userDaily($id);
+            $hourlyFlow = UserHourlyDataFlow::userHourly($id)->whereDate('created_at', date('Y-m-d'))->selectRaw('(DATE_FORMAT(user_hourly_data_flow.created_at, "%k")) as date, total')->pluck('total', 'date');
+            $dailyFlow = UserDailyDataFlow::userDaily($id)->whereMonth('created_at', date('n'))->selectRaw('(DATE_FORMAT(user_daily_data_flow.created_at, "%e")) as date, total')->pluck('total', 'date');
         }
         $currentFlow = $currentFlow->where('log_time', '>=', strtotime(date('Y-m-d H:0')))->sum(DB::raw('u + d'));
-        $hourlyFlow = $hourlyFlow->whereDate('created_at', date('Y-m-d'))->selectRaw('(DATE_FORMAT(user_hourly_data_flow.created_at, "%k")) as date, total')->pluck('total', 'date');
-        $dailyFlow = $dailyFlow->whereMonth('created_at', date('n'))->selectRaw('(DATE_FORMAT(user_daily_data_flow.created_at, "%e")) as date, total')->pluck('total', 'date');
 
         // 节点一天内的流量
         $hourlyData = array_fill(0, date('G') + 1, 0);

+ 1 - 1
app/Http/Controllers/User/AffiliateController.php

@@ -50,7 +50,7 @@ class AffiliateController extends Controller
 
         // 判断是否已存在申请
         if (ReferralApply::uid()->whereIn('status', [0, 1])->first()) {
-            return Response::json(['status' => 'fail', 'title' => trans('user.referral.failed'), 'message' => trans('user.referral.msg.appliedd')]);
+            return Response::json(['status' => 'fail', 'title' => trans('user.referral.failed'), 'message' => trans('user.referral.msg.applied')]);
         }
 
         // 校验可以提现金额是否超过系统设置的阀值

+ 1 - 1
app/Http/Controllers/User/SubscribeController.php

@@ -84,7 +84,7 @@ class SubscribeController extends Controller
 
         $servers = [];
         foreach ($nodeList as $node) {
-            $servers[] = $node->config($user);
+            $servers[] = $node->getConfig($user);
         }
 
         // 打乱数组

+ 8 - 7
app/Http/Controllers/UserController.php

@@ -108,7 +108,7 @@ class UserController extends Controller
     {
         $user = auth()->user();
         if ($request->isMethod('POST')) {
-            $server = Node::findOrFail($request->input('id'))->config($user); // 提取节点信息
+            $server = Node::findOrFail($request->input('id'))->getConfig($user); // 提取节点信息
 
             return Response::json(['status' => 'success', 'data' => $this->getUserNodeInfo($server, $request->input('type') !== 'text'), 'title' => $server['type']]);
         }
@@ -202,8 +202,8 @@ class UserController extends Controller
         $dataPlusDays = $user->reset_time ?? $user->expired_at;
 
         return view('user.services', [
-            'chargeGoodsList' => Goods::type(3)->whereStatus(1)->orderBy('price')->limit(99)->get(),
-            'goodsList'       => Goods::whereStatus(1)->where('type', '<=', '2')->orderByDesc('type')->orderByDesc('sort')->paginate(99)->appends($request->except('page')),
+            'chargeGoodsList' => Goods::type(3)->whereStatus(1)->orderBy('price')->get(),
+            'goodsList'       => Goods::whereStatus(1)->where('type', '<=', '2')->orderByDesc('type')->orderByDesc('sort')->get(),
             'renewTraffic'    => $renewPrice->renew ?? 0,
             'dataPlusDays'    => $dataPlusDays > date('Y-m-d') ? Helpers::daysToNow($dataPlusDays) : 0,
         ]);
@@ -480,6 +480,7 @@ class UserController extends Controller
             'paying_user'             => auth()->user()->activePayingUser(), // 付费用户判断
             'Shadowrocket_install'    => 'itms-services://?action=download-manifest&url='.sysConfig('website_url').'/clients/Shadowrocket.plist', // 客户端安装
             'Quantumult_install'      => 'itms-services://?action=download-manifest&url='.sysConfig('website_url').'/clients/Quantumult.plist', // 客户端安装
+            'QuantumultX_install'     => 'itms-services://?action=download-manifest&url='.sysConfig('website_url').'/clients/QuantumultX.plist', // 客户端安装
             'subscribe_status'        => $subscribe->status, // 订阅连接
             'link'                    => $subscribe_link,
             'subscribe_link'          => 'sub://'.base64url_encode($subscribe_link),
@@ -487,10 +488,10 @@ class UserController extends Controller
             'Shadowrocket_linkQrcode' => 'sub://'.base64url_encode($subscribe_link).'#'.base64url_encode(sysConfig('website_name')),
             'Clash_link'              => "clash://install-config?url={$subscribe_link}",
             'Surge_link'              => "surge:///install-config?url={$subscribe_link}",
-            'Quantumultx'             => 'quantumult-x:///update-configuration?remote-resource='.json_encode([
-                'server_remote'  => "{$subscribe_link},  tag=".urlencode(sysConfig('website_name').' '.sysConfig('website_url')),
-                'filter_remote'  => '',
-                'rewrite_remote' => '',
+            'QuantumultX_link'             => 'quantumult-x:///update-configuration?remote-resource='.json_encode([
+                'server_remote'  => ["{$subscribe_link}, tag=".sysConfig('website_name')],
+                'filter_remote'  => [],
+                'rewrite_remote' => [],
             ]),
             'Quantumult_linkOut'      => 'quantumult://configuration?server='.base64url_encode($subscribe_link).'&filter='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/Pro.conf').'&rejection='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/Rejection.conf'),
             'Quantumult_linkIn'       => 'quantumult://configuration?server='.base64url_encode($subscribe_link).'&filter='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/BacktoCN.conf').'&rejection='.base64url_encode('https://raw.githubusercontent.com/ZBrettonYe/VPN-Rules-Collection/master/Profiles/Quantumult/Rejection.conf'),

+ 3 - 3
app/Http/Middleware/WebApi.php

@@ -22,7 +22,7 @@ class WebApi
         $time = $request->header('timestamp');
 
         if (! isset($key)) {// 未提供 key
-            return $this->returnData('Your key is null!');
+            return $this->returnData('Your key is null!', 400);
         }
 
         $nodeAuth = $node->auth ?? null;
@@ -38,8 +38,8 @@ class WebApi
     }
 
     // 返回数据
-    public function returnData(string $message): JsonResponse
+    private function returnData(string $message, int $code = 401): JsonResponse
     {
-        return Response::json(['status' => 'fail', 'code' => 404, 'message' => $message]);
+        return Response::json(['status' => 'fail', 'code' => $code, 'message' => $message]);
     }
 }

+ 5 - 8
app/Http/Requests/Admin/NodeRequest.php

@@ -12,9 +12,9 @@ class NodeRequest extends FormRequest
             'is_ddns' => 'required|boolean',
             'name' => 'required|string',
             'server' => 'required_if:is_ddns,1|nullable|ends_with:'.implode(',', config('domains')),
-            'ip' => 'required_if:is_ddns,0|nullable',
-            'ipv6' => 'nullable',
-            'push_port' => 'numeric|between:0,65535',
+            'ip' => 'required_if:is_ddns,0|nullable|ipv4',
+            'ipv6' => 'nullable|ipv6',
+            'push_port' => 'numeric|between:1,65535|different:port',
             'traffic_rate' => 'required|numeric|min:0',
             'level' => 'required|numeric|exists:level,level',
             'rule_group_id' => 'nullable|exists:rule_group,id',
@@ -32,11 +32,10 @@ class NodeRequest extends FormRequest
             'protocol_param' => 'nullable|string',
             'obfs' => 'required_if:type,1,4|exists:ss_config,name',
             'obfs_param' => 'nullable|string',
-            'compatible' => 'required|boolean',
             'is_subscribe' => 'required|boolean',
             'detection_type' => 'required|numeric|between:0,3',
             'single' => 'required|boolean',
-            'port' => 'required_if:single,1,type,2,type,3|numeric|between:1,65535|nullable',
+            'port' => 'required_if:single,1,type,2,type,3|numeric|between:1,65535|different:push_port|nullable',
             'passwd' => 'exclude_unless:type,1,type,4|required_if:single,1|string|nullable',
             'v2_alter_id' => 'required_if:type,2|numeric|between:0,65535',
             'v2_method' => 'required_if:type,2',
@@ -47,9 +46,7 @@ class NodeRequest extends FormRequest
             'v2_sni' => 'string|nullable',
             'v2_tls' => 'required_if:type,2|boolean',
             'tls_provider' => 'json|nullable',
-            'is_relay' => 'required|boolean',
-            'relay_server' => 'required_if:is_relay,1',
-            'relay_port' => 'required_if:is_relay,1|numeric|between:1,65535',
+            'relay_node_id' => 'nullable|exists:node,id',
         ];
     }
 

+ 13 - 13
app/Jobs/VNet/reloadNode.php

@@ -35,20 +35,20 @@ class reloadNode implements ShouldQueue
         $allSuccess = true;
         foreach ($this->nodes as $node) {
             $ret = $this->send(($node->server ?: $node->ip).':'.$node->push_port, $node->auth->secret, [
-                'id' => $node->id,
-                'port' => (string) $node->port,
-                'passwd' => $node->passwd ?: '',
-                'method' => $node->method,
-                'protocol' => $node->protocol,
-                'obfs' => $node->obfs,
+                'id'             => $node->id,
+                'port'           => (string) $node->port,
+                'passwd'         => $node->passwd ?: '',
+                'method'         => $node->method,
+                'protocol'       => $node->protocol,
+                'obfs'           => $node->obfs,
                 'protocol_param' => $node->protocol_param,
-                'obfs_param' => $node->obfs_param ?: '',
-                'push_port' => $node->push_port,
-                'single' => $node->single,
-                'secret' => $node->auth->secret,
-                'speed_limit' => $node->getRawOriginal('speed_limit'),
-                'is_udp' => $node->is_udp,
-                'client_limit' => $node->client_limit,
+                'obfs_param'     => $node->obfs_param ?: '',
+                'push_port'      => $node->push_port,
+                'single'         => $node->profile['passwd'] ? 1 : 0,
+                'secret'         => $node->auth->secret,
+                'speed_limit'    => $node->getRawOriginal('speed_limit'),
+                'is_udp'         => $node->is_udp,
+                'client_limit'   => $node->client_limit,
                 // 'redirect_url' => (string) sysConfig('redirect_url'),
             ]);
 

+ 25 - 39
app/Models/Node.php

@@ -17,6 +17,9 @@ class Node extends Model
 {
     protected $table = 'node';
     protected $guarded = [];
+    protected $casts = [
+        'profile' => 'array',
+    ];
 
     public function labels()
     {
@@ -63,6 +66,11 @@ class Node extends Model
         return $this->belongsTo(RuleGroup::class);
     }
 
+    public function relayNode(): BelongsTo
+    {
+        return $this->belongsTo(Node::class);
+    }
+
     public function userGroups(): BelongsToMany
     {
         return $this->belongsToMany(UserGroup::class);
@@ -122,72 +130,54 @@ class Node extends Model
         return array_map('trim', explode(',', $ip));
     }
 
-    public function config(User $user)
+    public function getConfig(User $user)
     {
         $config = [
             'id'    => $this->id,
             'name'  => $this->name,
             'host'  => $this->host,
             'group' => sysConfig('website_name'),
+            'udp'   => $this->is_udp,
         ];
         switch ($this->type) {
             case 0:
                 $config = array_merge($config, [
                     'type'   => 'shadowsocks',
-                    'method' => $this->method,
-                    'udp'    => $this->is_udp,
                     'passwd' => $user->passwd,
-                ]);
-                if ($this->single) {
-                    $config['port'] = $this->is_relay ? $this->relay_port : $this->port;
+                ], $this->profile);
+                if ($this->port) {
+                    $config['port'] = $this->port;
                 } else {
                     $config['port'] = $user->port;
                 }
                 break;
             case 2:
                 $config = array_merge($config, [
-                    'type'        => 'v2ray',
-                    'port'        => $this->is_relay ? $this->relay_port : $this->port,
-                    'uuid'        => $user->vmess_id,
-                    'method'      => $this->v2_method,
-                    'v2_alter_id' => $this->v2_alter_id,
-                    'v2_net'      => $this->v2_net,
-                    'v2_type'     => $this->v2_type,
-                    'v2_host'     => $this->v2_host,
-                    'v2_path'     => $this->v2_path,
-                    'v2_tls'      => $this->v2_tls ? 'tls' : '',
-                    'v2_sni'      => $this->v2_sni,
-                    'udp'         => $this->is_udp,
-                ]);
+                    'type' => 'v2ray',
+                    'port' => $this->port,
+                    'uuid' => $user->vmess_id,
+                ], $this->profile);
                 break;
             case 3:
                 $config = array_merge($config, [
                     'type'   => 'trojan',
-                    'port'   => $this->is_relay ? $this->relay_port : $this->port,
+                    'port'   => $this->port,
                     'passwd' => $user->passwd,
-                    'sni'    => $this->is_relay ? $this->server : '',
-                    'udp'    => $this->is_udp,
-                ]);
+                    'sni'    => $this->relay_node_id ? $this->server : '',
+                ], $this->profile);
                 break;
             case 1:
             case 4:
                 $config = array_merge($config, [
-                    'type'       => $this->compatible ? 'shadowsocks' : 'shadowsocksr',
-                    'method'     => $this->method,
-                    'protocol'   => $this->protocol,
-                    'obfs'       => $this->obfs,
-                    'obfs_param' => $this->obfs_param,
-                    'udp'        => $this->is_udp,
-                ]);
-                if ($this->single) {
+                    'type' => 'shadowsocksr',
+                ], $this->profile);
+                if ($this->profile['passwd'] && $this->port) {
                     //单端口使用中转的端口
-                    $config['port'] = $this->is_relay ? $this->relay_port : $this->port;
-                    $config['passwd'] = $this->passwd;
+                    $config['port'] = $this->port;
                     $config['protocol_param'] = $user->port.':'.$user->passwd;
                 } else {
                     $config['port'] = $user->port;
                     $config['passwd'] = $user->passwd;
-                    $config['protocol_param'] = $this->protocol_param;
                     if ($this->type === 1) {
                         $config['method'] = $user->method;
                         $config['protocol'] = $user->protocol;
@@ -223,10 +213,6 @@ class Node extends Model
 
     public function getHostAttribute(): string
     {
-        if ($this->is_relay) {
-            return $this->relay_server;
-        }
-
-        return $this->server ?: $this->ip;
+        return $this->server ?? $this->ip ?? $this->ipv6;
     }
 }

+ 1 - 1
app/Observers/NodeObserver.php

@@ -81,7 +81,7 @@ class NodeObserver
 
     public function deleted(Node $node): void
     {
-        if ($node->is_ddns === 0 && $node->server && sysConfig('ddns_mode')) {
+        if ($node->server && sysConfig('ddns_mode')) {
             DDNS::destroy($node->server);
         }
     }

Fișier diff suprimat deoarece este prea mare
+ 244 - 190
composer.lock


+ 90 - 0
database/migrations/2022_01_22_231856_improve_node_table.php

@@ -0,0 +1,90 @@
+<?php
+
+use App\Models\Config;
+use App\Models\Node;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class ImproveNodeTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    protected $configs = [
+        'stripe_currency',
+    ];
+
+    public function up()
+    {
+        foreach ($this->configs as $config) {
+            Config::insert(['name' => $config]);
+        }
+
+        // 插入新字段
+        Schema::table('node', function (Blueprint $table) {
+            $table->json('profile')->comment('节点设置选项')->after('description');
+            $table->unsignedInteger('relay_node_id')->nullable()->comment('中转节点对接母节点, 默认NULL')->after('is_relay');
+        });
+
+        foreach (Node::all() as $node) {
+            $profile = null;
+            switch ($node->type) {
+                case 0:
+                    $profile = [
+                        'method' => $node->method,
+                    ];
+                    break;
+                case 2:
+                    $profile = [
+                        'method'      => $node->v2_method,
+                        'v2_alter_id' => $node->v2_alter_id,
+                        'v2_net'      => $node->v2_net,
+                        'v2_type'     => $node->v2_type,
+                        'v2_host'     => $node->v2_host,
+                        'v2_path'     => $node->v2_path,
+                        'v2_tls'      => $node->v2_tls ? 'tls' : '',
+                        'v2_sni'      => $node->v2_sni,
+                    ];
+                    break;
+                case 3:
+                    $profile = [
+                        'allow_insecure' => false,
+                    ];
+                    break;
+                case 1:
+                case 4:
+                    $profile = [
+                        'method'         => $node->method,
+                        'protocol'       => $node->protocol,
+                        'obfs'           => $node->obfs,
+                        'obfs_param'     => $node->obfs_param,
+                        'protocol_param' => $node->protocol_param,
+                        'passwd'         => $node->passwd,
+                    ];
+                    break;
+                default:
+            }
+            Node::whereId($node->id)->update(['profile' => $profile]);
+        }
+
+        // 销毁老字段
+        Schema::table('node', function (Blueprint $table) {
+            $table->dropColumn('relay_server', 'relay_port', 'method', 'protocol', 'protocol_param', 'obfs', 'obfs_param', 'compatible', 'single', 'passwd', 'v2_alter_id',
+                'v2_method', 'v2_net', 'v2_type', 'v2_host', 'v2_path', 'v2_tls', 'v2_sni', 'tls_provider', 'is_relay');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Config::destroy($this->configs);
+        // 太复杂了,无法逆转了
+    }
+}

+ 528 - 528
resources/views/admin/config/system.blade.php

@@ -1,582 +1,582 @@
 @extends('admin.layouts')
 @section('css')
-<link href="/assets/global/vendor/bootstrap-select/bootstrap-select.min.css" rel="stylesheet">
-<link href="/assets/global/vendor/switchery/switchery.min.css" rel="stylesheet">
-<link href="/assets/global/vendor/dropify/dropify.min.css" rel="stylesheet">
+    <link href="/assets/global/vendor/bootstrap-select/bootstrap-select.min.css" rel="stylesheet">
+    <link href="/assets/global/vendor/switchery/switchery.min.css" rel="stylesheet">
+    <link href="/assets/global/vendor/dropify/dropify.min.css" rel="stylesheet">
 @endsection
 @section('content')
-<div class="page-content container-fluid">
-    <div class="panel">
-        <div class="panel-heading">
-            <h1 class="panel-title"><i class="icon wb-settings"></i>通用配置</h1>
-        </div>
-        <div class="panel-body">
-            <div class="nav-tabs-horizontal" data-plugin="tabs">
-                <ul class="nav nav-tabs" role="tablist">
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link active" data-toggle="tab" href="#webSetting" aria-controls="webSetting" role="tab">网站常规</a>
-                    </li>
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link" data-toggle="tab" href="#account" aria-controls="account" role="tab">账号设置</a>
-                    </li>
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link" data-toggle="tab" href="#node" aria-controls="node" role="tab">节点设置</a>
-                    </li>
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link" data-toggle="tab" href="#extend" aria-controls="extend" role="tab">拓展功能</a>
-                    </li>
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link" data-toggle="tab" href="#checkIn" aria-controls="checkIn" role="tab">签到系统</a>
-                    </li>
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link" data-toggle="tab" href="#promo" aria-controls="promo" role="tab">推广系统</a>
-                    </li>
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link" data-toggle="tab" href="#notify" aria-controls="notify" role="tab">通知系统</a>
-                    </li>
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link" data-toggle="tab" href="#auto" aria-controls="auto" role="tab">自动任务</a>
-                    </li>
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link" data-toggle="tab" href="#other" aria-controls="other" role="tab">LOGO|客服|统计</a>
-                    </li>
-                    <li class="nav-item" role="presentation">
-                        <a class="nav-link" data-toggle="tab" href="#payment" aria-controls="payment" role="tab">支付系统</a>
-                    </li>
-                    <li class="dropdown nav-item" role="presentation">
-                        <a class="dropdown-toggle nav-link" data-toggle="dropdown" href="#" aria-expanded="false">菜单</a>
-                        <div class="dropdown-menu" role="menu">
-                            <a class="dropdown-item active" data-toggle="tab" href="#webSetting" aria-controls="webSetting" role="tab">网站常规</a>
-                            <a class="dropdown-item" data-toggle="tab" href="#account" aria-controls="account" role="tab">账号设置</a>
-                            <a class="dropdown-item" data-toggle="tab" href="#node" aria-controls="node" role="tab">节点设置</a>
-                            <a class="dropdown-item" data-toggle="tab" href="#extend" aria-controls="extend" role="tab">拓展功能</a>
-                            <a class="dropdown-item" data-toggle="tab" href="#checkIn" aria-controls="checkIn" role="tab">签到系统</a>
-                            <a class="dropdown-item" data-toggle="tab" href="#promo" aria-controls="promo" role="tab">推广系统</a>
-                            <a class="dropdown-item" data-toggle="tab" href="#notify" aria-controls="notify" role="tab">通知系统</a>
-                            <a class="dropdown-item" data-toggle="tab" href="#auto" aria-controls="auto" role="tab">自动任务</a>
-                            <a class="dropdown-item" data-toggle="tab" href="#other" aria-controls="other" role="tab">LOGO|客服|统计</a>
-                            <a class="dropdown-item" data-toggle="tab" href="#payment" aria-controls="payment" role="tab">支付系统</a>
-                        </div>
-                    </li>
-                </ul>
-                <div class="tab-content py-35 px-35">
-                    <x-system.tab-pane id="webSetting" :active="true">
-                        <x-system.input title="网站名称" :value="$website_name" code="website_name" help="发邮件时展示"/>
-                        <x-system.input title="网站地址" :value="$website_url" code="website_url" help="生成重置密码、在线支付必备" type="url"/>
-                        <x-system.input title="苹果账号" :value="$AppStore_id" code="AppStore_id" help="iOS软件设置教程中使用的苹果账号" type="email"/>
-                        <x-system.input title="苹果密码" :value="$AppStore_password" code="AppStore_password" help="iOS软件设置教程中使用的苹果密码" type="password"/>
-                        <x-system.input title="管理员邮箱" :value="$webmaster_email" code="webmaster_email" help="错误提示时会提供管理员邮箱作为联系方式" type="email"/>
-                        <div class="form-group col-lg-6">
-                            <div class="form-row">
-                                <label class="col-md-3 col-form-label" for="website_security_code">网站安全码</label>
-                                <div class="col-md-6">
-                                    <div class="input-group">
-                                        <input type="text" class="form-control" id="website_security_code" value="{{$website_security_code}}"/>
-                                        <span class="input-group-append">
+    <div class="page-content container-fluid">
+        <div class="panel">
+            <div class="panel-heading">
+                <h1 class="panel-title"><i class="icon wb-settings"></i>通用配置</h1>
+            </div>
+            <div class="panel-body">
+                <div class="nav-tabs-horizontal" data-plugin="tabs">
+                    <ul class="nav nav-tabs" role="tablist">
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link active" data-toggle="tab" href="#webSetting" aria-controls="webSetting" role="tab">网站常规</a>
+                        </li>
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link" data-toggle="tab" href="#account" aria-controls="account" role="tab">账号设置</a>
+                        </li>
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link" data-toggle="tab" href="#node" aria-controls="node" role="tab">节点设置</a>
+                        </li>
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link" data-toggle="tab" href="#extend" aria-controls="extend" role="tab">拓展功能</a>
+                        </li>
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link" data-toggle="tab" href="#checkIn" aria-controls="checkIn" role="tab">签到系统</a>
+                        </li>
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link" data-toggle="tab" href="#promo" aria-controls="promo" role="tab">推广系统</a>
+                        </li>
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link" data-toggle="tab" href="#notify" aria-controls="notify" role="tab">通知系统</a>
+                        </li>
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link" data-toggle="tab" href="#auto" aria-controls="auto" role="tab">自动任务</a>
+                        </li>
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link" data-toggle="tab" href="#other" aria-controls="other" role="tab">LOGO|客服|统计</a>
+                        </li>
+                        <li class="nav-item" role="presentation">
+                            <a class="nav-link" data-toggle="tab" href="#payment" aria-controls="payment" role="tab">支付系统</a>
+                        </li>
+                        <li class="dropdown nav-item" role="presentation">
+                            <a class="dropdown-toggle nav-link" data-toggle="dropdown" href="#" aria-expanded="false">菜单</a>
+                            <div class="dropdown-menu" role="menu">
+                                <a class="dropdown-item active" data-toggle="tab" href="#webSetting" aria-controls="webSetting" role="tab">网站常规</a>
+                                <a class="dropdown-item" data-toggle="tab" href="#account" aria-controls="account" role="tab">账号设置</a>
+                                <a class="dropdown-item" data-toggle="tab" href="#node" aria-controls="node" role="tab">节点设置</a>
+                                <a class="dropdown-item" data-toggle="tab" href="#extend" aria-controls="extend" role="tab">拓展功能</a>
+                                <a class="dropdown-item" data-toggle="tab" href="#checkIn" aria-controls="checkIn" role="tab">签到系统</a>
+                                <a class="dropdown-item" data-toggle="tab" href="#promo" aria-controls="promo" role="tab">推广系统</a>
+                                <a class="dropdown-item" data-toggle="tab" href="#notify" aria-controls="notify" role="tab">通知系统</a>
+                                <a class="dropdown-item" data-toggle="tab" href="#auto" aria-controls="auto" role="tab">自动任务</a>
+                                <a class="dropdown-item" data-toggle="tab" href="#other" aria-controls="other" role="tab">LOGO|客服|统计</a>
+                                <a class="dropdown-item" data-toggle="tab" href="#payment" aria-controls="payment" role="tab">支付系统</a>
+                            </div>
+                        </li>
+                    </ul>
+                    <div class="tab-content py-35 px-35">
+                        <x-system.tab-pane id="webSetting" :active="true">
+                            <x-system.input title="网站名称" :value="$website_name" code="website_name" help="发邮件时展示"/>
+                            <x-system.input title="网站地址" :value="$website_url" code="website_url" help="生成重置密码、在线支付必备" type="url"/>
+                            <x-system.input title="苹果账号" :value="$AppStore_id" code="AppStore_id" help="iOS软件设置教程中使用的苹果账号" type="email"/>
+                            <x-system.input title="苹果密码" :value="$AppStore_password" code="AppStore_password" help="iOS软件设置教程中使用的苹果密码" type="password"/>
+                            <x-system.input title="管理员邮箱" :value="$webmaster_email" code="webmaster_email" help="错误提示时会提供管理员邮箱作为联系方式" type="email"/>
+                            <div class="form-group col-lg-6">
+                                <div class="form-row">
+                                    <label class="col-md-3 col-form-label" for="website_security_code">网站安全码</label>
+                                    <div class="col-md-6">
+                                        <div class="input-group">
+                                            <input type="text" class="form-control" id="website_security_code" value="{{$website_security_code}}"/>
+                                            <span class="input-group-append">
                                                 <button class="btn btn-info" type="button" onclick="makeWebsiteSecurityCode()">生成</button>
                                                 <button class="btn btn-primary" type="button" onclick="update('website_security_code')">{{trans('common.update')}}</button>
                                             </span>
+                                        </div>
+                                        <span class="text-help">非空时必须通过<a href="{{route('login')}}?securityCode=" target="_blank">安全入口</a>加上安全码才可访问</span>
                                     </div>
-                                    <span class="text-help">非空时必须通过<a href="{{route('login')}}?securityCode=" target="_blank">安全入口</a>加上安全码才可访问</span>
                                 </div>
                             </div>
-                        </div>
-                        <x-system.select title="禁止访问模式" code="forbid_mode" help="依据IP对对应地区进行阻拦,非阻拦地区可正常访问"
-                                         :list="['关闭' => '', '阻拦大陆'=> 'ban_mainland', '阻拦中国' => 'ban_china', '阻拦海外' => 'ban_oversea']"/>
-                        <x-system.switch title="阻止机器人访问" code="is_forbid_robot" :check="$is_forbid_robot" help="如果是机器人、爬虫、代理访问网站则会抛出404错误"/>
-                        <x-system.switch title="维护模式" code="maintenance_mode" :check="$maintenance_mode"
-                                         help="启用后,用户访问转移至维护界面 | 管理员使用 <a href='javascript:(0)'>{{route('admin.login')}}</a> 登录"/>
-                        <x-system.input title="维护结束时间" :value="$maintenance_time" code="maintenance_time" help="用于维护界面倒计时" type="datetime-local"/>
-                        <x-system.textarea title="维护介绍内容" code="maintenance_content" :value="$maintenance_content" row="3" help="自定义维护内容信息"/>
-                        <x-system.input title="重定向地址" :value="$redirect_url" code="redirect_url" help="触发审计规则时访问请求被阻断并重定向至该地址" type="url"/>
-                    </x-system.tab-pane>
-                    <x-system.tab-pane id="account">
-                        <x-system.switch title="用户注册" code="is_register" :check="$is_register" help="关闭后无法注册"/>
-                        <x-system.select title="第三方登录平台" code="oauth_path" help="请在.ENV中添加设置,再在此处开启平台" multiple="1"
-                                         :list="array_flip(config('common.oauth.labels'))"/>
-                        <x-system.select title="账号类型" help="规范站点用户账号的类型,默认为电子邮箱" code="username_type" :list="['电子邮箱'=> 'email', '手机号码' => 'numeric', '任意用户名' => 'string']"/>
-                        <x-system.select title="邀请注册" code="is_invite_register" :list="['关闭' => '', '可选'=> 1, '必须' => 2]"/>
-                        <x-system.select title="激活账号" code="is_activate_account" :list="['关闭' => '', '注册前激活'=> 1, '注册后激活' => 2]" help="启用后用户需要通过邮件来激活账号"/>
-                        <x-system.select title="重置密码" code="password_reset_notification" :list="['关闭' => '', '邮箱'=> 'mail']" help="启用后用户可以重置密码"/>
-                        <x-system.switch title="免费邀请码" code="is_free_code" :check="$is_free_code" help="关闭后免费邀请码不可见"/>
-                        <x-system.input title="邀请链接 用户信息字符化" :value="$aff_salt" code="aff_salt" help="留空时,邀请链接将显示用户ID;填入任意英文/数字 即可对用户链接ID进行加密"/>
-                        <x-system.switch title="随机端口" code="is_rand_port" :check="$is_rand_port" help="注册、添加用户时随机生成端口"/>
-                        <x-system.input-limit title="端口范围" code="min_port" hcode="max_port" :value="$min_port" min="1000" max="$('#max_port').val()"
-                                              :hvalue="$max_port" hmin="$('#min_port').val()" hmax="65535" help="端口范围:1000 - 65535"/>
-                        <x-system.input-limit title="初始有效期" code="default_days" :value="$default_days" unit="天" help="用户注册时默认账户有效期,为0即当天到期"/>
-                        <x-system.input-limit title="初始流量" code="default_traffic" :value="$default_traffic" unit="MB" help="用户注册时默认可用流量"/>
-                        <x-system.input-limit title="可生成邀请码数" code="invite_num" :value="$invite_num" help="用户可以生成的邀请码数"/>
-                        <x-system.input-limit title="重置密码次数" code="reset_password_times" :value="$reset_password_times" help="24小时内可以通过邮件重置密码次数"/>
-                        <x-system.select title="邮箱过滤机制" code="is_email_filtering" help="黑名单: 用户可使用任意黑名单外的邮箱注册;白名单:用户只能选择使用白名单中的邮箱后缀注册"
-                                         :list="['关闭' => '', '黑名单' => 1, '白名单' => 2]"/>
-                        <x-system.input-limit title="激活账号次数" code="active_times" :value="$active_times" help="24小时内可以通过邮件激活账号次数"/>
-                        <x-system.input-limit title="同IP注册限制" code="register_ip_limit" :value="$register_ip_limit" help="同IP在24小时内允许注册数量,为0/留空时不限制"/>
-                        <x-system.input-limit title="用户-邀请码有效期" code="user_invite_days" :value="$user_invite_days" min="1" unit="天" help="用户自行生成邀请的有效期"/>
-                        <x-system.input-limit title="管理员-邀请码有效期" code="admin_invite_days" :value="$admin_invite_days" min="1" unit="天" help="管理员生成邀请码的有效期"/>
-                    </x-system.tab-pane>
-                    <x-system.tab-pane id="node">
-                        <x-system.input title="节点订阅地址" :value="$subscribe_domain" code="subscribe_domain" help="(推荐)防止面板域名被DNS投毒后无法正常订阅,需带http://或https://"
-                                        :holder="'默认为 '.$website_url" type="url"/>
-                        <x-system.input-limit title="订阅节点数" code="subscribe_max" :value="$subscribe_max" help="客户端订阅时取得几个节点,为0/留空时返回全部节点"/>
-                        <x-system.switch title="随机订阅" code="rand_subscribe" :check="$rand_subscribe" help="启用后,订阅时将随机返回节点信息,否则按节点排序返回"/>
-                        <x-system.switch title="高级订阅" code="is_custom_subscribe" :check="$is_custom_subscribe" help="启用后,订阅信息顶部将显示过期时间、剩余流量(只支持个别客户端)"/>
-                        <x-system.input title="授权/后端访问域名" :value="$web_api_url" code="web_api_url" help="例:https://demo.proxypanel.ml" type="url"/>
-                        <x-system.input title="V2Ray授权" :value="$v2ray_license" code="v2ray_license"/>
-                        <x-system.input title="Trojan授权" :value="$trojan_license" code="trojan_license"/>
-                        <x-system.input title="V2Ray TLS配置" :value="$v2ray_tls_provider" code="v2ray_tls_provider" help="后端自动签发/载入TLS证书时用(节点的设置值优先级高于此处)"/>
-                    </x-system.tab-pane>
-                    <x-system.tab-pane id="extend">
-                        <x-system.select title="DDNS模式" code="ddns_mode" help="添加/编辑/删除节点的【域名、ipv4、ipv6】时,自动更新对应内容至DNS服务商"
-                                         :list="['关闭' => '', 'Namesilo' => 'namesilo', '阿里云(国际&国内)' => 'aliyun', 'DNSPod' => 'dnspod', 'CloudFlare' => 'cloudflare']"/>
-                        <x-system.input title="DNS服务商Key" :value="$ddns_key" code="ddns_key"
-                                        help="浏览<a href='https://proxypanel.gitbook.io/wiki/ddns' target='_blank'>设置指南</a>来设置"/>
-                        <x-system.input title="DNS服务商Secret" :value="$ddns_secret" code="ddns_secret"/>
-                        <hr class="col-lg-12">
-                        <x-system.select title="验证码模式" code="is_captcha"
-                                         :list="['关闭' => '', '普通验证码' => 1, '极验Geetest' => 2, 'Google reCaptcha' => 3, 'hCaptcha' => 4]" help="启用后 登录/注册 需要进行验证码认证"/>
-                        <x-system.input title="验证码 Key" :value="$captcha_key" code="captcha_key"
-                                        help='浏览<a href="https://proxypanel.gitbook.io/wiki/captcha" target="_blank">设置指南</a>来设置'/>
-                        <x-system.input title="验证码 Secret/ID" :value="$captcha_secret" code="captcha_secret"/>
-                    </x-system.tab-pane>
-                    <x-system.tab-pane id="checkIn">
-                        <x-system.switch title="签到加流量" code="is_checkin" :check="$is_checkin" help="登录时将根据流量范围随机得到流量"/>
-                        <x-system.input-limit title="时间间隔" code="traffic_limit_time" :value="$traffic_limit_time" help="间隔多久才可以再次签到"/>
-                        <x-system.input-limit title="流量范围" code="min_rand_traffic" hcode="max_rand_traffic" :value="$min_rand_traffic" :hvalue="$max_rand_traffic"
-                                              :max="$max_rand_traffic" :hmin="$min_rand_traffic" unit="MB"/>
-                    </x-system.tab-pane>
-                    <x-system.tab-pane id="promo">
-                        <x-system.switch title="推广功能" code="referral_status" :check="$referral_status" help="关闭后用户不可见,但是不影响其正常邀请返利"/>
-                        <x-system.select title="返利模式" code="referral_type" :list="['关闭' => '', '首购返利' => 1, '循环返利' => 2]" help="切换模式后旧数据不变,新的返利按新的模式计算"/>
-                        <x-system.input-limit title="注册送流量" code="referral_traffic" :value="$referral_traffic" unit="MB" help="根据推广链接、邀请码注册则赠送相应的流量"/>
-                        <x-system.input-limit title="返利比例" code="referral_percent" :value="$referral_percent * 100" max="100" unit="%"
-                                              help="根据推广链接注册的账号每笔消费推广人可以分成的比例 "/>
-                        <x-system.input-limit title="提现限制" code="referral_money" :value="$referral_money" unit="元" help="满多少元才可以申请提现"/>
-                    </x-system.tab-pane>
-                    <x-system.tab-pane id="notify">
-                        <x-system.input-test title="SCKEY" :value="$server_chan_key" code="server_chan_key" help='启用ServerChan,请务必填入本值(<a href=https://sc.ftqq.com
+                            <x-system.select title="禁止访问模式" code="forbid_mode" help="依据IP对对应地区进行阻拦,非阻拦地区可正常访问"
+                                             :list="['关闭' => '', '阻拦大陆'=> 'ban_mainland', '阻拦中国' => 'ban_china', '阻拦海外' => 'ban_oversea']"/>
+                            <x-system.switch title="阻止机器人访问" code="is_forbid_robot" :check="$is_forbid_robot" help="如果是机器人、爬虫、代理访问网站则会抛出404错误"/>
+                            <x-system.switch title="维护模式" code="maintenance_mode" :check="$maintenance_mode"
+                                             help="启用后,用户访问转移至维护界面 | 管理员使用 <a href='javascript:(0)'>{{route('admin.login')}}</a> 登录"/>
+                            <x-system.input title="维护结束时间" :value="$maintenance_time" code="maintenance_time" help="用于维护界面倒计时" type="datetime-local"/>
+                            <x-system.textarea title="维护介绍内容" code="maintenance_content" :value="$maintenance_content" row="3" help="自定义维护内容信息"/>
+                            <x-system.input title="重定向地址" :value="$redirect_url" code="redirect_url" help="触发审计规则时访问请求被阻断并重定向至该地址" type="url"/>
+                        </x-system.tab-pane>
+                        <x-system.tab-pane id="account">
+                            <x-system.switch title="用户注册" code="is_register" :check="$is_register" help="关闭后无法注册"/>
+                            <x-system.select title="第三方登录平台" code="oauth_path" help="请在.ENV中添加设置,再在此处开启平台" multiple="1"
+                                             :list="array_flip(config('common.oauth.labels'))"/>
+                            <x-system.select title="账号类型" help="规范站点用户账号的类型,默认为电子邮箱" code="username_type" :list="['电子邮箱'=> 'email', '手机号码' => 'numeric', '任意用户名' => 'string']"/>
+                            <x-system.select title="邀请注册" code="is_invite_register" :list="['关闭' => '', '可选'=> 1, '必须' => 2]"/>
+                            <x-system.select title="激活账号" code="is_activate_account" :list="['关闭' => '', '注册前激活'=> 1, '注册后激活' => 2]" help="启用后用户需要通过邮件来激活账号"/>
+                            <x-system.select title="重置密码" code="password_reset_notification" :list="['关闭' => '', '邮箱'=> 'mail']" help="启用后用户可以重置密码"/>
+                            <x-system.switch title="免费邀请码" code="is_free_code" :check="$is_free_code" help="关闭后免费邀请码不可见"/>
+                            <x-system.input title="邀请链接 用户信息字符化" :value="$aff_salt" code="aff_salt" help="留空时,邀请链接将显示用户ID;填入任意英文/数字 即可对用户链接ID进行加密"/>
+                            <x-system.switch title="随机端口" code="is_rand_port" :check="$is_rand_port" help="注册、添加用户时随机生成端口"/>
+                            <x-system.input-limit title="端口范围" code="min_port" hcode="max_port" :value="$min_port" min="1000" max="$('#max_port').val()"
+                                                  :hvalue="$max_port" hmin="$('#min_port').val()" hmax="65535" help="端口范围:1000 - 65535"/>
+                            <x-system.input-limit title="初始有效期" code="default_days" :value="$default_days" unit="天" help="用户注册时默认账户有效期,为0即当天到期"/>
+                            <x-system.input-limit title="初始流量" code="default_traffic" :value="$default_traffic" unit="MB" help="用户注册时默认可用流量"/>
+                            <x-system.input-limit title="可生成邀请码数" code="invite_num" :value="$invite_num" help="用户可以生成的邀请码数"/>
+                            <x-system.input-limit title="重置密码次数" code="reset_password_times" :value="$reset_password_times" help="24小时内可以通过邮件重置密码次数"/>
+                            <x-system.select title="邮箱过滤机制" code="is_email_filtering" help="黑名单: 用户可使用任意黑名单外的邮箱注册;白名单:用户只能选择使用白名单中的邮箱后缀注册"
+                                             :list="['关闭' => '', '黑名单' => 1, '白名单' => 2]"/>
+                            <x-system.input-limit title="激活账号次数" code="active_times" :value="$active_times" help="24小时内可以通过邮件激活账号次数"/>
+                            <x-system.input-limit title="同IP注册限制" code="register_ip_limit" :value="$register_ip_limit" help="同IP在24小时内允许注册数量,为0/留空时不限制"/>
+                            <x-system.input-limit title="用户-邀请码有效期" code="user_invite_days" :value="$user_invite_days" min="1" unit="天" help="用户自行生成邀请的有效期"/>
+                            <x-system.input-limit title="管理员-邀请码有效期" code="admin_invite_days" :value="$admin_invite_days" min="1" unit="天" help="管理员生成邀请码的有效期"/>
+                        </x-system.tab-pane>
+                        <x-system.tab-pane id="node">
+                            <x-system.input title="节点订阅地址" :value="$subscribe_domain" code="subscribe_domain" help="(推荐)防止面板域名被DNS投毒后无法正常订阅,需带http://或https://"
+                                            :holder="'默认为 '.$website_url" type="url"/>
+                            <x-system.input-limit title="订阅节点数" code="subscribe_max" :value="$subscribe_max" help="客户端订阅时取得几个节点,为0/留空时返回全部节点"/>
+                            <x-system.switch title="随机订阅" code="rand_subscribe" :check="$rand_subscribe" help="启用后,订阅时将随机返回节点信息,否则按节点排序返回"/>
+                            <x-system.switch title="高级订阅" code="is_custom_subscribe" :check="$is_custom_subscribe" help="启用后,订阅信息顶部将显示过期时间、剩余流量(只支持个别客户端)"/>
+                            <x-system.input title="授权/后端访问域名" :value="$web_api_url" code="web_api_url" help="例:https://demo.proxypanel.ml" type="url"/>
+                            <x-system.input title="V2Ray授权" :value="$v2ray_license" code="v2ray_license"/>
+                            <x-system.input title="Trojan授权" :value="$trojan_license" code="trojan_license"/>
+                            <x-system.input title="V2Ray TLS配置" :value="$v2ray_tls_provider" code="v2ray_tls_provider" help="后端自动签发/载入TLS证书时用(节点的设置值优先级高于此处)"/>
+                        </x-system.tab-pane>
+                        <x-system.tab-pane id="extend">
+                            <x-system.select title="DDNS模式" code="ddns_mode" help="添加/编辑/删除节点的【域名、ipv4、ipv6】时,自动更新对应内容至DNS服务商"
+                                             :list="['关闭' => '', 'Namesilo' => 'namesilo', '阿里云(国际&国内)' => 'aliyun', 'DNSPod' => 'dnspod', 'CloudFlare' => 'cloudflare']"/>
+                            <x-system.input title="DNS服务商Key" :value="$ddns_key" code="ddns_key"
+                                            help="浏览<a href='https://proxypanel.gitbook.io/wiki/ddns' target='_blank'>设置指南</a>来设置"/>
+                            <x-system.input title="DNS服务商Secret" :value="$ddns_secret" code="ddns_secret"/>
+                            <hr class="col-lg-12">
+                            <x-system.select title="验证码模式" code="is_captcha"
+                                             :list="['关闭' => '', '普通验证码' => 1, '极验Geetest' => 2, 'Google reCaptcha' => 3, 'hCaptcha' => 4]" help="启用后 登录/注册 需要进行验证码认证"/>
+                            <x-system.input title="验证码 Key" :value="$captcha_key" code="captcha_key"
+                                            help='浏览<a href="https://proxypanel.gitbook.io/wiki/captcha" target="_blank">设置指南</a>来设置'/>
+                            <x-system.input title="验证码 Secret/ID" :value="$captcha_secret" code="captcha_secret"/>
+                        </x-system.tab-pane>
+                        <x-system.tab-pane id="checkIn">
+                            <x-system.switch title="签到加流量" code="is_checkin" :check="$is_checkin" help="登录时将根据流量范围随机得到流量"/>
+                            <x-system.input-limit title="时间间隔" code="traffic_limit_time" :value="$traffic_limit_time" help="间隔多久才可以再次签到"/>
+                            <x-system.input-limit title="流量范围" code="min_rand_traffic" hcode="max_rand_traffic" :value="$min_rand_traffic" :hvalue="$max_rand_traffic"
+                                                  :max="$max_rand_traffic" :hmin="$min_rand_traffic" unit="MB"/>
+                        </x-system.tab-pane>
+                        <x-system.tab-pane id="promo">
+                            <x-system.switch title="推广功能" code="referral_status" :check="$referral_status" help="关闭后用户不可见,但是不影响其正常邀请返利"/>
+                            <x-system.select title="返利模式" code="referral_type" :list="['关闭' => '', '首购返利' => 1, '循环返利' => 2]" help="切换模式后旧数据不变,新的返利按新的模式计算"/>
+                            <x-system.input-limit title="注册送流量" code="referral_traffic" :value="$referral_traffic" unit="MB" help="根据推广链接、邀请码注册则赠送相应的流量"/>
+                            <x-system.input-limit title="返利比例" code="referral_percent" :value="$referral_percent * 100" max="100" unit="%"
+                                                  help="根据推广链接注册的账号每笔消费推广人可以分成的比例 "/>
+                            <x-system.input-limit title="提现限制" code="referral_money" :value="$referral_money" unit="元" help="满多少元才可以申请提现"/>
+                        </x-system.tab-pane>
+                        <x-system.tab-pane id="notify">
+                            <x-system.input-test title="SCKEY" :value="$server_chan_key" code="server_chan_key" help='启用ServerChan,请务必填入本值(<a href=https://sc.ftqq.com
                                     target=_blank>申请 SCKEY</a>)' holder="请到ServerChan申请" test="serverChan"/>
-                        <x-system.input-test title="Bark设备号" :value="$bark_key" code="bark_key" holder="安装并打开Bark后取得" type="url"
-                                             help="推送消息到iOS设备,需要在iOS设备里装一个名为Bark的应用,取网址后的一长串代码,启用Bark,请务必填入本值" test="bark"/>
-                        <x-system.input-test title="Telegram Token" :value="$telegram_token" code="telegram_token" help="找 <a href=https://t.me/BotFather
+                            <x-system.input-test title="Bark设备号" :value="$bark_key" code="bark_key" holder="安装并打开Bark后取得" type="url"
+                                                 help="推送消息到iOS设备,需要在iOS设备里装一个名为Bark的应用,取网址后的一长串代码,启用Bark,请务必填入本值" test="bark"/>
+                            <x-system.input-test title="Telegram Token" :value="$telegram_token" code="telegram_token" help="找 <a href=https://t.me/BotFather
                                     target=_blank>@BotFather</a> 申请机器人" test="telegram"/>
-                        <x-system.input title="微信企业ID" :value="$wechat_cid" code="wechat_cid"
-                                        help="获取<a href=https://work.weixin.qq.com/wework_admin/frame#profile target=_blank>我的企业</a>中的企业ID"/>
-                        <x-system.input title="微信企业应用ID" :value="$wechat_aid" code="wechat_aid" holder="应用的AgentId"
-                                        help="在<a href=https://work.weixin.qq.com/wework_admin/frame#apps arget=_blank>应用管理</a>自建中创建应用 - AgentId"/>
-                        <x-system.input-test title="微信企业应用密钥" :value="$wechat_secret" code="wechat_secret" help='应用的Secret(可能需要下载企业微信才能查看)' holder="应用的Secret" test="weChat"/>
-                        <x-system.input title="微信企业应用TOKEN" :value="$wechat_token" code="wechat_token" help="{{'应用管理->应用->设置API接收->TOKEN,URL设置:'.route('wechat.verify')}}"/>
-                        <x-system.input title="微信企业应用EncodingAESKey" :value="$wechat_encodingAESKey" code="wechat_encodingAESKey" help='应用管理->应用->设置API接收->EncodingAESKey'/>
-                        <x-system.input-test title="TG酱Token" :value="$tg_chat_token" code="tg_chat_token" help='启用TG酱,请务必填入本值(<a href=https://t.me/realtgchat_bot
+                            <x-system.input title="微信企业ID" :value="$wechat_cid" code="wechat_cid"
+                                            help="获取<a href=https://work.weixin.qq.com/wework_admin/frame#profile target=_blank>我的企业</a>中的企业ID"/>
+                            <x-system.input title="微信企业应用ID" :value="$wechat_aid" code="wechat_aid" holder="应用的AgentId"
+                                            help="在<a href=https://work.weixin.qq.com/wework_admin/frame#apps arget=_blank>应用管理</a>自建中创建应用 - AgentId"/>
+                            <x-system.input-test title="微信企业应用密钥" :value="$wechat_secret" code="wechat_secret" help='应用的Secret(可能需要下载企业微信才能查看)' holder="应用的Secret" test="weChat"/>
+                            <x-system.input title="微信企业应用TOKEN" :value="$wechat_token" code="wechat_token" help="{{'应用管理->应用->设置API接收->TOKEN,URL设置:'.route('wechat.verify')}}"/>
+                            <x-system.input title="微信企业应用EncodingAESKey" :value="$wechat_encodingAESKey" code="wechat_encodingAESKey" help='应用管理->应用->设置API接收->EncodingAESKey'/>
+                            <x-system.input-test title="TG酱Token" :value="$tg_chat_token" code="tg_chat_token" help='启用TG酱,请务必填入本值(<a href=https://t.me/realtgchat_bot
                                     target=_blank>申请 Token</a>)' holder="请到Telegram申请" test="tgChat"/>
-                        <x-system.input-test title="PushPlus Token" :value="$pushplus_token" code="pushplus_token" help='启用PushPlus,请务必填入本值(<a href=https://www.pushplus.plus/push1.html
+                            <x-system.input-test title="PushPlus Token" :value="$pushplus_token" code="pushplus_token" help='启用PushPlus,请务必填入本值(<a href=https://www.pushplus.plus/push1.html
                                     target=_blank>申请 Token</a>)' holder="请到ServerChan申请" test="pushPlus"/>
-                        <x-system.switch title="PushBear" code="is_push_bear" :check="$is_push_bear"
-                                         help='使用PushBear推送微信消息给用户(<a href="https://pushbear.ftqq.com/admin/#/signin" target="_blank">创建消息通道</a>)'/>
-                        <x-system.input title="PushBear SendKey" :value="$push_bear_send_key" code="push_bear_send_key" help="启用PushBear,请务必填入本值" holder="创建消息通道后即可获取"/>
-                        <x-system.input title="PushBear订阅二维码" :value="$push_bear_qrcode" code="push_bear_qrcode" help="创建消息通道后,在二维码上点击右键“复制图片地址”并粘贴至此处"
-                                        holder="填入消息通道的二维码URL" type="url"/>
-                        <hr class="col-10"/>
-                        <x-system.select title="账号过期通知" code="account_expire_notification" help="通知用户账号即将到期" multiple="1" :list="['邮箱' => 'mail', '站内通知' => 'database']"/>
-                        <x-system.input-limit title="过期警告阈值" code="expire_days" :value="$expire_days" unit="元" help="【账号过期通知】开始阈值,每日通知用户"/>
-                        <x-system.select title="流量耗尽通知" code="data_exhaust_notification" help="通知用户流量即将耗尽" multiple="1" :list="['邮箱' => 'mail', '站内通知' => 'database']"/>
-                        <x-system.input-limit title="流量警告阈值" code="traffic_warning_percent" :value="$traffic_warning_percent" unit="%" help="【流量耗尽通知】开始阈值,每日通知用户"/>
-                        <x-system.select title="节点离线提醒" code="node_offline_notification" help="每10分钟检测节点离线并提醒管理员" multiple="1"
-                                         :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
+                            <x-system.switch title="PushBear" code="is_push_bear" :check="$is_push_bear"
+                                             help='使用PushBear推送微信消息给用户(<a href="https://pushbear.ftqq.com/admin/#/signin" target="_blank">创建消息通道</a>)'/>
+                            <x-system.input title="PushBear SendKey" :value="$push_bear_send_key" code="push_bear_send_key" help="启用PushBear,请务必填入本值" holder="创建消息通道后即可获取"/>
+                            <x-system.input title="PushBear订阅二维码" :value="$push_bear_qrcode" code="push_bear_qrcode" help="创建消息通道后,在二维码上点击右键“复制图片地址”并粘贴至此处"
+                                            holder="填入消息通道的二维码URL" type="url"/>
+                            <hr class="col-10"/>
+                            <x-system.select title="账号过期通知" code="account_expire_notification" help="通知用户账号即将到期" multiple="1" :list="['邮箱' => 'mail', '站内通知' => 'database']"/>
+                            <x-system.input-limit title="过期警告阈值" code="expire_days" :value="$expire_days" unit="元" help="【账号过期通知】开始阈值,每日通知用户"/>
+                            <x-system.select title="流量耗尽通知" code="data_exhaust_notification" help="通知用户流量即将耗尽" multiple="1" :list="['邮箱' => 'mail', '站内通知' => 'database']"/>
+                            <x-system.input-limit title="流量警告阈值" code="traffic_warning_percent" :value="$traffic_warning_percent" unit="%" help="【流量耗尽通知】开始阈值,每日通知用户"/>
+                            <x-system.select title="节点离线提醒" code="node_offline_notification" help="每10分钟检测节点离线并提醒管理员" multiple="1"
+                                             :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
                                              'tgChat', 'PushPlus' => 'pushPlus']"/>
-                        <x-system.input-limit title="离线提醒次数" code="offline_check_times" :value="$offline_check_times" unit="次" help="24小时内提醒n次后不再提醒"/>
-                        <x-system.select title="节点阻断提醒" code="node_blocked_notification" help="每小时检测节点是否被阻断并提醒管理员" multiple="1"
-                                         :list="['邮箱' => 'mail', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' => 'tgChat', 'PushPlus'
+                            <x-system.input-limit title="离线提醒次数" code="offline_check_times" :value="$offline_check_times" unit="次" help="24小时内提醒n次后不再提醒"/>
+                            <x-system.select title="节点阻断提醒" code="node_blocked_notification" help="每小时检测节点是否被阻断并提醒管理员" multiple="1"
+                                             :list="['邮箱' => 'mail', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' => 'tgChat', 'PushPlus'
                                              => 'pushPlus']"/>
-                        <x-system.input-limit title="阻断检测提醒" code="detection_check_times" :value="$detection_check_times" max="12" unit="次"
-                                              help="提醒N次后自动下线节点,为0/留空时不限制,不超过12"/>
-                        <x-system.select title="支付成功通知" code="payment_received_notification" help="用户支付订单后通知用户订单状态" multiple="1"
-                                         :list="['邮箱' => 'mail', '站内通知' => 'database', 'Telegram' => 'telegram']"/>
-                        <x-system.select title="人工支付确认通知" code="payment_confirm_notification" help="用户使用人工支付后通知管理员处理订单"
-                                         :list="['关闭' => '', 'Telegram' => 'telegram', '微信企业' => 'weChat']"/>
-                        <x-system.select title="工单关闭通知" code="ticket_closed_notification" help="工单关闭通知用户" multiple="1"
-                                         :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
+                            <x-system.input-limit title="阻断检测提醒" code="detection_check_times" :value="$detection_check_times" max="12" unit="次"
+                                                  help="提醒N次后自动下线节点,为0/留空时不限制,不超过12"/>
+                            <x-system.select title="支付成功通知" code="payment_received_notification" help="用户支付订单后通知用户订单状态" multiple="1"
+                                             :list="['邮箱' => 'mail', '站内通知' => 'database', 'Telegram' => 'telegram']"/>
+                            <x-system.select title="人工支付确认通知" code="payment_confirm_notification" help="用户使用人工支付后通知管理员处理订单"
+                                             :list="['关闭' => '', 'Telegram' => 'telegram', '微信企业' => 'weChat']"/>
+                            <x-system.select title="工单关闭通知" code="ticket_closed_notification" help="工单关闭通知用户" multiple="1"
+                                             :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
                                              'tgChat', 'PushPlus' => 'pushPlus']"/>
-                        <x-system.select title="新工单通知" code="ticket_created_notification" help="新工单通知管理/用户,取决于谁创建了新工单" multiple="1"
-                                         :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
+                            <x-system.select title="新工单通知" code="ticket_created_notification" help="新工单通知管理/用户,取决于谁创建了新工单" multiple="1"
+                                             :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
                                              'tgChat', 'PushPlus' => 'pushPlus']"/>
-                        <x-system.select title="工单回复通知" code="ticket_replied_notification" help="工单回复通知对方" multiple="1"
-                                         :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
+                            <x-system.select title="工单回复通知" code="ticket_replied_notification" help="工单回复通知对方" multiple="1"
+                                             :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
                                              'tgChat', 'PushPlus' => 'pushPlus']"/>
-                    </x-system.tab-pane>
-                    <x-system.tab-pane id="auto">
-                        <x-system.switch title="自动清除日志" code="is_clear_log" :check="$is_clear_log" help='(推荐)启用后自动清除无用日志'/>
-                        <x-system.switch title="流量自动重置" code="reset_traffic" :check="$reset_traffic" help='用户会按其购买套餐的日期自动重置可用流量'/>
-                        <x-system.switch title="订阅异常自动封禁" code="is_subscribe_ban" :check="$is_subscribe_ban" help='启用后用户订阅链接请求超过设定阈值则自动封禁'/>
-                        <x-system.input-limit title="订阅请求阈值" code="subscribe_ban_times" :value="$subscribe_ban_times" help="24小时内订阅链接请求次数限制"/>
-                        <x-system.switch title="异常自动封号" code="is_traffic_ban" :check="$is_traffic_ban" help='1小时内流量超过异常阈值则自动封号(仅禁用代理)'/>
-                        <x-system.select title="流量异常通知" code="data_anomaly_notification" help="1小时内流量超过异常阈值通知超管" multiple="1"
-                                         :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
+                        </x-system.tab-pane>
+                        <x-system.tab-pane id="auto">
+                            <x-system.switch title="自动清除日志" code="is_clear_log" :check="$is_clear_log" help='(推荐)启用后自动清除无用日志'/>
+                            <x-system.switch title="流量自动重置" code="reset_traffic" :check="$reset_traffic" help='用户会按其购买套餐的日期自动重置可用流量'/>
+                            <x-system.switch title="订阅异常自动封禁" code="is_subscribe_ban" :check="$is_subscribe_ban" help='启用后用户订阅链接请求超过设定阈值则自动封禁'/>
+                            <x-system.input-limit title="订阅请求阈值" code="subscribe_ban_times" :value="$subscribe_ban_times" help="24小时内订阅链接请求次数限制"/>
+                            <x-system.switch title="异常自动封号" code="is_traffic_ban" :check="$is_traffic_ban" help='1小时内流量超过异常阈值则自动封号(仅禁用代理)'/>
+                            <x-system.select title="流量异常通知" code="data_anomaly_notification" help="1小时内流量超过异常阈值通知超管" multiple="1"
+                                             :list="['邮箱' => 'mail', 'Bark' => 'bark', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
                                              'tgChat', 'PushPlus' => 'pushPlus']"/>
-                        <x-system.input-limit title="流量异常阈值" code="traffic_ban_value" :value="$traffic_ban_value" min="1" unit="GB" help="1小时内超过该值,则触发自动封号"/>
-                        <x-system.input-limit title="封号时长" code="traffic_ban_time" :value="$traffic_ban_time" unit="分钟" help="触发流量异常导致用户被封禁的时长,到期后自动解封"/>
-                        <x-system.switch title="端口回收机制" code="auto_release_port" :check="$auto_release_port" help="被封禁/过期{{config('tasks.release_port')}}天的账号端口自动释放"/>
-                        <x-system.switch title="过期自动封禁" code="is_ban_status" :check="$is_ban_status" help="(慎重)封禁整个账号会重置账号的所有数据且会导致用户无法登录,不开启状态下只封禁用户代理"/>
-                        <x-system.select title="节点使用报告" code="node_daily_notification" help="报告各节点流量昨日消耗情况" multiple="1"
-                                         :list="['邮箱' => 'mail', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
+                            <x-system.input-limit title="流量异常阈值" code="traffic_ban_value" :value="$traffic_ban_value" min="1" unit="GB" help="1小时内超过该值,则触发自动封号"/>
+                            <x-system.input-limit title="封号时长" code="traffic_ban_time" :value="$traffic_ban_time" unit="分钟" help="触发流量异常导致用户被封禁的时长,到期后自动解封"/>
+                            <x-system.switch title="端口回收机制" code="auto_release_port" :check="$auto_release_port" help="被封禁/过期{{config('tasks.release_port')}}天的账号端口自动释放"/>
+                            <x-system.switch title="过期自动封禁" code="is_ban_status" :check="$is_ban_status" help="(慎重)封禁整个账号会重置账号的所有数据且会导致用户无法登录,不开启状态下只封禁用户代理"/>
+                            <x-system.select title="节点使用报告" code="node_daily_notification" help="报告各节点流量昨日消耗情况" multiple="1"
+                                             :list="['邮箱' => 'mail', 'ServerChan' => 'serverChan', 'Telegram' => 'telegram', '微信企业' => 'weChat', 'TG酱' =>
                                              'tgChat', 'PushPlus' => 'pushPlus']"/>
-                    </x-system.tab-pane>
-                    <x-system.tab-pane id="other">
-                        <div class="col-12">
-                            @if($errors->any())
-                            <x-alert type="danger" :message="$errors->all()"/>
-                            @endif
-                            @if (Session::has('successMsg'))
-                            <x-alert type="success" :message="Session::get('successMsg')"/>
-                            @endif
-                        </div>
-                        <x-system.input title="首页LOGO" :value="$website_home_logo" code="website_home_logo" type="url"/>
-                        <x-system.input title="站内LOGO" :value="$website_logo" code="website_logo" type="url"/>
-                        <form action="{{route('admin.system.extend')}}" method="post" enctype="multipart/form-data" class="upload-form col-lg-12 row" role="form"
-                              id="setExtend">@csrf
-                            <x-system.input-file title="首页LOGO" code="website_home_logo" :value="$website_home_logo"/>
-                            <x-system.input-file title="站内LOGO" code="website_logo" :value="$website_logo"/>
-                        </form>
-                        <x-system.textarea title="统计代码" code="website_analytics" :value="$website_analytics" help="统计JS"/>
-                        <x-system.textarea title="客服代码" code="website_customer_service" :value="$website_customer_service" help="客服JS"/>
-                    </x-system.tab-pane>
-                    <div class="tab-pane" id="payment" role="tabpanel">
-                        <div class="tab-content pb-100">
-                            <x-system.tab-pane id="paymentSetting" :active="true">
-                                <x-system.select title="支付宝支付" code="is_AliPay"
-                                                 :list="['关闭' => '', 'F2F' => 'f2fpay', '码支付' => 'codepay', '易支付' => 'epay', '海狸支付' => 'paybeaver', '平头哥支付' => 'theadpay', 'Stripe支付宝' => 'stripe']"/>
-                                <x-system.select title="QQ钱包" code="is_QQPay" :list="['关闭' => '', '码支付' => 'codepay', '易支付' => 'epay']"/>
-                                <x-system.select title="微信支付" code="is_WeChatPay"
-                                                 :list="['关闭' => '', '码支付' => 'codepay', 'PayJS' => 'payjs', '易支付' => 'epay', '海狸支付' => 'paybeaver', 'Stripe微信' => 'stripe']"/>
-                                <x-system.select title="特殊支付" code="is_otherPay" multiple="1" :list="['麻瓜宝' => 'bitpayx', 'PayPal' => 'paypal', 'Stripe' => 'stripe']"/>
-                                <x-system.input title="自定义商品名称" :value="$subject_name" code="subject_name" help="用于在支付渠道的商品标题显示"/>
-                                <x-system.input title="通用支付回调地址" :value="$website_callback_url" code="website_callback_url"
-                                                help="防止因为网站域名被DNS投毒后导致支付无法正常回调,需带http://或https://" :holder="'默认为 '.$website_url" type="url"/>
-                            </x-system.tab-pane>
-                            <x-system.tab-pane id="AlipayF2F">
-                                <div class="form-group col-lg-6 d-flex">
-                                    <label class="col-md-3 col-form-label">支付宝F2F</label>
-                                    <div class="col-md-9">
-                                        本功能需要<a href="https://open.alipay.com/platform/appManage.htm?#/create/" target="_blank">蚂蚁金服开放平台</a>申请权限及应用
+                        </x-system.tab-pane>
+                        <x-system.tab-pane id="other">
+                            <div class="col-12">
+                                @if($errors->any())
+                                    <x-alert type="danger" :message="$errors->all()"/>
+                                @endif
+                                @if (Session::has('successMsg'))
+                                    <x-alert type="success" :message="Session::get('successMsg')"/>
+                                @endif
+                            </div>
+                            <x-system.input title="首页LOGO" :value="$website_home_logo" code="website_home_logo" type="url"/>
+                            <x-system.input title="站内LOGO" :value="$website_logo" code="website_logo" type="url"/>
+                            <form action="{{route('admin.system.extend')}}" method="post" enctype="multipart/form-data" class="upload-form col-lg-12 row" role="form"
+                                  id="setExtend">@csrf
+                                <x-system.input-file title="首页LOGO" code="website_home_logo" :value="$website_home_logo"/>
+                                <x-system.input-file title="站内LOGO" code="website_logo" :value="$website_logo"/>
+                            </form>
+                            <x-system.textarea title="统计代码" code="website_analytics" :value="$website_analytics" help="统计JS"/>
+                            <x-system.textarea title="客服代码" code="website_customer_service" :value="$website_customer_service" help="客服JS"/>
+                        </x-system.tab-pane>
+                        <div class="tab-pane" id="payment" role="tabpanel">
+                            <div class="tab-content pb-100">
+                                <x-system.tab-pane id="paymentSetting" :active="true">
+                                    <x-system.select title="支付宝支付" code="is_AliPay"
+                                                     :list="['关闭' => '', 'F2F' => 'f2fpay', '码支付' => 'codepay', '易支付' => 'epay', '海狸支付' => 'paybeaver', '平头哥支付' => 'theadpay', 'Stripe支付宝' => 'stripe']"/>
+                                    <x-system.select title="QQ钱包" code="is_QQPay" :list="['关闭' => '', '码支付' => 'codepay', '易支付' => 'epay']"/>
+                                    <x-system.select title="微信支付" code="is_WeChatPay"
+                                                     :list="['关闭' => '', '码支付' => 'codepay', 'PayJS' => 'payjs', '易支付' => 'epay', '海狸支付' => 'paybeaver', 'Stripe微信' => 'stripe']"/>
+                                    <x-system.select title="特殊支付" code="is_otherPay" multiple="1" :list="['麻瓜宝' => 'bitpayx', 'PayPal' => 'paypal', 'Stripe' => 'stripe']"/>
+                                    <x-system.input title="自定义商品名称" :value="$subject_name" code="subject_name" help="用于在支付渠道的商品标题显示"/>
+                                    <x-system.input title="通用支付回调地址" :value="$website_callback_url" code="website_callback_url"
+                                                    help="防止因为网站域名被DNS投毒后导致支付无法正常回调,需带http://或https://" :holder="'默认为 '.$website_url" type="url"/>
+                                </x-system.tab-pane>
+                                <x-system.tab-pane id="AlipayF2F">
+                                    <div class="form-group col-lg-6 d-flex">
+                                        <label class="col-md-3 col-form-label">支付宝F2F</label>
+                                        <div class="col-md-9">
+                                            本功能需要<a href="https://open.alipay.com/platform/appManage.htm?#/create/" target="_blank">蚂蚁金服开放平台</a>申请权限及应用
+                                        </div>
                                     </div>
-                                </div>
-                                <x-system.input title="应用ID" :value="$f2fpay_app_id" code="f2fpay_app_id" help="即:APPID"/>
-                                <x-system.input title="应用私钥" :value="$f2fpay_private_key" code="f2fpay_private_key" help="生成秘钥软件生成时,产生的应用秘钥"/>
-                                <x-system.input title="支付宝公钥" :value="$f2fpay_public_key" code="f2fpay_public_key" help="注意不是应用公钥!"/>
-                            </x-system.tab-pane>
-                            <x-system.tab-pane id="CodePay">
-                                <div class="form-group col-lg-6 d-flex">
-                                    <label class="col-md-3 col-form-label">码支付</label>
-                                    <div class="col-md-7">
-                                        请到 <a href="https://codepay.fateqq.com/i/377289" target="_blank">码支付</a>申请账号,然后下载登录其挂机软件
+                                    <x-system.input title="应用ID" :value="$f2fpay_app_id" code="f2fpay_app_id" help="即:APPID"/>
+                                    <x-system.input title="应用私钥" :value="$f2fpay_private_key" code="f2fpay_private_key" help="生成秘钥软件生成时,产生的应用秘钥"/>
+                                    <x-system.input title="支付宝公钥" :value="$f2fpay_public_key" code="f2fpay_public_key" help="注意不是应用公钥!"/>
+                                </x-system.tab-pane>
+                                <x-system.tab-pane id="CodePay">
+                                    <div class="form-group col-lg-6 d-flex">
+                                        <label class="col-md-3 col-form-label">码支付</label>
+                                        <div class="col-md-7">
+                                            请到 <a href="https://codepay.fateqq.com/i/377289" target="_blank">码支付</a>申请账号,然后下载登录其挂机软件
+                                        </div>
                                     </div>
-                                </div>
-                                <x-system.input title="请求URL" :value="$codepay_url" code="codepay_url" holder="https://codepay.fateqq.com/creat_order/?" type="url"/>
-                                <x-system.input title="码支付ID" :value="$codepay_id" code="codepay_id"/>
-                                <x-system.input title="通信密钥" :value="$codepay_key" code="codepay_key"/>
-                            </x-system.tab-pane>
-                            <x-system.tab-pane id="EPay">
-                                <div class="form-group col-lg-6 d-flex">
-                                    <label class="col-md-3 col-form-label">易支付</label>
-                                    @can('admin.test.epay')
-                                    <div class="col-md-7">
-                                        <button class="btn btn-primary" type="button" onclick="epayInfo()">查询</button>
+                                    <x-system.input title="请求URL" :value="$codepay_url" code="codepay_url" holder="https://codepay.fateqq.com/creat_order/?" type="url"/>
+                                    <x-system.input title="码支付ID" :value="$codepay_id" code="codepay_id"/>
+                                    <x-system.input title="通信密钥" :value="$codepay_key" code="codepay_key"/>
+                                </x-system.tab-pane>
+                                <x-system.tab-pane id="EPay">
+                                    <div class="form-group col-lg-6 d-flex">
+                                        <label class="col-md-3 col-form-label">易支付</label>
+                                        @can('admin.test.epay')
+                                            <div class="col-md-7">
+                                                <button class="btn btn-primary" type="button" onclick="epayInfo()">查询</button>
+                                            </div>
+                                        @endcan
                                     </div>
-                                    @endcan
-                                </div>
-                                <x-system.input title="接口对接地址" :value="$epay_url" code="epay_url" holder="https://www.example.com" type="url"/>
-                                <x-system.input title="商户ID" :value="$epay_mch_id" code="epay_mch_id"/>
-                                <x-system.input title="商户密钥" :value="$epay_key" code="epay_key"/>
-                            </x-system.tab-pane>
-                            <x-system.tab-pane id="PayJs">
-                                <div class="form-group col-lg-6 d-flex">
-                                    <label class="col-md-3 col-form-label">PayJs</label>
-                                    <div class="col-md-7">
-                                        请到<a href="https://payjs.cn/ref/zgxjnb" target="_blank">PayJs</a> 申请账号
+                                    <x-system.input title="接口对接地址" :value="$epay_url" code="epay_url" holder="https://www.example.com" type="url"/>
+                                    <x-system.input title="商户ID" :value="$epay_mch_id" code="epay_mch_id"/>
+                                    <x-system.input title="商户密钥" :value="$epay_key" code="epay_key"/>
+                                </x-system.tab-pane>
+                                <x-system.tab-pane id="PayJs">
+                                    <div class="form-group col-lg-6 d-flex">
+                                        <label class="col-md-3 col-form-label">PayJs</label>
+                                        <div class="col-md-7">
+                                            请到<a href="https://payjs.cn/ref/zgxjnb" target="_blank">PayJs</a> 申请账号
+                                        </div>
                                     </div>
-                                </div>
-                                <x-system.input title="商户号" :value="$payjs_mch_id" code="payjs_mch_id"
-                                                help='在<a href="https://payjs.cn/dashboard/member" target="_blank">本界面</a>获取信息'/>
-                                <x-system.input title="通信密钥" :value="$payjs_key" code="payjs_key"/>
-                            </x-system.tab-pane>
-                            <x-system.tab-pane id="PayPal">
-                                <div class="form-group col-lg-6 d-flex">
-                                    <label class="col-md-3 col-form-label">PayPal</label>
-                                    <div class="col-md-7">
-                                        使用商家账号登录<a href="https://www.paypal.com/businessprofile/mytools/apiaccess/firstparty" target="_blank">API凭证申请页</a>, 同意并获取设置信息
+                                    <x-system.input title="商户号" :value="$payjs_mch_id" code="payjs_mch_id"
+                                                    help='在<a href="https://payjs.cn/dashboard/member" target="_blank">本界面</a>获取信息'/>
+                                    <x-system.input title="通信密钥" :value="$payjs_key" code="payjs_key"/>
+                                </x-system.tab-pane>
+                                <x-system.tab-pane id="PayPal">
+                                    <div class="form-group col-lg-6 d-flex">
+                                        <label class="col-md-3 col-form-label">PayPal</label>
+                                        <div class="col-md-7">
+                                            使用商家账号登录<a href="https://www.paypal.com/businessprofile/mytools/apiaccess/firstparty" target="_blank">API凭证申请页</a>, 同意并获取设置信息
+                                        </div>
                                     </div>
-                                </div>
-                                <x-system.input title="API用户名" :value="$paypal_username" code="paypal_username"/>
-                                <x-system.input title="API密码" :value="$paypal_password" code="paypal_password"/>
-                                <x-system.input title="签名" :value="$paypal_secret" code="paypal_secret"/>
-                                {{--<x-system.input title="证书" :value="$paypal_certificate" code="paypal_certificate"/>--}}
-                                {{--<x-system.input title="应用ID" :value="$paypal_app_id" code="paypal_app_id"/>--}}
-                            </x-system.tab-pane>
-                            <x-system.tab-pane id="Stripe">
-                                <div class="form-group col-lg-6 d-flex">
-                                    <label class="col-md-3 col-form-label">Stripe</label>
-                                </div>
-                                <x-system.input title="Public Key" :value="$stripe_public_key" code="stripe_public_key"/>
-                                <x-system.input title="Secret Key" :value="$stripe_secret_key" code="stripe_secret_key"/>
-                                <x-system.input title="WebHook Signing secret" :value="$stripe_secret_key" code="stripe_signing_secret"/>
-                                <x-system.select title="货币" code="stripe_currency"
-                                                 :list="['HKD(港币)' => 'hkd', 'USD(美元)' => 'usd', 'SGD(新币)' => 'sgd', 'EUR(欧元)' => 'eur', 'GBP(英镑)' => 'gbp', 'JPY(日元)' => 'jpy', 'CAD(加元)' => 'cad']"/>
-                            </x-system.tab-pane>
-                            <x-system.tab-pane id="PayBeaver">
-                                <div class="form-group col-lg-6 d-flex">
-                                    <label class="col-md-3 col-form-label">海狸支付 PayBeaver</label>
-                                    <div class="col-md-7">
-                                        请到<a href="https://merchant.paybeaver.com/?aff_code=iK4GNuX8" target="_blank">海狸支付 PayBeaver</a>申请账号
+                                    <x-system.input title="API用户名" :value="$paypal_username" code="paypal_username"/>
+                                    <x-system.input title="API密码" :value="$paypal_password" code="paypal_password"/>
+                                    <x-system.input title="签名" :value="$paypal_secret" code="paypal_secret"/>
+                                    {{--<x-system.input title="证书" :value="$paypal_certificate" code="paypal_certificate"/>--}}
+                                    {{--<x-system.input title="应用ID" :value="$paypal_app_id" code="paypal_app_id"/>--}}
+                                </x-system.tab-pane>
+                                <x-system.tab-pane id="Stripe">
+                                    <div class="form-group col-lg-6 d-flex">
+                                        <label class="col-md-3 col-form-label">Stripe</label>
                                     </div>
-                                </div>
-                                <x-system.input title="App ID" :value="$paybeaver_app_id" code="paybeaver_app_id"
-                                                help='<a href="https://merchant.paybeaver.com/" target="_blank">商户中心</a> -&gt; 开发者 -&gt; App ID'/>
-                                <x-system.input title="App Secret" :value="$paybeaver_app_secret" code="paybeaver_app_secret"
-                                                help='<a href="https://merchant.paybeaver.com/" target="_blank">商户中心</a> -&gt; 开发者 -&gt; App Secret'/>
-                            </x-system.tab-pane>
-                            <x-system.tab-pane id="THeadPay">
-                                <div class="form-group col-lg-6 d-flex">
-                                    <label class="col-md-3 col-form-label">平头哥支付 THeadPay</label>
-                                    <div class="col-md-7">
-                                        请到<a href="https://theadpay.com/" target="_blank">平头哥支付 THeadPay</a>申请账号
+                                    <x-system.input title="Public Key" :value="$stripe_public_key" code="stripe_public_key"/>
+                                    <x-system.input title="Secret Key" :value="$stripe_secret_key" code="stripe_secret_key"/>
+                                    <x-system.input title="WebHook Signing secret" :value="$stripe_signing_secret" code="stripe_signing_secret"/>
+                                    <x-system.select title="货币" code="stripe_currency"
+                                                     :list="['HKD(港币)' => 'hkd', 'USD(美元)' => 'usd', 'SGD(新币)' => 'sgd', 'EUR(欧元)' => 'eur', 'GBP(英镑)' => 'gbp', 'JPY(日元)' => 'jpy', 'CAD(加元)' => 'cad']"/>
+                                </x-system.tab-pane>
+                                <x-system.tab-pane id="PayBeaver">
+                                    <div class="form-group col-lg-6 d-flex">
+                                        <label class="col-md-3 col-form-label">海狸支付 PayBeaver</label>
+                                        <div class="col-md-7">
+                                            请到<a href="https://merchant.paybeaver.com/?aff_code=iK4GNuX8" target="_blank">海狸支付 PayBeaver</a>申请账号
+                                        </div>
                                     </div>
-                                </div>
-                                <x-system.input title="接口地址" :value="$theadpay_url" code="theadpay_url" type="url"/>
-                                <x-system.input title="商家ID" :value="$theadpay_mchid" code="theadpay_mchid"/>
-                                <x-system.input title="商家密钥" :value="$theadpay_key" code="theadpay_key"/>
-                            </x-system.tab-pane>
-                            <x-system.tab-pane id="Manual">
-                                <div class="form-group col-lg-12 d-flex">
-                                    <label class="col-md-3 col-form-label">人工支付</label>
-                                    <div class="col-md-7">
-                                        设置后会自动开启对应显示
+                                    <x-system.input title="App ID" :value="$paybeaver_app_id" code="paybeaver_app_id"
+                                                    help='<a href="https://merchant.paybeaver.com/" target="_blank">商户中心</a> -&gt; 开发者 -&gt; App ID'/>
+                                    <x-system.input title="App Secret" :value="$paybeaver_app_secret" code="paybeaver_app_secret"
+                                                    help='<a href="https://merchant.paybeaver.com/" target="_blank">商户中心</a> -&gt; 开发者 -&gt; App Secret'/>
+                                </x-system.tab-pane>
+                                <x-system.tab-pane id="THeadPay">
+                                    <div class="form-group col-lg-6 d-flex">
+                                        <label class="col-md-3 col-form-label">平头哥支付 THeadPay</label>
+                                        <div class="col-md-7">
+                                            请到<a href="https://theadpay.com/" target="_blank">平头哥支付 THeadPay</a>申请账号
+                                        </div>
                                     </div>
-                                </div>
-                                <div class="col-12">
-                                    @if($errors->any())
-                                    <x-alert type="danger" :message="$errors->all()"/>
-                                    @endif
-                                    @if (Session::has('successMsg'))
-                                    <x-alert type="success" :message="Session::get('successMsg')"/>
-                                    @endif
-                                </div>
-                                <x-system.input title="支付宝二维码" :value="$alipay_qrcode" code="alipay_qrcode" type="url"/>
-                                <x-system.input title="微 信二维码" :value="$wechat_qrcode" code="wechat_qrcode" type="url"/>
-                                <form action="{{route('admin.system.extend')}}" method="post" enctype="multipart/form-data" class="upload-form col-lg-12 row" role="form"
-                                      id="setExtend">@csrf
-                                    <x-system.input-file title="支付宝二维码" code="alipay_qrcode" :value="$alipay_qrcode"/>
-                                    <x-system.input-file title="微 信二维码" code="wechat_qrcode" :value="$wechat_qrcode"/>
-                                </form>
-                            </x-system.tab-pane>
+                                    <x-system.input title="接口地址" :value="$theadpay_url" code="theadpay_url" type="url"/>
+                                    <x-system.input title="商家ID" :value="$theadpay_mchid" code="theadpay_mchid"/>
+                                    <x-system.input title="商家密钥" :value="$theadpay_key" code="theadpay_key"/>
+                                </x-system.tab-pane>
+                                <x-system.tab-pane id="Manual">
+                                    <div class="form-group col-lg-12 d-flex">
+                                        <label class="col-md-3 col-form-label">人工支付</label>
+                                        <div class="col-md-7">
+                                            设置后会自动开启对应显示
+                                        </div>
+                                    </div>
+                                    <div class="col-12">
+                                        @if($errors->any())
+                                            <x-alert type="danger" :message="$errors->all()"/>
+                                        @endif
+                                        @if (Session::has('successMsg'))
+                                            <x-alert type="success" :message="Session::get('successMsg')"/>
+                                        @endif
+                                    </div>
+                                    <x-system.input title="支付宝二维码" :value="$alipay_qrcode" code="alipay_qrcode" type="url"/>
+                                    <x-system.input title="微 信二维码" :value="$wechat_qrcode" code="wechat_qrcode" type="url"/>
+                                    <form action="{{route('admin.system.extend')}}" method="post" enctype="multipart/form-data" class="upload-form col-lg-12 row" role="form"
+                                          id="setExtend">@csrf
+                                        <x-system.input-file title="支付宝二维码" code="alipay_qrcode" :value="$alipay_qrcode"/>
+                                        <x-system.input-file title="微 信二维码" code="wechat_qrcode" :value="$wechat_qrcode"/>
+                                    </form>
+                                </x-system.tab-pane>
+                            </div>
+                            <ul class="nav nav-tabs nav-tabs-bottom nav-tabs-line dropup" role="tablist">
+                                <li class="nav-item">
+                                    <a class="nav-link active" data-toggle="tab" href="#paymentSetting" aria-controls="paymentSetting" role="tab">支付设置</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#AlipayF2F" aria-controls="AlipayF2F" role="tab">支付宝F2F</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#CodePay" aria-controls="CodePay" role="tab">码支付</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#EPay" aria-controls="EPay" role="tab">易支付</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#PayJs" aria-controls="PayJs" role="tab">PayJs</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#PayPal" aria-controls="PayPal" role="tab">PayPal</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#Stripe" aria-controls="Stripe" role="tab">Stripe</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#PayBeaver" aria-controls="PayBeaver" role="tab">PayBeaver</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#THeadPay" aria-controls="THeadPay" role="tab">平头哥支付</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a class="nav-link" data-toggle="tab" href="#Manual" aria-controls="Manual" role="tab">人工支付</a>
+                                </li>
+                                <li class="nav-item dropdown" style="display: none;">
+                                    <a class="dropdown-toggle nav-link" data-toggle="dropdown" href="#" aria-expanded="false" aria-haspopup="true">菜单</a>
+                                    <div class="dropdown-menu" role="menu">
+                                        <a class="dropdown-item active" data-toggle="tab" href="#paymentSetting" aria-controls="paymentSetting" role="tab">支付设置</a>
+                                        <a class="dropdown-item" data-toggle="tab" href="#AlipayF2F" aria-controls="AlipayF2F" role="tab">支付宝F2F</a>
+                                        <a class="dropdown-item" data-toggle="tab" href="#CodePay" aria-controls="CodePay" role="tab">码支付</a>
+                                        <a class="dropdown-item" data-toggle="tab" href="#EPay" aria-controls="EPay" role="tab">易支付</a>
+                                        <a class="dropdown-item" data-toggle="tab" href="#PayJs" aria-controls="PayJs" role="tab">PayJs</a>
+                                        <a class="dropdown-item" data-toggle="tab" href="#PayPal" aria-controls="PayPal" role="tab">PayPal</a>
+                                        <a class="dropdown-item" data-toggle="tab" href="#Stripe" aria-controls="Stripe" role="tab">Stripe</a>
+                                        <a class="dropdown-item" data-toggle="tab" href="#PayBeaver" aria-controls="PayBeaver" role="tab">PayBeaver</a>
+                                        <a class="dropdown-item" data-toggle="tab" href="#THeadPay" aria-controls="THeadPay" role="tab">平头哥支付</a>
+                                        <a class="dropdown-item" data-toggle="tab" href="#Manual" aria-controls="Manual" role="tab">人工支付</a>
+                                    </div>
+                                </li>
+                            </ul>
                         </div>
-                        <ul class="nav nav-tabs nav-tabs-bottom nav-tabs-line dropup" role="tablist">
-                            <li class="nav-item">
-                                <a class="nav-link active" data-toggle="tab" href="#paymentSetting" aria-controls="paymentSetting" role="tab">支付设置</a>
-                            </li>
-                            <li class="nav-item">
-                                <a class="nav-link" data-toggle="tab" href="#AlipayF2F" aria-controls="AlipayF2F" role="tab">支付宝F2F</a>
-                            </li>
-                            <li class="nav-item">
-                                <a class="nav-link" data-toggle="tab" href="#CodePay" aria-controls="CodePay" role="tab">码支付</a>
-                            </li>
-                            <li class="nav-item">
-                                <a class="nav-link" data-toggle="tab" href="#EPay" aria-controls="EPay" role="tab">易支付</a>
-                            </li>
-                            <li class="nav-item">
-                                <a class="nav-link" data-toggle="tab" href="#PayJs" aria-controls="PayJs" role="tab">PayJs</a>
-                            </li>
-                            <li class="nav-item">
-                                <a class="nav-link" data-toggle="tab" href="#PayPal" aria-controls="PayPal" role="tab">PayPal</a>
-                            </li>
-                            <li class="nav-item">
-                                <a class="nav-link" data-toggle="tab" href="#Stripe" aria-controls="Stripe" role="tab">Stripe</a>
-                            </li>
-                            <li class="nav-item">
-                                <a class="nav-link" data-toggle="tab" href="#PayBeaver" aria-controls="PayBeaver" role="tab">PayBeaver</a>
-                            </li>
-                            <li class="nav-item">
-                                <a class="nav-link" data-toggle="tab" href="#THeadPay" aria-controls="THeadPay" role="tab">平头哥支付</a>
-                            </li>
-                            <li class="nav-item">
-                                <a class="nav-link" data-toggle="tab" href="#Manual" aria-controls="Manual" role="tab">人工支付</a>
-                            </li>
-                            <li class="nav-item dropdown" style="display: none;">
-                                <a class="dropdown-toggle nav-link" data-toggle="dropdown" href="#" aria-expanded="false" aria-haspopup="true">菜单</a>
-                                <div class="dropdown-menu" role="menu">
-                                    <a class="dropdown-item active" data-toggle="tab" href="#paymentSetting" aria-controls="paymentSetting" role="tab">支付设置</a>
-                                    <a class="dropdown-item" data-toggle="tab" href="#AlipayF2F" aria-controls="AlipayF2F" role="tab">支付宝F2F</a>
-                                    <a class="dropdown-item" data-toggle="tab" href="#CodePay" aria-controls="CodePay" role="tab">码支付</a>
-                                    <a class="dropdown-item" data-toggle="tab" href="#EPay" aria-controls="EPay" role="tab">易支付</a>
-                                    <a class="dropdown-item" data-toggle="tab" href="#PayJs" aria-controls="PayJs" role="tab">PayJs</a>
-                                    <a class="dropdown-item" data-toggle="tab" href="#PayPal" aria-controls="PayPal" role="tab">PayPal</a>
-                                    <a class="dropdown-item" data-toggle="tab" href="#Stripe" aria-controls="Stripe" role="tab">Stripe</a>
-                                    <a class="dropdown-item" data-toggle="tab" href="#PayBeaver" aria-controls="PayBeaver" role="tab">PayBeaver</a>
-                                    <a class="dropdown-item" data-toggle="tab" href="#THeadPay" aria-controls="THeadPay" role="tab">平头哥支付</a>
-                                    <a class="dropdown-item" data-toggle="tab" href="#Manual" aria-controls="Manual" role="tab">人工支付</a>
-                                </div>
-                            </li>
-                        </ul>
                     </div>
                 </div>
             </div>
         </div>
     </div>
-</div>
 @endsection
 @section('javascript')
-<script src="/assets/global/vendor/bootstrap-select/bootstrap-select.min.js"></script>
-<script src="/assets/global/vendor/switchery/switchery.min.js"></script>
-<script src="/assets/global/vendor/dropify/dropify.min.js"></script>
-<script src="/assets/global/js/Plugin/bootstrap-select.js"></script>
-<script src="/assets/global/js/Plugin/switchery.js"></script>
-<script src="/assets/global/js/Plugin/responsive-tabs.js"></script>
-<script src="/assets/global/js/Plugin/tabs.js"></script>
-<script src="/assets/custom/jump-tab.js"></script>
-<script src="/assets/global/js/Plugin/dropify.js"></script>
-<script>
-    $(document).ready(function() {
-        $('#forbid_mode').selectpicker('val', '{{$forbid_mode}}');
-        $('#username_type').selectpicker('val', '{{$username_type ?? 'email'}}');
-        $('#is_invite_register').selectpicker('val', '{{$is_invite_register}}');
-        $('#is_activate_account').selectpicker('val', '{{$is_activate_account}}');
-        $('#ddns_mode').selectpicker('val', '{{$ddns_mode}}');
-        $('#is_captcha').selectpicker('val', '{{$is_captcha}}');
-        $('#referral_type').selectpicker('val', '{{$referral_type}}');
-        $('#is_email_filtering').selectpicker('val', '{{$is_email_filtering}}');
-        $('#is_AliPay').selectpicker('val', '{{$is_AliPay}}');
-        $('#is_QQPay').selectpicker('val', '{{$is_QQPay}}');
-        $('#is_WeChatPay').selectpicker('val', '{{$is_WeChatPay}}');
-        $('#is_otherPay').selectpicker('val', {!! $is_otherPay !!});
-        $('#oauth_path').selectpicker('val', {!! $oauth_path !!});
-        $('#account_expire_notification').selectpicker('val', {!! $account_expire_notification !!});
-        $('#data_anomaly_notification').selectpicker('val', {!! $data_anomaly_notification !!});
-        $('#data_exhaust_notification').selectpicker('val', {!! $data_exhaust_notification !!});
-        $('#node_blocked_notification').selectpicker('val', {!! $node_blocked_notification !!});
-        $('#node_daily_notification').selectpicker('val', {!! $node_daily_notification !!});
-        $('#node_offline_notification').selectpicker('val', {!! $node_offline_notification !!});
-        $('#password_reset_notification').selectpicker('val', '{{$password_reset_notification}}');
-        $('#payment_confirm_notification').selectpicker('val', '{{$payment_confirm_notification}}');
-        $('#payment_received_notification').selectpicker('val', {!! $payment_received_notification !!});
-        $('#ticket_closed_notification').selectpicker('val', {!! $ticket_closed_notification !!});
-        $('#ticket_created_notification').selectpicker('val', {!! $ticket_created_notification !!});
-        $('#ticket_replied_notification').selectpicker('val', {!! $ticket_replied_notification !!});
-
-        // Get all options within select
-        disablePayment(document.getElementById('is_AliPay').getElementsByTagName('option'));
-        disablePayment(document.getElementById('is_QQPay').getElementsByTagName('option'));
-        disablePayment(document.getElementById('is_WeChatPay').getElementsByTagName('option'));
-        disablePayment(document.getElementById('is_otherPay').getElementsByTagName('option'));
+    <script src="/assets/global/vendor/bootstrap-select/bootstrap-select.min.js"></script>
+    <script src="/assets/global/vendor/switchery/switchery.min.js"></script>
+    <script src="/assets/global/vendor/dropify/dropify.min.js"></script>
+    <script src="/assets/global/js/Plugin/bootstrap-select.js"></script>
+    <script src="/assets/global/js/Plugin/switchery.js"></script>
+    <script src="/assets/global/js/Plugin/responsive-tabs.js"></script>
+    <script src="/assets/global/js/Plugin/tabs.js"></script>
+    <script src="/assets/custom/jump-tab.js"></script>
+    <script src="/assets/global/js/Plugin/dropify.js"></script>
+    <script>
+        $(document).ready(function() {
+            $('#forbid_mode').selectpicker('val', '{{$forbid_mode}}');
+            $('#username_type').selectpicker('val', '{{$username_type ?? 'email'}}');
+            $('#is_invite_register').selectpicker('val', '{{$is_invite_register}}');
+            $('#is_activate_account').selectpicker('val', '{{$is_activate_account}}');
+            $('#ddns_mode').selectpicker('val', '{{$ddns_mode}}');
+            $('#is_captcha').selectpicker('val', '{{$is_captcha}}');
+            $('#referral_type').selectpicker('val', '{{$referral_type}}');
+            $('#is_email_filtering').selectpicker('val', '{{$is_email_filtering}}');
+            $('#is_AliPay').selectpicker('val', '{{$is_AliPay}}');
+            $('#is_QQPay').selectpicker('val', '{{$is_QQPay}}');
+            $('#is_WeChatPay').selectpicker('val', '{{$is_WeChatPay}}');
+            $('#is_otherPay').selectpicker('val', {!! $is_otherPay !!});
+            $('#oauth_path').selectpicker('val', {!! $oauth_path !!});
+            $('#account_expire_notification').selectpicker('val', {!! $account_expire_notification !!});
+            $('#data_anomaly_notification').selectpicker('val', {!! $data_anomaly_notification !!});
+            $('#data_exhaust_notification').selectpicker('val', {!! $data_exhaust_notification !!});
+            $('#node_blocked_notification').selectpicker('val', {!! $node_blocked_notification !!});
+            $('#node_daily_notification').selectpicker('val', {!! $node_daily_notification !!});
+            $('#node_offline_notification').selectpicker('val', {!! $node_offline_notification !!});
+            $('#password_reset_notification').selectpicker('val', '{{$password_reset_notification}}');
+            $('#payment_confirm_notification').selectpicker('val', '{{$payment_confirm_notification}}');
+            $('#payment_received_notification').selectpicker('val', {!! $payment_received_notification !!});
+            $('#ticket_closed_notification').selectpicker('val', {!! $ticket_closed_notification !!});
+            $('#ticket_created_notification').selectpicker('val', {!! $ticket_created_notification !!});
+            $('#ticket_replied_notification').selectpicker('val', {!! $ticket_replied_notification !!});
 
-    @if (!$captcha)
-        disableCaptcha(document.getElementById('is_captcha').getElementsByTagName('option'));
-    @endif
+            // Get all options within select
+            disablePayment(document.getElementById('is_AliPay').getElementsByTagName('option'));
+            disablePayment(document.getElementById('is_QQPay').getElementsByTagName('option'));
+            disablePayment(document.getElementById('is_WeChatPay').getElementsByTagName('option'));
+            disablePayment(document.getElementById('is_otherPay').getElementsByTagName('option'));
 
-    });
+            @if (!$captcha)
+            disableCaptcha(document.getElementById('is_captcha').getElementsByTagName('option'));
+            @endif
 
-    function disablePayment(op) {
-        for (let i = 1; i < op.length; i++) {
-        @json($payments).
-        includes(op[i].value)
-                ? op[i].disabled = false
-                : op[i].disabled = true;
-        }
-    }
+        });
 
-    function disableCaptcha(op) {
-        for (let i = 2; i < op.length; i++) {
-            op[i].disabled = true;
+        function disablePayment(op) {
+            for (let i = 1; i < op.length; i++) {
+                @json($payments).
+                includes(op[i].value)
+                    ? op[i].disabled = false
+                    : op[i].disabled = true;
+            }
         }
-    }
 
-    // 系统设置更新
-    function systemUpdate(systemItem, value) {
-    @can('admin.system.update')
-        $.post('{{route('admin.system.update')}}', {_token: '{{csrf_token()}}', name: systemItem, value: value}, function(ret) {
-            if (ret.status === 'success') {
-                swal.fire({title: ret.message, icon: 'success', timer: 1500, showConfirmButton: false});
-            } else {
-                swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload());
+        function disableCaptcha(op) {
+            for (let i = 2; i < op.length; i++) {
+                op[i].disabled = true;
             }
-        });
-    @else
-        swal.fire({title: '您没有权限修改系统参数!', icon: 'error', timer: 1500, showConfirmButton: false});
-    @endcan
-    }
-
-    // 正常input更新
-    function update(systemItem) {
-        systemUpdate(systemItem, $('#' + systemItem).val());
-    }
+        }
 
-    // 需要检查限制的更新
-    function updateFromInput(systemItem, lowerBound = false, upperBound = false) {
-        let value = parseInt($('#' + systemItem).val());
-        if (lowerBound !== false && value < lowerBound) {
-            swal.fire({title: '不能小于' + lowerBound, icon: 'warning', timer: 1500, showConfirmButton: false});
-        } else if (upperBound !== false && value > upperBound) {
-            swal.fire({title: '不能大于' + upperBound, icon: 'warning', timer: 1500, showConfirmButton: false});
-        } else {
-            systemUpdate(systemItem, value);
+        // 系统设置更新
+        function systemUpdate(systemItem, value) {
+            @can('admin.system.update')
+            $.post('{{route('admin.system.update')}}', {_token: '{{csrf_token()}}', name: systemItem, value: value}, function(ret) {
+                if (ret.status === 'success') {
+                    swal.fire({title: ret.message, icon: 'success', timer: 1500, showConfirmButton: false});
+                } else {
+                    swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload());
+                }
+            });
+            @else
+            swal.fire({title: '您没有权限修改系统参数!', icon: 'error', timer: 1500, showConfirmButton: false});
+            @endcan
         }
-    }
 
-    // 其他项更新选择
-    function updateFromOther(inputType, systemItem) {
-        let input = $('#' + systemItem);
-        switch (inputType) {
-            case 'select':
-                input.on('changed.bs.select', function() {
-                    systemUpdate(systemItem, $(this).val());
-                });
-                break;
-            case 'multiSelect':
-                input.on('changed.bs.select', function() {
-                    systemUpdate(systemItem, $(this).val().join(','));
-                });
-                break;
-            case 'switch':
-                systemUpdate(systemItem, document.getElementById(systemItem).checked ? 1 : 0);
-                break;
-            default:
-                break;
+        // 正常input更新
+        function update(systemItem) {
+            systemUpdate(systemItem, $('#' + systemItem).val());
         }
-    }
 
-    // 使用通知渠道 发送测试消息
-    @can('admin.test.notify')
-    function sendTestNotification(channel) {
-        $.post('{{route('admin.test.notify')}}', {_token: '{{csrf_token()}}', channel: channel}, function(ret) {
-            if (ret.status === 'success') {
-                swal.fire({title: ret.message, icon: 'success', timer: 1500, showConfirmButton: false});
+        // 需要检查限制的更新
+        function updateFromInput(systemItem, lowerBound = false, upperBound = false) {
+            let value = parseInt($('#' + systemItem).val());
+            if (lowerBound !== false && value < lowerBound) {
+                swal.fire({title: '不能小于' + lowerBound, icon: 'warning', timer: 1500, showConfirmButton: false});
+            } else if (upperBound !== false && value > upperBound) {
+                swal.fire({title: '不能大于' + upperBound, icon: 'warning', timer: 1500, showConfirmButton: false});
             } else {
-                swal.fire({title: ret.message, icon: 'error'});
+                systemUpdate(systemItem, value);
             }
-        });
-    }
-    @endcan
-
-    // 生成网站安全码
-    function makeWebsiteSecurityCode() {
-        $.get('{{route('createStr')}}', function(ret) {
-            $('#website_security_code').val(ret);
-        });
-    }
+        }
 
-    @can('admin.test.epay')
-    function epayInfo() {
-        $.get('{{route('admin.test.epay')}}', function(ret) {
-            if (ret.status === 'success') {
-                swal.fire({
-                    title: '易支付信息(仅供参考)',
-                    html: '商户状态: ' + ret.data['active'] + ' | 账号余额: ' + ret.data['money'] + ' | 结算账号:' + ret.data['account'] +
-                        '<br\><br\>渠道手续费:【支付宝 - ' + (100 - ret.data['alirate']) + '% | 微信 - ' + (100 - ret.data['wxrate']) +
-                        '% | QQ钱包 - ' + (100 - ret.data['qqrate']) + '%】<br\><br\> 请按照支付平台的介绍为准,本信息纯粹为Api获取信息',
-                    icon: 'info',
-                });
-            } else {
-                swal.fire({title: ret.message, icon: 'error'});
+        // 其他项更新选择
+        function updateFromOther(inputType, systemItem) {
+            let input = $('#' + systemItem);
+            switch (inputType) {
+                case 'select':
+                    input.on('changed.bs.select', function() {
+                        systemUpdate(systemItem, $(this).val());
+                    });
+                    break;
+                case 'multiSelect':
+                    input.on('changed.bs.select', function() {
+                        systemUpdate(systemItem, $(this).val().join(','));
+                    });
+                    break;
+                case 'switch':
+                    systemUpdate(systemItem, document.getElementById(systemItem).checked ? 1 : 0);
+                    break;
+                default:
+                    break;
             }
-        });
-    }
-    @endcan
-</script>
+        }
+
+        // 使用通知渠道 发送测试消息
+        @can('admin.test.notify')
+        function sendTestNotification(channel) {
+            $.post('{{route('admin.test.notify')}}', {_token: '{{csrf_token()}}', channel: channel}, function(ret) {
+                if (ret.status === 'success') {
+                    swal.fire({title: ret.message, icon: 'success', timer: 1500, showConfirmButton: false});
+                } else {
+                    swal.fire({title: ret.message, icon: 'error'});
+                }
+            });
+        }
+        @endcan
+
+        // 生成网站安全码
+        function makeWebsiteSecurityCode() {
+            $.get('{{route('createStr')}}', function(ret) {
+                $('#website_security_code').val(ret);
+            });
+        }
+
+        @can('admin.test.epay')
+        function epayInfo() {
+            $.get('{{route('admin.test.epay')}}', function(ret) {
+                if (ret.status === 'success') {
+                    swal.fire({
+                        title: '易支付信息(仅供参考)',
+                        html: '商户状态: ' + ret.data['active'] + ' | 账号余额: ' + ret.data['money'] + ' | 结算账号:' + ret.data['account'] +
+                            '<br\><br\>渠道手续费:【支付宝 - ' + (100 - ret.data['alirate']) + '% | 微信 - ' + (100 - ret.data['wxrate']) +
+                            '% | QQ钱包 - ' + (100 - ret.data['qqrate']) + '%】<br\><br\> 请按照支付平台的介绍为准,本信息纯粹为Api获取信息',
+                        icon: 'info',
+                    });
+                } else {
+                    swal.fire({title: ret.message, icon: 'error'});
+                }
+            });
+        }
+        @endcan
+    </script>
 @endsection

+ 29 - 17
resources/views/admin/node/index.blade.php

@@ -36,14 +36,14 @@
                         <th> ID</th>
                         <th> 类型</th>
                         <th> 名称</th>
-                        <th> IP</th>
                         <th> 域名</th>
+                        <th> IP</th>
                         <th> 存活</th>
-                        <th> {{trans('common.status')}}</th>
                         <th> 在线</th>
                         <th> 产生流量</th>
                         <th> 流量比例</th>
                         <th> 扩展</th>
+                        <th> {{trans('common.status')}}</th>
                         <th> {{trans('common.action')}}</th>
                     </tr>
                     </thead>
@@ -53,25 +53,37 @@
                             <td> {{$node->id}} </td>
                             <td> {{$node->type_label}} </td>
                             <td> {{$node->name}} </td>
-                            <td> {{$node->is_ddns ? 'DDNS' : $node->ip}} </td>
                             <td> {{$node->server}} </td>
-                            <td> {{$node->uptime}} </td>
+                            <td> {{$node->is_ddns ? 'DDNS' : $node->ip}} </td>
+                            <td> {{$node->uptime ?: '-'}} </td>
+                            <td> {{$node->online_users ?: '-'}} </td>
+                            <td> {{$node->transfer}} </td>
+                            <td> {{$node->traffic_rate}} </td>
                             <td>
-                                @if(!$node->isOnline)
-                                    <i class="red-600 icon wb-warning" aria-hidden="true"></i>
-                                @elseif (!$node->status)
-                                    <i class="yellow-600 icon wb-warning" aria-hidden="true"></i>
+                                @if(isset($node->profile['passwd']))
+                                    <span class="badge badge-lg badge-info"><i class="icon fas fa-stream"></i>单</span>
+                                @endif
+                                @if($node->relay_node_id)
+                                    <span class="badge badge-lg badge-info"><i class="icon fas fa-ethernet"></i>转</span>
+                                @endif
+                                @if(!$node->is_subscribe)
+                                    <span class="badge badge-lg badge-danger"><i class="icon fas fa-rss"></i><del>订</del></span>
                                 @endif
-                                {{$node->status? $node->load : '维护'}}
                             </td>
-                            <td> {{$node->online_users}} </td>
-                            <td> {{$node->transfer}} </td>
-                            <td> {{$node->traffic_rate}} </td>
                             <td>
-                                @if($node->compatible) <span class="badge badge-lg badge-info">兼</span> @endif
-                                @if($node->single) <span class="badge badge-lg badge-info">单</span> @endif
-                                @if($node->is_relay) <span class="badge badge-lg badge-info">中转</span> @endif
-                                @if(!$node->is_subscribe) <span class="badge badge-lg badge-danger"><del>订</del></span> @endif
+                                @if($node->isOnline)
+                                    @if ($node->status)
+                                        {{$node->load}}
+                                    @else
+                                        <i class="yellow-700 icon icon-spin fas fa-cog" aria-hidden="true"></i>
+                                    @endif
+                                @else
+                                    @if ($node->status)
+                                        <i class="red-600 icon fas fa-cog" aria-hidden="true"></i>
+                                    @else
+                                        <i class="red-600 icon fas fa-handshake-slash" aria-hidden="true"></i>
+                                    @endif
+                                @endif
                             </td>
                             <td>
                                 @canany(['admin.node.edit', 'admin.node.destroy', 'admin.node.monitor', 'admin.node.geo', 'admin.node.ping', 'admin.node.check', 'admin.node.reload'])
@@ -85,7 +97,7 @@
                                             </a>
                                         @endcan
                                         @can('admin.node.destroy')
-                                            <a class="dropdown-item" href="javascript:delNode('{{$node->id}}', '{{$node->name}}')" role="menuitem">
+                                            <a class="dropdown-item red-700" href="javascript:delNode('{{$node->id}}', '{{$node->name}}')" role="menuitem">
                                                 <i class="icon wb-trash" aria-hidden="true"></i> 删除
                                             </a>
                                         @endcan

+ 51 - 78
resources/views/admin/node/info.blade.php

@@ -12,7 +12,11 @@
     <div class="page-content container-fluid">
         <div class="panel">
             <div class="panel-heading">
-                <h2 class="panel-title">@isset($node) 编辑节点 @else 添加节点 @endisset</h2>
+                <h2 class="panel-title">@isset($node)
+                        编辑节点
+                    @else
+                        添加节点
+                    @endisset</h2>
             </div>
             <div class="alert alert-info" role="alert">
                 <button class="close" data-dismiss="alert" aria-label="Close">
@@ -58,7 +62,7 @@
                                     </div>
                                     <div class="form-group row">
                                         <label for="push_port" class="col-md-3 col-form-label"> 消息推送端口 </label>
-                                        <input type="number" class="form-control col-md-4" name="push_port" value="0" id="push_port">
+                                        <input type="number" class="form-control col-md-4" name="push_port" value="1080" id="push_port">
                                         <span class="text-help offset-md-3">必填且防火墙需放行,否则将导致消息推送异常</span>
                                     </div>
                                     <div class="form-group row">
@@ -215,11 +219,8 @@
                                                           placeholder="混淆不为 [plain] 时可填入参数进行流量伪装;&#13;&#10;混淆为 [http_simple] 时,建议端口为 80;&#13;&#10;混淆为 [tls] 时,建议端口为 443;"></textarea>
                                             </div>
                                             <div class="form-group row">
-                                                <label for="compatible" class="col-md-3 col-form-label">兼容SS</label>
-                                                <div class="col-md-9">
-                                                    <input type="checkbox" id="compatible" name="compatible" data-plugin="switchery">
-                                                </div>
-                                                <div class="text-help offset-md-3">
+                                                <label class="col-md-3 col-form-label">*兼容 SS</label>
+                                                <div class="text-help col-md-9">
                                                     如果兼容请在服务端配置协议和混淆时加上<span class="red-700">_compatible</span>
                                                 </div>
                                             </div>
@@ -372,20 +373,14 @@
                                         <div class="text-help offset-md-3"> 每30~60分钟随机进行节点阻断检测</div>
                                     </div>
                                     <div class="form-group row">
-                                        <label for="is_relay" class="col-md-3 col-form-label">中转</label>
-                                        <div class="col-md-9">
-                                            <input type="checkbox" id="is_relay" name="is_relay" data-plugin="switchery" onchange="switchSetting('is_relay')">
-                                        </div>
-                                    </div>
-                                    <div class="relay-setting">
-                                        <div class="form-group row">
-                                            <label for="relay_port" class="col-md-3 col-form-label"> 中转端口 </label>
-                                            <input type="number" class="form-control col-md-4" name="relay_port" id="relay_port" value="443">
-                                        </div>
-                                        <div class="form-group row">
-                                            <label for="relay_server" class="col-md-3 col-form-label"> 中转地址 </label>
-                                            <input type="text" class="form-control col-md-4" name="relay_server" id="relay_server">
-                                        </div>
+                                        <label for="relay_node_id" class="col-md-3 col-form-label">中转</label>
+                                        <select data-plugin="selectpicker" data-style="btn-outline btn-primary" class="col-md-5 form-control show-tick"
+                                                id="relay_node_id" name="relay_node_id">
+                                            <option value="">不使用</option>
+                                            @foreach($nodes as $name => $id)
+                                                <option value="{{$id}}">{{$id}} - {{$name}}</option>
+                                            @endforeach
+                                        </select>
                                     </div>
                                 </div>
                             </div>
@@ -412,7 +407,6 @@
         $(document).ready(function() {
             let v2_path = $('#v2_path');
             switchSetting('single');
-            switchSetting('is_relay');
             switchSetting('is_ddns');
             @isset($node)
 
@@ -431,6 +425,7 @@
             $('#client_limit').val('{{$node->client_limit}}');
             $('#labels').selectpicker('val', {{$node->labels->pluck('id')}});
             $('#country_code').selectpicker('val', '{{$node->country_code}}');
+            $('#relay_node_id').selectpicker('val', '{{$node->relay_node_id}}');
             $('#description').val('{{$node->description}}');
             $('#sort').val('{{$node->sort}}');
             @if($node->is_udp)
@@ -443,53 +438,46 @@
             $('#is_subscribe').click();
             @endif
             $("input[name='detection_type'][value='{{$node->detection_type}}']").click();
-            @if($node->single)
+            @if($node->profile['passwd'] && $node->port)
             $('#single').click();
+            $('#passwd').val('{{$node->profile['passwd']}}');
             @endif
             $('input[name = port]').val('{{$node->port}}');
-            $('#passwd').val('{{$node->passwd}}');
             $("input[name='type'][value='{{$node->type}}']").click();
 
-            switch ({{$node->type}}) {
-                case 1:
-                case 4:
-                    @if ($node->compatible)
-                    $('#compatible').click();
-                    @endif
-                    $('#protocol').selectpicker('val', '{{$node->protocol}}');
-                    $('#protocol_param').val('{{$node->protocol_param}}');
-                    $('#obfs').selectpicker('val', '{{$node->obfs}}');
-                    $('#obfs_param').val('{{$node->obfs_param}}');
-                case 0:
-                    $('#method').selectpicker('val', '{{$node->method}}');
-                    break;
-                case 2:
-                    //V2Ray
-                    $('#v2_alter_id').val('{{$node->v2_alter_id}}');
-                    $('#v2_method').selectpicker('val', '{{$node->v2_method}}');
-                    $('#v2_net').selectpicker('val', '{{$node->v2_net}}');
-                    $('#v2_type').selectpicker('val', '{{$node->v2_type}}');
-                    $('#v2_host').val('{{$node->v2_host}}');
-                    $('#v2_port').val('{{$node->port}}');
-                    $('#v2_sni').val('{{$node->v2_sni}}');
-                    v2_path.val('{{$node->v2_path}}');
-                    @if($node->v2_tls)
-                    $('#v2_tls').click();
-                    @endif
-                    $('#tls_provider').val('{!! $node->tls_provider !!}');
-                    break;
-                case 3:
-                    $('#trojan_port').val('{{$node->port}}');
-                    break;
-                default:
-            }
+            @switch($node->type)
+            @case(1)
+            @case(4)
+            $('#protocol').selectpicker('val', '{{$node->profile['protocol']}}');
+            $('#protocol_param').val('{{$node->profile['protocol_param']}}');
+            $('#obfs').selectpicker('val', '{{$node->profile['obfs']}}');
+            $('#obfs_param').val('{{$node->profile['obfs_param']}}');
+            @case(0)
+            $('#method').selectpicker('val', '{{$node->profile['method']}}');
+            @break
 
-            @if($node->is_relay)
-            // 中转
-            $('#is_relay').click();
-            $('#relay_port').val('{{$node->relay_port}}');
-            $('#relay_server').val('{{$node->relay_server}}');
+            @case(2)
+            //V2Ray
+            $('#v2_alter_id').val('{{$node->profile['v2_alter_id']}}');
+            $('#v2_method').selectpicker('val', '{{$node->profile['v2_method']}}');
+            $('#v2_net').selectpicker('val', '{{$node->profile['v2_net']}}');
+            $('#v2_type').selectpicker('val', '{{$node->profile['v2_type']}}');
+            $('#v2_host').val('{{$node->profile['v2_host']}}');
+            $('#v2_port').val('{{$node->port}}');
+            $('#v2_sni').val('{{$node->profile['v2_sni']}}');
+            v2_path.val('{{$node->profile['v2_path']}}');
+            @if($node->profile['v2_tls'])
+            $('#v2_tls').click();
             @endif
+            $('#tls_provider').val('{!! $node->tls_provider !!}');
+
+            @break
+            @case(3)
+            $('#trojan_port').val('{{$node->port}}');
+            @break
+            @default
+            @endswitch
+
             @else
             $('input[name=\'type\'][value=\'0\']').click();
             $('#status').click();
@@ -548,7 +536,6 @@
                     protocol_param: $('#protocol_param').val(),
                     obfs: $('#obfs').val(),
                     obfs_param: $('#obfs_param').val(),
-                    compatible: document.getElementById('compatible').checked ? 1 : 0,
                     is_subscribe: document.getElementById('is_subscribe').checked ? 1 : 0,
                     detection_type: $('input[name=\'detection_type\']:checked').val(),
                     single: document.getElementById('single').checked ? 1 : 0,
@@ -563,9 +550,7 @@
                     v2_sni: $('#v2_sni').val(),
                     v2_tls: document.getElementById('v2_tls').checked ? 1 : 0,
                     tls_provider: $('#tls_provider').val(),
-                    is_relay: document.getElementById('is_relay').checked ? 1 : 0,
-                    relay_port: $('#relay_port').val(),
-                    relay_server: $('#relay_server').val(),
+                    relay_node_id: $('#relay_node_id option:selected').val(),
                 },
                 success: function(ret) {
                     if (ret.status === 'success') {
@@ -608,18 +593,6 @@
                         $('.single-setting').hide();
                     }
                     break;
-                //设置中转
-                case 'is_relay':
-                    if (check) {
-                        $('.relay-setting').show();
-                        $('#relay_port').attr('required', true);
-                        $('#relay_server').attr('required', true);
-                    } else {
-                        $('.relay-setting').hide();
-                        $('#relay_port').removeAttr('required');
-                        $('#relay_server').removeAttr('required');
-                    }
-                    break;
                 // 设置是否使用DDNS
                 case 'is_ddns':
                     if (check) {

+ 1 - 2
resources/views/admin/user/export.blade.php

@@ -33,8 +33,7 @@
                                 @endcan
                             </td>
                             <td>
-                                @if($node->compatible) <span class="label label-info">兼</span> @endif
-                                @if($node->single) <span class="label label-danger">单</span> @endif
+                                @if($node->profile['passwd']) <span class="label label-danger">单</span> @endif
                                 @if($node->ipv6) <span class="label label-danger">IPv6</span> @endif
                             </td>
                             <td>{{$node->server}}</td>

+ 93 - 0
resources/views/components/ticket/reply.blade.php

@@ -0,0 +1,93 @@
+@extends('_layout')
+@section('title', sysConfig('website_name'))
+@section('body_class','page-login-v3 layout-full')
+@section('layout_css')
+    <style>
+        .layout-full {
+            margin-right: auto !important;
+            margin-left: auto !important;
+        }
+
+        @media (min-width: 992px) {
+            .layout-full {
+                max-width: 75vw;
+            }
+        }
+
+        @media (min-width: 1200px) {
+            .layout-full {
+                max-width: 50vw;
+            }
+        }
+    </style>
+@endsection
+@section('layout_content')
+    <div class="page vertical-align " data-animsition-in="fade-in" data-animsition-out="fade-out">
+        <div class="page-content container vertical-align-middle">
+            <div class="row">
+                <div class="col-md-6">
+                    <div class="panel panel-line @if( $order->status === 2 ) panel-success @else panel-danger @endif">
+                        <div class="panel-heading">
+                            <h3 class="panel-title">
+                                <i class="icon wb-shopping-cart" aria-hidden="true"></i> {{trans('user.invoice.detail')}}
+                            </h3>
+                        </div>
+                        <div class="panel-body">
+                            <ul class="list-group">
+                                <li class="list-group-item">
+                                    订单原价:¥{{ $order->origin_amount }}
+                                </li>
+                                <li class="list-group-item">
+                                    实际支付金额:¥{{ $order->origin_amount }}
+                                </li>
+                                <li class="list-group-item">
+                                    {{ trans('user.payment_method') }}:
+                                    {{ $order->pay_way === 1 ? trans('user.shop.pay_credit') : trans('user.shop.pay_online') }}
+                                </li>
+                                <li class="list-group-item">
+                                    {{ trans('user.bought_at') }}: {{ $order->created_at }}
+                                </li>
+                                @if($order->expired_at)
+                                    <li class="list-group-item">
+                                        {{ trans('common.expired_at') }}: {{ $order->expired_at }}
+                                    </li>
+                                @endif
+                                <li class="list-group-item">
+                                    {{ trans('common.status') }}:{!! $order->status_label !!}
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-md-6">
+                    <div class="panel panel-line panel-default">
+                        <div class="panel-heading">
+                            <h3 class="panel-title">
+                                <i class="icon wb-user-circle" aria-hidden="true"></i> 用户信息
+                            </h3>
+                        </div>
+                        <div class="panel-body">
+                            <ul class="list-group">
+                                <li class="list-group-item">
+                                    {{ trans('validation.attributes.nickname') }}:{{ $user->nickname }}
+                                </li>
+                                <li class="list-group-item">
+                                    {{ trans('validation.attributes.username') }}:{{ $user->username }}
+                                </li>
+                                <li class="list-group-item">
+                                    {{ trans('user.attribute.data') }}:{{ flowAutoShow($user->used_traffic) }} / {{ flowAutoShow($user->transfer_enable) }}
+                                </li>
+                                <li class="list-group-item">
+                                    余额:{{ $user->credit }}
+                                </li>
+                                <li class="list-group-item">
+                                    过期时间:{{ $user->expired_at }}
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+@endsection

+ 30 - 30
routes/api.php

@@ -5,68 +5,68 @@ Route::group(['namespace' => 'Api\WebApi', 'middleware' => 'webApi'], function (
     // ss后端WEBAPI V1版
     Route::group(['prefix' => 'ss/v1'], function () {
         Route::get('node/{node}', 'SSController@getNodeInfo'); // 获取节点信息
-        Route::post('nodeStatus/{node}', 'BaseController@setNodeStatus'); // 上报节点心跳信息
-        Route::post('nodeOnline/{node}', 'BaseController@setNodeOnline'); // 上报节点在线人数
+        Route::post('nodeStatus/{node}', 'CoreController@setNodeStatus'); // 上报节点心跳信息
+        Route::post('nodeOnline/{node}', 'CoreController@setNodeOnline'); // 上报节点在线人数
         Route::get('userList/{node}', 'SSController@getUserList'); // 获取节点可用的用户列表
-        Route::post('userTraffic/{node}', 'BaseController@setUserTraffic'); // 上报用户流量日志
-        Route::get('nodeRule/{node}', 'BaseController@getNodeRule'); // 获取节点的审计规则
-        Route::post('trigger/{node}', 'BaseController@addRuleLog'); // 上报用户触发的审计规则记录
+        Route::post('userTraffic/{node}', 'CoreController@setUserTraffic'); // 上报用户流量日志
+        Route::get('nodeRule/{node}', 'CoreController@getNodeRule'); // 获取节点的审计规则
+        Route::post('trigger/{node}', 'CoreController@addRuleLog'); // 上报用户触发的审计规则记录
     });
 
     // SSR后端WEBAPI V1版
     Route::group(['prefix' => 'ssr/v1'], function () {
         Route::get('node/{node}', 'SSRController@getNodeInfo'); // 获取节点信息
-        Route::post('nodeStatus/{node}', 'BaseController@setNodeStatus'); // 上报节点心跳信息
-        Route::post('nodeOnline/{node}', 'BaseController@setNodeOnline'); // 上报节点在线人数
+        Route::post('nodeStatus/{node}', 'CoreController@setNodeStatus'); // 上报节点心跳信息
+        Route::post('nodeOnline/{node}', 'CoreController@setNodeOnline'); // 上报节点在线人数
         Route::get('userList/{node}', 'SSRController@getUserList'); // 获取节点可用的用户列表
-        Route::post('userTraffic/{node}', 'BaseController@setUserTraffic'); // 上报用户流量日志
-        Route::get('nodeRule/{node}', 'BaseController@getNodeRule'); // 获取节点的审计规则
-        Route::post('trigger/{node}', 'BaseController@addRuleLog'); // 上报用户触发的审计规则记录
+        Route::post('userTraffic/{node}', 'CoreController@setUserTraffic'); // 上报用户流量日志
+        Route::get('nodeRule/{node}', 'CoreController@getNodeRule'); // 获取节点的审计规则
+        Route::post('trigger/{node}', 'CoreController@addRuleLog'); // 上报用户触发的审计规则记录
     });
 
     // VNet后端WEBAPI V1版 !!! 即将遗弃的api
     Route::group(['prefix' => 'web/v1'], function () {
         Route::get('node/{node}', 'SSRController@getNodeInfo'); // 获取节点信息
-        Route::post('nodeStatus/{node}', 'BaseController@setNodeStatus'); // 上报节点心跳信息
-        Route::post('nodeOnline/{node}', 'BaseController@setNodeOnline'); // 上报节点在线人数
+        Route::post('nodeStatus/{node}', 'CoreController@setNodeStatus'); // 上报节点心跳信息
+        Route::post('nodeOnline/{node}', 'CoreController@setNodeOnline'); // 上报节点在线人数
         Route::get('userList/{node}', 'SSRController@getUserList'); // 获取节点可用的用户列表
-        Route::post('userTraffic/{node}', 'BaseController@setUserTraffic'); // 上报用户流量日志
-        Route::get('nodeRule/{node}', 'BaseController@getNodeRule'); // 获取节点的审计规则
-        Route::post('trigger/{node}', 'BaseController@addRuleLog'); // 上报用户触发的审计规则记录
+        Route::post('userTraffic/{node}', 'CoreController@setUserTraffic'); // 上报用户流量日志
+        Route::get('nodeRule/{node}', 'CoreController@getNodeRule'); // 获取节点的审计规则
+        Route::post('trigger/{node}', 'CoreController@addRuleLog'); // 上报用户触发的审计规则记录
     });
 
     // VNet后端WEBAPI V2版 !!! 即将遗弃的api
     Route::group(['prefix' => 'vnet/v2'], function () {
         Route::get('node/{node}', 'SSRController@getNodeInfo'); // 获取节点信息
-        Route::post('nodeStatus/{node}', 'BaseController@setNodeStatus'); // 上报节点心跳信息
-        Route::post('nodeOnline/{node}', 'BaseController@setNodeOnline'); // 上报节点在线人数
+        Route::post('nodeStatus/{node}', 'CoreController@setNodeStatus'); // 上报节点心跳信息
+        Route::post('nodeOnline/{node}', 'CoreController@setNodeOnline'); // 上报节点在线人数
         Route::get('userList/{node}', 'SSRController@getUserList'); // 获取节点可用的用户列表
-        Route::post('userTraffic/{node}', 'BaseController@setUserTraffic'); // 上报用户流量日志
-        Route::get('nodeRule/{node}', 'BaseController@getNodeRule'); // 获取节点的审计规则
-        Route::post('trigger/{node}', 'BaseController@addRuleLog'); // 上报用户触发的审计规则记录
+        Route::post('userTraffic/{node}', 'CoreController@setUserTraffic'); // 上报用户流量日志
+        Route::get('nodeRule/{node}', 'CoreController@getNodeRule'); // 获取节点的审计规则
+        Route::post('trigger/{node}', 'CoreController@addRuleLog'); // 上报用户触发的审计规则记录
     });
 
     // V2Ray后端WEBAPI V1版
     Route::group(['prefix' => 'v2ray/v1'], function () {
         Route::get('node/{node}', 'V2RayController@getNodeInfo'); // 获取节点信息
-        Route::post('nodeStatus/{node}', 'BaseController@setNodeStatus'); // 上报节点心跳信息
-        Route::post('nodeOnline/{node}', 'BaseController@setNodeOnline'); // 上报节点在线人数
+        Route::post('nodeStatus/{node}', 'CoreController@setNodeStatus'); // 上报节点心跳信息
+        Route::post('nodeOnline/{node}', 'CoreController@setNodeOnline'); // 上报节点在线人数
         Route::get('userList/{node}', 'V2RayController@getUserList'); // 获取节点可用的用户列表
-        Route::post('userTraffic/{node}', 'BaseController@setUserTraffic'); // 上报用户流量日志
-        Route::get('nodeRule/{node}', 'BaseController@getNodeRule'); // 获取节点的审计规则
-        Route::post('trigger/{node}', 'BaseController@addRuleLog'); // 上报用户触发的审计规则记录
+        Route::post('userTraffic/{node}', 'CoreController@setUserTraffic'); // 上报用户流量日志
+        Route::get('nodeRule/{node}', 'CoreController@getNodeRule'); // 获取节点的审计规则
+        Route::post('trigger/{node}', 'CoreController@addRuleLog'); // 上报用户触发的审计规则记录
         Route::post('certificate/{node}', 'V2RayController@addCertificate'); // 上报节点伪装域名证书信息
     });
 
     // Trojan后端WEBAPI V1版
     Route::group(['prefix' => 'trojan/v1'], function () {
         Route::get('node/{node}', 'TrojanController@getNodeInfo'); // 获取节点信息
-        Route::post('nodeStatus/{node}', 'BaseController@setNodeStatus'); // 上报节点心跳信息
-        Route::post('nodeOnline/{node}', 'BaseController@setNodeOnline'); // 上报节点在线人数
+        Route::post('nodeStatus/{node}', 'CoreController@setNodeStatus'); // 上报节点心跳信息
+        Route::post('nodeOnline/{node}', 'CoreController@setNodeOnline'); // 上报节点在线人数
         Route::get('userList/{node}', 'TrojanController@getUserList'); // 获取节点可用的用户列表
-        Route::post('userTraffic/{node}', 'BaseController@setUserTraffic'); // 上报用户流量日志
-        Route::get('nodeRule/{node}', 'BaseController@getNodeRule'); // 获取节点的审计规则
-        Route::post('trigger/{node}', 'BaseController@addRuleLog'); // 上报用户触发的审计规则记录
+        Route::post('userTraffic/{node}', 'CoreController@setUserTraffic'); // 上报用户流量日志
+        Route::get('nodeRule/{node}', 'CoreController@getNodeRule'); // 获取节点的审计规则
+        Route::post('trigger/{node}', 'CoreController@addRuleLog'); // 上报用户触发的审计规则记录
     });
 });
 

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff