提交代码

This commit is contained in:
zpc 2025-04-24 00:57:14 +08:00
parent 98f4214809
commit af397d25c8
14 changed files with 562 additions and 34 deletions

View File

@ -4,6 +4,7 @@ using ChouBox.Code.TencentCloudExtend.Model;
using ChouBox.Model.Entities;
using HuanMeng.DotNetCore.Base;
using HuanMeng.DotNetCore.Extensions;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
@ -89,10 +90,66 @@ public class ChouBoxCodeBase
if (_httpContextAccessor == null)
{
_httpContextAccessor = _serviceProvider.GetRequiredService<IHttpContextAccessor>();
}
return _httpContextAccessor;
}
}
/// <summary>
/// 获取客户端真实IP地址考虑Nginx等代理情况
/// </summary>
/// <returns>客户端真实IP地址</returns>
protected string GetRealIpAddress()
{
var context = HttpContextAccessor.HttpContext;
if (context == null)
return "unknown";
// 尝试从X-Forwarded-For获取真实IP
string ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
// 如果X-Forwarded-For为空尝试X-Real-IP
if (string.IsNullOrEmpty(ip))
{
ip = context.Request.Headers["X-Real-IP"].FirstOrDefault();
}
// 尝试其他可能包含真实IP的头
if (string.IsNullOrEmpty(ip))
{
ip = context.Request.Headers["Proxy-Client-IP"].FirstOrDefault();
}
if (string.IsNullOrEmpty(ip))
{
ip = context.Request.Headers["WL-Proxy-Client-IP"].FirstOrDefault();
}
if (string.IsNullOrEmpty(ip))
{
ip = context.Request.Headers["HTTP_CLIENT_IP"].FirstOrDefault();
}
if (string.IsNullOrEmpty(ip))
{
ip = context.Request.Headers["HTTP_X_FORWARDED_FOR"].FirstOrDefault();
}
// 如果还是获取不到则使用RemoteIpAddress
if (string.IsNullOrEmpty(ip))
{
ip = context.Connection.RemoteIpAddress?.ToString();
}
// 如果X-Forwarded-For包含多个IP取第一个非内网IP
if (!string.IsNullOrEmpty(ip) && ip.Contains(","))
{
ip = ip.Split(',')[0].Trim();
}
return ip ?? "unknown";
}
#endregion
#region

View File

@ -2,6 +2,11 @@
using ChouBox.Code.AppExtend;
using ChouBox.Code.TencentCloudExtend;
using ChouBox.Model.Entities;
using HuanMeng.DotNetCore.Base;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@ -16,17 +21,23 @@ namespace ChouBox.Code.Other;
/// </summary>
public class SMSBLL : ChouBoxCodeBase
{
private const string RETRY_COUNT_SUFFIX = ":RetryCount";
private const string LOCK_SUFFIX = ":Lock";
public SMSBLL(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
/// <summary>
/// 发送验证码
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <param name="codeType">验证码类型1-注册2-登录3-找回密码4-修改手机5-修改邮箱6-其他</param>
/// <param name="userId">用户ID可为空表示未登录用户</param>
/// <returns>返回下一次可请求的等待秒数,-1表示当天不能再请求</returns>
/// <exception cref="CustomException"></exception>
/// <exception cref="Exception"></exception>
public async Task<string> SendPhoneAsync(string phone)
public async Task<int> SendPhoneAsync(string phone, sbyte codeType = 2, ulong? userId = null)
{
if (string.IsNullOrEmpty(phone))
{
@ -37,23 +48,131 @@ public class SMSBLL : ChouBoxCodeBase
{
throw new ArgumentNullException("暂未开放发送验证码!");
}
// 检查当天发送次数限制
var dailyCountKey = $"VerificationCodeDailyCount:{phone}:{DateTime.Now:yyyyMMdd}";
var dailyCount = RedisCache.StringGet<int?>(dailyCountKey) ?? 0;
// 获取重试次数
var retryCountKey = $"VerificationCode:{phone}{RETRY_COUNT_SUFFIX}";
var retryCount = RedisCache.StringGet<int?>(retryCountKey) ?? 0;
var resendLockKey = $"VerificationCode:{phone}{LOCK_SUFFIX}";
var resendLock = RedisCache.StringGet<string>(resendLockKey);
// 计算本次等待时间
int waitSeconds = GetWaitSeconds(retryCount);
if (resendLock != null && !string.IsNullOrEmpty(resendLock))
{
// 获取锁的剩余过期时间(秒)
var remainingSeconds = RedisCache.KeyTimeToLive(resendLockKey)?.TotalSeconds ?? 0;
remainingSeconds = Math.Ceiling(remainingSeconds); // 向上取整
string message;
if (remainingSeconds <= 60)
{
message = $"验证码发送过于频繁,请{remainingSeconds}秒后再试。";
}
else
{
int remainingMinutes = (int)Math.Floor(remainingSeconds / 60);
message = $"验证码发送过于频繁,请{remainingMinutes}分钟后再试。";
}
throw new CustomException(message);
}
// 设置每天最大发送次数为5次
const int maxDailyCount = 5;
if (dailyCount >= maxDailyCount)
{
// 记录达到每日上限日志
Logger.LogWarning($"手机号{phone}当天验证码发送次数已达上限({maxDailyCount}次)");
throw new CustomException($"当天验证码发送次数已达上限,请明天再试");
}
Random random = new Random();
var verificationCode = random.Next(1000, 9999);
var redisKey = $"VerificationCode:{phone}";
var redisVerificationCode = RedisCache.StringGet<string>(redisKey);
if (redisVerificationCode != null && !string.IsNullOrEmpty(redisVerificationCode))
{
throw new Exception("验证码已发送!");
}
TencentSMSSendVerificationCode tencentSMSSendVerificationCode = new TencentSMSSendVerificationCode(smsConfig, phone);
var result = await tencentSMSSendVerificationCode.SendVerificationCode(verificationCode.ToString(), 5);
if (!result)
{
throw new Exception("验证码发送失败");
}
await RedisCache.StringSetAsync(redisKey, verificationCode.ToString(), TimeSpan.FromMinutes(5));
// 获取客户端真实IP地址
string ipAddress = GetRealIpAddress();
return "验证码已发送";
try
{
TencentSMSSendVerificationCode tencentSMSSendVerificationCode = new TencentSMSSendVerificationCode(smsConfig, phone);
var result = await tencentSMSSendVerificationCode.SendVerificationCode(verificationCode.ToString(), 5);
if (!result)
{
// 记录发送失败日志
Logger.LogError($"验证码发送失败,手机号:{phone}IP{ipAddress}");
throw new CustomException("验证码发送失败");
}
// 发送成功存入Redis5分钟有效期
await RedisCache.StringSetAsync(redisKey, verificationCode.ToString(), TimeSpan.FromMinutes(5));
// 更新重试次数和锁定时间
retryCount++;
var nextWaitSeconds = GetWaitSeconds(retryCount);
// 设置不能重发的锁
await RedisCache.StringSetAsync(resendLockKey, "1", TimeSpan.FromSeconds(waitSeconds));
// 更新重试次数5分钟后过期
await RedisCache.StringSetAsync(retryCountKey, retryCount.ToString(), TimeSpan.FromMinutes(5));
// 更新当天发送次数计数并设置过期时间为当天剩余时间
dailyCount++;
var endOfDay = DateTime.Today.AddDays(1).AddSeconds(-1); // 当天23:59:59
var expireTime = endOfDay - DateTime.Now;
await RedisCache.StringSetAsync(dailyCountKey, dailyCount.ToString(), expireTime);
// 保存到数据库
var verificationRecord = new UserVerificationCodes
{
UserId = userId,
Account = phone,
Code = verificationCode.ToString(),
CodeType = codeType,
Channel = "sms",
IpAddress = ipAddress,
Status = 0, // 未使用
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
ExpiredAt = DateTime.Now.AddMinutes(5)
};
await Dao.Context.UserVerificationCodes.AddAsync(verificationRecord);
await Dao.Context.SaveChangesAsync();
return nextWaitSeconds;
}
catch (Exception ex)
{
// 记录异常日志
Logger.LogError($"发送验证码异常:{ex.Message},手机号:{phone}IP{ipAddress}");
throw;
}
}
/// <summary>
/// 根据重试次数获取等待时间
/// </summary>
/// <param name="retryCount">重试次数</param>
/// <returns>等待秒数,-1表示不允许再次请求</returns>
private int GetWaitSeconds(int retryCount)
{
return retryCount switch
{
0 => 30, // 第1次请求后等待30秒
1 => 60, // 第2次请求后等待60秒
2 => 60, // 第3次请求后等待60秒
3 => 300, // 第4次请求后等待300秒5分钟
4 => 300, // 第5次请求后等待300秒5分钟
_ => -1 // 超过5次则不允许再次请求
};
}
}

View File

@ -296,4 +296,9 @@ public partial class Goods
/// 每日限购次数
/// </summary>
public int DailyXiangou { get; set; }
/// <summary>
/// 下架金额当盒子利润值小于它时下架如100 盒子利润出现负数后,超过-100就下架
/// </summary>
public int XiajiaJine { get; set; }
}

View File

@ -39,4 +39,14 @@ public partial class GoodsOffshelfLog
/// 下架时间
/// </summary>
public int CreateTime { get; set; }
/// <summary>
/// 备注
/// </summary>
public string? Remarks { get; set; }
/// <summary>
/// 是否已读
/// </summary>
public int IsRead { get; set; }
}

View File

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
namespace ChouBox.Model.Entities;
/// <summary>
/// 用户验证码表
/// </summary>
public partial class UserVerificationCodes
{
/// <summary>
/// 主键ID
/// </summary>
public ulong Id { get; set; }
/// <summary>
/// 用户ID可为空表示未登录用户
/// </summary>
public ulong? UserId { get; set; }
/// <summary>
/// 账号(手机号/邮箱)
/// </summary>
public string Account { get; set; } = null!;
/// <summary>
/// 验证码
/// </summary>
public string Code { get; set; } = null!;
/// <summary>
/// 验证码类型1-注册2-登录3-找回密码4-修改手机5-修改邮箱6-其他
/// </summary>
public sbyte CodeType { get; set; }
/// <summary>
/// 发送渠道sms-短信email-邮件
/// </summary>
public string Channel { get; set; } = null!;
/// <summary>
/// 请求IP地址
/// </summary>
public string? IpAddress { get; set; }
/// <summary>
/// 状态0-未使用1-已使用2-已失效
/// </summary>
public sbyte Status { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// 更新时间
/// </summary>
public DateTime UpdatedAt { get; set; }
/// <summary>
/// 过期时间
/// </summary>
public DateTime ExpiredAt { get; set; }
/// <summary>
/// 使用时间
/// </summary>
public DateTime? UsedAt { get; set; }
}

View File

@ -5,7 +5,6 @@ using Pomelo.EntityFrameworkCore.MySql.Scaffolding.Internal;
namespace ChouBox.Model.Entities;
///
public partial class YoudaContext : DbContext
{
public YoudaContext()
@ -407,6 +406,11 @@ public partial class YoudaContext : DbContext
/// </summary>
public virtual DbSet<UserTaskList> UserTaskList { get; set; }
/// <summary>
/// 用户验证码表
/// </summary>
public virtual DbSet<UserVerificationCodes> UserVerificationCodes { get; set; }
/// <summary>
/// 会员vip
/// </summary>
@ -964,6 +968,8 @@ public partial class YoudaContext : DbContext
entity.HasIndex(e => e.Id, "id").IsUnique();
entity.HasIndex(e => new { e.UserId, e.Addtime, e.Status }, "idx_user_addtime_status");
entity.Property(e => e.Id)
.HasColumnType("int(10) unsigned")
.HasColumnName("id");
@ -1469,6 +1475,10 @@ public partial class YoudaContext : DbContext
.HasComment("下架生效抽数")
.HasColumnType("int(11)")
.HasColumnName("xiajia_auto_coushu");
entity.Property(e => e.XiajiaJine)
.HasComment("下架金额当盒子利润值小于它时下架如100 盒子利润出现负数后,超过-100就下架")
.HasColumnType("int(11)")
.HasColumnName("xiajia_jine");
entity.Property(e => e.XiajiaLirun)
.HasComment("下架利润率")
.HasColumnType("int(11)")
@ -1807,6 +1817,10 @@ public partial class YoudaContext : DbContext
.HasPrecision(10, 2)
.HasComment("出货总价值")
.HasColumnName("goods_total");
entity.Property(e => e.IsRead)
.HasComment("是否已读")
.HasColumnType("int(11)")
.HasColumnName("is_read");
entity.Property(e => e.OrderTotal)
.HasPrecision(10, 2)
.HasComment("订单总价值")
@ -1815,6 +1829,10 @@ public partial class YoudaContext : DbContext
.HasPrecision(10, 2)
.HasComment("当前利润率")
.HasColumnName("profit_rate");
entity.Property(e => e.Remarks)
.HasMaxLength(1000)
.HasComment("备注")
.HasColumnName("remarks");
entity.Property(e => e.XiajiaLirun)
.HasPrecision(10, 2)
.HasComment("配置的下架利润阈值")
@ -2733,8 +2751,12 @@ public partial class YoudaContext : DbContext
entity.HasIndex(e => e.Id, "id").IsUnique();
entity.HasIndex(e => new { e.GoodsId, e.ShangId, e.ParentGoodsListId }, "idx_count_fast");
entity.HasIndex(e => new { e.GoodsId, e.UserId, e.Addtime }, "idx_gid_uid_time");
entity.HasIndex(e => new { e.ShangId, e.ParentGoodsListId, e.GoodsId, e.OrderType, e.Id }, "idx_opt_query");
entity.HasIndex(e => new { e.UserId, e.Addtime }, "idx_user_addtime");
entity.HasIndex(e => e.InsuranceIs, "insurance_is");
@ -3922,7 +3944,7 @@ public partial class YoudaContext : DbContext
.HasColumnType("int(11) unsigned")
.HasColumnName("mb_number");
entity.Property(e => e.Mobile)
.HasMaxLength(11)
.HasMaxLength(15)
.HasComment("手机号")
.HasColumnName("mobile");
entity.Property(e => e.Money)
@ -4739,6 +4761,71 @@ public partial class YoudaContext : DbContext
.HasColumnName("z_number");
});
modelBuilder.Entity<UserVerificationCodes>(entity =>
{
entity.HasKey(e => e.Id).HasName("PRIMARY");
entity.ToTable("user_verification_codes", tb => tb.HasComment("用户验证码表"));
entity.HasIndex(e => new { e.Account, e.CodeType }, "idx_account_code_type");
entity.HasIndex(e => e.Code, "idx_code");
entity.HasIndex(e => e.ExpiredAt, "idx_expired_at");
entity.Property(e => e.Id)
.HasComment("主键ID")
.HasColumnType("bigint(20) unsigned")
.HasColumnName("id");
entity.Property(e => e.Account)
.HasMaxLength(100)
.HasComment("账号(手机号/邮箱)")
.HasColumnName("account");
entity.Property(e => e.Channel)
.HasMaxLength(20)
.HasComment("发送渠道sms-短信email-邮件")
.HasColumnName("channel");
entity.Property(e => e.Code)
.HasMaxLength(20)
.HasComment("验证码")
.HasColumnName("code");
entity.Property(e => e.CodeType)
.HasComment("验证码类型1-注册2-登录3-找回密码4-修改手机5-修改邮箱6-其他")
.HasColumnType("tinyint(4)")
.HasColumnName("code_type");
entity.Property(e => e.CreatedAt)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("创建时间")
.HasColumnType("datetime")
.HasColumnName("created_at");
entity.Property(e => e.ExpiredAt)
.HasComment("过期时间")
.HasColumnType("datetime")
.HasColumnName("expired_at");
entity.Property(e => e.IpAddress)
.HasMaxLength(50)
.HasComment("请求IP地址")
.HasColumnName("ip_address");
entity.Property(e => e.Status)
.HasComment("状态0-未使用1-已使用2-已失效")
.HasColumnType("tinyint(4)")
.HasColumnName("status");
entity.Property(e => e.UpdatedAt)
.ValueGeneratedOnAddOrUpdate()
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("更新时间")
.HasColumnType("datetime")
.HasColumnName("updated_at");
entity.Property(e => e.UsedAt)
.HasComment("使用时间")
.HasColumnType("datetime")
.HasColumnName("used_at");
entity.Property(e => e.UserId)
.HasComment("用户ID可为空表示未登录用户")
.HasColumnType("bigint(20) unsigned")
.HasColumnName("user_id");
});
modelBuilder.Entity<UserVip>(entity =>
{
entity.HasKey(e => e.Id).HasName("PRIMARY");

View File

@ -8,5 +8,5 @@ dotnet ef dbcontext scaffold "Server=192.168.1.56;Database=youda;User=youda;Pass
dotnet ef dbcontext scaffold "Server=192.168.1.56;Database=youda;User=youda;Password=youda;" Pomelo.EntityFrameworkCore.MySql -o Entities/ --use-database-names --no-pluralize --force --context-dir Context --project ChouBox.Model
dotnet ef dbcontext scaffold "Server=192.168.1.56;Database=youda;User=youda;Password=youda;" Pomelo.EntityFrameworkCore.MySql -o Entities/ --no-pluralize --force
dotnet ef dbcontext scaffold "server=192.168.195.13;port=3306;database=youda;user=youda;password=youda;charset=utf8mb4" Pomelo.EntityFrameworkCore.MySql -o Entities/ --no-pluralize --force
```

View File

@ -3,6 +3,7 @@
using HuanMeng.DotNetCore.AttributeExtend;
using HuanMeng.DotNetCore.Base;
using HuanMeng.DotNetCore.Extensions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@ -14,7 +15,7 @@ namespace ChouBox.WebApi.Controllers;
/// <param name="serviceProvider"></param>
[Route("api/v2/[controller]")]
[ApiController]
public class AccountController(IServiceProvider serviceProvider) : ControllerBase
public class AccountController(IServiceProvider serviceProvider, IHttpContextAccessor httpContextAccessor) : ControllerBase
{
@ -25,9 +26,10 @@ public class AccountController(IServiceProvider serviceProvider) : ControllerBas
/// <returns></returns>
[HttpPost]
[Route("sendSms")]
public async Task<string> SendPhoneAsync([FromForm]string phone)
[Message("验证码发送成功!")]
public async Task<int> SendPhoneAsync([FromForm] string phone)
{
SMSBLL sms = new SMSBLL(serviceProvider);
return await sms.SendPhoneAsync(phone);
return await sms.SendPhoneAsync(phone); ;
}
}

View File

@ -56,15 +56,112 @@ namespace ChouBox.WebApi.Filters
context.Result = new JsonResult(response);
}
// 处理其他类型的结果如ActionResult<string>
else if (context.Result is ObjectResult objResult && objResult.Value is string stringValue)
else if (context.Result is ObjectResult objResult)
{
var response = new BaseResponse<string>
// 处理基础类型
if (objResult.Value is string stringValue)
{
Status = 1,
Msg = customMessage,
Data = stringValue
};
context.Result = new JsonResult(response);
var response = new BaseResponse<string>
{
Status = 1,
Msg = customMessage,
Data = stringValue
};
context.Result = new JsonResult(response);
}
else if (objResult.Value is int intValue)
{
var response = new BaseResponse<int>
{
Status = 1,
Msg = customMessage,
Data = intValue
};
context.Result = new JsonResult(response);
}
else if (objResult.Value is bool boolValue)
{
var response = new BaseResponse<bool>
{
Status = 1,
Msg = customMessage,
Data = boolValue
};
context.Result = new JsonResult(response);
}
else if (objResult.Value is long longValue)
{
var response = new BaseResponse<long>
{
Status = 1,
Msg = customMessage,
Data = longValue
};
context.Result = new JsonResult(response);
}
else if (objResult.Value is double doubleValue)
{
var response = new BaseResponse<double>
{
Status = 1,
Msg = customMessage,
Data = doubleValue
};
context.Result = new JsonResult(response);
}
else if (objResult.Value is decimal decimalValue)
{
var response = new BaseResponse<decimal>
{
Status = 1,
Msg = customMessage,
Data = decimalValue
};
context.Result = new JsonResult(response);
}
else if (objResult.Value is DateTime dateTimeValue)
{
var response = new BaseResponse<DateTime>
{
Status = 1,
Msg = customMessage,
Data = dateTimeValue
};
context.Result = new JsonResult(response);
}
else if (objResult.Value is Guid guidValue)
{
var response = new BaseResponse<Guid>
{
Status = 1,
Msg = customMessage,
Data = guidValue
};
context.Result = new JsonResult(response);
}
// 如果不是基础类型则直接使用object类型的BaseResponse
else if (objResult.Value != null)
{
// 处理其他非基础类型
var response = new BaseResponse<object>
{
Status = 1,
Msg = customMessage,
Data = objResult.Value
};
context.Result = new JsonResult(response);
}
// 处理null值
else
{
var response = new BaseResponse<object>
{
Status = 1,
Msg = customMessage,
Data = null
};
context.Result = new JsonResult(response);
}
}
}

View File

@ -86,8 +86,8 @@ builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<ChouBoxCodeBase>();
#region
var _myAllowSpecificOrigins = "_myAllowSpecificOrigins";
builder.Services.AddCustomCors(_myAllowSpecificOrigins);
//var _myAllowSpecificOrigins = "_myAllowSpecificOrigins";
//builder.Services.AddCustomCors(_myAllowSpecificOrigins);
#endregion
var app = builder.Build();
@ -102,7 +102,7 @@ app.UseHttpsRedirection();
app.UseAuthorization();
//使用跨域
app.UseCors(_myAllowSpecificOrigins);
//app.UseCors(_myAllowSpecificOrigins);
//执行扩展中间件
app.UseMiddlewareAll();

View File

@ -8,5 +8,12 @@
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}, //
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:81"
}
}
}
}

View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.DotNetCore.Base
{
/// <summary>
/// 自定义异常类,用于特定业务场景
/// 该异常被捕获时不会记录日志,适用于普通业务逻辑错误
/// </summary>
public class CustomException : Exception
{
/// <summary>
/// 错误参数名
/// </summary>
public string ParamName { get; }
/// <summary>
/// 创建自定义异常
/// </summary>
/// <param name="message">错误消息</param>
public CustomException(string message) : base(message)
{
ParamName = message;
}
/// <summary>
/// 创建自定义异常
/// </summary>
/// <param name="message">错误消息</param>
/// <param name="paramName">参数名</param>
public CustomException(string message, string paramName) : base(message)
{
ParamName = paramName;
}
/// <summary>
/// 创建自定义异常
/// </summary>
/// <param name="message">错误消息</param>
/// <param name="innerException">内部异常</param>
public CustomException(string message, Exception innerException) : base(message, innerException)
{
ParamName = message;
}
/// <summary>
/// 创建自定义异常
/// </summary>
/// <param name="message">错误消息</param>
/// <param name="paramName">参数名</param>
/// <param name="innerException">内部异常</param>
public CustomException(string message, string paramName, Exception innerException) : base(message, innerException)
{
ParamName = paramName;
}
}
}

View File

@ -12,7 +12,12 @@ public enum ResponseCode
/// <summary>
/// 成功
/// </summary>
Success = 0,
Success = 1,
/// <summary>
/// 通用
/// </summary>
Common = 0,
/// <summary>
/// 正在处理中

View File

@ -36,7 +36,7 @@ namespace HuanMeng.DotNetCore.MiddlewareExtend
context.Response.StatusCode = StatusCodes.Status200OK;
BaseResponse<object> baseResponse = new BaseResponse<object>(ResponseCode.ParamError, ex.ParamName ?? "参数错误", null)
BaseResponse<object> baseResponse = new BaseResponse<object>(ResponseCode.Common, ex.ParamName ?? "参数错误", null)
{
};
@ -44,6 +44,15 @@ namespace HuanMeng.DotNetCore.MiddlewareExtend
// 将异常信息写入 HTTP 响应
await context.Response.WriteAsync(baseResponse.ToString());
}
catch (CustomException ex)
{
// 对自定义异常的特殊处理,不记录日志
context.Response.StatusCode = StatusCodes.Status200OK;
BaseResponse<object> baseResponse = new BaseResponse<object>(ResponseCode.Common, ex.ParamName ?? "", null);
context.Response.ContentType = "application/json; charset=utf-8";
// 将异常信息写入 HTTP 响应
await context.Response.WriteAsync(baseResponse.ToString());
}
catch (Exception ex)
{