Files
UniVerse/backend/UniVerse.Infrastructure/Services/UserService.cs
T

107 lines
3.6 KiB
C#

using Microsoft.EntityFrameworkCore;
using UniVerse.Application.DTOs.Common;
using UniVerse.Application.DTOs.Users;
using UniVerse.Application.Interfaces;
using UniVerse.Application.Mappings;
using UniVerse.Domain.Enums;
using UniVerse.Domain.Exceptions;
using UniVerse.Infrastructure.Data;
namespace UniVerse.Infrastructure.Services;
public class UserService : IUserService
{
private readonly AppDbContext _db;
private readonly IGamificationService _gamification;
public UserService(AppDbContext db, IGamificationService gamification)
{
_db = db;
_gamification = gamification;
}
public async Task<UserDto> GetByIdAsync(int id)
{
var user = await _db.Users.FindAsync(id)
?? throw new NotFoundException("User", id);
return user.ToDto(_gamification.CalculateLevel(user.Xp));
}
public async Task<UserDto> UpdateProfileAsync(int id, UpdateUserRequest request)
{
var user = await _db.Users.FindAsync(id)
?? throw new NotFoundException("User", id);
if (request.DisplayName != null) user.DisplayName = request.DisplayName;
if (request.AvatarUrl != null) user.AvatarUrl = request.AvatarUrl;
user.UpdatedAt = DateTime.UtcNow;
await _db.SaveChangesAsync();
return user.ToDto(_gamification.CalculateLevel(user.Xp));
}
public async Task<UserStatsDto> GetStatsAsync(int id)
{
var user = await _db.Users.FindAsync(id)
?? throw new NotFoundException("User", id);
var totalLectures = await _db.LectureEnrollments.CountAsync(e => e.UserId == id);
var attended = await _db.LectureEnrollments.CountAsync(e => e.UserId == id && e.Attended);
var reviews = await _db.Reviews.CountAsync(r => r.UserId == id);
var achievements = await _db.UserAchievements.CountAsync(ua => ua.UserId == id);
return new UserStatsDto(
totalLectures, attended, reviews,
user.Xp, user.Coins, _gamification.CalculateLevel(user.Xp), achievements
);
}
public async Task<PagedResult<UserDto>> GetAllAsync(UserFilterRequest filter)
{
var query = _db.Users.AsQueryable();
if (!string.IsNullOrEmpty(filter.Search))
{
var search = filter.Search.ToLower();
query = query.Where(u =>
u.Email.ToLower().Contains(search) ||
(u.DisplayName != null && u.DisplayName.ToLower().Contains(search)));
}
if (filter.Role.HasValue)
query = query.Where(u => u.Role == filter.Role.Value);
if (filter.IsActive.HasValue)
query = query.Where(u => u.IsActive == filter.IsActive.Value);
var total = await query.CountAsync();
var users = await query
.OrderByDescending(u => u.CreatedAt)
.Skip((filter.Page - 1) * filter.PageSize)
.Take(filter.PageSize)
.ToListAsync();
var items = users.Select(u => u.ToDto(_gamification.CalculateLevel(u.Xp))).ToList();
return PagedResult<UserDto>.Create(items, total, filter.Page, filter.PageSize);
}
public async Task SetRoleAsync(int id, UserRole role)
{
var user = await _db.Users.FindAsync(id)
?? throw new NotFoundException("User", id);
user.Role = role;
user.UpdatedAt = DateTime.UtcNow;
await _db.SaveChangesAsync();
}
public async Task SetActiveAsync(int id, bool isActive)
{
var user = await _db.Users.FindAsync(id)
?? throw new NotFoundException("User", id);
user.IsActive = isActive;
user.UpdatedAt = DateTime.UtcNow;
await _db.SaveChangesAsync();
}
}