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));
}
}
}