Merge branch 'dev' into 'master'

Merge branch 'dev_add_auth_1029' into 'master'

See merge request ql/apismnagaer_backend!9
This commit is contained in:
西街长安 2024-11-06 17:02:23 +00:00
commit ef8b9994d6
15 changed files with 234 additions and 17 deletions

View File

@ -9,6 +9,8 @@ namespace Apimanager_backend.Config
public MyAutomapper() public MyAutomapper()
{ {
CreateMap<User,UserInfoDto>(); CreateMap<User,UserInfoDto>();
CreateMap<CreateUserDto, User>()
.ForMember(dest => dest.PassHash, opt => opt.MapFrom(src => src.Password));
} }
} }
} }

View File

@ -0,0 +1,47 @@
using Apimanager_backend.Dtos;
using Apimanager_backend.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Apimanager_backend.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class AdminController : ControllerBase
{
private readonly IAdminService adminService;
private readonly IUserService userService;
public AdminController(IAdminService service,IUserService userService)
{
this.adminService = service;
this.userService = userService;
}
#region
[HttpGet]
[Authorize("Admin")]
public async Task<ActionResult<ResponseBase<List<UserInfoDto>>>> UserList(int pageIndex,int pageSize,bool desc)
{
var users = await adminService.GetUsersAsync(pageIndex,pageSize,desc);
var res = new ResponseBase<List<UserInfoDto>>(
code:1000,
message:"Success",
data:users
);
return Ok(res);
}
#endregion
[HttpGet]
[Authorize("Admin")]
public async Task<ActionResult<ResponseBase<UserInfoDto?>>> UserInfo(int userId)
{
var userInfo = await userService.GetUserAsync(userId);
var res = new ResponseBase<UserInfoDto?>(
code: 1000,
message: "Success",
data: userInfo
);
return Ok(res);
}
}
}

View File

@ -154,7 +154,19 @@ namespace Apimanager_backend.Controllers
); );
return Ok(res); return Ok(res);
} }
[HttpDelete]
[Authorize(Roles = "User")]
public async Task<ActionResult<ResponseBase<object?>>> Logout()
{
var userId = User.Claims.First(x => x.ValueType == "userId").Value;
await refreshTokenService.DeleterRefreshTokenAsync(userId);
var res = new ResponseBase<object?>(
code:1000,
message:"Success",
data: null
);
return Ok(res);
}
} }
} }

View File

@ -74,5 +74,18 @@ namespace Apimanager_backend.Controllers
); );
return Ok(res); return Ok(res);
} }
[HttpPost]
[Authorize(Roles = "User")]
public async Task<ActionResult<ResponseBase<UserInfoDto?>>> Update([FromBody]UpdateUserDto dto)
{
var userId = User.Claims.First(x => x.ValueType == "userId").Value;
var userInfo = await userService.UpdateUserAsync(int.Parse(userId),dto);
var res = new ResponseBase<object?>(
code:1000,
message:"Success",
data:userInfo
);
return Ok(res);
}
} }
} }

View File

@ -0,0 +1,8 @@
namespace Apimanager_backend.Dtos
{
public class AdminUpdateUserDto
{
public string Password { get; set; }
public decimal Balance { get; set; }
}
}

View File

@ -1,6 +1,16 @@
namespace Apimanager_backend.Dtos using System.ComponentModel.DataAnnotations;
namespace Apimanager_backend.Dtos
{ {
public class CreateUserDto public class CreateUserDto
{ {
[Required(ErrorMessage = "用户名必填")]
[MaxLength(20,ErrorMessage = "用户名最大长度20字符")]
public string Username { get; set; }
[Required(ErrorMessage = "密码必填")]
public string Password { get; set; }
[EmailAddress(ErrorMessage = "邮箱格式错误")]
public string Email { get; set; }
} }
} }

View File

@ -1,10 +1,10 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace Apimanager_backend.Dtos namespace Apimanager_backend.Dtos
{ {
public class UpdateUserDto public class UpdateUserDto
{ {
public int? userId { get; set; }
public string? password { get; set; } public string? password { get; set; }
} }
} }

View File

@ -35,16 +35,16 @@ namespace Apimanager_backend.Models
/// <summary> /// <summary>
/// 是否禁用 /// 是否禁用
/// </summary> /// </summary>
public bool IsBan { get; set; } // boolean public bool IsBan { get; set; } = false; // boolean
/// <summary> /// <summary>
/// 是否删除 /// 是否删除
/// </summary> /// </summary>
public bool IsDelete { get; set; } // boolean public bool IsDelete { get; set; } = false; // boolean
/// <summary> /// <summary>
/// 余额 /// 余额
/// </summary> /// </summary>
public decimal Balance { get; set; } // Decimal(10) public decimal Balance { get; set; } = 0; // Decimal(10)
/// <summary> /// <summary>
/// 创建时间,默认当前时间 /// 创建时间,默认当前时间

View File

@ -0,0 +1,112 @@
using Apimanager_backend.Data;
using Apimanager_backend.Dtos;
using Apimanager_backend.Exceptions;
using Apimanager_backend.Models;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel;
namespace Apimanager_backend.Services
{
public class AdminService : IAdminService
{
private readonly ApiContext context;
private readonly IMapper mapper;
private readonly ILogger<IAdminService> logger;
public AdminService(ApiContext context, IMapper mapper, ILogger<IAdminService> logger)
{
this.context = context;
this.mapper = mapper;
this.logger = logger;
}
#region
public async Task BanUserAsync(int userId)
{
var user = await context.Users.FirstOrDefaultAsync(x => x.Id == userId);
if (user == null)
{
throw new BaseException(2004,"用户不存在");
}
user.IsBan = true;
context.Users.Update(user);
await context.SaveChangesAsync();
}
#endregion
#region
public async Task<UserInfoDto> CreateUserAsync(CreateUserDto dto)
{
//添加用户
var user = mapper.Map<User>(dto);
context.Users.Add(user);
await context.SaveChangesAsync();
//添加默认角色
UserRole userRole = new UserRole
{
UserId = user.Id,
Role = "User"
};
context.UserRoles.Add(userRole);
await context.SaveChangesAsync();
return mapper.Map<UserInfoDto>(user);
}
#endregion
#region
public async Task DeleteUserAsync(int userId)
{
var user = await context.Users.FirstOrDefaultAsync(x => x.Id == userId);
if (user == null)
{
throw new BaseException(2004, "用户不存在");
}
user.IsDelete = true;
context.Users.Update(user);
await context.SaveChangesAsync();
}
#endregion
#region
public async Task<List<UserInfoDto>> GetUsersAsync(int page, int pageSize, bool desc)
{
var query = context.Users.Where(x => true)
.OrderBy(x => x.Id);
//倒序
if (desc)
{
query = query.OrderByDescending(x => x.Id);
}
//分页
var users = await query.Skip((page - 1) * pageSize)
.Take(pageSize).ToListAsync();
return mapper.Map<List<UserInfoDto>>(users);
}
#endregion
#region
public async Task UnbanUserAsync(int userId)
{
var user = await context.Users.FirstOrDefaultAsync(x => x.Id == userId);
if (user == null)
{
throw new BaseException(2004, "用户不存在");
}
user.IsBan = false;
context.Users.Update(user);
await context.SaveChangesAsync();
}
#endregion
#region
public async Task<UserInfoDto> UpdateUserAsync(int userId,AdminUpdateUserDto dto)
{
var user = await context.Users.FirstOrDefaultAsync(x => x.Id == userId);
if(user == null)
{
throw new BaseException(2004,"用户不存在");
}
user.PassHash = dto.Password;
user.Balance = dto.Balance;
context.Users.Update(user);
await context.SaveChangesAsync();
return mapper.Map<UserInfoDto>(user);
}
#endregion
}
}

View File

@ -25,6 +25,7 @@ namespace Apimanager_backend.Services
this.redis = redis; this.redis = redis;
this.emailService = emailService; this.emailService = emailService;
} }
#region
public async Task<UserInfoDto> LoginAsync(string username, string password) public async Task<UserInfoDto> LoginAsync(string username, string password)
{ {
//查找用户 //查找用户
@ -46,7 +47,8 @@ namespace Apimanager_backend.Services
return mapper.Map<UserInfoDto>(user); return mapper.Map<UserInfoDto>(user);
} }
#endregion
#region
public async Task<UserInfoDto> RegisterAsync(RegisterRequestDto dto) public async Task<UserInfoDto> RegisterAsync(RegisterRequestDto dto)
{ {
var db = redis.GetDatabase(DbIndex); var db = redis.GetDatabase(DbIndex);
@ -84,7 +86,8 @@ namespace Apimanager_backend.Services
} }
} }
#endregion
#region
public async Task SendRegisterCodeAsync(string email) public async Task SendRegisterCodeAsync(string email)
{ {
//生成随机码 //生成随机码
@ -101,5 +104,6 @@ namespace Apimanager_backend.Services
//发送邮件 //发送邮件
await emailService.SendEmailAsync(email,subject,body); await emailService.SendEmailAsync(email,subject,body);
} }
#endregion
} }
} }

View File

@ -36,5 +36,10 @@ namespace Apimanager_backend.Services
/// <param name="userId">用户ID</param> /// <param name="userId">用户ID</param>
/// <returns>异步操作</returns> /// <returns>异步操作</returns>
Task DeleteUserAsync(int userId); Task DeleteUserAsync(int userId);
/// <summary>
/// 修改用户信息
/// </summary>
/// <returns></returns>
Task<UserInfoDto> UpdateUserAsync(int userId,AdminUpdateUserDto dto);
} }
} }

View File

@ -23,7 +23,7 @@
/// <summary> /// <summary>
/// 更新刷新令牌有效期 /// 更新刷新令牌有效期
/// </summary> /// </summary>
/// <param name="refreshToken">刷新令牌</param> /// <param name="userId">用户id</param>
/// <returns>是否成功</returns> /// <returns>是否成功</returns>
Task UpdateRefreshTokenAsync(string userId); Task UpdateRefreshTokenAsync(string userId);
} }

View File

@ -34,7 +34,7 @@ namespace Apimanager_backend.Services
/// </summary> /// </summary>
/// <param name="user">包含更新信息的 <see cref="UpdateUserDto"/></param> /// <param name="user">包含更新信息的 <see cref="UpdateUserDto"/></param>
/// <returns>更新后的 <see cref="UserInfoDto"/></returns> /// <returns>更新后的 <see cref="UserInfoDto"/></returns>
Task<UserInfoDto> UpdateUserAsync(UpdateUserDto user); Task<UserInfoDto> UpdateUserAsync(int userId,UpdateUserDto user);
/// <summary> /// <summary>
/// 检测用户名是否被使用 /// 检测用户名是否被使用
/// </summary> /// </summary>

View File

@ -13,7 +13,7 @@ namespace Apimanager_backend.Services
this.redis = redis; this.redis = redis;
this.configuration = configuration; this.configuration = configuration;
} }
#region
public async Task<string> CreateRefereshTokenAsync(string userId) public async Task<string> CreateRefereshTokenAsync(string userId)
{ {
var refreshToken = Guid.NewGuid().ToString(); var refreshToken = Guid.NewGuid().ToString();
@ -28,7 +28,8 @@ namespace Apimanager_backend.Services
} }
return refreshToken; return refreshToken;
} }
#endregion
#region
public async Task DeleterRefreshTokenAsync(string userId) public async Task DeleterRefreshTokenAsync(string userId)
{ {
var db = redis.GetDatabase(DbIndex); var db = redis.GetDatabase(DbIndex);
@ -38,7 +39,8 @@ namespace Apimanager_backend.Services
throw new BaseException(1006, "Service unavailable"); throw new BaseException(1006, "Service unavailable");
} }
} }
#endregion
#region
public async Task UpdateRefreshTokenAsync(string userId) public async Task UpdateRefreshTokenAsync(string userId)
{ {
var db = redis.GetDatabase(DbIndex); var db = redis.GetDatabase(DbIndex);
@ -53,7 +55,8 @@ namespace Apimanager_backend.Services
//刷新过期时间 //刷新过期时间
await db.KeyExpireAsync(userId,TimeSpan.FromDays(expiryDays)); await db.KeyExpireAsync(userId,TimeSpan.FromDays(expiryDays));
} }
#endregion
#region
public async Task<bool> ValidateRefreshTokenAsync(string userId,string refreshToken) public async Task<bool> ValidateRefreshTokenAsync(string userId,string refreshToken)
{ {
var db = redis.GetDatabase(DbIndex); var db = redis.GetDatabase(DbIndex);
@ -70,5 +73,6 @@ namespace Apimanager_backend.Services
} }
return true; return true;
} }
#endregion
} }
} }

View File

@ -88,9 +88,9 @@ namespace Apimanager_backend.Services
} }
#endregion #endregion
public async Task<UserInfoDto> UpdateUserAsync(UpdateUserDto dto) public async Task<UserInfoDto> UpdateUserAsync(int userId,UpdateUserDto dto)
{ {
var user = await apiContext.Users.FirstOrDefaultAsync(x => x.Id == dto.userId); var user = await apiContext.Users.FirstOrDefaultAsync(x => x.Id == userId);
if (user == null) if (user == null)
{ {
throw new BaseException(2004, "用户不存在"); throw new BaseException(2004, "用户不存在");