From b28a89f26383aa75257e986c27ac8f8f86f1761e Mon Sep 17 00:00:00 2001 From: haoliang <821644@qq.com> Date: Wed, 29 Apr 2026 00:15:31 +0800 Subject: [PATCH] =?UTF-8?q?IIS=E9=83=A8=E7=BD=B2=E8=81=94=E8=B0=83?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9AOWIN=E7=A6=81=E7=94=A8+=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E9=9B=86=E7=BB=91=E5=AE=9A+SPA=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E5=9B=9E=E9=80=80+=E9=94=99=E8=AF=AF=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Web.config: 禁用OWIN自动发现(owin:AutomaticAppStartup=false),添加MySqlConnector依赖的程序集绑定重定向 - Global.asax.cs: Application_BeginRequest实现/admin/路径的SPA路由回退(无需URL Rewrite模块) - GlobalExceptionFilter: 输出完整异常堆栈+InnerException,便于联调定位问题 - request.ts: 错误提示直接显示后端返回的message,不再覆盖为固定文案 - vite.config.ts: base设为/admin/,静态资源路径正确指向/admin/assets/ --- frontend/src/utils/request.ts | 11 ++----- frontend/vite.config.ts | 2 ++ .../Filters/GlobalExceptionFilter.cs | 21 +++++++++++-- src/CncWebApi/Global.asax.cs | 30 +++++++++++++++++++ src/CncWebApi/Web.config | 21 +++++++++++++ 5 files changed, 73 insertions(+), 12 deletions(-) diff --git a/frontend/src/utils/request.ts b/frontend/src/utils/request.ts index 2a3704f..c957fec 100644 --- a/frontend/src/utils/request.ts +++ b/frontend/src/utils/request.ts @@ -42,15 +42,8 @@ service.interceptors.response.use( return Promise.reject(new Error(res.message)) } - // 其他业务错误 - const errorMessages: Record = { - 40001: res.message || '参数校验失败', - 40002: res.message || '资源不存在', - 40003: res.message || '资源已存在', - 50001: '服务器错误', - 50002: '采集服务未响应', - } - const msg = errorMessages[res.code] || res.message || '请求失败' + // 其他业务错误:优先显示后端返回的消息,便于定位问题 + const msg = res.message || '请求失败' ElMessage.error(msg) return Promise.reject(new Error(msg)) }, diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index a46fa05..3c075f1 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -5,6 +5,8 @@ import path from 'path' // https://vite.dev/config/ export default defineConfig({ + // 部署到 /admin/ 子路径,静态资源路径前缀 + base: '/admin/', plugins: [ vue(), viteMockPlugin({ diff --git a/src/CncWebApi/Filters/GlobalExceptionFilter.cs b/src/CncWebApi/Filters/GlobalExceptionFilter.cs index 87aa70b..40ae815 100644 --- a/src/CncWebApi/Filters/GlobalExceptionFilter.cs +++ b/src/CncWebApi/Filters/GlobalExceptionFilter.cs @@ -29,11 +29,26 @@ namespace CncWebApi.Filters } else { - // 未预期异常:记录日志,返回通用错误 - // TODO: 接入 log4net 记录完整异常堆栈 + // 未预期异常:返回详细错误信息用于诊断(生产环境应改为记录日志) + var ex = context.Exception; + var sb = new System.Text.StringBuilder(); + sb.AppendLine($"[{ex.GetType().FullName}] {ex.Message}"); + // 堆栈跟踪 + if (ex.StackTrace != null) sb.AppendLine(ex.StackTrace); + // InnerException 递归 + var inner = ex.InnerException; + int depth = 1; + while (inner != null && depth <= 5) + { + sb.AppendLine($"--- InnerException ({depth}) ---"); + sb.AppendLine($"[{inner.GetType().FullName}] {inner.Message}"); + if (inner.StackTrace != null) sb.AppendLine(inner.StackTrace); + inner = inner.InnerException; + depth++; + } var response = ApiResponse.Fail( CncModels.Constants.ErrorCode.InternalError, - "服务器内部错误"); + sb.ToString()); context.Response = context.Request.CreateResponse( HttpStatusCode.InternalServerError, response); } diff --git a/src/CncWebApi/Global.asax.cs b/src/CncWebApi/Global.asax.cs index 03f137f..fcd25de 100644 --- a/src/CncWebApi/Global.asax.cs +++ b/src/CncWebApi/Global.asax.cs @@ -18,5 +18,35 @@ namespace CncWebApi { GlobalConfiguration.Configure(WebApiConfig.Register); } + + /// + /// SPA 路由回退:/admin/ 下的非文件请求重写到 index.html + /// 用于支持前端 Vue Router 的 HTML5 History 模式 + /// + protected void Application_BeginRequest(object sender, EventArgs e) + { + var path = Request.Url.AbsolutePath; + + // 只处理 /admin/ 开头的路径 + if (path.StartsWith("/admin/", StringComparison.OrdinalIgnoreCase) || + path.Equals("/admin", StringComparison.OrdinalIgnoreCase)) + { + // 排除静态资源文件(有扩展名的) + var ext = System.IO.Path.GetExtension(path); + if (string.IsNullOrEmpty(ext)) + { + // SPA 路由:重写到 /admin/index.html + var physicalFile = Server.MapPath(path); + if (!System.IO.File.Exists(physicalFile)) + { + var indexPath = Server.MapPath("/admin/index.html"); + if (System.IO.File.Exists(indexPath)) + { + Context.RewritePath("/admin/index.html"); + } + } + } + } + } } } diff --git a/src/CncWebApi/Web.config b/src/CncWebApi/Web.config index 7cbd851..9cebd44 100644 --- a/src/CncWebApi/Web.config +++ b/src/CncWebApi/Web.config @@ -14,6 +14,8 @@ + + @@ -23,6 +25,8 @@ + + @@ -40,6 +44,23 @@ + + + + + + + + + + + + + + + + +