Bladeren bron

添加V2ray域名伪装管理相关; 链接再优化

兔姬桑 4 jaren geleden
bovenliggende
commit
fe85b61d2a

+ 3 - 2
app/Http/Controllers/Admin/ShopController.php

@@ -113,7 +113,8 @@ class ShopController extends Controller {
 	}
 
 	// 编辑商品
-	public function editGoods(Request $request, $id) {
+	public function editGoods(Request $request) {
+		$id = $request->input('id');
 		if($request->isMethod('POST')){
 			Validator::make($request->all(), [
 				'name'    => 'required',
@@ -182,7 +183,7 @@ class ShopController extends Controller {
 				DB::rollBack();
 			}
 
-			return Redirect::to('shop/edit/'.$id);
+			return Redirect::to('shop/edit?id='.$id);
 		}else{
 			$goods = Goods::query()->whereId($id)->first();
 

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

@@ -745,7 +745,8 @@ EOF;
 	}
 
 	// 用户流量监控
-	public function userMonitor($id) {
+	public function userMonitor(Request $request) {
+		$id = $request->input('id');
 		if(empty($id)){
 			return Redirect::to('admin/userList');
 		}
@@ -1665,7 +1666,7 @@ EOF;
 			});
 		}
 
-		$list = $query->groupBy('user_id','node_id')->orderByDesc('id');
+		$list = $query->groupBy('user_id', 'node_id')->orderByDesc('id');
 		foreach($list as $vo){
 			// 跳过上报多IP的
 			if(strpos($vo->ip, ',') == true || $vo->ip == null){
@@ -1685,7 +1686,7 @@ EOF;
 			$vo->ipInfo = $ipInfo['country'].' '.$ipInfo['province'].' '.$ipInfo['city'];
 		}
 
-		$view['list'] = $list->paginate(20)->appends($request->except('page'));;
+		$view['list'] = $list->paginate(20)->appends($request->except('page'));
 		$view['nodeList'] = SsNode::query()->whereStatus(1)->orderByDesc('sort')->orderByDesc('id')->get();
 
 		return Response::view('admin.logs.onlineIPMonitor', $view);

+ 71 - 1
app/Http/Controllers/NodeController.php

@@ -8,6 +8,7 @@ use App\Models\Country;
 use App\Models\Label;
 use App\Models\Level;
 use App\Models\NodeAuth;
+use App\Models\NodeCertificate;
 use App\Models\NodeRule;
 use App\Models\RuleGroup;
 use App\Models\SsNode;
@@ -160,6 +161,7 @@ class NodeController extends Controller {
 			$view['country_list'] = Country::query()->orderBy('code')->get();
 			$view['level_list'] = Level::query()->orderBy('level')->get();
 			$view['label_list'] = Label::query()->orderByDesc('sort')->orderBy('id')->get();
+			$view['dv_list'] = NodeCertificate::query()->orderBy('id')->get();
 
 			return Response::view('admin.node.nodeInfo', $view);
 		}
@@ -318,6 +320,7 @@ class NodeController extends Controller {
 			$view['country_list'] = Country::query()->orderBy('code')->get();
 			$view['level_list'] = Level::query()->orderBy('level')->get();
 			$view['label_list'] = Label::query()->orderByDesc('sort')->orderBy('id')->get();
+			$view['dv_list'] = NodeCertificate::query()->orderBy('id')->get();
 
 			return view('admin.node.nodeInfo', $view)->with(compact('node'));
 		}
@@ -368,7 +371,8 @@ class NodeController extends Controller {
 	}
 
 	// 节点流量监控
-	public function nodeMonitor($node_id) {
+	public function nodeMonitor(Request $request) {
+		$node_id = $request->input('id');
 		$node = SsNode::query()->whereId($node_id)->orderByDesc('sort')->first();
 		if(!$node){
 			Session::flash('errorMsg', '节点不存在,请重试');
@@ -520,4 +524,70 @@ class NodeController extends Controller {
 			return Response::json(['status' => 'fail', 'message' => '操作失败']);
 		}
 	}
+
+	// 域名证书列表
+	public function certificateList(Request $request) {
+		$DvList = NodeCertificate::query()->orderBy('id')->paginate(15)->appends($request->except('page'));
+		foreach($DvList as $Dv){
+			if($Dv->key && $Dv->pem){
+				$DvInfo = openssl_x509_parse($Dv->pem);
+				//dd($DvInfo);
+				$Dv->issuer = $DvInfo['issuer']['O'];
+				$Dv->from = $DvInfo['validFrom_time_t']? date('Y-m-d', $DvInfo['validFrom_time_t']) : null;
+				$Dv->to = $DvInfo['validTo']? date('Y-m-d', $DvInfo['validTo_time_t']) : null;
+			}
+		}
+			$view['list'] = $DvList;
+			return Response::view('admin.node.certificateList', $view);
+	}
+
+	// 添加域名证书
+	public function addCertificate(Request $request) {
+		if($request->isMethod('POST')){
+			$obj = new NodeCertificate();
+			$obj->domain = $request->input('domain');
+			$obj->key = str_replace(["\r", "\n"], '', $request->input('key'));
+			$obj->pem = str_replace(["\r", "\n"], '', $request->input('pem'));
+			$obj->save();
+
+			if($obj->id){
+				return Response::json(['status' => 'success', 'message' => '生成成功']);
+			}else{
+				return Response::json(['status' => 'fail', 'message' => '生成失败']);
+			}
+		}else{
+			return Response::view('admin.node.certificateInfo');
+		}
+	}
+
+	// 编辑域名证书
+	public function editCertificate(Request $request) {
+		$Dv = NodeCertificate::query()->find($request->input('id'));
+		if($request->isMethod('POST')){
+			if($Dv){
+				$ret = NodeCertificate::query()->update([
+					'domain' => $request->input('domain'),
+					'key'    => $request->input('key'),
+					'pem'    => $request->input('pem')
+				]);
+				if($ret){
+					return Response::json(['status' => 'success', 'message' => '修改成功']);
+				}
+			}
+			return Response::json(['status' => 'fail', 'message' => '修改失败']);
+		}else{
+			$view['Dv'] = $Dv;
+			return Response::view('admin.node.certificateInfo', $view);
+		}
+	}
+
+	// 删除域名证书
+	public function delCertificate(Request $request) {
+		try{
+			NodeCertificate::query()->whereId($request->input('id'))->delete();
+		}catch(Exception $e){
+			return Response::json(['status' => 'fail', 'message' => '错误:'.var_export($e, true)]);
+		}
+		return Response::json(['status' => 'success', 'message' => '操作成功']);
+	}
 }

+ 99 - 85
composer.lock

@@ -633,16 +633,16 @@
         },
         {
             "name": "doctrine/cache",
-            "version": "1.10.1",
+            "version": "1.10.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/cache.git",
-                "reference": "35a4a70cd94e09e2259dfae7488afc6b474ecbd3"
+                "reference": "13e3381b25847283a91948d04640543941309727"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/cache/zipball/35a4a70cd94e09e2259dfae7488afc6b474ecbd3",
-                "reference": "35a4a70cd94e09e2259dfae7488afc6b474ecbd3",
+                "url": "https://api.github.com/repos/doctrine/cache/zipball/13e3381b25847283a91948d04640543941309727",
+                "reference": "13e3381b25847283a91948d04640543941309727",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -717,7 +717,7 @@
                 "redis",
                 "xcache"
             ],
-            "time": "2020-05-27T16:24:54+00:00"
+            "time": "2020-07-07T18:54:01+00:00"
         },
         {
             "name": "doctrine/dbal",
@@ -1231,16 +1231,16 @@
         },
         {
             "name": "ezyang/htmlpurifier",
-            "version": "v4.12.0",
+            "version": "v4.13.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/ezyang/htmlpurifier.git",
-                "reference": "a617e55bc62a87eec73bd456d146d134ad716f03"
+                "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/a617e55bc62a87eec73bd456d146d134ad716f03",
-                "reference": "a617e55bc62a87eec73bd456d146d134ad716f03",
+                "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
+                "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -1262,6 +1262,9 @@
                 },
                 "files": [
                     "library/HTMLPurifier.composer.php"
+                ],
+                "exclude-from-classmap": [
+                    "/library/HTMLPurifier/Language/"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1280,7 +1283,7 @@
             "keywords": [
                 "html"
             ],
-            "time": "2019-10-28T03:44:26+00:00"
+            "time": "2020-06-29T00:56:53+00:00"
         },
         {
             "name": "fideloper/proxy",
@@ -2739,16 +2742,16 @@
         },
         {
             "name": "mews/purifier",
-            "version": "3.2.2",
+            "version": "3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mewebstudio/Purifier.git",
-                "reference": "75e4d9a0553b31c1fd31aef65f9561c30dbe5e5e"
+                "reference": "01445654edf1a737efd9c93bbbe5c90ddf006712"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mewebstudio/Purifier/zipball/75e4d9a0553b31c1fd31aef65f9561c30dbe5e5e",
-                "reference": "75e4d9a0553b31c1fd31aef65f9561c30dbe5e5e",
+                "url": "https://api.github.com/repos/mewebstudio/Purifier/zipball/01445654edf1a737efd9c93bbbe5c90ddf006712",
+                "reference": "01445654edf1a737efd9c93bbbe5c90ddf006712",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -2758,7 +2761,7 @@
                 ]
             },
             "require": {
-                "ezyang/htmlpurifier": "4.12.*",
+                "ezyang/htmlpurifier": "4.13.*",
                 "illuminate/config": "^5.1|^6.0|^7.0",
                 "illuminate/filesystem": "^5.1|^6.0|^7.0",
                 "illuminate/support": "^5.1|^6.0|^7.0",
@@ -2819,7 +2822,7 @@
                 "security",
                 "xss"
             ],
-            "time": "2020-04-10T19:42:16+00:00"
+            "time": "2020-07-10T17:14:50+00:00"
         },
         {
             "name": "misechow/geetest",
@@ -3128,16 +3131,16 @@
         },
         {
             "name": "nesbot/carbon",
-            "version": "2.36.0",
+            "version": "2.36.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "d0b65958d9942fd1b501fdb0800c67e8323aa08d"
+                "reference": "ee7378a36cc62952100e718bcc58be4c7210e55f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d0b65958d9942fd1b501fdb0800c67e8323aa08d",
-                "reference": "d0b65958d9942fd1b501fdb0800c67e8323aa08d",
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/ee7378a36cc62952100e718bcc58be4c7210e55f",
+                "reference": "ee7378a36cc62952100e718bcc58be4c7210e55f",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -3209,20 +3212,20 @@
                 "datetime",
                 "time"
             ],
-            "time": "2020-06-25T20:20:01+00:00"
+            "time": "2020-07-04T12:29:56+00:00"
         },
         {
             "name": "nikic/php-parser",
-            "version": "v4.5.0",
+            "version": "v4.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nikic/PHP-Parser.git",
-                "reference": "53c2753d756f5adb586dca79c2ec0e2654dd9463"
+                "reference": "c346bbfafe2ff60680258b631afb730d186ed864"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/53c2753d756f5adb586dca79c2ec0e2654dd9463",
-                "reference": "53c2753d756f5adb586dca79c2ec0e2654dd9463",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c346bbfafe2ff60680258b631afb730d186ed864",
+                "reference": "c346bbfafe2ff60680258b631afb730d186ed864",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -3267,7 +3270,7 @@
                 "parser",
                 "php"
             ],
-            "time": "2020-06-03T07:24:19+00:00"
+            "time": "2020-07-02T17:12:47+00:00"
         },
         {
             "name": "openlss/lib-array2xml",
@@ -4385,16 +4388,16 @@
         },
         {
             "name": "seld/phar-utils",
-            "version": "1.1.0",
+            "version": "1.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Seldaek/phar-utils.git",
-                "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0"
+                "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8800503d56b9867d43d9c303b9cbcc26016e82f0",
-                "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0",
+                "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8674b1d84ffb47cc59a101f5d5a3b61e87d23796",
+                "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -4431,7 +4434,7 @@
             "keywords": [
                 "phar"
             ],
-            "time": "2020-02-14T15:25:33+00:00"
+            "time": "2020-07-07T18:42:57+00:00"
         },
         {
             "name": "spatie/laravel-permission",
@@ -4982,16 +4985,16 @@
         },
         {
             "name": "symfony/event-dispatcher-contracts",
-            "version": "v1.1.7",
+            "version": "v1.1.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher-contracts.git",
-                "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18"
+                "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c43ab685673fb6c8d84220c77897b1d6cdbe1d18",
-                "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/84e23fdcd2517bf37aecbd16967e83f0caee25a7",
+                "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -5001,7 +5004,7 @@
                 ]
             },
             "require": {
-                "php": "^7.1.3"
+                "php": ">=7.1.3"
             },
             "suggest": {
                 "psr/event-dispatcher": "",
@@ -5011,6 +5014,10 @@
             "extra": {
                 "branch-alias": {
                     "dev-master": "1.1-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
                 }
             },
             "autoload": {
@@ -5042,7 +5049,7 @@
                 "interoperability",
                 "standards"
             ],
-            "time": "2019-09-17T09:54:03+00:00"
+            "time": "2020-07-06T13:19:58+00:00"
         },
         {
             "name": "symfony/filesystem",
@@ -6000,16 +6007,16 @@
         },
         {
             "name": "symfony/service-contracts",
-            "version": "v2.1.2",
+            "version": "v2.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/service-contracts.git",
-                "reference": "66a8f0957a3ca54e4f724e49028ab19d75a8918b"
+                "reference": "58c7475e5457c5492c26cc740cc0ad7464be9442"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/66a8f0957a3ca54e4f724e49028ab19d75a8918b",
-                "reference": "66a8f0957a3ca54e4f724e49028ab19d75a8918b",
+                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/58c7475e5457c5492c26cc740cc0ad7464be9442",
+                "reference": "58c7475e5457c5492c26cc740cc0ad7464be9442",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -6029,6 +6036,10 @@
             "extra": {
                 "branch-alias": {
                     "dev-master": "2.1-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
                 }
             },
             "autoload": {
@@ -6060,7 +6071,7 @@
                 "interoperability",
                 "standards"
             ],
-            "time": "2020-05-20T17:43:50+00:00"
+            "time": "2020-07-06T13:23:11+00:00"
         },
         {
             "name": "symfony/translation",
@@ -6146,16 +6157,16 @@
         },
         {
             "name": "symfony/translation-contracts",
-            "version": "v2.1.2",
+            "version": "v2.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation-contracts.git",
-                "reference": "e5ca07c8f817f865f618aa072c2fe8e0e637340e"
+                "reference": "616a9773c853097607cf9dd6577d5b143ffdcd63"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/e5ca07c8f817f865f618aa072c2fe8e0e637340e",
-                "reference": "e5ca07c8f817f865f618aa072c2fe8e0e637340e",
+                "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/616a9773c853097607cf9dd6577d5b143ffdcd63",
+                "reference": "616a9773c853097607cf9dd6577d5b143ffdcd63",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -6174,6 +6185,10 @@
             "extra": {
                 "branch-alias": {
                     "dev-master": "2.1-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
                 }
             },
             "autoload": {
@@ -6205,7 +6220,7 @@
                 "interoperability",
                 "standards"
             ],
-            "time": "2020-05-20T17:43:50+00:00"
+            "time": "2020-07-06T13:23:11+00:00"
         },
         {
             "name": "symfony/var-dumper",
@@ -6709,16 +6724,16 @@
         },
         {
             "name": "hamcrest/hamcrest-php",
-            "version": "v2.0.0",
+            "version": "v2.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/hamcrest/hamcrest-php.git",
-                "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad"
+                "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad",
-                "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad",
+                "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+                "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -6728,7 +6743,7 @@
                 ]
             },
             "require": {
-                "php": "^5.3|^7.0"
+                "php": "^5.3|^7.0|^8.0"
             },
             "replace": {
                 "cordoval/hamcrest-php": "*",
@@ -6736,14 +6751,13 @@
                 "kodova/hamcrest-php": "*"
             },
             "require-dev": {
-                "phpunit/php-file-iterator": "1.3.3",
-                "phpunit/phpunit": "~4.0",
-                "satooshi/php-coveralls": "^1.0"
+                "phpunit/php-file-iterator": "^1.4 || ^2.0",
+                "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.0-dev"
+                    "dev-master": "2.1-dev"
                 }
             },
             "autoload": {
@@ -6753,26 +6767,26 @@
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "BSD"
+                "BSD-3-Clause"
             ],
             "description": "This is the PHP port of Hamcrest Matchers",
             "keywords": [
                 "test"
             ],
-            "time": "2016-01-20T08:20:44+00:00"
+            "time": "2020-07-09T08:09:16+00:00"
         },
         {
             "name": "mockery/mockery",
-            "version": "1.4.0",
+            "version": "1.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mockery/mockery.git",
-                "reference": "6c6a7c533469873deacf998237e7649fc6b36223"
+                "reference": "1404386ca3410b04fe58b9517e85d702ab33b2c6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mockery/mockery/zipball/6c6a7c533469873deacf998237e7649fc6b36223",
-                "reference": "6c6a7c533469873deacf998237e7649fc6b36223",
+                "url": "https://api.github.com/repos/mockery/mockery/zipball/1404386ca3410b04fe58b9517e85d702ab33b2c6",
+                "reference": "1404386ca3410b04fe58b9517e85d702ab33b2c6",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -6782,15 +6796,15 @@
                 ]
             },
             "require": {
-                "hamcrest/hamcrest-php": "~2.0",
+                "hamcrest/hamcrest-php": "^2.0.1",
                 "lib-pcre": ">=7.0",
-                "php": "^7.3.0"
+                "php": "^7.3 || ^8.0"
             },
             "conflict": {
                 "phpunit/phpunit": "<8.0"
             },
             "require-dev": {
-                "phpunit/phpunit": "^8.0.0 || ^9.0.0"
+                "phpunit/phpunit": "^8.5 || ^9.0"
             },
             "type": "library",
             "extra": {
@@ -6833,7 +6847,7 @@
                 "test double",
                 "testing"
             ],
-            "time": "2020-05-19T14:25:16+00:00"
+            "time": "2020-07-09T08:31:54+00:00"
         },
         {
             "name": "myclabs/deep-copy",
@@ -7240,16 +7254,16 @@
         },
         {
             "name": "phpspec/prophecy",
-            "version": "v1.10.3",
+            "version": "1.11.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "451c3cd1418cf640de218914901e51b064abb093"
+                "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093",
-                "reference": "451c3cd1418cf640de218914901e51b064abb093",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160",
+                "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -7259,20 +7273,20 @@
                 ]
             },
             "require": {
-                "doctrine/instantiator": "^1.0.2",
-                "php": "^5.3|^7.0",
-                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
-                "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
-                "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
+                "doctrine/instantiator": "^1.2",
+                "php": "^7.2",
+                "phpdocumentor/reflection-docblock": "^5.0",
+                "sebastian/comparator": "^3.0 || ^4.0",
+                "sebastian/recursion-context": "^3.0 || ^4.0"
             },
             "require-dev": {
-                "phpspec/phpspec": "^2.5 || ^3.2",
-                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+                "phpspec/phpspec": "^6.0",
+                "phpunit/phpunit": "^8.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.10.x-dev"
+                    "dev-master": "1.11.x-dev"
                 }
             },
             "autoload": {
@@ -7305,7 +7319,7 @@
                 "spy",
                 "stub"
             ],
-            "time": "2020-03-05T15:02:03+00:00"
+            "time": "2020-07-08T12:44:21+00:00"
         },
         {
             "name": "phpunit/php-code-coverage",
@@ -8413,16 +8427,16 @@
         },
         {
             "name": "webmozart/assert",
-            "version": "1.9.0",
+            "version": "1.9.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/webmozart/assert.git",
-                "reference": "9dc4f203e36f2b486149058bade43c851dd97451"
+                "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/webmozart/assert/zipball/9dc4f203e36f2b486149058bade43c851dd97451",
-                "reference": "9dc4f203e36f2b486149058bade43c851dd97451",
+                "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
+                "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -8432,7 +8446,7 @@
                 ]
             },
             "require": {
-                "php": "^5.3.3 || ^7.0",
+                "php": "^5.3.3 || ^7.0 || ^8.0",
                 "symfony/polyfill-ctype": "^1.8"
             },
             "conflict": {
@@ -8464,7 +8478,7 @@
                 "check",
                 "validate"
             ],
-            "time": "2020-06-16T10:16:42+00:00"
+            "time": "2020-07-08T17:02:28+00:00"
         }
     ],
     "aliases": [],

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

@@ -464,9 +464,9 @@
 													<span class="input-group-append">
 														<button class="btn btn-primary" type="button" onclick="update('web_api_url')">修改</button>
 													</span>
-													<span class="text-help offset-md-3"> 用于 VNet后端 授权,此域名需要解析A记录到面板,例:https://demo.proxypanel.ml</span>
 												</div>
 											</div>
+											<span class="text-help offset-md-3"> 用于 VNet后端 授权,此域名需要解析A记录到面板,例:https://demo.proxypanel.ml</span>
 										</div>
 									</div>
 									<div class="form-group col-lg-6">

+ 15 - 10
resources/views/admin/layouts.blade.php

@@ -113,13 +113,13 @@
 					<span class="site-menu-title">管理中心</span>
 				</a>
 			</li>
-			<li class="site-menu-item has-sub {{in_array(Request::path(), ['admin/userList', 'admin/addUser', 'admin/editUser', 'admin/export', 'admin/onlineIPMonitor', 'admin/userMonitor', 'admin/userCreditLogList', 'subscribe/subscribeList']) ? 'active open' : ''}}">
+			<li class="site-menu-item has-sub {{in_array(Request::path(), ['admin/userList', 'admin/addUser', 'admin/editUser', 'admin/export', 'admin/userMonitor', 'admin/userCreditLogList', 'subscribe']) ? 'active open' : ''}}">
 				<a href="javascript:void(0)">
 					<i class="site-menu-icon wb-user" aria-hidden="true"></i>
 					<span class="site-menu-title">用户系统</span>
 				</a>
 				<ul class="site-menu-sub">
-					<li class="site-menu-item {{in_array(Request::path(), ['admin/userList', 'admin/addUser', 'admin/editUser', 'admin/export', 'admin/onlineIPMonitor', 'admin/userMonitor']) ? 'active open' : ''}}">
+					<li class="site-menu-item {{in_array(Request::path(), ['admin/userList', 'admin/addUser', 'admin/editUser', 'admin/export', 'admin/userMonitor']) ? 'active open' : ''}}">
 						<a href="/admin/userList">
 							<span class="site-menu-title">用户管理</span>
 						</a>
@@ -136,7 +136,7 @@
 					</li>
 				</ul>
 			</li>
-			<li class="site-menu-item has-sub {{in_array(Request::path(), ['ticket', 'ticket/add','ticket/reply', 'admin/articleList', 'admin/addArticle', 'admin/editArticle', 'marketing/push', 'marketing/email']) ? 'active open' : ''}}">
+			<li class="site-menu-item has-sub {{in_array(Request::path(), ['ticket', 'ticket/create', 'ticket/reply', 'admin/articleList', 'admin/addArticle', 'admin/editArticle', 'marketing/push', 'marketing/email']) ? 'active open' : ''}}">
 				<a href="javascript:void(0)">
 					<i class="site-menu-icon wb-chat-working" aria-hidden="true"></i>
 					<span class="site-menu-title">客服系统</span>
@@ -147,7 +147,7 @@
 					@endif
 				</a>
 				<ul class="site-menu-sub">
-					<li class="site-menu-item {{in_array(Request::path(), ['ticket', 'ticket/add','ticket/reply']) ? 'active open' : ''}}">
+					<li class="site-menu-item {{in_array(Request::path(), ['ticket', 'ticket/create', 'ticket/reply']) ? 'active open' : ''}}">
 						<a href="/ticket">
 							<span class="site-menu-title">服务工单</span>
 							@if(\App\Models\Ticket::query()->whereStatus(0)->count() > 0 )
@@ -174,7 +174,7 @@
 					</li>
 				</ul>
 			</li>
-			<li class="site-menu-item has-sub {{in_array(Request::path(), ['node', 'node/add', 'node/edit', 'node/monitor', 'node/pingLog']) ? 'active open' : ''}}">
+			<li class="site-menu-item has-sub {{in_array(Request::path(), ['node', 'node/add', 'node/edit', 'node/monitor', 'node/auth', 'node/certificate', 'node/certificate/add', 'node/certificate/edit', 'node/pingLog',]) ? 'active open' : ''}}">
 				<a href="javascript:void(0)">
 					<i class="site-menu-icon wb-grid-4" aria-hidden="true"></i>
 					<span class="site-menu-title">线路系统</span>
@@ -185,11 +185,16 @@
 							<span class="site-menu-title">线路管理</span>
 						</a>
 					</li>
-					<li class="site-menu-item {{in_array(Request::path(), ['node/auth', 'node/auth/add', 'node/auth/delete', 'node/auth/refresh']) ? 'active open' : ''}}">
+					<li class="site-menu-item {{in_array(Request::path(), ['node/auth']) ? 'active open' : ''}}">
 						<a href="/node/auth">
 							<span class="site-menu-title">线路授权</span>
 						</a>
 					</li>
+					<li class="site-menu-item {{in_array(Request::path(), ['node/certificate', 'node/certificate/add', 'node/certificate/edit']) ? 'active open' : ''}}">
+						<a href="/node/certificate">
+							<span class="site-menu-title">证书列表</span>
+						</a>
+					</li>
 					<li class="site-menu-item {{in_array(Request::path(), ['node/pingLog']) ? 'active open' : ''}}">
 						<a href="/node/pingLog">
 							<span class="site-menu-title">测速日志</span>
@@ -197,13 +202,13 @@
 					</li>
 				</ul>
 			</li>
-			<li class="site-menu-item has-sub {{in_array(Request::path(), ['rule', 'rule/add', 'rule/edit', 'rule/group', 'rule/group/add', 'rule/group/edit', 'rule/group/assign', 'rule/log']) ? 'active open' : ''}}">
+			<li class="site-menu-item has-sub {{in_array(Request::path(), ['rule', 'rule/group', 'rule/group/add', 'rule/group/edit', 'rule/group/assign', 'rule/log']) ? 'active open' : ''}}">
 				<a href="javascript:void(0)">
 					<i class="site-menu-icon wb-eye" aria-hidden="true"></i>
 					<span class="site-menu-title">审计规则</span>
 				</a>
 				<ul class="site-menu-sub">
-					<li class="site-menu-item {{in_array(Request::path(), ['rule', 'rule/add', 'rule/edit']) ? 'active open' : ''}}">
+					<li class="site-menu-item {{in_array(Request::path(), ['rule']) ? 'active open' : ''}}">
 						<a href="/rule">
 							<span class="site-menu-title">规则列表</span>
 						</a>
@@ -220,7 +225,7 @@
 					</li>
 				</ul>
 			</li>
-			<li class="site-menu-item has-sub {{in_array(Request::path(), ['shop', 'shop/add', 'shop/edit', 'coupon', 'coupon/add','admin/orderList']) ? 'active open' : ''}}">
+			<li class="site-menu-item has-sub {{in_array(Request::path(), ['shop', 'shop/add', 'shop/edit', 'coupon', 'coupon/add', 'admin/orderList']) ? 'active open' : ''}}">
 				<a href="javascript:void(0)">
 					<i class="site-menu-icon wb-shopping-cart" aria-hidden="true"></i>
 					<span class="site-menu-title">商品系统</span>
@@ -249,7 +254,7 @@
 					<span class="site-menu-title">推广系统</span>
 					@if(\App\Models\ReferralApply::query()->whereStatus(0)->count() > 0 )
 						<div class="site-menu-badge">
-							<span class="badge badge-pill badge-success">{{\App\Models\Ticket::query()->whereStatus(0)->count()}}</span>
+							<span class="badge badge-pill badge-success">{{\App\Models\ReferralApply::query()->whereStatus(0)->count()}}</span>
 						</div>
 					@endif
 				</a>

+ 1 - 1
resources/views/admin/node/authList.blade.php

@@ -8,7 +8,7 @@
 			<div class="panel-heading">
 				<h2 class="panel-title">节点授权列表<small>WEBAPI</small></h2>
 				<div class="panel-actions">
-					<button class="btn btn-outline-default" onclick="addAuth()">
+					<button class="btn btn-primary" onclick="addAuth()">
 						<i class="icon wb-plus" aria-hidden="true"></i>生成授权
 					</button>
 				</div>

+ 71 - 0
resources/views/admin/node/certificateInfo.blade.php

@@ -0,0 +1,71 @@
+@extends('admin.layouts')
+@section('css')
+	<link href="/assets/global/vendor/bootstrap-select/bootstrap-select.min.css" type="text/css" rel="stylesheet">
+@endsection
+@section('content')
+	<div class="page-content container">
+		<div class="panel">
+			<div class="panel-heading">
+				<h2 class="panel-title">@isset($Dv) 编辑 @else 添加 @endisset域名证书</h2>
+			</div>
+			<div class="panel-body">
+				<form action=@isset($Dv){{url('/node/certificate/edit')}} @else {{url('/node/certificate/add')}} @endisset method="post" enctype="multipart/form-data" class="form-horizontal" onsubmit="return Submit()">
+					<div class="form-group row">
+						<label for="domain" class="col-md-3 col-form-label">域名</label>
+						<div class="col-md-9">
+							<input type="text" class="form-control" name="domain" id="domain" @isset($Dv) value="{{$Dv->domain}}" @endisset>
+						</div>
+					</div>
+					<div class="form-group row">
+						<label for="key" class="col-md-3 col-form-label">Key</label>
+						<div class="col-md-9">
+							<textarea type="text" rows="10" class="form-control" name="key" id="key" placeholder="域名证书的KEY值,允许为空,VNET-V2Ray后端支持自动签证书">@isset($Dv) {{$Dv->key}} @endisset</textarea>
+						</div>
+					</div>
+					<div class="form-group row">
+						<label for="pem" class="col-md-3 col-form-label">Pem</label>
+						<div class="col-md-9">
+							<textarea type="text" rows="10" class="form-control" name="pem" id="pem" placeholder="域名证书的PEM值,允许为空,VNET-V2Ray后端支持自动签证书">@isset($Dv) {{$Dv->pem}} @endisset</textarea>
+						</div>
+					</div>
+					<div class="form-actions">
+						<button type="submit" class="btn btn-success">提 交</button>
+					</div>
+				</form>
+			</div>
+		</div>
+	</div>
+@endsection
+@section('script')
+	<script type="text/javascript">
+		// 添加域名证书
+		function Submit() {
+			$.ajax({
+				type: "POST",
+				url: @isset($Dv) "/node/certificate/edit" @else "/node/certificate/add" @endisset,
+				async: false,
+				data: {
+					_token: '{{csrf_token()}}',
+					id: '{{Request::get('id')}}',
+					domain: $('#domain').val(),
+					key: $('#key').val(),
+					pem: $('#pem').val(),
+				},
+				dataType: 'json',
+				success: function (ret) {
+					if (ret.status === 'success') {
+						swal.fire({title: ret.message, type: 'success', timer: 1000, showConfirmButton: false})
+							.then(() => window.location.href = '/node/certificate')
+					} else {
+						swal.fire({
+							title: '[错误 | Error]',
+							text: ret.message,
+							type: 'error'
+						});
+					}
+				}
+			});
+			return false;
+		}
+	</script>
+@endsection

+ 98 - 0
resources/views/admin/node/certificateList.blade.php

@@ -0,0 +1,98 @@
+@extends('admin.layouts')
+@section('css')
+	<link href="/assets/global/vendor/bootstrap-table/bootstrap-table.min.css" type="text/css" rel="stylesheet">
+@endsection
+@section('content')
+	<div class="page-content container-fluid">
+		<div class="panel">
+			<div class="panel-heading">
+				<h2 class="panel-title">域名证书列表<small>(V2Ray节点的伪装域名)</small></h2>
+				<div class="panel-actions">
+					<a href="/node/certificate/add" class="btn btn-primary">
+						<i class="icon wb-plus" aria-hidden="true"></i>添加域名证书
+					</a>
+				</div>
+			</div>
+			<div class="panel-body">
+				<table class="text-md-center" data-toggle="table" data-mobile-responsive="true">
+					<thead class="thead-default">
+					<tr>
+						<th> #</th>
+						<th> 域名</th>
+						<th> KEY</th>
+						<th> PEM</th>
+						<th> 签发机构</th>
+						<th> 签发日期</th>
+						<th> 到期时间</th>
+						<th> 操作</th>
+					</tr>
+					</thead>
+					<tbody>
+					@foreach ($list as $vo)
+						<tr>
+							<td> {{$vo->id}} </td>
+							<td> {{$vo->domain}} </td>
+							<td> {{$vo->key ? '✔' : '❌'}} </td>
+							<td> {{$vo->pem ? '✔' : '❌'}} </td>
+							<td> {{$vo->issuer}} </td>
+							<td> {{$vo->from}} </td>
+							<td> {{$vo->to}} </td>
+							<td>
+								<div class="btn-group">
+									<a href="/node/certificate/edit?id={{$vo->id}}" class="btn btn-primary">
+										<i class="icon wb-edit" aria-hidden="true"></i>
+									</a>
+									<button onclick="delCertificate('{{$vo->id}}')" class="btn btn-danger">
+										<i class="icon wb-trash" aria-hidden="true"></i>
+									</button>
+								</div>
+							</td>
+						</tr>
+					@endforeach
+					</tbody>
+				</table>
+			</div>
+			<div class="panel-footer">
+				<div class="row">
+					<div class="col-sm-4">
+						共 <code>{{$list->total()}}</code> 个域名证书
+					</div>
+					<div class="col-sm-8">
+						<nav class="Page navigation float-right">
+							{{$list->links()}}
+						</nav>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+@endsection
+@section('script')
+	<script src="/assets/global/vendor/bootstrap-table/bootstrap-table.min.js" type="text/javascript"></script>
+	<script src="/assets/global/vendor/bootstrap-table/extensions/mobile/bootstrap-table-mobile.min.js" type="text/javascript"></script>
+
+	<script type="text/javascript">
+		// 删除授权
+		function delCertificate(id) {
+			swal.fire({
+				title: '提示',
+				text: '确定删除该证书吗?',
+				type: 'info',
+				showCancelButton: true,
+				cancelButtonText: '{{trans('home.ticket_close')}}',
+				confirmButtonText: '{{trans('home.ticket_confirm')}}',
+			}).then((result) => {
+				if (result.value) {
+					$.post("/node/certificate/delete", {_token: '{{csrf_token()}}', id: id}, function (ret) {
+						if (ret.status === 'success') {
+							swal.fire({title: ret.message, type: 'success', timer: 1000, showConfirmButton: false})
+								.then(() => window.location.reload())
+						} else {
+							swal.fire({title: ret.message, type: "error"}).then(() => window.location.reload())
+						}
+					});
+				}
+			});
+		}
+	</script>
+@endsection

+ 28 - 10
resources/views/admin/node/nodeInfo.blade.php

@@ -276,7 +276,17 @@
 										</div>
 										<div class="form-group row v2_host">
 											<label for="v2_host" class="col-md-3 col-form-label">伪装域名</label>
-											<input type="text" class="form-control col-md-4" name="v2_host" id="v2_host">
+											<div class="col-md-4 pl-0">
+												<input type="text" class="form-control" name="v2_other" id="v2_host">
+												<div name="v2_ws">
+													<select data-plugin="selectpicker" data-style="btn-outline btn-primary" class="form-control" id="v2_ws">
+														<option value="" hidden></option>
+														@foreach($dv_list as $dv)
+															<option value="{{$dv->domain}}" @if(isset($node) && $node->v2_net == "ws" && $node->v2_host == $dv->domain) selected @endif>{{$dv->domain}}</option>
+														@endforeach
+													</select>
+												</div>
+											</div>
 											<div class="text-help offset-md-3"> 伪装类型为http时多个伪装域名逗号隔开,使用WebSocket传输协议时只允许单个</div>
 										</div>
 										<div class="form-group row">
@@ -381,7 +391,6 @@
 		const string = "{{strtolower(Str::random())}}";
 		$(document).ready(function () {
 			let v2_path = $('#v2_path');
-
 			@isset($node)
 
 			@if($node->is_ddns)
@@ -460,7 +469,6 @@
 				$('.obfs_param').hide();
 			}
 		});
-
 		// ajax同步提交
 		function Submit() {
 			$.ajax({
@@ -602,34 +610,44 @@
 			}
 		});
 
+		$("#v2_ws").on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
+			$('#v2_host').val($('#v2_ws').val());
+		})
+
 		// 设置V2Ray详细设置
 		$("#v2_net").on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
 			const type = $('.v2_type');
 			const type_option = $('#type_option');
 			const host = $('.v2_host');
 			const path = $('#v2_path');
+			const v2_ws = $('[name="v2_ws"]');
+			const v2_other = $('[name="v2_other"]');
 			type.show();
 			host.show();
+			v2_other.show();
+			v2_ws.hide();
 			path.val('/' + string);
-			switch (clickedIndex) {
-				case 1:
+			switch ($(this).val()) {
+				case 'kcp':
 					type_option.attr('disabled', false);
 					break;
-				case 2:
+				case 'ws':
+					v2_ws.show();
 					type.hide();
+					v2_other.hide();
 					break;
-				case 3:
+				case 'http':
 					type.hide();
 					break;
-				case 4:
+				case 'domainsocket':
 					type.hide();
 					host.hide();
 					break;
-				case 5:
+				case 'quic':
 					type_option.attr('disabled', false);
 					path.val(string);
 					break;
-				case 0:
+				case 'tcp':
 				default:
 					type_option.attr('disabled', true);
 					break;

+ 1 - 1
resources/views/admin/node/nodeList.blade.php

@@ -75,7 +75,7 @@
 									<a href="javascript:delNode('{{$node->id}}','{{$node->name}}')" class="btn btn-danger">
 										<i class="icon wb-trash"></i>
 									</a>
-									<a href="/node/monitor/{{$node->id}}" class="btn btn-primary">
+									<a href="/node/monitor?id={{$node->id}}" class="btn btn-primary">
 										<i class="icon wb-stats-bars"></i>
 									</a>
 								</div>

+ 1 - 1
resources/views/admin/shop/goodsInfo.blade.php

@@ -39,7 +39,7 @@
 				</div>
 			@endif
 			<div class="panel-body">
-				<form action=@isset($goods){{url('/shop/edit/'.$goods->id)}} @else {{url('/shop/add')}} @endisset"" method="post" enctype="multipart/form-data" class="form-horizontal" role="form">
+				<form action=@isset($goods){{url('/shop/edit?id='.$goods->id)}} @else {{url('/shop/add')}} @endisset"" method="post" enctype="multipart/form-data" class="form-horizontal" role="form">
 					{{csrf_field()}}
 					<label>
 						<input name="id" hidden/>

+ 1 - 1
resources/views/admin/shop/goodsList.blade.php

@@ -90,7 +90,7 @@
 							</td>
 							<td>
 								<div class="btn-group">
-									<a href="/shop/edit/{{$goods->id}}" class="btn btn-primary"><i
+									<a href="/shop/edit?id={{$goods->id}}" class="btn btn-primary"><i
 												class="icon wb-edit"></i></a>
 									<button class="btn btn-danger"
 											onclick="delGoods('{{$goods->id}}','{{$goods->name}}')"><i

+ 1 - 1
resources/views/admin/ticket/ticketList.blade.php

@@ -8,7 +8,7 @@
 			<div class="panel-heading">
 				<h3 class="panel-title">工单列表</h3>
 				<div class="panel-actions">
-					<a href="/ticket/add" class="btn btn-primary btn-animate btn-animate-side">
+					<a href="/ticket/create" class="btn btn-primary btn-animate btn-animate-side">
 						<span><i class="icon wb-plus" aria-hidden="true"></i> {{trans('home.ticket_table_new_button')}}
 						</span>
 					</a>

+ 1 - 1
resources/views/admin/user/userList.blade.php

@@ -130,7 +130,7 @@
 									<a href="/admin/export/{{$user->id}}" class="btn btn-primary">
 										<i class="icon wb-code" aria-hidden="true"></i>
 									</a>
-									<a href="/admin/userMonitor/{{$user->id}}" class="btn btn-primary">
+									<a href="/admin/userMonitor?id={{$user->id}}" class="btn btn-primary">
 										<i class="icon wb-stats-bars" aria-hidden="true"></i>
 									</a>
 									<a href="/admin/onlineIPMonitor?id={{$user->id}}" class="btn btn-primary">

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

@@ -72,14 +72,14 @@
 				<li class="nav-item hidden-float" id="toggleMenubar">
 					<a class="nav-link" data-toggle="menubar" href="#" role="button">
 						<i class="icon hamburger hamburger-arrow-left">
-							<span class="sr-only">Toggle menubar切换菜单栏</span>
+							<span class="sr-only">Toggle menubar | 切换菜单栏</span>
 							<span class="hamburger-bar"></span>
 						</i>
 					</a>
 				</li>
 				<li class="nav-item hidden-sm-down" id="toggleFullscreen">
 					<a class="nav-link icon icon-fullscreen" data-toggle="fullscreen" href="#" role="button">
-						<span class="sr-only">Toggle fullscreen切换全屏</span>
+						<span class="sr-only">Toggle fullscreen | 切换全屏</span>
 					</a>
 				</li>
 			</ul>

+ 12 - 4
routes/web.php

@@ -57,7 +57,7 @@ Route::group(['middleware' => ['isForbidden', 'isAdminLogin', 'isAdmin']], funct
 		Route::get('userBanLogList', 'AdminController@userBanLogList'); // 用户封禁记录
 		Route::get('userOnlineIPList', 'AdminController@userOnlineIPList'); // 用户在线IP记录
 		Route::any('export/{id}', 'AdminController@export'); // 导出(查看)配置信息
-		Route::get('userMonitor/{id}', 'AdminController@userMonitor'); // 用户流量监控
+		Route::get('userMonitor', 'AdminController@userMonitor'); // 用户流量监控
 		Route::post('resetUserTraffic', 'AdminController@resetUserTraffic'); // 重置用户流量
 		Route::post('handleUserCredit', 'AdminController@handleUserCredit'); // 用户余额充值
 		Route::post("switchToUser", "AdminController@switchToUser"); // 转换成某个用户的身份
@@ -76,22 +76,30 @@ Route::group(['middleware' => ['isForbidden', 'isAdminLogin', 'isAdmin']], funct
 			Route::get('userRebateList', 'AffiliateController@userRebateList'); // 返利流水记录
 		});
 	});
+
 	Route::group(['prefix' => 'node'], function() {
 		Route::get('/', 'NodeController@nodeList'); // 节点列表
 		Route::any('add', 'NodeController@addNode'); // 添加节点
 		Route::any('edit', 'NodeController@editNode'); // 编辑节点
 		Route::post('delete', 'NodeController@delNode'); // 删除节点
-		Route::get('monitor/{id}', 'NodeController@nodeMonitor'); // 节点流量监控
+		Route::get('monitor', 'NodeController@nodeMonitor'); // 节点流量监控
 		Route::post('check', 'NodeController@checkNode'); // 节点阻断检测
 		Route::post('ping', 'NodeController@pingNode'); // 节点ping测速
 		Route::get('pingLog', 'NodeController@pingLog'); //节点Ping测速日志
-		// 授权
+		// 节点Api授权相关
 		Route::group(['prefix' => 'auth'], function() {
 			Route::get('/', 'NodeController@authList'); // 节点授权列表
 			Route::post('add', 'NodeController@addAuth'); // 添加节点授权
 			Route::post('delete', 'NodeController@delAuth'); // 删除节点授权
 			Route::post('refresh', 'NodeController@refreshAuth'); // 重置节点授权
 		});
+		// 节点域名tls相关
+		Route::group(['prefix' => 'certificate'], function() {
+			Route::get('/', 'NodeController@certificateList'); // 域名证书列表
+			Route::any('add', 'NodeController@addCertificate'); // 添加域名证书
+			Route::any('edit', 'NodeController@editCertificate'); // 编辑域名证书
+			Route::post('delete', 'NodeController@delCertificate'); // 删除域名证书
+		});
 	});
 
 	Route::group(['namespace' => 'Admin'], function() {
@@ -113,7 +121,7 @@ Route::group(['middleware' => ['isForbidden', 'isAdminLogin', 'isAdmin']], funct
 		Route::group(['prefix' => 'shop'], function() {
 			Route::any('/', 'ShopController@goodsList'); // 商品列表
 			Route::any('add', 'ShopController@addGoods'); // 添加商品
-			Route::any('edit/{id}', 'ShopController@editGoods'); // 编辑商品
+			Route::any('edit', 'ShopController@editGoods'); // 编辑商品
 			Route::post('delete', 'ShopController@delGoods'); // 删除商品
 		});