修复提现拒绝审核参数校验
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user