feat: add withdrawal snapshot for review
This commit is contained in:
@@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -939,13 +940,26 @@ func (s *creator) Withdraw(ctx context.Context, tenantID, userID int64, form *cr
|
||||
}
|
||||
|
||||
// Validate Payout Account
|
||||
_, err = models.PayoutAccountQuery.WithContext(ctx).
|
||||
account, err := models.PayoutAccountQuery.WithContext(ctx).
|
||||
Where(models.PayoutAccountQuery.ID.Eq(form.AccountID), models.PayoutAccountQuery.TenantID.Eq(tid)).
|
||||
First()
|
||||
if err != nil {
|
||||
return errorx.ErrRecordNotFound.WithMsg("收款账户不存在")
|
||||
}
|
||||
|
||||
// 将收款账户快照写入订单,便于超管审核与打款核对。
|
||||
snapshotPayload, err := json.Marshal(fields.OrdersWithdrawalSnapshot{
|
||||
Method: form.Method,
|
||||
AccountID: account.ID,
|
||||
AccountType: account.Type,
|
||||
AccountName: account.Name,
|
||||
Account: account.Account,
|
||||
AccountRealname: account.Realname,
|
||||
})
|
||||
if err != nil {
|
||||
return errorx.ErrInternalError.WithCause(err).WithMsg("构建提现快照失败")
|
||||
}
|
||||
|
||||
return models.Q.Transaction(func(tx *models.Query) error {
|
||||
// 1. Deduct Balance
|
||||
info, err := tx.User.WithContext(ctx).
|
||||
@@ -968,7 +982,10 @@ func (s *creator) Withdraw(ctx context.Context, tenantID, userID int64, form *cr
|
||||
AmountOriginal: amount,
|
||||
AmountPaid: amount, // Actually Amount Withdrawn
|
||||
IdempotencyKey: uuid.NewString(),
|
||||
Snapshot: types.NewJSONType(fields.OrdersSnapshot{}), // Can store account details here
|
||||
Snapshot: types.NewJSONType(fields.OrdersSnapshot{
|
||||
Kind: "withdrawal",
|
||||
Data: snapshotPayload,
|
||||
}),
|
||||
}
|
||||
if err := tx.Order.WithContext(ctx).Create(order); err != nil {
|
||||
return err
|
||||
|
||||
@@ -3,12 +3,14 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"quyun/v2/app/commands/testx"
|
||||
creator_dto "quyun/v2/app/http/v1/dto"
|
||||
"quyun/v2/database"
|
||||
"quyun/v2/database/fields"
|
||||
"quyun/v2/database/models"
|
||||
"quyun/v2/pkg/consts"
|
||||
|
||||
@@ -293,6 +295,7 @@ func (s *CreatorTestSuite) Test_Withdraw() {
|
||||
Convey("should withdraw successfully", func() {
|
||||
form := &creator_dto.WithdrawForm{
|
||||
Amount: 20.00,
|
||||
Method: "external",
|
||||
AccountID: pa.ID,
|
||||
}
|
||||
err := Creator.Withdraw(ctx, tenantID, u.ID, form)
|
||||
@@ -308,6 +311,16 @@ func (s *CreatorTestSuite) Test_Withdraw() {
|
||||
First()
|
||||
So(o, ShouldNotBeNil)
|
||||
So(o.AmountPaid, ShouldEqual, 2000)
|
||||
So(o.Snapshot.Data().Kind, ShouldEqual, "withdrawal")
|
||||
|
||||
var snap fields.OrdersWithdrawalSnapshot
|
||||
So(json.Unmarshal(o.Snapshot.Data().Data, &snap), ShouldBeNil)
|
||||
So(snap.AccountID, ShouldEqual, pa.ID)
|
||||
So(snap.AccountType, ShouldEqual, pa.Type)
|
||||
So(snap.AccountName, ShouldEqual, pa.Name)
|
||||
So(snap.Account, ShouldEqual, pa.Account)
|
||||
So(snap.AccountRealname, ShouldEqual, pa.Realname)
|
||||
So(snap.Method, ShouldEqual, "external")
|
||||
|
||||
// Verify Ledger
|
||||
l, _ := models.TenantLedgerQuery.WithContext(ctx).Where(models.TenantLedgerQuery.OrderID.Eq(o.ID)).First()
|
||||
|
||||
@@ -4170,6 +4170,7 @@ func (s *super) toSuperOrderItem(o *models.Order, tenant *models.Tenant, buyer *
|
||||
AmountOriginal: o.AmountOriginal,
|
||||
AmountDiscount: o.AmountDiscount,
|
||||
AmountPaid: o.AmountPaid,
|
||||
Snapshot: o.Snapshot.Data(),
|
||||
CreatedAt: o.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: o.UpdatedAt.Format(time.RFC3339),
|
||||
}
|
||||
|
||||
@@ -78,3 +78,19 @@ type OrdersContentPurchaseSnapshot struct {
|
||||
// PurchasePricingNotes 价格计算补充说明(可选,便于排查争议)。
|
||||
PurchasePricingNotes string `json:"purchase_pricing_notes,omitempty"`
|
||||
}
|
||||
|
||||
// OrdersWithdrawalSnapshot 为“创作者提现订单”的快照信息(用于打款核对与审计追溯)。
|
||||
type OrdersWithdrawalSnapshot struct {
|
||||
// Method 提现方式(wallet/external)。
|
||||
Method string `json:"method"`
|
||||
// AccountID 收款账户ID(来源 payout_accounts)。
|
||||
AccountID int64 `json:"account_id"`
|
||||
// AccountType 收款账户类型(bank/alipay)。
|
||||
AccountType string `json:"account_type"`
|
||||
// AccountName 收款账户名称/开户行。
|
||||
AccountName string `json:"account_name"`
|
||||
// Account 收款账号。
|
||||
Account string `json:"account"`
|
||||
// AccountRealname 收款人姓名。
|
||||
AccountRealname string `json:"account_realname"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user