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; }
}