134 lines
4.0 KiB
Go
134 lines
4.0 KiB
Go
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)
|
|
period := s.displayPeriod(now, location)
|
|
currentPeriod, periodActive := s.currentPeriod(now, location)
|
|
|
|
var currentRechargeCents int64
|
|
if periodActive {
|
|
currentRechargeCents, err = s.loadCurrentRechargeCents(ctx, sysOrigin, user.UserID, currentPeriod)
|
|
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(period.StartAt),
|
|
PeriodEndAt: formatDateTime(period.EndAt),
|
|
CountdownMillis: maxInt64(0, period.EndAt.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, resp.SysOrigin, bundle.Levels)
|
|
matchedLevel := 0
|
|
if matchedOK {
|
|
matchedLevel = matched.Level
|
|
}
|
|
resp.LevelConfigs = buildLevelPayloads(bundle.Levels, rewardItems, currentRechargeCents, matchedLevel)
|
|
return resp, 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 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
|
|
}
|