refactor(storage): organize XPData directories

This commit is contained in:
zhengxuan.zhang
2026-08-05 09:31:07 +08:00
parent ccd73c24d5
commit 7aa14b707c
11 changed files with 76 additions and 69 deletions
+16 -6
View File
@@ -51,11 +51,11 @@ XplorePlane.sln
```xml
<add key="XpData:RootPath" value="D:\XPData" />
<add key="Serilog:LogPath" value="D:\XPData\Diagnostics\Logs" />
<add key="Sqlite:DbFilePath" value="D:\XPData\DataBase\XP.db" />
<add key="Detector:SavePath" value="D:\XPData\DetectorImages" />
<add key="Dump:StoragePath" value="D:\XPData\Diagnostics\Dumps" />
<add key="Report:OutputDirectory" value="D:\XPData\Reports" />
<add key="Serilog:LogPath" value="D:\XPData\Runtime\Diagnostics\Logs" />
<add key="Sqlite:DbFilePath" value="D:\XPData\Runtime\DataBase\XP.db" />
<add key="Detector:SavePath" value="D:\XPData\Results\DetectorImages" />
<add key="Dump:StoragePath" value="D:\XPData\Runtime\Diagnostics\Dumps" />
<add key="Report:OutputDirectory" value="D:\XPData\Results\Reports" />
```
推荐目录结构:
@@ -209,7 +209,17 @@ D:\XplorePlane\bin\x64\Debug\net8.0-windows\win-x64\Host\
### 检测池持久化约定
`PoolTaskPlan` 是检测池唯一的持久化模型,正式计划统一保存到 `D:\\XPData\\InspectionPool\\Plans\\*.xppool``InspectionDefinition` 只在运行时由计划映射生成,不再写入独立 `Definitions` 目录。`InspectionPool\\Runs\\{TaskId}` 保存任务运行记录;`Legacy\\GeneratedDefinitions` 仅归档历史生成文件,不参与 CNC 插入列表。
`PoolTaskPlan` 是检测池唯一的持久化模型,正式计划统一保存到 `D:\\XPData\\Plans\\InspectionPool\\*.xppool``InspectionDefinition` 只在运行时由计划映射生成,不再写入独立 `Definitions` 目录。`D:\\XPData\\Results\\Inspection\\PoolRuns\\{TaskId}` 保存任务运行记录;`Legacy\\GeneratedDefinitions` 仅归档历史生成文件,不参与 CNC 插入列表。
### XPData 分类
```text
D:\\XPData
├── Runtime\\ # DataBase、Calibration、Diagnostics
├── Plans\\ # CncPrograms、Pipelines、InspectionPool
├── Assets\\ # Templates、Models、References
└── Results\\ # Inspection、DetectorImages、Reports、Video
```
### TO-DO List
+7 -7
View File
@@ -11,7 +11,7 @@
<add key="UserManual" value="UserManual.pdf" />
<add key="DeviceId" value="PlanerCT001" />
<!-- 流水线默认流程图:启动时自动加载并显示。相对文件名解析到 {XpData:RootPath}\Pipelines 目录 -->
<!-- 流水线默认流程图:启动时自动加载并显示。相对文件名解析到 {XpData:RootPath}\Plans\Pipelines 目录 -->
<add key="Pipeline:DefaultModuleFile" value="默认.xppipe" />
<!-- 主界面显示设置 -->
@@ -33,7 +33,7 @@
<add key="License:LicenseState" value="20" />
<!-- Serilog日志配置 -->
<add key="Serilog:LogPath" value="D:\XPData\Diagnostics\Logs" />
<add key="Serilog:LogPath" value="D:\XPData\Runtime\Diagnostics\Logs" />
<add key="Serilog:MinimumLevel" value="Debug" />
<add key="Serilog:EnableConsole" value="true" />
<add key="Serilog:RollingInterval" value="Day" />
@@ -41,7 +41,7 @@
<add key="Serilog:RetainedFileCountLimit" value="365" />
<!-- 数据库SQLite配置 -->
<add key="Sqlite:DbFilePath" value="D:\XPData\DataBase\XP.db" />
<add key="Sqlite:DbFilePath" value="D:\XPData\Runtime\DataBase\XP.db" />
<add key="Sqlite:ConnectionTimeout" value="10" />
<add key="Sqlite:CreateIfNotExists" value="true" />
<!-- 是否启用SQLite WAL模式(提升并发读写性能,默认true) -->
@@ -87,7 +87,7 @@
<!-- 通用配置 | Common Configuration -->
<add key="Detector:IP" value="192.168.1.200" />
<add key="Detector:Port" value="5000" />
<add key="Detector:SavePath" value="D:\XPData\DetectorImages" />
<add key="Detector:SavePath" value="D:\XPData\Results\DetectorImages" />
<add key="Detector:AutoSave" value="true" />
<!-- Simulated 探测器专属配置 | Simulated Detector Specific Configuration -->
<add key="Detector:Simulated:Width" value="256" />
@@ -118,8 +118,8 @@
<add key="DetectorPipeline:ProcessEveryNFrames" value="1" />
<!-- Dump 配置 | Dump Configuration -->
<add key="Dump:StoragePath" value="D:\XPData\Diagnostics\Dumps" />
<add key="Dump:LogPath" value="D:\XPData\Diagnostics\Logs" />
<add key="Dump:StoragePath" value="D:\XPData\Runtime\Diagnostics\Dumps" />
<add key="Dump:LogPath" value="D:\XPData\Runtime\Diagnostics\Logs" />
<add key="Dump:EnableScheduledDump" value="false" />
<add key="Dump:ScheduledIntervalMinutes" value="60" />
<add key="Dump:MiniDumpSizeLimitMB" value="100" />
@@ -216,7 +216,7 @@
<add key="Reconstruction:Mode" value="Planar" />
<!-- 报告输出文件夹路径(绝对路径)| Report output directory (absolute path) -->
<add key="Report:OutputDirectory" value="D:\XPData\Reports" />
<add key="Report:OutputDirectory" value="D:\XPData\Results\Reports" />
<!-- 报告模板文件路径(相对于应用程序目录或绝对路径)| Template file path (relative to app dir or absolute) -->
<add key="Report:TemplatePath" value="Templates\StandardReportTemplate.json" />
<!-- 输出文件名模式 | File name pattern -->
+7 -7
View File
@@ -11,7 +11,7 @@
<add key="UserManual" value="UserManual.pdf" />
<add key="DeviceId" value="PlanerCT001" />
<!-- 流水线默认流程图:启动时自动加载并显示。相对文件名解析到 {XpData:RootPath}\Pipelines 目录 -->
<!-- 流水线默认流程图:启动时自动加载并显示。相对文件名解析到 {XpData:RootPath}\Plans\Pipelines 目录 -->
<add key="Pipeline:DefaultModuleFile" value="默认.xppipe" />
<!-- 检测项目采集:Simulated 用于离线开发,Real 使用运动/射线源/探测器服务 -->
@@ -30,7 +30,7 @@
<add key="License:LicenseState" value="20" />
<!-- Serilog日志配置 -->
<add key="Serilog:LogPath" value="D:\XPData\Diagnostics\Logs" />
<add key="Serilog:LogPath" value="D:\XPData\Runtime\Diagnostics\Logs" />
<add key="Serilog:MinimumLevel" value="Debug" />
<add key="Serilog:EnableConsole" value="true" />
<add key="Serilog:RollingInterval" value="Day" />
@@ -38,7 +38,7 @@
<add key="Serilog:RetainedFileCountLimit" value="365" />
<!-- 数据库SQLite配置 -->
<add key="Sqlite:DbFilePath" value="D:\XPData\DataBase\XP.db" />
<add key="Sqlite:DbFilePath" value="D:\XPData\Runtime\DataBase\XP.db" />
<add key="Sqlite:ConnectionTimeout" value="10" />
<add key="Sqlite:CreateIfNotExists" value="true" />
<!-- 是否启用SQLite WAL模式(提升并发读写性能,默认true) -->
@@ -84,7 +84,7 @@
<!-- 通用配置 | Common Configuration -->
<add key="Detector:IP" value="192.168.1.200" />
<add key="Detector:Port" value="5000" />
<add key="Detector:SavePath" value="D:\XPData\DetectorImages" />
<add key="Detector:SavePath" value="D:\XPData\Results\DetectorImages" />
<add key="Detector:AutoSave" value="true" />
<!-- Simulated 探测器专属配置 | Simulated Detector Specific Configuration -->
<add key="Detector:Simulated:Width" value="256" />
@@ -115,8 +115,8 @@
<add key="DetectorPipeline:ProcessEveryNFrames" value="1" />
<!-- Dump 配置 | Dump Configuration -->
<add key="Dump:StoragePath" value="D:\XPData\Diagnostics\Dumps" />
<add key="Dump:LogPath" value="D:\XPData\Diagnostics\Logs" />
<add key="Dump:StoragePath" value="D:\XPData\Runtime\Diagnostics\Dumps" />
<add key="Dump:LogPath" value="D:\XPData\Runtime\Diagnostics\Logs" />
<add key="Dump:EnableScheduledDump" value="false" />
<add key="Dump:ScheduledIntervalMinutes" value="60" />
<add key="Dump:MiniDumpSizeLimitMB" value="100" />
@@ -217,7 +217,7 @@
<add key="Reconstruction:Mode" value="Planar" />
<!-- 报告输出文件夹路径(绝对路径)| Report output directory (absolute path) -->
<add key="Report:OutputDirectory" value="D:\XPData\Reports" />
<add key="Report:OutputDirectory" value="D:\XPData\Results\Reports" />
<!-- 报告模板文件路径(相对于应用程序目录或绝对路径)| Template file path (relative to app dir or absolute) -->
<add key="Report:TemplatePath" value="Templates\StandardReportTemplate.json" />
<!-- 输出文件名模式 | File name pattern -->
+7 -7
View File
@@ -11,7 +11,7 @@
<add key="UserManual" value="UserManual.pdf" />
<add key="DeviceId" value="PlanerCT001" />
<!-- 流水线默认流程图:启动时自动加载并显示。相对文件名解析到 {XpData:RootPath}\Pipelines 目录 -->
<!-- 流水线默认流程图:启动时自动加载并显示。相对文件名解析到 {XpData:RootPath}\Plans\Pipelines 目录 -->
<add key="Pipeline:DefaultModuleFile" value="默认.xppipe" />
<!-- 主界面显示设置 -->
@@ -33,7 +33,7 @@
<add key="License:LicenseState" value="20" />
<!-- Serilog日志配置 -->
<add key="Serilog:LogPath" value="D:\XPData\Diagnostics\Logs" />
<add key="Serilog:LogPath" value="D:\XPData\Runtime\Diagnostics\Logs" />
<add key="Serilog:MinimumLevel" value="Debug" />
<add key="Serilog:EnableConsole" value="true" />
<add key="Serilog:RollingInterval" value="Day" />
@@ -41,7 +41,7 @@
<add key="Serilog:RetainedFileCountLimit" value="365" />
<!-- 数据库SQLite配置 -->
<add key="Sqlite:DbFilePath" value="D:\XPData\DataBase\XP.db" />
<add key="Sqlite:DbFilePath" value="D:\XPData\Runtime\DataBase\XP.db" />
<add key="Sqlite:ConnectionTimeout" value="10" />
<add key="Sqlite:CreateIfNotExists" value="true" />
<!-- 是否启用SQLite WAL模式(提升并发读写性能,默认true) -->
@@ -87,7 +87,7 @@
<!-- 通用配置 | Common Configuration -->
<add key="Detector:IP" value="192.168.1.200" />
<add key="Detector:Port" value="5000" />
<add key="Detector:SavePath" value="D:\XPData\DetectorImages" />
<add key="Detector:SavePath" value="D:\XPData\Results\DetectorImages" />
<add key="Detector:AutoSave" value="true" />
<!-- Simulated 探测器专属配置 | Simulated Detector Specific Configuration -->
<add key="Detector:Simulated:Width" value="256" />
@@ -118,8 +118,8 @@
<add key="DetectorPipeline:ProcessEveryNFrames" value="1" />
<!-- Dump 配置 | Dump Configuration -->
<add key="Dump:StoragePath" value="D:\XPData\Diagnostics\Dumps" />
<add key="Dump:LogPath" value="D:\XPData\Diagnostics\Logs" />
<add key="Dump:StoragePath" value="D:\XPData\Runtime\Diagnostics\Dumps" />
<add key="Dump:LogPath" value="D:\XPData\Runtime\Diagnostics\Logs" />
<add key="Dump:EnableScheduledDump" value="false" />
<add key="Dump:ScheduledIntervalMinutes" value="60" />
<add key="Dump:MiniDumpSizeLimitMB" value="100" />
@@ -216,7 +216,7 @@
<add key="Reconstruction:Mode" value="Planar" />
<!-- 报告输出文件夹路径(绝对路径)| Report output directory (absolute path) -->
<add key="Report:OutputDirectory" value="D:\XPData\Reports" />
<add key="Report:OutputDirectory" value="D:\XPData\Results\Reports" />
<!-- 报告模板文件路径(相对于应用程序目录或绝对路径)| Template file path (relative to app dir or absolute) -->
<add key="Report:TemplatePath" value="Templates\StandardReportTemplate.json" />
<!-- 输出文件名模式 | File name pattern -->
@@ -53,7 +53,7 @@ namespace XplorePlane.Services.Cnc
public class CncEditSessionStateService : ICncEditSessionStateService, IDisposable
{
private const int AutosaveDebounceMs = 5000;
private const string SessionFileName = ".cnc_session.json";
private const string SessionFileName = @"Runtime\.cnc_session.json";
private const string AutosaveDirName = ".autosave";
private readonly IXpDataPathService _dataPathService; // Xp 数据路径服务
@@ -205,4 +205,4 @@ namespace XplorePlane.Services.Cnc
}
}
}
}
}
@@ -44,9 +44,7 @@ namespace XplorePlane.Services.Inspection
private readonly string _poolDirectory;
public InspectionReferenceAssetService(IXpDataPathService pathService)
: this(Path.Combine(
(pathService ?? throw new ArgumentNullException(nameof(pathService))).RootPath,
"InspectionPool"))
: this((pathService ?? throw new ArgumentNullException(nameof(pathService))).AssetsPath)
{
}
@@ -123,7 +121,7 @@ namespace XplorePlane.Services.Inspection
{
EnsureValidId(definitionId);
cancellationToken.ThrowIfCancellationRequested();
var directory = Path.Combine(_poolDirectory, "Assets", definitionId.ToString("D"));
var directory = Path.Combine(_poolDirectory, "References", definitionId.ToString("D"));
if (Directory.Exists(directory))
Directory.Delete(directory, recursive: true);
return Task.CompletedTask;
@@ -134,7 +132,7 @@ namespace XplorePlane.Services.Inspection
CancellationToken cancellationToken = default)
{
var active = new HashSet<Guid>(activeDefinitionIds ?? Array.Empty<Guid>());
var assetsRoot = Path.Combine(_poolDirectory, "Assets");
var assetsRoot = Path.Combine(_poolDirectory, "References");
if (!Directory.Exists(assetsRoot))
return Task.CompletedTask;
foreach (var directory in Directory.EnumerateDirectories(assetsRoot))
@@ -158,7 +156,7 @@ namespace XplorePlane.Services.Inspection
}
private static string GetRelativePath(Guid id) =>
Path.Combine("Assets", id.ToString("D"), "reference.png");
Path.Combine("References", id.ToString("D"), "reference.png");
private static byte[] EncodePng(BitmapSource image)
{
@@ -175,4 +173,4 @@ namespace XplorePlane.Services.Inspection
throw new ArgumentException("检测项目 ID 不能为空", nameof(id));
}
}
}
}
@@ -93,7 +93,7 @@ namespace XplorePlane.Services.Inspection.Tasks
/// <inheritdoc />
public string GetDefaultReportDirectory()
{
var dir = Path.Combine(_dataPath.RootPath, "Reports");
var dir = _dataPath.ReportPath;
Directory.CreateDirectory(dir);
return dir;
}
@@ -106,4 +106,4 @@ namespace XplorePlane.Services.Inspection.Tasks
return value;
}
}
}
}
@@ -309,7 +309,7 @@ namespace XplorePlane.Services.Main.Recording
/// </summary>
internal static string GetVideoFolderPath(string rootPath)
{
return Path.Combine(rootPath, "VIDEO");
return Path.Combine(rootPath, "Results", "Video");
}
/// <summary>
@@ -666,4 +666,4 @@ namespace XplorePlane.Services.Main.Recording
oldState, newState, errorMessage, savedFilePath));
}
}
}
}
@@ -71,25 +71,25 @@ namespace XplorePlane.Services.Storage
}
}
/// <summary>CNC 程序目录(.xpcnc / .xpz)。</summary>
public string PlanPath => EnsureSubdirectory("CncPrograms");
/// <summary>CNC 计划目录(.xpcnc / .xpz)。</summary>
public string PlanPath => EnsureSubdirectory(Path.Combine("Plans", "CncPrograms"));
/// <summary>图像处理流水线目录(.xppipe)。</summary>
public string ToolsPath => EnsureSubdirectory("Pipelines");
/// <summary>图像处理流水线计划目录(.xppipe)。</summary>
public string ToolsPath => EnsureSubdirectory(Path.Combine("Plans", "Pipelines"));
/// <summary>统一检测执行结果目录。</summary>
public string DataPath => EnsureSubdirectory("InspectionResults");
public string DataPath => EnsureSubdirectory(Path.Combine("Results", "Inspection"));
public string ReportPath => EnsureSubdirectory("Reports");
public string ReportPath => EnsureSubdirectory(Path.Combine("Results", "Reports"));
public string AssetsPath => EnsureSubdirectory("Assets");
public string MatrixResultsPath => EnsureSubdirectory(Path.Combine("InspectionResults", "MatrixResults"));
public string MatrixResultsPath => EnsureSubdirectory(Path.Combine("Results", "Inspection", "MatrixResults"));
public string InspectionPoolPlansPath => EnsureSubdirectory(Path.Combine("InspectionPool", "Plans"));
public string InspectionPoolPlansPath => EnsureSubdirectory(Path.Combine("Plans", "InspectionPool"));
public string InspectionPoolRunsPath => EnsureSubdirectory(Path.Combine("InspectionPool", "Runs"));
public string InspectionPoolRunsPath => EnsureSubdirectory(Path.Combine("Results", "Inspection", "PoolRuns"));
public string DiagnosticsLogsPath => EnsureSubdirectory(Path.Combine("Diagnostics", "Logs"));
@@ -189,21 +189,20 @@ namespace XplorePlane.Services.Storage
private static void EnsureManagedDirectories(string rootPath)
{
Directory.CreateDirectory(rootPath);
Directory.CreateDirectory(Path.Combine(rootPath, "CncPrograms"));
Directory.CreateDirectory(Path.Combine(rootPath, "Pipelines"));
Directory.CreateDirectory(Path.Combine(rootPath, "Assets", "Templates"));
Directory.CreateDirectory(Path.Combine(rootPath, "Plans", "CncPrograms"));
Directory.CreateDirectory(Path.Combine(rootPath, "Plans", "Pipelines"));
Directory.CreateDirectory(Path.Combine(rootPath, "Plans", "InspectionPool"));
Directory.CreateDirectory(Path.Combine(rootPath, "Assets", "Models"));
Directory.CreateDirectory(Path.Combine(rootPath, "InspectionPool", "Plans"));
Directory.CreateDirectory(Path.Combine(rootPath, "InspectionPool", "Runs"));
Directory.CreateDirectory(Path.Combine(rootPath, "InspectionResults"));
Directory.CreateDirectory(Path.Combine(rootPath, "InspectionResults", "MatrixResults"));
Directory.CreateDirectory(Path.Combine(rootPath, "DataBase"));
Directory.CreateDirectory(Path.Combine(rootPath, "DetectorImages"));
Directory.CreateDirectory(Path.Combine(rootPath, "Calibration"));
Directory.CreateDirectory(Path.Combine(rootPath, "Diagnostics", "Logs"));
Directory.CreateDirectory(Path.Combine(rootPath, "Diagnostics", "Dumps"));
Directory.CreateDirectory(Path.Combine(rootPath, "Reports"));
Directory.CreateDirectory(Path.Combine(rootPath, "Video"));
Directory.CreateDirectory(Path.Combine(rootPath, "Runtime", "DataBase"));
Directory.CreateDirectory(Path.Combine(rootPath, "Runtime", "Calibration"));
Directory.CreateDirectory(Path.Combine(rootPath, "Runtime", "Diagnostics", "Logs"));
Directory.CreateDirectory(Path.Combine(rootPath, "Runtime", "Diagnostics", "Dumps"));
Directory.CreateDirectory(Path.Combine(rootPath, "Results", "Inspection"));
Directory.CreateDirectory(Path.Combine(rootPath, "Results", "Inspection", "MatrixResults"));
Directory.CreateDirectory(Path.Combine(rootPath, "Results", "Inspection", "PoolRuns"));
Directory.CreateDirectory(Path.Combine(rootPath, "Results", "DetectorImages"));
Directory.CreateDirectory(Path.Combine(rootPath, "Results", "Reports"));
Directory.CreateDirectory(Path.Combine(rootPath, "Results", "Video"));
}
}
}
@@ -571,7 +571,7 @@ namespace XplorePlane.ViewModels.Main
// 查找 CT.csv:优先数据目录下 Calibration 文件夹,兼容运行目录和旧路径
var dataCalibrationDir = Path.Combine(
System.Configuration.ConfigurationManager.AppSettings["XpData:RootPath"] ?? @"D:\XPData",
"Calibration");
"Runtime", "Calibration");
var appCalibrationDir = Path.Combine(AppContext.BaseDirectory, "Calibration");
// 写入目录始终使用数据目录(避免安装目录权限问题)
var calibrationDir = dataCalibrationDir;
@@ -972,4 +972,4 @@ namespace XplorePlane.ViewModels.Main
#endregion IDisposable
}
}
}
@@ -657,7 +657,7 @@ namespace XplorePlane.ViewModels.Setting
DefaultPipelineFile = GetAppSetting("Pipeline:DefaultModuleFile", "默认.xppipe");
// Serilog日志配置
SerilogLogPath = GetAppSetting("Serilog:LogPath", "D:\\XPData\\Diagnostics\\Logs");
SerilogLogPath = GetAppSetting("Serilog:LogPath", "D:\\XPData\\Runtime\\Diagnostics\\Logs");
SerilogMinimumLevel = GetAppSetting("Serilog:MinimumLevel", "Debug");
SerilogEnableConsole = GetBoolAppSetting("Serilog:EnableConsole", true);
SerilogRollingInterval = GetAppSetting("Serilog:RollingInterval", "Day");
@@ -665,7 +665,7 @@ namespace XplorePlane.ViewModels.Setting
SerilogRetainedFileCountLimit = GetIntAppSetting("Serilog:RetainedFileCountLimit", 365);
// SQLite配置
SqliteDbFilePath = GetAppSetting("Sqlite:DbFilePath", "D:\\XPData\\DataBase\\XP.db");
SqliteDbFilePath = GetAppSetting("Sqlite:DbFilePath", "D:\\XPData\\Runtime\\DataBase\\XP.db");
SqliteConnectionTimeout = GetIntAppSetting("Sqlite:ConnectionTimeout", 10);
SqliteCreateIfNotExists = GetBoolAppSetting("Sqlite:CreateIfNotExists", true);
SqliteEnableWalMode = GetBoolAppSetting("Sqlite:EnableWalMode", true);
@@ -681,7 +681,7 @@ namespace XplorePlane.ViewModels.Setting
DetectorType = GetAppSetting("Detector:Type", "Simulated");
DetectorIP = GetAppSetting("Detector:IP", "192.168.1.200");
DetectorPort = GetIntAppSetting("Detector:Port", 5000);
DetectorSavePath = GetAppSetting("Detector:SavePath", "D:\\XPData\\DetectorImages");
DetectorSavePath = GetAppSetting("Detector:SavePath", "D:\\XPData\\Results\\DetectorImages");
DetectorAutoSave = GetBoolAppSetting("Detector:AutoSave", true);
MainViewportRealtimeEnabledDefault = GetBoolAppSetting("MainViewport:RealtimeEnabledDefault", true);
@@ -697,7 +697,7 @@ namespace XplorePlane.ViewModels.Setting
LoadSafePoint();
// Dump配置
DumpStoragePath = GetAppSetting("Dump:StoragePath", "D:\\XPData\\Diagnostics\\Dumps");
DumpStoragePath = GetAppSetting("Dump:StoragePath", "D:\\XPData\\Runtime\\Diagnostics\\Dumps");
DumpEnableScheduledDump = GetBoolAppSetting("Dump:EnableScheduledDump", false);
DumpScheduledIntervalMinutes = GetIntAppSetting("Dump:ScheduledIntervalMinutes", 60);
DumpRetentionDays = GetIntAppSetting("Dump:RetentionDays", 7);