- Also regenerate all PathPoint.Id to avoid UNIQUE constraint on PathPoints.Id - Call RecalculateRoute() to rebuild edges with new point references - Edge constructor auto-generates new Id, so edges are fresh too
819 lines
31 KiB
C#
819 lines
31 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using NavisworksTransport.Core;
|
||
|
||
namespace NavisworksTransport.Commands
|
||
{
|
||
/// <summary>
|
||
/// 导入路径参数类
|
||
/// </summary>
|
||
public class ImportPathParameters
|
||
{
|
||
/// <summary>
|
||
/// 导入文件路径
|
||
/// </summary>
|
||
public string FilePath { get; set; }
|
||
|
||
/// <summary>
|
||
/// 导入格式
|
||
/// </summary>
|
||
public ExportFormat ImportFormat { get; set; } = ExportFormat.Xml;
|
||
|
||
/// <summary>
|
||
/// 是否合并到现有路径(false则替换所有路径)
|
||
/// </summary>
|
||
public bool MergeWithExisting { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 重名路径处理策略
|
||
/// </summary>
|
||
public DuplicateNameHandling DuplicateHandling { get; set; } = DuplicateNameHandling.Rename;
|
||
|
||
/// <summary>
|
||
/// 导入前是否创建当前路径的备份
|
||
/// </summary>
|
||
public bool CreateBackup { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 是否验证导入的路径数据
|
||
/// </summary>
|
||
public bool ValidateImportedData { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 导入后是否自动选择第一个路径为当前路径
|
||
/// </summary>
|
||
public bool AutoSelectFirstRoute { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 路径过滤条件(可选)
|
||
/// </summary>
|
||
public Func<PathRoute, bool> RouteFilter { get; set; }
|
||
|
||
/// <summary>
|
||
/// 操作描述
|
||
/// </summary>
|
||
public string Description { get; set; }
|
||
|
||
/// <summary>
|
||
/// 验证参数有效性
|
||
/// </summary>
|
||
public PathPlanningResult ValidateParameters()
|
||
{
|
||
var errors = new List<string>();
|
||
|
||
if (string.IsNullOrWhiteSpace(FilePath))
|
||
{
|
||
errors.Add("导入文件路径不能为空");
|
||
}
|
||
else if (!File.Exists(FilePath))
|
||
{
|
||
errors.Add($"导入文件不存在: {FilePath}");
|
||
}
|
||
else
|
||
{
|
||
// 检查文件扩展名与格式是否匹配
|
||
var extension = Path.GetExtension(FilePath).ToLower();
|
||
var expectedExtensions = ImportFormat == ExportFormat.Json ? new[] { ".json" } : new[] { ".xml" };
|
||
|
||
if (!expectedExtensions.Contains(extension))
|
||
{
|
||
errors.Add($"文件扩展名 '{extension}' 与导入格式 '{ImportFormat}' 不匹配");
|
||
}
|
||
|
||
// 检查文件大小
|
||
try
|
||
{
|
||
var fileInfo = new FileInfo(FilePath);
|
||
if (fileInfo.Length > 100 * 1024 * 1024) // 100MB限制
|
||
{
|
||
errors.Add("导入文件过大(超过100MB限制)");
|
||
}
|
||
else if (fileInfo.Length == 0)
|
||
{
|
||
errors.Add("导入文件为空");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
errors.Add($"无法读取文件信息: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
if (!Enum.IsDefined(typeof(ExportFormat), ImportFormat))
|
||
{
|
||
errors.Add("无效的导入格式");
|
||
}
|
||
|
||
if (!Enum.IsDefined(typeof(DuplicateNameHandling), DuplicateHandling))
|
||
{
|
||
errors.Add("无效的重名处理策略");
|
||
}
|
||
|
||
if (errors.Count > 0)
|
||
{
|
||
return PathPlanningResult.ValidationFailure($"参数验证失败: {string.Join("; ", errors)}");
|
||
}
|
||
|
||
return PathPlanningResult.Success("参数验证通过");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重名路径处理策略
|
||
/// </summary>
|
||
public enum DuplicateNameHandling
|
||
{
|
||
/// <summary>
|
||
/// 重命名新路径
|
||
/// </summary>
|
||
Rename,
|
||
|
||
/// <summary>
|
||
/// 覆盖现有路径
|
||
/// </summary>
|
||
Overwrite,
|
||
|
||
/// <summary>
|
||
/// 跳过重名路径
|
||
/// </summary>
|
||
Skip
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导入路径结果类
|
||
/// </summary>
|
||
public class ImportPathResult
|
||
{
|
||
/// <summary>
|
||
/// 成功导入的路径数量
|
||
/// </summary>
|
||
public int ImportedCount { get; set; }
|
||
|
||
/// <summary>
|
||
/// 跳过的路径数量
|
||
/// </summary>
|
||
public int SkippedCount { get; set; }
|
||
|
||
/// <summary>
|
||
/// 因重名被重命名的路径数量
|
||
/// </summary>
|
||
public int RenamedCount { get; set; }
|
||
|
||
/// <summary>
|
||
/// 失败的路径数量
|
||
/// </summary>
|
||
public int FailedCount { get; set; }
|
||
|
||
/// <summary>
|
||
/// 文件中的总路径数量
|
||
/// </summary>
|
||
public int TotalInFile { get; set; }
|
||
|
||
/// <summary>
|
||
/// 已导入的路径信息
|
||
/// </summary>
|
||
public List<string> ImportedPaths { get; set; }
|
||
|
||
/// <summary>
|
||
/// 跳过的路径信息
|
||
/// </summary>
|
||
public List<string> SkippedPaths { get; set; }
|
||
|
||
/// <summary>
|
||
/// 失败的路径信息
|
||
/// </summary>
|
||
public List<string> FailedPaths { get; set; }
|
||
|
||
/// <summary>
|
||
/// 备份文件路径(如果创建了备份)
|
||
/// </summary>
|
||
public string BackupFilePath { get; set; }
|
||
|
||
/// <summary>
|
||
/// 导入的文件路径
|
||
/// </summary>
|
||
public string ImportedFilePath { get; set; }
|
||
|
||
/// <summary>
|
||
/// 导入格式
|
||
/// </summary>
|
||
public ExportFormat ImportFormat { get; set; }
|
||
|
||
/// <summary>
|
||
/// 操作执行时间(毫秒)
|
||
/// </summary>
|
||
public long ExecutionTimeMs { get; set; }
|
||
|
||
public ImportPathResult()
|
||
{
|
||
ImportedPaths = new List<string>();
|
||
SkippedPaths = new List<string>();
|
||
FailedPaths = new List<string>();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导入成功率
|
||
/// </summary>
|
||
public double ImportSuccessRate => TotalInFile > 0 ? (double)ImportedCount / TotalInFile : 0.0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导入路径Command
|
||
/// </summary>
|
||
public class ImportPathCommand : CommandBase
|
||
{
|
||
#region 字段和属性
|
||
|
||
private readonly ImportPathParameters _parameters;
|
||
private readonly PathPlanningManager _pathPlanningManager;
|
||
private readonly UIStateManager _uiStateManager;
|
||
private readonly PathDataManager _pathDataManager;
|
||
|
||
/// <summary>
|
||
/// 命令参数
|
||
/// </summary>
|
||
public ImportPathParameters Parameters => _parameters;
|
||
|
||
#endregion
|
||
|
||
#region 构造函数
|
||
|
||
/// <summary>
|
||
/// 初始化导入路径命令
|
||
/// </summary>
|
||
/// <param name="parameters">导入参数</param>
|
||
/// <param name="pathPlanningManager">路径规划管理器</param>
|
||
public ImportPathCommand(ImportPathParameters parameters, PathPlanningManager pathPlanningManager = null)
|
||
: base("ImportPath", "导入路径", "从文件导入路径规划数据")
|
||
{
|
||
_parameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
|
||
_pathPlanningManager = pathPlanningManager ?? throw new ArgumentNullException(nameof(pathPlanningManager));
|
||
_uiStateManager = UIStateManager.Instance;
|
||
_pathDataManager = new PathDataManager();
|
||
|
||
LogInfo("导入路径命令初始化完成");
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region CommandBase实现
|
||
|
||
/// <summary>
|
||
/// 验证命令参数
|
||
/// </summary>
|
||
protected override PathPlanningResult ValidateParameters()
|
||
{
|
||
LogInfo("开始验证导入路径参数");
|
||
|
||
try
|
||
{
|
||
// 验证基础参数
|
||
var basicValidation = _parameters.ValidateParameters();
|
||
if (!basicValidation.IsSuccess)
|
||
{
|
||
LogWarning($"基础参数验证失败: {basicValidation.ErrorMessage}");
|
||
return basicValidation;
|
||
}
|
||
|
||
// 验证PathPlanningManager状态
|
||
if (_pathPlanningManager == null)
|
||
{
|
||
return PathPlanningResult.ValidationFailure("路径规划管理器未初始化");
|
||
}
|
||
|
||
// 验证文件格式(尝试解析)
|
||
try
|
||
{
|
||
if (_parameters.ImportFormat == ExportFormat.Xml)
|
||
{
|
||
var testResult = _pathDataManager.ValidateExportFile(_parameters.FilePath, ExportFormat.Xml);
|
||
if (!testResult.IsValid)
|
||
{
|
||
return PathPlanningResult.ValidationFailure($"XML文件格式验证失败: {string.Join("; ", testResult.Errors)}");
|
||
}
|
||
if (testResult.Warnings.Count > 0)
|
||
{
|
||
LogWarning($"XML文件格式警告: {string.Join("; ", testResult.Warnings)}");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception validateEx)
|
||
{
|
||
LogWarning($"文件格式预验证失败: {validateEx.Message}");
|
||
}
|
||
|
||
LogInfo("参数验证通过");
|
||
return PathPlanningResult.Success("所有参数验证通过");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogError("参数验证过程中发生异常", ex);
|
||
return PathPlanningResult.ValidationFailure($"验证过程异常: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 执行导入路径的核心逻辑
|
||
/// </summary>
|
||
protected override async Task<PathPlanningResult> ExecuteInternalAsync(CancellationToken cancellationToken)
|
||
{
|
||
LogInfo("开始执行导入路径");
|
||
var startTime = DateTime.UtcNow;
|
||
|
||
try
|
||
{
|
||
// 第一阶段:初始化(10%)
|
||
UpdateProgress(10, "正在初始化导入操作...");
|
||
ThrowIfCancellationRequested(cancellationToken);
|
||
|
||
// 更新UI状态
|
||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||
{
|
||
LogInfo("UI状态更新:路径导入进行中");
|
||
});
|
||
|
||
var result = new ImportPathResult
|
||
{
|
||
ImportedFilePath = _parameters.FilePath,
|
||
ImportFormat = _parameters.ImportFormat
|
||
};
|
||
|
||
// 第二阶段:创建备份(20%)
|
||
if (_parameters.CreateBackup && _pathPlanningManager.Routes.Count > 0)
|
||
{
|
||
UpdateProgress(20, "正在创建导入前备份...");
|
||
ThrowIfCancellationRequested(cancellationToken);
|
||
|
||
try
|
||
{
|
||
result.BackupFilePath = await CreateBackupAsync(cancellationToken);
|
||
LogInfo($"备份已创建: {result.BackupFilePath}");
|
||
}
|
||
catch (Exception backupEx)
|
||
{
|
||
LogWarning($"创建备份失败: {backupEx.Message}");
|
||
// 备份失败不阻止导入操作,但记录警告
|
||
}
|
||
}
|
||
|
||
// 第三阶段:读取导入文件(30%)
|
||
UpdateProgress(30, "正在读取导入文件...");
|
||
ThrowIfCancellationRequested(cancellationToken);
|
||
|
||
List<PathRoute> importedRoutes = await Task.Run(() => LoadRoutesFromFile(), cancellationToken);
|
||
|
||
if (importedRoutes == null || importedRoutes.Count == 0)
|
||
{
|
||
LogWarning("导入文件中没有找到有效的路径数据");
|
||
return PathPlanningResult.Success("导入文件中没有找到有效的路径数据");
|
||
}
|
||
|
||
result.TotalInFile = importedRoutes.Count;
|
||
LogInfo($"从文件中读取到 {importedRoutes.Count} 个路径");
|
||
|
||
// 第四阶段:应用过滤和验证(40%)
|
||
UpdateProgress(40, "正在验证导入数据...");
|
||
ThrowIfCancellationRequested(cancellationToken);
|
||
|
||
// 应用过滤器
|
||
if (_parameters.RouteFilter != null)
|
||
{
|
||
var originalCount = importedRoutes.Count;
|
||
importedRoutes = importedRoutes.Where(_parameters.RouteFilter).ToList();
|
||
LogInfo($"过滤后剩余 {importedRoutes.Count} 个路径(原始 {originalCount} 个)");
|
||
}
|
||
|
||
// 验证导入的路径
|
||
if (_parameters.ValidateImportedData)
|
||
{
|
||
await Task.Run(() => ValidateImportedRoutes(importedRoutes, result), cancellationToken);
|
||
}
|
||
|
||
// 第五阶段:处理重名和合并(50% - 80%)
|
||
UpdateProgress(50, "正在处理路径合并...");
|
||
ThrowIfCancellationRequested(cancellationToken);
|
||
|
||
await Task.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
LogInfo("开始处理路径导入和合并");
|
||
|
||
// 如果不是合并模式,先清空现有路径
|
||
if (!_parameters.MergeWithExisting)
|
||
{
|
||
var existingRoutesCount = _pathPlanningManager.Routes.Count;
|
||
if (existingRoutesCount > 0)
|
||
{
|
||
LogInfo($"非合并模式:将清空现有的 {existingRoutesCount} 个路径");
|
||
// 注意:这里应该通过PathPlanningManager的方法来清空,但由于架构限制,我们需要小心处理
|
||
// 实际实现可能需要调用PathPlanningManager的相应方法
|
||
}
|
||
}
|
||
|
||
int processedCount = 0;
|
||
foreach (var route in importedRoutes)
|
||
{
|
||
try
|
||
{
|
||
// 检查取消请求
|
||
ThrowIfCancellationRequested(cancellationToken);
|
||
|
||
bool shouldImport = true;
|
||
string finalRouteName = route.Name;
|
||
|
||
// 处理重名
|
||
if (_pathPlanningManager.Routes.Any(r => r.Name == route.Name))
|
||
{
|
||
switch (_parameters.DuplicateHandling)
|
||
{
|
||
case DuplicateNameHandling.Skip:
|
||
shouldImport = false;
|
||
result.SkippedCount++;
|
||
result.SkippedPaths.Add($"{route.Name} - 重名跳过");
|
||
LogInfo($"跳过重名路径: {route.Name}");
|
||
break;
|
||
|
||
case DuplicateNameHandling.Rename:
|
||
{
|
||
var originalName = route.Name;
|
||
finalRouteName = GenerateUniqueName(originalName, _pathPlanningManager.Routes);
|
||
route.Name = finalRouteName;
|
||
route.Id = Guid.NewGuid().ToString();
|
||
foreach (var pt in route.Points)
|
||
{
|
||
pt.Id = Guid.NewGuid().ToString();
|
||
}
|
||
route.RecalculateRoute("导入重命名");
|
||
if (finalRouteName != originalName)
|
||
{
|
||
result.RenamedCount++;
|
||
LogInfo($"重命名路径: {originalName} -> {finalRouteName}");
|
||
}
|
||
break;
|
||
}
|
||
|
||
case DuplicateNameHandling.Overwrite:
|
||
// 先删除现有的同名路径
|
||
var existingRoute = _pathPlanningManager.Routes.FirstOrDefault(r => r.Name == route.Name);
|
||
if (existingRoute != null)
|
||
{
|
||
_pathPlanningManager.DeleteRoute(existingRoute);
|
||
LogInfo($"覆盖现有路径: {route.Name}");
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (shouldImport)
|
||
{
|
||
// 导入路径
|
||
bool addSuccess = _pathPlanningManager.AddRoute(route);
|
||
|
||
if (addSuccess)
|
||
{
|
||
result.ImportedCount++;
|
||
result.ImportedPaths.Add($"{finalRouteName} ({route.Points.Count} 个点)");
|
||
LogInfo($"成功导入路径: {finalRouteName}");
|
||
}
|
||
else
|
||
{
|
||
result.FailedCount++;
|
||
result.FailedPaths.Add($"{finalRouteName} - 添加失败");
|
||
LogWarning($"添加路径失败: {finalRouteName}");
|
||
}
|
||
}
|
||
|
||
processedCount++;
|
||
|
||
// 更新进度(50% - 80%)
|
||
var progressPercent = 50 + (int)((double)processedCount / importedRoutes.Count * 30);
|
||
UpdateProgress(progressPercent, $"正在导入路径... ({processedCount}/{importedRoutes.Count})");
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
throw; // 重新抛出取消异常
|
||
}
|
||
catch (Exception routeEx)
|
||
{
|
||
result.FailedCount++;
|
||
result.FailedPaths.Add($"{route.Name} - 异常: {routeEx.Message}");
|
||
LogError($"导入路径时发生异常: {route.Name}", routeEx);
|
||
}
|
||
}
|
||
|
||
LogInfo($"路径导入完成 - 导入: {result.ImportedCount}, 失败: {result.FailedCount}, 跳过: {result.SkippedCount}");
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
LogInfo("路径导入被用户取消");
|
||
throw; // 重新抛出取消异常
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogError("批量导入路径时发生异常", ex);
|
||
throw;
|
||
}
|
||
}, cancellationToken);
|
||
|
||
UpdateProgress(85, "正在完成导入操作...");
|
||
ThrowIfCancellationRequested(cancellationToken);
|
||
|
||
// 完成(100%)
|
||
UpdateProgress(100, "路径导入完成");
|
||
|
||
var elapsedMs = (DateTime.UtcNow - startTime).TotalMilliseconds;
|
||
result.ExecutionTimeMs = (long)elapsedMs;
|
||
|
||
LogInfo($"导入路径执行完成,总耗时: {elapsedMs:F0}ms");
|
||
LogInfo($"导入结果 - 文件中: {result.TotalInFile}, 导入: {result.ImportedCount}, 失败: {result.FailedCount}, 跳过: {result.SkippedCount}, 重命名: {result.RenamedCount}");
|
||
|
||
// 创建结果对象
|
||
string resultMessage;
|
||
if (result.TotalInFile == 0)
|
||
{
|
||
resultMessage = "导入文件中没有找到路径数据";
|
||
}
|
||
else
|
||
{
|
||
resultMessage = $"路径导入完成:导入 {result.ImportedCount}/{result.TotalInFile} 项";
|
||
if (result.FailedCount > 0)
|
||
{
|
||
resultMessage += $",失败 {result.FailedCount} 项";
|
||
}
|
||
if (result.SkippedCount > 0)
|
||
{
|
||
resultMessage += $",跳过 {result.SkippedCount} 项";
|
||
}
|
||
if (result.RenamedCount > 0)
|
||
{
|
||
resultMessage += $",重命名 {result.RenamedCount} 项";
|
||
}
|
||
}
|
||
|
||
var commandResult = PathPlanningResult<ImportPathResult>.Success(result, resultMessage);
|
||
commandResult.ElapsedMilliseconds = (long)elapsedMs;
|
||
return commandResult;
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
LogInfo("导入路径被用户取消");
|
||
throw; // 让基类处理取消异常
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
var elapsedMs = (DateTime.UtcNow - startTime).TotalMilliseconds;
|
||
LogError($"导入路径执行失败,已耗时: {elapsedMs:F0}ms", ex);
|
||
|
||
// 尝试恢复UI状态
|
||
try
|
||
{
|
||
await _uiStateManager.ExecuteUIUpdateAsync(() =>
|
||
{
|
||
LogInfo("尝试恢复UI状态");
|
||
});
|
||
}
|
||
catch (Exception uiEx)
|
||
{
|
||
LogError("UI状态恢复失败", uiEx);
|
||
}
|
||
|
||
return PathPlanningResult.Failure($"导入路径失败: {ex.Message}", ex);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 私有辅助方法
|
||
|
||
/// <summary>
|
||
/// 从文件加载路径
|
||
/// </summary>
|
||
private List<PathRoute> LoadRoutesFromFile()
|
||
{
|
||
try
|
||
{
|
||
LogInfo($"开始从文件加载路径: {_parameters.FilePath}");
|
||
|
||
List<PathRoute> routes;
|
||
if (_parameters.ImportFormat == ExportFormat.Json)
|
||
{
|
||
routes = _pathDataManager.ImportFromJson(_parameters.FilePath);
|
||
}
|
||
else
|
||
{
|
||
routes = _pathDataManager.ImportFromXml(_parameters.FilePath);
|
||
}
|
||
|
||
LogInfo($"从文件加载了 {routes?.Count ?? 0} 个路径");
|
||
return routes ?? new List<PathRoute>();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogError("从文件加载路径失败", ex);
|
||
throw new InvalidOperationException($"读取导入文件失败: {ex.Message}", ex);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证导入的路径
|
||
/// </summary>
|
||
private void ValidateImportedRoutes(List<PathRoute> routes, ImportPathResult result)
|
||
{
|
||
LogInfo("开始验证导入的路径数据");
|
||
|
||
var invalidRoutes = new List<PathRoute>();
|
||
foreach (var route in routes)
|
||
{
|
||
try
|
||
{
|
||
// 使用PathPlanningManager的验证方法
|
||
var validationResult = _pathPlanningManager.ValidateRoute(route);
|
||
if (!validationResult.IsSuccess)
|
||
{
|
||
invalidRoutes.Add(route);
|
||
result.FailedPaths.Add($"{route.Name} - 验证失败: {validationResult.ErrorMessage}");
|
||
LogWarning($"路径验证失败: {route.Name} - {validationResult.ErrorMessage}");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
invalidRoutes.Add(route);
|
||
result.FailedPaths.Add($"{route.Name} - 验证异常: {ex.Message}");
|
||
LogError($"验证路径时发生异常: {route.Name}", ex);
|
||
}
|
||
}
|
||
|
||
// 从导入列表中移除无效路径
|
||
foreach (var invalidRoute in invalidRoutes)
|
||
{
|
||
routes.Remove(invalidRoute);
|
||
result.FailedCount++;
|
||
}
|
||
|
||
LogInfo($"路径验证完成,有效路径: {routes.Count}, 无效路径: {invalidRoutes.Count}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成唯一名称
|
||
/// </summary>
|
||
private string GenerateUniqueName(string baseName, IEnumerable<PathRoute> existingRoutes)
|
||
{
|
||
var existingNames = existingRoutes.Select(r => r.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||
|
||
if (!existingNames.Contains(baseName))
|
||
{
|
||
return baseName;
|
||
}
|
||
|
||
int counter = 1;
|
||
string newName;
|
||
do
|
||
{
|
||
newName = $"{baseName}_{counter}";
|
||
counter++;
|
||
} while (existingNames.Contains(newName));
|
||
|
||
return newName;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建导入前备份
|
||
/// </summary>
|
||
private async Task<string> CreateBackupAsync(CancellationToken cancellationToken)
|
||
{
|
||
try
|
||
{
|
||
var backupFileName = $"路径导入前备份_{DateTime.Now:yyyyMMdd_HHmmss}.xml";
|
||
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
|
||
var backupPath = Path.Combine(documentsPath, "NavisworksTransport", "Backups");
|
||
|
||
if (!Directory.Exists(backupPath))
|
||
{
|
||
Directory.CreateDirectory(backupPath);
|
||
}
|
||
|
||
var backupFilePath = Path.Combine(backupPath, backupFileName);
|
||
|
||
var exportSettings = new ExportSettings
|
||
{
|
||
ProjectName = "导入前备份",
|
||
Description = $"导入 {Path.GetFileName(_parameters.FilePath)} 前的备份",
|
||
Units = "meters"
|
||
};
|
||
|
||
await Task.Run(() =>
|
||
{
|
||
bool success = _pathDataManager.ExportToXml(_pathPlanningManager.Routes.ToList(), backupFilePath, exportSettings);
|
||
if (!success)
|
||
{
|
||
throw new InvalidOperationException("备份文件创建失败");
|
||
}
|
||
}, cancellationToken);
|
||
|
||
return backupFilePath;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogError("创建备份文件失败", ex);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 公共方法
|
||
|
||
/// <summary>
|
||
/// 创建导入XML文件的快捷命令
|
||
/// </summary>
|
||
/// <param name="filePath">XML文件路径</param>
|
||
/// <param name="mergeWithExisting">是否合并到现有路径</param>
|
||
/// <param name="createBackup">是否创建备份</param>
|
||
/// <returns>导入路径命令实例</returns>
|
||
public static ImportPathCommand CreateXmlImport(string filePath, bool mergeWithExisting = true, bool createBackup = true)
|
||
{
|
||
var parameters = new ImportPathParameters
|
||
{
|
||
FilePath = filePath,
|
||
ImportFormat = ExportFormat.Xml,
|
||
MergeWithExisting = mergeWithExisting,
|
||
CreateBackup = createBackup,
|
||
DuplicateHandling = DuplicateNameHandling.Rename,
|
||
ValidateImportedData = true,
|
||
AutoSelectFirstRoute = true,
|
||
Description = $"导入XML文件: {Path.GetFileName(filePath)}"
|
||
};
|
||
|
||
return new ImportPathCommand(parameters);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建导入JSON文件的快捷命令
|
||
/// </summary>
|
||
/// <param name="filePath">JSON文件路径</param>
|
||
/// <param name="mergeWithExisting">是否合并到现有路径</param>
|
||
/// <param name="createBackup">是否创建备份</param>
|
||
/// <returns>导入路径命令实例</returns>
|
||
public static ImportPathCommand CreateJsonImport(string filePath, bool mergeWithExisting = true, bool createBackup = true)
|
||
{
|
||
var parameters = new ImportPathParameters
|
||
{
|
||
FilePath = filePath,
|
||
ImportFormat = ExportFormat.Json,
|
||
MergeWithExisting = mergeWithExisting,
|
||
CreateBackup = createBackup,
|
||
DuplicateHandling = DuplicateNameHandling.Rename,
|
||
ValidateImportedData = true,
|
||
AutoSelectFirstRoute = true,
|
||
Description = $"导入JSON文件: {Path.GetFileName(filePath)}"
|
||
};
|
||
|
||
return new ImportPathCommand(parameters);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建带过滤器的导入命令
|
||
/// </summary>
|
||
/// <param name="filePath">文件路径</param>
|
||
/// <param name="routeFilter">路径过滤器</param>
|
||
/// <param name="duplicateHandling">重名处理策略</param>
|
||
/// <returns>导入路径命令实例</returns>
|
||
public static ImportPathCommand CreateWithFilter(string filePath, Func<PathRoute, bool> routeFilter, DuplicateNameHandling duplicateHandling = DuplicateNameHandling.Rename)
|
||
{
|
||
var parameters = new ImportPathParameters
|
||
{
|
||
FilePath = filePath,
|
||
ImportFormat = Path.GetExtension(filePath).ToLower() == ".json" ? ExportFormat.Json : ExportFormat.Xml,
|
||
MergeWithExisting = true,
|
||
CreateBackup = true,
|
||
DuplicateHandling = duplicateHandling,
|
||
ValidateImportedData = true,
|
||
AutoSelectFirstRoute = true,
|
||
RouteFilter = routeFilter,
|
||
Description = $"带过滤器导入文件: {Path.GetFileName(filePath)}"
|
||
};
|
||
|
||
return new ImportPathCommand(parameters);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取命令执行摘要信息
|
||
/// </summary>
|
||
/// <returns>命令信息摘要</returns>
|
||
public string GetExecutionSummary()
|
||
{
|
||
return $"导入路径命令 - 文件:{Path.GetFileName(_parameters.FilePath ?? "未指定")}, " +
|
||
$"格式:{_parameters.ImportFormat}, " +
|
||
$"合并:{_parameters.MergeWithExisting}, " +
|
||
$"重名处理:{_parameters.DuplicateHandling}, " +
|
||
$"状态:{Status}";
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |