101 lines
3.8 KiB
C#
101 lines
3.8 KiB
C#
using Extrudex.Domain.Enums;
|
||
using Extrudex.Domain.Interfaces;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
|
||
namespace Extrudex.API.Controllers;
|
||
|
||
/// <summary>
|
||
/// Controller for generating QR codes for Extrudex resources (spools, printers, locations).
|
||
/// Returns QR codes as PNG or SVG images optimized for small label printing.
|
||
/// QR codes encode deep links that resolve to the resource's detail page.
|
||
/// </summary>
|
||
[ApiController]
|
||
[Route("api/qr")]
|
||
public class QrController : ControllerBase
|
||
{
|
||
private readonly IQrCodeService _qrCodeService;
|
||
private readonly ILogger<QrController> _logger;
|
||
|
||
/// <summary>
|
||
/// Initializes a new instance of the <see cref="QrController"/> class.
|
||
/// </summary>
|
||
/// <param name="qrCodeService">The QR code generation service.</param>
|
||
/// <param name="logger">The logger for diagnostic output.</param>
|
||
public QrController(IQrCodeService qrCodeService, ILogger<QrController> logger)
|
||
{
|
||
_qrCodeService = qrCodeService;
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Generates a QR code for the specified resource type and ID.
|
||
/// Returns the QR code as a PNG image by default, or as SVG when
|
||
/// the <c>format</c> query parameter is set to "svg".
|
||
/// </summary>
|
||
/// <param name="resourceType">
|
||
/// The type of resource: <c>spool</c>, <c>printer</c>, or <c>location</c>.
|
||
/// </param>
|
||
/// <param name="id">The unique identifier of the resource.</param>
|
||
/// <param name="format">
|
||
/// Optional output format: <c>png</c> (default) or <c>svg</c>.
|
||
/// SVG is resolution-independent and ideal for printing at any scale.
|
||
/// </param>
|
||
/// <param name="size">
|
||
/// Optional pixel density per QR module for PNG output (default: 20).
|
||
/// Ignored for SVG output. Range: 4–40.
|
||
/// </param>
|
||
/// <returns>The QR code image in the requested format.</returns>
|
||
/// <response code="200">Returns the QR code image.</response>
|
||
/// <response code="400">If the resource type is invalid or parameters are out of range.</response>
|
||
[HttpGet("{resourceType}/{id:guid}")]
|
||
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK, "image/png")]
|
||
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK, "image/svg+xml")]
|
||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||
public IActionResult GetQrCode(
|
||
string resourceType,
|
||
Guid id,
|
||
[FromQuery] string format = "png",
|
||
[FromQuery] int size = 20)
|
||
{
|
||
_logger.LogDebug("Generating QR code: resourceType={ResourceType}, id={Id}, format={Format}, size={Size}",
|
||
resourceType, id, format, size);
|
||
|
||
// Parse resource type
|
||
if (!Enum.TryParse<QrResourceType>(resourceType, ignoreCase: true, out var parsedType))
|
||
{
|
||
return BadRequest(new
|
||
{
|
||
error = $"Invalid resource type: '{resourceType}'. " +
|
||
$"Valid values are: spool, printer, location."
|
||
});
|
||
}
|
||
|
||
// Validate format
|
||
format = format.ToLowerInvariant();
|
||
if (format is not ("png" or "svg"))
|
||
{
|
||
return BadRequest(new
|
||
{
|
||
error = $"Invalid format: '{format}'. Valid values are: png, svg."
|
||
});
|
||
}
|
||
|
||
// Validate size for PNG
|
||
if (format == "png" && (size < 4 || size > 40))
|
||
{
|
||
return BadRequest(new
|
||
{
|
||
error = $"Size must be between 4 and 40. Received: {size}."
|
||
});
|
||
}
|
||
|
||
if (format == "svg")
|
||
{
|
||
var svg = _qrCodeService.GenerateSvg(parsedType, id);
|
||
return Content(svg, "image/svg+xml");
|
||
}
|
||
|
||
var pngBytes = _qrCodeService.GeneratePng(parsedType, id, size);
|
||
return File(pngBytes, "image/png");
|
||
}
|
||
} |