dramaling-vocab-learning/backend/DramaLing.Api/Repositories/UserRepository.cs

201 lines
5.1 KiB
C#

using Microsoft.EntityFrameworkCore;
using DramaLing.Api.Data;
using DramaLing.Api.Models.Entities;
namespace DramaLing.Api.Repositories;
/// <summary>
/// User Repository 實作
/// </summary>
public class UserRepository : BaseRepository<User>, IUserRepository
{
public UserRepository(DramaLingDbContext context, ILogger<UserRepository> logger)
: base(context, logger)
{
}
#region
public async Task<User?> GetByEmailAsync(string email)
{
try
{
return await _dbSet
.AsNoTracking()
.FirstOrDefaultAsync(u => u.Email == email);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting user by email: {Email}", email);
throw;
}
}
public async Task<User?> GetByUsernameAsync(string username)
{
try
{
return await _dbSet
.AsNoTracking()
.FirstOrDefaultAsync(u => u.Username == username);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting user by username: {Username}", username);
throw;
}
}
public async Task<bool> ExistsByEmailAsync(string email)
{
try
{
return await _dbSet.AnyAsync(u => u.Email == email);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error checking user existence by email: {Email}", email);
throw;
}
}
public async Task<bool> ExistsByUsernameAsync(string username)
{
try
{
return await _dbSet.AnyAsync(u => u.Username == username);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error checking user existence by username: {Username}", username);
throw;
}
}
#endregion
#region
public async Task<User?> GetUserWithSettingsAsync(Guid userId)
{
try
{
return await _dbSet
.AsNoTracking()
.Include(u => u.Settings)
.FirstOrDefaultAsync(u => u.Id == userId);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting user with settings: {UserId}", userId);
throw;
}
}
public async Task<User?> GetUserWithStatsAsync(Guid userId)
{
try
{
return await _dbSet
.AsNoTracking()
.Include(u => u.DailyStats!)
.FirstOrDefaultAsync(u => u.Id == userId);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting user with stats: {UserId}", userId);
throw;
}
}
#endregion
#region
public async Task<Dictionary<string, object>> GetUserLearningStatsAsync(Guid userId)
{
try
{
var stats = new Dictionary<string, object>
{
["TotalFlashcards"] = 0,
["MasteredFlashcards"] = 0,
["MasteryRate"] = 0.0,
["StudyDaysThisMonth"] = 0,
["TotalStudyTimeSeconds"] = 0
};
return stats;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting user learning stats: {UserId}", userId);
throw;
}
}
public async Task<int> GetTotalStudyTimeAsync(Guid userId)
{
try
{
return 0; // 簡化實作
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting total study time: {UserId}", userId);
throw;
}
}
public async Task<DateTime?> GetLastActivityDateAsync(Guid userId)
{
try
{
return DateTime.UtcNow; // 簡化實作
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting last activity date: {UserId}", userId);
throw;
}
}
#endregion
#region
public async Task<IEnumerable<User>> GetActiveUsersAsync(int days)
{
try
{
return await _dbSet
.AsNoTracking()
.Take(10) // 簡化實作
.ToListAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting active users for {Days} days", days);
throw;
}
}
public async Task<IEnumerable<User>> GetNewUsersAsync(DateTime since)
{
try
{
return await _dbSet
.AsNoTracking()
.Where(u => u.CreatedAt >= since)
.OrderByDescending(u => u.CreatedAt)
.ToListAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting new users since: {Since}", since);
throw;
}
}
#endregion
}