using System; using System.Collections.Generic; using System.IO; namespace TeamAAS { /// /// 统一路径/文件名入口。全应用的文件/目录一律经由此类拼取, /// 需要整体迁移数据目录(或更换宿主)时,只需改 一处,内核逻辑不变。 /// public static class PathHelper { /// 统一数据根目录(唯一对外可改参数)。默认=程序基目录。 public static string Root { get; set; } = AppDomain.CurrentDomain.BaseDirectory; // 子目录名(固定) private const string ConfigFolder = "Config"; private const string ProductsFolder = "Products"; private const string RecipeFolder = "Recipe"; private const string RuntimeFolder = "Runtime"; private const string LocalizationFolder = "Localization"; private const string PluginsFolder = "Plugins"; // 共享配置/数据文件名(固定) private const string SystemConfigName = "SystemConfiguration.json"; private const string GlobalEventName = "GlobalEventConfig.json"; private const string FeedersName = "Feeders.json"; private const string FeederRecipesName = "Feeder_recipes.json"; private const string DatabaseName = "Database.db"; private static string Ensure(string dir) { if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) Directory.CreateDirectory(dir); return dir; } /// Config 目录(自动创建)。 public static string ConfigDirectory => Ensure(Path.Combine(Root, ConfigFolder)); /// Products 目录(自动创建)。 public static string ProductsDir => Ensure(Path.Combine(Root, ProductsFolder)); /// Recipe(配方/全局变量)目录(自动创建)。 public static string RecipeDir => Ensure(Path.Combine(Root, RecipeFolder)); /// Runtime 目录(依赖/插件/语言包,只读不创建)。 public static string RuntimeDir => Path.Combine(Root, RuntimeFolder); /// 插件目录 Runtime\Plugins。 public static string PluginsDir => Path.Combine(RuntimeDir, PluginsFolder); /// 语言包目录 Runtime\Localization。 public static string LocalizationDir => Path.Combine(RuntimeDir, LocalizationFolder); /// 解析语言包目录:优先 Runtime\Localization,回退 Root\Localization。 public static string ResolveLocalizationDir() { if (Directory.Exists(LocalizationDir)) return LocalizationDir; var alt = Path.Combine(Root, LocalizationFolder); return Directory.Exists(alt) ? alt : LocalizationDir; } // 共享配置/数据文件绝对路径 /// Config\SystemConfiguration.json。 public static string SystemConfigurationFile => Path.Combine(ConfigDirectory, SystemConfigName); /// Config\GlobalEventConfig.json。 public static string GlobalEventConfigFile => Path.Combine(ConfigDirectory, GlobalEventName); /// Config\feeders.json。 public static string FeedersConfigFile => Path.Combine(ConfigDirectory, FeedersName); /// Config\feeder_recipes.json。 public static string FeederRecipesFile => Path.Combine(ConfigDirectory, FeederRecipesName); /// 根目录下的 database.db。 public static string DatabaseFile => Path.Combine(Root, DatabaseName); /// Config\global_vars.json(机器级全局固定变量,不随产品变)。 public static string GlobalFixedVarsFile => Path.Combine(ConfigDirectory, "global_vars.json"); /// /// 将名称中的非法文件名字符替换为 '_'。 /// public static string SanitizeFileName(string name) { if (string.IsNullOrEmpty(name)) return name; foreach (char c in Path.GetInvalidFileNameChars()) name = name.Replace(c, '_'); return name; } /// /// 生成不重复的名称(如 流程1、流程2...)。候选集由 existPredicate 判定。 /// public static string GenerateUniqueName(string baseName, Func existsPredicate) { if (existsPredicate == null) throw new ArgumentNullException(nameof(existsPredicate)); string candidate = baseName; int suffix = 1; while (existsPredicate(candidate)) candidate = baseName + suffix++; return candidate; } /// /// 生成不重复的名称(基于已有名称集合)。 /// public static string GenerateUniqueName(string baseName, ICollection existingNames) { if (existingNames == null) throw new ArgumentNullException(nameof(existingNames)); return GenerateUniqueName(baseName, n => existingNames.Contains(n)); } } }