PathHelper.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. namespace TeamAAS
  5. {
  6. /// <summary>
  7. /// 统一路径/文件名入口。全应用的文件/目录一律经由此类拼取,
  8. /// 需要整体迁移数据目录(或更换宿主)时,只需改 <see cref="Root"/> 一处,内核逻辑不变。
  9. /// </summary>
  10. public static class PathHelper
  11. {
  12. /// <summary>统一数据根目录(唯一对外可改参数)。默认=程序基目录。</summary>
  13. public static string Root { get; set; } = AppDomain.CurrentDomain.BaseDirectory;
  14. // 子目录名(固定)
  15. private const string ConfigFolder = "Config";
  16. private const string ProductsFolder = "Products";
  17. private const string RecipeFolder = "Recipe";
  18. private const string RuntimeFolder = "Runtime";
  19. private const string LocalizationFolder = "Localization";
  20. private const string PluginsFolder = "Plugins";
  21. // 共享配置/数据文件名(固定)
  22. private const string SystemConfigName = "SystemConfiguration.json";
  23. private const string GlobalEventName = "GlobalEventConfig.json";
  24. private const string FeedersName = "Feeders.json";
  25. private const string FeederRecipesName = "Feeder_recipes.json";
  26. private const string DatabaseName = "Database.db";
  27. private static string Ensure(string dir)
  28. {
  29. if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) Directory.CreateDirectory(dir);
  30. return dir;
  31. }
  32. /// <summary>Config 目录(自动创建)。</summary>
  33. public static string ConfigDirectory => Ensure(Path.Combine(Root, ConfigFolder));
  34. /// <summary>Products 目录(自动创建)。</summary>
  35. public static string ProductsDir => Ensure(Path.Combine(Root, ProductsFolder));
  36. /// <summary>Recipe(配方/全局变量)目录(自动创建)。</summary>
  37. public static string RecipeDir => Ensure(Path.Combine(Root, RecipeFolder));
  38. /// <summary>Runtime 目录(依赖/插件/语言包,只读不创建)。</summary>
  39. public static string RuntimeDir => Path.Combine(Root, RuntimeFolder);
  40. /// <summary>插件目录 Runtime\Plugins。</summary>
  41. public static string PluginsDir => Path.Combine(RuntimeDir, PluginsFolder);
  42. /// <summary>语言包目录 Runtime\Localization。</summary>
  43. public static string LocalizationDir => Path.Combine(RuntimeDir, LocalizationFolder);
  44. /// <summary>解析语言包目录:优先 Runtime\Localization,回退 Root\Localization。</summary>
  45. public static string ResolveLocalizationDir()
  46. {
  47. if (Directory.Exists(LocalizationDir)) return LocalizationDir;
  48. var alt = Path.Combine(Root, LocalizationFolder);
  49. return Directory.Exists(alt) ? alt : LocalizationDir;
  50. }
  51. // 共享配置/数据文件绝对路径
  52. /// <summary>Config\SystemConfiguration.json。</summary>
  53. public static string SystemConfigurationFile => Path.Combine(ConfigDirectory, SystemConfigName);
  54. /// <summary>Config\GlobalEventConfig.json。</summary>
  55. public static string GlobalEventConfigFile => Path.Combine(ConfigDirectory, GlobalEventName);
  56. /// <summary>Config\feeders.json。</summary>
  57. public static string FeedersConfigFile => Path.Combine(ConfigDirectory, FeedersName);
  58. /// <summary>Config\feeder_recipes.json。</summary>
  59. public static string FeederRecipesFile => Path.Combine(ConfigDirectory, FeederRecipesName);
  60. /// <summary>根目录下的 database.db。</summary>
  61. public static string DatabaseFile => Path.Combine(Root, DatabaseName);
  62. /// <summary>Config\global_vars.json(机器级全局固定变量,不随产品变)。</summary>
  63. public static string GlobalFixedVarsFile => Path.Combine(ConfigDirectory, "global_vars.json");
  64. /// <summary>
  65. /// 将名称中的非法文件名字符替换为 '_'。
  66. /// </summary>
  67. public static string SanitizeFileName(string name)
  68. {
  69. if (string.IsNullOrEmpty(name)) return name;
  70. foreach (char c in Path.GetInvalidFileNameChars())
  71. name = name.Replace(c, '_');
  72. return name;
  73. }
  74. /// <summary>
  75. /// 生成不重复的名称(如 流程1、流程2...)。候选集由 existPredicate 判定。
  76. /// </summary>
  77. public static string GenerateUniqueName(string baseName, Func<string, bool> existsPredicate)
  78. {
  79. if (existsPredicate == null) throw new ArgumentNullException(nameof(existsPredicate));
  80. string candidate = baseName;
  81. int suffix = 1;
  82. while (existsPredicate(candidate))
  83. candidate = baseName + suffix++;
  84. return candidate;
  85. }
  86. /// <summary>
  87. /// 生成不重复的名称(基于已有名称集合)。
  88. /// </summary>
  89. public static string GenerateUniqueName(string baseName, ICollection<string> existingNames)
  90. {
  91. if (existingNames == null) throw new ArgumentNullException(nameof(existingNames));
  92. return GenerateUniqueName(baseName, n => existingNames.Contains(n));
  93. }
  94. }
  95. }