对矩阵测量程序,增加模板CNC的存储
This commit is contained in:
@@ -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 序列化)────────────
|
||||
|
||||
@@ -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() };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user