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; }
+
///
/// 操作时间
///