package grpc import ( "context" "time" activityv1 "hyapp.local/api/proto/activity/v1" "hyapp/pkg/appcode" "hyapp/pkg/xerr" domain "hyapp/services/activity-service/internal/domain/weeklystar" service "hyapp/services/activity-service/internal/service/weeklystar" ) // WeeklyStarServer exposes App/H5 weekly-star reads. type WeeklyStarServer struct { activityv1.UnimplementedWeeklyStarServiceServer svc *service.Service } func NewWeeklyStarServer(svc *service.Service) *WeeklyStarServer { return &WeeklyStarServer{svc: svc} } func (s *WeeklyStarServer) GetWeeklyStarCurrent(ctx context.Context, req *activityv1.GetWeeklyStarCurrentRequest) (*activityv1.GetWeeklyStarCurrentResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) cycle, topEntries, myEntry, found, err := s.svc.GetCurrent(ctx, req.GetUserId(), req.GetRegionId()) if err != nil { return nil, xerr.ToGRPCError(err) } resp := &activityv1.GetWeeklyStarCurrentResponse{ Cycle: weeklyStarCycleToProto(cycle), TopEntries: weeklyStarEntriesToProto(topEntries), ServerTimeMs: time.Now().UnixMilli(), } if found { resp.MyEntry = weeklyStarEntryToProto(myEntry) } return resp, nil } func (s *WeeklyStarServer) ListWeeklyStarLeaderboard(ctx context.Context, req *activityv1.ListWeeklyStarLeaderboardRequest) (*activityv1.ListWeeklyStarLeaderboardResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) cycle, entries, nextToken, total, err := s.svc.ListLeaderboard(ctx, req.GetCycleId(), req.GetRegionId(), req.GetPageSize(), req.GetPageToken()) if err != nil { return nil, xerr.ToGRPCError(err) } return &activityv1.ListWeeklyStarLeaderboardResponse{ Cycle: weeklyStarCycleToProto(cycle), Entries: weeklyStarEntriesToProto(entries), NextPageToken: nextToken, Total: total, }, nil } func (s *WeeklyStarServer) ListWeeklyStarHistory(ctx context.Context, req *activityv1.ListWeeklyStarHistoryRequest) (*activityv1.ListWeeklyStarHistoryResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) cycles, err := s.svc.ListHistory(ctx, req.GetRegionId(), req.GetLimit()) if err != nil { return nil, xerr.ToGRPCError(err) } resp := &activityv1.ListWeeklyStarHistoryResponse{Cycles: make([]*activityv1.WeeklyStarHistoryCycle, 0, len(cycles)), ServerTimeMs: time.Now().UnixMilli()} for _, cycle := range cycles { resp.Cycles = append(resp.Cycles, &activityv1.WeeklyStarHistoryCycle{ Cycle: weeklyStarCycleToProto(cycle.Cycle), TopEntries: weeklyStarEntriesToProto(cycle.TopEntries), }) } return resp, nil } // AdminWeeklyStarServer exposes admin weekly-star configuration and audit reads. type AdminWeeklyStarServer struct { activityv1.UnimplementedAdminWeeklyStarServiceServer svc *service.Service } func NewAdminWeeklyStarServer(svc *service.Service) *AdminWeeklyStarServer { return &AdminWeeklyStarServer{svc: svc} } func (s *AdminWeeklyStarServer) ListWeeklyStarCycles(ctx context.Context, req *activityv1.ListWeeklyStarCyclesRequest) (*activityv1.ListWeeklyStarCyclesResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) var regionID *int64 if req.GetRegionId() >= 0 && req.RegionId != 0 { value := req.GetRegionId() regionID = &value } cycles, total, err := s.svc.ListCycles(ctx, domain.ListQuery{ RegionID: regionID, Status: req.GetStatus(), StartMS: req.GetStartMs(), EndMS: req.GetEndMs(), Page: req.GetPage(), PageSize: req.GetPageSize(), }) if err != nil { return nil, xerr.ToGRPCError(err) } resp := &activityv1.ListWeeklyStarCyclesResponse{Cycles: make([]*activityv1.WeeklyStarCycle, 0, len(cycles)), Total: total} for _, cycle := range cycles { resp.Cycles = append(resp.Cycles, weeklyStarCycleToProto(cycle)) } return resp, nil } func (s *AdminWeeklyStarServer) CreateWeeklyStarCycle(ctx context.Context, req *activityv1.UpsertWeeklyStarCycleRequest) (*activityv1.UpsertWeeklyStarCycleResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) cycle, created, err := s.svc.CreateCycle(ctx, domain.CycleCommand{Cycle: weeklyStarCycleFromProto(req.GetCycle()), OperatorAdminID: req.GetOperatorAdminId()}) if err != nil { return nil, xerr.ToGRPCError(err) } return &activityv1.UpsertWeeklyStarCycleResponse{Cycle: weeklyStarCycleToProto(cycle), Created: created}, nil } func (s *AdminWeeklyStarServer) GetWeeklyStarCycle(ctx context.Context, req *activityv1.GetWeeklyStarCycleRequest) (*activityv1.GetWeeklyStarCycleResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) cycle, err := s.svc.GetCycle(ctx, req.GetCycleId()) if err != nil { return nil, xerr.ToGRPCError(err) } return &activityv1.GetWeeklyStarCycleResponse{Cycle: weeklyStarCycleToProto(cycle)}, nil } func (s *AdminWeeklyStarServer) UpdateWeeklyStarCycle(ctx context.Context, req *activityv1.UpsertWeeklyStarCycleRequest) (*activityv1.UpsertWeeklyStarCycleResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) cycle, created, err := s.svc.UpdateCycle(ctx, domain.CycleCommand{Cycle: weeklyStarCycleFromProto(req.GetCycle()), OperatorAdminID: req.GetOperatorAdminId()}) if err != nil { return nil, xerr.ToGRPCError(err) } return &activityv1.UpsertWeeklyStarCycleResponse{Cycle: weeklyStarCycleToProto(cycle), Created: created}, nil } func (s *AdminWeeklyStarServer) SetWeeklyStarCycleStatus(ctx context.Context, req *activityv1.SetWeeklyStarCycleStatusRequest) (*activityv1.SetWeeklyStarCycleStatusResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) cycle, err := s.svc.SetCycleStatus(ctx, req.GetCycleId(), req.GetStatus(), req.GetOperatorAdminId()) if err != nil { return nil, xerr.ToGRPCError(err) } return &activityv1.SetWeeklyStarCycleStatusResponse{Cycle: weeklyStarCycleToProto(cycle)}, nil } func (s *AdminWeeklyStarServer) ListWeeklyStarLeaderboard(ctx context.Context, req *activityv1.ListWeeklyStarLeaderboardRequest) (*activityv1.ListWeeklyStarLeaderboardResponse, error) { return NewWeeklyStarServer(s.svc).ListWeeklyStarLeaderboard(ctx, req) } func (s *AdminWeeklyStarServer) ListWeeklyStarSettlements(ctx context.Context, req *activityv1.ListWeeklyStarSettlementsRequest) (*activityv1.ListWeeklyStarSettlementsResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) settlements, err := s.svc.ListSettlements(ctx, req.GetCycleId()) if err != nil { return nil, xerr.ToGRPCError(err) } resp := &activityv1.ListWeeklyStarSettlementsResponse{Settlements: make([]*activityv1.WeeklyStarSettlement, 0, len(settlements))} for _, settlement := range settlements { resp.Settlements = append(resp.Settlements, weeklyStarSettlementToProto(settlement)) } return resp, nil } func weeklyStarCycleFromProto(item *activityv1.WeeklyStarCycle) domain.Cycle { if item == nil { return domain.Cycle{} } cycle := domain.Cycle{ CycleID: item.GetCycleId(), ActivityCode: item.GetActivityCode(), RegionID: item.GetRegionId(), Title: item.GetTitle(), Status: item.GetStatus(), StartMS: item.GetStartMs(), EndMS: item.GetEndMs(), CreatedByAdminID: item.GetCreatedByAdminId(), UpdatedByAdminID: item.GetUpdatedByAdminId(), } for _, gift := range item.GetGifts() { cycle.Gifts = append(cycle.Gifts, domain.Gift{GiftID: gift.GetGiftId(), SortOrder: gift.GetSortOrder()}) } for _, reward := range item.GetRewards() { cycle.Rewards = append(cycle.Rewards, domain.Reward{RankNo: reward.GetRankNo(), ResourceGroupID: reward.GetResourceGroupId()}) } return cycle } func weeklyStarCycleToProto(item domain.Cycle) *activityv1.WeeklyStarCycle { if item.CycleID == "" { return nil } resp := &activityv1.WeeklyStarCycle{ AppCode: item.AppCode, CycleId: item.CycleID, ActivityCode: item.ActivityCode, RegionId: item.RegionID, Title: item.Title, Status: item.Status, StartMs: item.StartMS, EndMs: item.EndMS, Gifts: make([]*activityv1.WeeklyStarGift, 0, len(item.Gifts)), Rewards: make([]*activityv1.WeeklyStarReward, 0, len(item.Rewards)), CreatedByAdminId: item.CreatedByAdminID, UpdatedByAdminId: item.UpdatedByAdminID, SettledAtMs: item.SettledAtMS, CreatedAtMs: item.CreatedAtMS, UpdatedAtMs: item.UpdatedAtMS, } for _, gift := range item.Gifts { resp.Gifts = append(resp.Gifts, &activityv1.WeeklyStarGift{GiftId: gift.GiftID, SortOrder: gift.SortOrder}) } for _, reward := range item.Rewards { resp.Rewards = append(resp.Rewards, &activityv1.WeeklyStarReward{RankNo: reward.RankNo, ResourceGroupId: reward.ResourceGroupID}) } return resp } func weeklyStarEntryToProto(item domain.LeaderboardEntry) *activityv1.WeeklyStarLeaderboardEntry { if item.UserID <= 0 { return nil } return &activityv1.WeeklyStarLeaderboardEntry{ RankNo: item.RankNo, UserId: item.UserID, Score: item.Score, FirstScoredAtMs: item.FirstScoredAtMS, LastScoredAtMs: item.LastScoredAtMS, } } func weeklyStarEntriesToProto(items []domain.LeaderboardEntry) []*activityv1.WeeklyStarLeaderboardEntry { resp := make([]*activityv1.WeeklyStarLeaderboardEntry, 0, len(items)) for _, item := range items { resp = append(resp, weeklyStarEntryToProto(item)) } return resp } func weeklyStarSettlementToProto(item domain.Settlement) *activityv1.WeeklyStarSettlement { return &activityv1.WeeklyStarSettlement{ SettlementId: item.SettlementID, CycleId: item.CycleID, RankNo: item.RankNo, UserId: item.UserID, Score: item.Score, ResourceGroupId: item.ResourceGroupID, WalletCommandId: item.WalletCommandID, WalletGrantId: item.WalletGrantID, Status: item.Status, FailureReason: item.FailureReason, AttemptCount: item.AttemptCount, CreatedAtMs: item.CreatedAtMS, UpdatedAtMs: item.UpdatedAtMS, } }