10.20PLC+相机2.3视觉修改
This commit is contained in:
		
							
								
								
									
										244
									
								
								Check.Main/Dispatch/ProductManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								Check.Main/Dispatch/ProductManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| using Check.Main.Common; | ||||
| using Newtonsoft.Json; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
| using System.Threading.Tasks; | ||||
| using System.Xml; | ||||
| using System.Xml.Serialization; | ||||
|  | ||||
| namespace Check.Main.Dispatch | ||||
| { | ||||
|     public static class ProductManager | ||||
|     { | ||||
|         private static readonly string _productRootPath = Path.Combine(Application.StartupPath, "Product"); | ||||
|         private static readonly string _productListFilePath = Path.Combine(Application.StartupPath, "products.json"); | ||||
|  | ||||
|         // --- 公共属性和事件 --- | ||||
|         public static List<string> ProductList { get; private set; } = new List<string>(); | ||||
|         public static string CurrentProductName { get; private set; } | ||||
|         public static ProcessConfig CurrentConfig { get; private set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当产品切换或配置加载后触发。 | ||||
|         /// </summary> | ||||
|         public static event Action OnProductChanged; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 静态构造函数,在程序启动时自动执行。 | ||||
|         /// </summary> | ||||
|         static ProductManager() | ||||
|         { | ||||
|             Directory.CreateDirectory(_productRootPath); // 确保Product文件夹存在 | ||||
|             LoadProductList(); | ||||
|             // 默认加载列表中的第一个产品,或者创建一个默认的 | ||||
|             SwitchToProduct(ProductList.FirstOrDefault() ?? "DefaultProduct"); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 切换到指定的产品,并加载其配置。 | ||||
|         /// </summary> | ||||
|         public static bool SwitchToProduct(string productName) | ||||
|         { | ||||
|             if (string.IsNullOrWhiteSpace(productName)) return false; | ||||
|  | ||||
|             ThreadSafeLogger.Log($"正在切换到产品: {productName}"); | ||||
|             var config = LoadConfigForProduct(productName); | ||||
|             if (config == null) | ||||
|             { | ||||
|                 // 如果加载失败(例如新创建的产品还没有配置文件),则创建一个新的 | ||||
|                 config = new ProcessConfig(); | ||||
|             } | ||||
|  | ||||
|              | ||||
|             CurrentProductName = productName; | ||||
|             CurrentConfig = config; | ||||
|  | ||||
|             // 广播产品已变更的通知 | ||||
|             OnProductChanged?.Invoke(); | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 添加一个新产品。 | ||||
|         /// </summary> | ||||
|         public static bool AddNewProduct(string newProductName) | ||||
|         { | ||||
|             if (string.IsNullOrWhiteSpace(newProductName) || ProductList.Contains(newProductName)) | ||||
|             { | ||||
|                 return false; // 名称无效或已存在 | ||||
|             } | ||||
|  | ||||
|             // 创建一个全新的、空的配置 | ||||
|             var newConfig = new ProcessConfig(); | ||||
|  | ||||
|             // 保存这个新产品的空配置,这也会创建文件夹 | ||||
|             if (SaveConfigForProduct(newProductName, newConfig)) | ||||
|             { | ||||
|                 ProductList.Add(newProductName); | ||||
|                 SaveProductList(); // 更新产品列表文件 | ||||
|                 SwitchToProduct(newProductName); // 创建后立即切换到新产品 | ||||
|                 return true; | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 删除指定的产品及其所有相关配置。 | ||||
|         /// </summary> | ||||
|         /// <param name="productNameToDelete">要删除的产品名称。</param> | ||||
|         /// <returns>成功删除返回 true,否则返回 false。</returns> | ||||
|         public static bool DeleteProduct(string productNameToDelete) | ||||
|         { | ||||
|             if (string.IsNullOrWhiteSpace(productNameToDelete) || !ProductList.Contains(productNameToDelete)) | ||||
|             { | ||||
|                 ThreadSafeLogger.Log($"[警告] 尝试删除一个不存在的产品: {productNameToDelete}"); | ||||
|                 return false; // 产品不存在 | ||||
|             } | ||||
|  | ||||
|             ThreadSafeLogger.Log($"正在删除产品: {productNameToDelete}..."); | ||||
|             try | ||||
|             { | ||||
|                 // 1. 从产品列表中移除 | ||||
|                 ProductList.Remove(productNameToDelete); | ||||
|                 SaveProductList(); // 更新列表文件 | ||||
|  | ||||
|                 // 2. 删除对应的配置文件夹 | ||||
|                 var safeFolderName = GetSafeFolderName(productNameToDelete); | ||||
|                 var productDir = Path.Combine(_productRootPath, safeFolderName); | ||||
|                 if (Directory.Exists(productDir)) | ||||
|                 { | ||||
|                     Directory.Delete(productDir, true); // true 表示递归删除所有子文件和子文件夹 | ||||
|                 } | ||||
|  | ||||
|                 ThreadSafeLogger.Log($"产品 '{productNameToDelete}' 已成功删除。"); | ||||
|  | ||||
|                 // 3. 如果被删除的是当前活动产品,则需要切换到一个新的有效产品 | ||||
|                 if (CurrentProductName == productNameToDelete) | ||||
|                 { | ||||
|                     // 切换到列表中的第一个产品,或者如果列表为空,则创建一个默认产品 | ||||
|                     string nextProduct = ProductList.FirstOrDefault() ?? "DefaultProduct"; | ||||
|                     SwitchToProduct(nextProduct); | ||||
|                 }  | ||||
|                 else | ||||
|                 { | ||||
|                     // 如果删除的不是当前产品,我们仍然需要触发一次事件, | ||||
|                     // 以便UI(主要是下拉列表)能够刷新它的数据源。 | ||||
|                     OnProductChanged?.Invoke(); | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ThreadSafeLogger.Log($"[错误] 删除产品 '{productNameToDelete}' 失败: {ex.Message}"); | ||||
|                 // 如果出错,最好把刚删除的项加回来,保持状态一致性 | ||||
|                 if (!ProductList.Contains(productNameToDelete)) | ||||
|                 { | ||||
|                     ProductList.Add(productNameToDelete); | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 为当前产品保存更改。 | ||||
|         /// </summary> | ||||
|         public static void SaveCurrentProductConfig() | ||||
|         { | ||||
|             if (CurrentConfig != null && !string.IsNullOrWhiteSpace(CurrentProductName)) | ||||
|             { | ||||
|                 SaveConfigForProduct(CurrentProductName, CurrentConfig); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         #region 文件操作辅助方法 | ||||
|  | ||||
|         private static void LoadProductList() | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 if (File.Exists(_productListFilePath)) | ||||
|                 { | ||||
|                     var json = File.ReadAllText(_productListFilePath); | ||||
|                     ProductList = JsonConvert.DeserializeObject<List<string>>(json) ?? new List<string>(); | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ThreadSafeLogger.Log($"[错误] 加载产品列表失败: {ex.Message}"); | ||||
|                 ProductList = new List<string>(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static void SaveProductList() | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var json = JsonConvert.SerializeObject(ProductList, Newtonsoft.Json.Formatting.Indented); | ||||
|                 File.WriteAllText(_productListFilePath, json); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ThreadSafeLogger.Log($"[错误] 保存产品列表失败: {ex.Message}"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static ProcessConfig LoadConfigForProduct(string productName) | ||||
|         { | ||||
|             var safeFolderName = GetSafeFolderName(productName); | ||||
|             var configPath = Path.Combine(_productRootPath, safeFolderName, "config.xml"); | ||||
|  | ||||
|             if (!File.Exists(configPath)) return null; | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 XmlSerializer serializer = new XmlSerializer(typeof(ProcessConfig)); | ||||
|                 using (var fs = new FileStream(configPath, FileMode.Open, FileAccess.Read)) | ||||
|                 { | ||||
|                     return (ProcessConfig)serializer.Deserialize(fs); | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ThreadSafeLogger.Log($"[错误] 加载产品 '{productName}' 的配置失败: {ex.Message}"); | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static bool SaveConfigForProduct(string productName, ProcessConfig config) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var safeFolderName = GetSafeFolderName(productName); | ||||
|                 var productDir = Path.Combine(_productRootPath, safeFolderName); | ||||
|                 Directory.CreateDirectory(productDir); // 确保文件夹存在 | ||||
|  | ||||
|                 var configPath = Path.Combine(productDir, "config.xml"); | ||||
|  | ||||
|                 XmlSerializer serializer = new XmlSerializer(typeof(ProcessConfig)); | ||||
|                 using (var fs = new FileStream(configPath, FileMode.Create, FileAccess.Write)) | ||||
|                 { | ||||
|                     serializer.Serialize(fs, config); | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 ThreadSafeLogger.Log($"[错误] 保存产品 '{productName}' 的配置失败: {ex.Message}"); | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static string GetSafeFolderName(string productName) | ||||
|         { | ||||
|             // 移除所有不适合做文件夹名称的字符 | ||||
|             string invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); | ||||
|             Regex r = new Regex(string.Format("[{0}]", Regex.Escape(invalidChars))); | ||||
|             return r.Replace(productName, ""); | ||||
|         } | ||||
|  | ||||
|         #endregion | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user