package provider import ( "context" "fmt" "strconv" "github.com/topfans/backend/pkg/logger" pb "github.com/topfans/backend/pkg/proto/task" "github.com/topfans/backend/services/taskService/service" "go.uber.org/zap" ) // TaskMobileProvider 实现 TaskMobileService 接口 type TaskMobileProvider struct { dailySvc service.DailyTaskService onboardingSvc service.OnboardingService revenueSvc service.RevenueService } func NewTaskMobileProvider( dailySvc service.DailyTaskService, onboardingSvc service.OnboardingService, revenueSvc service.RevenueService, ) *TaskMobileProvider { return &TaskMobileProvider{ dailySvc: dailySvc, onboardingSvc: onboardingSvc, revenueSvc: revenueSvc, } } // extractUserInfoFromDubboAttachments 从 Dubbo attachments 提取用户信息 func extractUserInfoFromDubboAttachments(ctx context.Context) (int64, int64, error) { // Dubbo-go 使用 constant.AttachmentKey 获取 attachments // 但这里使用通用的 context.Value 方式 if attachments := ctx.Value("attachments"); attachments != nil { if attMap, ok := attachments.(map[string]interface{}); ok { userID, starID := extractUserInfoFromMap(attMap) if userID > 0 && starID > 0 { return userID, starID, nil } } } return 0, 0, fmt.Errorf("failed to extract user info from Dubbo attachments") } // extractUserInfoFromMap 从 map 中提取用户信息 func extractUserInfoFromMap(attMap map[string]interface{}) (int64, int64) { var userID, starID int64 if uid, ok := attMap["user_id"]; ok { switch v := uid.(type) { case int64: userID = v case float64: userID = int64(v) case string: if parsed, err := strconv.ParseInt(v, 10, 64); err == nil { userID = parsed } } } if sid, ok := attMap["star_id"]; ok { switch v := sid.(type) { case int64: starID = v case float64: starID = int64(v) case string: if parsed, err := strconv.ParseInt(v, 10, 64); err == nil { starID = parsed } } } return userID, starID } func (p *TaskMobileProvider) GetDailyTasks(ctx context.Context, req *pb.GetDailyTasksRequest) (*pb.GetDailyTasksResponse, error) { userID, starID, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("GetDailyTasks: failed to extract user", zap.Error(err)) return &pb.GetDailyTasksResponse{ Tasks: []*pb.DailyTaskItem{}, }, nil } logger.Logger.Debug("GetDailyTasks", zap.Int64("user_id", userID), zap.Int64("star_id", starID)) return p.dailySvc.GetDailyTasks(ctx, userID, starID) } func (p *TaskMobileProvider) ReportEvent(ctx context.Context, req *pb.ReportEventRequest) (*pb.ReportEventResponse, error) { userID, _, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("ReportEvent: failed to extract user", zap.Error(err)) return &pb.ReportEventResponse{ Success: false, }, nil } logger.Logger.Debug("ReportEvent", zap.Int64("user_id", userID), zap.String("event_type", req.EventType), zap.Int64("star_id", req.StarId)) return p.dailySvc.ReportEvent(ctx, userID, req.StarId, req.EventType) } func (p *TaskMobileProvider) ClaimDailyTask(ctx context.Context, req *pb.ClaimDailyTaskRequest) (*pb.ClaimDailyTaskResponse, error) { userID, _, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("ClaimDailyTask: failed to extract user", zap.Error(err)) return &pb.ClaimDailyTaskResponse{Success: false}, nil } logger.Logger.Debug("ClaimDailyTask", zap.Int64("user_id", userID), zap.String("task_key", req.TaskKey), zap.Int64("star_id", req.StarId)) return p.dailySvc.ClaimDailyTask(ctx, userID, req.StarId, req.TaskKey) } func (p *TaskMobileProvider) ClaimAllDailyTasks(ctx context.Context, req *pb.ClaimAllDailyTasksRequest) (*pb.ClaimAllDailyTasksResponse, error) { userID, _, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("ClaimAllDailyTasks: failed to extract user", zap.Error(err)) return &pb.ClaimAllDailyTasksResponse{ClaimedCount: 0}, nil } logger.Logger.Debug("ClaimAllDailyTasks", zap.Int64("user_id", userID), zap.Int64("star_id", req.StarId)) return p.dailySvc.ClaimAllDailyTasks(ctx, userID, req.StarId) } func (p *TaskMobileProvider) CompleteGuide(ctx context.Context, req *pb.CompleteGuideRequest) (*pb.CompleteGuideResponse, error) { userID, _, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("CompleteGuide: failed to extract user", zap.Error(err)) return &pb.CompleteGuideResponse{}, nil } logger.Logger.Debug("CompleteGuide", zap.Int64("user_id", userID), zap.String("task_key", req.TaskKey)) return p.onboardingSvc.CompleteGuide(ctx, userID, req.TaskKey) } func (p *TaskMobileProvider) GetOnboardingStatus(ctx context.Context, req *pb.GetOnboardingStatusRequest) (*pb.GetOnboardingStatusResponse, error) { userID, _, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("GetOnboardingStatus: failed to extract user", zap.Error(err)) return &pb.GetOnboardingStatusResponse{}, nil } logger.Logger.Debug("GetOnboardingStatus", zap.Int64("user_id", userID)) return p.onboardingSvc.GetOnboardingStatus(ctx, userID) } func (p *TaskMobileProvider) AdvanceStage(ctx context.Context, req *pb.AdvanceStageRequest) (*pb.AdvanceStageResponse, error) { userID, _, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("AdvanceStage: failed to extract user", zap.Error(err)) return &pb.AdvanceStageResponse{}, nil } logger.Logger.Debug("AdvanceStage", zap.Int64("user_id", userID), zap.Int32("target_stage", req.TargetStage)) return p.onboardingSvc.AdvanceStage(ctx, userID, req.TargetStage) } func (p *TaskMobileProvider) ClaimOnboardingReward(ctx context.Context, req *pb.ClaimOnboardingRewardRequest) (*pb.ClaimOnboardingRewardResponse, error) { userID, _, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("ClaimOnboardingReward: failed to extract user", zap.Error(err)) return &pb.ClaimOnboardingRewardResponse{Success: false}, nil } logger.Logger.Debug("ClaimOnboardingReward", zap.Int64("user_id", userID), zap.Int32("stage", req.Stage)) return p.onboardingSvc.ClaimOnboardingReward(ctx, userID, req.Stage) } func (p *TaskMobileProvider) GetExhibitionRevenue(ctx context.Context, req *pb.GetExhibitionRevenueRequest) (*pb.GetExhibitionRevenueResponse, error) { userID, starID, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("GetExhibitionRevenue: failed to extract user", zap.Error(err)) return &pb.GetExhibitionRevenueResponse{ Items: []*pb.ExhibitionRevenueItem{}, }, nil } logger.Logger.Debug("GetExhibitionRevenue", zap.Int64("user_id", userID), zap.Int64("star_id", starID), zap.String("status", req.Status)) return p.revenueSvc.GetExhibitionRevenue(ctx, userID, starID, req.Status, req.Page, req.PageSize) } func (p *TaskMobileProvider) ClaimExhibitionRevenue(ctx context.Context, req *pb.ClaimExhibitionRevenueRequest) (*pb.ClaimExhibitionRevenueResponse, error) { userID, starID, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("ClaimExhibitionRevenue: failed to extract user", zap.Error(err)) return &pb.ClaimExhibitionRevenueResponse{Success: false}, nil } logger.Logger.Debug("ClaimExhibitionRevenue", zap.Int64("user_id", userID), zap.Int64("star_id", starID), zap.Int64("revenue_id", req.RevenueId)) return p.revenueSvc.ClaimExhibitionRevenue(ctx, userID, starID, req.RevenueId) } func (p *TaskMobileProvider) ClaimAllExhibitionRevenue(ctx context.Context, req *pb.ClaimAllExhibitionRevenueRequest) (*pb.ClaimAllExhibitionRevenueResponse, error) { userID, starID, err := extractUserInfoFromDubboAttachments(ctx) if err != nil { logger.Logger.Error("ClaimAllExhibitionRevenue: failed to extract user", zap.Error(err)) return &pb.ClaimAllExhibitionRevenueResponse{ClaimedCount: 0}, nil } logger.Logger.Debug("ClaimAllExhibitionRevenue", zap.Int64("user_id", userID), zap.Int64("star_id", starID)) return p.revenueSvc.ClaimAllExhibitionRevenue(ctx, userID, starID) }