130 lines
3.7 KiB
C#
130 lines
3.7 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using backend.Data;
|
||
using backend.DTOs;
|
||
using backend.Models;
|
||
|
||
namespace backend.Controllers;
|
||
|
||
[ApiController]
|
||
[Route("api/[controller]")]
|
||
public class UserController : ControllerBase
|
||
{
|
||
private readonly AppDbContext _db;
|
||
|
||
public UserController(AppDbContext db)
|
||
{
|
||
_db = db;
|
||
}
|
||
|
||
[HttpPost("register")]
|
||
public async Task<IActionResult> Register([FromBody] RegisterRequest request)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(request.FullName) || string.IsNullOrWhiteSpace(request.Contact))
|
||
{
|
||
return BadRequest(new { message = "نام و شناسه الزامی هستند." });
|
||
}
|
||
|
||
if (request.Contact.Length < 5)
|
||
{
|
||
return BadRequest(new { message = "شناسه باید حداقل ۵ کاراکتر باشد." });
|
||
}
|
||
|
||
// Check if contact already exists
|
||
var existingUser = await _db.Users.FirstOrDefaultAsync(u => u.Contact == request.Contact);
|
||
if (existingUser != null)
|
||
{
|
||
return Conflict(new { message = "این شناسه قبلاً ثبت شده است. لطفاً با کد رهگیری وارد شوید." });
|
||
}
|
||
|
||
// Generate unique tracking code
|
||
string trackingCode;
|
||
do
|
||
{
|
||
trackingCode = GenerateTrackingCode();
|
||
} while (await _db.Users.AnyAsync(u => u.TrackingCode == trackingCode));
|
||
|
||
var user = new User
|
||
{
|
||
FullName = request.FullName.Trim(),
|
||
Contact = request.Contact.Trim(),
|
||
TrackingCode = trackingCode
|
||
};
|
||
|
||
_db.Users.Add(user);
|
||
|
||
// Save the user first so that user.Id is populated by the database
|
||
await _db.SaveChangesAsync();
|
||
|
||
// Create initial total score record with the now-populated user.Id
|
||
var totalScore = new UserTotalScore
|
||
{
|
||
UserId = user.Id,
|
||
TotalPoints = 0
|
||
};
|
||
_db.UserTotalScores.Add(totalScore);
|
||
|
||
await _db.SaveChangesAsync();
|
||
|
||
return Ok(new RegisterResponse
|
||
{
|
||
UserId = user.Id,
|
||
TrackingCode = trackingCode
|
||
});
|
||
}
|
||
|
||
[HttpPost("login")]
|
||
public async Task<IActionResult> Login([FromBody] LoginRequest request)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(request.TrackingCode))
|
||
{
|
||
return BadRequest(new { message = "کد رهگیری الزامی است." });
|
||
}
|
||
|
||
var user = await _db.Users
|
||
.Include(u => u.QuizAttempt)
|
||
.Include(u => u.KhatmSelections)
|
||
.FirstOrDefaultAsync(u => u.TrackingCode == request.TrackingCode.Trim());
|
||
|
||
if (user == null)
|
||
{
|
||
return NotFound(new { message = "کد رهگیری نامعتبر است." });
|
||
}
|
||
|
||
return Ok(new LoginResponse
|
||
{
|
||
UserId = user.Id,
|
||
FullName = user.FullName,
|
||
Contact = user.Contact,
|
||
IsQuizCompleted = user.QuizAttempt != null,
|
||
KhatmSelections = user.KhatmSelections
|
||
.Where(ks => ks.IsSelected)
|
||
.Select(ks => ks.KhatmItemId)
|
||
.ToList()
|
||
});
|
||
}
|
||
|
||
[HttpGet("{userId}/score")]
|
||
public async Task<IActionResult> GetScore(int userId)
|
||
{
|
||
var totalScore = await _db.UserTotalScores
|
||
.FirstOrDefaultAsync(ts => ts.UserId == userId);
|
||
|
||
if (totalScore == null)
|
||
{
|
||
return NotFound(new { message = "کاربر یافت نشد." });
|
||
}
|
||
|
||
return Ok(new UserScoreResponse
|
||
{
|
||
TotalScore = totalScore.TotalPoints
|
||
});
|
||
}
|
||
|
||
private static string GenerateTrackingCode()
|
||
{
|
||
var random = new Random();
|
||
return random.Next(1000, 10000).ToString();
|
||
}
|
||
}
|