2026-05-05 03:05:06 +08:00

137 lines
4.9 KiB
Go

package grpc
import (
"context"
walletv1 "hyapp.local/api/proto/wallet/v1"
"hyapp/pkg/appcode"
"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) {
ctx = appcode.WithContext(ctx, req.GetAppCode())
receipt, err := s.svc.DebitGift(ctx, ledger.DebitGiftCommand{
AppCode: req.GetAppCode(),
CommandID: req.GetCommandId(),
RoomID: req.GetRoomId(),
SenderUserID: req.GetSenderUserId(),
TargetUserID: req.GetTargetUserId(),
GiftID: req.GetGiftId(),
GiftCount: req.GetGiftCount(),
PriceVersion: req.GetPriceVersion(),
RegionID: req.GetRegionId(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.DebitGiftResponse{
BillingReceiptId: receipt.BillingReceiptID,
BalanceAfter: receipt.BalanceAfter,
TransactionId: receipt.TransactionID,
CoinSpent: receipt.CoinSpent,
ChargeAssetType: receipt.ChargeAssetType,
ChargeAmount: receipt.ChargeAmount,
GiftPointAdded: receipt.GiftPointAdded,
HeatValue: receipt.HeatValue,
PriceVersion: receipt.PriceVersion,
}, nil
}
// GetBalances 返回用户多资产余额投影。
func (s *Server) GetBalances(ctx context.Context, req *walletv1.GetBalancesRequest) (*walletv1.GetBalancesResponse, error) {
ctx = appcode.WithContext(ctx, req.GetAppCode())
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{
AppCode: balance.AppCode,
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) {
ctx = appcode.WithContext(ctx, req.GetAppCode())
balance, transactionID, err := s.svc.AdminCreditAsset(ctx, ledger.AdminCreditAssetCommand{
AppCode: req.GetAppCode(),
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{
AppCode: balance.AppCode,
AssetType: balance.AssetType,
AvailableAmount: balance.AvailableAmount,
FrozenAmount: balance.FrozenAmount,
Version: balance.Version,
},
}, nil
}
// TransferCoinFromSeller 处理币商转玩家金币,调用方必须先完成币商身份校验。
func (s *Server) TransferCoinFromSeller(ctx context.Context, req *walletv1.TransferCoinFromSellerRequest) (*walletv1.TransferCoinFromSellerResponse, error) {
ctx = appcode.WithContext(ctx, req.GetAppCode())
receipt, err := s.svc.TransferCoinFromSeller(ctx, ledger.CoinSellerTransferCommand{
AppCode: req.GetAppCode(),
CommandID: req.GetCommandId(),
SellerUserID: req.GetSellerUserId(),
TargetUserID: req.GetTargetUserId(),
SellerRegionID: req.GetSellerRegionId(),
TargetRegionID: req.GetTargetRegionId(),
Amount: req.GetAmount(),
Reason: req.GetReason(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.TransferCoinFromSellerResponse{
TransactionId: receipt.TransactionID,
SellerBalanceAfter: receipt.SellerBalanceAfter,
TargetBalanceAfter: receipt.TargetBalanceAfter,
Amount: receipt.Amount,
RechargeUsdMinor: receipt.RechargeUSDMinor,
RechargeCurrencyCode: receipt.RechargeCurrencyCode,
RechargePolicyId: receipt.RechargePolicyID,
RechargePolicyVersion: receipt.RechargePolicyVersion,
RechargePolicyCoinAmount: receipt.RechargePolicyCoinAmount,
RechargePolicyUsdMinorAmount: receipt.RechargePolicyUSDMinorUnit,
}, nil
}