package grpc import ( "context" walletv1 "hyapp/api/proto/wallet/v1" "hyapp/pkg/xerr" "hyapp/services/wallet-service/internal/domain/ledger" walletservice "hyapp/services/wallet-service/internal/service/wallet" ) // Server 把 wallet-service 用例层适配为 gRPC 接口。 type Server struct { walletv1.UnimplementedWalletServiceServer svc *walletservice.Service } // NewServer 创建 wallet gRPC server。 func NewServer(svc *walletservice.Service) *Server { return &Server{svc: svc} } // DebitGift 只负责 protobuf 转换和错误映射,扣费规则在 service/repository。 func (s *Server) DebitGift(ctx context.Context, req *walletv1.DebitGiftRequest) (*walletv1.DebitGiftResponse, error) { receipt, err := s.svc.DebitGift(ctx, ledger.DebitGiftCommand{ CommandID: req.GetCommandId(), RoomID: req.GetRoomId(), SenderUserID: req.GetSenderUserId(), TargetUserID: req.GetTargetUserId(), GiftID: req.GetGiftId(), GiftCount: req.GetGiftCount(), PriceVersion: req.GetPriceVersion(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &walletv1.DebitGiftResponse{ BillingReceiptId: receipt.BillingReceiptID, BalanceAfter: receipt.BalanceAfter, TransactionId: receipt.TransactionID, CoinSpent: receipt.CoinSpent, GiftPointAdded: receipt.GiftPointAdded, HeatValue: receipt.HeatValue, PriceVersion: receipt.PriceVersion, }, nil } // GetBalances 返回用户多资产余额投影。 func (s *Server) GetBalances(ctx context.Context, req *walletv1.GetBalancesRequest) (*walletv1.GetBalancesResponse, error) { balances, err := s.svc.GetBalances(ctx, req.GetUserId(), req.GetAssetTypes()) if err != nil { return nil, xerr.ToGRPCError(err) } response := &walletv1.GetBalancesResponse{Balances: make([]*walletv1.AssetBalance, 0, len(balances))} for _, balance := range balances { response.Balances = append(response.Balances, &walletv1.AssetBalance{ AssetType: balance.AssetType, AvailableAmount: balance.AvailableAmount, FrozenAmount: balance.FrozenAmount, Version: balance.Version, }) } return response, nil } // AdminCreditAsset 处理后台手动入账,公网权限和审计入口由 gateway/admin 层控制。 func (s *Server) AdminCreditAsset(ctx context.Context, req *walletv1.AdminCreditAssetRequest) (*walletv1.AdminCreditAssetResponse, error) { balance, transactionID, err := s.svc.AdminCreditAsset(ctx, ledger.AdminCreditAssetCommand{ CommandID: req.GetCommandId(), TargetUserID: req.GetTargetUserId(), AssetType: req.GetAssetType(), Amount: req.GetAmount(), OperatorUserID: req.GetOperatorUserId(), Reason: req.GetReason(), EvidenceRef: req.GetEvidenceRef(), }) if err != nil { return nil, xerr.ToGRPCError(err) } return &walletv1.AdminCreditAssetResponse{ TransactionId: transactionID, Balance: &walletv1.AssetBalance{ AssetType: balance.AssetType, AvailableAmount: balance.AvailableAmount, FrozenAmount: balance.FrozenAmount, Version: balance.Version, }, }, nil }