- StatisticInternalProvider: TrackEvent/BatchTrackEvent
- StatisticCombinedProvider: all 9 RPCs (7 dashboard + 2 event) on single service
- materializer: 4 MV REFRESH CONCURRENTLY + pg_try_advisory_lock + refresh_log
- dashboard_repo: 7 aggregation SQLs (week_rank / 7d curve / top5 / level dist / upgrade progress)
- dashboard_service: 7 RPCs with Redis 5min TTL + cache miss protection (1min empty)
- Cache wrapper: JSON serialize + format dash:{rpc}:{starID}:{userID}
- main.go: integrated workers + Dubbo triple server :20009
- cross-service userService.GetFanProfile (for crystal_balance)
- client/user_rpc_client.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
40 lines
970 B
Go
40 lines
970 B
Go
package client
|
||
|
||
import (
|
||
"context"
|
||
|
||
pbUser "github.com/topfans/backend/pkg/proto/user"
|
||
)
|
||
|
||
// UserServiceClient 封装 userService 的 Dubbo 调用
|
||
type UserServiceClient struct {
|
||
userSocial pbUser.UserSocialService
|
||
}
|
||
|
||
// NewUserServiceClient 构造
|
||
func NewUserServiceClient(svc pbUser.UserSocialService) *UserServiceClient {
|
||
return &UserServiceClient{userSocial: svc}
|
||
}
|
||
|
||
// GetCrystalBalance 调 userService.GetFanProfile 取 crystal_balance
|
||
// (userService 没单独 GetCrystalBalance,FanProfile 含此字段)
|
||
func (c *UserServiceClient) GetCrystalBalance(ctx context.Context, userID, starID int64) (int64, error) {
|
||
resp, err := c.userSocial.GetFanProfile(ctx, &pbUser.GetFanProfileRequest{
|
||
UserId: userID,
|
||
StarId: starID,
|
||
})
|
||
if err != nil {
|
||
return 0, err
|
||
}
|
||
if resp == nil || resp.Base == nil {
|
||
return 0, nil
|
||
}
|
||
if resp.Base.Code != 0 {
|
||
return 0, nil
|
||
}
|
||
if resp.Profile == nil {
|
||
return 0, nil
|
||
}
|
||
return resp.Profile.CrystalBalance, nil
|
||
}
|