package grpc import ( "context" walletv1 "hyapp.local/api/proto/wallet/v1" "hyapp/pkg/appcode" "hyapp/pkg/xerr" "hyapp/services/wallet-service/internal/domain/ledger" ) // 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 } // GetWalletOverview 返回钱包首页摘要,供我的页和钱包二级页复用。 func (s *Server) GetWalletOverview(ctx context.Context, req *walletv1.GetWalletOverviewRequest) (*walletv1.GetWalletOverviewResponse, error) { ctx = appcode.WithContext(ctx, req.GetAppCode()) overview, err := s.svc.GetWalletOverview(ctx, req.GetUserId()) if err != nil { return nil, xerr.ToGRPCError(err) } return &walletv1.GetWalletOverviewResponse{ Balances: balancesToProto(overview.Balances), FeatureFlags: walletFeatureFlagsToProto(overview.FeatureFlags), }, nil } // GetWalletValueSummary 返回我的页钱包卡片最小金币余额。 func (s *Server) GetWalletValueSummary(ctx context.Context, req *walletv1.GetWalletValueSummaryRequest) (*walletv1.GetWalletValueSummaryResponse, error) { ctx = appcode.WithContext(ctx, req.GetAppCode()) summary, err := s.svc.GetWalletValueSummary(ctx, req.GetUserId()) if err != nil { return nil, xerr.ToGRPCError(err) } return &walletv1.GetWalletValueSummaryResponse{Summary: &walletv1.WalletValueSummary{ CoinAmount: summary.CoinAmount, UpdatedAtMs: summary.UpdatedAtMS, }}, nil } // GetUserGiftWall 返回当前用户收到礼物的聚合墙;调用方负责限定 user_id 为当前登录用户。 func (s *Server) GetUserGiftWall(ctx context.Context, req *walletv1.GetUserGiftWallRequest) (*walletv1.GetUserGiftWallResponse, error) { ctx = appcode.WithContext(ctx, req.GetAppCode()) wall, err := s.svc.GetUserGiftWall(ctx, req.GetUserId()) if err != nil { return nil, xerr.ToGRPCError(err) } resp := &walletv1.GetUserGiftWallResponse{ Items: make([]*walletv1.GiftWallItem, 0, len(wall.Items)), GiftKindCount: wall.GiftKindCount, GiftTotalCount: wall.GiftTotalCount, TotalValue: wall.TotalValue, TotalCoinValue: wall.TotalCoinValue, TotalDiamondValue: wall.TotalDiamondValue, TotalGiftPoint: wall.TotalGiftPoint, TotalHeatValue: wall.TotalHeatValue, } for _, item := range wall.Items { resp.Items = append(resp.Items, giftWallItemToProto(item)) } return resp, nil } // GetDiamondExchangeConfig 返回钻石兑换配置。 func (s *Server) GetDiamondExchangeConfig(ctx context.Context, req *walletv1.GetDiamondExchangeConfigRequest) (*walletv1.GetDiamondExchangeConfigResponse, error) { ctx = appcode.WithContext(ctx, req.GetAppCode()) rules, err := s.svc.GetDiamondExchangeConfig(ctx, req.GetUserId()) if err != nil { return nil, xerr.ToGRPCError(err) } resp := &walletv1.GetDiamondExchangeConfigResponse{Rules: make([]*walletv1.DiamondExchangeRule, 0, len(rules))} for _, rule := range rules { resp.Rules = append(resp.Rules, &walletv1.DiamondExchangeRule{ ExchangeType: rule.ExchangeType, FromAssetType: rule.FromAssetType, ToAssetType: rule.ToAssetType, FromAmount: rule.FromAmount, ToAmount: rule.ToAmount, Enabled: rule.Enabled, }) } return resp, nil } // ListWalletTransactions 返回当前用户钱包流水。 func (s *Server) ListWalletTransactions(ctx context.Context, req *walletv1.ListWalletTransactionsRequest) (*walletv1.ListWalletTransactionsResponse, error) { ctx = appcode.WithContext(ctx, req.GetAppCode()) items, total, err := s.svc.ListWalletTransactions(ctx, ledger.ListWalletTransactionsQuery{ AppCode: req.GetAppCode(), UserID: req.GetUserId(), AssetType: req.GetAssetType(), Page: req.GetPage(), PageSize: req.GetPageSize(), }) if err != nil { return nil, xerr.ToGRPCError(err) } resp := &walletv1.ListWalletTransactionsResponse{Transactions: make([]*walletv1.WalletTransaction, 0, len(items)), Total: total} for _, item := range items { resp.Transactions = append(resp.Transactions, &walletv1.WalletTransaction{ EntryId: item.EntryID, TransactionId: item.TransactionID, BizType: item.BizType, AssetType: item.AssetType, AvailableDelta: item.AvailableDelta, FrozenDelta: item.FrozenDelta, AvailableAfter: item.AvailableAfter, FrozenAfter: item.FrozenAfter, CounterpartyUserId: item.CounterpartyUserID, RoomId: item.RoomID, CreatedAtMs: item.CreatedAtMS, }) } return resp, nil } func balancesToProto(balances []ledger.AssetBalance) []*walletv1.AssetBalance { items := make([]*walletv1.AssetBalance, 0, len(balances)) for _, balance := range balances { items = append(items, balanceToProto(balance)) } return items } func balanceToProto(balance ledger.AssetBalance) *walletv1.AssetBalance { return &walletv1.AssetBalance{ AppCode: balance.AppCode, AssetType: balance.AssetType, AvailableAmount: balance.AvailableAmount, FrozenAmount: balance.FrozenAmount, Version: balance.Version, } } func giftWallItemToProto(item ledger.GiftWallItem) *walletv1.GiftWallItem { return &walletv1.GiftWallItem{ GiftId: item.GiftID, GiftName: item.GiftName, ResourceId: item.ResourceID, Resource: giftWallResourceToProto(item.Resource), ResourceSnapshotJson: item.ResourceSnapshotJSON, GiftTypeCode: item.GiftTypeCode, PresentationJson: item.PresentationJSON, GiftCount: item.GiftCount, TotalValue: item.TotalValue, TotalCoinValue: item.TotalCoinValue, TotalDiamondValue: item.TotalDiamondValue, TotalGiftPoint: item.TotalGiftPoint, TotalHeatValue: item.TotalHeatValue, ChargeAssetType: item.ChargeAssetType, LastPriceVersion: item.LastPriceVersion, FirstReceivedAtMs: item.FirstReceivedAtMS, LastReceivedAtMs: item.LastReceivedAtMS, SortOrder: item.SortOrder, } } func giftWallResourceToProto(resource ledger.GiftWallResource) *walletv1.Resource { if resource.ResourceID == 0 { return nil } return &walletv1.Resource{ AppCode: resource.AppCode, ResourceId: resource.ResourceID, ResourceCode: resource.ResourceCode, ResourceType: resource.ResourceType, Name: resource.Name, Status: resource.Status, Grantable: resource.Grantable, GrantStrategy: resource.GrantStrategy, WalletAssetType: resource.WalletAssetType, WalletAssetAmount: resource.WalletAssetAmount, UsageScopes: resource.UsageScopes, AssetUrl: resource.AssetURL, PreviewUrl: resource.PreviewURL, AnimationUrl: resource.AnimationURL, MetadataJson: resource.MetadataJSON, SortOrder: resource.SortOrder, CreatedAtMs: resource.CreatedAtMS, UpdatedAtMs: resource.UpdatedAtMS, } } func walletFeatureFlagsToProto(flags ledger.WalletFeatureFlags) *walletv1.WalletFeatureFlags { return &walletv1.WalletFeatureFlags{ RechargeEnabled: flags.RechargeEnabled, DiamondExchangeEnabled: flags.DiamondExchangeEnabled, } }