diff --git a/Framework/YLErp.Core/Helpers/HttpHelper.cs b/Framework/YLErp.Core/Helpers/HttpHelper.cs index bbeb9b3c..460316b8 100644 --- a/Framework/YLErp.Core/Helpers/HttpHelper.cs +++ b/Framework/YLErp.Core/Helpers/HttpHelper.cs @@ -76,6 +76,13 @@ namespace YLErp.Helpers // 发送请求并响应结果 var response = await client.ExecuteAsync>(request); var responseContent = response.Content; + + // 检查响应内容是否为空 + if (string.IsNullOrEmpty(responseContent)) + { + throw new ServiceException($"接口返回为空 - URL: {_baseUrl}{apiPath}, StatusCode: {response.StatusCode}"); + } + return Newtonsoft.Json.JsonConvert.DeserializeObject(responseContent); } public async Task GetRequestNoAuth(string apiPath) diff --git a/YLErpDAL/Modules/RiskModule/QuotaMonitorService.cs b/YLErpDAL/Modules/RiskModule/QuotaMonitorService.cs index 60f833a8..0c348bc7 100644 --- a/YLErpDAL/Modules/RiskModule/QuotaMonitorService.cs +++ b/YLErpDAL/Modules/RiskModule/QuotaMonitorService.cs @@ -4970,6 +4970,7 @@ namespace YLErp.Modules.RiskModule foreach (var item in positions) { CheckUnderlyingRequest clientOrderParam = new CheckUnderlyingRequest() { clientId = clientId, securityId = item.UnderlyingCode, orderQty = item.PosiQuantity * 0.0001m, side = item.PositionType - 1 }; + _logger.Info($"[CheckUnderlyingWhiteList] 构建请求参数 - clientId: {clientId}, securityId: {item.UnderlyingCode}, orderQty: {item.PosiQuantity * 0.0001m}, side: {item.PositionType - 1}"); clientOrderParams.Add(clientOrderParam); } if (!string.IsNullOrEmpty(baseUrl) && !string.IsNullOrEmpty(checkUrl)) diff --git a/YLErpWeb/Controllers/AccountController.cs b/YLErpWeb/Controllers/AccountController.cs index e9fe8a92..4fb4fc1a 100644 --- a/YLErpWeb/Controllers/AccountController.cs +++ b/YLErpWeb/Controllers/AccountController.cs @@ -311,13 +311,9 @@ namespace YLErp.Web.Controllers HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme); logger.Info($"[退出登录] SignOutAsync 已调用"); - // 清除 JWT Token Cookie - Response.Cookies.Delete("Access-Token"); - Response.Cookies.Delete("Access-Token-Encrypt"); - logger.Info($"[退出登录] JWT Token Cookie 已清除"); - - // 将当前 JWT Token 加入黑名单(使其立即失效) - if (Request.Cookies.TryGetValue("Access-Token", out var accessToken) && !string.IsNullOrEmpty(accessToken)) + // 先将当前 JWT Token 加入黑名单(使其立即失效),然后再删除 Cookie + string accessToken = null; + if (Request.Cookies.TryGetValue("Access-Token", out accessToken) && !string.IsNullOrEmpty(accessToken)) { try { @@ -340,6 +336,11 @@ namespace YLErp.Web.Controllers } } + // 清除 JWT Token Cookie(在加入黑名单之后) + Response.Cookies.Delete("Access-Token"); + Response.Cookies.Delete("Access-Token-Encrypt"); + logger.Info($"[退出登录] JWT Token Cookie 已清除"); + if (SsoLoginConfig.SSO_Enable) { switch (loginName?.ToLowerInvariant()) diff --git a/YLErpWeb/Middleware/RefreshTokenMiddleware.cs b/YLErpWeb/Middleware/RefreshTokenMiddleware.cs index 2ace3483..da37529e 100644 --- a/YLErpWeb/Middleware/RefreshTokenMiddleware.cs +++ b/YLErpWeb/Middleware/RefreshTokenMiddleware.cs @@ -34,6 +34,25 @@ namespace YLErp.Web.Middleware /// HTTP上下文 public async Task InvokeAsync(HttpContext context) { + // 获取当前请求路径 + var path = context.Request.Path.Value?.ToLowerInvariant() ?? ""; + + // 跳过登录相关页面和静态资源,避免黑名单Token影响登录流程 + if (path.StartsWith("/account/login") || + path.StartsWith("/account/logout") || + path.StartsWith("/account/captcha") || + path.StartsWith("/account/sso") || + path.StartsWith("/account/callback") || + path.StartsWith("/content/") || + path.StartsWith("/scripts/") || + path.StartsWith("/css/") || + path.StartsWith("/images/") || + path.StartsWith("/favicon.ico")) + { + await _next(context); + return; + } + // 检查是否有Access-Token if (context.Request.Cookies.TryGetValue("Access-Token", out var token)) { @@ -66,7 +85,8 @@ namespace YLErp.Web.Middleware context.Response.Cookies.Delete("Access-Token"); context.Response.Cookies.Delete("Access-Token-Encrypt"); context.Response.StatusCode = 401; - await context.Response.WriteAsync("Token已失效,请重新登录"); + context.Response.ContentType = "text/plain; charset=utf-8"; + await context.Response.WriteAsync("Token has expired / Token已失效,请重新登录 (Please go to login page / 请访问登录页面: /Account/Login)"); return; }