From 6d9263ceefcb300f115b689f604d949b166434aa Mon Sep 17 00:00:00 2001 From: shanshanzhong Date: Mon, 25 May 2026 19:52:28 -0700 Subject: [PATCH] fix: guard RefererId and monetary fields against zero-value overwrite in updateUserBasicInfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change RefererId, Balance, GiftAmount, Commission from int64 to *int64 in UpdateUserBasiceInfoRequest - When field is nil (not sent by client), skip update entirely — prevents zero-value from clobbering existing data - When field is non-nil, dereference and apply as before (including explicit 0 to clear a value) - Mirrors the existing guard pattern already used for Avatar, ReferCode, Enable, IsAdmin, etc. Fixes: RefererId unconditional overwrite at line 123 (P02) Fixes: Balance/GiftAmount/Commission triggering adjustment to 0 when omitted (P03) Co-authored-by: multica-agent --- apis/admin/user.api | 28 +++++++++---------- .../admin/user/updateUserBasicInfoLogic.go | 28 ++++++++++--------- internal/types/types.go | 28 +++++++++---------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/apis/admin/user.api b/apis/admin/user.api index aa6243f..3f4ba90 100644 --- a/apis/admin/user.api +++ b/apis/admin/user.api @@ -38,20 +38,20 @@ type ( Id int64 `form:"id" validate:"required"` } UpdateUserBasiceInfoRequest { - UserId int64 `json:"user_id" validate:"required"` - Password string `json:"password"` - Avatar string `json:"avatar"` - Balance int64 `json:"balance"` - Commission int64 `json:"commission"` - ReferralPercentage uint8 `json:"referral_percentage"` - OnlyFirstPurchase *bool `json:"only_first_purchase"` - GiftAmount int64 `json:"gift_amount"` - Telegram int64 `json:"telegram"` - ReferCode string `json:"refer_code"` - RefererId int64 `json:"referer_id"` - Enable *bool `json:"enable"` - IsAdmin *bool `json:"is_admin"` - Remark string `json:"remark"` + UserId int64 `json:"user_id" validate:"required"` + Password string `json:"password"` + Avatar string `json:"avatar"` + Balance *int64 `json:"balance"` + Commission *int64 `json:"commission"` + ReferralPercentage uint8 `json:"referral_percentage"` + OnlyFirstPurchase *bool `json:"only_first_purchase"` + GiftAmount *int64 `json:"gift_amount"` + Telegram int64 `json:"telegram"` + ReferCode string `json:"refer_code"` + RefererId *int64 `json:"referer_id"` + Enable *bool `json:"enable"` + IsAdmin *bool `json:"is_admin"` + Remark string `json:"remark"` } UpdateUserNotifySettingRequest { UserId int64 `json:"user_id" validate:"required"` diff --git a/internal/logic/admin/user/updateUserBasicInfoLogic.go b/internal/logic/admin/user/updateUserBasicInfoLogic.go index fcefa92..d183604 100644 --- a/internal/logic/admin/user/updateUserBasicInfoLogic.go +++ b/internal/logic/admin/user/updateUserBasicInfoLogic.go @@ -46,13 +46,13 @@ func (l *UpdateUserBasicInfoLogic) UpdateUserBasicInfo(req *types.UpdateUserBasi } err = l.svcCtx.UserModel.Transaction(l.ctx, func(tx *gorm.DB) error { - if userInfo.Balance != req.Balance { - change := req.Balance - userInfo.Balance + if req.Balance != nil && userInfo.Balance != *req.Balance { + change := *req.Balance - userInfo.Balance balanceLog := log.Balance{ Type: log.BalanceTypeAdjust, Amount: change, OrderNo: "", - Balance: req.Balance, + Balance: *req.Balance, Timestamp: time.Now().UnixMilli(), } content, _ := balanceLog.Marshal() @@ -66,14 +66,14 @@ func (l *UpdateUserBasicInfoLogic) UpdateUserBasicInfo(req *types.UpdateUserBasi if err != nil { return err } - userInfo.Balance = req.Balance + userInfo.Balance = *req.Balance } - if userInfo.GiftAmount != req.GiftAmount { - change := req.GiftAmount - userInfo.GiftAmount + if req.GiftAmount != nil && userInfo.GiftAmount != *req.GiftAmount { + change := *req.GiftAmount - userInfo.GiftAmount if change != 0 { var changeType uint16 - if userInfo.GiftAmount < req.GiftAmount { + if userInfo.GiftAmount < *req.GiftAmount { changeType = log.GiftTypeIncrease } else { changeType = log.GiftTypeReduce @@ -81,7 +81,7 @@ func (l *UpdateUserBasicInfoLogic) UpdateUserBasicInfo(req *types.UpdateUserBasi giftLog := log.Gift{ Type: changeType, Amount: change, - Balance: req.GiftAmount, + Balance: *req.GiftAmount, Remark: "Admin adjustment", Timestamp: time.Now().UnixMilli(), } @@ -96,23 +96,23 @@ func (l *UpdateUserBasicInfoLogic) UpdateUserBasicInfo(req *types.UpdateUserBasi if err != nil { return err } - userInfo.GiftAmount = req.GiftAmount + userInfo.GiftAmount = *req.GiftAmount } } - if req.Commission != userInfo.Commission { + if req.Commission != nil && *req.Commission != userInfo.Commission { if isWithdrawalScene(req.Remark) { logWithdrawalGuard(l.Logger, userInfo.Id) return errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "commission overwrite is blocked in withdrawal scene") } - change := req.Commission - userInfo.Commission + change := *req.Commission - userInfo.Commission if err = l.svcCtx.UserModel.UpdateCommission(l.ctx, userInfo.Id, change, tx); err != nil { return err } if err = logicCommon.WriteCommissionLog(tx, userInfo.Id, log.CommissionTypeAdjust, change, ""); err != nil { return err } - userInfo.Commission = req.Commission + userInfo.Commission = *req.Commission } if req.Avatar != "" { userInfo.Avatar = req.Avatar @@ -120,7 +120,9 @@ func (l *UpdateUserBasicInfoLogic) UpdateUserBasicInfo(req *types.UpdateUserBasi if req.ReferCode != "" { userInfo.ReferCode = req.ReferCode } - userInfo.RefererId = req.RefererId + if req.RefererId != nil { + userInfo.RefererId = *req.RefererId + } if req.Enable != nil { userInfo.Enable = req.Enable } diff --git a/internal/types/types.go b/internal/types/types.go index 385aec1..8c5787f 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -3223,20 +3223,20 @@ type UpdateUserAuthMethodRequest struct { } type UpdateUserBasiceInfoRequest struct { - UserId int64 `json:"user_id" validate:"required"` - Password string `json:"password"` - Avatar string `json:"avatar"` - Balance int64 `json:"balance"` - Commission int64 `json:"commission"` - ReferralPercentage uint8 `json:"referral_percentage"` - OnlyFirstPurchase *bool `json:"only_first_purchase"` - GiftAmount int64 `json:"gift_amount"` - Telegram int64 `json:"telegram"` - ReferCode string `json:"refer_code"` - RefererId int64 `json:"referer_id"` - Enable *bool `json:"enable"` - IsAdmin *bool `json:"is_admin"` - Remark string `json:"remark"` + UserId int64 `json:"user_id" validate:"required"` + Password string `json:"password"` + Avatar string `json:"avatar"` + Balance *int64 `json:"balance"` + Commission *int64 `json:"commission"` + ReferralPercentage uint8 `json:"referral_percentage"` + OnlyFirstPurchase *bool `json:"only_first_purchase"` + GiftAmount *int64 `json:"gift_amount"` + Telegram int64 `json:"telegram"` + ReferCode string `json:"refer_code"` + RefererId *int64 `json:"referer_id"` + Enable *bool `json:"enable"` + IsAdmin *bool `json:"is_admin"` + Remark string `json:"remark"` } type UpdateUserNotifyRequest struct {