2026-04-20 22:07:10 +08:00

160 lines
4.4 KiB
Go

package signinreward
import (
"context"
"net/http"
"strconv"
"strings"
"time"
"chatapp3-golang/internal/model"
"gorm.io/gorm"
)
type signInRewardRecordRow struct {
model.SignInRewardLog
Account string `gorm:"column:account"`
UserAvatar string `gorm:"column:user_avatar"`
UserNickname string `gorm:"column:user_nickname"`
CountryCode string `gorm:"column:country_code"`
CountryName string `gorm:"column:country_name"`
}
// PageRecords 返回后台签到记录分页数据。
func (s *SignInRewardService) PageRecords(
ctx context.Context,
sysOrigin string,
claimDate string,
status string,
userID int64,
cursor int,
limit int,
) (*SignInRewardRecordPageResponse, error) {
sysOrigin = normalizeSignInRewardSysOrigin(sysOrigin)
if sysOrigin == "" {
return nil, NewAppError(http.StatusBadRequest, "bad_request", "sysOrigin is required")
}
bundle, err := s.loadConfigBundle(ctx, sysOrigin)
if err != nil {
return nil, err
}
location := resolveSignInRewardLocation(signInRewardDefaultTimezone)
if bundle.Config != nil {
location = resolveSignInRewardLocation(bundle.Config.Timezone)
}
resolvedDate := normalizeSignInRewardClaimDate(claimDate, location)
page, size := normalizeSignInRewardPage(cursor, limit)
query := s.newRecordBaseQuery(ctx, sysOrigin, resolvedDate)
if strings.TrimSpace(status) != "" {
query = query.Where("log.status = ?", strings.ToUpper(strings.TrimSpace(status)))
}
if userID > 0 {
query = query.Where("log.user_id = ?", userID)
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, err
}
var signCount int64
if err := s.newRecordBaseQuery(ctx, sysOrigin, resolvedDate).Count(&signCount).Error; err != nil {
return nil, err
}
var successCount int64
if err := s.newRecordBaseQuery(ctx, sysOrigin, resolvedDate).
Where("log.status = ?", signInRewardStatusSuccess).
Count(&successCount).Error; err != nil {
return nil, err
}
records := make([]SignInRewardRecordView, 0)
if total > 0 {
var rows []signInRewardRecordRow
if err := query.
Select("log.*, user.account, user.user_avatar, user.user_nickname, user.country_code, user.country_name").
Joins("LEFT JOIN user_base_info AS user ON user.id = log.user_id").
Order("log.create_time desc").
Order("log.id desc").
Offset((page - 1) * size).
Limit(size).
Find(&rows).Error; err != nil {
return nil, err
}
records = make([]SignInRewardRecordView, 0, len(rows))
for _, row := range rows {
records = append(records, SignInRewardRecordView{
ID: row.ID,
UserID: row.UserID,
Account: row.Account,
UserAvatar: row.UserAvatar,
UserNickname: row.UserNickname,
CountryCode: row.CountryCode,
CountryName: row.CountryName,
ClaimDate: row.ClaimDate,
DayIndex: row.DayIndex,
StreakCount: row.StreakCount,
RewardGroupID: row.RewardGroupID,
RewardGroupName: row.RewardGroupName,
Status: strings.ToUpper(strings.TrimSpace(row.Status)),
ErrorMessage: strings.TrimSpace(row.ErrorMessage),
CreateTime: formatSignInRewardDateTime(row.CreateTime),
UpdateTime: formatSignInRewardDateTime(row.UpdateTime),
})
}
}
return &SignInRewardRecordPageResponse{
Date: resolvedDate,
Timezone: location.String(),
SignCount: signCount,
SuccessCount: successCount,
Records: records,
Total: total,
}, nil
}
func (s *SignInRewardService) newRecordBaseQuery(ctx context.Context, sysOrigin string, claimDate string) *gorm.DB {
return s.repo.DB.WithContext(ctx).
Table("sign_in_reward_log AS log").
Where("log.sys_origin = ? AND log.claim_date = ?", sysOrigin, claimDate)
}
func normalizeSignInRewardClaimDate(claimDate string, location *time.Location) string {
claimDate = strings.TrimSpace(claimDate)
if claimDate != "" {
return claimDate
}
return time.Now().In(location).Format("2006-01-02")
}
func normalizeSignInRewardPage(cursor int, limit int) (int, int) {
if cursor <= 0 {
cursor = 1
}
if limit <= 0 {
limit = 20
}
if limit > 100 {
limit = 100
}
return cursor, limit
}
// ParseSignInRewardUserID 解析后台分页查询里传入的 userId。
func ParseSignInRewardUserID(raw string) int64 {
value := strings.TrimSpace(raw)
if value == "" {
return 0
}
parsed, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return 0
}
return parsed
}