✨
This commit is contained in:
284
StopShopping.Services/Implementions/UserService.cs
Normal file
284
StopShopping.Services/Implementions/UserService.cs
Normal file
@@ -0,0 +1,284 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StopShopping.EF;
|
||||
using StopShopping.Services.Extensions;
|
||||
using StopShopping.Services.Models;
|
||||
using StopShopping.Services.Models.Req;
|
||||
using StopShopping.Services.Models.Resp;
|
||||
|
||||
namespace StopShopping.Services.Implementions;
|
||||
|
||||
public class UserService : IUserService
|
||||
{
|
||||
public UserService(
|
||||
ILogger<UserService> logger,
|
||||
StopShoppingContext dbContext,
|
||||
ICipherService cipherService,
|
||||
IAccessTokenService accessTokenService,
|
||||
IClaimsService claimsService,
|
||||
IFileService fileService,
|
||||
ISerialNoGenerator serialNoGenerator)
|
||||
{
|
||||
_logger = logger;
|
||||
_dbContext = dbContext;
|
||||
_cipherService = cipherService;
|
||||
_accessTokenService = accessTokenService;
|
||||
_claimsService = claimsService;
|
||||
_fileService = fileService;
|
||||
_serialNoGenerator = serialNoGenerator;
|
||||
}
|
||||
|
||||
private readonly ILogger<UserService> _logger;
|
||||
private readonly StopShoppingContext _dbContext;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IAccessTokenService _accessTokenService;
|
||||
private readonly IClaimsService _claimsService;
|
||||
private readonly IFileService _fileService;
|
||||
private readonly ISerialNoGenerator _serialNoGenerator;
|
||||
|
||||
public async Task<ApiResponse> SignUpAsync(SignUpParams model)
|
||||
{
|
||||
var user = await _dbContext.Users.FirstOrDefaultAsync(u => u.Account == model.Account);
|
||||
if (null != user)
|
||||
return ApiResponse.Failed("帐户名已存在");
|
||||
|
||||
user = new EF.Models.User
|
||||
{
|
||||
Account = model.Account!,
|
||||
Addresses = [],
|
||||
Avatar = Consts.DEFAULT_AVATAR,
|
||||
CurrentRole = model.DefaultRole.GetValue(),
|
||||
NickName = model.NickName!,
|
||||
Password = _cipherService.EncryptUserPassword(model.Password!)
|
||||
};
|
||||
|
||||
await _dbContext.AddAsync(user);
|
||||
if (await _dbContext.SaveChangesAsync() > 0)
|
||||
return ApiResponse.Succed();
|
||||
|
||||
return ApiResponse.Failed("数据库操作失败");
|
||||
}
|
||||
|
||||
public async Task<SignInResult<SignInUser>> SignInAsync(SignInParams model)
|
||||
{
|
||||
SignInResult<SignInUser> result = new();
|
||||
|
||||
var user = await _dbContext.Users
|
||||
.FirstOrDefaultAsync(u => u.Account == model.Account);
|
||||
if (null == user || user.Password != _cipherService.EncryptUserPassword(model.Password!))
|
||||
{
|
||||
result.IsSucced = false;
|
||||
result.Message = "账号或密码错误";
|
||||
|
||||
return result;
|
||||
}
|
||||
user.LastLoginTime = DateTime.Now;
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
var claimsIdentity = _claimsService.BuildIdentity(user);
|
||||
|
||||
result.RefreshToken = await _accessTokenService.SetRefreshTokenAsync(user.Id, SystemRoles.User);
|
||||
|
||||
result.User = new SignInUser
|
||||
{
|
||||
AvatarUrl = string.IsNullOrWhiteSpace(user.Avatar)
|
||||
? null
|
||||
: _fileService.GetFileUrl(UploadScences.Avatar, user.Avatar),
|
||||
NickName = user.NickName,
|
||||
DefaultRole = user.CurrentRole.ToUserRoles(),
|
||||
AccessToken = _accessTokenService.GenerateAccessToken(claimsIdentity)
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<SignInResult<SignInAdmin>> SignInAdminAsync(SignInParams model)
|
||||
{
|
||||
SignInResult<SignInAdmin> result = new();
|
||||
|
||||
var admin = await _dbContext.Administrators
|
||||
.FirstOrDefaultAsync(u => u.Account == model.Account);
|
||||
if (null == admin || admin.Password != _cipherService.EncryptUserPassword(model.Password!))
|
||||
{
|
||||
result.IsSucced = false;
|
||||
result.Message = "账号或密码错误";
|
||||
|
||||
return result;
|
||||
}
|
||||
admin.LastLoginTime = DateTime.Now;
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
var claimsIdentity = _claimsService.BuildAdminIdentity(admin);
|
||||
|
||||
result.RefreshToken = await _accessTokenService.SetRefreshTokenAsync(admin.Id, SystemRoles.Admin);
|
||||
|
||||
result.User = new SignInAdmin
|
||||
{
|
||||
NickName = admin.NickName,
|
||||
AccessToken = _accessTokenService.GenerateAccessToken(claimsIdentity)
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task GenerateDefaultAdminAsync()
|
||||
{
|
||||
var defaultAdmin = await _dbContext.Administrators
|
||||
.Where(a => a.Account == Consts.DEFAULT_ADMIN_ACCOUNT)
|
||||
.FirstOrDefaultAsync();
|
||||
if (null != defaultAdmin)
|
||||
{
|
||||
_logger.LogInformation("默认管理员已存在,已跳过");
|
||||
return;
|
||||
}
|
||||
|
||||
var pwd = _serialNoGenerator.GenerateRandomPassword();
|
||||
defaultAdmin = new()
|
||||
{
|
||||
Account = Consts.DEFAULT_ADMIN_ACCOUNT,
|
||||
NickName = "超级管理员",
|
||||
Password = _cipherService.EncryptUserPassword(pwd)
|
||||
};
|
||||
await _dbContext.Administrators.AddAsync(defaultAdmin);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
_logger.LogInformation(
|
||||
"默认管理员({Account})已生成,请立马修改密码:{Password}",
|
||||
Consts.DEFAULT_ADMIN_ACCOUNT,
|
||||
pwd);
|
||||
}
|
||||
|
||||
public async Task<ApiResponse> ChangePasswordAsync(ChangePasswordParams model)
|
||||
{
|
||||
int userId = _claimsService.GetCurrentUserId();
|
||||
var user = await _dbContext.Users
|
||||
.FirstAsync(u => u.Id == userId);
|
||||
|
||||
if (_cipherService.EncryptUserPassword(model.OldPassword!) != user.Password)
|
||||
return ApiResponse.Failed("原密码错误");
|
||||
|
||||
user.Password = _cipherService.EncryptUserPassword(model.NewPassword!);
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return ApiResponse.Succed();
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<User>> GetUserInfoAsync()
|
||||
{
|
||||
var userId = _claimsService.GetCurrentUserId();
|
||||
var model = await _dbContext.Users
|
||||
.FirstAsync(u => u.Id == userId);
|
||||
|
||||
User user = new()
|
||||
{
|
||||
Account = model.Account,
|
||||
AvatarUrl = string.IsNullOrWhiteSpace(model.Avatar)
|
||||
? null
|
||||
: _fileService.GetFileUrl(UploadScences.Avatar, model.Avatar),
|
||||
DefaultRole = model.CurrentRole.ToUserRoles(),
|
||||
LastLoginTime = model.LastLoginTime?.ToFormatted(),
|
||||
NickName = model.NickName,
|
||||
Telephone = model.Telephone
|
||||
};
|
||||
|
||||
return new ApiResponse<User>(user);
|
||||
}
|
||||
|
||||
public async Task<ApiResponse> EditAsync(EditUserParams model)
|
||||
{
|
||||
int userId = _claimsService.GetCurrentUserId();
|
||||
var user = await _dbContext.Users.FirstAsync(u => u.Id == userId);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.AvatarFileName))
|
||||
user.Avatar = model.AvatarFileName;
|
||||
user.CurrentRole = model.DefaultRole.GetValue();
|
||||
if (!string.IsNullOrWhiteSpace(model.NickName))
|
||||
user.NickName = model.NickName;
|
||||
if (!string.IsNullOrWhiteSpace(model.Telephone))
|
||||
user.Telephone = model.Telephone;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return ApiResponse.Succed();
|
||||
}
|
||||
|
||||
public ApiResponse<List<Address>> GetAddresses()
|
||||
{
|
||||
var userId = _claimsService.GetCurrentUserId();
|
||||
|
||||
var addresses = _dbContext.Addresses
|
||||
.Where(a => a.UserId == userId)
|
||||
.OrderByDescending(a => a.Default)
|
||||
.AsNoTracking()
|
||||
.Select(Cast)
|
||||
.ToList();
|
||||
|
||||
return new ApiResponse<List<Address>>(addresses);
|
||||
}
|
||||
|
||||
public async Task<ApiResponse> EditAddressAsync(EditAddressParams model)
|
||||
{
|
||||
EF.Models.Address? address = null;
|
||||
|
||||
var userId = _claimsService.GetCurrentUserId();
|
||||
|
||||
if (model.Id.HasValue && model.Id > 0)
|
||||
{
|
||||
address = await _dbContext.Addresses
|
||||
.FirstOrDefaultAsync(a => a.Id == model.Id && a.UserId == userId);
|
||||
if (null == address)
|
||||
return ApiResponse.Failed("地址已不存在");
|
||||
}
|
||||
else
|
||||
{
|
||||
address = new();
|
||||
await _dbContext.Addresses.AddAsync(address);
|
||||
}
|
||||
|
||||
address.Default = model.Default;
|
||||
address.Detail = model.Detail;
|
||||
address.DistrictLevel1Id = model.DistrictLevel1Id;
|
||||
address.DistrictLevel2Id = model.DistrictLevel2Id;
|
||||
address.DistrictLevel3Id = model.DistrictLevel3Id;
|
||||
address.DistrictLevel4Id = model.DistrictLevel4Id;
|
||||
address.Name = model.Name;
|
||||
address.Tag = model.Tag;
|
||||
address.Telephone = model.Telephone;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return ApiResponse.Succed();
|
||||
}
|
||||
|
||||
public async Task<ApiResponse> DeleteAddressAsync(int id)
|
||||
{
|
||||
var userId = _claimsService.GetCurrentUserId();
|
||||
await _dbContext.Addresses
|
||||
.Where(a => a.Id == id && a.UserId == userId)
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
return ApiResponse.Succed();
|
||||
}
|
||||
|
||||
#region private methods
|
||||
|
||||
private Address Cast(EF.Models.Address a)
|
||||
{
|
||||
return new Address
|
||||
{
|
||||
Default = a.Default,
|
||||
Detail = a.Detail,
|
||||
DistrictLevel1Id = a.DistrictLevel1Id,
|
||||
DistrictLevel2Id = a.DistrictLevel2Id,
|
||||
DistrictLevel3Id = a.DistrictLevel3Id,
|
||||
DistrictLevel4Id = a.DistrictLevel4Id,
|
||||
Id = a.Id,
|
||||
Name = a.Name,
|
||||
Tag = a.Tag,
|
||||
Telephone = a.Telephone
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user