feat(panel): customers stats strip with 3x-ui depletion semantics (round-2 #1)

GET /api/customers gains a summary object (total/online/depleted/
depletingSoon/disabled/enabled) computed server-side; the customers page
renders it as a six-cell stats strip above the toolbar.

Predicates aligned verbatim with 3x-ui client_paging.go:
- depleted = (limit>0 && used>=limit) || (expiry set && expiry<=now),
  counted regardless of status;
- depletingSoon = active && !depleted && (expiry within expireDiff days
  || remaining traffic < trafficDiff GB), thresholds from new settings
  expireDiff/trafficDiff with 3x-ui's factory default 0 (nobody counts
  until configured);
- enabled = status active; disabled = manual suspensions only.
Online reuses the existing 3-minute presence projection.

Golden diff confined to the additive summary keys; summary_test.go
covers every bucket with thresholds off (soon=0) and on (soon=2).
This commit is contained in:
aaaamoooo
2026-10-21 11:18:00 +08:00
parent 1b32b57377
commit 35c9bd2cc0
6 changed files with 166 additions and 17 deletions
+19 -3
View File
@@ -1,6 +1,6 @@
{
"meta": {
"capturedAt": "2026-10-20T20:52:29.987Z",
"capturedAt": "2026-10-20T20:56:25.514Z",
"note": "Go panel golden baseline; see README.md in this directory."
},
"sections": {
@@ -105,7 +105,15 @@
"usedDownlinkBytes": 0,
"usedUplinkBytes": 0
}
]
],
"summary": {
"depleted": 0,
"depletingSoon": 0,
"disabled": 0,
"enabled": 2,
"online": 0,
"total": 2
}
},
"status": 200
},
@@ -1298,7 +1306,15 @@
"usedDownlinkBytes": 0,
"usedUplinkBytes": 0
}
]
],
"summary": {
"depleted": 0,
"depletingSoon": 0,
"disabled": 0,
"enabled": 3,
"online": 1,
"total": 3
}
},
"status": 200
},