61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package memory
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"hyapp/pkg/xerr"
|
|
"hyapp/services/wallet-service/internal/domain/ledger"
|
|
)
|
|
|
|
// Repository 是钱包单元测试用内存账本。
|
|
// 它保留幂等命中语义,但不作为生产路径。
|
|
type Repository struct {
|
|
mu sync.Mutex
|
|
balance map[int64]int64
|
|
receipts map[string]ledger.Receipt
|
|
}
|
|
|
|
// NewRepository 创建内存账本。
|
|
func NewRepository() *Repository {
|
|
return &Repository{
|
|
balance: make(map[int64]int64),
|
|
receipts: make(map[string]ledger.Receipt),
|
|
}
|
|
}
|
|
|
|
// SetBalance 为测试准备用户余额。
|
|
func (r *Repository) SetBalance(userID int64, balance int64) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
r.balance[userID] = balance
|
|
}
|
|
|
|
// DebitGift 执行内存扣费并按 command_id 幂等返回原始回执。
|
|
func (r *Repository) DebitGift(_ context.Context, command ledger.DebitGiftCommand) (ledger.Receipt, error) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
if receipt, ok := r.receipts[command.CommandID]; ok {
|
|
return receipt, nil
|
|
}
|
|
|
|
total := command.TotalGiftValue()
|
|
current := r.balance[command.SenderUserID]
|
|
if current < total {
|
|
return ledger.Receipt{}, xerr.New(xerr.InsufficientBalance, "insufficient balance")
|
|
}
|
|
|
|
receipt := ledger.Receipt{
|
|
BillingReceiptID: fmt.Sprintf("bill_%s", command.CommandID),
|
|
TotalGiftValue: total,
|
|
BalanceAfter: current - total,
|
|
}
|
|
r.balance[command.SenderUserID] = receipt.BalanceAfter
|
|
r.receipts[command.CommandID] = receipt
|
|
|
|
return receipt, nil
|
|
}
|