using ivf_tl_Entity.DebugEntitys; using ivf_tl_Entity.GlobalEntitys; using ivf_tl_Entity.GlobalEnums; using ivf_tl_Operate.CustomUserControls; using ivf_tl_Operate.View; using ivf_tl_Services; using System; using System.Collections.Generic; using System.Configuration; using System.IO; using System.Linq; using System.Resources; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media.Imaging; using System.Xml; namespace ivf_tl_Operate { public class AppData { public static AppData Instance = new Lazy(() => new AppData()).Value; public string DefeatPan { get; set; } = "C"; public string PicSuf { get; set; } = ".png"; /// /// 主窗口 /// public MainWindow MainWindow { get; set; } /// /// 首页 /// public MainPageView MainPageView { get; set; } /// /// 首页舱室信息控件 /// public List CustomHouseInfoList { get; set; } = new List(); public string TlSn { get; set; } = "NEO-1-20230107"; public string TlNum { get; set; } = "20230107"; public TLSettingCommon TLSettingCommon { get; set; } public HttpHelper HttpHelper { get; set; } public LogHelper LogHelper { get; set; } public MqttHelper MqttHelper { get; set; } public ConvertHelper ConvertHelper { get; set; } //public string BaseUrl = "http://gateway.aivfo.com:36000/"; public string BaseUrl = "http://192.168.31.89:10010/"; private string MqttIp = "211.149.139.131"; private int MqttPort = 1883; private string MqttUserName = "aivfo"; private string MqttPassword = "aivfo"; private string MqttClientId = "TL/Surafce/tlSn"; private string MqttTopicName = "TL/House/surface/tlSn"; private string fertilizationTypeString = "FERTILIZATION_TYPE"; public ExUserInfo CurrentUserInfo { get; set; } = new ExUserInfo(); public List FertilizationTypeEntitieList { get; set; } public string OutInterString { get; set; } = "1"; private AppData() { // M5-01-2 / R8:启动期配置改走 AppConfigHelper 容错读取,缺键返回默认值而非裸 NPE/FormatException 崩在构造里。 BaseUrl = $"{ivf_tl_Operate.Helpers.AppConfigHelper.GetString("urlIp")}:{ivf_tl_Operate.Helpers.AppConfigHelper.GetString("urlPort")}/"; MqttIp = ivf_tl_Operate.Helpers.AppConfigHelper.GetString("mqttIp"); MqttPort = ivf_tl_Operate.Helpers.AppConfigHelper.GetInt("mqttPort", 1883); OutInterString = ivf_tl_Operate.Helpers.AppConfigHelper.GetString("outInter", "1"); if (OutInterString == "1") { //测试环境外网 BaseUrl = "http://test-gateway.aivfo.com:36000/"; MqttIp = "211.149.139.131"; MqttPort = 62883; } #if DEBUG //开发环境 BaseUrl = "http://192.168.0.207:10010/"; MqttIp = "192.168.0.207"; MqttPort = 1883; //测试环境 BaseUrl = "http://192.168.0.91:10010/"; MqttIp = "192.168.0.91"; MqttPort = 1883; //开发环境外网 BaseUrl = "http://gateway.aivfo.com:36000/"; MqttIp = "211.149.139.131"; MqttPort = 61883; //测试环境外网 BaseUrl = "http://test-gateway.aivfo.com:36000/"; MqttIp = "211.149.139.131"; MqttPort = 62883; #endif } public bool AppDataInit(string _account, string _password, string _tlNum) { LogHelper = new LogHelper(); LogHelper.Pan = DefeatPan; HttpHelper = new HttpHelper(_account, _password, LogHelper); var exuserinfo = HttpHelper.Init(BaseUrl); if (exuserinfo != null && !string.IsNullOrEmpty(exuserinfo.username)) { TlNum = _tlNum; TlSn = $"NEO-1-{TlNum}"; CurrentUserInfo.account = _account; CurrentUserInfo.password = _password; ConvertHelper = new ConvertHelper(); } else { return false; } CurrentUserInfo.email = exuserinfo.email; CurrentUserInfo.phone = exuserinfo.phone; CurrentUserInfo.username = exuserinfo.username; CurrentUserInfo.operatorInformation = exuserinfo.operatorInformation; // M8-P3b:登录后设置操作日志的 operator 与设备上下文(TlSn)。 SetOperationLogContext(); if (MqttHelper != null) MqttHelper.DisPoseMqtt(); MqttClientId = $"TL/Surafce/{TlSn}/{DateTime.Now}"; MqttTopicName = $"TL/House/surface/{TlSn}"; MqttHelper = new MqttHelper(MqttIp, MqttPort, MqttUserName, MqttPassword, MqttClientId, MqttTopicName); MqttHelper.ErrorLogEvent += LogHelper.TLLog; MqttHelper.ExceptionLogEvent += LogHelper.ExceptionLog; TLSettingCommon = HttpHelper.SettingCommonApi(TlSn); FertilizationTypeEntitieList = HttpHelper.QueryDictionaryByTypeApi(fertilizationTypeString); return true; } /// /// M8-P3b:当前登录操作者(供操作日志 operator 字段用)。AsyncLocal 不跨 UI 事件传播, /// 故同时存静态值作全局默认,埋点处可显式取用。来源:登录用户 username(无则 account)。 /// public static string CurrentOperator { get; private set; } /// /// M8-P3b:把登录用户与设备 SN 写入操作日志上下文。全 try 兜底。 /// private void SetOperationLogContext() { try { string op = !string.IsNullOrEmpty(CurrentUserInfo?.username) ? CurrentUserInfo.username : CurrentUserInfo?.account; CurrentOperator = op; Aivfo.OperationLog.OperationLogContext.Operator = op; // 设备 SN 作为全局默认(埋点未显式给 tlSn 时回退到此)。 if (Aivfo.OperationLog.OperationLogger.Options != null) Aivfo.OperationLog.OperationLogger.Options.TlSn = TlSn; } catch { /* 兜底:绝不因设置日志上下文影响登录 */ } } /// /// 返回首页 /// public void BackMainPage() { MainWindow.LoadPage(MainPageView); } public CustomHouseInfo HouseSnToCustomHouseInfo(int houseSn) { return CustomHouseInfoList.FirstOrDefault(x => x.HouseSn == houseSn); } public void SetApp(string name, string pass, string _tlNum) { Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.AppSettings.Settings["userName"].Value = name; // M5-02-2:passWord 写回时加密(DPAPI,与读取点 Decrypt 对称)。 config.AppSettings.Settings["passWord"].Value = ivf_tl_Operate.Helpers.CryptoHelper.Encrypt(pass); config.AppSettings.Settings["tlNum"].Value = _tlNum; config.Save(ConfigurationSaveMode.Modified); System.Configuration.ConfigurationManager.RefreshSection("appSettings"); } public void setAppConfig(string name, string pass, string _tlNum) { try { // M5-02-2:passWord 写回时加密(登录流程经此点写盘)。 string encPass = ivf_tl_Operate.Helpers.CryptoHelper.Encrypt(pass); string fileName = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "ivf_tl_Operate.dll.config"); if (!File.Exists(fileName)) return; var xmlDoc = new XmlDocument(); xmlDoc.Load(fileName); var tags = xmlDoc.GetElementsByTagName("appSettings"); XmlNode appSettingsNode = xmlDoc.SelectSingleNode("configuration/appSettings"); if (appSettingsNode != null) { XmlNodeList addNodes = appSettingsNode.SelectNodes("add"); foreach (XmlNode addNode in addNodes) { if (addNode.Attributes["key"].Value == "userName") addNode.Attributes["value"].Value = name; if (addNode.Attributes["key"].Value == "passWord") addNode.Attributes["value"].Value = encPass; if (addNode.Attributes["key"].Value == "tlNum") addNode.Attributes["value"].Value = _tlNum; } } xmlDoc.Save(fileName); System.Configuration.ConfigurationManager.RefreshSection("appSettings"); xmlDoc = null; } catch (Exception ex) { return; } } public void SetApp(int _tlNum) { Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.AppSettings.Settings["tlNum"].Value = _tlNum.ToString(); config.Save(ConfigurationSaveMode.Modified); System.Configuration.ConfigurationManager.RefreshSection("appSettings"); } public BitmapImage LogoBitmapImage(LogoEnum logoEnum) { try { #if DEBUG string basePath = @"C:\PersonalSpace\work\1 VisualWorkSpace\LogoFile"; #else string basePath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Resources", "LogoFile"); #endif string logoFile = string.Empty; switch (logoEnum) { case LogoEnum.Login: logoFile = "LoginLogo.png"; break; case LogoEnum.Rectangle: logoFile = "RectangleLogo.png"; break; case LogoEnum.Circle: logoFile = "CircleLogo.png"; break; case LogoEnum.BlackCircle: logoFile = "BlackCircleLogo.png"; break; default: break; } if (string.IsNullOrEmpty(logoFile)) return null; string filePath = Path.Combine(basePath, logoFile); if (!File.Exists(filePath)) return null; BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.UriSource = new Uri(filePath); bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.EndInit(); bitmap.Freeze(); return bitmap; } catch (Exception ex) { return null; } } public void SetImageSource(Image image, LogoEnum logoEnum) { image.Source = LogoBitmapImage(logoEnum); } } }