feat: 新增找回密码功能接口
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Account;
|
||||
|
||||
public class RetrievePasswordDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 唯一标识码
|
||||
/// </summary>
|
||||
public string? Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 电话
|
||||
/// </summary>
|
||||
public long Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证码
|
||||
/// </summary>
|
||||
public string? Code { get; set; }
|
||||
}
|
||||
@@ -27,6 +27,7 @@ using Yi.Framework.Rbac.Domain.Repositories;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Caches;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Consts;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Dtos;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Enums;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Etos;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Options;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
@@ -44,6 +45,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
private IDistributedCache<UserInfoCacheItem, UserInfoCacheKey> _userCache;
|
||||
private UserManager _userManager;
|
||||
private IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public AccountService(IUserRepository userRepository,
|
||||
ICurrentUser currentUser,
|
||||
IAccountManager accountManager,
|
||||
@@ -127,7 +129,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
loginEto.UserId = userInfo.User.Id;
|
||||
await LocalEventBus.PublishAsync(loginEto);
|
||||
}
|
||||
|
||||
|
||||
return new { Token = accessToken, RefreshToken = refreshToken };
|
||||
}
|
||||
|
||||
@@ -178,14 +180,35 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 注册 手机验证码
|
||||
/// 手机验证码-注册
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("captcha-phone")]
|
||||
[AllowAnonymous]
|
||||
public async Task<object> PostCaptchaPhoneForRegisterAsync(PhoneCaptchaImageDto input)
|
||||
{
|
||||
return await PostCaptchaPhoneAsync(ValidationPhoneTypeEnum.Register, input);
|
||||
}
|
||||
/// <summary>
|
||||
/// 手机验证码-找回密码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("captcha-phone/repassword")]
|
||||
public async Task<object> PostCaptchaPhoneForRetrievePasswordAsync(PhoneCaptchaImageDto input)
|
||||
{
|
||||
return await PostCaptchaPhoneAsync(ValidationPhoneTypeEnum.RetrievePassword, input);
|
||||
}
|
||||
/// <summary>
|
||||
/// 手机验证码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
public async Task<object> PostCaptchaPhone(PhoneCaptchaImageDto input)
|
||||
private async Task<object> PostCaptchaPhoneAsync(ValidationPhoneTypeEnum validationPhoneType,
|
||||
PhoneCaptchaImageDto input)
|
||||
{
|
||||
await ValidationPhone(input.Phone);
|
||||
var value = await _phoneCache.GetAsync(new CaptchaPhoneCacheKey(input.Phone));
|
||||
var value = await _phoneCache.GetAsync(new CaptchaPhoneCacheKey(validationPhoneType, input.Phone));
|
||||
|
||||
//防止暴刷
|
||||
if (value is not null)
|
||||
@@ -200,7 +223,8 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
var uuid = Guid.NewGuid();
|
||||
await _aliyunManger.SendSmsAsync(input.Phone, code);
|
||||
|
||||
await _phoneCache.SetAsync(new CaptchaPhoneCacheKey(input.Phone), new CaptchaPhoneCacheItem(code),
|
||||
await _phoneCache.SetAsync(new CaptchaPhoneCacheKey(ValidationPhoneTypeEnum.Register, input.Phone),
|
||||
new CaptchaPhoneCacheItem(code),
|
||||
new DistributedCacheEntryOptions { SlidingExpiration = TimeSpan.FromMinutes(10) });
|
||||
return new
|
||||
{
|
||||
@@ -211,19 +235,44 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
/// <summary>
|
||||
/// 校验电话验证码,需要与电话号码绑定
|
||||
/// </summary>
|
||||
private async Task ValidationPhoneCaptchaAsync(RegisterDto input)
|
||||
private async Task ValidationPhoneCaptchaAsync(ValidationPhoneTypeEnum validationPhoneType, long phone,
|
||||
string code)
|
||||
{
|
||||
var item = await _phoneCache.GetAsync(new CaptchaPhoneCacheKey(input.Phone.ToString()));
|
||||
if (item is not null && item.Code.Equals($"{input.Code}"))
|
||||
var item = await _phoneCache.GetAsync(new CaptchaPhoneCacheKey(validationPhoneType, phone.ToString()));
|
||||
if (item is not null && item.Code.Equals($"{code}"))
|
||||
{
|
||||
//成功,需要清空
|
||||
await _phoneCache.RemoveAsync(new CaptchaPhoneCacheKey(input.Phone.ToString()));
|
||||
await _phoneCache.RemoveAsync(new CaptchaPhoneCacheKey(validationPhoneType, code.ToString()));
|
||||
return;
|
||||
}
|
||||
|
||||
throw new UserFriendlyException("验证码错误");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 找回密码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
[AllowAnonymous]
|
||||
[UnitOfWork]
|
||||
public async Task PostRetrievePasswordAsync(RetrievePasswordDto input)
|
||||
{
|
||||
if (_rbacOptions.EnableCaptcha)
|
||||
{
|
||||
//校验验证码,根据电话号码获取 value,比对验证码已经uuid
|
||||
await ValidationPhoneCaptchaAsync(ValidationPhoneTypeEnum.RetrievePassword, input.Phone, input.Code);
|
||||
}
|
||||
|
||||
var entity = await _userRepository.GetFirstAsync(x => x.Phone == input.Phone);
|
||||
if (entity is null)
|
||||
{
|
||||
throw new UserFriendlyException("该手机号码未注册");
|
||||
}
|
||||
|
||||
await _accountManager.RestPasswordAsync(entity.Id, input.Password);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 注册,需要验证码通过
|
||||
/// </summary>
|
||||
@@ -241,16 +290,16 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
if (_rbacOptions.EnableCaptcha)
|
||||
{
|
||||
//校验验证码,根据电话号码获取 value,比对验证码已经uuid
|
||||
await ValidationPhoneCaptchaAsync(input);
|
||||
await ValidationPhoneCaptchaAsync(ValidationPhoneTypeEnum.Register, input.Phone, input.Code);
|
||||
}
|
||||
|
||||
//注册领域逻辑
|
||||
await _accountManager.RegisterAsync(input.UserName, input.Password, input.Phone,input.Nick);
|
||||
await _accountManager.RegisterAsync(input.UserName, input.Password, input.Phone, input.Nick);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 查询已登录的账户信息,已缓存
|
||||
/// 查询已登录的账户信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Route("account")]
|
||||
@@ -270,9 +319,6 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前登录用户的前端路由
|
||||
/// 支持ruoyi/pure
|
||||
@@ -280,7 +326,7 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
/// <returns></returns>
|
||||
[Authorize]
|
||||
[Route("account/Vue3Router/{routerType?}")]
|
||||
public async Task<object> GetVue3Router([FromRoute]string? routerType)
|
||||
public async Task<object> GetVue3Router([FromRoute] string? routerType)
|
||||
{
|
||||
var userId = _currentUser.Id;
|
||||
if (_currentUser.Id is null)
|
||||
@@ -298,18 +344,19 @@ namespace Yi.Framework.Rbac.Application.Services
|
||||
}
|
||||
|
||||
object output = null;
|
||||
if (routerType is null ||routerType=="ruoyi")
|
||||
if (routerType is null || routerType == "ruoyi")
|
||||
{
|
||||
//将后端菜单转换成前端路由,组件级别需要过滤
|
||||
output =
|
||||
ObjectMapper.Map<List<MenuDto>, List<MenuAggregateRoot>>(menus).Vue3RuoYiRouterBuild();
|
||||
}
|
||||
else if (routerType =="pure")
|
||||
else if (routerType == "pure")
|
||||
{
|
||||
//将后端菜单转换成前端路由,组件级别需要过滤
|
||||
output =
|
||||
ObjectMapper.Map<List<MenuDto>, List<MenuAggregateRoot>>(menus).Vue3PureRouterBuild();
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Yi.Framework.Rbac.Domain.Shared.Enums;
|
||||
|
||||
namespace Yi.Framework.Rbac.Domain.Shared.Caches
|
||||
{
|
||||
@@ -14,13 +15,15 @@ namespace Yi.Framework.Rbac.Domain.Shared.Caches
|
||||
|
||||
public class CaptchaPhoneCacheKey
|
||||
{
|
||||
public CaptchaPhoneCacheKey(string phone) { Phone = phone; }
|
||||
|
||||
public CaptchaPhoneCacheKey(ValidationPhoneTypeEnum validationPhoneType,string phone) { Phone = phone;
|
||||
ValidationPhoneType = validationPhoneType;
|
||||
}
|
||||
public ValidationPhoneTypeEnum ValidationPhoneType { get; set; }
|
||||
public string Phone { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Phone:{Phone}";
|
||||
return $"Phone:{ValidationPhoneType.ToString()}:{Phone}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Yi.Framework.Rbac.Domain.Shared.Enums;
|
||||
|
||||
public enum ValidationPhoneTypeEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册
|
||||
/// </summary>
|
||||
Register,
|
||||
/// <summary>
|
||||
/// 忘记密码
|
||||
/// </summary>
|
||||
RetrievePassword
|
||||
}
|
||||
@@ -180,6 +180,8 @@ namespace Yi.Framework.Rbac.Domain.Managers
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 令牌转换
|
||||
@@ -250,7 +252,7 @@ namespace Yi.Framework.Rbac.Domain.Managers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置密码
|
||||
/// 重置密码,也可以是找回密码
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="password"></param>
|
||||
@@ -258,7 +260,6 @@ namespace Yi.Framework.Rbac.Domain.Managers
|
||||
public async Task<bool> RestPasswordAsync(Guid userId, string password)
|
||||
{
|
||||
var user = await _repository.GetByIdAsync(userId);
|
||||
// EntityHelper.TrySetId(user, () => GuidGenerator.Create(), true);
|
||||
user.EncryPassword.Password = password;
|
||||
user.BuildPassword();
|
||||
return await _repository.UpdateAsync(user);
|
||||
@@ -276,7 +277,6 @@ namespace Yi.Framework.Rbac.Domain.Managers
|
||||
var user = new UserAggregateRoot(userName, password, phone,nick);
|
||||
await _userManager.CreateAsync(user);
|
||||
await _userManager.SetDefautRoleAsync(user.Id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,12 +51,12 @@ namespace Yi.Framework.Rbac.Domain.Operlog
|
||||
/// <summary>
|
||||
/// 请求参数
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "RequestParam")]
|
||||
[SugarColumn(ColumnName = "RequestParam",ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
||||
public string? RequestParam { get; set; }
|
||||
/// <summary>
|
||||
/// 请求结果
|
||||
///</summary>
|
||||
[SugarColumn(ColumnName = "RequestResult", Length = 9999)]
|
||||
[SugarColumn(ColumnName = "RequestResult",ColumnDataType = StaticConfig.CodeFirst_BigString)]
|
||||
public string? RequestResult { get; set; }
|
||||
|
||||
public DateTime CreationTime { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user