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 _logger; private readonly IMapper _mapper; private readonly ICacheService _cacheService; private readonly IDatabase _redis; public UserService( ImContext imContext,ILogger 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 GetUserInfoAsync(int userId) { //查询redis缓存,如果存在直接返回不走查库逻辑 var key = RedisKeys.GetUserinfoKey(userId.ToString()); var userinfoCache = await _cacheService.GetAsync(key); if (userinfoCache != null) return _mapper.Map(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(user); } #endregion #region 通过用户名获取用户信息 public async Task GetUserInfoByUsernameAsync(string username) { var userinfo = await _cacheService.GetUserCacheAsync(username); if (userinfo != null) return _mapper.Map(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(user); } #endregion #region 重置用户密码 public async Task 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 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 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(user); } #endregion #region 批量获取用户信息 public async Task> GetUserInfoListAsync(List ids) { //读取缓存中存在的用户,存在直接添加到结果列表 var idKeyArr = ids.Select(s => (RedisKey)RedisKeys.GetUserinfoKey(s.ToString())).ToArray(); var values = await _redis.StringGetAsync(idKeyArr); List results = []; List missingIds = []; for(int i = 0; i < ids.Count; i++) { if (values[i].HasValue) { results.Add(JsonSerializer.Deserialize(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>(results); } #endregion } }