using Microsoft.AspNetCore.Mvc; using DramaLing.Api.Models.DTOs; using DramaLing.Api.Services; using System.Security.Claims; namespace DramaLing.Api.Controllers; [ApiController] public abstract class BaseController : ControllerBase { protected readonly ILogger _logger; protected readonly IAuthService? _authService; protected BaseController(ILogger logger, IAuthService? authService = null) { _logger = logger; _authService = authService; } /// /// 統一的成功響應格式 /// protected IActionResult SuccessResponse(T data, string? message = null) { return Ok(new ApiResponse { Success = true, Data = data, Message = message, Timestamp = DateTime.UtcNow }); } /// /// 統一的錯誤響應格式 /// protected IActionResult ErrorResponse(string code, string message, object? details = null, int statusCode = 500) { var response = new ApiErrorResponse { Success = false, Error = new ApiError { Code = code, Message = message, Details = details, Suggestions = GetSuggestionsForError(code) }, RequestId = Guid.NewGuid().ToString(), Timestamp = DateTime.UtcNow }; return StatusCode(statusCode, response); } /// /// 獲取當前用戶ID(統一處理認證) /// protected async Task GetCurrentUserIdAsync() { if (_authService != null) { // 使用AuthService進行JWT解析(適用於已實現認證的Controller) var userId = await _authService.GetUserIdFromTokenAsync(Request.Headers.Authorization); if (userId.HasValue) return userId.Value; } // Fallback: 從Claims直接解析 var userIdString = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? User.FindFirst("sub")?.Value; if (Guid.TryParse(userIdString, out var parsedUserId)) return parsedUserId; throw new UnauthorizedAccessException("Invalid or missing user authentication"); } /// /// 檢查是否為測試環境 /// protected bool IsTestEnvironment() { var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); return environment == "Development" || environment == "Testing"; } /// /// 統一的模型驗證錯誤處理 /// protected IActionResult HandleModelStateErrors() { var errors = ModelState .Where(x => x.Value?.Errors.Count > 0) .ToDictionary( kvp => kvp.Key, kvp => kvp.Value?.Errors.Select(e => e.ErrorMessage).ToArray() ?? Array.Empty() ); return ErrorResponse("VALIDATION_ERROR", "輸入資料驗證失敗", errors, 400); } /// /// 根據錯誤代碼獲取建議 /// private List GetSuggestionsForError(string errorCode) { return errorCode switch { "VALIDATION_ERROR" => new List { "請檢查輸入格式", "確保所有必填欄位已填寫" }, "INVALID_INPUT" => new List { "請檢查輸入格式", "確保文本長度在限制內" }, "RATE_LIMIT_EXCEEDED" => new List { "升級到Premium帳戶以獲得無限使用", "明天重新嘗試" }, "AI_SERVICE_ERROR" => new List { "請稍後重試", "如果問題持續,請聯繫客服" }, "UNAUTHORIZED" => new List { "請檢查登入狀態", "確認Token是否有效" }, "NOT_FOUND" => new List { "請檢查資源ID是否正確", "確認資源是否存在" }, _ => new List { "請稍後重試", "如果問題持續,請聯繫客服" } }; } } /// /// 統一API響應格式 /// public class ApiResponse { public bool Success { get; set; } = true; public T? Data { get; set; } public string? Message { get; set; } public DateTime Timestamp { get; set; } = DateTime.UtcNow; } /// /// 分頁響應格式 /// public class PagedApiResponse : ApiResponse> { public PaginationMetadata Pagination { get; set; } = new(); } /// /// 分頁元數據 /// public class PaginationMetadata { public int CurrentPage { get; set; } public int PageSize { get; set; } public int TotalCount { get; set; } public int TotalPages { get; set; } public bool HasNext { get; set; } public bool HasPrevious { get; set; } }