diff --git a/Infrastructure/Model/SendEmailDto.cs b/Infrastructure/Model/SendEmailDto.cs index 6674ec4..f8d0b9c 100644 --- a/Infrastructure/Model/SendEmailDto.cs +++ b/Infrastructure/Model/SendEmailDto.cs @@ -12,9 +12,9 @@ namespace Infrastructure.Model /// /// 主题 /// - [Required(ErrorMessage = "主题不能为空")] + // [Required(ErrorMessage = "主题不能为空")] public string Subject { get; set; } - [Required(ErrorMessage = "发送人不能为空")] + // [Required(ErrorMessage = "发送人不能为空")] public string ToUser { get; set; } public string Content { get; set; } = ""; public string HtmlContent { get; set; } diff --git a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs index 316dbcb..798aad7 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Options; using NETCore.Encrypt; using ZR.Admin.WebApi.Filters; +using ZR.Infrastructure.Cache; using ZR.Service.System; using ZR.Service.System.IService; using ZR.ServiceCore.Model; @@ -191,6 +192,64 @@ namespace ZR.Admin.WebApi.Controllers.System return ToResponse(ResultCode.CUSTOM_ERROR, "注册失败,请联系管理员"); } + /// + /// 发送邮箱验证码 + /// + /// + /// + [HttpPost("getMailCode")] + public async Task GetMailCode([FromBody] SendEmailDto sendEmailVo) + { + if (string.IsNullOrEmpty(sendEmailVo.ToUser)) + { + return ToResponse(ApiResult.Error($"邮箱不能为空")); + } + if (string.IsNullOrEmpty(optionSettings.MailOptions.FromEmail) || string.IsNullOrEmpty(optionSettings.MailOptions.Password)) + { + return ToResponse(ApiResult.Error($"请配置邮箱信息")); + } + + if (sendEmailVo.ToUser.Length > 32) + { + // 解密邮箱 + sendEmailVo.ToUser = EncryptProvider.RSADecryptWithPem(PrivatePem, sendEmailVo.ToUser); + + // 验证邮箱是否存在于系统用户中 + var user = await sysUserService.IsAnyAsync(it => it.Email == sendEmailVo.ToUser); + // if (user == null || user.UserId <= 0) + // 不存在则提示错误 + if (!user) + { + return ToResponse(ApiResult.Error($"邮箱错误,请联系管理员")); + } + + } + else + { + string[] saltKey = await RedisServer.Session.LRangeAsync("saltMail:" + sendEmailVo.ToUser, 0, 1); + if (saltKey.Length > 0) + { + sendEmailVo.ToUser = saltKey[0]; + } + else + { + return ToResponse(ApiResult.Error($"邮箱错误,请联系管理员")); + } + } + // 实例化MailHelper以准备发送邮件 + MailHelper mailHelper = new(); + // 生成6位邮箱验证码 + var verifyCode = mailHelper.VerifyCode(6); + // 设置存入Redis的key为 verifyCode: 前缀 + (盐 + 邮箱)的MD5值 + var key = "verifyCode:" + sendEmailVo.ToUser; + // 存入Redis中设置过期时间为15分钟 + var res = await RedisServer.Session.SetAsync(key, verifyCode, 900); + // 发送邮件,主题为 ZRAdmin.NET邮箱验证码,内容为验证码 + mailHelper.SendMail(sendEmailVo.ToUser, "ZRAdmin.NET邮箱验证码", verifyCode); + + return SUCCESS(res); + } + #region 二维码登录 /// diff --git a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj index a232719..2e10d71 100644 --- a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj +++ b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj @@ -42,5 +42,8 @@ Never + + appsettings.json + diff --git a/ZR.Admin.WebApi/appsettings.json b/ZR.Admin.WebApi/appsettings.json index f821864..7c4f607 100644 --- a/ZR.Admin.WebApi/appsettings.json +++ b/ZR.Admin.WebApi/appsettings.json @@ -88,14 +88,14 @@ //邮箱配置信息 "MailOptions": { //发件人名称 - "FromName": "system", + "FromName": "文永达", //发送人邮箱 - "FromEmail": "", //eg:xxxx@qq.com + "FromEmail": "1224169330@qq.com", //eg:xxxx@qq.com //发送人邮箱密码 - "Password": "", + "Password": "wbctsfvdazchibdh", //协议 "Smtp": "smtp.qq.com", - "Port": 587, + "Port": 465, "Signature": "系统邮件,请勿回复!", "UseSsl": true }, diff --git a/ZR.Common/MailHelper.cs b/ZR.Common/MailHelper.cs index a46cf48..541db71 100644 --- a/ZR.Common/MailHelper.cs +++ b/ZR.Common/MailHelper.cs @@ -6,6 +6,7 @@ using MimeKit.Text; using System; using System.Collections.Generic; using System.IO; +using System.Text; namespace ZR.Common { @@ -148,5 +149,32 @@ namespace ZR.Common return "fail"; } } + + public string VerifyCode(int n) + { + var strB = new StringBuilder(); + var rand = new Random(); + for (var i = 0; i < n; i++) + { + var r1 = rand.Next(3); + var r2 = 0; + // r2为ASCII码值 + switch (r1) + { + case 0: // 数字: 48-57的随机数 + r2 = rand.Next(48, 58); + break; + case 1: + r2 = rand.Next(65, 91); // 大写字母: 65-90的随机数 + break; + case 2: + r2 = rand.Next(97, 123); // 小写字母: 97-122的随机数 + break; + } + + strB.Append((char)r2); + } + return strB.ToString(); + } } } \ No newline at end of file diff --git a/ZR.ServiceCore/Middleware/GlobalExceptionMiddleware.cs b/ZR.ServiceCore/Middleware/GlobalExceptionMiddleware.cs index 080dedb..0fcb940 100644 --- a/ZR.ServiceCore/Middleware/GlobalExceptionMiddleware.cs +++ b/ZR.ServiceCore/Middleware/GlobalExceptionMiddleware.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using NLog; using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Routing; using ZR.Common; using ZR.Model.System; using ZR.Service.System.IService; @@ -50,6 +51,9 @@ namespace ZR.ServiceCore.Middleware string msg; string error = string.Empty; bool notice = true; + var stackTrace = string.Empty; + var controller = context.GetRouteData().Values["Controller"].ToString(); + var action = context.GetRouteData().Values["Action"].ToString(); //自定义异常 if (ex is CustomException customException) { @@ -57,6 +61,7 @@ namespace ZR.ServiceCore.Middleware msg = customException.Message; error = customException.LogMsg; notice = customException.Notice; + stackTrace = customException.StackTrace; } else if (ex is ArgumentException)//参数异常 { @@ -69,6 +74,7 @@ namespace ZR.ServiceCore.Middleware error = $"{ex.Message}"; logLevel = LogLevel.Error; context.Response.StatusCode = 500; + stackTrace = ex.StackTrace; } var options = new textJson.JsonSerializerOptions { @@ -90,8 +96,10 @@ namespace ZR.ServiceCore.Middleware RequestMethod = context.Request.Method, JsonResult = responseResult, ErrorMsg = string.IsNullOrEmpty(error) ? msg : error, + StackTrace = stackTrace, OperName = HttpContextExtension.GetName(context), OperLocation = ip_info.Province + " " + ip_info.City, + Method = controller + "." + action + "()", OperTime = DateTime.Now, OperParam = HttpContextExtension.GetRequestValue(context, context.Request.Method) }; diff --git a/ZR.ServiceCore/Model/SysOperLog.cs b/ZR.ServiceCore/Model/SysOperLog.cs index 5fb0469..3fcf00c 100644 --- a/ZR.ServiceCore/Model/SysOperLog.cs +++ b/ZR.ServiceCore/Model/SysOperLog.cs @@ -89,6 +89,11 @@ namespace ZR.ServiceCore.Model /// public string ErrorMsg { get; set; } + /// + /// 错误堆栈信息 + /// + public string StackTrace { get; set; } + /// /// 操作时间 ///