live-forum/server/webapi/LiveForum/LiveForum.Service/Users/UserInfoService.cs
2026-03-24 11:27:37 +08:00

198 lines
6.9 KiB
C#
Raw Permalink 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 FreeSql;
using LiveForum.IService.Others;
using LiveForum.IService.Users;
using LiveForum.Model;
using LiveForum.Model.Dto.Others;
using LiveForum.Model.Dto.Users;
using Mapster;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace LiveForum.Service.Users
{
/// <summary>
/// 用户信息转换服务实现
/// </summary>
public class UserInfoService : IUserInfoService
{
private readonly ICertificationTypesCacheService _cacheService;
private readonly IBaseRepository<T_Users> _userRepository;
private readonly IOptionsSnapshot<AppSettings> _appSettingsSnapshot;
public UserInfoService(
ICertificationTypesCacheService cacheService,
IBaseRepository<T_Users> userRepository,
IOptionsSnapshot<AppSettings> appSettingsSnapshot)
{
_cacheService = cacheService;
_userRepository = userRepository;
_appSettingsSnapshot = appSettingsSnapshot;
}
/// <summary>
/// 将 T_Users 转换为 UserInfoDto自动获取认证类型数据
/// </summary>
public async Task<UserInfoDto> ToUserInfoDtoAsync(T_Users user)
{
if (user == null)
{
return null;
}
var certificationTypesDict = await _cacheService.GetAllCertificationTypesDictionaryAsync();
// 获取默认头像(如果用户头像为空)
var avatar = user.Avatar ?? "";
if (string.IsNullOrEmpty(avatar))
{
var appSettings = _appSettingsSnapshot.Value;
avatar = string.IsNullOrEmpty(appSettings.UserDefaultIcon)
? ""
: appSettings.UserDefaultIcon;
}
//user.Adapt<UserInfoDto>();
return new UserInfoDto
{
UserId = user.Id,
NickName = user.NickName ?? "",
Avatar = avatar,
IsVip = user.IsVip,
CertifiedStatus=user.CertifiedStatus,
IsCertified = user.IsCertified,
CertifiedType = user.CertifiedType.HasValue && user.CertifiedType.Value > 0
? certificationTypesDict.GetValueOrDefault(user.CertifiedType.Value)
: null
};
}
/// <summary>
/// 批量将 T_Users 列表转换为 UserInfoDto 字典(自动获取认证类型数据)
/// </summary>
public async Task<Dictionary<long, UserInfoDto>> ToUserInfoDtoDictionaryAsync(IEnumerable<T_Users> users)
{
var result = new Dictionary<long, UserInfoDto>();
if (users == null)
{
return result;
}
// 一次性获取所有认证类型数据
var certificationTypesDict = await _cacheService.GetAllCertificationTypesDictionaryAsync();
// 获取默认头像配置(一次性获取,避免重复调用)
var appSettings = _appSettingsSnapshot.Value;
var defaultAvatar = string.IsNullOrEmpty(appSettings.UserDefaultIcon)
? ""
: appSettings.UserDefaultIcon;
foreach (var user in users)
{
if (user == null)
{
continue;
}
// 获取用户头像,如果为空则使用默认头像
var avatar = user.Avatar ?? "";
if (string.IsNullOrEmpty(avatar))
{
avatar = defaultAvatar;
}
var dto = new UserInfoDto
{
UserId = user.Id,
NickName = user.NickName ?? "",
Avatar = avatar,
IsVip = user.IsVip,
CertifiedStatus = user.CertifiedStatus,
IsCertified = user.IsCertified,
CertifiedType = user.CertifiedType.HasValue && user.CertifiedType.Value > 0
? certificationTypesDict.GetValueOrDefault(user.CertifiedType.Value)
: null
};
result[user.Id] = dto;
}
return result;
}
/// <summary>
/// 根据用户ID获取用户信息
/// </summary>
/// <param name="userId">用户ID</param>
/// <returns>用户信息DTO如果用户不存在则返回null</returns>
public async Task<UserInfoDto> GetUserInfo(long userId)
{
// 1. 根据用户ID查询用户
var user = await _userRepository.Select
.Where(x => x.Id == userId)
.FirstAsync();
// 2. 如果用户不存在返回null
if (user == null)
{
return null;
}
// 3. 使用已有的转换方法转换为DTO
return await ToUserInfoDtoAsync(user);
}
/// <summary>
/// 生成唯一的6位数字UID
/// </summary>
/// <returns>唯一的6位数字UID字符串</returns>
public async Task<string> GenerateUniqueUIDAsync()
{
const int maxRetries = 10; // 最大重试次数,避免无限循环
var random = new Random();
for (int i = 0; i < maxRetries; i++)
{
// 生成6位随机数100000-999999
string uid = random.Next(100000, 1000000).ToString();
// 检查数据库中是否已存在该UID
var exists = await _userRepository.Select
.Where(x => x.UID == uid)
.AnyAsync();
if (!exists)
{
return uid;
}
}
// 如果重试多次仍然冲突,使用时间戳+随机数组合
// 格式后6位时间戳的毫秒部分 + 2位随机数取最后6位
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
var fallbackUid = (timestamp.Substring(Math.Max(0, timestamp.Length - 4)) + random.Next(10, 100)).PadLeft(6, '0');
// 再次检查是否冲突
var stillExists = await _userRepository.Select
.Where(x => x.UID == fallbackUid)
.AnyAsync();
if (stillExists)
{
// 最后备用方案使用GUID的前6位数字
var guidHash = Math.Abs(Guid.NewGuid().GetHashCode()).ToString();
return guidHash.Substring(0, Math.Min(6, guidHash.Length)).PadLeft(6, '0');
}
return fallbackUid;
}
}
}