2026-04-29 23:07:50 +08:00

95 lines
3.0 KiB
Go

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
}