修复提现拒绝审核参数校验

This commit is contained in:
yml2213
2026-07-05 20:33:47 +08:00
parent 1984e07e91
commit 7937b0df8a
6 changed files with 53 additions and 4 deletions
+2 -1
View File
@@ -526,8 +526,9 @@ func assertWalletAndWithdrawal(t *testing.T, walletService *wallet.Service, with
assertEqual(t, "提现申请金额", req.AmountCent, int64(10000)) assertEqual(t, "提现申请金额", req.AmountCent, int64(10000))
assertEqual(t, "提现申请状态", req.Status, "pending") assertEqual(t, "提现申请状态", req.Status, "pending")
approved := true
reviewed, err := withdrawalService.Review(t.Context(), adminID, req.ID, withdrawal.ReviewWithdrawalRequest{ reviewed, err := withdrawalService.Review(t.Context(), adminID, req.ID, withdrawal.ReviewWithdrawalRequest{
Approved: true, Approved: &approved,
Remark: "E2E 审核通过", Remark: "E2E 审核通过",
}) })
if err != nil { if err != nil {
+3 -2
View File
@@ -87,7 +87,8 @@ func (r *Repository) Review(ctx context.Context, adminID, id uint64, req ReviewW
} }
now := time.Now() now := time.Now()
if req.Approved { approved := *req.Approved
if approved {
// 审核通过,进入处理中状态 // 审核通过,进入处理中状态
withdrawal.Status = "processing" withdrawal.Status = "processing"
} else { } else {
@@ -103,7 +104,7 @@ func (r *Repository) Review(ctx context.Context, adminID, id uint64, req ReviewW
} }
// 如果拒绝,解冻余额 // 如果拒绝,解冻余额
if !req.Approved { if !approved {
if err := wallet.AppendEntries(tx, wallet.Entry{ if err := wallet.AppendEntries(tx, wallet.Entry{
UserID: withdrawal.UserID, UserID: withdrawal.UserID,
Direction: "out", Direction: "out",
+1 -1
View File
@@ -61,7 +61,7 @@ type CreateWithdrawalRequest struct {
} }
type ReviewWithdrawalRequest struct { type ReviewWithdrawalRequest struct {
Approved bool `json:"approved" binding:"required"` Approved *bool `json:"approved" binding:"required"`
Remark string `json:"remark"` Remark string `json:"remark"`
} }
@@ -0,0 +1,41 @@
package withdrawal
import (
"net/http/httptest"
"strings"
"testing"
"github.com/gin-gonic/gin"
)
func TestReviewWithdrawalRequestBindApprovedFalse(t *testing.T) {
gin.SetMode(gin.TestMode)
c, _ := gin.CreateTestContext(httptest.NewRecorder())
c.Request = httptest.NewRequest("POST", "/admin/withdrawals/1/review", strings.NewReader(`{"approved":false,"remark":"资料不符"}`))
c.Request.Header.Set("Content-Type", "application/json")
var req ReviewWithdrawalRequest
if err := c.ShouldBindJSON(&req); err != nil {
t.Fatalf("approved=false 应该通过参数绑定: %v", err)
}
if req.Approved == nil {
t.Fatal("approved 字段应该被识别为已传入")
}
if *req.Approved {
t.Fatal("approved=false 不应该被绑定成 true")
}
}
func TestReviewWithdrawalRequestBindMissingApproved(t *testing.T) {
gin.SetMode(gin.TestMode)
c, _ := gin.CreateTestContext(httptest.NewRecorder())
c.Request = httptest.NewRequest("POST", "/admin/withdrawals/1/review", strings.NewReader(`{"remark":"资料不符"}`))
c.Request.Header.Set("Content-Type", "application/json")
var req ReviewWithdrawalRequest
if err := c.ShouldBindJSON(&req); err == nil {
t.Fatal("缺少 approved 字段时应该参数绑定失败")
}
}
@@ -230,6 +230,8 @@ func writeError(c *gin.Context, err error) {
response.BadRequest(c, "提现金额超过最大限额") response.BadRequest(c, "提现金额超过最大限额")
case ErrWithdrawalLocked: case ErrWithdrawalLocked:
response.BadRequest(c, "提现申请状态已锁定,无法操作") response.BadRequest(c, "提现申请状态已锁定,无法操作")
case ErrInvalidReviewAction:
response.BadRequest(c, "审核参数无效")
case ErrUnauthorized: case ErrUnauthorized:
response.Unauthorized(c, "无权限操作") response.Unauthorized(c, "无权限操作")
default: default:
@@ -13,6 +13,7 @@ var (
ErrMinWithdrawalAmount = errors.New("amount below minimum withdrawal") ErrMinWithdrawalAmount = errors.New("amount below minimum withdrawal")
ErrMaxWithdrawalAmount = errors.New("amount exceeds maximum withdrawal") ErrMaxWithdrawalAmount = errors.New("amount exceeds maximum withdrawal")
ErrWithdrawalLocked = errors.New("withdrawal status locked") ErrWithdrawalLocked = errors.New("withdrawal status locked")
ErrInvalidReviewAction = errors.New("invalid review action")
ErrUnauthorized = errors.New("unauthorized") ErrUnauthorized = errors.New("unauthorized")
) )
@@ -99,6 +100,9 @@ func (s *Service) Review(ctx context.Context, adminID, id uint64, req ReviewWith
if s.repo == nil { if s.repo == nil {
return nil, ErrDependencyUnavailable return nil, ErrDependencyUnavailable
} }
if req.Approved == nil {
return nil, ErrInvalidReviewAction
}
return s.repo.Review(ctx, adminID, id, req) return s.repo.Review(ctx, adminID, id, req)
} }