2026-05-25 23:20:32 +08:00

170 lines
4.7 KiB
Go

package firstrechargereward
import (
"context"
"sort"
"strings"
"time"
"chatapp3-golang/internal/integration"
"chatapp3-golang/internal/model"
)
func configSnapshotFromModel(row model.FirstRechargeRewardConfig) configSnapshot {
return configSnapshot{
ID: row.ID,
SysOrigin: strings.ToUpper(strings.TrimSpace(row.SysOrigin)),
Enabled: row.Enabled,
UpdateTime: row.UpdateTime,
}
}
func levelSnapshotFromModel(row model.FirstRechargeRewardLevel) levelSnapshot {
return levelSnapshot{
ID: row.ID,
Level: row.Level,
RechargeAmountCents: row.RechargeAmountCents,
RewardGroupID: row.RewardGroupID,
RewardGroupName: strings.TrimSpace(row.RewardGroupName),
Enabled: row.Enabled,
}
}
func refConfigSnapshot(value configSnapshot) *configSnapshot {
return &value
}
func buildLevelPayloads(
levels []levelSnapshot,
rewardItems map[int64][]RewardItem,
currentRechargeCents int64,
matchedLevel int,
admin bool,
) []LevelPayload {
payloads := make([]LevelPayload, 0, len(levels))
for _, level := range levels {
if !admin && !level.Enabled {
continue
}
payloads = append(payloads, LevelPayload{
ID: level.ID,
Level: level.Level,
RechargeAmount: formatAmountCents(level.RechargeAmountCents),
RechargeAmountCents: level.RechargeAmountCents,
RewardGroupID: level.RewardGroupID,
RewardGroupName: level.RewardGroupName,
RewardItems: rewardItems[level.RewardGroupID],
Enabled: level.Enabled,
Reached: currentRechargeCents >= level.RechargeAmountCents,
Current: matchedLevel > 0 && matchedLevel == level.Level,
})
}
return payloads
}
func pickMatchedLevel(levels []levelSnapshot, rechargeAmountCents int64) (levelSnapshot, bool) {
var matched levelSnapshot
ok := false
for _, level := range levels {
if !level.Enabled || level.RechargeAmountCents <= 0 || level.RewardGroupID <= 0 {
continue
}
if rechargeAmountCents >= level.RechargeAmountCents && (!ok || level.RechargeAmountCents > matched.RechargeAmountCents) {
matched = level
ok = true
}
}
return matched, ok
}
func sortLevels(levels []levelSnapshot) {
sort.Slice(levels, func(i, j int) bool {
if levels[i].RechargeAmountCents == levels[j].RechargeAmountCents {
return levels[i].Level < levels[j].Level
}
return levels[i].RechargeAmountCents < levels[j].RechargeAmountCents
})
}
func (s *Service) loadRewardItemsMap(ctx context.Context, levels []levelSnapshot) map[int64][]RewardItem {
if s.java == nil {
return map[int64][]RewardItem{}
}
groupIDs := make([]int64, 0)
seen := make(map[int64]struct{})
for _, level := range levels {
if level.RewardGroupID <= 0 {
continue
}
if _, exists := seen[level.RewardGroupID]; exists {
continue
}
seen[level.RewardGroupID] = struct{}{}
groupIDs = append(groupIDs, level.RewardGroupID)
}
sort.Slice(groupIDs, func(i, j int) bool { return groupIDs[i] < groupIDs[j] })
result := make(map[int64][]RewardItem, len(groupIDs))
for _, groupID := range groupIDs {
detail, err := s.java.GetRewardGroupDetail(ctx, groupID)
if err != nil {
continue
}
result[groupID] = rewardItemsFromGroup(detail)
}
return result
}
func rewardItemsFromGroup(detail integration.RewardGroupDetail) []RewardItem {
items := make([]RewardItem, 0, len(detail.RewardConfigList))
for _, item := range detail.RewardConfigList {
items = append(items, RewardItem{
ID: int64(item.ID),
Type: rewardItemDisplayType(item),
Name: strings.TrimSpace(item.Name),
Content: strings.TrimSpace(item.Content),
Quantity: int64(item.Quantity),
Cover: firstNonEmpty(item.Cover, item.SourceURL),
Remark: strings.TrimSpace(item.Remark),
})
}
return items
}
func rewardItemDisplayType(item integration.RewardGroupItem) string {
itemType := strings.ToUpper(strings.TrimSpace(item.Type))
detailType := strings.ToUpper(strings.TrimSpace(item.DetailType))
if itemType == "PROPS" {
if detailType != "" && detailType != "PROPS" {
return detailType
}
if isVipRewardItem(item) {
return "NOBLE_VIP"
}
}
return itemType
}
func isVipRewardItem(item integration.RewardGroupItem) bool {
name := strings.ToUpper(strings.TrimSpace(item.Name))
remark := strings.ToUpper(strings.TrimSpace(item.Remark))
return strings.Contains(name, "VIP") ||
strings.Contains(name, "NOBLE") ||
strings.Contains(remark, "VIP") ||
strings.Contains(remark, "NOBLE")
}
func formatDateTime(t time.Time) string {
if t.IsZero() {
return ""
}
return t.Format("2006-01-02 15:04:05")
}
func formatPtrDateTime(t *time.Time) string {
if t == nil {
return ""
}
return formatDateTime(*t)
}