using System; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Serialization; namespace CadParamPluging.Common { public static class ParamCatalogStore { private const string FolderName = "CadParamPluging"; private const string FileName = "param-catalog.xml"; public static string GetFilePath() { var dir = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), FolderName); return Path.Combine(dir, FileName); } public static ParamCatalog Load() { try { var defaults = ParamCatalog.CreateDefault(); defaults.Normalize(); var path = GetFilePath(); if (!File.Exists(path)) { return defaults; } using (var stream = File.OpenRead(path)) { var serializer = new XmlSerializer(typeof(ParamCatalog)); var obj = serializer.Deserialize(stream) as ParamCatalog; if (obj == null) { return defaults; } obj.Normalize(); // Merge: keep local modifications, but add any missing keys from built-in defaults. foreach (var def in defaults.Items) { if (obj.FindByKey(def.Key) == null) { obj.Items.Add(def.Clone()); continue; } var existing = obj.FindByKey(def.Key); if (existing != null) { if (string.IsNullOrWhiteSpace(existing.Label) && !string.IsNullOrWhiteSpace(def.Label)) { existing.Label = def.Label; } if (string.IsNullOrWhiteSpace(existing.Group) && !string.IsNullOrWhiteSpace(def.Group)) { existing.Group = def.Group; } } } // Migration: move remark-like fields into "备注参数" group if they are still using older default groups. var remarkKeys = new HashSet(StringComparer.OrdinalIgnoreCase) { "MaterialGrade", "FeatureCategory", "MaterialTechnicalCondition", "ForgingTechnicalCondition", "InspectionCategory", "ForgingCategory", "HeatTreatmentState", "HeatTreatmentProcess", "Hardness", "UltrasonicRequirement", "MarkingContent", "PartsPerForging", "SurfaceRoughness", "DesignRevision", "SerialInfo", "MachiningSpecimenRequirement", "AdditionalNotes" }; foreach (var key in remarkKeys) { var existing = obj.FindByKey(key); if (existing == null) { continue; } var g = existing.Group ?? string.Empty; if (string.IsNullOrWhiteSpace(g) || string.Equals(g, "材料", StringComparison.OrdinalIgnoreCase) || string.Equals(g, "检验/热处理", StringComparison.OrdinalIgnoreCase) || string.Equals(g, "标注/说明", StringComparison.OrdinalIgnoreCase)) { existing.Group = "备注参数"; } } // Migration: remove legacy demo parameters if they exist. obj.Items = (obj.Items ?? new System.Collections.Generic.List()) .Where(x => x != null && !string.Equals(x.Key, "Width", StringComparison.OrdinalIgnoreCase) && !string.Equals(x.Key, "Height", StringComparison.OrdinalIgnoreCase) && !string.Equals(x.Key, "PartDimensionsPrime", StringComparison.OrdinalIgnoreCase)) .ToList(); obj.Normalize(); return obj; } } catch { var defaults = ParamCatalog.CreateDefault(); defaults.Normalize(); return defaults; } } public static void Save(ParamCatalog catalog) { if (catalog == null) { throw new ArgumentNullException(nameof(catalog)); } catalog.Normalize(); var path = GetFilePath(); var dir = Path.GetDirectoryName(path); if (!string.IsNullOrEmpty(dir)) { Directory.CreateDirectory(dir); } var tempPath = path + ".tmp"; var serializer = new XmlSerializer(typeof(ParamCatalog)); using (var stream = File.Create(tempPath)) { serializer.Serialize(stream, catalog); } if (File.Exists(path)) { File.Delete(path); } File.Move(tempPath, path); } } }