diff --git a/Core/MAX.Core/Caches/MemoryCache.cs b/Core/MAX.Core/Caches/MemoryCache.cs
index b2bc36a..4631bc3 100644
--- a/Core/MAX.Core/Caches/MemoryCache.cs
+++ b/Core/MAX.Core/Caches/MemoryCache.cs
@@ -1,6 +1,6 @@
using MAX.Core.DependencyInjection;
-using MAX.Core.Infrastructure;
+using MAX.Core.Interfaces;
using System;
using System.Collections.Concurrent;
using System.Linq;
diff --git a/Core/MAX.Core/DependencyInjection/IDependencyRegistrar.cs b/Core/MAX.Core/DependencyInjection/IDependencyRegistrar.cs
index 92cb66b..4abc09e 100644
--- a/Core/MAX.Core/DependencyInjection/IDependencyRegistrar.cs
+++ b/Core/MAX.Core/DependencyInjection/IDependencyRegistrar.cs
@@ -1,10 +1,12 @@
-namespace MAX.Core.DependencyInjection;
+using MAX.Core.Interfaces;
+
+namespace MAX.Core.DependencyInjection;
///
/// 依赖注册器:把当前模块的服务注册到 。
/// 底层使用哪个容器由宿主项目决定,MAX.Core 不引用任何容器。
///
-public interface IDependencyRegistrar
+public interface IDependencyRegistrar: IPriority
{
///
/// 注册服务
diff --git a/Core/MAX.Core/Interfaces/IPriority.cs b/Core/MAX.Core/Interfaces/IPriority.cs
new file mode 100644
index 0000000..3b61afb
--- /dev/null
+++ b/Core/MAX.Core/Interfaces/IPriority.cs
@@ -0,0 +1,33 @@
+namespace MAX.Core.Interfaces;
+
+public interface IPriority
+{
+ /// 优先级(优先级越高越先执行)
+ int Priority { get; }
+}
+
+public static class IntPriority
+{
+ public const int Highest = 5000;
+
+ public const int VeryHigh = 4000;
+
+ public const int Higher = 3000;
+
+ public const int High = 2000;
+
+ public const int AboveNormal = 1000;
+
+ public const int Normal = 0;
+
+ public const int BelowNormal = -1000;
+
+ public const int Low = -2000;
+
+ public const int Lower = -3000;
+
+ public const int VeryLow = -4000;
+
+ public const int Lowest = -5000;
+
+}
diff --git a/Core/MAX.Core/Infrastructure/IStartup.cs b/Core/MAX.Core/Interfaces/IStartup.cs
similarity index 92%
rename from Core/MAX.Core/Infrastructure/IStartup.cs
rename to Core/MAX.Core/Interfaces/IStartup.cs
index edbe252..0767a3f 100644
--- a/Core/MAX.Core/Infrastructure/IStartup.cs
+++ b/Core/MAX.Core/Interfaces/IStartup.cs
@@ -1,6 +1,6 @@
using MAX.Core.DependencyInjection;
-namespace MAX.Core.Infrastructure;
+namespace MAX.Core.Interfaces;
///
/// 启动器:实现 ,由宿主项目统一发现并按 排序执行。
diff --git a/Core/MAX.Core/Infrastructure/SingleInstance.cs b/Core/MAX.Core/Interfaces/SingleInstance.cs
similarity index 95%
rename from Core/MAX.Core/Infrastructure/SingleInstance.cs
rename to Core/MAX.Core/Interfaces/SingleInstance.cs
index b6eb50a..7a2df56 100644
--- a/Core/MAX.Core/Infrastructure/SingleInstance.cs
+++ b/Core/MAX.Core/Interfaces/SingleInstance.cs
@@ -1,7 +1,7 @@
using System;
using System.Reflection;
-namespace MAX.Core.Infrastructure;
+namespace MAX.Core.Interfaces;
///
/// 单例,需要在当前类中定义
diff --git a/Core/MAX.Core/Logger/ICustomLogger.cs b/Core/MAX.Core/Logger/ICustomLogger.cs
index 456a96b..2014a9c 100644
--- a/Core/MAX.Core/Logger/ICustomLogger.cs
+++ b/Core/MAX.Core/Logger/ICustomLogger.cs
@@ -1,5 +1,4 @@
-using MAX.Core.Infrastructure;
-
+
namespace MAX.Core.Logger;
/// 自定义日志记录器接口
diff --git a/Core/MAX.Core/Startup.cs b/Core/MAX.Core/Startup.cs
index 724d8fd..2f5cb1d 100644
--- a/Core/MAX.Core/Startup.cs
+++ b/Core/MAX.Core/Startup.cs
@@ -24,7 +24,7 @@
*/
using MAX.Core.DependencyInjection;
-using MAX.Core.Infrastructure;
+using MAX.Core.Interfaces;
namespace MAX.Core;
diff --git a/Core/MAX.Framework/Commons/AppException.cs b/Core/MAX.Framework/Commons/AppException.cs
new file mode 100644
index 0000000..84cd2af
--- /dev/null
+++ b/Core/MAX.Framework/Commons/AppException.cs
@@ -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;
+ }
+ }
+}
diff --git a/Core/MAX.Framework/Commons/GlobalExceptionFilter.cs b/Core/MAX.Framework/Commons/GlobalExceptionFilter.cs
new file mode 100644
index 0000000..465a872
--- /dev/null
+++ b/Core/MAX.Framework/Commons/GlobalExceptionFilter.cs
@@ -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 _logger;
+
+ public GlobalExceptionFilter(ILogger 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;
+ }
+ }
+}
diff --git a/Core/MAX.Framework/Commons/PageData.cs b/Core/MAX.Framework/Commons/PageData.cs
new file mode 100644
index 0000000..8e83396
--- /dev/null
+++ b/Core/MAX.Framework/Commons/PageData.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MAX.Framework.Commons
+{
+ public class PageData
+ {
+ 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 List { get; set; } = new();
+
+ public PageData() { }
+
+ public PageData(List list, long total, int pageIndex, int pageSize)
+ {
+ List = list;
+ Total = total;
+ PageIndex = pageIndex;
+ PageSize = pageSize;
+ }
+ }
+
+}
diff --git a/Core/MAX.Framework/Commons/UnifyResultFilter.cs b/Core/MAX.Framework/Commons/UnifyResultFilter.cs
new file mode 100644
index 0000000..f4aa54f
--- /dev/null
+++ b/Core/MAX.Framework/Commons/UnifyResultFilter.cs
@@ -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
+{
+ ///
+ /// 返回过滤
+ ///
+ public class UnifyResultFilter : IActionFilter
+ {
+ public void OnActionExecuted(ActionExecutedContext context)
+ {
+ if (context.Result is ObjectResult objResult)
+ {
+ if (!IsAlreadyWrapped(objResult.Value))
+ {
+ var apiResult = ApiResult