完成剩余模块 Context 超时控制改造
This commit is contained in:
@@ -30,7 +30,7 @@ func (h *Handler) Create(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
withdrawal, err := h.service.Create(userID, req)
|
||||
withdrawal, err := h.service.Create(c.Request.Context(), userID, req)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
@@ -49,7 +49,7 @@ func (h *Handler) List(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||
|
||||
result, err := h.service.List(userID, page, pageSize)
|
||||
result, err := h.service.List(c.Request.Context(), userID, page, pageSize)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
@@ -70,7 +70,7 @@ func (h *Handler) FindByID(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
withdrawal, err := h.service.FindByID(userID, id)
|
||||
withdrawal, err := h.service.FindByID(c.Request.Context(), userID, id)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
@@ -91,7 +91,7 @@ func (h *Handler) Cancel(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.service.Cancel(userID, id); err != nil {
|
||||
if err := h.service.Cancel(c.Request.Context(), userID, id); err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
}
|
||||
@@ -108,7 +108,7 @@ func (h *Handler) AdminList(c *gin.Context) {
|
||||
query.Size = 20
|
||||
}
|
||||
|
||||
result, err := h.service.AdminList(query)
|
||||
result, err := h.service.AdminList(c.Request.Context(), query)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
@@ -123,7 +123,7 @@ func (h *Handler) AdminFindByID(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
withdrawal, err := h.service.AdminFindByID(id)
|
||||
withdrawal, err := h.service.AdminFindByID(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
@@ -150,7 +150,7 @@ func (h *Handler) Review(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
withdrawal, err := h.service.Review(adminID, id, req)
|
||||
withdrawal, err := h.service.Review(c.Request.Context(), adminID, id, req)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
@@ -177,7 +177,7 @@ func (h *Handler) ConfirmPayment(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
withdrawal, err := h.service.ConfirmPayment(adminID, id, req)
|
||||
withdrawal, err := h.service.ConfirmPayment(c.Request.Context(), adminID, id, req)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package withdrawal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
@@ -28,10 +29,11 @@ func NewRepository(db *gorm.DB, walletRepo *wallet.Repository) *Repository {
|
||||
}
|
||||
|
||||
// 用户创建提现申请
|
||||
func (r *Repository) Create(userID uint64, req CreateWithdrawalRequest) (*WithdrawalDTO, error) {
|
||||
func (r *Repository) Create(ctx context.Context, userID uint64, req CreateWithdrawalRequest) (*WithdrawalDTO, error) {
|
||||
db := r.db.WithContext(ctx)
|
||||
// 验证收款账号
|
||||
var paymentAccount model.UserPaymentAccount
|
||||
if err := r.db.Where("id = ? AND user_id = ? AND status = ?", req.PaymentAccountID, userID, "active").
|
||||
if err := db.Where("id = ? AND user_id = ? AND status = ?", req.PaymentAccountID, userID, "active").
|
||||
First(&paymentAccount).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("payment account not found")
|
||||
@@ -71,7 +73,7 @@ func (r *Repository) Create(userID uint64, req CreateWithdrawalRequest) (*Withdr
|
||||
}
|
||||
|
||||
// 事务处理
|
||||
err = r.db.Transaction(func(tx *gorm.DB) error {
|
||||
err = db.Transaction(func(tx *gorm.DB) error {
|
||||
// 创建提现申请
|
||||
if err := tx.Create(&withdrawal).Error; err != nil {
|
||||
return err
|
||||
@@ -105,13 +107,14 @@ func (r *Repository) Create(userID uint64, req CreateWithdrawalRequest) (*Withdr
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.FindByID(userID, withdrawal.ID)
|
||||
return r.FindByID(ctx, userID, withdrawal.ID)
|
||||
}
|
||||
|
||||
// 用户查询提现列表
|
||||
func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
||||
func (r *Repository) List(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
||||
db := r.db.WithContext(ctx)
|
||||
var total int64
|
||||
if err := r.db.Model(&model.WithdrawalRequest{}).
|
||||
if err := db.Model(&model.WithdrawalRequest{}).
|
||||
Where("user_id = ?", userID).
|
||||
Count(&total).Error; err != nil {
|
||||
return nil, err
|
||||
@@ -119,7 +122,7 @@ func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult,
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
var withdrawals []model.WithdrawalRequest
|
||||
if err := r.db.Where("user_id = ?", userID).
|
||||
if err := db.Where("user_id = ?", userID).
|
||||
Order("created_at DESC").
|
||||
Offset(offset).Limit(pageSize).
|
||||
Find(&withdrawals).Error; err != nil {
|
||||
@@ -140,9 +143,9 @@ func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult,
|
||||
}
|
||||
|
||||
// 用户查询提现详情
|
||||
func (r *Repository) FindByID(userID, id uint64) (*WithdrawalDTO, error) {
|
||||
func (r *Repository) FindByID(ctx context.Context, userID, id uint64) (*WithdrawalDTO, error) {
|
||||
var withdrawal model.WithdrawalRequest
|
||||
if err := r.db.Where("id = ? AND user_id = ?", id, userID).
|
||||
if err := r.db.WithContext(ctx).Where("id = ? AND user_id = ?", id, userID).
|
||||
First(&withdrawal).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrWithdrawalNotFound
|
||||
@@ -154,9 +157,10 @@ func (r *Repository) FindByID(userID, id uint64) (*WithdrawalDTO, error) {
|
||||
}
|
||||
|
||||
// 用户取消提现
|
||||
func (r *Repository) Cancel(userID, id uint64) error {
|
||||
func (r *Repository) Cancel(ctx context.Context, userID, id uint64) error {
|
||||
db := r.db.WithContext(ctx)
|
||||
var withdrawal model.WithdrawalRequest
|
||||
if err := r.db.Where("id = ? AND user_id = ?", id, userID).
|
||||
if err := db.Where("id = ? AND user_id = ?", id, userID).
|
||||
First(&withdrawal).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return ErrWithdrawalNotFound
|
||||
@@ -169,7 +173,7 @@ func (r *Repository) Cancel(userID, id uint64) error {
|
||||
return ErrWithdrawalLocked
|
||||
}
|
||||
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
// 更新状态
|
||||
if err := tx.Model(&withdrawal).Update("status", "cancelled").Error; err != nil {
|
||||
return err
|
||||
@@ -201,8 +205,8 @@ func (r *Repository) Cancel(userID, id uint64) error {
|
||||
}
|
||||
|
||||
// 管理员查询提现列表
|
||||
func (r *Repository) AdminList(query AdminListQuery) (*AdminPaginatedResult, error) {
|
||||
db := r.db.Model(&model.WithdrawalRequest{})
|
||||
func (r *Repository) AdminList(ctx context.Context, query AdminListQuery) (*AdminPaginatedResult, error) {
|
||||
db := r.db.WithContext(ctx).Model(&model.WithdrawalRequest{})
|
||||
|
||||
if query.Status != "" {
|
||||
db = db.Where("status = ?", query.Status)
|
||||
@@ -226,7 +230,7 @@ func (r *Repository) AdminList(query AdminListQuery) (*AdminPaginatedResult, err
|
||||
|
||||
items := make([]WithdrawalDetailDTO, 0, len(withdrawals))
|
||||
for _, w := range withdrawals {
|
||||
dto, err := r.toDetailDTO(w)
|
||||
dto, err := r.toDetailDTO(ctx, w)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@@ -242,21 +246,22 @@ func (r *Repository) AdminList(query AdminListQuery) (*AdminPaginatedResult, err
|
||||
}
|
||||
|
||||
// 管理员查询提现详情
|
||||
func (r *Repository) AdminFindByID(id uint64) (*WithdrawalDetailDTO, error) {
|
||||
func (r *Repository) AdminFindByID(ctx context.Context, id uint64) (*WithdrawalDetailDTO, error) {
|
||||
var withdrawal model.WithdrawalRequest
|
||||
if err := r.db.First(&withdrawal, id).Error; err != nil {
|
||||
if err := r.db.WithContext(ctx).First(&withdrawal, id).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrWithdrawalNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return r.toDetailDTO(withdrawal)
|
||||
return r.toDetailDTO(ctx, withdrawal)
|
||||
}
|
||||
|
||||
// 管理员审核提现
|
||||
func (r *Repository) Review(adminID, id uint64, req ReviewWithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||||
func (r *Repository) Review(ctx context.Context, adminID, id uint64, req ReviewWithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||||
db := r.db.WithContext(ctx)
|
||||
var withdrawal model.WithdrawalRequest
|
||||
if err := r.db.First(&withdrawal, id).Error; err != nil {
|
||||
if err := db.First(&withdrawal, id).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrWithdrawalNotFound
|
||||
}
|
||||
@@ -282,7 +287,7 @@ func (r *Repository) Review(adminID, id uint64, req ReviewWithdrawalRequest) (*W
|
||||
withdrawal.ReviewedAt = &now
|
||||
withdrawal.ReviewRemark = req.Remark
|
||||
|
||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
||||
err := db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Save(&withdrawal).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -317,13 +322,14 @@ func (r *Repository) Review(adminID, id uint64, req ReviewWithdrawalRequest) (*W
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.AdminFindByID(id)
|
||||
return r.AdminFindByID(ctx, id)
|
||||
}
|
||||
|
||||
// 管理员确认打款
|
||||
func (r *Repository) ConfirmPayment(adminID, id uint64, req ConfirmPaymentRequest) (*WithdrawalDetailDTO, error) {
|
||||
func (r *Repository) ConfirmPayment(ctx context.Context, adminID, id uint64, req ConfirmPaymentRequest) (*WithdrawalDetailDTO, error) {
|
||||
db := r.db.WithContext(ctx)
|
||||
var withdrawal model.WithdrawalRequest
|
||||
if err := r.db.First(&withdrawal, id).Error; err != nil {
|
||||
if err := db.First(&withdrawal, id).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, ErrWithdrawalNotFound
|
||||
}
|
||||
@@ -342,7 +348,7 @@ func (r *Repository) ConfirmPayment(adminID, id uint64, req ConfirmPaymentReques
|
||||
withdrawal.PaymentProofURL = req.PaymentProofURL
|
||||
withdrawal.PaymentRemark = req.Remark
|
||||
|
||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
||||
err := db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Save(&withdrawal).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -367,7 +373,7 @@ func (r *Repository) ConfirmPayment(adminID, id uint64, req ConfirmPaymentReques
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.AdminFindByID(id)
|
||||
return r.AdminFindByID(ctx, id)
|
||||
}
|
||||
|
||||
// 转换为用户DTO
|
||||
@@ -393,16 +399,17 @@ func toDTO(w model.WithdrawalRequest) WithdrawalDTO {
|
||||
}
|
||||
|
||||
// 转换为管理员详细DTO
|
||||
func (r *Repository) toDetailDTO(w model.WithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||||
func (r *Repository) toDetailDTO(ctx context.Context, w model.WithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||||
db := r.db.WithContext(ctx)
|
||||
// 查询用户信息
|
||||
var user model.User
|
||||
r.db.Select("nickname, phone").First(&user, w.UserID)
|
||||
db.Select("nickname, phone").First(&user, w.UserID)
|
||||
|
||||
// 查询审核人信息
|
||||
var reviewedByName string
|
||||
if w.ReviewedBy != nil {
|
||||
var admin model.AdminUser
|
||||
if err := r.db.Select("nickname").First(&admin, *w.ReviewedBy).Error; err == nil {
|
||||
if err := db.Select("nickname").First(&admin, *w.ReviewedBy).Error; err == nil {
|
||||
reviewedByName = admin.Nickname
|
||||
}
|
||||
}
|
||||
@@ -411,7 +418,7 @@ func (r *Repository) toDetailDTO(w model.WithdrawalRequest) (*WithdrawalDetailDT
|
||||
var paidByName string
|
||||
if w.PaidBy != nil {
|
||||
var admin model.AdminUser
|
||||
if err := r.db.Select("nickname").First(&admin, *w.PaidBy).Error; err == nil {
|
||||
if err := db.Select("nickname").First(&admin, *w.PaidBy).Error; err == nil {
|
||||
paidByName = admin.Nickname
|
||||
}
|
||||
}
|
||||
@@ -421,7 +428,7 @@ func (r *Repository) toDetailDTO(w model.WithdrawalRequest) (*WithdrawalDetailDT
|
||||
var certificateURLs []string
|
||||
if w.PaymentAccountID != nil {
|
||||
var paymentAccount model.UserPaymentAccount
|
||||
if err := r.db.First(&paymentAccount, *w.PaymentAccountID).Error; err == nil {
|
||||
if err := db.First(&paymentAccount, *w.PaymentAccountID).Error; err == nil {
|
||||
// 解密账号
|
||||
decrypted, err := crypto.Decrypt(paymentAccount.AccountNo)
|
||||
if err == nil {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package withdrawal
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDependencyUnavailable = errors.New("dependency unavailable")
|
||||
@@ -14,7 +17,7 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
MinWithdrawalAmountCent = 1000 // 最低提现金额:10元 = 1000分
|
||||
MinWithdrawalAmountCent = 1000 // 最低提现金额:10元 = 1000分
|
||||
MaxWithdrawalAmountCent = 500000 // 单笔最高提现金额:5000元 = 500000分
|
||||
WithdrawalFeeRate = 0.0 // 手续费率(暂时0%)
|
||||
)
|
||||
@@ -28,7 +31,7 @@ func NewService(repo *Repository) *Service {
|
||||
}
|
||||
|
||||
// 用户端方法
|
||||
func (s *Service) Create(userID uint64, req CreateWithdrawalRequest) (*WithdrawalDTO, error) {
|
||||
func (s *Service) Create(ctx context.Context, userID uint64, req CreateWithdrawalRequest) (*WithdrawalDTO, error) {
|
||||
if s.repo == nil {
|
||||
return nil, ErrDependencyUnavailable
|
||||
}
|
||||
@@ -41,10 +44,10 @@ func (s *Service) Create(userID uint64, req CreateWithdrawalRequest) (*Withdrawa
|
||||
return nil, ErrMaxWithdrawalAmount
|
||||
}
|
||||
|
||||
return s.repo.Create(userID, req)
|
||||
return s.repo.Create(ctx, userID, req)
|
||||
}
|
||||
|
||||
func (s *Service) List(userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
||||
func (s *Service) List(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
||||
if s.repo == nil {
|
||||
return nil, ErrDependencyUnavailable
|
||||
}
|
||||
@@ -54,25 +57,25 @@ func (s *Service) List(userID uint64, page, pageSize int) (*PaginatedResult, err
|
||||
if pageSize < 1 || pageSize > 100 {
|
||||
pageSize = 20
|
||||
}
|
||||
return s.repo.List(userID, page, pageSize)
|
||||
return s.repo.List(ctx, userID, page, pageSize)
|
||||
}
|
||||
|
||||
func (s *Service) FindByID(userID, id uint64) (*WithdrawalDTO, error) {
|
||||
func (s *Service) FindByID(ctx context.Context, userID, id uint64) (*WithdrawalDTO, error) {
|
||||
if s.repo == nil {
|
||||
return nil, ErrDependencyUnavailable
|
||||
}
|
||||
return s.repo.FindByID(userID, id)
|
||||
return s.repo.FindByID(ctx, userID, id)
|
||||
}
|
||||
|
||||
func (s *Service) Cancel(userID, id uint64) error {
|
||||
func (s *Service) Cancel(ctx context.Context, userID, id uint64) error {
|
||||
if s.repo == nil {
|
||||
return ErrDependencyUnavailable
|
||||
}
|
||||
return s.repo.Cancel(userID, id)
|
||||
return s.repo.Cancel(ctx, userID, id)
|
||||
}
|
||||
|
||||
// 管理员端方法
|
||||
func (s *Service) AdminList(query AdminListQuery) (*AdminPaginatedResult, error) {
|
||||
func (s *Service) AdminList(ctx context.Context, query AdminListQuery) (*AdminPaginatedResult, error) {
|
||||
if s.repo == nil {
|
||||
return nil, ErrDependencyUnavailable
|
||||
}
|
||||
@@ -82,26 +85,26 @@ func (s *Service) AdminList(query AdminListQuery) (*AdminPaginatedResult, error)
|
||||
if query.Size < 1 || query.Size > 100 {
|
||||
query.Size = 20
|
||||
}
|
||||
return s.repo.AdminList(query)
|
||||
return s.repo.AdminList(ctx, query)
|
||||
}
|
||||
|
||||
func (s *Service) AdminFindByID(id uint64) (*WithdrawalDetailDTO, error) {
|
||||
func (s *Service) AdminFindByID(ctx context.Context, id uint64) (*WithdrawalDetailDTO, error) {
|
||||
if s.repo == nil {
|
||||
return nil, ErrDependencyUnavailable
|
||||
}
|
||||
return s.repo.AdminFindByID(id)
|
||||
return s.repo.AdminFindByID(ctx, id)
|
||||
}
|
||||
|
||||
func (s *Service) Review(adminID, id uint64, req ReviewWithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||||
func (s *Service) Review(ctx context.Context, adminID, id uint64, req ReviewWithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||||
if s.repo == nil {
|
||||
return nil, ErrDependencyUnavailable
|
||||
}
|
||||
return s.repo.Review(adminID, id, req)
|
||||
return s.repo.Review(ctx, adminID, id, req)
|
||||
}
|
||||
|
||||
func (s *Service) ConfirmPayment(adminID, id uint64, req ConfirmPaymentRequest) (*WithdrawalDetailDTO, error) {
|
||||
func (s *Service) ConfirmPayment(ctx context.Context, adminID, id uint64, req ConfirmPaymentRequest) (*WithdrawalDetailDTO, error) {
|
||||
if s.repo == nil {
|
||||
return nil, ErrDependencyUnavailable
|
||||
}
|
||||
return s.repo.ConfirmPayment(adminID, id, req)
|
||||
return s.repo.ConfirmPayment(ctx, adminID, id, req)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user