diff --git a/internal/logic/public/user/commissionWithdrawLogic.go b/internal/logic/public/user/commissionWithdrawLogic.go index 0fe7e90..d16dec0 100644 --- a/internal/logic/public/user/commissionWithdrawLogic.go +++ b/internal/logic/public/user/commissionWithdrawLogic.go @@ -2,10 +2,16 @@ package user import ( "context" + "time" + "github.com/perfect-panel/server/internal/model/log" + "github.com/perfect-panel/server/internal/model/user" "github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/types" + "github.com/perfect-panel/server/pkg/constant" "github.com/perfect-panel/server/pkg/logger" + "github.com/perfect-panel/server/pkg/xerr" + "github.com/pkg/errors" ) type CommissionWithdrawLogic struct { @@ -24,7 +30,79 @@ func NewCommissionWithdrawLogic(ctx context.Context, svcCtx *svc.ServiceContext) } func (l *CommissionWithdrawLogic) CommissionWithdraw(req *types.CommissionWithdrawRequest) (resp *types.WithdrawalLog, err error) { - // todo: add your logic here and delete this line + u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User) + if !ok { + logger.Error("current user is not found in context") + return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access") + } - return + if u.Commission < req.Amount { + logger.Errorf("User %d has insufficient commission balance: %.2f, requested: %.2f", u.Id, float64(u.Commission)/100, float64(req.Amount)/100) + return nil, errors.Wrapf(xerr.NewErrCode(xerr.UserCommissionNotEnough), "User %d has insufficient commission balance", u.Id) + } + + tx := l.svcCtx.DB.WithContext(l.ctx).Begin() + + // update user commission balance + u.Commission -= req.Amount + if err = l.svcCtx.UserModel.Update(l.ctx, u, tx); err != nil { + tx.Rollback() + l.Errorf("Failed to update user %d commission balance: %v", u.Id, err) + return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "Failed to update user %d commission balance: %v", u.Id, err) + } + + // create withdrawal log + logInfo := log.Commission{ + Type: log.CommissionTypeConvertBalance, + Amount: req.Amount, + Timestamp: time.Now().UnixMilli(), + } + b, err := logInfo.Marshal() + + if err != nil { + tx.Rollback() + l.Errorf("Failed to marshal commission log for user %d: %v", u.Id, err) + return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "Failed to marshal commission log for user %d: %v", u.Id, err) + } + + err = tx.Model(log.SystemLog{}).Create(&log.SystemLog{ + Type: log.TypeCommission.Uint8(), + Date: time.Now().Format("2006-01-02"), + ObjectID: u.Id, + Content: string(b), + CreatedAt: time.Now(), + }).Error + + if err != nil { + tx.Rollback() + l.Errorf("Failed to create commission log for user %d: %v", u.Id, err) + return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "Failed to create commission log for user %d: %v", u.Id, err) + } + + err = tx.Model(&user.Withdrawal{}).Create(&user.Withdrawal{ + UserId: u.Id, + Amount: req.Amount, + Content: req.Content, + Status: 0, + Reason: "", + }).Error + + if err != nil { + tx.Rollback() + l.Errorf("Failed to create withdrawal log for user %d: %v", u.Id, err) + return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "Failed to create withdrawal log for user %d: %v", u.Id, err) + } + if err = tx.Commit().Error; err != nil { + l.Errorf("Transaction commit failed for user %d withdrawal: %v", u.Id, err) + return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "Transaction commit failed for user %d withdrawal: %v", u.Id, err) + } + + return &types.WithdrawalLog{ + UserId: u.Id, + Amount: req.Amount, + Content: req.Content, + Status: 0, + Reason: "", + CreatedAt: time.Now().UnixMilli(), + }, nil } diff --git a/internal/model/log/log.go b/internal/model/log/log.go index af3eb98..1afd13d 100644 --- a/internal/model/log/log.go +++ b/internal/model/log/log.go @@ -33,23 +33,24 @@ const ( TypeTrafficStat Type = 42 // Daily traffic statistics log ) const ( - ResetSubscribeTypeAuto uint16 = 231 // Auto reset - ResetSubscribeTypeAdvance uint16 = 232 // Advance reset - ResetSubscribeTypePaid uint16 = 233 // Paid reset - ResetSubscribeTypeQuota uint16 = 234 // Quota reset - BalanceTypeRecharge uint16 = 321 // Recharge - BalanceTypeWithdraw uint16 = 322 // Withdraw - BalanceTypePayment uint16 = 323 // Payment - BalanceTypeRefund uint16 = 324 // Refund - BalanceTypeAdjust uint16 = 326 // Admin Adjust - BalanceTypeReward uint16 = 325 // Reward - CommissionTypePurchase uint16 = 331 // Purchase - CommissionTypeRenewal uint16 = 332 // Renewal - CommissionTypeRefund uint16 = 333 // Refund - commissionTypeWithdraw uint16 = 334 // withdraw - CommissionTypeAdjust uint16 = 335 // Admin Adjust - GiftTypeIncrease uint16 = 341 // Increase - GiftTypeReduce uint16 = 342 // Reduce + ResetSubscribeTypeAuto uint16 = 231 // Auto reset + ResetSubscribeTypeAdvance uint16 = 232 // Advance reset + ResetSubscribeTypePaid uint16 = 233 // Paid reset + ResetSubscribeTypeQuota uint16 = 234 // Quota reset + BalanceTypeRecharge uint16 = 321 // Recharge + BalanceTypeWithdraw uint16 = 322 // Withdraw + BalanceTypePayment uint16 = 323 // Payment + BalanceTypeRefund uint16 = 324 // Refund + BalanceTypeAdjust uint16 = 326 // Admin Adjust + BalanceTypeReward uint16 = 325 // Reward + CommissionTypePurchase uint16 = 331 // Purchase + CommissionTypeRenewal uint16 = 332 // Renewal + CommissionTypeRefund uint16 = 333 // Refund + CommissionTypeWithdraw uint16 = 334 // withdraw + CommissionTypeAdjust uint16 = 335 // Admin Adjust + CommissionTypeConvertBalance uint16 = 336 // Convert to Balance + GiftTypeIncrease uint16 = 341 // Increase + GiftTypeReduce uint16 = 342 // Reduce ) // Uint8 converts Type to uint8. diff --git a/pkg/xerr/errCode.go b/pkg/xerr/errCode.go index c9377c4..7e1bfd3 100644 --- a/pkg/xerr/errCode.go +++ b/pkg/xerr/errCode.go @@ -18,15 +18,16 @@ const ( // User error const ( - UserExist uint32 = 20001 - UserNotExist uint32 = 20002 - UserPasswordError uint32 = 20003 - UserDisabled uint32 = 20004 - InsufficientBalance uint32 = 20005 - StopRegister uint32 = 20006 - TelegramNotBound uint32 = 20007 - UserNotBindOauth uint32 = 20008 - InviteCodeError uint32 = 20009 + UserExist uint32 = 20001 + UserNotExist uint32 = 20002 + UserPasswordError uint32 = 20003 + UserDisabled uint32 = 20004 + InsufficientBalance uint32 = 20005 + StopRegister uint32 = 20006 + TelegramNotBound uint32 = 20007 + UserNotBindOauth uint32 = 20008 + InviteCodeError uint32 = 20009 + UserCommissionNotEnough uint32 = 20010 ) // Node error