package rechargereward import ( "context" "net/http" "strings" "time" ) // GetHome 返回当前登录用户的充值奖励 H5 数据。 func (s *Service) GetHome(ctx context.Context, user AuthUser) (*RechargeRewardHomeResponse, error) { sysOrigin, err := requireRechargeRewardUser(user) if err != nil { return nil, err } if s.java == nil { return nil, NewAppError(http.StatusServiceUnavailable, "java_gateway_unavailable", "java gateway is unavailable") } bundle, err := s.loadConfigBundle(ctx, sysOrigin) if err != nil { return nil, err } location := s.location if bundle.Config != nil { location = resolveLocation(bundle.Config.Timezone, s.location) } now := time.Now().In(location) periodStart, periodEnd := currentMonthBounds(now, location) currentRechargeCents, err := s.loadCurrentRechargeCents(ctx, user.UserID) if err != nil { return nil, err } accumulatedRechargeCents, err := s.loadAccumulatedRechargeCents(ctx, user.UserID) if err != nil { return nil, err } resp := &RechargeRewardHomeResponse{ ActivityStatus: rechargeRewardActivityStatus(bundle.Config != nil && bundle.Config.Enabled), Configured: bundle.Config != nil, Enabled: bundle.Config != nil && bundle.Config.Enabled, SysOrigin: sysOrigin, Timezone: location.String(), PeriodStartAt: formatDateTime(periodStart), PeriodEndAt: formatDateTime(periodEnd), CountdownMillis: maxInt64(0, periodEnd.UnixMilli()-now.UnixMilli()), UserID: user.UserID, CurrentRechargeAmount: formatAmountCents(currentRechargeCents), CurrentRechargeAmountCents: currentRechargeCents, AccumulatedRechargeAmount: formatAmountCents(accumulatedRechargeCents), AccumulatedRechargeAmountCents: accumulatedRechargeCents, LevelConfigs: []RechargeRewardLevelPayload{}, } if bundle.Config != nil { resp.SysOrigin = bundle.Config.SysOrigin resp.Timezone = normalizeRechargeRewardTimezone(bundle.Config.Timezone) } if profile, err := s.java.GetUserProfile(ctx, user.UserID); err == nil { resp.UserAccount = profile.Account resp.UserNickname = profile.UserNickname resp.UserAvatar = profile.UserAvatar } else if !isEmptyJavaProfileError(err) { return nil, err } if bundle.Config == nil { return resp, nil } matched, matchedOK := pickMatchedLevel(bundle.Levels, currentRechargeCents) next, nextOK := pickNextLevel(bundle.Levels, currentRechargeCents) if matchedOK { resp.MatchedLevel = matched.Level } if nextOK { resp.NextLevel = next.Level resp.NextRechargeAmount = formatAmountCents(next.RechargeAmountCents) resp.NextRechargeAmountCents = next.RechargeAmountCents } rewardItems := s.loadRewardItemsMap(ctx, bundle.Levels) matchedLevel := 0 if matchedOK { matchedLevel = matched.Level } resp.LevelConfigs = buildLevelPayloads(bundle.Levels, rewardItems, currentRechargeCents, matchedLevel) return resp, nil } func (s *Service) loadCurrentRechargeCents(ctx context.Context, userID int64) (int64, error) { amount, err := s.java.GetThisMonthTotalPersonalRecharge(ctx, userID) if err != nil { return 0, err } return parseIntegrationAmountCents(integrationAmount(amount)), nil } func (s *Service) loadAccumulatedRechargeCents(ctx context.Context, userID int64) (int64, error) { recharges, err := s.java.MapUserTotalRecharge(ctx, []int64{userID}) if err != nil { return 0, err } return totalRechargeCents(recharges[userID]), nil } func currentMonthBounds(now time.Time, location *time.Location) (time.Time, time.Time) { local := now.In(location) start := time.Date(local.Year(), local.Month(), 1, 0, 0, 0, 0, location) return start, start.AddDate(0, 1, 0) } func resolveLocation(timezone string, fallback *time.Location) *time.Location { location, err := time.LoadLocation(normalizeRechargeRewardTimezone(timezone)) if err == nil { return location } if fallback != nil { return fallback } return time.UTC } func rechargeRewardActivityStatus(enabled bool) string { if enabled { return rechargeRewardActivityStatusOngoing } return rechargeRewardActivityStatusDisabled } func isEmptyJavaProfileError(err error) bool { if err == nil { return false } return strings.Contains(strings.ToLower(err.Error()), "empty") } func maxInt64(a, b int64) int64 { if a > b { return a } return b }