Files
ProxyPanel/app/Http/Controllers/Admin/NodeController.php
2021-01-12 14:32:02 +08:00

204 lines
7.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Controllers\Admin;
use App\Components\NetworkDetection;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\NodeRequest;
use App\Jobs\VNet\reloadNode;
use App\Models\Country;
use App\Models\Label;
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;
use Log;
use Response;
class NodeController extends Controller
{
// 节点列表
public function index(Request $request)
{
$status = $request->input('status');
$query = Node::with(['onlineLogs', 'dailyDataFlows']);
if (isset($status)) {
$query->whereStatus($status);
}
$nodeList = $query->orderByDesc('sort')->orderBy('id')->paginate(15)->appends($request->except('page'));
foreach ($nodeList as $node) {
// 在线人数
$online_log = $node->onlineLogs()->where('log_time', '>=', strtotime('-5 minutes'))->latest('log_time')->first();
$node->online_users = $online_log->online_user ?? 0;
// 已产生流量
$node->transfer = flowAutoShow($node->dailyDataFlows()->sum('total'));
// 负载10分钟以内
$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->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 ($request->has('labels')) {
$node->labels()->attach($request->input('labels'));
}
return Response::json(['status' => 'success', 'message' => '添加成功']);
}
} catch (Exception $e) {
Log::error('添加节点信息异常:'.$e->getMessage());
return Response::json(['status' => 'fail', 'message' => '添加线路失败:'.$e->getMessage()]);
}
return Response::json(['status' => 'fail', 'message' => '添加线路失败']);
}
// 编辑节点页面
public function edit(Node $node)
{
return view('admin.node.info', [
'node' => $node,
'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 update(NodeRequest $request, Node $node): JsonResponse
{
try {
$array = $request->validated();
Arr::forget($array, ['labels']);
if ($node->update($array)) {
// 更新节点标签
$node->labels()->sync($request->input('labels'));
return Response::json(['status' => 'success', 'message' => '编辑成功']);
}
} catch (Exception $e) {
Log::error('编辑节点信息异常:'.$e->getMessage());
return Response::json(['status' => 'fail', 'message' => '编辑失败:'.$e->getMessage()]);
}
return Response::json(['status' => 'fail', 'message' => '编辑失败']);
}
// 删除节点
public function destroy(Node $node): JsonResponse
{
try {
if ($node->delete()) {
return Response::json(['status' => 'success', 'message' => '删除成功']);
}
} catch (Exception $e) {
Log::error('删除线路失败:'.$e->getMessage());
return Response::json(['status' => 'fail', 'message' => '删除线路失败:'.$e->getMessage()]);
}
return Response::json(['status' => 'fail', 'message' => '删除线路失败']);
}
// 节点信息验证
public function checkNode(Node $node): JsonResponse
{
// 使用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] = (new NetworkDetection)->networkCheck($node->ip, true); //ICMP
$data[1] = (new NetworkDetection)->networkCheck($node->ip, false, $node->single ? $node->port : 22); //TCP
return Response::json(['status' => 'success', 'title' => '['.$node->name.']阻断信息', 'message' => $data]);
}
// 刷新节点地理位置
public function refreshGeo($id): JsonResponse
{
if ($id) {
$ret = Node::findOrFail($id)->refresh_geo();
} else {
foreach (Node::whereStatus(1)->get() as $node) {
$ret = $node->refresh_geo();
}
}
if ($ret) {
return Response::json(['status' => 'success', 'message' => '获取地理位置更新成功!']);
}
return Response::json(['status' => 'fail', 'message' => '获取地理位置更新失败!']);
}
// 重载节点
public function reload(Node $node): JsonResponse
{
if (reloadNode::dispatchNow($node)) {
return Response::json(['status' => 'success', 'message' => '重载成功!']);
}
return Response::json(['status' => 'fail', 'message' => '重载失败!']);
}
// 节点流量监控
public function nodeMonitor(Node $node)
{
return view('admin.node.monitor', array_merge(['nodeName' => $node->name, 'nodeServer' => $node->server], $this->DataFlowChart($node->id, true)));
}
// Ping节点延迟
public function pingNode(Node $node): JsonResponse
{
if ($result = (new NetworkDetection)->ping($node->is_ddns ? $node->server : $node->ip)) {
return Response::json([
'status' => 'success',
'message' => $result,
]);
}
return Response::json(['status' => 'fail', 'message' => 'Ping访问失败']);
}
}