QrRapido/Controllers/QRController.cs
Ricardo Carneiro 7a0c12f8d2
Some checks failed
Deploy QR Rapido / test (push) Failing after 17s
Deploy QR Rapido / build-and-push (push) Has been skipped
Deploy QR Rapido / deploy-staging (push) Has been skipped
Deploy QR Rapido / deploy-production (push) Has been skipped
feat: api separada do front-end e area do desenvolvedor.
2026-03-08 12:40:51 -03:00

200 lines
7.2 KiB
C#

using Microsoft.AspNetCore.Mvc;
using QRRapidoApp.Models.ViewModels;
using QRRapidoApp.Models.DTOs;
using QRRapidoApp.Services;
using System.Diagnostics;
using System.Security.Claims;
using System.Text;
using System.Security.Cryptography;
using Microsoft.Extensions.Localization;
using QRRapidoApp.Models;
using MongoDB.Driver;
namespace QRRapidoApp.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class QRController : ControllerBase
{
private readonly IQRBusinessManager _qrBusinessManager;
private readonly IUserService _userService;
private readonly IQRCodeService _qrService; // Mantido para Download
private readonly ILogger<QRController> _logger;
private readonly IStringLocalizer<QRRapidoApp.Resources.SharedResource> _localizer;
public QRController(
IQRBusinessManager qrBusinessManager,
IUserService userService,
IQRCodeService qrService,
ILogger<QRController> logger,
IStringLocalizer<QRRapidoApp.Resources.SharedResource> localizer)
{
_qrBusinessManager = qrBusinessManager;
_userService = userService;
_qrService = qrService;
_logger = logger;
_localizer = localizer;
}
[HttpPost("GenerateRapid")]
public async Task<IActionResult> GenerateRapid([FromBody] QRGenerationRequest request)
{
var context = new UserRequesterContext
{
UserId = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value,
IpAddress = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown",
DeviceId = Request.Cookies["_qr_device_id"]
};
var result = await _qrBusinessManager.ProcessGenerationAsync(request, context);
if (!result.Success)
{
if (result.ErrorCode == "LIMIT_REACHED")
{
return StatusCode(429, new
{
error = result.Message,
upgradeUrl = "/Account/Login"
});
}
if (result.ErrorCode == "INSUFFICIENT_CREDITS")
{
return StatusCode(402, new {
success = false,
error = result.Message,
redirectUrl = "/Pagamento/SelecaoPlano"
});
}
return BadRequest(new { success = false, error = result.Message });
}
// Gerenciar Cookie de DeviceID para anônimos
if (!context.IsAuthenticated && string.IsNullOrEmpty(context.DeviceId))
{
var newDeviceId = Guid.NewGuid().ToString("N");
Response.Cookies.Append("_qr_device_id", newDeviceId, new CookieOptions
{
Expires = DateTime.UtcNow.AddYears(1),
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.Strict
});
}
return Ok(new
{
success = true,
QRCodeBase64 = result.QRCodeBase64,
QRId = result.QRId,
FromCache = result.FromCache,
RemainingQRs = context.IsAuthenticated ? result.RemainingCredits : (result.RemainingFreeQRs > 0 ? result.RemainingFreeQRs : 0),
Message = result.Message,
GenerationTimeMs = result.GenerationTimeMs
});
}
[HttpGet("GetUserStats")]
public async Task<IActionResult> GetUserStats()
{
var userId = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (string.IsNullOrEmpty(userId)) return Unauthorized();
var user = await _userService.GetUserAsync(userId);
if (user == null) return NotFound();
return Ok(new
{
credits = user.Credits,
freeUsed = user.FreeQRsUsed,
freeLimit = 5,
isPremium = user.Credits > 0 || user.FreeQRsUsed < 5
});
}
[HttpGet("Download/{qrId}")]
public async Task<IActionResult> Download(string qrId, string format = "png")
{
try
{
var qrData = await _userService.GetQRDataAsync(qrId);
if (qrData == null) return NotFound();
byte[] fileContent = Convert.FromBase64String(qrData.QRCodeBase64);
var contentType = "image/png";
var fileName = $"qrrapido-{qrId}.png";
if (format == "svg")
{
fileContent = await _qrService.ConvertToSvgAsync(qrData.QRCodeBase64);
contentType = "image/svg+xml";
fileName = fileName.Replace(".png", ".svg");
}
else if (format == "pdf")
{
fileContent = await _qrService.ConvertToPdfAsync(qrData.QRCodeBase64, qrData.Size);
contentType = "application/pdf";
fileName = fileName.Replace(".png", ".pdf");
}
return File(fileContent, contentType, fileName);
}
catch (Exception ex)
{
_logger.LogError(ex, "Download error");
return StatusCode(500);
}
}
[HttpGet("History")]
public async Task<IActionResult> GetHistory(int limit = 20)
{
var userId = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (string.IsNullOrEmpty(userId)) return Unauthorized();
return Ok(await _userService.GetUserQRHistoryAsync(userId, limit));
}
[HttpPost("GenerateRapidWithLogo")]
public async Task<IActionResult> GenerateRapidWithLogo([FromForm] QRGenerationRequest request, IFormFile? logo)
{
var userId = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (string.IsNullOrEmpty(userId)) return Unauthorized();
if (logo != null)
{
using var ms = new MemoryStream();
await logo.CopyToAsync(ms);
request.Logo = ms.ToArray();
request.HasLogo = true;
}
var context = new UserRequesterContext
{
UserId = userId,
IpAddress = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown"
};
var result = await _qrBusinessManager.ProcessGenerationAsync(request, context);
if (!result.Success) return BadRequest(result);
return Ok(new {
success = true,
QRCodeBase64 = result.QRCodeBase64,
QRId = result.QRId,
RemainingQRs = result.RemainingCredits
});
}
[HttpPost("SaveToHistory")]
public async Task<IActionResult> SaveToHistory([FromBody] SaveToHistoryRequest request)
{
return Ok(new { success = true });
}
}
public class SaveToHistoryRequest
{
public string QrId { get; set; } = string.Empty;
}
}