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 }