using System;
using System.Configuration;
namespace ivf_tl_Operate.Helpers
{
///
/// M5-01-2 / M5-02:统一配置读写封装(operate 单一数据源 App.config 的集中接管点)。
/// - 强类型容错读取(缺键返回默认值而非 NPE,缓解 R8"改一处漏一处起不来")。
/// - 加密项读写经 (passWord / engineerPwd 等本机凭据)。
/// - :启动一次性明文→密文迁移(幂等)。
/// 分层标注([D8] 待确认):
/// 本地层:urlIp/urlPort/mqttIp/mqttPort/kfkaIP/kfkaPort/cacheDisk/Language/outInter/tlNum/houseEnabled/userName/passWord(加密)/engineerPwd(加密)
/// 数据库层(TLSetting,不在此封装):autoFocusTime/videoFps/cropNum/heapDate/keepDate/cleanSurfaceData
/// 暂留本地、待 D8 定归属:csTime/gbTime/VentNum/... 换气/CCD 类业务键
/// [M7] 容错与迁移随合并进程运行验证(本地不可构建/运行)。
///
public static class AppConfigHelper
{
/// 工程师口令的 config 键(M5-02-3 治理 tl13579)。
public const string EngineerPwdKey = "engineerPwd";
/// 工程师口令缺省值(首次无值回退;迁移时加密回写)。
public const string DefaultEngineerPwd = "tl13579";
/// 容错读取字符串,缺键/空返回默认值。
public static string GetString(string key, string defaultValue = "")
{
try
{
var v = ConfigurationManager.AppSettings[key];
return string.IsNullOrEmpty(v) ? defaultValue : v;
}
catch
{
return defaultValue;
}
}
/// 容错读取整数,缺键/解析失败返回默认值。
public static int GetInt(string key, int defaultValue = 0)
{
return int.TryParse(GetString(key, null), out var r) ? r : defaultValue;
}
///
/// 读取加密项并解密(旧明文原样返回,由迁移逻辑负责回写)。缺键返回默认值。
///
public static string GetDecrypted(string key, string defaultValue = "")
{
var raw = GetString(key, null);
if (string.IsNullOrEmpty(raw)) return defaultValue;
return CryptoHelper.Decrypt(raw);
}
///
/// 写回普通键(沿用 OpenExeConfiguration + RefreshSection,对齐 AppData.SetApp 写法)。
///
public static void Save(string key, string value)
{
try
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
config.AppSettings.Settings.Add(key, value);
else
config.AppSettings.Settings[key].Value = value;
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
catch
{
// 写失败不抛出(避免阻断 UI/启动);[M7] 运行环境核查落盘。
}
}
/// 加密后写回(用于 passWord / engineerPwd 等凭据)。
public static void SaveEncrypted(string key, string plain)
{
Save(key, CryptoHelper.Encrypt(plain));
}
///
/// M5-02-5:启动一次性凭据迁移(幂等)。
/// (a) passWord:明文(旧值,如 123456)→密文回写;已是密文则跳过。
/// (b) engineerPwd:键缺失→以默认 tl13579 加密建键;明文→密文回写。
/// 仅当存在需迁移的明文时才写盘,已全部加密则不触碰文件(幂等)。
///
public static void MigratePlaintextCredentials()
{
try
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
bool changed = false;
// (a) passWord 明文 → 密文
var pw = config.AppSettings.Settings["passWord"];
if (pw != null && !string.IsNullOrEmpty(pw.Value) && !CryptoHelper.IsEncrypted(pw.Value))
{
pw.Value = CryptoHelper.Encrypt(pw.Value);
changed = true;
}
// (b) engineerPwd 缺键或明文 → 加密建键/回写(治理 tl13579)
var ep = config.AppSettings.Settings[EngineerPwdKey];
if (ep == null)
{
config.AppSettings.Settings.Add(EngineerPwdKey, CryptoHelper.Encrypt(DefaultEngineerPwd));
changed = true;
}
else if (!string.IsNullOrEmpty(ep.Value) && !CryptoHelper.IsEncrypted(ep.Value))
{
ep.Value = CryptoHelper.Encrypt(ep.Value);
changed = true;
}
if (changed)
{
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
}
catch
{
// 迁移失败不阻断启动;[M7] 运行环境核查首次迁移。
}
}
/// 读取工程师口令明文(解密;键缺失/解密失败回退默认 tl13579)。
public static string GetEngineerPwd()
{
var v = GetDecrypted(EngineerPwdKey, DefaultEngineerPwd);
return string.IsNullOrEmpty(v) ? DefaultEngineerPwd : v;
}
}
}