using System.Security.Cryptography;
using MySqlConnector;
namespace Rmsys.Infrastructure;
///
/// 系统配置读写(直连 MySQL,不依赖 EF)。
/// 为什么不用 EF:JWT 签名密钥必须在 AddAuthentication 之前就拿到,
/// 那时 DI 容器还没建好,只能用原始连接读。
/// 表不存在或库连不上时返回 null,由调用方回退到配置文件 —— 不让启动直接崩。
///
public static class SysConfigStore
{
public static string? Get(string connStr, string key)
{
try
{
using var c = new MySqlConnection(connStr);
c.Open();
using var cmd = c.CreateCommand();
cmd.CommandText = "select ConfigValue from sysconfigs where ConfigKey=@k limit 1";
cmd.Parameters.AddWithValue("@k", key);
var v = cmd.ExecuteScalar();
return v == null || v is DBNull ? null : Convert.ToString(v);
}
catch
{
return null; // 表未建 / 库不可达 → 回退
}
}
public static bool Set(string connStr, string key, string value, string remark, string? by = null)
{
try
{
using var c = new MySqlConnection(connStr);
c.Open();
using var cmd = c.CreateCommand();
cmd.CommandText = @"
insert into sysconfigs(ConfigKey,ConfigValue,Remark,IsSecret,UpdatedAt,UpdatedBy)
values(@k,@v,@r,1,@t,@by)
on duplicate key update ConfigValue=@v, Remark=@r, UpdatedAt=@t, UpdatedBy=@by";
cmd.Parameters.AddWithValue("@k", key);
cmd.Parameters.AddWithValue("@v", value);
cmd.Parameters.AddWithValue("@r", remark);
cmd.Parameters.AddWithValue("@t", DateTime.Now);
cmd.Parameters.AddWithValue("@by", (object?)by ?? DBNull.Value);
return cmd.ExecuteNonQuery() > 0;
}
catch
{
return false;
}
}
/// 存在就取,不存在就生成并写入;库不可用时返回 null
public static string? GetOrCreate(string connStr, string key, Func factory, string remark)
{
var v = Get(connStr, key);
if (!string.IsNullOrWhiteSpace(v)) return v;
var created = factory();
return Set(connStr, key, created, remark) ? created : null;
}
/// 生成 48 字节随机密钥(base64 后 64 字符,够 HMAC-SHA256 用)
public static string NewSecret() => Convert.ToBase64String(RandomNumberGenerator.GetBytes(48));
}