370 lines
14 KiB
Go
370 lines
14 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/growth"
|
|
service "hyapp/services/activity-service/internal/service/growth"
|
|
)
|
|
|
|
// GrowthLevelServer 把 App 等级查询和内部等级事件消费适配为 gRPC。
|
|
type GrowthLevelServer struct {
|
|
activityv1.UnimplementedGrowthLevelServiceServer
|
|
|
|
svc *service.Service
|
|
}
|
|
|
|
func NewGrowthLevelServer(svc *service.Service) *GrowthLevelServer {
|
|
return &GrowthLevelServer{svc: svc}
|
|
}
|
|
|
|
func (s *GrowthLevelServer) GetMyLevelOverview(ctx context.Context, req *activityv1.GetMyLevelOverviewRequest) (*activityv1.GetMyLevelOverviewResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
overview, err := s.svc.GetMyLevelOverview(ctx, req.GetUserId())
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
resp := &activityv1.GetMyLevelOverviewResponse{
|
|
Tracks: make([]*activityv1.LevelTrackOverview, 0, len(overview.Tracks)),
|
|
ServerTimeMs: overview.ServerTimeMS,
|
|
}
|
|
for _, item := range overview.Tracks {
|
|
resp.Tracks = append(resp.Tracks, levelTrackOverviewToProto(item))
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *GrowthLevelServer) GetLevelTrack(ctx context.Context, req *activityv1.GetLevelTrackRequest) (*activityv1.GetLevelTrackResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
detail, err := s.svc.GetLevelTrack(ctx, req.GetUserId(), req.GetTrack())
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
resp := &activityv1.GetLevelTrackResponse{
|
|
Overview: levelTrackOverviewToProto(detail.Overview),
|
|
Rules: make([]*activityv1.LevelRule, 0, len(detail.Rules)),
|
|
Tiers: make([]*activityv1.LevelTier, 0, len(detail.Tiers)),
|
|
ServerTimeMs: detail.ServerTimeMS,
|
|
}
|
|
for _, rule := range detail.Rules {
|
|
resp.Rules = append(resp.Rules, levelRuleToProto(rule))
|
|
}
|
|
for _, tier := range detail.Tiers {
|
|
resp.Tiers = append(resp.Tiers, levelTierToProto(tier))
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *GrowthLevelServer) BatchGetUserLevelDisplayProfiles(ctx context.Context, req *activityv1.BatchGetUserLevelDisplayProfilesRequest) (*activityv1.BatchGetUserLevelDisplayProfilesResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
profiles, err := s.svc.BatchGetUserLevelDisplayProfiles(ctx, req.GetUserIds())
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
resp := &activityv1.BatchGetUserLevelDisplayProfilesResponse{
|
|
Profiles: make([]*activityv1.UserLevelDisplayProfile, 0, len(profiles.Profiles)),
|
|
ServerTimeMs: profiles.ServerTimeMS,
|
|
}
|
|
for _, item := range profiles.Profiles {
|
|
resp.Profiles = append(resp.Profiles, userLevelDisplayProfileToProto(item))
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *GrowthLevelServer) ListLevelRewards(ctx context.Context, req *activityv1.ListLevelRewardsRequest) (*activityv1.ListLevelRewardsResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
rewards, total, err := s.svc.ListLevelRewards(ctx, domain.RewardQuery{
|
|
UserID: req.GetUserId(),
|
|
Track: req.GetTrack(),
|
|
Status: req.GetStatus(),
|
|
Page: req.GetPage(),
|
|
PageSize: req.GetPageSize(),
|
|
})
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
resp := &activityv1.ListLevelRewardsResponse{Rewards: make([]*activityv1.LevelRewardJob, 0, len(rewards)), Total: total}
|
|
for _, reward := range rewards {
|
|
resp.Rewards = append(resp.Rewards, levelRewardToProto(reward))
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *GrowthLevelServer) ConsumeLevelEvent(ctx context.Context, req *activityv1.ConsumeLevelEventRequest) (*activityv1.ConsumeLevelEventResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
result, err := s.svc.ConsumeLevelEvent(ctx, domain.ValueEvent{
|
|
EventID: req.GetEventId(),
|
|
SourceEventID: req.GetSourceEventId(),
|
|
SourceService: req.GetSourceService(),
|
|
SourceEventType: req.GetSourceEventType(),
|
|
UserID: req.GetUserId(),
|
|
Track: req.GetTrack(),
|
|
MetricType: req.GetMetricType(),
|
|
ValueDelta: req.GetValueDelta(),
|
|
OccurredAtMS: req.GetOccurredAtMs(),
|
|
DimensionsJSON: req.GetDimensionsJson(),
|
|
})
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
return &activityv1.ConsumeLevelEventResponse{
|
|
EventId: result.EventID,
|
|
Status: result.Status,
|
|
LevelChanged: result.LevelChanged,
|
|
PreviousLevel: result.PreviousLevel,
|
|
NewLevel: result.NewLevel,
|
|
RewardJobCount: result.RewardJobCount,
|
|
}, nil
|
|
}
|
|
|
|
func (s *GrowthLevelServer) SetUserLevel(ctx context.Context, req *activityv1.SetUserLevelRequest) (*activityv1.SetUserLevelResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
result, err := s.svc.SetUserLevel(ctx, domain.SetUserLevelCommand{
|
|
CommandID: req.GetCommandId(),
|
|
UserID: req.GetUserId(),
|
|
Track: req.GetTrack(),
|
|
Level: req.GetLevel(),
|
|
OperatorUserID: req.GetOperatorUserId(),
|
|
Reason: req.GetReason(),
|
|
})
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
return &activityv1.SetUserLevelResponse{
|
|
EventId: result.EventID,
|
|
Status: result.Status,
|
|
Track: result.Track,
|
|
PreviousLevel: result.PreviousLevel,
|
|
NewLevel: result.NewLevel,
|
|
TotalValue: result.TotalValue,
|
|
RewardJobCount: result.RewardJobCount,
|
|
ServerTimeMs: result.ServerTimeMS,
|
|
}, nil
|
|
}
|
|
|
|
func (s *GrowthLevelServer) IssueRegistrationLevelBadges(ctx context.Context, req *activityv1.IssueRegistrationLevelBadgesRequest) (*activityv1.IssueRegistrationLevelBadgesResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
grants, err := s.svc.IssueRegistrationLevelBadges(ctx, req.GetUserId(), req.GetCommandId())
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
resp := &activityv1.IssueRegistrationLevelBadgesResponse{
|
|
Grants: make([]*activityv1.RegistrationLevelBadgeGrant, 0, len(grants.Grants)),
|
|
ServerTimeMs: grants.ServerTimeMS,
|
|
}
|
|
for _, item := range grants.Grants {
|
|
resp.Grants = append(resp.Grants, registrationLevelBadgeGrantToProto(item))
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
// AdminGrowthLevelServer 暴露后台等级配置入口,业务约束仍由 service/repository 校验。
|
|
type AdminGrowthLevelServer struct {
|
|
activityv1.UnimplementedAdminGrowthLevelServiceServer
|
|
|
|
svc *service.Service
|
|
}
|
|
|
|
func NewAdminGrowthLevelServer(svc *service.Service) *AdminGrowthLevelServer {
|
|
return &AdminGrowthLevelServer{svc: svc}
|
|
}
|
|
|
|
func (s *AdminGrowthLevelServer) ListLevelConfig(ctx context.Context, req *activityv1.ListLevelConfigRequest) (*activityv1.ListLevelConfigResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
config, err := s.svc.ListLevelConfig(ctx, domain.ConfigQuery{
|
|
Track: req.GetTrack(),
|
|
Status: req.GetStatus(),
|
|
})
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
resp := &activityv1.ListLevelConfigResponse{
|
|
Tracks: make([]*activityv1.LevelTrack, 0, len(config.Tracks)),
|
|
Rules: make([]*activityv1.LevelRule, 0, len(config.Rules)),
|
|
Tiers: make([]*activityv1.LevelTier, 0, len(config.Tiers)),
|
|
ServerTimeMs: config.ServerTimeMS,
|
|
}
|
|
for _, track := range config.Tracks {
|
|
resp.Tracks = append(resp.Tracks, levelTrackToProto(track))
|
|
}
|
|
for _, rule := range config.Rules {
|
|
resp.Rules = append(resp.Rules, levelRuleToProto(rule))
|
|
}
|
|
for _, tier := range config.Tiers {
|
|
resp.Tiers = append(resp.Tiers, levelTierToProto(tier))
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *AdminGrowthLevelServer) UpsertLevelTrack(ctx context.Context, req *activityv1.UpsertLevelTrackRequest) (*activityv1.UpsertLevelTrackResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
item, created, err := s.svc.UpsertLevelTrack(ctx, domain.TrackCommand{
|
|
Track: req.GetTrack(),
|
|
Name: req.GetName(),
|
|
Status: req.GetStatus(),
|
|
SortOrder: req.GetSortOrder(),
|
|
DisplayConfigJSON: req.GetDisplayConfigJson(),
|
|
})
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
return &activityv1.UpsertLevelTrackResponse{Track: levelTrackToProto(item), Created: created}, nil
|
|
}
|
|
|
|
func (s *AdminGrowthLevelServer) UpsertLevelRule(ctx context.Context, req *activityv1.UpsertLevelRuleRequest) (*activityv1.UpsertLevelRuleResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
item, created, err := s.svc.UpsertLevelRule(ctx, domain.RuleCommand{
|
|
Track: req.GetTrack(),
|
|
Level: req.GetLevel(),
|
|
RequiredValue: req.GetRequiredValue(),
|
|
Name: req.GetName(),
|
|
Status: req.GetStatus(),
|
|
RewardResourceGroupID: req.GetRewardResourceGroupId(),
|
|
SortOrder: req.GetSortOrder(),
|
|
DisplayConfigJSON: req.GetDisplayConfigJson(),
|
|
OperatorAdminID: req.GetOperatorAdminId(),
|
|
})
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
return &activityv1.UpsertLevelRuleResponse{Rule: levelRuleToProto(item), Created: created}, nil
|
|
}
|
|
|
|
func (s *AdminGrowthLevelServer) UpsertLevelTier(ctx context.Context, req *activityv1.UpsertLevelTierRequest) (*activityv1.UpsertLevelTierResponse, error) {
|
|
ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode())
|
|
item, created, err := s.svc.UpsertLevelTier(ctx, domain.TierCommand{
|
|
TierID: req.GetTierId(),
|
|
Track: req.GetTrack(),
|
|
MinLevel: req.GetMinLevel(),
|
|
MaxLevel: req.GetMaxLevel(),
|
|
Name: req.GetName(),
|
|
DisplayAvatarFrameResourceID: req.GetDisplayAvatarFrameResourceId(),
|
|
DisplayBadgeResourceID: req.GetDisplayBadgeResourceId(),
|
|
RewardResourceGroupID: req.GetRewardResourceGroupId(),
|
|
Status: req.GetStatus(),
|
|
DisplayConfigJSON: req.GetDisplayConfigJson(),
|
|
OperatorAdminID: req.GetOperatorAdminId(),
|
|
})
|
|
if err != nil {
|
|
return nil, xerr.ToGRPCError(err)
|
|
}
|
|
return &activityv1.UpsertLevelTierResponse{Tier: levelTierToProto(item), Created: created}, nil
|
|
}
|
|
|
|
func levelTrackToProto(item domain.Track) *activityv1.LevelTrack {
|
|
return &activityv1.LevelTrack{
|
|
Track: item.Track,
|
|
Name: item.Name,
|
|
Status: item.Status,
|
|
SortOrder: item.SortOrder,
|
|
DisplayConfigJson: item.DisplayConfigJSON,
|
|
CreatedAtMs: item.CreatedAtMS,
|
|
UpdatedAtMs: item.UpdatedAtMS,
|
|
}
|
|
}
|
|
|
|
func levelRuleToProto(item domain.Rule) *activityv1.LevelRule {
|
|
return &activityv1.LevelRule{
|
|
Track: item.Track,
|
|
Level: item.Level,
|
|
RequiredValue: item.RequiredValue,
|
|
Name: item.Name,
|
|
Status: item.Status,
|
|
RewardResourceGroupId: item.RewardResourceGroupID,
|
|
SortOrder: item.SortOrder,
|
|
DisplayConfigJson: item.DisplayConfigJSON,
|
|
CreatedByAdminId: item.CreatedByAdminID,
|
|
UpdatedByAdminId: item.UpdatedByAdminID,
|
|
CreatedAtMs: item.CreatedAtMS,
|
|
UpdatedAtMs: item.UpdatedAtMS,
|
|
}
|
|
}
|
|
|
|
func levelTierToProto(item domain.Tier) *activityv1.LevelTier {
|
|
return &activityv1.LevelTier{
|
|
TierId: item.TierID,
|
|
Track: item.Track,
|
|
MinLevel: item.MinLevel,
|
|
MaxLevel: item.MaxLevel,
|
|
Name: item.Name,
|
|
DisplayAvatarFrameResourceId: item.DisplayAvatarFrameResourceID,
|
|
DisplayBadgeResourceId: item.DisplayBadgeResourceID,
|
|
RewardResourceGroupId: item.RewardResourceGroupID,
|
|
Status: item.Status,
|
|
DisplayConfigJson: item.DisplayConfigJSON,
|
|
CreatedByAdminId: item.CreatedByAdminID,
|
|
UpdatedByAdminId: item.UpdatedByAdminID,
|
|
CreatedAtMs: item.CreatedAtMS,
|
|
UpdatedAtMs: item.UpdatedAtMS,
|
|
}
|
|
}
|
|
|
|
func levelTrackOverviewToProto(item domain.TrackOverview) *activityv1.LevelTrackOverview {
|
|
return &activityv1.LevelTrackOverview{
|
|
Track: item.Track,
|
|
Name: item.Name,
|
|
Level: item.Level,
|
|
TierId: item.TierID,
|
|
TotalValue: item.TotalValue,
|
|
CurrentLevelRequiredValue: item.CurrentLevelRequiredValue,
|
|
NextLevel: item.NextLevel,
|
|
NextLevelRequiredValue: item.NextLevelRequiredValue,
|
|
DisplayAvatarFrameResourceId: item.DisplayAvatarFrameResourceID,
|
|
DisplayBadgeResourceId: item.DisplayBadgeResourceID,
|
|
DisplayBadgeSourceLevel: item.DisplayBadgeSourceLevel,
|
|
RewardPendingCount: item.RewardPendingCount,
|
|
SortOrder: item.SortOrder,
|
|
}
|
|
}
|
|
|
|
func userLevelDisplayProfileToProto(item domain.UserLevelDisplayProfile) *activityv1.UserLevelDisplayProfile {
|
|
return &activityv1.UserLevelDisplayProfile{
|
|
UserId: item.UserID,
|
|
Wealth: levelDisplayTrackProfileToProto(item.Wealth),
|
|
Game: levelDisplayTrackProfileToProto(item.Game),
|
|
Charm: levelDisplayTrackProfileToProto(item.Charm),
|
|
}
|
|
}
|
|
|
|
func levelDisplayTrackProfileToProto(item domain.LevelDisplayTrackProfile) *activityv1.LevelDisplayTrackProfile {
|
|
return &activityv1.LevelDisplayTrackProfile{
|
|
Track: item.Track,
|
|
Level: item.Level,
|
|
TierId: item.TierID,
|
|
AvatarFrameResourceId: item.AvatarFrameResourceID,
|
|
BadgeResourceId: item.BadgeResourceID,
|
|
BadgeSourceLevel: item.BadgeSourceLevel,
|
|
UpdatedAtMs: item.UpdatedAtMS,
|
|
}
|
|
}
|
|
|
|
func levelRewardToProto(item domain.RewardJob) *activityv1.LevelRewardJob {
|
|
return &activityv1.LevelRewardJob{
|
|
RewardJobId: item.RewardJobID,
|
|
UserId: item.UserID,
|
|
Track: item.Track,
|
|
RewardSourceType: item.RewardSourceType,
|
|
RewardSourceId: item.RewardSourceID,
|
|
ResourceGroupId: item.ResourceGroupID,
|
|
WalletCommandId: item.WalletCommandID,
|
|
WalletGrantId: item.WalletGrantID,
|
|
Status: item.Status,
|
|
AttemptCount: item.AttemptCount,
|
|
FailureReason: item.FailureReason,
|
|
CreatedAtMs: item.CreatedAtMS,
|
|
UpdatedAtMs: item.UpdatedAtMS,
|
|
}
|
|
}
|
|
|
|
func registrationLevelBadgeGrantToProto(item domain.RegistrationLevelBadgeGrant) *activityv1.RegistrationLevelBadgeGrant {
|
|
return &activityv1.RegistrationLevelBadgeGrant{
|
|
Track: item.Track,
|
|
Level: item.Level,
|
|
ResourceId: item.ResourceID,
|
|
GrantId: item.GrantID,
|
|
}
|
|
}
|