package user import ( "context" "os" "strings" "time" logicCommon "github.com/perfect-panel/server/internal/logic/common" "github.com/perfect-panel/server/internal/model/log" "github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/pkg/logger" "github.com/perfect-panel/server/pkg/tool" "github.com/perfect-panel/server/pkg/xerr" "github.com/pkg/errors" "gorm.io/gorm" ) type UpdateUserBasicInfoLogic struct { logger.Logger ctx context.Context svcCtx *svc.ServiceContext } // NewUpdateUserBasicInfoLogic Update user basic info func NewUpdateUserBasicInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateUserBasicInfoLogic { return &UpdateUserBasicInfoLogic{ Logger: logger.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *UpdateUserBasicInfoLogic) UpdateUserBasicInfo(req *types.UpdateUserBasiceInfoRequest) error { userInfo, err := l.svcCtx.UserModel.FindOne(l.ctx, req.UserId) if err != nil { l.Errorw("[UpdateUserBasicInfoLogic] Find User Error:", logger.Field("err", err.Error()), logger.Field("userId", req.UserId)) return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "Find User Error") } isDemo := strings.ToLower(os.Getenv("PPANEL_MODE")) == "demo" if req.Avatar != "" && !tool.IsValidImageSize(req.Avatar, 1024) { return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "Invalid Image Size") } 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, OrderNo: "", Balance: req.Balance, Timestamp: time.Now().UnixMilli(), } 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 { return err } 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, 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 { 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 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 } if req.Avatar != "" { userInfo.Avatar = req.Avatar } if req.ReferCode != "" { userInfo.ReferCode = req.ReferCode } if req.RefererId != 0 { userInfo.RefererId = req.RefererId } if req.Enable != nil { userInfo.Enable = req.Enable } if req.IsAdmin != nil { userInfo.IsAdmin = req.IsAdmin } if req.Remark != "" { userInfo.Remark = req.Remark } if req.OnlyFirstPurchase != nil { userInfo.OnlyFirstPurchase = req.OnlyFirstPurchase } if req.ReferralPercentage != 0 { 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 { return err } return nil }) if err != nil { l.Errorw("[UpdateUserBasicInfoLogic] Update User Error:", logger.Field("err", err.Error()), logger.Field("userId", req.UserId)) 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.NewErrCode(xerr.DatabaseUpdateError), "Update User Error") } return nil }