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
{
///
/// 用户信息转换服务实现
///
public class UserInfoService : IUserInfoService
{
private readonly ICertificationTypesCacheService _cacheService;
private readonly IBaseRepository _userRepository;
private readonly IOptionsSnapshot _appSettingsSnapshot;
public UserInfoService(
ICertificationTypesCacheService cacheService,
IBaseRepository userRepository,
IOptionsSnapshot appSettingsSnapshot)
{
_cacheService = cacheService;
_userRepository = userRepository;
_appSettingsSnapshot = appSettingsSnapshot;
}
///
/// 将 T_Users 转换为 UserInfoDto(自动获取认证类型数据)
///
public async Task 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();
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
};
}
///
/// 批量将 T_Users 列表转换为 UserInfoDto 字典(自动获取认证类型数据)
///
public async Task> ToUserInfoDtoDictionaryAsync(IEnumerable users)
{
var result = new Dictionary();
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;
}
///
/// 根据用户ID获取用户信息
///
/// 用户ID
/// 用户信息DTO,如果用户不存在则返回null
public async Task 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);
}
///
/// 生成唯一的6位数字UID
///
/// 唯一的6位数字UID字符串
public async Task 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;
}
}
}