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 }