fix(api): 修复节点流量限额共享统计与父子显隐联动

统一节点流量统计与限额展示口径,节点详情新增昨日流量,
并让今日、昨日和本月使用清晰的半开时间窗口聚合

同 machine_id 或同 host 的节点现在共享当前账期已用流量,
管理端优先使用后端 traffic_limit_snapshot 展示月额度状态,
mi-node 下发的 current_used 也改为共享账期统计

新增 parent_auto_hidden 标记与父节点显隐联动服务,父节点
因自动上线或流量限额变为不可展示时会隐藏当前显示的子节点,
恢复时只恢复这批自动隐藏的子节点,避免覆盖手动操作
This commit is contained in:
yinjianm
2026-04-29 02:24:57 +08:00
parent 922e86070d
commit e847252e12
27 changed files with 2078 additions and 47 deletions
@@ -5,6 +5,7 @@ namespace Tests\Unit;
use App\Models\Server;
use App\Models\ServerGfwCheck;
use App\Services\ServerAutoOnlineService;
use App\Services\ServerParentVisibilityService;
use App\Services\ServerService;
use App\Utils\CacheKey;
use Illuminate\Foundation\Testing\RefreshDatabase;
@@ -15,6 +16,13 @@ class ServerAutoOnlineServiceTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
Cache::flush();
}
public function test_sync_updates_only_nodes_with_auto_online_enabled(): void
{
$managedOffline = $this->makeServer([
@@ -115,6 +123,42 @@ class ServerAutoOnlineServiceTest extends TestCase
$this->assertTrue($managedOnline->fresh()->show);
}
public function test_parent_auto_online_sync_hides_and_restores_only_auto_hidden_children(): void
{
$parent = $this->makeServer([
'name' => 'parent-auto-managed',
'show' => true,
'auto_online' => true,
]);
$visibleChild = $this->makeServer([
'name' => 'visible-child',
'parent_id' => $parent->id,
'show' => true,
]);
$manualHiddenChild = $this->makeServer([
'name' => 'manual-hidden-child',
'parent_id' => $parent->id,
'show' => false,
]);
app(ServerAutoOnlineService::class)->sync();
$this->assertFalse($parent->fresh()->show);
$this->assertFalse($visibleChild->fresh()->show);
$this->assertTrue($visibleChild->fresh()->parent_auto_hidden);
$this->assertFalse($manualHiddenChild->fresh()->show);
$this->assertFalse($manualHiddenChild->fresh()->parent_auto_hidden);
$this->markNodeOnline($parent);
app(ServerAutoOnlineService::class)->sync();
$this->assertTrue($parent->fresh()->show);
$this->assertTrue($visibleChild->fresh()->show);
$this->assertFalse($visibleChild->fresh()->parent_auto_hidden);
$this->assertFalse($manualHiddenChild->fresh()->show);
$this->assertFalse($manualHiddenChild->fresh()->parent_auto_hidden);
}
public function test_touch_node_syncs_auto_online_node_immediately(): void
{
$managedOnline = $this->makeServer([
@@ -128,6 +172,22 @@ class ServerAutoOnlineServiceTest extends TestCase
$this->assertTrue($managedOnline->fresh()->show);
}
public function test_clear_parent_auto_hidden_prevents_later_parent_restore_from_overriding_manual_choice(): void
{
$child = $this->makeServer([
'name' => 'manually-adjusted-child',
'show' => false,
'parent_auto_hidden' => true,
'parent_auto_action_at' => 123456,
]);
app(ServerParentVisibilityService::class)->clearParentAutoHidden($child);
$child->save();
$this->assertFalse($child->fresh()->parent_auto_hidden);
$this->assertNull($child->fresh()->parent_auto_action_at);
}
private function makeServer(array $attributes = []): Server
{
return Server::create(array_merge([
@@ -142,6 +202,7 @@ class ServerAutoOnlineServiceTest extends TestCase
'auto_online' => false,
'gfw_check_enabled' => true,
'gfw_auto_hidden' => false,
'parent_auto_hidden' => false,
'enabled' => true,
], $attributes));
}