diff --git a/Apimanager_backend/Config/MyAutomapper.cs b/Apimanager_backend/Config/MyAutomapper.cs index 159ff8c..aaccdb9 100644 --- a/Apimanager_backend/Config/MyAutomapper.cs +++ b/Apimanager_backend/Config/MyAutomapper.cs @@ -9,6 +9,8 @@ namespace Apimanager_backend.Config public MyAutomapper() { CreateMap(); + CreateMap() + .ForMember(dest => dest.PassHash, opt => opt.MapFrom(src => src.Password)); } } } diff --git a/Apimanager_backend/Controllers/AdminController.cs b/Apimanager_backend/Controllers/AdminController.cs new file mode 100644 index 0000000..577a6ad --- /dev/null +++ b/Apimanager_backend/Controllers/AdminController.cs @@ -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>>> UserList(int pageIndex,int pageSize,bool desc) + { + var users = await adminService.GetUsersAsync(pageIndex,pageSize,desc); + var res = new ResponseBase>( + code:1000, + message:"Success", + data:users + ); + return Ok(res); + } + #endregion + [HttpGet] + [Authorize("Admin")] + public async Task>> UserInfo(int userId) + { + var userInfo = await userService.GetUserAsync(userId); + var res = new ResponseBase( + code: 1000, + message: "Success", + data: userInfo + ); + return Ok(res); + } + } +} diff --git a/Apimanager_backend/Controllers/AuthController.cs b/Apimanager_backend/Controllers/AuthController.cs index a4086d0..cbbca15 100644 --- a/Apimanager_backend/Controllers/AuthController.cs +++ b/Apimanager_backend/Controllers/AuthController.cs @@ -154,7 +154,19 @@ namespace Apimanager_backend.Controllers ); return Ok(res); } - - + + [HttpDelete] + [Authorize(Roles = "User")] + public async Task>> Logout() + { + var userId = User.Claims.First(x => x.ValueType == "userId").Value; + await refreshTokenService.DeleterRefreshTokenAsync(userId); + var res = new ResponseBase( + code:1000, + message:"Success", + data: null + ); + return Ok(res); + } } } diff --git a/Apimanager_backend/Controllers/UserController.cs b/Apimanager_backend/Controllers/UserController.cs index cabdd18..d6ce368 100644 --- a/Apimanager_backend/Controllers/UserController.cs +++ b/Apimanager_backend/Controllers/UserController.cs @@ -74,5 +74,18 @@ namespace Apimanager_backend.Controllers ); return Ok(res); } + [HttpPost] + [Authorize(Roles = "User")] + public async Task>> 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( + code:1000, + message:"Success", + data:userInfo + ); + return Ok(res); + } } } diff --git a/Apimanager_backend/Dtos/AdminUpdateUserDto.cs b/Apimanager_backend/Dtos/AdminUpdateUserDto.cs new file mode 100644 index 0000000..e82b1e7 --- /dev/null +++ b/Apimanager_backend/Dtos/AdminUpdateUserDto.cs @@ -0,0 +1,8 @@ +namespace Apimanager_backend.Dtos +{ + public class AdminUpdateUserDto + { + public string Password { get; set; } + public decimal Balance { get; set; } + } +} diff --git a/Apimanager_backend/Dtos/CreateUserDto.cs b/Apimanager_backend/Dtos/CreateUserDto.cs index 9c8b9d2..95aae53 100644 --- a/Apimanager_backend/Dtos/CreateUserDto.cs +++ b/Apimanager_backend/Dtos/CreateUserDto.cs @@ -1,6 +1,16 @@ -namespace Apimanager_backend.Dtos +using System.ComponentModel.DataAnnotations; + +namespace Apimanager_backend.Dtos { 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; } + } } diff --git a/Apimanager_backend/Dtos/UpdateUserDto.cs b/Apimanager_backend/Dtos/UpdateUserDto.cs index 6029f4f..7f3411d 100644 --- a/Apimanager_backend/Dtos/UpdateUserDto.cs +++ b/Apimanager_backend/Dtos/UpdateUserDto.cs @@ -1,10 +1,10 @@ using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; namespace Apimanager_backend.Dtos { public class UpdateUserDto { - public int? userId { get; set; } public string? password { get; set; } } } diff --git a/Apimanager_backend/Models/User.cs b/Apimanager_backend/Models/User.cs index c3c3eb1..0366bea 100644 --- a/Apimanager_backend/Models/User.cs +++ b/Apimanager_backend/Models/User.cs @@ -35,16 +35,16 @@ namespace Apimanager_backend.Models /// /// 是否禁用 /// - public bool IsBan { get; set; } // boolean + public bool IsBan { get; set; } = false; // boolean /// /// 是否删除 /// - public bool IsDelete { get; set; } // boolean + public bool IsDelete { get; set; } = false; // boolean /// /// 余额 /// - public decimal Balance { get; set; } // Decimal(10) + public decimal Balance { get; set; } = 0; // Decimal(10) /// /// 创建时间,默认当前时间 diff --git a/Apimanager_backend/Services/AdminService.cs b/Apimanager_backend/Services/AdminService.cs new file mode 100644 index 0000000..5cd7898 --- /dev/null +++ b/Apimanager_backend/Services/AdminService.cs @@ -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 logger; + public AdminService(ApiContext context, IMapper mapper, ILogger 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 CreateUserAsync(CreateUserDto dto) + { + //添加用户 + var user = mapper.Map(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(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> 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>(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 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(user); + } + #endregion + } +} diff --git a/Apimanager_backend/Services/AuthService.cs b/Apimanager_backend/Services/AuthService.cs index e1773b0..d4993e2 100644 --- a/Apimanager_backend/Services/AuthService.cs +++ b/Apimanager_backend/Services/AuthService.cs @@ -25,6 +25,7 @@ namespace Apimanager_backend.Services this.redis = redis; this.emailService = emailService; } + #region 用户登录 public async Task LoginAsync(string username, string password) { //查找用户 @@ -46,7 +47,8 @@ namespace Apimanager_backend.Services return mapper.Map(user); } - + #endregion + #region 用户注册 public async Task RegisterAsync(RegisterRequestDto dto) { var db = redis.GetDatabase(DbIndex); @@ -84,7 +86,8 @@ namespace Apimanager_backend.Services } } - + #endregion + #region 发送注册验证码 public async Task SendRegisterCodeAsync(string email) { //生成随机码 @@ -101,5 +104,6 @@ namespace Apimanager_backend.Services //发送邮件 await emailService.SendEmailAsync(email,subject,body); } + #endregion } } diff --git a/Apimanager_backend/Services/IAdminService.cs b/Apimanager_backend/Services/IAdminService.cs index d2c90f6..e19fb34 100644 --- a/Apimanager_backend/Services/IAdminService.cs +++ b/Apimanager_backend/Services/IAdminService.cs @@ -36,5 +36,10 @@ namespace Apimanager_backend.Services /// 用户ID /// 异步操作 Task DeleteUserAsync(int userId); + /// + /// 修改用户信息 + /// + /// + Task UpdateUserAsync(int userId,AdminUpdateUserDto dto); } } diff --git a/Apimanager_backend/Services/IRefreshTokenService.cs b/Apimanager_backend/Services/IRefreshTokenService.cs index 22f7a16..577078e 100644 --- a/Apimanager_backend/Services/IRefreshTokenService.cs +++ b/Apimanager_backend/Services/IRefreshTokenService.cs @@ -23,7 +23,7 @@ /// /// 更新刷新令牌有效期 /// - /// 刷新令牌 + /// 用户id /// 是否成功 Task UpdateRefreshTokenAsync(string userId); } diff --git a/Apimanager_backend/Services/IUserService.cs b/Apimanager_backend/Services/IUserService.cs index 644a04b..7da04dc 100644 --- a/Apimanager_backend/Services/IUserService.cs +++ b/Apimanager_backend/Services/IUserService.cs @@ -34,7 +34,7 @@ namespace Apimanager_backend.Services /// /// 包含更新信息的 /// 更新后的 - Task UpdateUserAsync(UpdateUserDto user); + Task UpdateUserAsync(int userId,UpdateUserDto user); /// /// 检测用户名是否被使用 /// diff --git a/Apimanager_backend/Services/RefreshTokenService.cs b/Apimanager_backend/Services/RefreshTokenService.cs index cef7e9d..ea58d97 100644 --- a/Apimanager_backend/Services/RefreshTokenService.cs +++ b/Apimanager_backend/Services/RefreshTokenService.cs @@ -13,7 +13,7 @@ namespace Apimanager_backend.Services this.redis = redis; this.configuration = configuration; } - + #region 创建刷新令牌 public async Task CreateRefereshTokenAsync(string userId) { var refreshToken = Guid.NewGuid().ToString(); @@ -28,7 +28,8 @@ namespace Apimanager_backend.Services } return refreshToken; } - + #endregion + #region 删除刷新令牌 public async Task DeleterRefreshTokenAsync(string userId) { var db = redis.GetDatabase(DbIndex); @@ -38,7 +39,8 @@ namespace Apimanager_backend.Services throw new BaseException(1006, "Service unavailable"); } } - + #endregion + #region 刷新令牌有效期 public async Task UpdateRefreshTokenAsync(string userId) { var db = redis.GetDatabase(DbIndex); @@ -53,7 +55,8 @@ namespace Apimanager_backend.Services //刷新过期时间 await db.KeyExpireAsync(userId,TimeSpan.FromDays(expiryDays)); } - + #endregion + #region 验证令牌 public async Task ValidateRefreshTokenAsync(string userId,string refreshToken) { var db = redis.GetDatabase(DbIndex); @@ -70,5 +73,6 @@ namespace Apimanager_backend.Services } return true; } + #endregion } } diff --git a/Apimanager_backend/Services/UserService.cs b/Apimanager_backend/Services/UserService.cs index 1f80d9c..76528c1 100644 --- a/Apimanager_backend/Services/UserService.cs +++ b/Apimanager_backend/Services/UserService.cs @@ -88,9 +88,9 @@ namespace Apimanager_backend.Services } #endregion - public async Task UpdateUserAsync(UpdateUserDto dto) + public async Task 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) { throw new BaseException(2004, "用户不存在");