feat(api): 新增节点墙状态检测闭环

新增父节点墙状态检测任务、结果上报与节点列表状态装饰,
支持子节点继承父节点检测结果并通过 WS/REST 双链路执行

管理端补充墙状态筛选、搜索、单行与批量检测入口,
同时更新知识库归档并新增后续自动上线方案包
This commit is contained in:
yinjianm
2026-04-27 23:45:44 +08:00
parent b3a8d504d1
commit 9af9dd0df7
23 changed files with 1365 additions and 7 deletions
@@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\ServerSave;
use App\Models\Server;
use App\Models\ServerGroup;
use App\Services\ServerGfwCheckService;
use App\Services\ServerService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -16,7 +17,7 @@ class ManageController extends Controller
{
public function getNodes(Request $request)
{
$servers = ServerService::getAllServers()->map(function ($item) {
$servers = app(ServerGfwCheckService::class)->decorateServers(ServerService::getAllServers())->map(function ($item) {
$item['groups'] = ServerGroup::whereIn('id', $item['group_ids'] ?? [])->get(['name', 'id']);
$item['parent'] = $item->parent;
return $item;
@@ -277,6 +278,25 @@ class ManageController extends Controller
}
}
public function checkGfw(Request $request)
{
$params = $request->validate([
'ids' => 'required|array',
'ids.*' => 'integer',
]);
if (empty($params['ids'])) {
return $this->fail([400, '请选择需要检测的节点']);
}
$result = app(ServerGfwCheckService::class)->startChecks(
$params['ids'],
$request->user()?->id
);
return $this->success($result);
}
/**
* 复制节点
* @param \Illuminate\Http\Request $request
@@ -3,6 +3,7 @@
namespace App\Http\Controllers\V2\Server;
use App\Http\Controllers\Controller;
use App\Services\ServerGfwCheckService;
use App\Services\ServerService;
use App\WebSocket\NodeWorker;
use Illuminate\Http\Request;
@@ -75,4 +76,33 @@ class ServerController extends Controller
return response()->json(['data' => true]);
}
public function gfwTask(Request $request, ServerGfwCheckService $service): JsonResponse
{
$node = $request->attributes->get('node_info');
if (!$node) {
return response()->json(['data' => null]);
}
return response()->json(['data' => $service->getPendingTaskForNode($node)]);
}
public function gfwReport(Request $request, ServerGfwCheckService $service): JsonResponse
{
$node = $request->attributes->get('node_info');
if (!$node) {
return response()->json(['data' => false], 404);
}
$params = $request->validate([
'check_id' => 'required|integer',
'status' => 'nullable|string',
'summary' => 'nullable|array',
'operator_summary' => 'nullable|array',
'raw_result' => 'nullable|array',
'error_message' => 'nullable|string',
]);
return response()->json(['data' => $service->reportResult($node, $params)]);
}
}
+1
View File
@@ -91,6 +91,7 @@ class AdminRoute
$router->post('/sort', [ManageController::class, 'sort']);
$router->post('/batchDelete', [ManageController::class, 'batchDelete']);
$router->post('/batchUpdate', [ManageController::class, 'batchUpdate']);
$router->post('/checkGfw', [ManageController::class, 'checkGfw']);
$router->post('/resetTraffic', [ManageController::class, 'resetTraffic']);
$router->post('/batchResetTraffic', [ManageController::class, 'batchResetTraffic']);
$router->get('/generateEchKey', [ManageController::class, 'generateEchKey']);
+2
View File
@@ -18,6 +18,8 @@ class ServerRoute
], function ($route) {
$route->match(['GET', 'POST'], 'handshake', [ServerController::class, 'handshake']);
$route->post('report', [ServerController::class, 'report']);
$route->get('gfw/task', [ServerController::class, 'gfwTask']);
$route->post('gfw/report', [ServerController::class, 'gfwReport']);
$route->get('config', [UniProxyController::class, 'config']);
$route->get('user', [UniProxyController::class, 'user']);
$route->post('push', [UniProxyController::class, 'push']);