对矩阵测量程序,增加模板CNC的存储

This commit is contained in:
zhengxuan.zhang
2026-06-03 11:37:33 +08:00
parent db0994e91b
commit 8626cd6f1b
3 changed files with 66 additions and 4 deletions
+2 -1
View File
@@ -40,7 +40,8 @@ namespace XplorePlane.Models
double StartOffsetX,
double StartOffsetY,
string CncProgramPath,
IReadOnlyList<MatrixCell> Cells
IReadOnlyList<MatrixCell> Cells,
string CncProgramContent = null
);
// ── 矩阵执行摘要模型(用于 matrix_summary.json 序列化)────────────
+10 -2
View File
@@ -7,6 +7,7 @@ using System.Text.Json.Serialization;
using System.Threading.Tasks;
using XP.Common.Logging.Interfaces;
using XplorePlane.Models;
using XplorePlane.Services.Cnc;
namespace XplorePlane.Services.Matrix
{
@@ -19,6 +20,7 @@ namespace XplorePlane.Services.Matrix
public class MatrixService : IMatrixService
{
private readonly ILoggerService _logger;
private readonly ICncProgramService _cncProgramService;
// ── 序列化配置 | Serialization options ──
private static readonly JsonSerializerOptions MatrixJsonOptions = new()
@@ -29,11 +31,13 @@ namespace XplorePlane.Services.Matrix
Converters = { new JsonStringEnumConverter() }
};
public MatrixService(ILoggerService logger)
public MatrixService(ILoggerService logger, ICncProgramService cncProgramService)
{
ArgumentNullException.ThrowIfNull(logger);
ArgumentNullException.ThrowIfNull(cncProgramService);
_logger = logger.ForModule<MatrixService>();
_cncProgramService = cncProgramService;
_logger.Info("MatrixService 已初始化 | MatrixService initialized");
}
@@ -130,7 +134,11 @@ namespace XplorePlane.Services.Matrix
// 优先使用传入的文件路径(绝对路径),否则回退到程序名
var programPath = !string.IsNullOrWhiteSpace(filePath) ? filePath : program.Name;
var updated = layout with { CncProgramPath = programPath };
// 序列化 CNC 程序内容嵌入矩阵布局,便于直接运行无需依赖外部文件
var programContent = _cncProgramService.Serialize(program);
var updated = layout with { CncProgramPath = programPath, CncProgramContent = programContent };
_logger.Info("已关联 CNC 程序到矩阵布局 | Associated CNC program with matrix layout: LayoutId={LayoutId}, Program={ProgramPath}",
layout.Id, programPath);
@@ -3,6 +3,7 @@ using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
@@ -524,7 +525,23 @@ namespace XplorePlane.ViewModels.Cnc
CncProgram templateProgram;
try
{
templateProgram = await _cncProgramService.LoadAsync(AssociatedProgramPath);
// 优先从文件加载,文件不存在时回退到嵌入的 CNC 内容
// Prefer loading from file; fall back to embedded CNC content if file is missing
if (File.Exists(AssociatedProgramPath))
{
templateProgram = await _cncProgramService.LoadAsync(AssociatedProgramPath);
}
else if (!string.IsNullOrWhiteSpace(_currentLayout.CncProgramContent))
{
templateProgram = _cncProgramService.Deserialize(_currentLayout.CncProgramContent);
_logger.Info("CNC 文件不存在,使用嵌入内容运行 | CNC file not found, using embedded content: {Path}", AssociatedProgramPath);
}
else
{
MessageBox.Show($"无法加载程序文件:{AssociatedProgramName}\n文件不存在且矩阵方案中未嵌入程序内容,请重新关联。",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
}
catch (Exception ex)
{
@@ -594,6 +611,10 @@ namespace XplorePlane.ViewModels.Cnc
}
finally
{
// 将 ViewModel 中的执行状态同步回 _currentLayout,确保保存时反映实际执行结果
// Sync execution status from ViewModels back to _currentLayout so saves reflect actual results
SyncCellStatusToLayout();
IsExecuting = false;
_executionCts?.Dispose();
_executionCts = null;
@@ -641,5 +662,37 @@ namespace XplorePlane.ViewModels.Cnc
SelectedCell = match ?? Cells.FirstOrDefault();
}
}
/// <summary>
/// 将 ViewModel 中各单元格的执行状态同步回 _currentLayout 不可变模型。
/// 执行后调用,确保保存矩阵时 Status/ErrorMessage 字段反映实际执行结果。
/// Sync cell execution status from ViewModels back to the immutable _currentLayout model.
/// Called after execution to ensure saved matrix reflects actual execution results.
/// </summary>
private void SyncCellStatusToLayout()
{
if (_currentLayout == null || Cells == null || Cells.Count == 0)
return;
var updatedCells = new List<MatrixCell>(_currentLayout.Cells.Count);
foreach (var original in _currentLayout.Cells)
{
var cellVm = Cells.FirstOrDefault(c => c.Row == original.Row && c.Column == original.Column);
if (cellVm != null)
{
updatedCells.Add(original with
{
Status = cellVm.Status,
ErrorMessage = cellVm.ErrorMessage ?? original.ErrorMessage
});
}
else
{
updatedCells.Add(original);
}
}
_currentLayout = _currentLayout with { Cells = updatedCells.AsReadOnly() };
}
}
}