Files
emall-api/FutureMailAPI/Services/UserService.cs
2025-10-16 15:21:52 +08:00

294 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.EntityFrameworkCore;
using FutureMailAPI.Data;
using FutureMailAPI.Models;
using FutureMailAPI.DTOs;
using FutureMailAPI.Helpers;
namespace FutureMailAPI.Services
{
public interface IUserService
{
Task<ApiResponse<UserResponseDto>> RegisterAsync(UserRegisterDto registerDto);
Task<ApiResponse<AuthResponseDto>> LoginAsync(UserLoginDto loginDto);
Task<ApiResponse<UserResponseDto>> GetUserByIdAsync(int userId);
Task<ApiResponse<UserResponseDto>> GetUserByUsernameAsync(string username);
Task<ApiResponse<UserResponseDto>> GetUserByEmailAsync(string email);
Task<ApiResponse<UserResponseDto>> GetUserByUsernameOrEmailAsync(string usernameOrEmail);
Task<ApiResponse<UserResponseDto>> UpdateUserAsync(int userId, UserUpdateDto updateDto);
Task<ApiResponse<bool>> ChangePasswordAsync(int userId, ChangePasswordDto changePasswordDto);
Task<ApiResponse<UserResponseDto>> CreateUserAsync(UserRegisterDto registerDto);
}
public class UserService : IUserService
{
private readonly FutureMailDbContext _context;
private readonly IPasswordHelper _passwordHelper;
public UserService(FutureMailDbContext context, IPasswordHelper passwordHelper)
{
_context = context;
_passwordHelper = passwordHelper;
}
public async Task<ApiResponse<UserResponseDto>> RegisterAsync(UserRegisterDto registerDto)
{
// 检查用户名是否已存在
var existingUserByUsername = await _context.Users
.FirstOrDefaultAsync(u => u.Username == registerDto.Username);
if (existingUserByUsername != null)
{
return ApiResponse<UserResponseDto>.ErrorResult("用户名已存在");
}
// 检查邮箱是否已存在
var existingUserByEmail = await _context.Users
.FirstOrDefaultAsync(u => u.Email == registerDto.Email);
if (existingUserByEmail != null)
{
return ApiResponse<UserResponseDto>.ErrorResult("邮箱已被注册");
}
// 生成盐值
var salt = _passwordHelper.GenerateSalt();
// 创建新用户(使用正确的密码哈希方法)
var user = new User
{
Username = registerDto.Username,
Email = registerDto.Email,
PasswordHash = _passwordHelper.HashPassword(registerDto.Password, salt),
Salt = salt,
Nickname = registerDto.Nickname ?? registerDto.Username,
CreatedAt = DateTime.UtcNow
};
_context.Users.Add(user);
await _context.SaveChangesAsync();
var userDto = MapToUserResponseDto(user);
return ApiResponse<UserResponseDto>.SuccessResult(userDto, "注册成功");
}
public async Task<ApiResponse<AuthResponseDto>> LoginAsync(UserLoginDto loginDto)
{
// 查找用户(通过用户名或邮箱)
User? user;
if (loginDto.UsernameOrEmail.Contains("@"))
{
user = await _context.Users
.FirstOrDefaultAsync(u => u.Email == loginDto.UsernameOrEmail);
}
else
{
user = await _context.Users
.FirstOrDefaultAsync(u => u.Username == loginDto.UsernameOrEmail);
}
if (user == null)
{
return ApiResponse<AuthResponseDto>.ErrorResult("用户名或密码错误");
}
// 验证密码
if (!_passwordHelper.VerifyPassword(loginDto.Password, user.PasswordHash, user.Salt))
{
return ApiResponse<AuthResponseDto>.ErrorResult("用户名或密码错误");
}
// 更新最后登录时间
user.LastLoginAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
// 创建认证响应无token版本
var authResponse = new AuthResponseDto
{
User = MapToUserResponseDto(user)
};
return ApiResponse<AuthResponseDto>.SuccessResult(authResponse, "登录成功");
}
public async Task<ApiResponse<UserResponseDto>> GetUserByIdAsync(int userId)
{
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Id == userId);
if (user == null)
{
return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
}
var userDto = MapToUserResponseDto(user);
return ApiResponse<UserResponseDto>.SuccessResult(userDto);
}
public async Task<ApiResponse<UserResponseDto>> GetUserByUsernameAsync(string username)
{
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Username == username);
if (user == null)
{
return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
}
var userDto = MapToUserResponseDto(user);
return ApiResponse<UserResponseDto>.SuccessResult(userDto);
}
public async Task<ApiResponse<UserResponseDto>> GetUserByEmailAsync(string email)
{
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Email == email);
if (user == null)
{
return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
}
var userDto = MapToUserResponseDto(user);
return ApiResponse<UserResponseDto>.SuccessResult(userDto);
}
public async Task<ApiResponse<UserResponseDto>> GetUserByUsernameOrEmailAsync(string usernameOrEmail)
{
User? user;
if (usernameOrEmail.Contains("@"))
{
user = await _context.Users
.FirstOrDefaultAsync(u => u.Email == usernameOrEmail);
}
else
{
user = await _context.Users
.FirstOrDefaultAsync(u => u.Username == usernameOrEmail);
}
if (user == null)
{
return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
}
var userDto = MapToUserResponseDto(user);
return ApiResponse<UserResponseDto>.SuccessResult(userDto);
}
public async Task<ApiResponse<UserResponseDto>> UpdateUserAsync(int userId, UserUpdateDto updateDto)
{
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Id == userId);
if (user == null)
{
return ApiResponse<UserResponseDto>.ErrorResult("用户不存在");
}
// 更新用户信息
if (updateDto.Nickname != null)
{
user.Nickname = updateDto.Nickname;
}
if (updateDto.Avatar != null)
{
user.Avatar = updateDto.Avatar;
}
await _context.SaveChangesAsync();
var userDto = MapToUserResponseDto(user);
return ApiResponse<UserResponseDto>.SuccessResult(userDto, "更新成功");
}
public async Task<ApiResponse<bool>> ChangePasswordAsync(int userId, ChangePasswordDto changePasswordDto)
{
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Id == userId);
if (user == null)
{
return ApiResponse<bool>.ErrorResult("用户不存在");
}
// 验证当前密码
if (!_passwordHelper.VerifyPassword(changePasswordDto.CurrentPassword, user.PasswordHash, user.Salt))
{
return ApiResponse<bool>.ErrorResult("当前密码错误");
}
// 更新密码
var salt = _passwordHelper.GenerateSalt();
user.PasswordHash = _passwordHelper.HashPassword(changePasswordDto.NewPassword, salt);
user.Salt = salt;
await _context.SaveChangesAsync();
return ApiResponse<bool>.SuccessResult(true, "密码修改成功");
}
public async Task<ApiResponse<UserResponseDto>> CreateUserAsync(UserRegisterDto registerDto)
{
// 检查用户名是否已存在
var existingUserByUsername = await _context.Users
.FirstOrDefaultAsync(u => u.Username == registerDto.Username);
if (existingUserByUsername != null)
{
return ApiResponse<UserResponseDto>.ErrorResult("用户名已存在");
}
// 检查邮箱是否已存在
var existingUserByEmail = await _context.Users
.FirstOrDefaultAsync(u => u.Email == registerDto.Email);
if (existingUserByEmail != null)
{
return ApiResponse<UserResponseDto>.ErrorResult("邮箱已被注册");
}
// 生成盐值
var salt = _passwordHelper.GenerateSalt();
// 创建新用户(使用正确的密码哈希方法)
var user = new User
{
Username = registerDto.Username,
Email = registerDto.Email,
PasswordHash = _passwordHelper.HashPassword(registerDto.Password, salt),
Salt = salt,
Nickname = registerDto.Nickname ?? registerDto.Username,
CreatedAt = DateTime.UtcNow
};
_context.Users.Add(user);
await _context.SaveChangesAsync();
var userDto = MapToUserResponseDto(user);
return ApiResponse<UserResponseDto>.SuccessResult(userDto, "用户创建成功");
}
private static UserResponseDto MapToUserResponseDto(User user)
{
return new UserResponseDto
{
Id = user.Id,
Username = user.Username,
Email = user.Email,
Nickname = user.Nickname,
Avatar = user.Avatar,
CreatedAt = user.CreatedAt,
LastLoginAt = user.LastLoginAt
};
}
}
}