This commit is contained in:
gpu 2026-02-03 02:45:16 +08:00
parent d2ed3380ad
commit 8eaa2ccf3f
2 changed files with 125 additions and 8 deletions

View File

@ -119,6 +119,11 @@ public class AdminConfigService : IAdminConfigService
if (existingConfig != null)
{
// 如果值相同,直接返回成功(无需更新)
if (existingConfig.ConfigValue == jsonValue)
{
return true;
}
// 更新现有配置
existingConfig.ConfigValue = jsonValue;
}

View File

@ -1,3 +1,4 @@
using System.Text.Json;
using HoneyBox.Core.Interfaces;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
@ -13,11 +14,13 @@ namespace HoneyBox.Core.Services;
public class UserService : BaseService<User, int>, IUserService
{
private readonly ILogger<UserService> _logger;
private readonly IConfigService _configService;
public UserService(HoneyBoxDbContext dbContext, ILogger<UserService> logger)
public UserService(HoneyBoxDbContext dbContext, ILogger<UserService> logger, IConfigService configService)
: base(dbContext)
{
_logger = logger;
_configService = configService;
}
/// <inheritdoc/>
@ -59,8 +62,8 @@ public class UserService : BaseService<User, int>, IUserService
if (dto == null)
throw new ArgumentNullException(nameof(dto));
// Generate UID
var uid = GenerateUid();
// Generate UID based on config
var uid = await GenerateUidAsync();
var user = new User
{
@ -273,12 +276,121 @@ public class UserService : BaseService<User, int>, IUserService
/// <summary>
/// Generate a unique UID for new user
/// </summary>
private string GenerateUid()
private async Task<string> GenerateUidAsync()
{
// Generate a numeric UID based on timestamp and random number
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var random = Random.Shared.Next(1000, 9999);
return $"{timestamp}{random}";
// 读取用户配置
var userConfigJson = await _configService.GetConfigValueAsync("user_config");
int uidType = 2; // 默认数字ID
int uidLength = 6; // 默认6位
if (!string.IsNullOrEmpty(userConfigJson))
{
try
{
var userConfig = JsonSerializer.Deserialize<Dictionary<string, string>>(userConfigJson,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (userConfig != null)
{
if (userConfig.TryGetValue("uid_type", out var uidTypeStr) && int.TryParse(uidTypeStr, out var parsedType))
{
uidType = parsedType;
}
if (userConfig.TryGetValue("uid_length", out var uidLengthStr) && int.TryParse(uidLengthStr, out var parsedLength))
{
uidLength = parsedLength;
}
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to parse user_config, using defaults");
}
}
// 根据配置生成UID
string uid;
int maxAttempts = 100;
int attempt = 0;
do
{
uid = uidType switch
{
1 => await GenerateRealIdUidAsync(), // 真实ID基于数据库自增
2 => GenerateNumericUid(uidLength), // 数字ID
3 => GenerateAlphanumericUid(uidLength), // 随机字符和数字
_ => GenerateNumericUid(uidLength)
};
attempt++;
}
while (await UidExistsAsync(uid) && attempt < maxAttempts);
if (attempt >= maxAttempts)
{
// 如果多次尝试都重复,使用时间戳+随机数作为后备方案
uid = $"{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}{Random.Shared.Next(100, 999)}";
}
return uid;
}
/// <summary>
/// 检查UID是否已存在
/// </summary>
private async Task<bool> UidExistsAsync(string uid)
{
return await _dbSet.AnyAsync(u => u.Uid == uid);
}
/// <summary>
/// 生成真实ID类型的UID基于当前最大用户ID
/// </summary>
private async Task<string> GenerateRealIdUidAsync()
{
var maxId = await _dbSet.MaxAsync(u => (int?)u.Id) ?? 0;
return (maxId + 1).ToString();
}
/// <summary>
/// 生成纯数字UID
/// </summary>
private static string GenerateNumericUid(int length)
{
if (length < 4) length = 4;
if (length > 12) length = 12;
// 第一位不能是0
var firstDigit = Random.Shared.Next(1, 10).ToString();
var remainingLength = length - 1;
var remaining = new char[remainingLength];
for (int i = 0; i < remainingLength; i++)
{
remaining[i] = (char)('0' + Random.Shared.Next(0, 10));
}
return firstDigit + new string(remaining);
}
/// <summary>
/// 生成字母数字混合UID
/// </summary>
private static string GenerateAlphanumericUid(int length)
{
if (length < 4) length = 4;
if (length > 16) length = 16;
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var result = new char[length];
for (int i = 0; i < length; i++)
{
result[i] = chars[Random.Shared.Next(chars.Length)];
}
return new string(result);
}
/// <summary>