2026-06-25 21:30:26 +08:00

157 lines
6.1 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"
)
// 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(),
SenderRegionID: req.GetSenderRegionId(),
TargetIsHost: req.GetTargetIsHost(),
TargetHostRegionID: req.GetTargetHostRegionId(),
TargetAgencyOwnerUserID: req.GetTargetAgencyOwnerUserId(),
EntitlementID: req.GetEntitlementId(),
ChargeSource: req.GetChargeSource(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return debitGiftResponseFromReceipt(receipt), nil
}
// DebitDirectGift 处理私聊送礼账务命令;私聊没有房间状态,区域和主播身份必须由 gateway 注入。
func (s *Server) DebitDirectGift(ctx context.Context, req *walletv1.DebitDirectGiftRequest) (*walletv1.DebitGiftResponse, error) {
ctx = appcode.WithContext(ctx, req.GetAppCode())
receipt, err := s.svc.DebitDirectGift(ctx, ledger.DebitGiftCommand{
AppCode: req.GetAppCode(),
CommandID: req.GetCommandId(),
SenderUserID: req.GetSenderUserId(),
TargetUserID: req.GetTargetUserId(),
GiftID: req.GetGiftId(),
GiftCount: req.GetGiftCount(),
PriceVersion: req.GetPriceVersion(),
RegionID: req.GetRegionId(),
SenderRegionID: req.GetSenderRegionId(),
TargetIsHost: req.GetTargetIsHost(),
TargetHostRegionID: req.GetTargetHostRegionId(),
TargetAgencyOwnerUserID: req.GetTargetAgencyOwnerUserId(),
EntitlementID: req.GetEntitlementId(),
ChargeSource: req.GetChargeSource(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return debitGiftResponseFromReceipt(receipt), nil
}
// BatchDebitGift 只负责批量目标 protobuf 转换;同事务扣费和幂等由 wallet service/repository 保证。
func (s *Server) BatchDebitGift(ctx context.Context, req *walletv1.BatchDebitGiftRequest) (*walletv1.BatchDebitGiftResponse, error) {
ctx = appcode.WithContext(ctx, req.GetAppCode())
targets := make([]ledger.DebitGiftTargetCommand, 0, len(req.GetTargets()))
for _, target := range req.GetTargets() {
targets = append(targets, ledger.DebitGiftTargetCommand{
CommandID: target.GetCommandId(),
TargetUserID: target.GetTargetUserId(),
TargetIsHost: target.GetTargetIsHost(),
TargetHostRegionID: target.GetTargetHostRegionId(),
TargetAgencyOwnerUserID: target.GetTargetAgencyOwnerUserId(),
})
}
receipt, err := s.svc.BatchDebitGift(ctx, ledger.BatchDebitGiftCommand{
AppCode: req.GetAppCode(),
CommandID: req.GetCommandId(),
RoomID: req.GetRoomId(),
SenderUserID: req.GetSenderUserId(),
GiftID: req.GetGiftId(),
GiftCount: req.GetGiftCount(),
PriceVersion: req.GetPriceVersion(),
RegionID: req.GetRegionId(),
SenderRegionID: req.GetSenderRegionId(),
Targets: targets,
EntitlementID: req.GetEntitlementId(),
ChargeSource: req.GetChargeSource(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
response := &walletv1.BatchDebitGiftResponse{
Aggregate: debitGiftResponseFromReceipt(receipt.Aggregate),
Receipts: make([]*walletv1.BatchDebitGiftReceipt, 0, len(receipt.Targets)),
}
for _, target := range receipt.Targets {
response.Receipts = append(response.Receipts, &walletv1.BatchDebitGiftReceipt{
TargetUserId: target.TargetUserID,
CommandId: target.CommandID,
Billing: debitGiftResponseFromReceipt(target.Receipt),
})
}
return response, nil
}
// DebitRobotGift 扣机器人专用金币;该入口只供内部机器人房间编排链路调用。
func (s *Server) DebitRobotGift(ctx context.Context, req *walletv1.DebitRobotGiftRequest) (*walletv1.DebitGiftResponse, error) {
ctx = appcode.WithContext(ctx, req.GetAppCode())
receipt, err := s.svc.DebitRobotGift(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(),
SenderRegionID: req.GetSenderRegionId(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return debitGiftResponseFromReceipt(receipt), nil
}
func debitGiftResponseFromReceipt(receipt ledger.Receipt) *walletv1.DebitGiftResponse {
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,
GiftTypeCode: receipt.GiftTypeCode,
CpRelationType: receipt.CPRelationType,
GiftName: receipt.GiftName,
GiftIconUrl: receipt.GiftIconURL,
GiftAnimationUrl: receipt.GiftAnimationURL,
GiftEffectTypes: receipt.GiftEffectTypes,
PriceVersion: receipt.PriceVersion,
HostPeriodDiamondAdded: receipt.HostPeriodDiamondAdded,
HostPeriodCycleKey: receipt.HostPeriodCycleKey,
EntitlementId: receipt.EntitlementID,
ChargeSource: receipt.ChargeSource,
GiftIncomeCoinAmount: receipt.GiftIncomeCoinAmount,
GiftIncomeBalanceAfter: receipt.GiftIncomeBalanceAfter,
}
}