fix: F1 批处理回写主库检测记录(历史表格碰撞数 0 问题)+ 通道排除诊断

问题1(历史表格碰撞数 0):
- F1 副实例检测结果只更新队列表,主库 CollisionDetectionRecords
  未更新(批处理创建快照时 CollisionCount=0)→ 动画检测历史表格显示 0
- 修复:F1 完成后 UpdateCollisionDetectionResult 回写主库记录
  (testName=F1副实例检测_{route}_{itemId})
- 配套:测试端点 batch-queue-add 创建检测记录(与 UI 一致);
  UpdateBatchQueueItemAsync 的 UPDATE 补 DetectionRecordId 列

问题2(通道被碰撞):
- 副实例通道缓存正常(3 个可通行 = 用户设置),非通道对象 689 个
- 增加通道诊断日志:副实例检测完成后打印通道对象/碰撞对象/
  碰撞中含通道对比(验证楼板等通道是否被正确排除)
- 测试模型验证:碰撞中含通道 0 个(排除正常)

验证:F1 测试 30 秒通过,回写日志确认(Id=534 碰撞 12)
This commit is contained in:
tian 2026-08-06 18:33:42 +08:00
parent 68776ef22e
commit 6b13e3126b
3 changed files with 82 additions and 1 deletions

View File

@ -629,6 +629,29 @@ namespace NavisworksTransport.Core
} }
LogManager.Info($"[F2映射] 完成: {mappedCount}/{detection.CollidedObjectMappings.Count} 个碰撞对象映射到主模型"); LogManager.Info($"[F2映射] 完成: {mappedCount}/{detection.CollidedObjectMappings.Count} 个碰撞对象映射到主模型");
// 🔥 回写主库检测记录:副实例检测结果更新到主 NW 的 CollisionDetectionRecords
// (批处理创建快照时 CollisionCount=0动画检测历史表格读主库——不回写则显示 0
if (item.DetectionRecordId.HasValue)
{
try
{
_database.UpdateCollisionDetectionResult(
item.DetectionRecordId.Value,
testName: $"F1副实例检测_{pathRoute.Name}_{item.Id}",
collisionCount: detection.TotalCollisions,
animationCollisionCount: detection.TotalCollisions);
LogManager.Info($"[批处理] 已回写主库检测记录: DetectionRecordId={item.DetectionRecordId}, 碰撞数={detection.TotalCollisions}");
}
catch (Exception recordEx)
{
LogManager.Warning($"[批处理] 回写检测记录失败: {recordEx.Message}");
}
}
else
{
LogManager.Warning($"[批处理] F1 任务缺少 DetectionRecordId无法回写检测记录 (itemId={item.Id})");
}
// F3清理副实例临时工作目录导出模型/临时库/路径文件);副实例刚关闭,文件锁可能未释放,带重试 // F3清理副实例临时工作目录导出模型/临时库/路径文件);副实例刚关闭,文件锁可能未释放,带重试
string workDirectory = Path.Combine(Path.GetTempPath(), "NavisworksTransportBatch", $"item-{item.Id}"); string workDirectory = Path.Combine(Path.GetTempPath(), "NavisworksTransportBatch", $"item-{item.Id}");
for (int cleanupAttempt = 0; cleanupAttempt < 3; cleanupAttempt++) for (int cleanupAttempt = 0; cleanupAttempt < 3; cleanupAttempt++)

View File

@ -3166,7 +3166,8 @@ namespace NavisworksTransport
cmd.CommandText = @" cmd.CommandText = @"
UPDATE BatchQueueItems UPDATE BatchQueueItems
SET Status = @Status, StartTime = @StartTime, EndTime = @EndTime, ErrorMessage = @ErrorMessage, SET Status = @Status, StartTime = @StartTime, EndTime = @EndTime, ErrorMessage = @ErrorMessage,
ClashDetectiveTestName = @ClashDetectiveTestName, CollisionCount = @CollisionCount ClashDetectiveTestName = @ClashDetectiveTestName, CollisionCount = @CollisionCount,
DetectionRecordId = @DetectionRecordId
WHERE Id = @Id"; WHERE Id = @Id";
cmd.Parameters.AddWithValue("@Status", item.Status.ToString()); cmd.Parameters.AddWithValue("@Status", item.Status.ToString());
@ -3175,6 +3176,7 @@ namespace NavisworksTransport
cmd.Parameters.AddWithValue("@ErrorMessage", item.ErrorMessage ?? ""); cmd.Parameters.AddWithValue("@ErrorMessage", item.ErrorMessage ?? "");
cmd.Parameters.AddWithValue("@ClashDetectiveTestName", item.ClashDetectiveTestName ?? ""); cmd.Parameters.AddWithValue("@ClashDetectiveTestName", item.ClashDetectiveTestName ?? "");
cmd.Parameters.AddWithValue("@CollisionCount", item.CollisionCount ?? (object)DBNull.Value); cmd.Parameters.AddWithValue("@CollisionCount", item.CollisionCount ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("@DetectionRecordId", item.DetectionRecordId ?? (object)DBNull.Value);
cmd.Parameters.AddWithValue("@Id", item.Id); cmd.Parameters.AddWithValue("@Id", item.Id);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();

View File

@ -1177,6 +1177,40 @@ namespace NavisworksTransport.Core.Services
int itemId = await manager.AddQueueItemAsync(item).ConfigureAwait(false); int itemId = await manager.AddQueueItemAsync(item).ConfigureAwait(false);
// 创建检测记录(与 UI“加入批处理”一致F1 副实例检测结果回写主库检测记录
// (动画检测历史表格读主库 CollisionDetectionRecords
int? detectionRecordId = null;
try
{
var pathDatabase = pathManager?.GetPathDatabase();
if (pathDatabase != null)
{
var record = new NavisworksTransport.CollisionDetectionRecord
{
RouteId = route.Id,
CreatedTime = DateTime.Now,
FrameRate = frameRate,
DurationSeconds = durationSeconds,
IsVirtualObject = isVirtualObject,
AnimatedObjectName = isVirtualObject ? "虚拟物体" : movingObjectName,
DetectAllObjects = true,
Description = $"测试批处理添加于 {DateTime.Now:yyyy-MM-dd HH:mm:ss}",
TestName = $"批处理任务创建_{DateTime.Now:MMdd_HHmmssfff}",
TestTime = DateTime.Now,
CollisionCount = 0,
AnimationCollisionCount = 0
};
detectionRecordId = pathDatabase.SaveCollisionDetectionRecord(record);
item.DetectionRecordId = detectionRecordId;
await manager.GetDatabase().UpdateBatchQueueItemAsync(item).ConfigureAwait(false);
LogManager.Info($"[测试HTTP] 批处理项已创建检测记录 (Id={detectionRecordId}, itemId={itemId})");
}
}
catch (Exception recordEx)
{
LogManager.Warning($"[测试HTTP] 创建批处理检测记录失败: {recordEx.Message}");
}
// 真实物体:主实例解析名字并写入 MovingObject 引用BatchQueueItems 表无 MovingObjectName 列, // 真实物体:主实例解析名字并写入 MovingObject 引用BatchQueueItems 表无 MovingObjectName 列,
// F1 副实例检测从 ModelItemReferences 读取移动物体名) // F1 副实例检测从 ModelItemReferences 读取移动物体名)
if (!isVirtualObject) if (!isVirtualObject)
@ -1578,6 +1612,28 @@ namespace NavisworksTransport.Core.Services
PathAnimationManager animationManager = PathAnimationManager.GetInstance(); PathAnimationManager animationManager = PathAnimationManager.GetInstance();
CollisionReportResult report = animationVm.LastGeneratedReport; CollisionReportResult report = animationVm.LastGeneratedReport;
// 🔥 通道排除诊断:打印通道对象 vs 碰撞对象对比(验证楼板等通道是否被正确排除)
try
{
var channelCache = ClashDetectiveIntegration.GetChannelObjectsCache();
var collidedNames = report?.AllCollisions?.Select(c => c.Item2?.DisplayName)
.Where(n => !string.IsNullOrWhiteSpace(n))
.Distinct()
.ToList() ?? new List<string>();
var channelNames = channelCache?.Select(c => c.DisplayName)
.Where(n => !string.IsNullOrWhiteSpace(n))
.Distinct()
.ToList() ?? new List<string>();
var channelHit = collidedNames.Intersect(channelNames, StringComparer.OrdinalIgnoreCase).ToList();
LogManager.Info($"[通道诊断] 通道对象({channelNames.Count})={string.Join(", ", channelNames)}");
LogManager.Info($"[通道诊断] 碰撞对象({collidedNames.Count})={string.Join(", ", collidedNames)}");
LogManager.Info($"[通道诊断] 碰撞中含通道: {channelHit.Count} 个 = {string.Join(", ", channelHit)}");
}
catch (Exception diagEx)
{
LogManager.Warning($"[通道诊断] 输出失败: {diagEx.Message}");
}
return new return new
{ {
route = setupResult.route, route = setupResult.route,