From d0ade35042cc95d3d1cd819dbf9fd17245a0fe90 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Mon, 26 Jan 2026 16:12:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A2=B0=E6=92=9E=E6=8A=A5?= =?UTF-8?q?=E5=91=8AHTML=E7=94=9F=E6=88=90=E5=99=A8=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=87=AA=E5=8A=A8=E5=AF=BC=E5=87=BAHTML=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NavisworksTransportPlugin.csproj | 1 + .../GenerateCollisionReportCommand.cs | 15 + src/Utils/CollisionReportHtmlGenerator.cs | 296 ++++++++++++++++++ src/Utils/PathHelper.cs | 8 + 4 files changed, 320 insertions(+) create mode 100644 src/Utils/CollisionReportHtmlGenerator.cs diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj index be9c13f..a62c873 100644 --- a/NavisworksTransportPlugin.csproj +++ b/NavisworksTransportPlugin.csproj @@ -175,6 +175,7 @@ + diff --git a/src/Commands/GenerateCollisionReportCommand.cs b/src/Commands/GenerateCollisionReportCommand.cs index ad17679..a8e23a8 100644 --- a/src/Commands/GenerateCollisionReportCommand.cs +++ b/src/Commands/GenerateCollisionReportCommand.cs @@ -269,6 +269,21 @@ namespace NavisworksTransport.Commands // 显示报告(UI线程) ShowReport(result); + + // 🔥 自动导出HTML报告 + try + { + string htmlPath = Utils.CollisionReportHtmlGenerator.AutoSaveHtmlReport(result); + if (!string.IsNullOrEmpty(htmlPath)) + { + LogManager.Info($"HTML报告已自动导出: {htmlPath}"); + } + } + catch (Exception ex) + { + LogManager.Error($"自动导出HTML报告失败: {ex.Message}"); + // HTML导出失败不影响报告生成 + } } catch (OperationCanceledException) { diff --git a/src/Utils/CollisionReportHtmlGenerator.cs b/src/Utils/CollisionReportHtmlGenerator.cs new file mode 100644 index 0000000..f2a310c --- /dev/null +++ b/src/Utils/CollisionReportHtmlGenerator.cs @@ -0,0 +1,296 @@ +using System; +using System.IO; +using System.Linq; +using System.Text; +using NavisworksTransport.Commands; + +namespace NavisworksTransport.Utils +{ + /// + /// 碰撞报告HTML生成器 + /// + public static class CollisionReportHtmlGenerator + { + /// + /// 生成HTML报告内容 + /// + /// 碰撞报告结果 + /// HTML文件路径(用于计算截图相对路径) + /// HTML内容 + public static string GenerateHtmlReport(CollisionReportResult report, string htmlFilePath) + { + if (report == null) + { + throw new ArgumentNullException(nameof(report)); + } + + var html = new StringBuilder(); + var now = DateTime.Now; + + // HTML头部和样式 + html.AppendLine(""); + html.AppendLine(""); + html.AppendLine(""); + html.AppendLine("NavisworksTransport 碰撞检测报告"); + html.AppendLine(""); + html.AppendLine(""); + + // 报告标题 + html.AppendLine($"

NavisworksTransport 碰撞检测报告

"); + html.AppendLine($"

生成时间: {now:yyyy年MM月dd日 HH:mm:ss}

"); + html.AppendLine($"

报告类型: 综合报告

"); + html.AppendLine($"

路径名称: {report.PathName ?? "未知路径"}

"); + + // 总体统计 + html.AppendLine("
"); + html.AppendLine("

总体统计

"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
总碰撞数
"); + html.AppendLine($"
{report.TotalCollisions}
"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
碰撞构件
"); + html.AppendLine($"
{report.UniqueCollidedObjectsCount}个
"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
检测点
"); + html.AppendLine($"
{report.AnimationCollisions}个
"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
"); + + // 动画参数 + html.AppendLine("

动画参数

"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
帧率
"); + html.AppendLine($"
{report.FrameRate} FPS
"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
时长
"); + html.AppendLine($"
{report.Duration:F1} 秒
"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
检测容差
"); + html.AppendLine($"
{report.DetectionTolerance:F2} 米
"); + html.AppendLine("
"); + html.AppendLine("
"); + + // 碰撞场景截图 + if (!string.IsNullOrEmpty(report.ScreenshotPath) && File.Exists(report.ScreenshotPath)) + { + html.AppendLine("

碰撞场景截图

"); + html.AppendLine("
"); + + // 使用 PathHelper 计算相对路径 + string relativePath = PathHelper.GetRelativePath(htmlFilePath, report.ScreenshotPath); + + html.AppendLine("
"); + html.AppendLine($"\"碰撞场景截图\""); + html.AppendLine("
"); + html.AppendLine($"

分辨率: {report.ScreenshotWidth} x {report.ScreenshotHeight}

"); + html.AppendLine($"

格式: {report.ScreenshotFormat}

"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
"); + } + + // 运动构件信息 + if (!string.IsNullOrEmpty(report.MovingObjectInfo)) + { + html.AppendLine("

运动构件信息

"); + html.AppendLine("
"); + html.AppendLine($"🚛 {report.MovingObjectInfo}"); + html.AppendLine("
"); + } + + // 碰撞构件清单 + if (report.CollidedObjectsList?.Count > 0) + { + html.AppendLine("

碰撞构件清单

"); + html.AppendLine("
"); + int index = 1; + foreach (var objName in report.CollidedObjectsList.Take(50)) // 限制显示前50个 + { + html.AppendLine($"
{index}. {objName}
"); + index++; + } + if (report.CollidedObjectsList.Count > 50) + { + html.AppendLine($"
... 还有 {report.CollidedObjectsList.Count - 50} 个构件
"); + } + html.AppendLine("
"); + } + + // 总结与建议 + html.AppendLine("

总结与建议

"); + html.AppendLine("
"); + + // 根据碰撞数量生成总结信息 + string summaryMessage; + if (report.TotalCollisions == 0) + { + summaryMessage = "✅ 未检测到碰撞,路径规划合理,可以安全通行。"; + } + else if (report.TotalCollisions <= 5) + { + summaryMessage = $"⚠️ 检测到 {report.TotalCollisions} 个碰撞,建议优化路径或调整构件位置。"; + } + else + { + summaryMessage = $"🔴 检测到 {report.TotalCollisions} 个碰撞,存在严重安全隐患,必须立即处理。"; + } + + html.AppendLine($"

{summaryMessage}

"); + + // 生成建议措施 + html.AppendLine("

建议措施:

"); + html.AppendLine("
    "); + + if (report.TotalCollisions == 0) + { + html.AppendLine("
  • 保持当前路径规划方案
  • "); + html.AppendLine("
  • 定期检查构件位置变化
  • "); + html.AppendLine("
  • 建议进行现场复核确认
  • "); + } + else + { + html.AppendLine("
  • 检查碰撞构件的实际位置和尺寸
  • "); + html.AppendLine("
  • 优化路径规划,避开碰撞区域
  • "); + html.AppendLine("
  • 调整构件位置或尺寸
  • "); + html.AppendLine("
  • 考虑增加安全间隙
  • "); + html.AppendLine("
  • 进行现场勘察确认
  • "); + } + + html.AppendLine("
"); + html.AppendLine("
"); + + // 详细碰撞信息(前10个) + if (report.AllCollisions?.Count > 0) + { + html.AppendLine("

碰撞详情

"); + int collisionIndex = 1; + foreach (var collision in report.AllCollisions.Take(10)) + { + html.AppendLine("
"); + + // 生成碰撞标题 + string item1Name = collision.Item1 != null ? ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item1) : "未知对象"; + string item2Name = collision.Item2 != null ? ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2) : "未知对象"; + html.AppendLine($"
{collisionIndex}. {item1Name} ↔ {item2Name}
"); + + // 碰撞距离 + html.AppendLine($"

碰撞距离: {collision.Distance:F3} 米

"); + + // 碰撞位置 + if (collision.Center != null) + { + html.AppendLine($"

碰撞位置: ({collision.Center.X:F2}, {collision.Center.Y:F2}, {collision.Center.Z:F2})

"); + } + + html.AppendLine("
"); + collisionIndex++; + } + if (report.AllCollisions.Count > 10) + { + html.AppendLine($"

... 还有 {report.AllCollisions.Count - 10} 个碰撞未显示

"); + } + } + + // HTML结尾 + html.AppendLine($"
"); + html.AppendLine($"

报告生成完成 - {now:HH:mm:ss}

"); + html.AppendLine(""); + + return html.ToString(); + } + + /// + /// 保存HTML报告到文件 + /// + /// 碰撞报告结果 + /// HTML文件保存路径 + /// 是否保存成功 + public static bool SaveHtmlReport(CollisionReportResult report, string htmlFilePath) + { + try + { + // 确保目录存在 + string directory = Path.GetDirectoryName(htmlFilePath); + if (!string.IsNullOrEmpty(directory)) + { + PathHelper.EnsureDirectoryExists(directory); + } + + // 生成HTML内容 + string htmlContent = GenerateHtmlReport(report, htmlFilePath); + + // 保存到文件 + File.WriteAllText(htmlFilePath, htmlContent, System.Text.Encoding.UTF8); + + LogManager.Info($"HTML报告已保存: {htmlFilePath}"); + return true; + } + catch (Exception ex) + { + LogManager.Error($"保存HTML报告失败: {ex.Message}", ex); + return false; + } + } + + /// + /// 自动生成并保存HTML报告到默认目录 + /// + /// 碰撞报告结果 + /// HTML文件路径,失败返回null + public static string AutoSaveHtmlReport(CollisionReportResult report) + { + try + { + // 生成文件名 + string sanitizedName = PathHelper.SanitizeFileName(report.PathName ?? "未知路径"); + string fileName = PathHelper.GenerateTimestampedFileName($"collision_{sanitizedName}", "html"); + + // 获取报告目录 + string reportDir = PathHelper.GetReportDirectory(); + string htmlFilePath = Path.Combine(reportDir, fileName); + + // 保存报告 + if (SaveHtmlReport(report, htmlFilePath)) + { + return htmlFilePath; + } + + return null; + } + catch (Exception ex) + { + LogManager.Error($"自动保存HTML报告失败: {ex.Message}", ex); + return null; + } + } + } +} \ No newline at end of file diff --git a/src/Utils/PathHelper.cs b/src/Utils/PathHelper.cs index f16f3cd..2ea2007 100644 --- a/src/Utils/PathHelper.cs +++ b/src/Utils/PathHelper.cs @@ -33,6 +33,14 @@ namespace NavisworksTransport.Utils return Path.Combine(GetPluginDirectory(), "screenshots"); } + /// + /// 获取报告目录路径 + /// + public static string GetReportDirectory() + { + return Path.Combine(GetPluginDirectory(), "reports"); + } + /// /// 确保目录存在,不存在则创建 ///