174 lines
5.8 KiB
C#
174 lines
5.8 KiB
C#
using DramaLing.Api.Models.DTOs;
|
|
using DramaLing.Api.Services;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.Security.Claims;
|
|
|
|
namespace DramaLing.Api.Controllers;
|
|
|
|
[Route("api/[controller]")]
|
|
[Authorize]
|
|
public class ImageGenerationController : BaseController
|
|
{
|
|
private readonly IImageGenerationOrchestrator _orchestrator;
|
|
|
|
public ImageGenerationController(
|
|
IImageGenerationOrchestrator orchestrator,
|
|
ILogger<ImageGenerationController> logger) : base(logger)
|
|
{
|
|
_orchestrator = orchestrator ?? throw new ArgumentNullException(nameof(orchestrator));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 為指定詞卡生成例句圖片
|
|
/// </summary>
|
|
/// <param name="flashcardId">詞卡 ID</param>
|
|
/// <param name="request">生成請求參數</param>
|
|
/// <returns>生成請求結果</returns>
|
|
[HttpPost("flashcards/{flashcardId}/generate")]
|
|
public async Task<IActionResult> GenerateImage(
|
|
Guid flashcardId,
|
|
[FromBody] GenerationRequest request)
|
|
{
|
|
try
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
request.UserId = userId;
|
|
|
|
_logger.LogInformation("Starting image generation for flashcard {FlashcardId} by user {UserId}",
|
|
flashcardId, userId);
|
|
|
|
var result = await _orchestrator.StartGenerationAsync(flashcardId, request);
|
|
|
|
return SuccessResponse(result);
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
_logger.LogWarning(ex, "Invalid request for flashcard {FlashcardId}", flashcardId);
|
|
return ErrorResponse("INVALID_REQUEST", ex.Message, null, 400);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to start image generation for flashcard {FlashcardId}", flashcardId);
|
|
return ErrorResponse("GENERATION_FAILED", "Failed to start generation");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 獲取圖片生成狀態
|
|
/// </summary>
|
|
/// <param name="requestId">生成請求 ID</param>
|
|
/// <returns>生成狀態詳情</returns>
|
|
[HttpGet("requests/{requestId}/status")]
|
|
public async Task<IActionResult> GetGenerationStatus(Guid requestId)
|
|
{
|
|
try
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
_logger.LogInformation("Getting generation status for request {RequestId} by user {UserId}",
|
|
requestId, userId);
|
|
|
|
var status = await _orchestrator.GetGenerationStatusAsync(requestId);
|
|
|
|
return SuccessResponse(status);
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
_logger.LogWarning(ex, "Generation request {RequestId} not found", requestId);
|
|
return ErrorResponse("NOT_FOUND", ex.Message, null, 404);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to get status for request {RequestId}", requestId);
|
|
return ErrorResponse("STATUS_ERROR", "Failed to get status");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 取消圖片生成請求
|
|
/// </summary>
|
|
/// <param name="requestId">生成請求 ID</param>
|
|
/// <returns>取消結果</returns>
|
|
[HttpPost("requests/{requestId}/cancel")]
|
|
public async Task<IActionResult> CancelGeneration(Guid requestId)
|
|
{
|
|
try
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
_logger.LogInformation("Cancelling generation request {RequestId} by user {UserId}",
|
|
requestId, userId);
|
|
|
|
var cancelled = await _orchestrator.CancelGenerationAsync(requestId);
|
|
|
|
if (cancelled)
|
|
{
|
|
return SuccessResponse(new { message = "Generation cancelled successfully" });
|
|
}
|
|
else
|
|
{
|
|
return ErrorResponse("CANCEL_FAILED", "Cannot cancel this request", null, 400);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to cancel generation request {RequestId}", requestId);
|
|
return ErrorResponse("CANCEL_ERROR", "Failed to cancel generation");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 獲取用戶的圖片生成歷史
|
|
/// </summary>
|
|
/// <param name="page">頁碼</param>
|
|
/// <param name="pageSize">每頁數量</param>
|
|
/// <returns>生成歷史列表</returns>
|
|
[HttpGet("history")]
|
|
public async Task<IActionResult> GetGenerationHistory(
|
|
[FromQuery] int page = 1,
|
|
[FromQuery] int pageSize = 20)
|
|
{
|
|
try
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
|
|
// TODO: 實現分頁查詢邏輯
|
|
// 暫時返回空列表
|
|
var history = new
|
|
{
|
|
requests = new List<object>(),
|
|
pagination = new
|
|
{
|
|
currentPage = page,
|
|
pageSize = pageSize,
|
|
totalCount = 0,
|
|
totalPages = 0
|
|
}
|
|
};
|
|
|
|
return SuccessResponse(history);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to get generation history for user");
|
|
return ErrorResponse("HISTORY_ERROR", "Failed to get history");
|
|
}
|
|
}
|
|
|
|
private Guid GetCurrentUserId()
|
|
{
|
|
var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value
|
|
?? User.FindFirst("sub")?.Value;
|
|
|
|
if (string.IsNullOrEmpty(userIdClaim))
|
|
{
|
|
throw new UnauthorizedAccessException("User ID not found in token");
|
|
}
|
|
|
|
if (!Guid.TryParse(userIdClaim, out var userId))
|
|
{
|
|
throw new UnauthorizedAccessException("Invalid user ID format in token");
|
|
}
|
|
|
|
return userId;
|
|
}
|
|
} |