mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-13 08:35:00 +03:00
fix(groups): preserve group traffic totals on global client reset (#7094)
Adjust group baselines before clearing client counters so group usage survives a global reset.
This commit is contained in:
committed by
GitHub
parent
efe768521d
commit
7da8fd23be
@@ -174,6 +174,40 @@ func TestGroupTotalsSurviveBulkClientReset(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupTotalsSurviveGlobalClientReset(t *testing.T) {
|
||||
initTrafficTestDB(t)
|
||||
svc := &ClientService{}
|
||||
|
||||
seedGroupedClient(t, "alice", "reset", 100, 200)
|
||||
seedGroupedClient(t, "bob", "unreset", 40, 60)
|
||||
if err := svc.ResetGroupTraffic("reset"); err != nil {
|
||||
t.Fatalf("ResetGroupTraffic: %v", err)
|
||||
}
|
||||
|
||||
if _, err := svc.ResetAllTraffics(); err != nil {
|
||||
t.Fatalf("ResetAllTraffics: %v", err)
|
||||
}
|
||||
if g := groupByName(t, svc, "unreset"); g.Up != 40 || g.Down != 60 || g.TrafficUsed != 100 {
|
||||
t.Fatalf("global reset changed accumulated group usage: got %+v, want up=40 down=60 used=100", g)
|
||||
}
|
||||
|
||||
var traffic xray.ClientTraffic
|
||||
if err := database.GetDB().Where("email = ?", "alice").First(&traffic).Error; err != nil {
|
||||
t.Fatalf("load alice traffic: %v", err)
|
||||
}
|
||||
if traffic.Up != 0 || traffic.Down != 0 {
|
||||
t.Fatalf("client traffic not reset: up=%d down=%d", traffic.Up, traffic.Down)
|
||||
}
|
||||
|
||||
if err := database.GetDB().Model(&traffic).
|
||||
Updates(map[string]any{"up": 10, "down": 20}).Error; err != nil {
|
||||
t.Fatalf("record new alice traffic: %v", err)
|
||||
}
|
||||
if g := groupByName(t, svc, "reset"); g.Up != 10 || g.Down != 20 || g.TrafficUsed != 30 {
|
||||
t.Fatalf("global reset hid new group usage: got %+v, want up=10 down=20 used=30", g)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupTotalsSurviveClientDelete(t *testing.T) {
|
||||
initTrafficTestDB(t)
|
||||
csvc := &ClientService{}
|
||||
|
||||
@@ -67,6 +67,14 @@ func adjustGroupBaselinesForRemovedTraffic(tx *gorm.DB, emails []string) error {
|
||||
return shiftGroupBaselines(tx, emails, -1)
|
||||
}
|
||||
|
||||
func adjustAllGroupBaselinesForRemovedTraffic(tx *gorm.DB) error {
|
||||
totals, err := sumGroupTraffic(tx, "c.group_name <> ''")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return applyGroupBaselineShift(tx, totals, -1)
|
||||
}
|
||||
|
||||
// adjustGroupBaselinesForRestoredTraffic shifts group baselines up by counters an
|
||||
// import restored, so usage from before the import never enters a group total.
|
||||
func adjustGroupBaselinesForRestoredTraffic(tx *gorm.DB, emails []string) error {
|
||||
@@ -92,6 +100,10 @@ func shiftGroupBaselines(tx *gorm.DB, emails []string, sign int64) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
return applyGroupBaselineShift(tx, totals, sign)
|
||||
}
|
||||
|
||||
func applyGroupBaselineShift(tx *gorm.DB, totals map[string]*groupCounters, sign int64) error {
|
||||
for name, d := range totals {
|
||||
if d.up == 0 && d.down == 0 {
|
||||
continue
|
||||
|
||||
@@ -252,6 +252,9 @@ func (s *ClientService) ResetAllTraffics() (bool, error) {
|
||||
if qErr != nil {
|
||||
return qErr
|
||||
}
|
||||
if err := adjustAllGroupBaselinesForRemovedTraffic(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
if affected, qErr = zeroClientTraffics(tx, nil, keepOff); qErr != nil {
|
||||
return qErr
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user