diff --git a/app/Http/Controllers/Admin/SensitiveWordsController.php b/app/Http/Controllers/Admin/SensitiveWordsController.php index 508b18c5..5d7c23dc 100644 --- a/app/Http/Controllers/Admin/SensitiveWordsController.php +++ b/app/Http/Controllers/Admin/SensitiveWordsController.php @@ -20,7 +20,7 @@ class SensitiveWordsController extends Controller { public function sensitiveWordsList() { $view['list'] = SensitiveWords::query()->orderByDesc('id')->paginate(15); - return Response::view('admin.sensitiveWords.sensitiveWordsList', $view); + return Response::view('admin.config.sensitiveWordsList', $view); } // 添加敏感词 diff --git a/app/Http/Controllers/Admin/ShopController.php b/app/Http/Controllers/Admin/ShopController.php index 579587cd..2ddca10b 100644 --- a/app/Http/Controllers/Admin/ShopController.php +++ b/app/Http/Controllers/Admin/ShopController.php @@ -182,7 +182,7 @@ class ShopController extends Controller { DB::rollBack(); } - return Redirect::to('shop/editGoods/'.$id); + return Redirect::to('shop/edit/'.$id); }else{ $goods = Goods::query()->whereId($id)->first(); diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 042f41ec..c0cbb763 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -4,7 +4,6 @@ namespace App\Http\Controllers; use App\Components\Helpers; use App\Components\IPIP; -use App\Components\NetworkDetection; use App\Components\PushNotification; use App\Components\QQWry; use App\Models\Article; @@ -19,13 +18,9 @@ use App\Models\ReferralApply; use App\Models\ReferralLog; use App\Models\SsConfig; use App\Models\SsNode; -use App\Models\SsNodeInfo; use App\Models\SsNodeIp; use App\Models\SsNodeLabel; -use App\Models\SsNodeOnlineLog; -use App\Models\SsNodePing; use App\Models\SsNodeTrafficDaily; -use App\Models\SsNodeTrafficHourly; use App\Models\User; use App\Models\UserBanLog; use App\Models\UserCreditLog; @@ -473,444 +468,6 @@ class AdminController extends Controller { } } - // 节点列表 - public function nodeList(Request $request) { - if($request->isMethod('POST')){ - $id = $request->input('id'); - $node = SsNode::query()->whereId($id)->first(); - // 使用DDNS的node先通过gethostbyname获取ipv4地址 - if($node->is_ddns){ - $ip = gethostbyname($node->server); - if(strcmp($ip, $node->server) != 0){ - $node->ip = $ip; - }else{ - return Response::json(['status' => 'fail', 'title' => 'IP获取错误', 'message' => $node->name.'IP获取失败']); - } - } - $data[0] = NetworkDetection::networkCheck($node->ip, true); //ICMP - $data[1] = NetworkDetection::networkCheck($node->ip, false, $node->single? $node->port : null); //TCP - - return Response::json(['status' => 'success', 'title' => '['.$node->name.']阻断信息', 'message' => $data]); - }else{ - $status = $request->input('status'); - - $query = SsNode::query(); - - if(isset($status)){ - $query->whereStatus($status); - } - - $nodeList = $query->orderByDesc('status')->orderBy('id')->paginate(15)->appends($request->except('page')); - foreach($nodeList as $node){ - // 在线人数 - $online_log = SsNodeOnlineLog::query() - ->whereNodeId($node->id) - ->where('log_time', '>=', strtotime("-5 minutes")) - ->orderByDesc('id') - ->first(); - $node->online_users = empty($online_log)? 0 : $online_log->online_user; - - // 已产生流量 - $totalTraffic = SsNodeTrafficDaily::query()->whereNodeId($node->id)->sum('total'); - $node->transfer = flowAutoShow($totalTraffic); - - // 负载(10分钟以内) - $node_info = SsNodeInfo::query() - ->whereNodeId($node->id) - ->where('log_time', '>=', strtotime("-10 minutes")) - ->orderByDesc('id') - ->first(); - $node->isOnline = empty($node_info) || empty($node_info->load)? 0 : 1; - $node->load = $node->isOnline? $node_info->load : '离线'; - $node->uptime = empty($node_info)? 0 : seconds2time($node_info->uptime); - } - - $view['nodeList'] = $nodeList; - } - - return Response::view('admin.node.nodeList', $view); - } - - // 添加节点 - public function addNode(Request $request) { - if($request->isMethod('POST')){ - $validator = $this->nodeValidation($request); - if($validator){ - return $validator; - } - - // TODO:判断是否已存在绑定了相同域名的节点,提示是否要强制替换,或者不提示之前强制将其他节点的绑定域名置为空,然后发起域名绑定请求,或者请求进入队列 - try{ - DB::beginTransaction(); - - $node = new SsNode(); - $node->type = $request->input('type'); - $node->name = $request->input('name'); - $node->country_code = $request->input('country_code'); - $node->server = $request->input('server'); - $node->ip = $request->input('ip'); - $node->ipv6 = $request->input('ipv6'); - $node->relay_server = $request->input('relay_server'); - $node->relay_port = $request->input('relay_port'); - $node->level = $request->input('level'); - $node->speed_limit = $request->input('speed_limit'); - $node->client_limit = $request->input('client_limit'); - $node->description = $request->input('description'); - $node->method = $request->input('method'); - $node->protocol = $request->input('protocol'); - $node->protocol_param = $request->input('protocol_param'); - $node->obfs = $request->input('obfs'); - $node->obfs_param = $request->input('obfs_param'); - $node->traffic_rate = $request->input('traffic_rate'); - $node->is_subscribe = intval($request->input('is_subscribe')); - $node->is_ddns = intval($request->input('is_ddns')); - $node->is_relay = intval($request->input('is_relay')); - $node->is_udp = intval($request->input('is_udp')); - $node->ssh_port = $request->input('ssh_port'); - $node->detection_type = $request->input('detection_type'); - $node->compatible = intval($request->input('compatible')); - $node->single = intval($request->input('single')); - $node->port = $request->input('port'); - $node->passwd = $request->input('passwd'); - $node->sort = $request->input('sort'); - $node->status = intval($request->input('status')); - $node->v2_alter_id = $request->input('v2_alter_id'); - $node->v2_port = $request->input('v2_port'); - $node->v2_method = $request->input('v2_method'); - $node->v2_net = $request->input('v2_net'); - $node->v2_type = $request->input('v2_type'); - $node->v2_host = $request->input('v2_host'); - $node->v2_path = $request->input('v2_path'); - $node->v2_tls = intval($request->input('v2_tls')); - $node->v2_tls_insecure = intval($request->input('v2_tls_insecure')); - $node->v2_tls_insecure_ciphers = intval($request->input('v2_tls_insecure_ciphers')); - $node->save(); - - DB::commit(); - // 生成节点标签 - $this->makeNodeLabels($node->id, $request->input('labels')); - - return Response::json(['status' => 'success', 'message' => '添加成功']); - }catch(Exception $e){ - DB::rollBack(); - Log::error('添加节点信息异常:'.$e->getMessage()); - - return Response::json(['status' => 'fail', 'message' => '添加失败:'.$e->getMessage()]); - } - }else{ - $view['method_list'] = Helpers::methodList(); - $view['protocol_list'] = Helpers::protocolList(); - $view['obfs_list'] = Helpers::obfsList(); - $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(); - - return Response::view('admin.node.nodeInfo', $view); - } - } - - // 节点信息验证 - private function nodeValidation(Request $request) { - if($request->input('server')){ - $domain = $request->input('server'); - $domain = explode('.', $domain); - $domainSuffix = end($domain); // 取得域名后缀 - - if(!in_array($domainSuffix, \config('domains'))){ - return Response::json(['status' => 'fail', 'message' => '绑定域名不合法']); - } - } - - $validator = Validator::make($request->all(), [ - 'type' => 'required|between:1,3', - 'name' => 'required', - 'country_code' => 'required', - 'server' => 'required_if:is_ddns,1', - 'ssh_port' => 'numeric|between:0,65535', - 'traffic_rate' => 'required|numeric|min:0', - 'level' => 'required|numeric|between:0,255', - 'speed_limit' => 'required|numeric|min:0', - 'client_limit' => 'required|numeric|min:0', - 'port' => 'numeric|between:0,65535', - 'ip' => 'ipv4', - 'ipv6' => 'nullable|ipv6', - 'relay_server' => 'required_if:is_relay,1', - 'relay_port' => 'required_if:is_relay,1|numeric|between:0,65535', - 'method' => 'required_if:type,1', - 'protocol' => 'required_if:type,1', - 'obfs' => 'required_if:type,1', - 'is_subscribe' => 'boolean', - 'is_ddns' => 'boolean', - 'is_relay' => 'boolean', - 'is_udp' => 'boolean', - 'detection_type' => 'between:0,3', - 'compatible' => 'boolean', - 'single' => 'boolean', - 'sort' => 'required|numeric|between:0,255', - 'status' => 'boolean', - 'v2_alter_id' => 'required_if:type,2|numeric|between:0,65535', - 'v2_port' => 'required_if:type,2|numeric|between:0,65535', - 'v2_method' => 'required_if:type,2', - 'v2_net' => 'required_if:type,2', - 'v2_type' => 'required_if:type,2', - 'v2_tls' => 'boolean', - 'v2_tls_insecure' => 'required_if:v2_tls,1|boolean', - 'v2_tls_insecure_ciphers' => 'required_if:v2_tls,1|boolean' - ], [ - 'server.required_unless' => '开启DDNS, 域名不能为空', - ]); - - if($validator->fails()){ - return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]); - } - return false; - } - - // 生成节点标签 - private function makeNodeLabels($nodeId, $labels) { - // 先删除所有该节点的标签 - SsNodeLabel::query()->whereNodeId($nodeId)->delete(); - - if(!empty($labels) && is_array($labels)){ - foreach($labels as $label){ - $nodeLabel = new SsNodeLabel(); - $nodeLabel->node_id = $nodeId; - $nodeLabel->label_id = $label; - $nodeLabel->save(); - } - } - } - - // 编辑节点 - public function editNode(Request $request) { - $id = $request->input('id'); - - if($request->isMethod('POST')){ - $validator = $this->nodeValidation($request); - if($validator){ - return $validator; - } - - try{ - DB::beginTransaction(); - - $data = [ - 'type' => $request->input('type'), - 'name' => $request->input('name'), - 'country_code' => $request->input('country_code'), - 'server' => $request->input('server'), - 'ip' => $request->input('ip'), - 'ipv6' => $request->input('ipv6'), - 'relay_server' => $request->input('relay_server'), - 'relay_port' => $request->input('relay_port'), - 'level' => $request->input('level'), - 'speed_limit' => $request->input('speed_limit'), - 'client_limit' => $request->input('client_limit'), - 'description' => $request->input('description'), - 'method' => $request->input('method'), - 'protocol' => $request->input('protocol'), - 'protocol_param' => $request->input('protocol_param'), - 'obfs' => $request->input('obfs'), - 'obfs_param' => $request->input('obfs_param'), - 'traffic_rate' => $request->input('traffic_rate'), - 'is_subscribe' => intval($request->input('is_subscribe')), - 'is_ddns' => intval($request->input('is_ddns')), - 'is_relay' => intval($request->input('is_relay')), - 'is_udp' => intval($request->input('is_udp')), - 'ssh_port' => $request->input('ssh_port'), - 'detection_type' => $request->input('detection_type'), - 'compatible' => intval($request->input('compatible')), - 'single' => intval($request->input('single')), - 'port' => $request->input('port'), - 'passwd' => $request->input('passwd'), - 'sort' => $request->input('sort'), - 'status' => intval($request->input('status')), - 'v2_alter_id' => $request->input('v2_alter_id'), - 'v2_port' => $request->input('v2_port'), - 'v2_method' => $request->input('v2_method'), - 'v2_net' => $request->input('v2_net'), - 'v2_type' => $request->input('v2_type'), - 'v2_host' => $request->input('v2_host'), - 'v2_path' => $request->input('v2_path'), - 'v2_tls' => intval($request->input('v2_tls')), - 'v2_tls_insecure' => intval($request->input('v2_tls_insecure')), - 'v2_tls_insecure_ciphers' => intval($request->input('v2_tls_insecure_ciphers')) - ]; - - // 生成节点标签 - $this->makeNodeLabels($id, $request->input('labels')); - - SsNode::query()->whereId($id)->update($data); - // TODO:更新节点绑定的域名DNS(将节点IP更新到域名DNS 的A记录) - - DB::commit(); - - return Response::json(['status' => 'success', 'message' => '编辑成功']); - }catch(Exception $e){ - DB::rollBack(); - Log::error('编辑节点信息异常:'.$e->getMessage()); - - return Response::json(['status' => 'fail', 'message' => '编辑失败:'.$e->getMessage()]); - } - }else{ - $node = SsNode::query()->with(['label'])->whereId($id)->first(); - if($node){ - $node->labels = $node->label->pluck('label_id'); - } - - $view['node'] = $node; - $view['method_list'] = Helpers::methodList(); - $view['protocol_list'] = Helpers::protocolList(); - $view['obfs_list'] = Helpers::obfsList(); - $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(); - - return view('admin.node.nodeInfo', $view)->with(compact('node')); - } - } - - // 删除节点 - public function delNode(Request $request) { - $id = $request->input('id'); - - $node = SsNode::query()->whereId($id)->first(); - if(!$node){ - return Response::json(['status' => 'fail', 'data' => '', 'message' => '节点不存在,请重试']); - } - - try{ - DB::beginTransaction(); - // 删除分组关联、节点标签、节点相关日志 - SsNode::query()->whereId($id)->delete(); - SsNodeLabel::query()->whereNodeId($id)->delete(); - SsNodeInfo::query()->whereNodeId($id)->delete(); - SsNodeOnlineLog::query()->whereNodeId($id)->delete(); - SsNodeTrafficDaily::query()->whereNodeId($id)->delete(); - SsNodeTrafficHourly::query()->whereNodeId($id)->delete(); - SsNodePing::query()->whereNodeId($id)->delete(); - UserTrafficDaily::query()->whereNodeId($id)->delete(); - UserTrafficHourly::query()->whereNodeId($id)->delete(); - UserTrafficLog::query()->whereNodeId($id)->delete(); - - DB::commit(); - - return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']); - }catch(Exception $e){ - DB::rollBack(); - Log::error('删除节点信息异常:'.$e->getMessage()); - - return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败:'.$e->getMessage()]); - } - } - - // 节点流量监控 - public function nodeMonitor($node_id) { - $node = SsNode::query()->whereId($node_id)->orderByDesc('sort')->first(); - if(!$node){ - Session::flash('errorMsg', '节点不存在,请重试'); - - return Redirect::back(); - } - - // 查看流量 - $dailyData = []; - $hourlyData = []; - - // 节点一个月内的流量 - $nodeTrafficDaily = SsNodeTrafficDaily::query() - ->with(['info']) - ->whereNodeId($node->id) - ->where('created_at', '>=', date('Y-m', time())) - ->orderBy('created_at') - ->pluck('total') - ->toArray(); - $dailyTotal = date('d', time()) - 1;//今天不算,减一 - $dailyCount = count($nodeTrafficDaily); - for($x = 0; $x < ($dailyTotal - $dailyCount); $x++){ - $dailyData[$x] = 0; - } - for($x = ($dailyTotal - $dailyCount); $x < $dailyTotal; $x++){ - $dailyData[$x] = round($nodeTrafficDaily[$x - ($dailyTotal - $dailyCount)] / GB, 3); - } - - // 节点一天内的流量 - $nodeTrafficHourly = SsNodeTrafficHourly::query() - ->with(['info']) - ->whereNodeId($node->id) - ->where('created_at', '>=', date('Y-m-d', time())) - ->orderBy('created_at') - ->pluck('total') - ->toArray(); - $hourlyTotal = date('H', time()); - $hourlyCount = count($nodeTrafficHourly); - for($x = 0; $x < ($hourlyTotal - $hourlyCount); $x++){ - $hourlyData[$x] = 0; - } - for($x = ($hourlyTotal - $hourlyCount); $x < $hourlyTotal; $x++){ - $hourlyData[$x] = round($nodeTrafficHourly[$x - ($hourlyTotal - $hourlyCount)] / GB, 3); - } - - $view['trafficDaily'] = ['nodeName' => $node->name, 'dailyData' => json_encode($dailyData)]; - - $view['trafficHourly'] = ['nodeName' => $node->name, 'hourlyData' => json_encode($hourlyData)]; - - - // 本月天数数据 - $monthDays = []; - for($i = 1; $i <= date("d"); $i++){ - $monthDays[] = $i; - } - // 本日小时数据 - $dayHours = []; - for($i = 1; $i <= date("H"); $i++){ - $dayHours[] = $i; - } - - $view['nodeName'] = $node->name; - $view['nodeServer'] = $node->server; - $view['monthDays'] = json_encode($monthDays); - $view['dayHours'] = json_encode($dayHours); - - return Response::view('admin.node.nodeMonitor', $view); - } - - // Ping节点延迟 - public function pingNode(Request $request) { - $node = SsNode::query()->whereId($request->input('id'))->first(); - if(!$node){ - return Response::json(['status' => 'fail', 'message' => '节点不存在,请重试']); - } - - $result = NetworkDetection::ping($node->is_ddns? $node->server : $node->ip); - - if($result){ - $data[0] = $result['China Telecom']['time']?: '无'; - $data[1] = $result['China Unicom']['time']?: '无'; - $data[2] = $result['China Mobile']['time']?: '无'; - $data[3] = $result['Hong Kong']['time']?: '无'; - - return Response::json(['status' => 'success', 'message' => $data]); - }else{ - return Response::json(['status' => 'fail', 'message' => 'Ping访问失败']); - } - } - - // Ping节点延迟日志 - public function nodePingLog(Request $request) { - - $node_id = $request->input('nodeId'); - $query = SsNodePing::query(); - if(isset($node_id)){ - $query->whereNodeId($node_id); - } - - $view['nodeList'] = SsNode::query()->orderBy('id')->get(); - $view['pingLogs'] = $query->orderBy('id')->paginate(15)->appends($request->except('page')); - - return Response::view('admin.logs.nodePingLog', $view); - } - // 文章列表 public function articleList(Request $request) { $view['list'] = Article::query()->orderByDesc('sort')->paginate(15)->appends($request->except('page')); diff --git a/app/Http/Controllers/NodeController.php b/app/Http/Controllers/NodeController.php new file mode 100644 index 00000000..f84d5e3a --- /dev/null +++ b/app/Http/Controllers/NodeController.php @@ -0,0 +1,467 @@ +isMethod('POST')){ + $id = $request->input('id'); + $node = SsNode::query()->whereId($id)->first(); + // 使用DDNS的node先获取ipv4地址 + if($node->is_ddns){ + $ip = gethostbyname($node->server); + if(strcmp($ip, $node->server) != 0){ + $node->ip = $ip; + }else{ + return Response::json(['status' => 'fail', 'title' => 'IP获取错误', 'message' => $node->name.'IP获取失败']); + } + } + $data[0] = NetworkDetection::networkCheck($node->ip, true); //ICMP + $data[1] = NetworkDetection::networkCheck($node->ip, false, $node->single? $node->port : null); //TCP + + return Response::json(['status' => 'success', 'title' => '['.$node->name.']阻断信息', 'message' => $data]); + }else{ + $status = $request->input('status'); + + $query = SsNode::query(); + + if(isset($status)){ + $query->whereStatus($status); + } + + $nodeList = $query->orderByDesc('status')->orderBy('id')->paginate(15)->appends($request->except('page')); + foreach($nodeList as $node){ + // 在线人数 + $online_log = SsNodeOnlineLog::query() + ->whereNodeId($node->id) + ->where('log_time', '>=', strtotime("-5 minutes")) + ->orderByDesc('id') + ->first(); + $node->online_users = empty($online_log)? 0 : $online_log->online_user; + + // 已产生流量 + $totalTraffic = SsNodeTrafficDaily::query()->whereNodeId($node->id)->sum('total'); + $node->transfer = flowAutoShow($totalTraffic); + + // 负载(10分钟以内) + $node_info = SsNodeInfo::query() + ->whereNodeId($node->id) + ->where('log_time', '>=', strtotime("-10 minutes")) + ->orderByDesc('id') + ->first(); + $node->isOnline = empty($node_info) || empty($node_info->load)? 0 : 1; + $node->load = $node->isOnline? $node_info->load : '离线'; + $node->uptime = empty($node_info)? 0 : seconds2time($node_info->uptime); + } + + $view['nodeList'] = $nodeList; + } + + return Response::view('admin.node.nodeList', $view); + } + + // 添加节点 + public function addNode(Request $request) { + if($request->isMethod('POST')){ + $validator = $this->nodeValidation($request); + if($validator){ + return $validator; + } + + // TODO:判断是否已存在绑定了相同域名的节点,提示是否要强制替换,或者不提示之前强制将其他节点的绑定域名置为空,然后发起域名绑定请求,或者请求进入队列 + try{ + DB::beginTransaction(); + + $node = new SsNode(); + $node->type = $request->input('type'); + $node->name = $request->input('name'); + $node->country_code = $request->input('country_code'); + $node->server = $request->input('server'); + $node->ip = $request->input('ip'); + $node->ipv6 = $request->input('ipv6'); + $node->relay_server = $request->input('relay_server'); + $node->relay_port = $request->input('relay_port'); + $node->level = $request->input('level'); + $node->speed_limit = $request->input('speed_limit'); + $node->client_limit = $request->input('client_limit'); + $node->description = $request->input('description'); + $node->method = $request->input('method'); + $node->protocol = $request->input('protocol'); + $node->protocol_param = $request->input('protocol_param'); + $node->obfs = $request->input('obfs'); + $node->obfs_param = $request->input('obfs_param'); + $node->traffic_rate = $request->input('traffic_rate'); + $node->is_subscribe = intval($request->input('is_subscribe')); + $node->is_ddns = intval($request->input('is_ddns')); + $node->is_relay = intval($request->input('is_relay')); + $node->is_udp = intval($request->input('is_udp')); + $node->ssh_port = $request->input('ssh_port'); + $node->detection_type = $request->input('detection_type'); + $node->compatible = intval($request->input('compatible')); + $node->single = intval($request->input('single')); + $node->port = $request->input('port'); + $node->passwd = $request->input('passwd'); + $node->sort = $request->input('sort'); + $node->status = intval($request->input('status')); + $node->v2_alter_id = $request->input('v2_alter_id'); + $node->v2_port = $request->input('v2_port'); + $node->v2_method = $request->input('v2_method'); + $node->v2_net = $request->input('v2_net'); + $node->v2_type = $request->input('v2_type'); + $node->v2_host = $request->input('v2_host'); + $node->v2_path = $request->input('v2_path'); + $node->v2_tls = intval($request->input('v2_tls')); + $node->v2_tls_insecure = intval($request->input('v2_tls_insecure')); + $node->v2_tls_insecure_ciphers = intval($request->input('v2_tls_insecure_ciphers')); + $node->save(); + + DB::commit(); + // 生成节点标签 + $this->makeLabels($node->id, $request->input('labels')); + + return Response::json(['status' => 'success', 'message' => '添加成功']); + }catch(Exception $e){ + DB::rollBack(); + Log::error('添加节点信息异常:'.$e->getMessage()); + + return Response::json(['status' => 'fail', 'message' => '添加失败:'.$e->getMessage()]); + } + }else{ + $view['method_list'] = Helpers::methodList(); + $view['protocol_list'] = Helpers::protocolList(); + $view['obfs_list'] = Helpers::obfsList(); + $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(); + + return Response::view('admin.node.nodeInfo', $view); + } + } + + // 节点信息验证 + private function nodeValidation(Request $request) { + if($request->input('server')){ + $domain = $request->input('server'); + $domain = explode('.', $domain); + $domainSuffix = end($domain); // 取得域名后缀 + + if(!in_array($domainSuffix, config('domains'))){ + return Response::json(['status' => 'fail', 'message' => '绑定域名不合法']); + } + } + + $validator = Validator::make($request->all(), [ + 'type' => 'required|between:1,3', + 'name' => 'required', + 'country_code' => 'required', + 'server' => 'required_if:is_ddns,1', + 'ssh_port' => 'numeric|between:0,65535', + 'traffic_rate' => 'required|numeric|min:0', + 'level' => 'required|numeric|between:0,255', + 'speed_limit' => 'required|numeric|min:0', + 'client_limit' => 'required|numeric|min:0', + 'port' => 'numeric|between:0,65535', + 'ip' => 'ipv4', + 'ipv6' => 'nullable|ipv6', + 'relay_server' => 'required_if:is_relay,1', + 'relay_port' => 'required_if:is_relay,1|numeric|between:0,65535', + 'method' => 'required_if:type,1', + 'protocol' => 'required_if:type,1', + 'obfs' => 'required_if:type,1', + 'is_subscribe' => 'boolean', + 'is_ddns' => 'boolean', + 'is_relay' => 'boolean', + 'is_udp' => 'boolean', + 'detection_type' => 'between:0,3', + 'compatible' => 'boolean', + 'single' => 'boolean', + 'sort' => 'required|numeric|between:0,255', + 'status' => 'boolean', + 'v2_alter_id' => 'required_if:type,2|numeric|between:0,65535', + 'v2_port' => 'required_if:type,2|numeric|between:0,65535', + 'v2_method' => 'required_if:type,2', + 'v2_net' => 'required_if:type,2', + 'v2_type' => 'required_if:type,2', + 'v2_tls' => 'boolean', + 'v2_tls_insecure' => 'required_if:v2_tls,1|boolean', + 'v2_tls_insecure_ciphers' => 'required_if:v2_tls,1|boolean' + ], [ + 'server.required_unless' => '开启DDNS, 域名不能为空', + ]); + + if($validator->fails()){ + return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]); + } + return false; + } + + // 生成节点标签 + private function makeLabels($nodeId, $labels) { + // 先删除所有该节点的标签 + SsNodeLabel::query()->whereNodeId($nodeId)->delete(); + + if(!empty($labels) && is_array($labels)){ + foreach($labels as $label){ + $nodeLabel = new SsNodeLabel(); + $nodeLabel->node_id = $nodeId; + $nodeLabel->label_id = $label; + $nodeLabel->save(); + } + } + } + + // 编辑节点 + public function editNode(Request $request) { + $id = $request->input('id'); + + if($request->isMethod('POST')){ + $validator = $this->nodeValidation($request); + if($validator){ + return $validator; + } + + try{ + DB::beginTransaction(); + + $data = [ + 'type' => $request->input('type'), + 'name' => $request->input('name'), + 'country_code' => $request->input('country_code'), + 'server' => $request->input('server'), + 'ip' => $request->input('ip'), + 'ipv6' => $request->input('ipv6'), + 'relay_server' => $request->input('relay_server'), + 'relay_port' => $request->input('relay_port'), + 'level' => $request->input('level'), + 'speed_limit' => $request->input('speed_limit'), + 'client_limit' => $request->input('client_limit'), + 'description' => $request->input('description'), + 'method' => $request->input('method'), + 'protocol' => $request->input('protocol'), + 'protocol_param' => $request->input('protocol_param'), + 'obfs' => $request->input('obfs'), + 'obfs_param' => $request->input('obfs_param'), + 'traffic_rate' => $request->input('traffic_rate'), + 'is_subscribe' => intval($request->input('is_subscribe')), + 'is_ddns' => intval($request->input('is_ddns')), + 'is_relay' => intval($request->input('is_relay')), + 'is_udp' => intval($request->input('is_udp')), + 'ssh_port' => $request->input('ssh_port'), + 'detection_type' => $request->input('detection_type'), + 'compatible' => intval($request->input('compatible')), + 'single' => intval($request->input('single')), + 'port' => $request->input('port'), + 'passwd' => $request->input('passwd'), + 'sort' => $request->input('sort'), + 'status' => intval($request->input('status')), + 'v2_alter_id' => $request->input('v2_alter_id'), + 'v2_port' => $request->input('v2_port'), + 'v2_method' => $request->input('v2_method'), + 'v2_net' => $request->input('v2_net'), + 'v2_type' => $request->input('v2_type'), + 'v2_host' => $request->input('v2_host'), + 'v2_path' => $request->input('v2_path'), + 'v2_tls' => intval($request->input('v2_tls')), + 'v2_tls_insecure' => intval($request->input('v2_tls_insecure')), + 'v2_tls_insecure_ciphers' => intval($request->input('v2_tls_insecure_ciphers')) + ]; + + // 生成节点标签 + $this->makeLabels($id, $request->input('labels')); + + SsNode::query()->whereId($id)->update($data); + // TODO:更新节点绑定的域名DNS(将节点IP更新到域名DNS 的A记录) + + DB::commit(); + + return Response::json(['status' => 'success', 'message' => '编辑成功']); + }catch(Exception $e){ + DB::rollBack(); + Log::error('编辑节点信息异常:'.$e->getMessage()); + + return Response::json(['status' => 'fail', 'message' => '编辑失败:'.$e->getMessage()]); + } + }else{ + $node = SsNode::query()->with(['label'])->whereId($id)->first(); + if($node){ + $node->labels = $node->label->pluck('label_id'); + } + + $view['node'] = $node; + $view['method_list'] = Helpers::methodList(); + $view['protocol_list'] = Helpers::protocolList(); + $view['obfs_list'] = Helpers::obfsList(); + $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(); + + return view('admin.node.nodeInfo', $view)->with(compact('node')); + } + } + + // 删除节点 + public function delNode(Request $request) { + $id = $request->input('id'); + + $node = SsNode::query()->whereId($id)->first(); + if(!$node){ + return Response::json(['status' => 'fail', 'data' => '', 'message' => '节点不存在,请重试']); + } + + try{ + DB::beginTransaction(); + // 删除分组关联、节点标签、节点相关日志 + SsNode::query()->whereId($id)->delete(); + SsNodeLabel::query()->whereNodeId($id)->delete(); + SsNodeInfo::query()->whereNodeId($id)->delete(); + SsNodeOnlineLog::query()->whereNodeId($id)->delete(); + SsNodeTrafficDaily::query()->whereNodeId($id)->delete(); + SsNodeTrafficHourly::query()->whereNodeId($id)->delete(); + SsNodePing::query()->whereNodeId($id)->delete(); + UserTrafficDaily::query()->whereNodeId($id)->delete(); + UserTrafficHourly::query()->whereNodeId($id)->delete(); + UserTrafficLog::query()->whereNodeId($id)->delete(); + + DB::commit(); + + return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']); + }catch(Exception $e){ + DB::rollBack(); + Log::error('删除节点信息异常:'.$e->getMessage()); + + return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败:'.$e->getMessage()]); + } + } + + // 节点流量监控 + public function nodeMonitor($node_id) { + $node = SsNode::query()->whereId($node_id)->orderByDesc('sort')->first(); + if(!$node){ + Session::flash('errorMsg', '节点不存在,请重试'); + + return Redirect::back(); + } + + // 查看流量 + $dailyData = []; + $hourlyData = []; + + // 节点一个月内的流量 + $nodeTrafficDaily = SsNodeTrafficDaily::query() + ->with(['info']) + ->whereNodeId($node->id) + ->where('created_at', '>=', date('Y-m', time())) + ->orderBy('created_at') + ->pluck('total') + ->toArray(); + $dailyTotal = date('d', time()) - 1;//今天不算,减一 + $dailyCount = count($nodeTrafficDaily); + for($x = 0; $x < ($dailyTotal - $dailyCount); $x++){ + $dailyData[$x] = 0; + } + for($x = ($dailyTotal - $dailyCount); $x < $dailyTotal; $x++){ + $dailyData[$x] = round($nodeTrafficDaily[$x - ($dailyTotal - $dailyCount)] / GB, 3); + } + + // 节点一天内的流量 + $nodeTrafficHourly = SsNodeTrafficHourly::query() + ->with(['info']) + ->whereNodeId($node->id) + ->where('created_at', '>=', date('Y-m-d', time())) + ->orderBy('created_at') + ->pluck('total') + ->toArray(); + $hourlyTotal = date('H', time()); + $hourlyCount = count($nodeTrafficHourly); + for($x = 0; $x < ($hourlyTotal - $hourlyCount); $x++){ + $hourlyData[$x] = 0; + } + for($x = ($hourlyTotal - $hourlyCount); $x < $hourlyTotal; $x++){ + $hourlyData[$x] = round($nodeTrafficHourly[$x - ($hourlyTotal - $hourlyCount)] / GB, 3); + } + + $view['trafficDaily'] = ['nodeName' => $node->name, 'dailyData' => json_encode($dailyData)]; + + $view['trafficHourly'] = ['nodeName' => $node->name, 'hourlyData' => json_encode($hourlyData)]; + + + // 本月天数数据 + $monthDays = []; + for($i = 1; $i <= date("d"); $i++){ + $monthDays[] = $i; + } + // 本日小时数据 + $dayHours = []; + for($i = 1; $i <= date("H"); $i++){ + $dayHours[] = $i; + } + + $view['nodeName'] = $node->name; + $view['nodeServer'] = $node->server; + $view['monthDays'] = json_encode($monthDays); + $view['dayHours'] = json_encode($dayHours); + + return Response::view('admin.node.nodeMonitor', $view); + } + + // Ping节点延迟 + public function pingNode(Request $request) { + $node = SsNode::query()->whereId($request->input('id'))->first(); + if(!$node){ + return Response::json(['status' => 'fail', 'message' => '节点不存在,请重试']); + } + + $result = NetworkDetection::ping($node->is_ddns? $node->server : $node->ip); + + if($result){ + $data[0] = $result['China Telecom']['time']?: '无'; + $data[1] = $result['China Unicom']['time']?: '无'; + $data[2] = $result['China Mobile']['time']?: '无'; + $data[3] = $result['Hong Kong']['time']?: '无'; + + return Response::json(['status' => 'success', 'message' => $data]); + }else{ + return Response::json(['status' => 'fail', 'message' => 'Ping访问失败']); + } + } + + // Ping节点延迟日志 + public function pingLog(Request $request) { + + $node_id = $request->input('nodeId'); + $query = SsNodePing::query(); + if(isset($node_id)){ + $query->whereNodeId($node_id); + } + + $view['nodeList'] = SsNode::query()->orderBy('id')->get(); + $view['pingLogs'] = $query->orderBy('id')->paginate(15)->appends($request->except('page')); + + return Response::view('admin.logs.nodePingLog', $view); + } +} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index bd42458f..88504211 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -369,7 +369,7 @@ class UserController extends Controller { } // 添加工单 - public function addTicket(Request $request) { + public function createTicket(Request $request) { $title = $request->input('title'); $content = clean($request->input('content')); $content = str_replace("eval", "", str_replace("atob", "", $content)); diff --git a/resources/views/admin/sensitiveWords/sensitiveWordsList.blade.php b/resources/views/admin/config/sensitiveWordsList.blade.php similarity index 98% rename from resources/views/admin/sensitiveWords/sensitiveWordsList.blade.php rename to resources/views/admin/config/sensitiveWordsList.blade.php index 8120fecf..84a110a7 100644 --- a/resources/views/admin/sensitiveWords/sensitiveWordsList.blade.php +++ b/resources/views/admin/config/sensitiveWordsList.blade.php @@ -133,7 +133,7 @@ confirmButtonText: '确定', }).then((result) => { if (result.value) { - $.post("/sensitiveWords/del", {id: id, _token: '{{csrf_token()}}'}, function (ret) { + $.post("/sensitiveWords/delete", {id: id, _token: '{{csrf_token()}}'}, function (ret) { if (ret.status === 'success') { swal.fire({title: ret.message, type: 'success', timer: 1000, showConfirmButton: false}) .then(() => window.location.reload()) diff --git a/resources/views/admin/coupon/addCoupon.blade.php b/resources/views/admin/coupon/addCoupon.blade.php index 07f1d09b..6e960702 100644 --- a/resources/views/admin/coupon/addCoupon.blade.php +++ b/resources/views/admin/coupon/addCoupon.blade.php @@ -15,7 +15,7 @@
@if (Session::has('successMsg')) @@ -33,7 +33,7 @@ @endif