feat: 新增路由配置、交易处理和用户连击功能,并初始化相关服务与处理器

This commit is contained in:
2026-01-28 10:08:48 +08:00
parent 4d024eba8e
commit e811256d99
7 changed files with 508 additions and 2 deletions

View File

@@ -0,0 +1,109 @@
package repository
import (
"errors"
"time"
"accounting-app/internal/models"
"gorm.io/gorm"
)
// StreakRepository handles database operations for user streaks
type StreakRepository struct {
db *gorm.DB
}
// NewStreakRepository creates a new StreakRepository instance
func NewStreakRepository(db *gorm.DB) *StreakRepository {
return &StreakRepository{db: db}
}
// GetByUserID retrieves a user's streak record
func (r *StreakRepository) GetByUserID(userID uint) (*models.UserStreak, error) {
var streak models.UserStreak
if err := r.db.Where("user_id = ?", userID).First(&streak).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil // Return nil without error if not found
}
return nil, err
}
return &streak, nil
}
// Create creates a new streak record
func (r *StreakRepository) Create(streak *models.UserStreak) error {
return r.db.Create(streak).Error
}
// Update updates an existing streak record
func (r *StreakRepository) Update(streak *models.UserStreak) error {
return r.db.Save(streak).Error
}
// GetOrCreate retrieves existing streak record or creates a new one
func (r *StreakRepository) GetOrCreate(userID uint) (*models.UserStreak, error) {
streak, err := r.GetByUserID(userID)
if err != nil {
return nil, err
}
if streak == nil {
// Create new streak record
streak = &models.UserStreak{
UserID: userID,
CurrentStreak: 0,
LongestStreak: 0,
TotalRecordDays: 0,
}
if err := r.Create(streak); err != nil {
return nil, err
}
}
return streak, nil
}
// HasTransactionOnDate checks if user has any transaction on the given date
func (r *StreakRepository) HasTransactionOnDate(userID uint, date time.Time) (bool, error) {
var count int64
startOfDay := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
endOfDay := startOfDay.Add(24 * time.Hour)
err := r.db.Model(&models.Transaction{}).
Where("user_id = ? AND transaction_date >= ? AND transaction_date < ?", userID, startOfDay, endOfDay).
Count(&count).Error
if err != nil {
return false, err
}
return count > 0, nil
}
// GetTransactionDatesInRange returns all dates with transactions in a date range
func (r *StreakRepository) GetTransactionDatesInRange(userID uint, startDate, endDate time.Time) ([]time.Time, error) {
var dates []time.Time
rows, err := r.db.Model(&models.Transaction{}).
Select("DATE(transaction_date) as date").
Where("user_id = ? AND transaction_date >= ? AND transaction_date <= ?", userID, startDate, endDate).
Group("DATE(transaction_date)").
Order("date ASC").
Rows()
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var date time.Time
if err := rows.Scan(&date); err != nil {
return nil, err
}
dates = append(dates, date)
}
return dates, nil
}