feat: 添加用户记账连击(streak)功能,包括服务、处理器、模型和仓库层。
This commit is contained in:
@@ -107,3 +107,51 @@ func (r *StreakRepository) GetTransactionDatesInRange(userID uint, startDate, en
|
||||
|
||||
return dates, nil
|
||||
}
|
||||
|
||||
// GetDailyContribution returns daily transaction counts in a date range
|
||||
func (r *StreakRepository) GetDailyContribution(userID uint, startDate, endDate time.Time) ([]models.DailyContribution, error) {
|
||||
var results []models.DailyContribution
|
||||
|
||||
// SQLite uses strftime, MySQL/Postgres uses DATE()
|
||||
// Using a more generic approach compatible with SQLite (which is likely used locally)
|
||||
// For production readiness with multiple DBs, raw SQL might be safer or check dialect
|
||||
|
||||
rows, err := r.db.Model(&models.Transaction{}).
|
||||
Select("DATE(transaction_date) as date, COUNT(*) as count").
|
||||
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 dateStr string // Using string to handle potential format differences
|
||||
var count int
|
||||
// Scan into generic types then convert
|
||||
// Some drivers return date as time.Time, some as string/bytes
|
||||
// Let's try scan into string first (common for DATE() function result)
|
||||
// Or scan into interface{} to be safe
|
||||
if err := rows.Scan(&dateStr, &count); err != nil {
|
||||
// If string scan fails, try time.Time
|
||||
// Unfortunately we can't rewind rows. scan is one-way.
|
||||
// But usually drivers handle string conversion for DATE()
|
||||
// If this fails we might need to adjust based on specific DB driver
|
||||
return nil, err
|
||||
}
|
||||
// Normalize date string to YYYY-MM-DD (take first 10 chars if it includes time)
|
||||
if len(dateStr) > 10 {
|
||||
dateStr = dateStr[:10]
|
||||
}
|
||||
|
||||
results = append(results, models.DailyContribution{
|
||||
Date: dateStr,
|
||||
Count: count,
|
||||
})
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user