using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace Haoliang.Core.Services { // 中间件和过滤器 public class ExceptionMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public ExceptionMiddleware(RequestDelegate next, ILogger logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (Exception ex) { _logger.LogError(ex, "An unhandled exception occurred"); await HandleExceptionAsync(context, ex); } } private static Task HandleExceptionAsync(HttpContext context, Exception exception) { context.Response.ContentType = "application/json"; var response = new { success = false, message = "Internal server error", timestamp = DateTime.Now, error = exception.Message }; context.Response.StatusCode = 500; return context.Response.WriteAsJsonAsync(response); } } public class LoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public LoggingMiddleware(RequestDelegate next, ILogger logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { var startTime = DateTime.Now; // 记录请求信息 _logger.LogInformation($"Request: {context.Request.Method} {context.Request.Path}"); try { await _next(context); } finally { var duration = DateTime.Now - startTime; _logger.LogInformation($"Response: {context.Response.StatusCode} - Duration: {duration.TotalMilliseconds}ms"); } } } public class CORSMiddleware { private readonly RequestDelegate _next; public CORSMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With"); if (context.Request.Method == "OPTIONS") { context.Response.StatusCode = 200; return; } await _next(context); } } // API响应格式 public class ApiResponse { public bool Success { get; set; } public object Data { get; set; } public string Message { get; set; } public DateTime Timestamp { get; set; } public int Code { get; set; } public static ApiResponse NotFound(string message = "Resource not found") { return Error(message, 404); } public static ApiResponse BadRequest(string message = "Bad request") { return Error(message, 400); } public static ApiResponse Unauthorized(string message = "Unauthorized") { return Error(message, 401); } } // 统一响应包装器 public class PagedResponse { public IEnumerable Items { get; set; } public int TotalCount { get; set; } public int PageNumber { get; set; } public int PageSize { get; set; } public int TotalPages { get; set; } public bool HasNextPage { get; set; } public bool HasPreviousPage { get; set; } public static PagedResponse Create(IEnumerable items, int totalCount, int pageNumber, int pageSize) { return new PagedResponse { Items = items, TotalCount = totalCount, PageNumber = pageNumber, PageSize = pageSize, TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize), HasNextPage = pageNumber < (int)Math.Ceiling(totalCount / (double)pageSize), HasPreviousPage = pageNumber > 1 }; } } // 分页参数 public class PaginationParams { public int PageNumber { get; set; } = 1; public int PageSize { get; set; } = 10; public string SortBy { get; set; } public string SortOrder { get; set; } = "asc"; public string Search { get; set; } } // 排序参数 public class SortParams { public string Field { get; set; } public string Direction { get; set; } = "asc"; } }