feat(api): 新增节点流量悬浮详情与即时自动上线同步
为 server/manage/getNodes 返回节点级今日、本月与累计流量统计, 并在节点管理页名称悬浮层展示上行、下行和合计流量。 同时为自动上线补齐单节点同步入口,在管理端保存、 批量更新以及 REST/WS 心跳后立即同步 show 状态, 避免复制节点后开启自动上线仍需等待定时任务。 另优化管理端前端 Docker 发布流程,默认仅构建 amd64, 并收敛 BuildKit 缓存导出以缩短发布时间
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Services;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\ServerGfwCheck;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ServerAutoOnlineService
|
||||
{
|
||||
@@ -12,50 +13,74 @@ class ServerAutoOnlineService
|
||||
$servers = Server::query()
|
||||
->where('auto_online', true)
|
||||
->get();
|
||||
$gfwStatuses = app(ServerGfwCheckService::class)->getLatestStatusesForServers($servers);
|
||||
|
||||
$result = [
|
||||
'total' => $servers->count(),
|
||||
return $this->syncServers($servers);
|
||||
}
|
||||
|
||||
public function syncServer(Server $server): array
|
||||
{
|
||||
if (!(bool) $server->auto_online) {
|
||||
return $this->emptyResult();
|
||||
}
|
||||
|
||||
return $this->syncServers(collect([$server]));
|
||||
}
|
||||
|
||||
private function syncServers(Collection $servers): array
|
||||
{
|
||||
$gfwStatuses = app(ServerGfwCheckService::class)->getLatestStatusesForServers($servers);
|
||||
$result = $this->emptyResult($servers->count());
|
||||
|
||||
foreach ($servers as $server) {
|
||||
$this->syncServerWithStatuses($server, $gfwStatuses, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function syncServerWithStatuses(Server $server, array $gfwStatuses, array &$result): void
|
||||
{
|
||||
$sourceNodeId = (int) ($server->parent_id ?: $server->id);
|
||||
$gfwStatus = $gfwStatuses[$sourceNodeId] ?? null;
|
||||
$isGfwManaged = (bool) ($server->gfw_check_enabled ?? true) && $gfwStatus !== null;
|
||||
$isGfwBlocked = $isGfwManaged && $gfwStatus === ServerGfwCheck::STATUS_BLOCKED;
|
||||
$isGfwHeld = $isGfwManaged
|
||||
&& (bool) $server->gfw_auto_hidden
|
||||
&& $gfwStatus !== ServerGfwCheck::STATUS_NORMAL;
|
||||
$shouldShow = !$isGfwBlocked && !$isGfwHeld && (int) $server->available_status !== Server::STATUS_OFFLINE;
|
||||
$shouldClearGfwAutoHidden = $gfwStatus === ServerGfwCheck::STATUS_NORMAL
|
||||
&& (bool) $server->gfw_auto_hidden;
|
||||
$wasShown = (bool) $server->show;
|
||||
|
||||
if ($wasShown === $shouldShow && !$shouldClearGfwAutoHidden) {
|
||||
$result['unchanged']++;
|
||||
return;
|
||||
}
|
||||
|
||||
$server->show = $shouldShow;
|
||||
if ($isGfwBlocked) {
|
||||
$server->gfw_auto_hidden = true;
|
||||
$server->gfw_auto_action_at = time();
|
||||
} elseif ($shouldClearGfwAutoHidden) {
|
||||
$server->gfw_auto_hidden = false;
|
||||
$server->gfw_auto_action_at = time();
|
||||
}
|
||||
$server->save();
|
||||
|
||||
$result['updated']++;
|
||||
if ($wasShown !== $shouldShow) {
|
||||
$shouldShow ? $result['shown']++ : $result['hidden']++;
|
||||
}
|
||||
}
|
||||
|
||||
private function emptyResult(int $total = 0): array
|
||||
{
|
||||
return [
|
||||
'total' => $total,
|
||||
'updated' => 0,
|
||||
'shown' => 0,
|
||||
'hidden' => 0,
|
||||
'unchanged' => 0,
|
||||
];
|
||||
|
||||
foreach ($servers as $server) {
|
||||
$sourceNodeId = (int) ($server->parent_id ?: $server->id);
|
||||
$gfwStatus = $gfwStatuses[$sourceNodeId] ?? null;
|
||||
$isGfwManaged = (bool) ($server->gfw_check_enabled ?? true) && $gfwStatus !== null;
|
||||
$isGfwBlocked = $isGfwManaged && $gfwStatus === ServerGfwCheck::STATUS_BLOCKED;
|
||||
$isGfwHeld = $isGfwManaged
|
||||
&& (bool) $server->gfw_auto_hidden
|
||||
&& $gfwStatus !== ServerGfwCheck::STATUS_NORMAL;
|
||||
$shouldShow = !$isGfwBlocked && !$isGfwHeld && (int) $server->available_status !== Server::STATUS_OFFLINE;
|
||||
$shouldClearGfwAutoHidden = $gfwStatus === ServerGfwCheck::STATUS_NORMAL
|
||||
&& (bool) $server->gfw_auto_hidden;
|
||||
$wasShown = (bool) $server->show;
|
||||
|
||||
if ($wasShown === $shouldShow && !$shouldClearGfwAutoHidden) {
|
||||
$result['unchanged']++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$server->show = $shouldShow;
|
||||
if ($isGfwBlocked) {
|
||||
$server->gfw_auto_hidden = true;
|
||||
$server->gfw_auto_action_at = time();
|
||||
} elseif ($shouldClearGfwAutoHidden) {
|
||||
$server->gfw_auto_hidden = false;
|
||||
$server->gfw_auto_action_at = time();
|
||||
}
|
||||
$server->save();
|
||||
|
||||
$result['updated']++;
|
||||
if ($wasShown !== $shouldShow) {
|
||||
$shouldShow ? $result['shown']++ : $result['hidden']++;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,6 +210,10 @@ class ServerService
|
||||
time(),
|
||||
3600
|
||||
);
|
||||
|
||||
if ((bool) $node->auto_online) {
|
||||
app(ServerAutoOnlineService::class)->syncServer($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user