topfans/backend/services/statisticService/provider/statistic_combined_provider.go
2026-06-09 00:37:42 +08:00

133 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package provider
import (
"context"
"strconv"
"time"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"go.uber.org/zap"
"github.com/topfans/backend/pkg/logger"
pb "github.com/topfans/backend/pkg/proto/statistic"
"github.com/topfans/backend/services/statisticService/metrics"
"github.com/topfans/backend/services/statisticService/service"
)
// StatisticCombinedProvider 完整 StatisticService 实现9 RPC
// - 看板 7 RPCT12 由 DashboardService 实现)
// - 事件 2 RPCT9 由 StatisticInternalProvider 实现)
type StatisticCombinedProvider struct {
*StatisticInternalProvider
dashSvc *service.DashboardService
}
// NewStatisticCombinedProvider 构造
func NewStatisticCombinedProvider(internal *StatisticInternalProvider, dashSvc *service.DashboardService) *StatisticCombinedProvider {
return &StatisticCombinedProvider{
StatisticInternalProvider: internal,
dashSvc: dashSvc,
}
}
func userIDFromContext(ctx context.Context) int64 {
// 必须从 Dubbo attachments 读取(与 assetService/socialService/userService 一致)
// 协议gateway 通过 ctx.Value(constant.AttachmentKey, map{"user_id": "1"}) 写入
// 经过 triple 协议传输后gateway 的 string 在 attachments 里变成 ["1"](单元素字符串数组)
// 之前用 ctx.Value("user_id") 直接读 string key永远拿到 nil → 返回 0
if attachments := ctx.Value(constant.AttachmentKey); attachments != nil {
if attMap, ok := attachments.(map[string]interface{}); ok {
if v, ok := attMap["user_id"]; ok {
switch s := v.(type) {
case string:
n, _ := strconv.ParseInt(s, 10, 64)
return n
case int64:
return s
case int:
return int64(s)
case float64:
return int64(s)
case []string:
if len(s) > 0 {
n, _ := strconv.ParseInt(s[0], 10, 64)
return n
}
case []interface{}:
if len(s) > 0 {
switch inner := s[0].(type) {
case string:
n, _ := strconv.ParseInt(inner, 10, 64)
return n
case int64:
return inner
case int:
return int64(inner)
case float64:
return int64(inner)
}
}
}
}
}
}
return 0
}
func (p *StatisticCombinedProvider) recordRPC(rpc string, start time.Time, err error) {
status := "ok"
if err != nil {
status = "error"
}
metrics.DashboardRPCTotal.WithLabelValues(rpc, status).Inc()
metrics.DashboardRPCDuration.WithLabelValues(rpc).Observe(time.Since(start).Seconds())
}
// ===== 看板 7 RPC =====
func (p *StatisticCombinedProvider) GetTodayOverview(ctx context.Context, req *pb.GetTodayOverviewRequest) (*pb.GetTodayOverviewResponse, error) {
t0 := time.Now()
defer func() { p.recordRPC("GetTodayOverview", t0, nil) }()
resp, err := p.dashSvc.GetTodayOverview(ctx, userIDFromContext(ctx), req.StarId)
if err != nil {
logger.Logger.Warn("GetTodayOverview failed", zap.Error(err))
}
return resp, err
}
func (p *StatisticCombinedProvider) Get7DayIncomeCurve(ctx context.Context, req *pb.Get7DayIncomeCurveRequest) (*pb.Get7DayIncomeCurveResponse, error) {
t0 := time.Now()
defer func() { p.recordRPC("Get7DayIncomeCurve", t0, nil) }()
return p.dashSvc.Get7DayIncomeCurve(ctx, userIDFromContext(ctx), req.StarId)
}
func (p *StatisticCombinedProvider) GetExhibitionIncomeSummary(ctx context.Context, req *pb.GetExhibitionIncomeSummaryRequest) (*pb.GetExhibitionIncomeSummaryResponse, error) {
t0 := time.Now()
defer func() { p.recordRPC("GetExhibitionIncomeSummary", t0, nil) }()
return p.dashSvc.GetExhibitionIncomeSummary(ctx, userIDFromContext(ctx), req.StarId)
}
func (p *StatisticCombinedProvider) GetLikeIncomeByLevel(ctx context.Context, req *pb.GetLikeIncomeByLevelRequest) (*pb.GetLikeIncomeByLevelResponse, error) {
t0 := time.Now()
defer func() { p.recordRPC("GetLikeIncomeByLevel", t0, nil) }()
return p.dashSvc.GetLikeIncomeByLevel(ctx, userIDFromContext(ctx), req.StarId)
}
func (p *StatisticCombinedProvider) GetTopAssetsByEarning(ctx context.Context, req *pb.GetTopAssetsByEarningRequest) (*pb.GetTopAssetsByEarningResponse, error) {
t0 := time.Now()
defer func() { p.recordRPC("GetTopAssetsByEarning", t0, nil) }()
return p.dashSvc.GetTopAssetsByEarning(ctx, userIDFromContext(ctx), req.StarId)
}
func (p *StatisticCombinedProvider) GetAssetLevelDistribution(ctx context.Context, req *pb.GetAssetLevelDistributionRequest) (*pb.GetAssetLevelDistributionResponse, error) {
t0 := time.Now()
defer func() { p.recordRPC("GetAssetLevelDistribution", t0, nil) }()
return p.dashSvc.GetAssetLevelDistribution(ctx, userIDFromContext(ctx), req.StarId)
}
func (p *StatisticCombinedProvider) GetAssetUpgradeProgress(ctx context.Context, req *pb.GetAssetUpgradeProgressRequest) (*pb.GetAssetUpgradeProgressResponse, error) {
t0 := time.Now()
defer func() { p.recordRPC("GetAssetUpgradeProgress", t0, nil) }()
return p.dashSvc.GetAssetUpgradeProgress(ctx, userIDFromContext(ctx), req.StarId)
}