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:
+13
-8
@@ -268,14 +268,19 @@ func (d *Data) Clone() *Data {
|
||||
}
|
||||
|
||||
type Settings struct {
|
||||
BrandName string `json:"brandName"`
|
||||
SessionHours float64 `json:"sessionHours"`
|
||||
ObservationTtlMinutes float64 `json:"observationTtlMinutes"`
|
||||
ActivityRetentionDays float64 `json:"activityRetentionDays"`
|
||||
CompletedJobRetentionDays float64 `json:"completedJobRetentionDays"`
|
||||
ExternalSubRefreshMinutes float64 `json:"externalSubRefreshMinutes,omitempty"`
|
||||
AllowPrivateSubSources bool `json:"allowPrivateSubSources,omitempty"`
|
||||
Extra extraFields `json:"-"`
|
||||
BrandName string `json:"brandName"`
|
||||
SessionHours float64 `json:"sessionHours"`
|
||||
ObservationTtlMinutes float64 `json:"observationTtlMinutes"`
|
||||
ActivityRetentionDays float64 `json:"activityRetentionDays"`
|
||||
CompletedJobRetentionDays float64 `json:"completedJobRetentionDays"`
|
||||
ExternalSubRefreshMinutes float64 `json:"externalSubRefreshMinutes,omitempty"`
|
||||
AllowPrivateSubSources bool `json:"allowPrivateSubSources,omitempty"`
|
||||
// Depleting-soon thresholds for the customers summary, aligned with
|
||||
// 3x-ui's expireDiff/trafficDiff settings (same names, units and
|
||||
// factory default of 0 = nobody counts as depleting soon).
|
||||
ExpireDiff float64 `json:"expireDiff,omitempty"`
|
||||
TrafficDiff float64 `json:"trafficDiff,omitempty"`
|
||||
Extra extraFields `json:"-"`
|
||||
}
|
||||
|
||||
func (s *Settings) UnmarshalJSON(raw []byte) error {
|
||||
|
||||
Reference in New Issue
Block a user