mirror of
https://github.com/DrizzleTime/Foxel.git
synced 2026-05-31 21:20:52 +08:00
refactor(services): split services into separate folders and update namespaces
This commit is contained in:
139
Services/Configuration/ConfigService.cs
Normal file
139
Services/Configuration/ConfigService.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
using System.Text.Json;
|
||||
using Foxel.Models.DataBase;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace Foxel.Services.Configuration;
|
||||
|
||||
public class ConfigService(
|
||||
IDbContextFactory<MyDbContext> contextFactory,
|
||||
IMemoryCache memoryCache,
|
||||
ILogger<ConfigService> logger)
|
||||
: IConfigService
|
||||
{
|
||||
// 缓存过期时间
|
||||
private readonly TimeSpan _cacheExpiration = TimeSpan.FromMinutes(30);
|
||||
|
||||
public string this[string key] => GetValueAsync(key).GetAwaiter().GetResult() ?? string.Empty;
|
||||
|
||||
public async Task<string?> GetValueAsync(string key)
|
||||
{
|
||||
// 尝试从缓存获取配置值
|
||||
if (memoryCache.TryGetValue($"config:{key}", out string? cachedValue))
|
||||
{
|
||||
return cachedValue;
|
||||
}
|
||||
|
||||
// 如果缓存中没有,从数据库获取
|
||||
await using var context = await contextFactory.CreateDbContextAsync();
|
||||
var config = await context.Configs.FirstOrDefaultAsync(c => c.Key == key);
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
// 尝试从环境变量获取
|
||||
string envVarKey = key.ToUpper().Replace(".", "_").Replace("-", "_");
|
||||
string? envVarValue = Environment.GetEnvironmentVariable(envVarKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(envVarValue))
|
||||
{
|
||||
memoryCache.Set($"config:{key}", envVarValue, _cacheExpiration);
|
||||
return envVarValue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// 将配置值添加到缓存
|
||||
memoryCache.Set($"config:{key}", config.Value, _cacheExpiration);
|
||||
|
||||
return config.Value;
|
||||
}
|
||||
|
||||
public async Task<T?> GetValueAsync<T>(string key, T? defaultValue = default)
|
||||
{
|
||||
var value = await GetValueAsync(key);
|
||||
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return defaultValue;
|
||||
|
||||
try
|
||||
{
|
||||
return JsonSerializer.Deserialize<T>(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "无法将配置值反序列化为所需类型: {Type}", typeof(T).Name);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Config?> GetConfigAsync(string key)
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync();
|
||||
return await context.Configs.FirstOrDefaultAsync(c => c.Key == key);
|
||||
}
|
||||
|
||||
public async Task<List<Config>> GetAllConfigsAsync()
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync();
|
||||
return await context.Configs.OrderBy(c => c.Key).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<Config> SetConfigAsync(string key, string value, string? description = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
throw new ArgumentException("配置键不能为空", nameof(key));
|
||||
|
||||
await using var context = await contextFactory.CreateDbContextAsync();
|
||||
|
||||
var config = await context.Configs.FirstOrDefaultAsync(c => c.Key == key);
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
// 创建新配置
|
||||
config = new Config
|
||||
{
|
||||
Key = key,
|
||||
Value = value,
|
||||
Description = description ?? string.Empty,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
UpdatedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
context.Configs.Add(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 更新现有配置
|
||||
config.Value = value;
|
||||
if (description != null)
|
||||
{
|
||||
config.Description = description;
|
||||
}
|
||||
config.UpdatedAt = DateTime.UtcNow;
|
||||
}
|
||||
await context.SaveChangesAsync();
|
||||
memoryCache.Set($"config:{key}", value, _cacheExpiration);
|
||||
return config;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteConfigAsync(string key)
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync();
|
||||
|
||||
var config = await context.Configs.FirstOrDefaultAsync(c => c.Key == key);
|
||||
if (config == null)
|
||||
return false;
|
||||
|
||||
context.Configs.Remove(config);
|
||||
await context.SaveChangesAsync();
|
||||
memoryCache.Remove($"config:{key}");
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> ExistsAsync(string key)
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync();
|
||||
return await context.Configs.AnyAsync(c => c.Key == key);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user