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
@@ -0,0 +1,54 @@
<?php
namespace Tests\Unit\Admin;
use App\Http\Controllers\V2\Admin\Server\ManageController;
use Carbon\Carbon;
use ReflectionMethod;
use Tests\TestCase;
class NodeTrafficStatsWindowTest extends TestCase
{
public function test_node_traffic_windows_include_today_yesterday_and_current_month(): void
{
$timezone = config('app.timezone');
$reference = Carbon::create(2026, 4, 29, 13, 45, 0, $timezone)->timestamp;
$windows = $this->resolveWindows($reference);
$this->assertSame(Carbon::create(2026, 4, 29, 0, 0, 0, $timezone)->timestamp, $windows['today']['start']);
$this->assertSame(Carbon::create(2026, 4, 30, 0, 0, 0, $timezone)->timestamp, $windows['today']['end']);
$this->assertSame(Carbon::create(2026, 4, 28, 0, 0, 0, $timezone)->timestamp, $windows['yesterday']['start']);
$this->assertSame(Carbon::create(2026, 4, 29, 0, 0, 0, $timezone)->timestamp, $windows['yesterday']['end']);
$this->assertSame(Carbon::create(2026, 4, 1, 0, 0, 0, $timezone)->timestamp, $windows['month']['start']);
$this->assertSame(Carbon::create(2026, 5, 1, 0, 0, 0, $timezone)->timestamp, $windows['month']['end']);
}
public function test_node_traffic_windows_handle_first_day_of_month(): void
{
$timezone = config('app.timezone');
$reference = Carbon::create(2026, 5, 1, 8, 10, 0, $timezone)->timestamp;
$windows = $this->resolveWindows($reference);
$this->assertSame(Carbon::create(2026, 4, 30, 0, 0, 0, $timezone)->timestamp, $windows['yesterday']['start']);
$this->assertSame(Carbon::create(2026, 5, 1, 0, 0, 0, $timezone)->timestamp, $windows['yesterday']['end']);
$this->assertSame(Carbon::create(2026, 5, 1, 0, 0, 0, $timezone)->timestamp, $windows['month']['start']);
$this->assertSame(Carbon::create(2026, 6, 1, 0, 0, 0, $timezone)->timestamp, $windows['month']['end']);
}
/**
* @return array<string, array{start: int, end: int}>
*/
private function resolveWindows(int $referenceTimestamp): array
{
$controller = new ManageController();
$method = new ReflectionMethod(ManageController::class, 'resolveNodeTrafficWindows');
$method->setAccessible(true);
/** @var array<string, array{start: int, end: int}> $result */
$result = $method->invoke($controller, $referenceTimestamp);
return $result;
}
}