mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-14 23:31:00 +00:00
fix(groups): report changed bulk moves without restarting xray (#6199)
This commit is contained in:
@@ -148,7 +148,6 @@ func (a *GroupController) bulkAdd(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
jsonObj(c, gin.H{"affected": affected}, nil)
|
||||
a.xrayService.SetToNeedRestart()
|
||||
notifyClientsChanged()
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/database"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/database/model"
|
||||
)
|
||||
|
||||
func TestAddToGroupReportsOnlyChangedRecordsIncludingNull(t *testing.T) {
|
||||
setupConflictDB(t)
|
||||
db := database.GetDB()
|
||||
if err := db.Create(&model.ClientGroup{Name: "paid"}).Error; err != nil {
|
||||
t.Fatalf("create group: %v", err)
|
||||
}
|
||||
rows := []model.ClientRecord{
|
||||
{Email: "same@example", UUID: "same", Group: "paid"},
|
||||
{Email: "other@example", UUID: "other", Group: "free"},
|
||||
{Email: "null@example", UUID: "null"},
|
||||
}
|
||||
if err := db.Create(&rows).Error; err != nil {
|
||||
t.Fatalf("create clients: %v", err)
|
||||
}
|
||||
if err := db.Model(&model.ClientRecord{}).Where("email = ?", "null@example").UpdateColumn("group_name", nil).Error; err != nil {
|
||||
t.Fatalf("set NULL group: %v", err)
|
||||
}
|
||||
|
||||
got, err := (&ClientService{}).AddToGroup([]string{"same@example", "other@example", "null@example", "missing@example"}, "paid")
|
||||
if err != nil {
|
||||
t.Fatalf("AddToGroup: %v", err)
|
||||
}
|
||||
if got != 2 {
|
||||
t.Fatalf("affected = %d, want 2 changed records", got)
|
||||
}
|
||||
got, err = (&ClientService{}).AddToGroup([]string{"same@example", "other@example", "null@example"}, "paid")
|
||||
if err != nil {
|
||||
t.Fatalf("second AddToGroup: %v", err)
|
||||
}
|
||||
if got != 0 {
|
||||
t.Fatalf("second affected = %d, want 0", got)
|
||||
}
|
||||
}
|
||||
@@ -234,7 +234,9 @@ func (s *ClientService) AddToGroup(emails []string, group string) (int, error) {
|
||||
var records []model.ClientRecord
|
||||
for _, batch := range chunkStrings(emails, sqlInChunk) {
|
||||
var rows []model.ClientRecord
|
||||
if err := db.Where("email IN ?", batch).Find(&rows).Error; err != nil {
|
||||
if err := db.Where("email IN ?", batch).
|
||||
Where("group_name IS NULL OR group_name <> ?", group).
|
||||
Find(&rows).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
records = append(records, rows...)
|
||||
@@ -248,13 +250,17 @@ func (s *ClientService) AddToGroup(emails []string, group string) (int, error) {
|
||||
}
|
||||
|
||||
tx := db.Begin()
|
||||
var affected int64
|
||||
for _, batch := range chunkStrings(affectedEmails, sqlInChunk) {
|
||||
if err := tx.Model(&model.ClientRecord{}).
|
||||
result := tx.Model(&model.ClientRecord{}).
|
||||
Where("email IN ?", batch).
|
||||
UpdateColumn("group_name", group).Error; err != nil {
|
||||
Where("group_name IS NULL OR group_name <> ?", group).
|
||||
UpdateColumn("group_name", group)
|
||||
if result.Error != nil {
|
||||
tx.Rollback()
|
||||
return 0, err
|
||||
return 0, result.Error
|
||||
}
|
||||
affected += result.RowsAffected
|
||||
}
|
||||
|
||||
var inboundIDs []int
|
||||
@@ -331,7 +337,7 @@ func (s *ClientService) AddToGroup(emails []string, group string) (int, error) {
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(records), nil
|
||||
return int(affected), nil
|
||||
}
|
||||
|
||||
func (s *ClientService) replaceGroupValue(oldName, newName string) (int, error) {
|
||||
|
||||
Reference in New Issue
Block a user