对矩阵测量程序,增加模板CNC的存储
This commit is contained in:
@@ -40,7 +40,8 @@ namespace XplorePlane.Models
|
|||||||
double StartOffsetX,
|
double StartOffsetX,
|
||||||
double StartOffsetY,
|
double StartOffsetY,
|
||||||
string CncProgramPath,
|
string CncProgramPath,
|
||||||
IReadOnlyList<MatrixCell> Cells
|
IReadOnlyList<MatrixCell> Cells,
|
||||||
|
string CncProgramContent = null
|
||||||
);
|
);
|
||||||
|
|
||||||
// ── 矩阵执行摘要模型(用于 matrix_summary.json 序列化)────────────
|
// ── 矩阵执行摘要模型(用于 matrix_summary.json 序列化)────────────
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Text.Json.Serialization;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using XP.Common.Logging.Interfaces;
|
using XP.Common.Logging.Interfaces;
|
||||||
using XplorePlane.Models;
|
using XplorePlane.Models;
|
||||||
|
using XplorePlane.Services.Cnc;
|
||||||
|
|
||||||
namespace XplorePlane.Services.Matrix
|
namespace XplorePlane.Services.Matrix
|
||||||
{
|
{
|
||||||
@@ -19,6 +20,7 @@ namespace XplorePlane.Services.Matrix
|
|||||||
public class MatrixService : IMatrixService
|
public class MatrixService : IMatrixService
|
||||||
{
|
{
|
||||||
private readonly ILoggerService _logger;
|
private readonly ILoggerService _logger;
|
||||||
|
private readonly ICncProgramService _cncProgramService;
|
||||||
|
|
||||||
// ── 序列化配置 | Serialization options ──
|
// ── 序列化配置 | Serialization options ──
|
||||||
private static readonly JsonSerializerOptions MatrixJsonOptions = new()
|
private static readonly JsonSerializerOptions MatrixJsonOptions = new()
|
||||||
@@ -29,11 +31,13 @@ namespace XplorePlane.Services.Matrix
|
|||||||
Converters = { new JsonStringEnumConverter() }
|
Converters = { new JsonStringEnumConverter() }
|
||||||
};
|
};
|
||||||
|
|
||||||
public MatrixService(ILoggerService logger)
|
public MatrixService(ILoggerService logger, ICncProgramService cncProgramService)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(logger);
|
ArgumentNullException.ThrowIfNull(logger);
|
||||||
|
ArgumentNullException.ThrowIfNull(cncProgramService);
|
||||||
|
|
||||||
_logger = logger.ForModule<MatrixService>();
|
_logger = logger.ForModule<MatrixService>();
|
||||||
|
_cncProgramService = cncProgramService;
|
||||||
|
|
||||||
_logger.Info("MatrixService 已初始化 | MatrixService initialized");
|
_logger.Info("MatrixService 已初始化 | MatrixService initialized");
|
||||||
}
|
}
|
||||||
@@ -130,7 +134,11 @@ namespace XplorePlane.Services.Matrix
|
|||||||
|
|
||||||
// 优先使用传入的文件路径(绝对路径),否则回退到程序名
|
// 优先使用传入的文件路径(绝对路径),否则回退到程序名
|
||||||
var programPath = !string.IsNullOrWhiteSpace(filePath) ? filePath : program.Name;
|
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}",
|
_logger.Info("已关联 CNC 程序到矩阵布局 | Associated CNC program with matrix layout: LayoutId={LayoutId}, Program={ProgramPath}",
|
||||||
layout.Id, programPath);
|
layout.Id, programPath);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Prism.Commands;
|
|||||||
using Prism.Events;
|
using Prism.Events;
|
||||||
using Prism.Mvvm;
|
using Prism.Mvvm;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -523,9 +524,25 @@ namespace XplorePlane.ViewModels.Cnc
|
|||||||
|
|
||||||
CncProgram templateProgram;
|
CncProgram templateProgram;
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
// 优先从文件加载,文件不存在时回退到嵌入的 CNC 内容
|
||||||
|
// Prefer loading from file; fall back to embedded CNC content if file is missing
|
||||||
|
if (File.Exists(AssociatedProgramPath))
|
||||||
{
|
{
|
||||||
templateProgram = await _cncProgramService.LoadAsync(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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBox.Show($"无法加载程序文件:{AssociatedProgramName}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show($"无法加载程序文件:{AssociatedProgramName}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
@@ -594,6 +611,10 @@ namespace XplorePlane.ViewModels.Cnc
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
// 将 ViewModel 中的执行状态同步回 _currentLayout,确保保存时反映实际执行结果
|
||||||
|
// Sync execution status from ViewModels back to _currentLayout so saves reflect actual results
|
||||||
|
SyncCellStatusToLayout();
|
||||||
|
|
||||||
IsExecuting = false;
|
IsExecuting = false;
|
||||||
_executionCts?.Dispose();
|
_executionCts?.Dispose();
|
||||||
_executionCts = null;
|
_executionCts = null;
|
||||||
@@ -641,5 +662,37 @@ namespace XplorePlane.ViewModels.Cnc
|
|||||||
SelectedCell = match ?? Cells.FirstOrDefault();
|
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