IM/backend/IM_API/Services/UserService.cs
2026-02-08 18:43:20 +08:00

130 lines
5.2 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 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
}
}