feat: migrate business settings to json
parent
343fcd8b80
commit
15b7ac84e8
@ -0,0 +1,85 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Txgy.EWS.Client.Common
|
||||
{
|
||||
public class BusinessConfig
|
||||
{
|
||||
public EndpointSettings Endpoints { get; set; }
|
||||
public PathSettings Paths { get; set; }
|
||||
public RuntimeSettings Runtime { get; set; }
|
||||
public DatabaseSettings Database { get; set; }
|
||||
public BrandingSettings Branding { get; set; }
|
||||
public ReportSettings Report { get; set; }
|
||||
public CoordinateSettings Coordinates { get; set; }
|
||||
}
|
||||
|
||||
public class EndpointSettings
|
||||
{
|
||||
public string ApiDomain { get; set; }
|
||||
}
|
||||
|
||||
public class PathSettings
|
||||
{
|
||||
public string AlarmSetting { get; set; }
|
||||
public string AlarmLevelConfig { get; set; }
|
||||
public string ReportEventLevelSetting { get; set; }
|
||||
public string WorkAreaFilePath { get; set; }
|
||||
public string StationsCsvFilePath { get; set; }
|
||||
public string CadDwgFilePath { get; set; }
|
||||
public string DwgJsonSetting { get; set; }
|
||||
public string WavesMseedFilePath { get; set; }
|
||||
public string WavesTxtFilePath { get; set; }
|
||||
public string LocalSqLiteDb { get; set; }
|
||||
public string DwgSettings { get; set; }
|
||||
public string CadSettingsFileName { get; set; }
|
||||
}
|
||||
|
||||
public class RuntimeSettings
|
||||
{
|
||||
public bool IsDesign { get; set; }
|
||||
public bool IsRealtime { get; set; }
|
||||
public int RefreshInterval { get; set; }
|
||||
public int EventShowTotalSeconds { get; set; }
|
||||
public int LoadDataTimeLenMins { get; set; }
|
||||
public int DataCacheTimeLenMins { get; set; }
|
||||
}
|
||||
|
||||
public class DatabaseSettings
|
||||
{
|
||||
public Dictionary<string, string> Connections { get; set; }
|
||||
public TableSettings Tables { get; set; }
|
||||
}
|
||||
|
||||
public class TableSettings
|
||||
{
|
||||
public string RealtimeResultTable { get; set; }
|
||||
public string RealtimeWaveDataTable { get; set; }
|
||||
public string RealtimeFocalmechanismTable { get; set; }
|
||||
public string PostResultTable { get; set; }
|
||||
public string PostWaveDataTable { get; set; }
|
||||
public string PostFocalmechanismTable { get; set; }
|
||||
}
|
||||
|
||||
public class BrandingSettings
|
||||
{
|
||||
public string CommpanyName { get; set; }
|
||||
public string SystemNameCn { get; set; }
|
||||
public string SystemNameEn { get; set; }
|
||||
public string WorkAreaName { get; set; }
|
||||
public string SystemShortName { get; set; }
|
||||
}
|
||||
|
||||
public class ReportSettings
|
||||
{
|
||||
public string DailyReportStartTime { get; set; }
|
||||
public double DailyReportPlanOffsetX { get; set; }
|
||||
public double DailyReportPlanOffsetY { get; set; }
|
||||
}
|
||||
|
||||
public class CoordinateSettings
|
||||
{
|
||||
public double BaseX { get; set; }
|
||||
public double BaseY { get; set; }
|
||||
public double BaseZ { get; set; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,267 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Txgy.EWS.Client.Common
|
||||
{
|
||||
public static class BusinessConfigManager
|
||||
{
|
||||
private static readonly object SyncRoot = new object();
|
||||
private static BusinessConfig _current;
|
||||
|
||||
public static string ConfigPath => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config", "client-settings.json");
|
||||
|
||||
public static BusinessConfig Current
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return _current ?? (_current = Read());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static BusinessConfig Read()
|
||||
{
|
||||
if (!File.Exists(ConfigPath))
|
||||
{
|
||||
throw new FileNotFoundException("Business config file was not found.", ConfigPath);
|
||||
}
|
||||
|
||||
var json = File.ReadAllText(ConfigPath);
|
||||
var config = JsonConvert.DeserializeObject<BusinessConfig>(json);
|
||||
Validate(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
public static BusinessConfig Reload()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_current = Read();
|
||||
FreeSqlTencent.Reset();
|
||||
FreeSqlLocalSqLite.Reset();
|
||||
return _current;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetConnectionString(string name)
|
||||
{
|
||||
var connections = Current.Database.Connections;
|
||||
if (connections == null || !connections.TryGetValue(name, out var value) || string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
throw new InvalidOperationException($"Business config is missing database connection: {name}");
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static string GetRequiredPath(string value, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
throw new InvalidOperationException($"Business config is missing path: {name}");
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static string GetAppSetting(string key)
|
||||
{
|
||||
if (!GetLegacyAppSettings().TryGetValue(key, out var token))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (token == null || token.Type == JTokenType.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return token.Type == JTokenType.String ? token.Value<string>() : token.ToString();
|
||||
}
|
||||
|
||||
public static void UpdateAppSetting(string key, string value)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
var root = ReadRoot();
|
||||
var appSettings = GetLegacyAppSettings(root);
|
||||
if (!appSettings.TryGetValue(key, out var token) || token == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Business config does not support writing setting: {key}");
|
||||
}
|
||||
|
||||
token.Replace(ConvertValue(token, value));
|
||||
SaveRoot(root);
|
||||
_current = root.ToObject<BusinessConfig>();
|
||||
Validate(_current);
|
||||
FreeSqlTencent.Reset();
|
||||
FreeSqlLocalSqLite.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateRuntimeSettings(int loadDataTimeLenMins, int dataCacheTimeLenMins)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
var root = ReadRoot();
|
||||
root["runtime"]["loadDataTimeLenMins"] = loadDataTimeLenMins;
|
||||
root["runtime"]["dataCacheTimeLenMins"] = dataCacheTimeLenMins;
|
||||
SaveRoot(root);
|
||||
_current = root.ToObject<BusinessConfig>();
|
||||
Validate(_current);
|
||||
}
|
||||
}
|
||||
|
||||
private static JObject ReadRoot()
|
||||
{
|
||||
if (!File.Exists(ConfigPath))
|
||||
{
|
||||
throw new FileNotFoundException("Business config file was not found.", ConfigPath);
|
||||
}
|
||||
|
||||
return JObject.Parse(File.ReadAllText(ConfigPath));
|
||||
}
|
||||
|
||||
private static void SaveRoot(JObject root)
|
||||
{
|
||||
var serializer = JsonSerializer.Create(new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
StringEscapeHandling = StringEscapeHandling.EscapeNonAscii
|
||||
});
|
||||
string json;
|
||||
using (var writer = new StringWriter())
|
||||
{
|
||||
serializer.Serialize(writer, root);
|
||||
json = writer.ToString();
|
||||
}
|
||||
var tempPath = ConfigPath + ".tmp";
|
||||
File.WriteAllText(tempPath, json);
|
||||
if (File.Exists(ConfigPath))
|
||||
{
|
||||
File.Delete(ConfigPath);
|
||||
}
|
||||
File.Move(tempPath, ConfigPath);
|
||||
}
|
||||
|
||||
private static Dictionary<string, JToken> GetLegacyAppSettings()
|
||||
{
|
||||
return GetLegacyAppSettings(ReadRoot());
|
||||
}
|
||||
|
||||
private static Dictionary<string, JToken> GetLegacyAppSettings(JObject root)
|
||||
{
|
||||
return new Dictionary<string, JToken>
|
||||
{
|
||||
{ "api_domain", root["endpoints"]?["apiDomain"] },
|
||||
{ "AlarmSetting", root["paths"]?["alarmSetting"] },
|
||||
{ "AlarmLevelConfig", root["paths"]?["alarmLevelConfig"] },
|
||||
{ "ReportEventLevelSetting", root["paths"]?["reportEventLevelSetting"] },
|
||||
{ "WorkAreaFilePath", root["paths"]?["workAreaFilePath"] },
|
||||
{ "StationsCsvFilePath", root["paths"]?["stationsCsvFilePath"] },
|
||||
{ "CadDwgFilePath", root["paths"]?["cadDwgFilePath"] },
|
||||
{ "DwgJsonSetting", root["paths"]?["dwgJsonSetting"] },
|
||||
{ "WavesMseedFilePath", root["paths"]?["wavesMseedFilePath"] },
|
||||
{ "WavesTxtFilePath", root["paths"]?["wavesTxtFilePath"] },
|
||||
{ "LocalSqLiteDb", root["paths"]?["localSqLiteDb"] },
|
||||
{ "DwgSettings", root["paths"]?["dwgSettings"] },
|
||||
{ "CadSettingsFileName", root["paths"]?["cadSettingsFileName"] },
|
||||
{ "IsDesign", root["runtime"]?["isDesign"] },
|
||||
{ "IsRealtime", root["runtime"]?["isRealtime"] },
|
||||
{ "RefreshInterval", root["runtime"]?["refreshInterval"] },
|
||||
{ "EventShowTotalSeconds", root["runtime"]?["eventShowTotalSeconds"] },
|
||||
{ "LoadDataTimeLenMins", root["runtime"]?["loadDataTimeLenMins"] },
|
||||
{ "DataCacheTimeLenMins", root["runtime"]?["dataCacheTimeLenMins"] },
|
||||
{ "RealtimeResultTable", root["database"]?["tables"]?["realtimeResultTable"] },
|
||||
{ "RealtimeWaveDataTable", root["database"]?["tables"]?["realtimeWaveDataTable"] },
|
||||
{ "RealtimeFocalmechanismTable", root["database"]?["tables"]?["realtimeFocalmechanismTable"] },
|
||||
{ "PostResultTable", root["database"]?["tables"]?["postResultTable"] },
|
||||
{ "PostWaveDataTable", root["database"]?["tables"]?["postWaveDataTable"] },
|
||||
{ "PostFocalmechanismTable", root["database"]?["tables"]?["postFocalmechanismTable"] },
|
||||
{ "CommpanyName", root["branding"]?["commpanyName"] },
|
||||
{ "SystemNameCn", root["branding"]?["systemNameCn"] },
|
||||
{ "SystemNameEn", root["branding"]?["systemNameEn"] },
|
||||
{ "WorkAreaName", root["branding"]?["workAreaName"] },
|
||||
{ "SystemShortName", root["branding"]?["systemShortName"] },
|
||||
{ "日报起始时间", root["report"]?["dailyReportStartTime"] },
|
||||
{ "日报平面图横向偏移", root["report"]?["dailyReportPlanOffsetX"] },
|
||||
{ "日报平面图纵向偏移", root["report"]?["dailyReportPlanOffsetY"] },
|
||||
{ "BaseX", root["coordinates"]?["baseX"] },
|
||||
{ "BaseY", root["coordinates"]?["baseY"] },
|
||||
{ "BaseZ", root["coordinates"]?["baseZ"] }
|
||||
};
|
||||
}
|
||||
|
||||
private static JToken ConvertValue(JToken currentValue, string value)
|
||||
{
|
||||
switch (currentValue.Type)
|
||||
{
|
||||
case JTokenType.Boolean:
|
||||
return bool.Parse(value);
|
||||
case JTokenType.Integer:
|
||||
return int.Parse(value);
|
||||
case JTokenType.Float:
|
||||
return double.Parse(value);
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Validate(BusinessConfig config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
throw new InvalidOperationException("Business config file format is invalid.");
|
||||
}
|
||||
|
||||
Require(config.Endpoints?.ApiDomain, "endpoints.apiDomain");
|
||||
Require(config.Paths?.AlarmSetting, "paths.alarmSetting");
|
||||
Require(config.Paths?.AlarmLevelConfig, "paths.alarmLevelConfig");
|
||||
Require(config.Paths?.ReportEventLevelSetting, "paths.reportEventLevelSetting");
|
||||
Require(config.Paths?.WorkAreaFilePath, "paths.workAreaFilePath");
|
||||
Require(config.Paths?.StationsCsvFilePath, "paths.stationsCsvFilePath");
|
||||
Require(config.Paths?.CadDwgFilePath, "paths.cadDwgFilePath");
|
||||
Require(config.Paths?.DwgJsonSetting, "paths.dwgJsonSetting");
|
||||
Require(config.Paths?.WavesMseedFilePath, "paths.wavesMseedFilePath");
|
||||
Require(config.Paths?.WavesTxtFilePath, "paths.wavesTxtFilePath");
|
||||
Require(config.Paths?.LocalSqLiteDb, "paths.localSqLiteDb");
|
||||
Require(config.Branding?.CommpanyName, "branding.commpanyName");
|
||||
Require(config.Branding?.SystemNameCn, "branding.systemNameCn");
|
||||
Require(config.Branding?.SystemNameEn, "branding.systemNameEn");
|
||||
Require(config.Branding?.WorkAreaName, "branding.workAreaName");
|
||||
Require(config.Branding?.SystemShortName, "branding.systemShortName");
|
||||
Require(config.Report?.DailyReportStartTime, "report.dailyReportStartTime");
|
||||
Require(config.Database?.Tables?.RealtimeResultTable, "database.tables.realtimeResultTable");
|
||||
Require(config.Database?.Tables?.RealtimeWaveDataTable, "database.tables.realtimeWaveDataTable");
|
||||
Require(config.Database?.Tables?.RealtimeFocalmechanismTable, "database.tables.realtimeFocalmechanismTable");
|
||||
Require(config.Database?.Tables?.PostResultTable, "database.tables.postResultTable");
|
||||
Require(config.Database?.Tables?.PostWaveDataTable, "database.tables.postWaveDataTable");
|
||||
Require(config.Database?.Tables?.PostFocalmechanismTable, "database.tables.postFocalmechanismTable");
|
||||
GetConnectionStringFromConfig(config, "TencetnMySQL");
|
||||
GetConnectionStringFromConfig(config, "NasMySQL");
|
||||
}
|
||||
|
||||
private static void Require(string value, string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
throw new InvalidOperationException($"Business config is missing setting: {name}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetConnectionStringFromConfig(BusinessConfig config, string name)
|
||||
{
|
||||
if (config.Database?.Connections == null ||
|
||||
!config.Database.Connections.TryGetValue(name, out var value) ||
|
||||
string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
throw new InvalidOperationException($"Business config is missing database connection: {name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
{
|
||||
"endpoints": {
|
||||
"apiDomain": "http://8.141.12.31:80/api/v1/"
|
||||
},
|
||||
"paths": {
|
||||
"alarmSetting": "\\resources\\alarmsetting.json",
|
||||
"alarmLevelConfig": "\\resources\\alarmlevel.json",
|
||||
"reportEventLevelSetting": "resources\\ReportEventLevelSettings.json",
|
||||
"workAreaFilePath": "\\resources\\WorkAreaSettings-N2107.json",
|
||||
"stationsCsvFilePath": "\\resources\\N2107_1116.csv",
|
||||
"cadDwgFilePath": "\\resources\\N2107_V2013_1117.dwg",
|
||||
"dwgJsonSetting": "resources\\DwgSetting.json",
|
||||
"wavesMseedFilePath": "D:\\EwsCache\\Mseed",
|
||||
"wavesTxtFilePath": "D:\\EwsCache\\Txt",
|
||||
"localSqLiteDb": "EwsLocalSqLite.db",
|
||||
"dwgSettings": null,
|
||||
"cadSettingsFileName": null
|
||||
},
|
||||
"runtime": {
|
||||
"isDesign": false,
|
||||
"isRealtime": true,
|
||||
"refreshInterval": 10,
|
||||
"eventShowTotalSeconds": 86400,
|
||||
"loadDataTimeLenMins": 720,
|
||||
"dataCacheTimeLenMins": 720
|
||||
},
|
||||
"database": {
|
||||
"connections": {
|
||||
"TencetnMySQL": "Data Source=bj-cdb-q64mbxr6.sql.tencentcdb.com;Port=60027;Database=yuwu2026;User=yuwudba;Password=Yw123456;SslMode = none;",
|
||||
"NasMySQL": "Data Source=tayfx.work;Port=60027;Database=YuwuN1100;User=yuwudba;Password=Yw123456;SslMode = none;"
|
||||
},
|
||||
"tables": {
|
||||
"realtimeResultTable": "realtimeeventresult",
|
||||
"realtimeWaveDataTable": "realtimewavedatas",
|
||||
"realtimeFocalmechanismTable": "realtimefocalmechanism",
|
||||
"postResultTable": "postproeventresult",
|
||||
"postWaveDataTable": "postproeventwavedatas",
|
||||
"postFocalmechanismTable": "postprofocalmechanism"
|
||||
}
|
||||
},
|
||||
"branding": {
|
||||
"commpanyName": "\u6cb3\u5357\u7406\u5de5\u5927\u5b66",
|
||||
"systemNameCn": "\u7164\u77ff\u52a8\u529b\u707e\u5bb3\u5fae\u5730\u9707\u5b9e\u65f6\u9884\u8b66\u7cfb\u7edf",
|
||||
"systemNameEn": "Microseismic Real-time Monitoring System",
|
||||
"workAreaName": "N2107",
|
||||
"systemShortName": "\u9884\u8b66\u7cfb\u7edf"
|
||||
},
|
||||
"report": {
|
||||
"dailyReportStartTime": "00:00:00",
|
||||
"dailyReportPlanOffsetX": -200,
|
||||
"dailyReportPlanOffsetY": -350
|
||||
},
|
||||
"coordinates": {
|
||||
"baseX": 38396517,
|
||||
"baseY": 4029418,
|
||||
"baseZ": 1208
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue