2026-05-20 18:07:33 +08:00

260 lines
10 KiB
Go

package grpc
import (
"context"
activityv1 "hyapp.local/api/proto/activity/v1"
"hyapp/pkg/appcode"
"hyapp/pkg/xerr"
domain "hyapp/services/activity-service/internal/domain/luckygift"
service "hyapp/services/activity-service/internal/service/luckygift"
)
// LuckyGiftServer 暴露房间送礼主链路调用的幸运礼物查询和抽奖入口。
type LuckyGiftServer struct {
activityv1.UnimplementedLuckyGiftServiceServer
svc *service.Service
}
func NewLuckyGiftServer(svc *service.Service) *LuckyGiftServer {
return &LuckyGiftServer{svc: svc}
}
func (s *LuckyGiftServer) CheckLuckyGift(ctx context.Context, req *activityv1.CheckLuckyGiftRequest) (*activityv1.CheckLuckyGiftResponse, error) {
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
result, err := s.svc.Check(ctx, domain.CheckCommand{
PoolID: req.GetPoolId(),
GiftID: req.GetGiftId(),
UserID: req.GetUserId(),
RoomID: req.GetRoomId(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &activityv1.CheckLuckyGiftResponse{
Enabled: result.Enabled,
Reason: result.Reason,
PoolId: result.PoolID,
GiftId: result.GiftID,
GiftPrice: result.GiftPrice,
RuleVersion: result.RuleVersion,
TargetRtpPpm: result.TargetRTPPPM,
ExperiencePool: result.ExperiencePool,
}, nil
}
func (s *LuckyGiftServer) ExecuteLuckyGiftDraw(ctx context.Context, req *activityv1.ExecuteLuckyGiftDrawRequest) (*activityv1.ExecuteLuckyGiftDrawResponse, error) {
meta := req.GetLuckyGift()
ctx = appcode.WithContext(ctx, meta.GetMeta().GetAppCode())
result, err := s.svc.Draw(ctx, domain.DrawCommand{
CommandID: meta.GetCommandId(),
PoolID: meta.GetPoolId(),
UserID: meta.GetUserId(),
DeviceID: meta.GetDeviceId(),
RoomID: meta.GetRoomId(),
AnchorID: meta.GetAnchorId(),
GiftID: meta.GetGiftId(),
CoinSpent: meta.GetCoinSpent(),
PaidAtMS: meta.GetPaidAtMs(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &activityv1.ExecuteLuckyGiftDrawResponse{Result: luckyDrawResultToProto(result)}, nil
}
// AdminLuckyGiftServer 暴露后台幸运礼物规则配置和抽奖审计入口。
type AdminLuckyGiftServer struct {
activityv1.UnimplementedAdminLuckyGiftServiceServer
svc *service.Service
}
func NewAdminLuckyGiftServer(svc *service.Service) *AdminLuckyGiftServer {
return &AdminLuckyGiftServer{svc: svc}
}
func (s *AdminLuckyGiftServer) GetLuckyGiftConfig(ctx context.Context, req *activityv1.GetLuckyGiftConfigRequest) (*activityv1.GetLuckyGiftConfigResponse, error) {
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
config, err := s.svc.GetConfig(ctx, req.GetPoolId())
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &activityv1.GetLuckyGiftConfigResponse{Config: luckyConfigToProto(config)}, nil
}
func (s *AdminLuckyGiftServer) UpsertLuckyGiftConfig(ctx context.Context, req *activityv1.UpsertLuckyGiftConfigRequest) (*activityv1.UpsertLuckyGiftConfigResponse, error) {
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
config := luckyConfigFromProto(req.GetConfig())
config.UpdatedByAdminID = req.GetOperatorAdminId()
updated, err := s.svc.UpsertConfig(ctx, config)
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &activityv1.UpsertLuckyGiftConfigResponse{Config: luckyConfigToProto(updated)}, nil
}
func (s *AdminLuckyGiftServer) ListLuckyGiftDraws(ctx context.Context, req *activityv1.ListLuckyGiftDrawsRequest) (*activityv1.ListLuckyGiftDrawsResponse, error) {
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
draws, total, err := s.svc.ListDraws(ctx, domain.DrawQuery{
GiftID: req.GetGiftId(),
PoolID: req.GetPoolId(),
UserID: req.GetUserId(),
RoomID: req.GetRoomId(),
Status: req.GetStatus(),
Page: req.GetPage(),
PageSize: req.GetPageSize(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
resp := &activityv1.ListLuckyGiftDrawsResponse{Draws: make([]*activityv1.LuckyGiftDrawResult, 0, len(draws)), Total: total}
for _, draw := range draws {
resp.Draws = append(resp.Draws, luckyDrawResultToProto(draw))
}
return resp, nil
}
func luckyConfigFromProto(config *activityv1.LuckyGiftConfig) domain.Config {
if config == nil {
return domain.Config{}
}
tiers := make([]domain.Tier, 0, len(config.GetTiers()))
for _, tier := range config.GetTiers() {
tiers = append(tiers, domain.Tier{
Pool: tier.GetPool(),
TierID: tier.GetTierId(),
RewardCoins: tier.GetRewardCoins(),
MultiplierPPM: tier.GetMultiplierPpm(),
Weight: tier.GetWeight(),
HighWaterOnly: tier.GetHighWaterOnly(),
Enabled: tier.GetEnabled(),
})
}
return domain.Config{
AppCode: config.GetAppCode(),
GiftID: config.GetGiftId(),
PoolID: config.GetPoolId(),
Enabled: config.GetEnabled(),
RuleVersion: config.GetRuleVersion(),
GiftPrice: config.GetGiftPrice(),
TargetRTPPPM: config.GetTargetRtpPpm(),
PoolRatePPM: config.GetPoolRatePpm(),
GlobalWindowDraws: config.GetGlobalWindowDraws(),
GiftWindowDraws: config.GetGiftWindowDraws(),
NoviceDrawLimit: config.GetNoviceDrawLimit(),
IntermediateDrawLimit: config.GetIntermediateDrawLimit(),
HighMultiplier: config.GetHighMultiplier(),
HighWaterPoolMultiple: config.GetHighWaterPoolMultiple(),
PlatformPoolWeightPPM: config.GetPlatformPoolWeightPpm(),
RoomPoolWeightPPM: config.GetRoomPoolWeightPpm(),
GiftPoolWeightPPM: config.GetGiftPoolWeightPpm(),
InitialPlatformPool: config.GetInitialPlatformPool(),
InitialGiftPool: config.GetInitialGiftPool(),
InitialRoomPool: config.GetInitialRoomPool(),
PlatformReserve: config.GetPlatformReserve(),
GiftReserve: config.GetGiftReserve(),
RoomReserve: config.GetRoomReserve(),
MaxSinglePayout: config.GetMaxSinglePayout(),
UserHourlyPayoutCap: config.GetUserHourlyPayoutCap(),
UserDailyPayoutCap: config.GetUserDailyPayoutCap(),
DeviceDailyPayoutCap: config.GetDeviceDailyPayoutCap(),
RoomHourlyPayoutCap: config.GetRoomHourlyPayoutCap(),
AnchorDailyPayoutCap: config.GetAnchorDailyPayoutCap(),
RoomAtmosphereRatePPM: config.GetRoomAtmosphereRatePpm(),
RoomAtmosphereInitial: config.GetRoomAtmosphereInitial(),
RoomAtmosphereReserve: config.GetRoomAtmosphereReserve(),
ActivityBudget: config.GetActivityBudget(),
ActivityDailyLimit: config.GetActivityDailyLimit(),
LargeTierEnabled: config.GetLargeTierEnabled(),
MultiplierPPMs: append([]int64(nil), config.GetMultiplierPpms()...),
Tiers: tiers,
UpdatedByAdminID: config.GetUpdatedByAdminId(),
CreatedAtMS: config.GetCreatedAtMs(),
UpdatedAtMS: config.GetUpdatedAtMs(),
}
}
func luckyConfigToProto(config domain.Config) *activityv1.LuckyGiftConfig {
tiers := make([]*activityv1.LuckyGiftTier, 0, len(config.Tiers))
for _, tier := range config.Tiers {
tiers = append(tiers, &activityv1.LuckyGiftTier{
Pool: tier.Pool,
TierId: tier.TierID,
RewardCoins: tier.RewardCoins,
MultiplierPpm: tier.MultiplierPPM,
Weight: tier.Weight,
HighWaterOnly: tier.HighWaterOnly,
Enabled: tier.Enabled,
})
}
return &activityv1.LuckyGiftConfig{
AppCode: config.AppCode,
GiftId: config.GiftID,
PoolId: config.PoolID,
Enabled: config.Enabled,
RuleVersion: config.RuleVersion,
GiftPrice: config.GiftPrice,
TargetRtpPpm: config.TargetRTPPPM,
PoolRatePpm: config.PoolRatePPM,
GlobalWindowDraws: config.GlobalWindowDraws,
GiftWindowDraws: config.GiftWindowDraws,
NoviceDrawLimit: config.NoviceDrawLimit,
IntermediateDrawLimit: config.IntermediateDrawLimit,
HighMultiplier: config.HighMultiplier,
HighWaterPoolMultiple: config.HighWaterPoolMultiple,
PlatformPoolWeightPpm: config.PlatformPoolWeightPPM,
RoomPoolWeightPpm: config.RoomPoolWeightPPM,
GiftPoolWeightPpm: config.GiftPoolWeightPPM,
InitialPlatformPool: config.InitialPlatformPool,
InitialGiftPool: config.InitialGiftPool,
InitialRoomPool: config.InitialRoomPool,
PlatformReserve: config.PlatformReserve,
GiftReserve: config.GiftReserve,
RoomReserve: config.RoomReserve,
MaxSinglePayout: config.MaxSinglePayout,
UserHourlyPayoutCap: config.UserHourlyPayoutCap,
UserDailyPayoutCap: config.UserDailyPayoutCap,
DeviceDailyPayoutCap: config.DeviceDailyPayoutCap,
RoomHourlyPayoutCap: config.RoomHourlyPayoutCap,
AnchorDailyPayoutCap: config.AnchorDailyPayoutCap,
RoomAtmosphereRatePpm: config.RoomAtmosphereRatePPM,
RoomAtmosphereInitial: config.RoomAtmosphereInitial,
RoomAtmosphereReserve: config.RoomAtmosphereReserve,
ActivityBudget: config.ActivityBudget,
ActivityDailyLimit: config.ActivityDailyLimit,
LargeTierEnabled: config.LargeTierEnabled,
MultiplierPpms: append([]int64(nil), config.MultiplierPPMs...),
Tiers: tiers,
UpdatedByAdminId: config.UpdatedByAdminID,
CreatedAtMs: config.CreatedAtMS,
UpdatedAtMs: config.UpdatedAtMS,
}
}
func luckyDrawResultToProto(result domain.DrawResult) *activityv1.LuckyGiftDrawResult {
return &activityv1.LuckyGiftDrawResult{
DrawId: result.DrawID,
CommandId: result.CommandID,
PoolId: result.PoolID,
GiftId: result.GiftID,
RuleVersion: result.RuleVersion,
ExperiencePool: result.ExperiencePool,
SelectedTierId: result.SelectedTierID,
BaseRewardCoins: result.BaseRewardCoins,
RoomAtmosphereRewardCoins: result.RoomAtmosphereRewardCoins,
ActivitySubsidyCoins: result.ActivitySubsidyCoins,
EffectiveRewardCoins: result.EffectiveRewardCoins,
BudgetSourcesJson: result.BudgetSourcesJSON,
RewardStatus: result.RewardStatus,
RtpWindowIndex: result.RTPWindowIndex,
GiftRtpWindowIndex: result.GiftRTPWindowIndex,
GlobalBaseRtpPpm: result.GlobalBaseRTPPPM,
GiftBaseRtpPpm: result.GiftBaseRTPPPM,
StageFeedback: result.StageFeedback,
HighMultiplier: result.HighMultiplier,
CreatedAtMs: result.CreatedAtMS,
}
}