130 lines
5.2 KiB
C#
130 lines
5.2 KiB
C#
using AutoMapper;
|
||
using IM_API.Dtos.User;
|
||
using IM_API.Exceptions;
|
||
using IM_API.Interface.Services;
|
||
using IM_API.Models;
|
||
using IM_API.Tools;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using StackExchange.Redis;
|
||
using System.Text.Json;
|
||
|
||
namespace IM_API.Services
|
||
{
|
||
public class UserService : IUserService
|
||
{
|
||
private readonly ImContext _context;
|
||
private readonly ILogger<UserService> _logger;
|
||
private readonly IMapper _mapper;
|
||
private readonly ICacheService _cacheService;
|
||
private readonly IDatabase _redis;
|
||
public UserService(
|
||
ImContext imContext,ILogger<UserService> logger,
|
||
IMapper mapper, ICacheService cacheService, IConnectionMultiplexer connectionMultiplexer)
|
||
{
|
||
this._context = imContext;
|
||
this._logger = logger;
|
||
this._mapper = mapper;
|
||
_cacheService = cacheService;
|
||
_redis = connectionMultiplexer.GetDatabase();
|
||
}
|
||
#region 获取用户信息
|
||
public async Task<UserInfoDto> GetUserInfoAsync(int userId)
|
||
{
|
||
//查询redis缓存,如果存在直接返回不走查库逻辑
|
||
var key = RedisKeys.GetUserinfoKey(userId.ToString());
|
||
var userinfoCache = await _cacheService.GetAsync<User>(key);
|
||
if (userinfoCache != null) return _mapper.Map<UserInfoDto>(userinfoCache);
|
||
//无缓存查库
|
||
var user = await _context.Users
|
||
.FirstOrDefaultAsync(x => x.Id == userId);
|
||
if (user == null)
|
||
{
|
||
throw new BaseException(CodeDefine.USER_NOT_FOUND);
|
||
}
|
||
await _cacheService.SetUserCacheAsync(user);
|
||
return _mapper.Map<UserInfoDto>(user);
|
||
}
|
||
#endregion
|
||
#region 通过用户名获取用户信息
|
||
public async Task<UserInfoDto> GetUserInfoByUsernameAsync(string username)
|
||
{
|
||
var userinfo = await _cacheService.GetUserCacheAsync(username);
|
||
if (userinfo != null) return _mapper.Map<UserInfoDto>(userinfo);
|
||
var user = await _context.Users.FirstOrDefaultAsync(x => x.Username == username);
|
||
if (user == null)
|
||
{
|
||
throw new BaseException(CodeDefine.USER_NOT_FOUND);
|
||
}
|
||
await _cacheService.SetUserCacheAsync(user);
|
||
return _mapper.Map<UserInfoDto>(user);
|
||
}
|
||
#endregion
|
||
#region 重置用户密码
|
||
public async Task<bool> ResetPasswordAsync(int userId, string oldPassword, string password)
|
||
{
|
||
var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == userId);
|
||
if (user is null) throw new BaseException(CodeDefine.USER_NOT_FOUND);
|
||
//验证原密码
|
||
if (user.Password != oldPassword) throw new BaseException(CodeDefine.PASSWORD_ERROR);
|
||
user.Password = password;
|
||
await _context.SaveChangesAsync();
|
||
return true;
|
||
}
|
||
#endregion
|
||
#region 更新用户在线状态
|
||
public async Task<bool> UpdateOlineStatusAsync(int userId,UserOnlineStatus onlineStatus)
|
||
{
|
||
var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == userId);
|
||
if (user is null) throw new BaseException(CodeDefine.USER_NOT_FOUND);
|
||
user.OnlineStatusEnum = onlineStatus;
|
||
await _context.SaveChangesAsync();
|
||
return true;
|
||
}
|
||
#endregion
|
||
#region 更新用户信息
|
||
public async Task<UserInfoDto> UpdateUserAsync(int userId,UpdateUserDto dto)
|
||
{
|
||
var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == userId);
|
||
if (user is null) throw new BaseException(CodeDefine.USER_NOT_FOUND);
|
||
_mapper.Map(dto,user);
|
||
await _context.SaveChangesAsync();
|
||
await _cacheService.SetUserCacheAsync(user);
|
||
return _mapper.Map<UserInfoDto>(user);
|
||
}
|
||
#endregion
|
||
#region 批量获取用户信息
|
||
public async Task<List<UserInfoDto>> GetUserInfoListAsync(List<int> ids)
|
||
{
|
||
//读取缓存中存在的用户,存在直接添加到结果列表
|
||
var idKeyArr = ids.Select(s => (RedisKey)RedisKeys.GetUserinfoKey(s.ToString())).ToArray();
|
||
var values = await _redis.StringGetAsync(idKeyArr);
|
||
List<User> results = [];
|
||
List<int> missingIds = [];
|
||
for(int i = 0; i < ids.Count; i++)
|
||
{
|
||
if (values[i].HasValue)
|
||
{
|
||
results.Add(JsonSerializer.Deserialize<User>(values[i]));
|
||
}
|
||
else
|
||
{
|
||
missingIds.Add(ids[i]);
|
||
}
|
||
}
|
||
//如果存在没有缓存的用户则进行查库
|
||
if (missingIds.Any())
|
||
{
|
||
var dbUsers = await _context.Users
|
||
.Where(x => ids.Contains(x.Id)).ToListAsync();
|
||
|
||
results.AddRange(dbUsers);
|
||
|
||
var setTasks = dbUsers.Select(s => _cacheService.SetUserCacheAsync(s)).ToList();
|
||
await Task.WhenAll(setTasks);
|
||
}
|
||
return _mapper.Map<List<UserInfoDto>>(results);
|
||
}
|
||
#endregion
|
||
}
|
||
}
|