fix(api/settings): wrap batch update in database transaction

Use database transaction for batch settings update to ensure atomicity.
If any individual update fails, the entire batch will be rolled back,
preventing partial configuration updates.

- Wrap all updates in db.Transaction()
- Return detailed error on failure
master
veypi 1 week ago
parent 5304c30fb9
commit e96277ee85

@ -8,8 +8,10 @@ package settings
import ( import (
"github.com/veypi/vbase/auth" "github.com/veypi/vbase/auth"
"github.com/veypi/vbase/cfg"
"github.com/veypi/vbase/models" "github.com/veypi/vbase/models"
"github.com/veypi/vigo" "github.com/veypi/vigo"
"gorm.io/gorm"
) )
// UpdateItem 更新项 // UpdateItem 更新项
@ -45,13 +47,29 @@ func update(x *vigo.X, req *UpdateRequest) (*UpdateResponse, error) {
return nil, vigo.ErrForbidden.WithString("only admin can update settings") return nil, vigo.ErrForbidden.WithString("only admin can update settings")
} }
// 使用事务确保批量更新的原子性
db := cfg.DB()
updated := 0 updated := 0
err = db.Transaction(func(tx *gorm.DB) error {
for _, item := range req.Settings { for _, item := range req.Settings {
if err := models.SetSetting(item.Key, item.Value, userID); err != nil { var s models.Setting
return nil, vigo.ErrInternalServer.WithString("failed to update " + item.Key) if err := tx.Where("`key` = ?", item.Key).First(&s).Error; err != nil {
return err
}
s.Value = item.Value
s.UpdatedBy = userID
if err := tx.Save(&s).Error; err != nil {
return err
} }
updated++ updated++
} }
return nil
})
if err != nil {
return nil, vigo.ErrInternalServer.WithError(err)
}
return &UpdateResponse{ return &UpdateResponse{
Updated: updated, Updated: updated,

Loading…
Cancel
Save