更新框架,增加云库搜索模块

This commit is contained in:
chfei committed 2026-09-18 18:40:10 +08:00
1 parent 8526e5e0d2
commit f2caec6083
192 files changed
+3626 -804

No files matched your search

@@ -0,0 +1,18 @@
using MAX.Framework.Dtos;
using System;
using System.Collections.Generic;
using System.Text;
namespace MAX.Framework.Commons
{
public class AppException : Exception
{
public int Code { get; }
public AppException(string message, int code = ResultCode.BusinessError)
: base(message)
{
Code = code;
}
}
}
@@ -0,0 +1,42 @@
using MAX.Framework.Dtos;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
namespace MAX.Framework.Commons
{
public class GlobalExceptionFilter : IExceptionFilter
{
private readonly ILogger<GlobalExceptionFilter> _logger;
public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger)
{
_logger = logger;
}
public void OnException(ExceptionContext context)
{
var traceId = context.HttpContext.TraceIdentifier;
var result = context.Exception switch
{
AppException be => ApiResult.Fail(be.Message, be.Code),
ValidationException ve => ApiResult.Fail(ve.Message, ResultCode.ValidationError),
UnauthorizedAccessException => ApiResult.Fail("未授权访问", ResultCode.Unauthorized),
_ => ApiResult.Fail("服务器内部错误", ResultCode.ServerError)
};
_logger.LogError(context.Exception, "请求异常 TraceId: {TraceId}", traceId);
context.Result = new ObjectResult(result)
{
StatusCode = 200 // 关键:HTTP状态码统一200,业务状态用Code表达
};
context.ExceptionHandled = true;
}
}
}
+26
View File
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace MAX.Framework.Commons
{
public class PageData<T>
{
public long Total { get; set; }
public int PageIndex { get; set; }
public int PageSize { get; set; }
public int TotalPages => PageSize > 0 ? (int)Math.Ceiling((double)Total / PageSize) : 0;
public List<T> List { get; set; } = new();
public PageData() { }
public PageData(List<T> list, long total, int pageIndex, int pageSize)
{
List = list;
Total = total;
PageIndex = pageIndex;
PageSize = pageSize;
}
}
}
@@ -0,0 +1,52 @@
using MAX.Framework.Dtos;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Text;
namespace MAX.Framework.Commons
{
/// <summary>
/// 返回过滤
/// </summary>
public class UnifyResultFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
if (context.Result is ObjectResult objResult)
{
if (!IsAlreadyWrapped(objResult.Value))
{
var apiResult = ApiResult<object>.Success(objResult.Value);
objResult.Value = apiResult;
objResult.DeclaredType = null;
}
}
else if (context.Result is EmptyResult || context.Result is NoContentResult)
{
context.Result = new ObjectResult(ApiResult.Success());
}
}
public void OnActionExecuting(ActionExecutingContext context) { }
private static bool IsAlreadyWrapped(object? value)
{
if (value is null) return false;
var type = value.GetType();
// 递归判断:只要类型链上有任何一层是 ApiResult<> 的开放泛型定义,或直接是 ApiResult,就算已包装
while (type is not null)
{
if (type == typeof(ApiResult)) return true;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ApiResult<>)) return true;
type = type.BaseType;
}
return false;
}
}
}
@@ -0,0 +1,53 @@
using MAX.Framework.Dtos;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
namespace MAX.Framework.Commons
{
public class UnsupportedMediaTypeHandlingMiddleware
{
private readonly RequestDelegate _next;
public UnsupportedMediaTypeHandlingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// 用一个内存流替换原始的Response.Body,方便判断状态码后决定是否要改写
var originalBodyStream = context.Response.Body;
using var memoryStream = new MemoryStream();
context.Response.Body = memoryStream;
await _next(context);
if (context.Response.StatusCode == StatusCodes.Status415UnsupportedMediaType)
{
var result = ApiResult.Fail("请求参数格式不正确", ResultCode.ValidationError);
var json = JsonSerializer.Serialize(result);
var bytes = Encoding.UTF8.GetBytes(json);
context.Response.Clear();
context.Response.StatusCode = StatusCodes.Status200OK; // 统一成200,和其他接口一致
context.Response.ContentType = "application/json; charset=utf-8";
context.Response.ContentLength = bytes.Length;
await context.Response.Body.WriteAsync(bytes);
await context.Response.Body.FlushAsync(originalBodyStream is null ? default : default);
}
else
{
// 非415的情况,把内存流内容原样写回真正的Response.Body
memoryStream.Seek(0, SeekOrigin.Begin);
await memoryStream.CopyToAsync(originalBodyStream);
}
context.Response.Body = originalBodyStream;
}
}
}