107 lines
3.6 KiB
C#
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();
|
|
}
|
|
}
|