package services import ( "context" "fmt" "github.com/shopspring/decimal" "go.uber.org/zap" "tyapi-server/internal/domains/finance/entities" "tyapi-server/internal/domains/finance/repositories" ) // FinanceService 财务领域服务 // 负责财务相关的业务逻辑,包括钱包管理、余额操作等 type FinanceService struct { walletRepo repositories.WalletRepository logger *zap.Logger } // NewFinanceService 创建财务领域服务 func NewFinanceService( walletRepo repositories.WalletRepository, logger *zap.Logger, ) *FinanceService { return &FinanceService{ walletRepo: walletRepo, logger: logger, } } // CreateWallet 创建钱包 func (s *FinanceService) CreateWallet(ctx context.Context, userID string) (*entities.Wallet, error) { // 检查用户是否已有钱包 existingWallet, err := s.walletRepo.GetByUserID(ctx, userID) if err == nil && existingWallet != nil { return nil, fmt.Errorf("用户已有钱包") } // 创建钱包 wallet := &entities.Wallet{ UserID: userID, Balance: decimal.Zero, IsActive: true, WalletType: "MAIN", } createdWallet, err := s.walletRepo.Create(ctx, *wallet) if err != nil { s.logger.Error("创建钱包失败", zap.Error(err)) return nil, fmt.Errorf("创建钱包失败: %w", err) } s.logger.Info("钱包创建成功", zap.String("wallet_id", createdWallet.ID), zap.String("user_id", userID), ) return &createdWallet, nil } // GetWallet 获取钱包信息 func (s *FinanceService) GetWallet(ctx context.Context, userID string) (*entities.Wallet, error) { wallet, err := s.walletRepo.GetByUserID(ctx, userID) if err != nil { return nil, fmt.Errorf("钱包不存在: %w", err) } return wallet, nil } // GetWalletByID 根据ID获取钱包 func (s *FinanceService) GetWalletByID(ctx context.Context, walletID string) (*entities.Wallet, error) { wallet, err := s.walletRepo.GetByID(ctx, walletID) if err != nil { return nil, fmt.Errorf("钱包不存在: %w", err) } return &wallet, nil } // RechargeWallet 充值钱包 func (s *FinanceService) RechargeWallet(ctx context.Context, userID string, amount float64) error { if amount <= 0 { return fmt.Errorf("充值金额必须大于0") } wallet, err := s.walletRepo.GetByUserID(ctx, userID) if err != nil { return fmt.Errorf("钱包不存在: %w", err) } // 更新余额 amountDecimal := decimal.NewFromFloat(amount) wallet.AddBalance(amountDecimal) if err := s.walletRepo.Update(ctx, *wallet); err != nil { s.logger.Error("充值失败", zap.Error(err)) return fmt.Errorf("充值失败: %w", err) } s.logger.Info("钱包充值成功", zap.String("wallet_id", wallet.ID), zap.String("user_id", userID), zap.Float64("amount", amount), zap.String("new_balance", wallet.GetFormattedBalance()), ) return nil } // DeductWallet 扣减钱包余额 func (s *FinanceService) DeductWallet(ctx context.Context, userID string, amount float64) error { if amount <= 0 { return fmt.Errorf("扣减金额必须大于0") } wallet, err := s.walletRepo.GetByUserID(ctx, userID) if err != nil { return fmt.Errorf("钱包不存在: %w", err) } amountDecimal := decimal.NewFromFloat(amount) if err := wallet.SubtractBalance(amountDecimal); err != nil { return err } if err := s.walletRepo.Update(ctx, *wallet); err != nil { s.logger.Error("扣减失败", zap.Error(err)) return fmt.Errorf("扣减失败: %w", err) } s.logger.Info("钱包扣减成功", zap.String("wallet_id", wallet.ID), zap.String("user_id", userID), zap.Float64("amount", amount), zap.String("new_balance", wallet.GetFormattedBalance()), ) return nil } // GetWalletBalance 获取钱包余额 func (s *FinanceService) GetWalletBalance(ctx context.Context, userID string) (float64, error) { wallet, err := s.walletRepo.GetByUserID(ctx, userID) if err != nil { return 0, fmt.Errorf("钱包不存在: %w", err) } balance, _ := wallet.Balance.Float64() return balance, nil } // CheckWalletBalance 检查钱包余额是否足够 func (s *FinanceService) CheckWalletBalance(ctx context.Context, userID string, amount float64) (bool, error) { wallet, err := s.walletRepo.GetByUserID(ctx, userID) if err != nil { return false, fmt.Errorf("钱包不存在: %w", err) } amountDecimal := decimal.NewFromFloat(amount) return wallet.HasSufficientBalance(amountDecimal), nil }