dramaling-vocab-learning/backend/DramaLing.Api/Controllers/AIController.cs

126 lines
4.0 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using DramaLing.Api.Models.DTOs;
using DramaLing.Api.Services;
using System.Diagnostics;
namespace DramaLing.Api.Controllers;
[Route("api/ai")]
[AllowAnonymous]
public class AIController : BaseController
{
private readonly IAnalysisService _analysisService;
public AIController(
IAnalysisService analysisService,
ILogger<AIController> logger) : base(logger)
{
_analysisService = analysisService;
}
/// <summary>
/// 智能分析英文句子
/// </summary>
/// <param name="request">分析請求</param>
/// <returns>分析結果</returns>
[HttpPost("analyze-sentence")]
public async Task<IActionResult> AnalyzeSentence(
[FromBody] SentenceAnalysisRequest request)
{
var requestId = Guid.NewGuid().ToString();
var stopwatch = Stopwatch.StartNew();
try
{
_logger.LogInformation("Processing sentence analysis request {RequestId}", requestId);
// Input validation
if (!ModelState.IsValid)
{
return HandleModelStateErrors();
}
// 使用帶快取的分析服務
var options = request.Options ?? new AnalysisOptions();
var analysisData = await _analysisService.AnalyzeSentenceAsync(
request.InputText, options);
stopwatch.Stop();
analysisData.Metadata.ProcessingDate = DateTime.UtcNow;
_logger.LogInformation("Sentence analysis completed for request {RequestId} in {ElapsedMs}ms",
requestId, stopwatch.ElapsedMilliseconds);
var response = new SentenceAnalysisResponse
{
Success = true,
ProcessingTime = stopwatch.Elapsed.TotalSeconds,
Data = analysisData
};
return SuccessResponse(response);
}
catch (ArgumentException ex)
{
_logger.LogWarning(ex, "Invalid input for request {RequestId}", requestId);
return ErrorResponse("INVALID_INPUT", ex.Message, null, 400);
}
catch (InvalidOperationException ex)
{
_logger.LogError(ex, "AI service error for request {RequestId}", requestId);
return ErrorResponse("AI_SERVICE_ERROR", "AI服務暫時不可用", null, 500);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error processing request {RequestId}", requestId);
return ErrorResponse("INTERNAL_ERROR", "伺服器內部錯誤", null, 500);
}
}
/// <summary>
/// 健康檢查端點
/// </summary>
[HttpGet("health")]
public IActionResult GetHealth()
{
var healthData = new
{
Status = "Healthy",
Service = "AI Analysis Service",
Timestamp = DateTime.UtcNow,
Version = "1.0"
};
return SuccessResponse(healthData);
}
/// <summary>
/// 取得分析統計資訊
/// </summary>
[HttpGet("stats")]
public async Task<IActionResult> GetAnalysisStats()
{
try
{
var stats = await _analysisService.GetAnalysisStatsAsync();
var statsData = new
{
TotalAnalyses = stats.TotalAnalyses,
CachedAnalyses = stats.CachedAnalyses,
CacheHitRate = stats.CacheHitRate,
AverageResponseTimeMs = stats.AverageResponseTimeMs,
LastAnalysisAt = stats.LastAnalysisAt,
ProviderUsage = stats.ProviderUsageStats
};
return SuccessResponse(statsData);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting analysis stats");
return ErrorResponse("INTERNAL_ERROR", "無法取得統計資訊");
}
}
}