2026-05-15 23:44:56 +08:00

199 lines
6.7 KiB
Go

package voiceroomrocket
import (
"context"
"net/http"
"strings"
"time"
"chatapp3-golang/internal/model"
)
// ListRewardPopups 返回当前用户未读中奖弹窗记录。
func (s *Service) ListRewardPopups(ctx context.Context, user AuthUser, roomID int64) (*RewardPopupResponse, error) {
sysOrigin := s.normalizeSysOrigin(user.SysOrigin)
query := s.repo.DB.WithContext(ctx).
Where("sys_origin = ? AND user_id = ? AND popup_status = ?", sysOrigin, user.UserID, popupStatusUnread).
Order("create_time DESC, id DESC").
Limit(100)
if roomID > 0 {
query = query.Where("room_id = ?", roomID)
}
var rows []model.VoiceRoomRocketRewardRecord
if err := query.Find(&rows).Error; err != nil {
return nil, err
}
records := toRewardRecordViews(rows, s.mapUserProfiles(ctx, rewardRecordUserIDs(rows)))
return &RewardPopupResponse{Records: records}, nil
}
// AckRewardPopups 标记中奖弹窗为已读。
func (s *Service) AckRewardPopups(ctx context.Context, user AuthUser, req AckRewardPopupsRequest) error {
if len(req.RewardRecordIDs) == 0 {
return NewAppError(http.StatusBadRequest, "missing_reward_record_ids", "rewardRecordIds is required")
}
ids := make([]int64, 0, len(req.RewardRecordIDs))
for _, id := range req.RewardRecordIDs {
if id.Int64() > 0 {
ids = append(ids, id.Int64())
}
}
if len(ids) == 0 {
return NewAppError(http.StatusBadRequest, "missing_reward_record_ids", "rewardRecordIds is required")
}
return s.repo.DB.WithContext(ctx).
Model(&model.VoiceRoomRocketRewardRecord{}).
Where("sys_origin = ? AND user_id = ? AND id IN ?", s.normalizeSysOrigin(user.SysOrigin), user.UserID, ids).
Updates(map[string]any{
"popup_status": popupStatusRead,
"update_time": time.Now(),
}).Error
}
// PageRewardRecords 返回用户最近中奖记录。
func (s *Service) PageRewardRecords(ctx context.Context, user AuthUser, roomID int64, cursor int, limit int) (*RewardRecordPageResponse, error) {
cursor, limit = normalizePage(cursor, limit)
snapshot, err := s.loadConfig(ctx, user.SysOrigin)
if err != nil {
return nil, err
}
keepDays := snapshot.RewardRecordKeepDays
if keepDays <= 0 {
keepDays = defaultRewardRecordKeepDays
}
startAt := time.Now().AddDate(0, 0, -keepDays)
query := s.repo.DB.WithContext(ctx).
Where("sys_origin = ? AND user_id = ? AND create_time >= ?", snapshot.SysOrigin, user.UserID, startAt).
Order("create_time DESC, id DESC").
Offset((cursor - 1) * limit).
Limit(limit)
if roomID > 0 {
query = query.Where("room_id = ?", roomID)
}
var rows []model.VoiceRoomRocketRewardRecord
if err := query.Find(&rows).Error; err != nil {
return nil, err
}
records := toRewardRecordViews(rows, s.mapUserProfiles(ctx, rewardRecordUserIDs(rows)))
resp := &RewardRecordPageResponse{
Records: records,
Cursor: cursor,
Limit: limit,
}
if len(records) == 0 {
resp.EmptyReason = "仅展示最近 35 天的记录"
}
return resp, nil
}
// PageRoomRewardRecords 返回房间内某次火箭发射的全部中奖记录。
func (s *Service) PageRoomRewardRecords(ctx context.Context, user AuthUser, roomID int64, launchNo string, cursor int, limit int) (*RewardRecordPageResponse, error) {
cursor, limit = normalizePage(cursor, limit)
snapshot, err := s.loadConfig(ctx, user.SysOrigin)
if err != nil {
return nil, err
}
keepDays := snapshot.RewardRecordKeepDays
if keepDays <= 0 {
keepDays = defaultRewardRecordKeepDays
}
startAt := time.Now().AddDate(0, 0, -keepDays)
launchNo = strings.TrimSpace(launchNo)
if launchNo == "" {
query := s.repo.DB.WithContext(ctx).
Model(&model.VoiceRoomRocketRewardRecord{}).
Where("sys_origin = ? AND create_time >= ? AND launch_no <> ?", snapshot.SysOrigin, startAt, "").
Order("create_time DESC, id DESC").
Limit(1)
if roomID > 0 {
query = query.Where("room_id = ?", roomID)
}
var launchNos []string
if err := query.Pluck("launch_no", &launchNos).Error; err != nil {
return nil, err
}
if len(launchNos) == 0 {
return &RewardRecordPageResponse{Records: []RewardRecordView{}, Cursor: cursor, Limit: limit}, nil
}
launchNo = launchNos[0]
}
query := s.repo.DB.WithContext(ctx).
Where("sys_origin = ? AND launch_no = ? AND create_time >= ?", snapshot.SysOrigin, launchNo, startAt).
Order("create_time DESC, id DESC").
Offset((cursor - 1) * limit).
Limit(limit)
if roomID > 0 {
query = query.Where("room_id = ?", roomID)
}
var rows []model.VoiceRoomRocketRewardRecord
if err := query.Find(&rows).Error; err != nil {
return nil, err
}
records := toRewardRecordViews(rows, s.mapUserProfiles(ctx, rewardRecordUserIDs(rows)))
return &RewardRecordPageResponse{Records: records, Cursor: cursor, Limit: limit}, nil
}
// PageAdminLaunchRecords 返回后台发射记录。
func (s *Service) PageAdminLaunchRecords(ctx context.Context, sysOrigin string, roomID int64, cursor int, limit int) (*LaunchRecordPageResponse, error) {
cursor, limit = normalizePage(cursor, limit)
query := s.repo.DB.WithContext(ctx).
Where("sys_origin = ?", s.normalizeSysOrigin(sysOrigin)).
Order("launch_time DESC, id DESC").
Offset((cursor - 1) * limit).
Limit(limit)
if roomID > 0 {
query = query.Where("room_id = ?", roomID)
}
var rows []model.VoiceRoomRocketLaunch
if err := query.Find(&rows).Error; err != nil {
return nil, err
}
records := make([]LaunchRecordView, 0, len(rows))
for _, row := range rows {
records = append(records, toLaunchRecordView(row))
}
return &LaunchRecordPageResponse{Records: records, Cursor: cursor, Limit: limit}, nil
}
// PageAdminRewardRecords 返回后台奖励记录。
func (s *Service) PageAdminRewardRecords(ctx context.Context, sysOrigin string, roomID int64, userID int64, grantStatus string, cursor int, limit int) (*RewardRecordPageResponse, error) {
cursor, limit = normalizePage(cursor, limit)
query := s.repo.DB.WithContext(ctx).
Where("sys_origin = ?", s.normalizeSysOrigin(sysOrigin)).
Order("create_time DESC, id DESC").
Offset((cursor - 1) * limit).
Limit(limit)
if roomID > 0 {
query = query.Where("room_id = ?", roomID)
}
if userID > 0 {
query = query.Where("user_id = ?", userID)
}
if grantStatus != "" {
query = query.Where("grant_status = ?", grantStatus)
}
var rows []model.VoiceRoomRocketRewardRecord
if err := query.Find(&rows).Error; err != nil {
return nil, err
}
records := toRewardRecordViews(rows, s.mapUserProfiles(ctx, rewardRecordUserIDs(rows)))
return &RewardRecordPageResponse{Records: records, Cursor: cursor, Limit: limit}, nil
}
func rewardRecordUserIDs(rows []model.VoiceRoomRocketRewardRecord) []int64 {
seen := make(map[int64]struct{}, len(rows))
userIDs := make([]int64, 0, len(rows))
for _, row := range rows {
if row.UserID <= 0 {
continue
}
if _, ok := seen[row.UserID]; ok {
continue
}
seen[row.UserID] = struct{}{}
userIDs = append(userIDs, row.UserID)
}
return userIDs
}