feat(commission): implement commission withdrawal logic and logging

This commit is contained in:
Tension 2025-11-29 14:33:05 +08:00
parent 7277438b07
commit 143445a2fc
3 changed files with 108 additions and 28 deletions

View File

@ -2,10 +2,16 @@ package user
import ( import (
"context" "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/svc"
"github.com/perfect-panel/server/internal/types" "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/logger"
"github.com/perfect-panel/server/pkg/xerr"
"github.com/pkg/errors"
) )
type CommissionWithdrawLogic struct { 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) { 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
} }

View File

@ -46,8 +46,9 @@ const (
CommissionTypePurchase uint16 = 331 // Purchase CommissionTypePurchase uint16 = 331 // Purchase
CommissionTypeRenewal uint16 = 332 // Renewal CommissionTypeRenewal uint16 = 332 // Renewal
CommissionTypeRefund uint16 = 333 // Refund CommissionTypeRefund uint16 = 333 // Refund
commissionTypeWithdraw uint16 = 334 // withdraw CommissionTypeWithdraw uint16 = 334 // withdraw
CommissionTypeAdjust uint16 = 335 // Admin Adjust CommissionTypeAdjust uint16 = 335 // Admin Adjust
CommissionTypeConvertBalance uint16 = 336 // Convert to Balance
GiftTypeIncrease uint16 = 341 // Increase GiftTypeIncrease uint16 = 341 // Increase
GiftTypeReduce uint16 = 342 // Reduce GiftTypeReduce uint16 = 342 // Reduce
) )

View File

@ -27,6 +27,7 @@ const (
TelegramNotBound uint32 = 20007 TelegramNotBound uint32 = 20007
UserNotBindOauth uint32 = 20008 UserNotBindOauth uint32 = 20008
InviteCodeError uint32 = 20009 InviteCodeError uint32 = 20009
UserCommissionNotEnough uint32 = 20010
) )
// Node error // Node error