using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.IO; using YY.Admin.Core.Util; namespace YY.Admin.Helper { /// /// 服务器连接配置读写工具。 /// public static class ServerSettingsStore { private const string DefaultWebSocketPath = "/websocket/scada-sync"; /// /// 安装目录随包发布的默认配置(只读)。 /// public static string GetBundledAppSettingsPath() { return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configuration", "appsettings.json"); } /// /// 用户覆盖配置(可写),仅覆盖 JeecgIntegration 节点时使用。 /// public static string GetUserAppSettingsPath() { var dir = AppWritablePaths.EnsureDirectoryExists(AppWritablePaths.ConfigurationDirectory); return Path.Combine(dir, "appsettings.json"); } /// /// 兼容旧调用:优先返回用于读取的实际路径(存在用户覆盖则用用户文件)。 /// public static string GetConfigPath() { var user = GetUserAppSettingsPath(); if (File.Exists(user)) { return user; } return GetBundledAppSettingsPath(); } public class ServerSettingsModel { public string Ip { get; set; } = "127.0.0.1"; public int Port { get; set; } = 8080; public string BaseScheme { get; set; } = "http"; public string BasePath { get; set; } = "/jeecg-boot"; public string WebSocketUrl { get; set; } = string.Empty; public string WebSocketPath { get; set; } = DefaultWebSocketPath; /// /// 是否断开连接(true=断开,false=连接) /// public bool DisconnectConnection { get; set; } = false; } private static JObject LoadMergedRoot() { var bundledPath = GetBundledAppSettingsPath(); if (!File.Exists(bundledPath)) { throw new FileNotFoundException("未找到安装目录默认配置文件 appsettings.json", bundledPath); } var root = JObject.Parse(File.ReadAllText(bundledPath)); var userPath = GetUserAppSettingsPath(); if (!File.Exists(userPath)) { return root; } var userRoot = JObject.Parse(File.ReadAllText(userPath)); var userJeecg = userRoot["JeecgIntegration"] as JObject; if (userJeecg != null) { root["JeecgIntegration"] = userJeecg; } return root; } public static ServerSettingsModel Load() { var model = new ServerSettingsModel(); var root = LoadMergedRoot(); var jeecg = root["JeecgIntegration"] as JObject; if (jeecg == null) { return model; } var baseUrl = jeecg.Value("BaseUrl") ?? string.Empty; if (Uri.TryCreate(baseUrl, UriKind.Absolute, out var uri)) { model.BaseScheme = uri.Scheme; model.Ip = uri.Host; model.Port = uri.Port; model.BasePath = string.IsNullOrWhiteSpace(uri.AbsolutePath) ? string.Empty : uri.AbsolutePath.TrimEnd('/'); } model.WebSocketUrl = jeecg.Value("WebSocketUrl") ?? string.Empty; model.WebSocketPath = NormalizeWebSocketPath(jeecg.Value("WebSocketPath")); model.DisconnectConnection = jeecg.Value("DisconnectConnection") ?? false; return model; } public static void Save(ServerSettingsModel model) { var root = LoadMergedRoot(); var jeecg = root["JeecgIntegration"] as JObject; if (jeecg == null) { jeecg = new JObject(); root["JeecgIntegration"] = jeecg; } var basePath = string.IsNullOrWhiteSpace(model.BasePath) ? string.Empty : model.BasePath.TrimEnd('/'); if (!string.IsNullOrWhiteSpace(basePath) && !basePath.StartsWith('/')) { basePath = "/" + basePath; } var baseUrl = $"{model.BaseScheme}://{model.Ip}:{model.Port}{basePath}"; var webSocketPath = NormalizeWebSocketPath(model.WebSocketPath); var webSocketUrl = string.IsNullOrWhiteSpace(model.WebSocketUrl) ? BuildDefaultWebSocketUrl(model.BaseScheme, model.Ip, model.Port, basePath, webSocketPath) : model.WebSocketUrl.Trim(); jeecg["BaseUrl"] = baseUrl; jeecg["WebSocketUrl"] = webSocketUrl; jeecg["WebSocketPath"] = webSocketPath; jeecg["DisconnectConnection"] = model.DisconnectConnection; var userPath = GetUserAppSettingsPath(); var outRoot = new JObject { ["JeecgIntegration"] = jeecg }; File.WriteAllText(userPath, outRoot.ToString(Formatting.Indented)); } public static string BuildDefaultWebSocketUrl(string baseScheme, string ip, int port, string basePath, string webSocketPath = DefaultWebSocketPath) { var safeScheme = string.Equals(baseScheme, "https", StringComparison.OrdinalIgnoreCase) ? "wss" : "ws"; var safeBasePath = string.IsNullOrWhiteSpace(basePath) ? string.Empty : basePath.TrimEnd('/'); if (!string.IsNullOrWhiteSpace(safeBasePath) && !safeBasePath.StartsWith('/')) { safeBasePath = "/" + safeBasePath; } var safeWsPath = NormalizeWebSocketPath(webSocketPath); return $"{safeScheme}://{ip}:{port}{safeBasePath}{safeWsPath}"; } private static string NormalizeWebSocketPath(string? webSocketPath) { var value = string.IsNullOrWhiteSpace(webSocketPath) ? DefaultWebSocketPath : webSocketPath.Trim(); if (!value.StartsWith('/')) { value = "/" + value; } return value; } } }