From 869d7fbe596ce46b61b609453c91f1795f0926b9 Mon Sep 17 00:00:00 2001 From: shanshanzhong Date: Tue, 13 Jan 2026 19:04:59 -0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7=E5=A4=87=E6=B3=A8=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E5=B9=B6=E4=BC=98=E5=8C=96=E7=94=A8=E6=88=B7=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E6=9B=B4=E6=96=B0=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为User类型添加remark字段以支持用户备注功能 重构updateUserBasicInfoLogic使用事务处理用户信息更新 优化错误处理和日志记录 --- apis/types.api | 1 + .../admin/user/updateUserBasicInfoLogic.go | 168 ++++++++++-------- internal/types/types.go | 1 + 3 files changed, 91 insertions(+), 79 deletions(-) diff --git a/apis/types.api b/apis/types.api index 3dfe833..fb965c3 100644 --- a/apis/types.api +++ b/apis/types.api @@ -28,6 +28,7 @@ type ( EnableTradeNotify bool `json:"enable_trade_notify"` LastLoginTime int64 `json:"last_login_time"` MemberStatus string `json:"member_status"` + Remark string `json:"remark"` AuthMethods []UserAuthMethod `json:"auth_methods"` UserDevices []UserDevice `json:"user_devices"` CreatedAt int64 `json:"created_at"` diff --git a/internal/logic/admin/user/updateUserBasicInfoLogic.go b/internal/logic/admin/user/updateUserBasicInfoLogic.go index 1cb3345..16ce972 100644 --- a/internal/logic/admin/user/updateUserBasicInfoLogic.go +++ b/internal/logic/admin/user/updateUserBasicInfoLogic.go @@ -2,6 +2,7 @@ package user import ( "context" + "fmt" "os" "strings" "time" @@ -13,6 +14,7 @@ import ( "github.com/perfect-panel/server/pkg/tool" "github.com/perfect-panel/server/pkg/xerr" "github.com/pkg/errors" + "gorm.io/gorm" ) type UpdateUserBasicInfoLogic struct { @@ -43,101 +45,109 @@ func (l *UpdateUserBasicInfoLogic) UpdateUserBasicInfo(req *types.UpdateUserBasi return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "Invalid Image Size") } - if userInfo.Balance != req.Balance { - change := req.Balance - userInfo.Balance - balanceLog := log.Balance{ - Type: log.BalanceTypeAdjust, - Amount: change, - OrderNo: "", - Balance: req.Balance, - Timestamp: time.Now().UnixMilli(), - } - content, _ := balanceLog.Marshal() - - err = l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{ - Type: log.TypeBalance.Uint8(), - Date: time.Now().Format(time.DateOnly), - ObjectID: userInfo.Id, - Content: string(content), - }) - if err != nil { - l.Errorw("[UpdateUserBasicInfoLogic] Insert Balance Log Error:", logger.Field("err", err.Error()), logger.Field("userId", req.UserId)) - return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "Insert Balance Log Error") - } - userInfo.Balance = req.Balance - } - - if userInfo.GiftAmount != req.GiftAmount { - change := req.GiftAmount - userInfo.GiftAmount - if change != 0 { - var changeType uint16 - if userInfo.GiftAmount < req.GiftAmount { - changeType = log.GiftTypeIncrease - } else { - changeType = log.GiftTypeReduce - } - giftLog := log.Gift{ - Type: changeType, + err = l.svcCtx.UserModel.Transaction(l.ctx, func(tx *gorm.DB) error { + if userInfo.Balance != req.Balance { + change := req.Balance - userInfo.Balance + balanceLog := log.Balance{ + Type: log.BalanceTypeAdjust, Amount: change, - Balance: req.GiftAmount, - Remark: "Admin adjustment", + OrderNo: "", + Balance: req.Balance, Timestamp: time.Now().UnixMilli(), } - content, _ := giftLog.Marshal() - // Add gift amount change log - err = l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{ - Type: log.TypeGift.Uint8(), + content, _ := balanceLog.Marshal() + + err = tx.Create(&log.SystemLog{ + Type: log.TypeBalance.Uint8(), Date: time.Now().Format(time.DateOnly), ObjectID: userInfo.Id, Content: string(content), - }) + }).Error if err != nil { - l.Errorw("[UpdateUserBasicInfoLogic] Insert Balance Log Error:", logger.Field("err", err.Error()), logger.Field("userId", req.UserId)) - return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "Insert Balance Log Error") + return err } - userInfo.GiftAmount = req.GiftAmount - } - } - - if req.Commission != userInfo.Commission { - - commentLog := log.Commission{ - Type: log.CommissionTypeAdjust, - Amount: req.Commission - userInfo.Commission, - Timestamp: time.Now().UnixMilli(), + userInfo.Balance = req.Balance } - content, _ := commentLog.Marshal() - err = l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{ - Type: log.TypeCommission.Uint8(), - Date: time.Now().Format(time.DateOnly), - ObjectID: userInfo.Id, - Content: string(content), - }) + if userInfo.GiftAmount != req.GiftAmount { + change := req.GiftAmount - userInfo.GiftAmount + if change != 0 { + var changeType uint16 + if userInfo.GiftAmount < req.GiftAmount { + changeType = log.GiftTypeIncrease + } else { + changeType = log.GiftTypeReduce + } + giftLog := log.Gift{ + Type: changeType, + Amount: change, + Balance: req.GiftAmount, + Remark: "Admin adjustment", + Timestamp: time.Now().UnixMilli(), + } + content, _ := giftLog.Marshal() + // Add gift amount change log + err = tx.Create(&log.SystemLog{ + Type: log.TypeGift.Uint8(), + Date: time.Now().Format(time.DateOnly), + ObjectID: userInfo.Id, + Content: string(content), + }).Error + if err != nil { + return err + } + userInfo.GiftAmount = req.GiftAmount + } + } + + if req.Commission != userInfo.Commission { + + commentLog := log.Commission{ + Type: log.CommissionTypeAdjust, + Amount: req.Commission - userInfo.Commission, + Timestamp: time.Now().UnixMilli(), + } + + content, _ := commentLog.Marshal() + err = tx.Create(&log.SystemLog{ + Type: log.TypeCommission.Uint8(), + Date: time.Now().Format(time.DateOnly), + ObjectID: userInfo.Id, + Content: string(content), + }).Error + if err != nil { + return err + } + userInfo.Commission = req.Commission + } + tool.DeepCopy(userInfo, req) + userInfo.Remark = req.Remark + userInfo.MemberStatus = req.MemberStatus + userInfo.OnlyFirstPurchase = &req.OnlyFirstPurchase + userInfo.ReferralPercentage = req.ReferralPercentage + + if req.Password != "" { + if userInfo.Id == 2 && isDemo { + return errors.New("Demo mode does not allow modification of the admin user password") + } + userInfo.Password = tool.EncodePassWord(req.Password) + userInfo.Algo = "default" + } + + err = l.svcCtx.UserModel.Update(l.ctx, userInfo, tx) if err != nil { - l.Errorw("[UpdateUserBasicInfoLogic] Insert Commission Log Error:", logger.Field("err", err.Error()), logger.Field("userId", req.UserId)) - return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "Insert Commission Log Error") + return err } - userInfo.Commission = req.Commission - } - tool.DeepCopy(userInfo, req) - userInfo.Remark = req.Remark - userInfo.MemberStatus = req.MemberStatus - userInfo.OnlyFirstPurchase = &req.OnlyFirstPurchase - userInfo.ReferralPercentage = req.ReferralPercentage - if req.Password != "" { - if userInfo.Id == 2 && isDemo { - return errors.Wrapf(xerr.NewErrCodeMsg(503, "Demo mode does not allow modification of the admin user password"), "UpdateUserBasicInfo failed: cannot update admin user password in demo mode") - } - userInfo.Password = tool.EncodePassWord(req.Password) - userInfo.Algo = "default" - } + return nil + }) - err = l.svcCtx.UserModel.Update(l.ctx, userInfo) if err != nil { l.Errorw("[UpdateUserBasicInfoLogic] Update User Error:", logger.Field("err", err.Error()), logger.Field("userId", req.UserId)) - return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "Update User Error") + if err.Error() == "Demo mode does not allow modification of the admin user password" { + return errors.Wrapf(xerr.NewErrCodeMsg(503, "Demo mode does not allow modification of the admin user password"), "UpdateUserBasicInfo failed: cannot update admin user password in demo mode") + } + return errors.Wrapf(xerr.NewErrCodeMsg(xerr.DatabaseUpdateError, fmt.Sprintf("Database update error: %v", err)), "Update User Error") } return nil diff --git a/internal/types/types.go b/internal/types/types.go index 8c3ae56..7fddcf0 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -2604,6 +2604,7 @@ type User struct { EnableTradeNotify bool `json:"enable_trade_notify"` LastLoginTime int64 `json:"last_login_time"` MemberStatus string `json:"member_status"` + Remark string `json:"remark"` AuthMethods []UserAuthMethod `json:"auth_methods"` UserDevices []UserDevice `json:"user_devices"` CreatedAt int64 `json:"created_at"`