Files
AohDrllTools/MainWindowViewModel.cs
2025-12-07 20:25:27 +08:00

1607 lines
61 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Windows;
using DrillTools.Integration;
namespace DrillTools
{
/// <summary>
/// 主窗口视图模型
/// </summary>
public class MainWindowViewModel : INotifyPropertyChanged
{
private ObservableCollection<ToolItem> _tools = new();
private ToolItem? _selectedTool;
private string _drillTapeContent = string.Empty;
private bool _canMoveUp;
private bool _canMoveDown;
private string _originalFilePath = string.Empty;
/// <summary>
/// 刀具列表
/// </summary>
public ObservableCollection<ToolItem> Tools
{
get => _tools;
set => SetProperty(ref _tools, value);
}
/// <summary>
/// 选中的刀具
/// </summary>
public ToolItem? SelectedTool
{
get => _selectedTool;
set
{
if (SetProperty(ref _selectedTool, value))
{
UpdateMoveButtonsState();
}
}
}
/// <summary>
/// 钻带内容
/// </summary>
public string DrillTapeContent
{
get => _drillTapeContent;
set => SetProperty(ref _drillTapeContent, value);
}
/// <summary>
/// 是否可以上移
/// </summary>
public bool CanMoveUp
{
get => _canMoveUp;
set => SetProperty(ref _canMoveUp, value);
}
/// <summary>
/// 是否可以下移
/// </summary>
public bool CanMoveDown
{
get => _canMoveDown;
set => SetProperty(ref _canMoveDown, value);
}
/// <summary>
/// 原始文件路径
/// </summary>
public string OriginalFilePath
{
get => _originalFilePath;
set
{
if (SetProperty(ref _originalFilePath, value))
{
// 当原始文件路径改变时,通知 HasOriginalFile 属性也已更改
OnPropertyChanged(nameof(HasOriginalFile));
}
}
}
/// <summary>
/// 是否有原始文件
/// </summary>
public bool HasOriginalFile => !string.IsNullOrEmpty(OriginalFilePath);
/// <summary>
/// 从钻带内容加载刀具信息
/// </summary>
/// <param name="drillTapeContent">钻带内容</param>
public void LoadToolsFromDrillTape(string drillTapeContent)
{
DrillTapeContent = drillTapeContent;
Tools.Clear();
try
{
// 使用现有的 DrillTapeProcessor 处理钻带数据
var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
if (result.Success)
{
foreach (var toolResult in result.ToolResults)
{
var toolItem = new ToolItem
{
ToolNumber = toolResult.ToolNumber,
Diameter = toolResult.Diameter,
// 孔数相关属性已移除
// RegularHoles = toolResult.RegularHoles;
// SlotHoles = toolResult.SlotHoles;
// TotalHoles = toolResult.TotalHoles;
ToolType = toolResult.ToolType,
ToolSuffixType = toolResult.ToolSuffixType,
ToolCategory = toolResult.ToolCategory,
HoleLocations = toolResult.Locations ?? new List<string>()
};
// 如果是机台码使用DrillTapeProcessor已经解析出的机台码信息
if (toolResult.ToolType == ToolType.MachineCode)
{
toolItem.MachineCodeCommand = toolResult.MachineCodeCommand;
toolItem.MachineCodeType = toolResult.MachineCodeType;
// 添加日志验证机台码信息传递
System.Diagnostics.Debug.WriteLine($"[机台码传递] T{toolResult.ToolNumber:D2}: 命令={toolItem.MachineCodeCommand}, 类型={toolItem.MachineCodeType}");
// 如果 toolResult.Locations 已经包含坐标数据,则使用它
// 否则从原始钻带内容中提取坐标行
if (toolItem.HoleLocations == null || toolItem.HoleLocations.Count == 0)
{
// 从钻带内容中提取机台码坐标行
var toolPattern = $@"%.+?T{toolResult.ToolNumber:D2}(.*?)(?=T\d{{2}}|M30)";
var match = System.Text.RegularExpressions.Regex.Match(DrillTapeContent, toolPattern, System.Text.RegularExpressions.RegexOptions.Singleline);
if (match.Success)
{
string holeSection = match.Groups[1].Value;
// 查找机台码坐标行
var coordinatePattern = @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)";
var coordinateMatches = System.Text.RegularExpressions.Regex.Matches(holeSection, coordinatePattern);
toolItem.HoleLocations = new List<string>();
foreach (Match coordMatch in coordinateMatches)
{
toolItem.HoleLocations.Add(coordMatch.Value);
}
System.Diagnostics.Debug.WriteLine($"[机台码坐标] T{toolResult.ToolNumber:D2}: 找到{toolItem.HoleLocations.Count}个坐标");
}
}
}
Tools.Add(toolItem);
}
// 更新按钮状态
UpdateMoveButtonsState();
}
else
{
System.Windows.MessageBox.Show($"解析钻带失败: {result.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show($"解析钻带时发生异常: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 重新排序刀具
/// </summary>
/// <param name="oldIndex">原索引</param>
/// <param name="newIndex">新索引</param>
public void ReorderTools(int oldIndex, int newIndex)
{
if (oldIndex < 0 || oldIndex >= Tools.Count || newIndex < 0 || newIndex >= Tools.Count)
return;
var tool = Tools[oldIndex];
// 检查是否是机台码刀具,如果是则不允许移动
if (tool.ToolType == ToolType.MachineCode)
{
System.Windows.MessageBox.Show("机台码刀具不允许移动位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// 检查目标位置是否是机台码刀具
var targetTool = Tools[newIndex];
if (targetTool.ToolType == ToolType.MachineCode)
{
System.Windows.MessageBox.Show("不能移动到机台码刀具位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
Tools.RemoveAt(oldIndex);
Tools.Insert(newIndex, tool);
}
/// <summary>
/// 上移选中的刀具
/// </summary>
public void MoveSelectedToolUp()
{
if (SelectedTool == null || !CanMoveUp)
return;
int currentIndex = Tools.IndexOf(SelectedTool);
System.Diagnostics.Debug.WriteLine($"[MoveUp] 开始上移操作,选中项索引: {currentIndex}, 刀具编号: T{SelectedTool.ToolNumber:D2}");
if (currentIndex > 0)
{
// 检查是否是机台码刀具
if (SelectedTool.ToolType == ToolType.MachineCode)
{
System.Windows.MessageBox.Show("机台码刀具不允许移动位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// 检查目标位置是否是机台码刀具
var targetTool = Tools[currentIndex - 1];
if (targetTool.ToolType == ToolType.MachineCode)
{
System.Windows.MessageBox.Show("不能移动到机台码刀具位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// 保存选中的刀具引用
var selectedTool = SelectedTool;
int newIndex = currentIndex - 1;
// 执行上移操作
Tools.RemoveAt(currentIndex);
Tools.Insert(newIndex, selectedTool);
System.Diagnostics.Debug.WriteLine($"[MoveUp] 上移完成,新索引: {newIndex}");
// 使用延迟方法重新选中移动后的项
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
System.Diagnostics.Debug.WriteLine($"[MoveUp] 延迟设置选中项,刀具编号: T{selectedTool.ToolNumber:D2}");
SelectedTool = selectedTool;
UpdateMoveButtonsState();
}), System.Windows.Threading.DispatcherPriority.Background);
}
}
/// <summary>
/// 下移选中的刀具
/// </summary>
public void MoveSelectedToolDown()
{
if (SelectedTool == null || !CanMoveDown)
return;
int currentIndex = Tools.IndexOf(SelectedTool);
System.Diagnostics.Debug.WriteLine($"[MoveDown] 开始下移操作,选中项索引: {currentIndex}, 刀具编号: T{SelectedTool.ToolNumber:D2}");
if (currentIndex >= 0 && currentIndex < Tools.Count - 1)
{
// 检查是否是机台码刀具
if (SelectedTool.ToolType == ToolType.MachineCode)
{
System.Windows.MessageBox.Show("机台码刀具不允许移动位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// 检查目标位置是否是机台码刀具
var targetTool = Tools[currentIndex + 1];
if (targetTool.ToolType == ToolType.MachineCode)
{
System.Windows.MessageBox.Show("不能移动到机台码刀具位置", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// 保存选中的刀具引用
var selectedTool = SelectedTool;
int newIndex = currentIndex + 1;
// 执行下移操作
Tools.RemoveAt(currentIndex);
Tools.Insert(newIndex, selectedTool);
System.Diagnostics.Debug.WriteLine($"[MoveDown] 下移完成,新索引: {newIndex}");
// 使用延迟方法重新选中移动后的项
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
System.Diagnostics.Debug.WriteLine($"[MoveDown] 延迟设置选中项,刀具编号: T{selectedTool.ToolNumber:D2}");
SelectedTool = selectedTool;
UpdateMoveButtonsState();
}), System.Windows.Threading.DispatcherPriority.Background);
}
}
/// <summary>
/// 更新上移/下移按钮的状态
/// </summary>
private void UpdateMoveButtonsState()
{
if (SelectedTool == null)
{
CanMoveUp = false;
CanMoveDown = false;
System.Diagnostics.Debug.WriteLine("[UpdateButtons] 没有选中项,禁用所有按钮");
return;
}
int index = Tools.IndexOf(SelectedTool);
CanMoveUp = index > 0;
CanMoveDown = index >= 0 && index < Tools.Count - 1;
System.Diagnostics.Debug.WriteLine($"[UpdateButtons] 选中项索引: {index}, CanMoveUp: {CanMoveUp}, CanMoveDown: {CanMoveDown}");
}
/// <summary>
/// 保存刀具顺序并应用到钻带处理
/// </summary>
/// <returns>重新排序后的钻带内容</returns>
public string ApplyToolOrderToDrillTape()
{
if (string.IsNullOrEmpty(OriginalFilePath))
{
throw new InvalidOperationException("没有原始文件路径,请先加载钻带文件");
}
if (Tools.Count == 0)
{
throw new InvalidOperationException("没有刀具数据,请先加载钻带文件");
}
try
{
// 1. 使用现有的扩展方法生成重新排序后的钻带内容
string reorderedDrillTape = DrillTapeProcessorExtensions.GenerateReorderedDrillTape(DrillTapeContent, Tools.ToList());
// 2. 改进的备份逻辑
if (File.Exists(OriginalFilePath))
{
string backupFilePath = OriginalFilePath + ".bak";
// 检查备份文件是否已存在
if (File.Exists(backupFilePath))
{
var result = System.Windows.MessageBox.Show(
"备份文件已存在,请选择处理方式:\n\n" +
"是(Y):覆盖现有备份文件\n" +
"否(N):创建带时间戳的新备份文件\n" +
"取消:中止保存操作\n\n" +
"提示:选择'否'可以保留之前的备份历史",
"备份选项",
MessageBoxButton.YesNoCancel,
MessageBoxImage.Question);
switch (result)
{
case MessageBoxResult.Yes:
// 覆盖现有备份文件
File.Copy(OriginalFilePath, backupFilePath, true);
break;
case MessageBoxResult.No:
// 创建带时间戳的新备份文件
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string timestampBackupPath = $"{OriginalFilePath}.{timestamp}.bak";
File.Copy(OriginalFilePath, timestampBackupPath);
break;
case MessageBoxResult.Cancel:
// 用户取消操作
throw new OperationCanceledException("用户取消了保存操作");
}
}
else
{
// 备份文件不存在,直接创建
File.Copy(OriginalFilePath, backupFilePath);
}
}
// 3. 将重新排序后的钻带内容写入原始文件
File.WriteAllText(OriginalFilePath, reorderedDrillTape);
// 4. 更新当前钻带内容
DrillTapeContent = reorderedDrillTape;
return reorderedDrillTape;
}
catch (OperationCanceledException)
{
// 重新抛出取消异常,不包装
throw;
}
catch (Exception ex)
{
throw new InvalidOperationException($"保存钻带文件失败: {ex.Message}", ex);
}
}
/// <summary>
/// 重排刀序并重新编号
/// </summary>
/// <returns>重排后的钻带内容</returns>
public string ReorderAndRenumberTools()
{
if (Tools.Count == 0)
{
throw new InvalidOperationException("没有可重排的刀具");
}
// 1. 创建原始刀具编号到新编号的映射
var toolNumberMapping = new Dictionary<int, int>();
var originalToNewMapping = new Dictionary<int, int>(); // 保存原始映射关系
// 2. 按当前列表顺序重新编号T01, T02, T03...
int newToolNumber = 1;
foreach (var tool in Tools.ToList())
{
// 机台码刀具不允许重新编号
if (tool.ToolType != ToolType.MachineCode)
{
originalToNewMapping[tool.ToolNumber] = newToolNumber;
toolNumberMapping[tool.ToolNumber] = newToolNumber;
tool.ToolNumber = newToolNumber++;
}
else
{
// 机台码刀具保持原始编号,但也要加入映射
toolNumberMapping[tool.ToolNumber] = tool.ToolNumber;
}
}
// 3. 更新钻带内容中的刀具编号和孔位数据
string updatedDrillTape = UpdateDrillTapeWithNewToolNumbers(DrillTapeContent, toolNumberMapping);
// 4. 更新钻带内容
DrillTapeContent = updatedDrillTape;
// 5. 更新界面显示
OnPropertyChanged(nameof(Tools));
return updatedDrillTape;
}
/// <summary>
/// 使用新的刀具编号更新钻带内容
/// </summary>
/// <param name="originalDrillTape">原始钻带内容</param>
/// <param name="toolNumberMapping">刀具编号映射</param>
/// <returns>更新后的钻带内容</returns>
private string UpdateDrillTapeWithNewToolNumbers(string originalDrillTape, Dictionary<int, int> toolNumberMapping)
{
var lines = originalDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
var result = new List<string>();
// 创建新编号到刀具对象的映射,以便获取对应的坐标数据
var newNumberToToolMap = new Dictionary<int, ToolItem>();
foreach (var tool in Tools)
{
if (toolNumberMapping.ContainsValue(tool.ToolNumber))
{
newNumberToToolMap[tool.ToolNumber] = tool;
}
}
// 首先解析原始钻带中的刀具定义行,保存参数信息
var originalToolDefinitions = new Dictionary<int, string>();
var headerLines = new List<string>();
foreach (var line in lines)
{
string trimmedLine = line.Trim();
if (trimmedLine == "%")
{
//headerLines.Add(line);
break;
}
// 处理刀具定义行(如 T01C1.049H05000Z+0.000S060.00F105.0U0700.0
if (Regex.IsMatch(trimmedLine, @"^T(\d+)C"))
{
var match = Regex.Match(trimmedLine, @"^T(\d+)C(.*)$");
if (match.Success)
{
int originalToolNumber = int.Parse(match.Groups[1].Value);
originalToolDefinitions[originalToolNumber] = match.Groups[2].Value;
}
}
else
{
if (line != "")
headerLines.Add(line);
}
}
// 添加头部信息
result.AddRange(headerLines);
// 按照新的刀具编号顺序输出刀具定义部分
var sortedTools = Tools.OrderBy(t => t.ToolNumber).ToList();
foreach (var tool in sortedTools)
{
// 查找原始刀具编号
int originalToolNumber = -1;
foreach (var kvp in toolNumberMapping)
{
if (kvp.Value == tool.ToolNumber)
{
originalToolNumber = kvp.Key;
break;
}
}
if (originalToolNumber != -1 && originalToolDefinitions.ContainsKey(originalToolNumber))
{
string toolDef = $"T{tool.ToolNumber:D2}C{originalToolDefinitions[originalToolNumber]}";
result.Add(toolDef);
}
}
// 添加 % 符号
result.Add("%");
// 处理刀具切换行和坐标数据部分
// 按新刀具编号顺序输出刀具切换行和对应的坐标数据
var sortedToolsForData = Tools.OrderBy(t => t.ToolNumber).ToList();
foreach (var tool in sortedToolsForData)
{
// 添加刀具切换行
result.Add($"T{tool.ToolNumber:D2}");
// 添加该刀具对应的所有坐标数据
if (tool.ToolType != ToolType.MachineCode && tool.HoleLocations != null && tool.HoleLocations.Count > 0)
{
foreach (var location in tool.HoleLocations)
{
result.Add(location);
}
}
// 如果是机台码刀具,添加机台码命令和坐标
if (tool.ToolType == ToolType.MachineCode)
{
if (!string.IsNullOrEmpty(tool.MachineCodeCommand) && !string.IsNullOrEmpty(tool.MachineCodeType))
{
result.Add($"{tool.MachineCodeCommand},{tool.MachineCodeType},$S $N");
// 添加机台码的坐标数据
if (tool.HoleLocations != null && tool.HoleLocations.Count > 0)
{
foreach (var location in tool.HoleLocations)
{
result.Add(location);
}
}
}
}
}
// 添加结束标记
result.Add("M30");
return string.Join("\r\n", result);
}
/// <summary>
/// 加载示例数据
/// </summary>
public void LoadSampleData()
{
// 清空原始文件路径,因为这是示例数据
OriginalFilePath = string.Empty;
Tools.Clear();
// 添加示例刀具数据
Tools.Add(new ToolItem
{
ToolNumber = 1,
Diameter = 1.049, // 尾号9特殊孔径固定为圆孔
// 孔数相关属性已移除
// RegularHoles = 7,
// SlotHoles = 0,
// TotalHoles = 7,
ToolType = ToolType.Regular,
ToolSuffixType = ToolItem.GetToolSuffixType(1.049), // 特殊孔径
ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.049)),
HoleLocations = new List<string>
{
"X-167525Y013500",
"X-167525Y018500",
"X-167525Y023500",
"X167525Y013500",
"X167525Y018500",
"X167525Y023500",
"X099366Y502000"
}
});
Tools.Add(new ToolItem
{
ToolNumber = 2,
Diameter = 1.550, // 尾号0 -> 钻针
// 孔数相关属性已移除
// RegularHoles = 5,
// SlotHoles = 0,
// TotalHoles = 5,
ToolType = ToolType.Regular,
ToolSuffixType = ToolItem.GetToolSuffixType(1.550), // 基于孔径计算
ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.550)),
HoleLocations = new List<string>
{
"X-065975Y115250",
"X-085825Y122450",
"X-085825Y124550",
"X-097425Y115250",
"X103093Y502000"
}
});
Tools.Add(new ToolItem
{
ToolNumber = 3,
Diameter = 1.156, // 尾号6 -> EA型槽刀
// 孔数相关属性已移除
// RegularHoles = 1,
// SlotHoles = 528,
// TotalHoles = 529,
ToolType = ToolType.Slot,
ToolSuffixType = ToolItem.GetToolSuffixType(1.156), // 基于孔径计算
ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.156)),
HoleLocations = new List<string>
{
"X-069659Y016450G85X-094159Y016450",
"X-181341Y195550G85X-156841Y195550",
"X-069659Y210450G85X-094159Y210450",
"X-181341Y389550G85X-156841Y389550",
"X-069659Y404450G85X-094159Y404450",
"X-181341Y583550G85X-156841Y583550",
"X162939Y596000"
}
});
Tools.Add(new ToolItem
{
ToolNumber = 4,
Diameter = 1.451, // 尾号1 -> 槽刀
// 孔数相关属性已移除
// RegularHoles = 57,
// SlotHoles = 0,
// TotalHoles = 57,
ToolType = ToolType.Regular,
ToolSuffixType = ToolItem.GetToolSuffixType(1.451), // 基于孔径计算
ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.451)),
HoleLocations = new List<string>
{
"X-065975Y115250",
"X-085825Y122450",
"X-085825Y124550",
"X-097425Y115250",
"X103093Y502000"
}
});
Tools.Add(new ToolItem
{
ToolNumber = 5,
Diameter = 1.153, // 尾号3 -> 粉尘刀
// 孔数相关属性已移除
// RegularHoles = 10,
// SlotHoles = 0,
// TotalHoles = 10,
ToolType = ToolType.Regular,
ToolSuffixType = ToolItem.GetToolSuffixType(1.153), // 基于孔径计算
ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(1.153)),
HoleLocations = new List<string>
{
"X-065975Y115250",
"X-085825Y122450",
"X-085825Y124550",
"X-097425Y115250",
"X103093Y502000"
}
});
Tools.Add(new ToolItem
{
ToolNumber = 6,
Diameter = 0.499, // 特殊孔径固定为圆孔(机台码)
// 孔数相关属性已移除
// RegularHoles = 57,
// SlotHoles = 0,
// TotalHoles = 57,
ToolType = ToolType.MachineCode,
MachineCodeCommand = "M97",
MachineCodeType = "A*",
ToolSuffixType = ToolItem.GetToolSuffixType(0.499), // 特殊孔径
ToolCategory = ToolItem.GetToolCategory(ToolItem.GetToolSuffixType(0.499)),
HoleLocations = new List<string> { "X-194000Y002000" } // 机台码刀具的坐标数据
});
// 更新按钮状态
UpdateMoveButtonsState();
// 加载示例钻带内容
DrillTapeContent = @"M48
;厚铜板参数-镀膜-EA-250618
T01C1.049H05000Z+0.000S060.00F105.0U0700.0
T02C1.550H01500Z+0.150S070.00F008.0U0800.0
T03C1.156H03000Z-0.200S040.00F030.0U0900.0
T04C1.451H01500Z+0.150S070.00F008.0U0800.0
T05C1.153H01500Z+0.150S070.00F008.0U0800.0
T06C0.499H01500Z+0.150S070.00F008.0U0800.0
%
T01
X-167525Y013500
X-167525Y018500
X-167525Y023500
X167525Y013500
X167525Y018500
X167525Y023500
X099366Y502000
T02
X-065975Y115250
X-085825Y122450
X-085825Y124550
X-097425Y115250
X103093Y502000
T03
X-069659Y016450G85X-094159Y016450
X-181341Y195550G85X-156841Y195550
X-069659Y210450G85X-094159Y210450
X-181341Y389550G85X-156841Y389550
X-069659Y404450G85X-094159Y404450
X-181341Y583550G85X-156841Y583550
X162939Y596000
T04
X-065975Y115250
X-085825Y122450
X-085825Y124550
X-097425Y115250
X103093Y502000
T05
X-065975Y115250
X-085825Y122450
X-085825Y124550
X-097425Y115250
X103093Y502000
T06
M97,A*,$S $N
X-194000Y002000
M30";
}
public event PropertyChangedEventHandler? PropertyChanged;
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))
return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// 测试机台码孔数计算功能
/// </summary>
public void TestMachineCodeHoleCalculation()
{
Console.WriteLine("=== 机台码孔数计算测试 ===");
// 测试钻带内容
string drillTapeContent = @"M48
;厚铜板参数-镀膜-EA-250618
T01C0.799H05000Z+0.000S060.00F105.0U0700.0
T02C0.656H01500Z+0.150S070.00F008.0U0800.0
T03C1.601H03000Z-0.200S040.00F030.0U0900.0
T04C0.499
%
T01
X-167525Y013500
X-167525Y018500
X-167525Y023500
X167525Y013500
X167525Y018500
X167525Y023500
X099366Y502000
T02
X-065975Y115250
X-085825Y122450
X-085825Y124550
X-097425Y115250
X103093Y502000
T03
X-069659Y016450G85X-094159Y016450
X-181341Y195550G85X-156841Y195550
X-069659Y210450G85X-094159Y210450
X-181341Y389550G85X-156841Y389550
X-069659Y404450G85X-094159Y404450
X-181341Y583550G85X-156841Y583550
X162939Y596000
T04
M97,A*,$S $N
X-194000Y002000
M30";
// 处理钻带
var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
// 输出结果
Console.WriteLine($"处理状态: {(result.Success ? "" : "")}");
if (!result.Success)
{
Console.WriteLine($"错误信息: {result.Message}");
return;
}
Console.WriteLine("\n刀具统计:");
Console.WriteLine("刀具\t孔径(mm)\t类型\t\t普通孔数\t槽孔数\t总孔数\t孔位数量");
Console.WriteLine("========================================================================");
foreach (var tool in result.ToolResults)
{
string toolTypeDisplay = tool.ToolType switch
{
ToolType.Regular => "圆孔",
ToolType.Slot => "槽孔",
ToolType.MachineCode => "机台码",
_ => "未知"
};
Console.WriteLine($"T{tool.ToolNumber:D2}\t{tool.Diameter:F3}\t\t{toolTypeDisplay}\t{tool.RegularHoles}\t\t{tool.SlotHoles}\t{tool.TotalHoles}\t{tool.Locations?.Count ?? 0}");
}
Console.WriteLine($"\n总孔数: {result.TotalHoles}");
// 验证结果
Console.WriteLine("\n=== 验证结果 ===");
VerifyResults(result);
// 测试孔位数据
Console.WriteLine("\n=== 孔位数据测试 ===");
TestHoleLocations(result);
}
/// <summary>
/// 测试孔位数据
/// </summary>
/// <param name="result">钻带处理结果</param>
private void TestHoleLocations(DrillTapeResult result)
{
foreach (var tool in result.ToolResults)
{
Console.WriteLine($"\nT{tool.ToolNumber:D2} 孔位数据 ({tool.Locations?.Count ?? 0} 个):");
if (tool.Locations != null && tool.Locations.Count > 0)
{
foreach (var location in tool.Locations.Take(5)) // 只显示前5个
{
Console.WriteLine($" {location}");
}
if (tool.Locations.Count > 5)
{
Console.WriteLine($" ... 还有 {tool.Locations.Count - 5} 个孔位");
}
}
else
{
Console.WriteLine(" 无孔位数据");
}
}
}
private void VerifyResults(DrillTapeResult result)
{
// CAM350的预期结果
var expectedResults = new[]
{
new { ToolNumber = 1, Diameter = 0.799, ExpectedHoles = 7 },
new { ToolNumber = 2, Diameter = 0.656, ExpectedHoles = 5 },
new { ToolNumber = 3, Diameter = 1.601, ExpectedHoles = 529 },
new { ToolNumber = 4, Diameter = 0.499, ExpectedHoles = 57 }
};
bool allMatch = true;
foreach (var expected in expectedResults)
{
var actual = result.ToolResults.Find(t => t.ToolNumber == expected.ToolNumber);
if (actual != null)
{
bool match = Math.Abs(actual.Diameter - expected.Diameter) < 0.001 &&
actual.TotalHoles == expected.ExpectedHoles;
Console.WriteLine($"T{expected.ToolNumber:D2} ({expected.Diameter:F3}mm): " +
$"预期={expected.ExpectedHoles}, 实际={actual.TotalHoles}, " +
$"{(match ? "" : "")}");
if (!match)
allMatch = false;
}
else
{
Console.WriteLine($"T{expected.ToolNumber:D2}: 未找到结果 ✗");
allMatch = false;
}
}
Console.WriteLine($"\n总体结果: {(allMatch ? " CAM350一致" : " ")}");
}
/// <summary>
/// 测试刀具尾号类型功能
/// </summary>
public void TestToolSuffixTypeFunctionality()
{
Console.WriteLine("=== 刀具尾号类型功能测试 ===");
// 测试不同孔径的尾号类型
double[] testDiameters = { 1.049, 1.550, 1.156, 1.451, 1.153, 1.255, 1.266, 1.277, 1.288, 1.299 };
Console.WriteLine("孔径(mm)\t尾号\t尾号类型\t\t大类");
Console.WriteLine("==============================================");
foreach (double diameter in testDiameters)
{
string diameterStr = diameter.ToString("F3");
char lastChar = diameterStr[diameterStr.Length - 1];
int suffix = int.Parse(lastChar.ToString());
var suffixType = ToolItem.GetToolSuffixType(diameter);
var category = ToolItem.GetToolCategory(suffixType);
var suffixDisplay = ToolItem.GetToolSuffixTypeDisplay(suffixType);
var categoryDisplay = ToolItem.GetToolCategoryDisplay(category);
Console.WriteLine($"{diameter:F3}\t{suffix}\t{suffixDisplay}\t{categoryDisplay}");
}
Console.WriteLine();
Console.WriteLine("=== 测试钻带处理功能 ===");
// 测试钻带处理
string drillTapeContent = @"M48
T10C1.049
T11C1.550
T12C1.156
T13C1.451
T14C1.153
T15C1.255
T16C1.266
T17C1.277
%
T10
X01000Y01000
T11
X02000Y02000
T12
X03000Y03000
T13
X04000Y04000
T14
X05000Y05000
T15
X06000Y06000
T16
X07000Y07000
T17
X08000Y08000
M30";
var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
if (result.Success)
{
Console.WriteLine("钻带处理成功!");
Console.WriteLine();
Console.WriteLine("刀具编号\t孔径(mm)\t类型\t\t尾号类型\t大类\t\t孔数");
Console.WriteLine("================================================================");
foreach (var tool in result.ToolResults)
{
string toolTypeDisplay = tool.ToolType switch
{
ToolType.Regular => "圆孔",
ToolType.Slot => "槽孔",
ToolType.MachineCode => "机台码",
_ => "未知"
};
string suffixTypeDisplay = tool.ToolSuffixType switch
{
ToolSuffixType.Drill => "钻针",
ToolSuffixType.Slot => "槽刀",
ToolSuffixType.EASlot => "EA型槽刀",
ToolSuffixType.DustSlot => "粉尘刀",
ToolSuffixType.DeburrSlot => "去毛刺刀",
ToolSuffixType.NonStandard => "非标刀",
ToolSuffixType.EASlot2 => "EA型槽刀",
ToolSuffixType.Special => "特殊刀具",
_ => "未知"
};
string categoryDisplay = tool.ToolCategory switch
{
ToolCategory.Drill => "钻针",
ToolCategory.Slot => "槽刀",
ToolCategory.EA => "EA刀",
ToolCategory.NonStandard => "非标刀",
ToolCategory.Special => "特殊刀",
_ => "未知"
};
Console.WriteLine($"T{tool.ToolNumber:D2}\t{tool.Diameter:F3}\t\t{toolTypeDisplay}\t{suffixTypeDisplay}\t{categoryDisplay}\t{tool.TotalHoles}");
}
}
else
{
Console.WriteLine($"钻带处理失败: {result.Message}");
}
Console.WriteLine();
Console.WriteLine("测试完成!");
}
/// <summary>
/// 测试孔位数据功能(可在应用启动时调用)
/// </summary>
public static void TestHoleLocationsFunctionality()
{
Console.WriteLine("=== 孔位数据功能测试 ===");
Console.WriteLine();
// 使用用户提供的钻带数据示例
string drillTapeContent = @"M48
T01C0.799H05000Z+0.000S060.00F105.0U0700.0
T02C1.049H05000Z+0.000S045.00F105.0U0700.0
%
T01
X-281000Y003000
X-276000Y003000
X-271000Y003000
X271000Y003000
X276000Y003000
X281000Y003000
X-281000Y702500
X-276000Y702500
X-271000Y702500
X271000Y703000
X276000Y703000
X281000Y703000
X077370Y704000
T02
X-100000Y100000
X-200000Y200000
X-300000Y300000
M30";
// 处理钻带
var result = DrillTapeProcessor.ProcessDrillTape(drillTapeContent);
// 输出结果
Console.WriteLine($"处理状态: {(result.Success ? "" : "")}");
if (!result.Success)
{
Console.WriteLine($"错误信息: {result.Message}");
return;
}
Console.WriteLine("\n刀具统计:");
Console.WriteLine("刀具\t孔径(mm)\t类型\t\t普通孔数\t槽孔数\t总孔数\t孔位数量");
Console.WriteLine("========================================================================");
foreach (var tool in result.ToolResults)
{
string toolTypeDisplay = tool.ToolType switch
{
ToolType.Regular => "圆孔",
ToolType.Slot => "槽孔",
ToolType.MachineCode => "机台码",
_ => "未知"
};
Console.WriteLine($"T{tool.ToolNumber:D2}\t{tool.Diameter:F3}\t\t{toolTypeDisplay}\t{tool.RegularHoles}\t\t{tool.SlotHoles}\t{tool.TotalHoles}\t{tool.Locations?.Count ?? 0}");
}
Console.WriteLine($"\n总孔数: {result.TotalHoles}");
// 详细显示孔位数据
Console.WriteLine("\n=== 详细孔位数据 ===");
foreach (var tool in result.ToolResults)
{
Console.WriteLine($"\nT{tool.ToolNumber:D2} 孔位数据 ({tool.Locations?.Count ?? 0} 个):");
if (tool.Locations != null && tool.Locations.Count > 0)
{
int count = 0;
foreach (var location in tool.Locations)
{
Console.WriteLine($" [{++count:D2}] {location}");
}
}
else
{
Console.WriteLine(" 无孔位数据");
}
}
// 验证T01的孔位数据是否符合预期
Console.WriteLine("\n=== 验证T01孔位数据 ===");
var t01Result = result.ToolResults.Find(t => t.ToolNumber == 1);
if (t01Result != null && t01Result.Locations != null)
{
var expectedLocations = new System.Collections.Generic.List<string>
{
"X-281000Y003000",
"X-276000Y003000",
"X-271000Y003000",
"X271000Y003000",
"X276000Y003000",
"X281000Y003000",
"X-281000Y702500",
"X-276000Y702500",
"X-271000Y702500",
"X271000Y703000",
"X276000Y703000",
"X281000Y703000",
"X077370Y704000"
};
bool allMatch = true;
if (t01Result.Locations.Count == expectedLocations.Count)
{
for (int i = 0; i < expectedLocations.Count; i++)
{
if (t01Result.Locations[i] != expectedLocations[i])
{
Console.WriteLine($" 位置 {i + 1}: 预期 {expectedLocations[i]}, 实际 {t01Result.Locations[i]} ✗");
allMatch = false;
}
else
{
Console.WriteLine($" 位置 {i + 1}: {t01Result.Locations[i]} ✓");
}
}
}
else
{
Console.WriteLine($" 孔位数量不匹配: 预期 {expectedLocations.Count}, 实际 {t01Result.Locations.Count} ✗");
allMatch = false;
}
Console.WriteLine($"\nT01孔位数据验证结果: {(allMatch ? " " : " ")}");
}
else
{
Console.WriteLine("未找到T01刀具数据 ✗");
}
Console.WriteLine("\n孔位数据功能测试完成");
}
/// <summary>
/// 显示刀具详情窗口
/// </summary>
/// <param name="tool">要显示详情的刀具</param>
public void ShowToolDetail(ToolItem tool)
{
if (tool == null)
return;
try
{
var detailWindow = new ToolDetailWindow(tool);
detailWindow.Owner = System.Windows.Application.Current.MainWindow;
detailWindow.ShowDialog();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show($"显示刀具详情失败: {ex.Message}", "错误",
System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
}
}
/// <summary>
/// 测试重排刀序功能
/// </summary>
public void TestReorderAndRenumberTools()
{
Console.WriteLine("=== 重排刀序功能测试 ===");
// 1. 加载测试数据
LoadSampleData();
// 2. 记录原始状态
var originalOrder = Tools.Select(t => new
{
t.ToolNumber,
t.Diameter,
LocationCount = t.HoleLocations?.Count ?? 0,
FirstLocation = t.HoleLocations?.FirstOrDefault() ?? ""
}).ToList();
Console.WriteLine("原始刀具顺序:");
foreach (var tool in originalOrder)
{
Console.WriteLine($"T{tool.ToolNumber:D2}({tool.Diameter:F3}): {tool.LocationCount}个坐标, 首个坐标: {tool.FirstLocation}");
}
// 3. 执行重排操作将T02移到第一位
if (Tools.Count >= 2)
{
var toolToMove = Tools.FirstOrDefault(t => t.ToolNumber == 2);
if (toolToMove != null && toolToMove.ToolType != ToolType.MachineCode)
{
int oldIndex = Tools.IndexOf(toolToMove);
ReorderTools(oldIndex, 0);
}
}
// 4. 执行重新编号
string reorderedDrillTape = ReorderAndRenumberTools();
// 5. 验证结果
Console.WriteLine("\n重排后刀具顺序:");
var reorderedOrder = Tools.Select(t => new
{
t.ToolNumber,
t.Diameter,
LocationCount = t.HoleLocations?.Count ?? 0,
FirstLocation = t.HoleLocations?.FirstOrDefault() ?? ""
}).ToList();
foreach (var tool in reorderedOrder)
{
Console.WriteLine($"T{tool.ToolNumber:D2}({tool.Diameter:F3}): {tool.LocationCount}个坐标, 首个坐标: {tool.FirstLocation}");
}
// 6. 验证钻带内容
Console.WriteLine("\n重排后的钻带内容:");
Console.WriteLine(reorderedDrillTape);
// 7. 验证坐标跟随
VerifyCoordinateBinding(originalOrder.ToList<dynamic>(), reorderedOrder.ToList<dynamic>());
Console.WriteLine("\n重排刀序功能测试完成");
}
/// <summary>
/// 验证坐标绑定关系
/// </summary>
private void VerifyCoordinateBinding(List<dynamic> originalOrder, List<dynamic> reorderedOrder)
{
Console.WriteLine("\n=== 验证坐标绑定关系 ===");
// 创建直径到坐标的映射
var originalDiameterToLocation = new Dictionary<double, string>();
foreach (var tool in originalOrder)
{
originalDiameterToLocation[tool.Diameter] = tool.FirstLocation;
}
// 验证重排后的坐标绑定
bool allMatch = true;
foreach (var tool in reorderedOrder)
{
if (originalDiameterToLocation.ContainsKey(tool.Diameter))
{
string originalLocation = originalDiameterToLocation[tool.Diameter];
if (tool.FirstLocation != originalLocation)
{
Console.WriteLine($"✗ 刀具{tool.Diameter:F3}的坐标不匹配: 原始{originalLocation}, 重排后{tool.FirstLocation}");
allMatch = false;
}
else
{
Console.WriteLine($"✓ 刀具{tool.Diameter:F3}的坐标正确跟随: {tool.FirstLocation}");
}
}
}
Console.WriteLine($"\n坐标绑定验证结果: {(allMatch ? " " : " ")}");
}
/// <summary>
/// 测试修正后的重排刀序功能
/// </summary>
public void TestFixedReorderFunction()
{
Console.WriteLine("=== 测试修正后的重排刀序功能 ===");
// 1. 加载测试数据
LoadSampleData();
Console.WriteLine("原始刀具顺序:");
foreach (var tool in Tools)
{
Console.WriteLine($"T{tool.ToolNumber:D2}C{tool.Diameter:F3}");
}
// 2. 模拟用户重排操作将T02移到第一位
if (Tools.Count >= 2)
{
var toolToMove = Tools.FirstOrDefault(t => t.ToolNumber == 2);
if (toolToMove != null && toolToMove.ToolType != ToolType.MachineCode)
{
int oldIndex = Tools.IndexOf(toolToMove);
ReorderTools(oldIndex, 0);
Console.WriteLine("\n重排后刀具顺序重新编号前:");
foreach (var tool in Tools)
{
Console.WriteLine($"T{tool.ToolNumber:D2}C{tool.Diameter:F3}");
}
// 3. 执行重新编号
string reorderedDrillTape = ReorderAndRenumberTools();
Console.WriteLine("\n重排并重新编号后的刀具顺序:");
foreach (var tool in Tools)
{
Console.WriteLine($"T{tool.ToolNumber:D2}C{tool.Diameter:F3}");
}
// 4. 验证刀具定义部分是否按顺序排列
Console.WriteLine("\n=== 验证结果 ===");
var lines = reorderedDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
var toolDefinitionOrder = new List<int>();
foreach (var line in lines)
{
if (line.Trim() == "%")
{
break;
}
if (Regex.IsMatch(line, @"^T(\d+)C"))
{
var match = Regex.Match(line, @"^T(\d+)C");
if (match.Success)
{
toolDefinitionOrder.Add(int.Parse(match.Groups[1].Value));
}
}
}
Console.WriteLine("刀具定义部分的顺序: " + string.Join(", ", toolDefinitionOrder.Select(t => $"T{t:D2}")));
bool isOrdered = true;
for (int i = 1; i < toolDefinitionOrder.Count; i++)
{
if (toolDefinitionOrder[i] < toolDefinitionOrder[i - 1])
{
isOrdered = false;
break;
}
}
Console.WriteLine($"刀具定义部分是否按顺序排列: {(isOrdered ? "" : "")}");
if (isOrdered)
{
Console.WriteLine("✓ 重排刀序功能修正成功!");
}
else
{
Console.WriteLine("✗ 重排刀序功能仍有问题!");
}
// 5. 显示完整的重排后钻带内容
Console.WriteLine("\n重排后的钻带内容:");
Console.WriteLine(reorderedDrillTape);
}
}
}
/// <summary>
/// 测试机台码坐标数据完整性
/// </summary>
public void TestMachineCodeCoordinateIntegrity()
{
Console.WriteLine("=== 机台码坐标数据完整性测试 ===");
// 1. 加载示例数据
LoadSampleData();
// 2. 执行重排刀序操作
string reorderedDrillTape = ReorderAndRenumberTools();
// 3. 验证机台码坐标数据
Console.WriteLine("重排后的钻带内容:");
Console.WriteLine(reorderedDrillTape);
// 4. 检查机台码部分是否包含坐标数据
var lines = reorderedDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
bool foundMachineCode = false;
bool foundCoordinate = false;
int machineCodeToolNumber = -1;
for (int i = 0; i < lines.Length; i++)
{
string line = lines[i].Trim();
// 查找机台码刀具
if (Regex.IsMatch(line, @"^T(\d+)"))
{
var match = Regex.Match(line, @"^T(\d+)");
if (match.Success)
{
int toolNumber = int.Parse(match.Groups[1].Value);
var tool = Tools.FirstOrDefault(t => t.ToolNumber == toolNumber);
if (tool != null && tool.ToolType == ToolType.MachineCode)
{
foundMachineCode = true;
machineCodeToolNumber = toolNumber;
Console.WriteLine($"\n找到机台码刀具 T{toolNumber:D2}");
// 检查下一行是否是机台码命令
if (i + 1 < lines.Length)
{
string nextLine = lines[i + 1].Trim();
if (Regex.IsMatch(nextLine, @"(M97|M98),(A\*|B\*),\$S \$N"))
{
Console.WriteLine($" 机台码命令: {nextLine}");
// 检查下下行是否是坐标数据
if (i + 2 < lines.Length)
{
string coordinateLine = lines[i + 2].Trim();
if (Regex.IsMatch(coordinateLine, @"X([+-]?\d+\.?\d*)Y([+-]?\d+\.?\d*)"))
{
foundCoordinate = true;
Console.WriteLine($" 坐标数据: {coordinateLine}");
}
}
}
}
}
}
}
}
// 5. 输出测试结果
Console.WriteLine("\n=== 测试结果 ===");
Console.WriteLine($"找到机台码刀具: {(foundMachineCode ? "" : "")}");
Console.WriteLine($"找到坐标数据: {(foundCoordinate ? "" : "")}");
if (foundMachineCode && foundCoordinate)
{
Console.WriteLine("✓ 机台码坐标数据完整性测试通过!");
}
else
{
Console.WriteLine("✗ 机台码坐标数据完整性测试失败!");
if (!foundMachineCode)
Console.WriteLine(" 原因:未找到机台码刀具");
if (!foundCoordinate)
Console.WriteLine(" 原因:机台码刀具缺少坐标数据");
}
// 6. 验证ToolItem中的坐标数据
var machineCodeTool = Tools.FirstOrDefault(t => t.ToolType == ToolType.MachineCode);
if (machineCodeTool != null)
{
Console.WriteLine($"\nToolItem中的机台码坐标数据:");
Console.WriteLine($" 刀具编号: T{machineCodeTool.ToolNumber:D2}");
Console.WriteLine($" 机台码命令: {machineCodeTool.MachineCodeCommand}");
Console.WriteLine($" 机台码类型: {machineCodeTool.MachineCodeType}");
Console.WriteLine($" 坐标数量: {machineCodeTool.HoleLocations?.Count ?? 0}");
if (machineCodeTool.HoleLocations != null && machineCodeTool.HoleLocations.Count > 0)
{
foreach (var location in machineCodeTool.HoleLocations)
{
Console.WriteLine($" 坐标: {location}");
}
}
}
}
/// <summary>
/// 测试机台码处理修复效果
/// </summary>
public void TestMachineCodeProcessingFix()
{
Console.WriteLine("=== 测试机台码处理修复效果 ===");
// 测试钻带内容(包含机台码)
string testDrillTape = @"M48
;厚铜板参数-镀膜-EA-250618
T01C1.049H05000Z+0.000S060.00F105.0U0700.0
T02C1.550H01500Z+0.150S070.00F008.0U0800.0
T03C1.156H03000Z-0.200S040.00F030.0U0900.0
T04C0.499H01500Z+0.150S070.00F008.0U0800.0
%
T01
X-167525Y013500
X-167525Y018500
X-167525Y023500
T02
X-065975Y115250
X-085825Y122450
T03
X-069659Y016450G85X-094159Y016450
X-181341Y195550G85X-156841Y195550
T04
M97,A*,$S $N
X-194000Y002000
M30";
try
{
// 1. 使用DrillTapeProcessor处理钻带
Console.WriteLine("\n1. 使用DrillTapeProcessor处理钻带:");
var result = DrillTapeProcessor.ProcessDrillTape(testDrillTape);
if (!result.Success)
{
Console.WriteLine($"处理失败: {result.Message}");
return;
}
// 2. 检查ToolResult中的机台码信息
Console.WriteLine("\n2. 检查ToolResult中的机台码信息:");
foreach (var toolResult in result.ToolResults)
{
Console.WriteLine($"T{toolResult.ToolNumber:D2}: 类型={toolResult.ToolType}, 命令={toolResult.MachineCodeCommand}, 类型={toolResult.MachineCodeType}");
}
// 3. 使用LoadToolsFromDrillTape方法加载到ViewModel
Console.WriteLine("\n3. 加载到ViewModel并检查ToolItem中的机台码信息:");
DrillTapeContent = testDrillTape;
Tools.Clear();
LoadToolsFromDrillTape(testDrillTape);
foreach (var tool in Tools)
{
Console.WriteLine($"T{tool.ToolNumber:D2}: 类型={tool.ToolType}, 命令={tool.MachineCodeCommand}, 类型={tool.MachineCodeType}");
}
// 4. 测试GenerateReorderedDrillTape方法
Console.WriteLine("\n4. 测试GenerateReorderedDrillTape方法:");
string reorderedDrillTape = DrillTapeProcessorExtensions.GenerateReorderedDrillTape(testDrillTape, Tools.ToList());
Console.WriteLine("重排后的钻带内容:");
Console.WriteLine(reorderedDrillTape);
// 5. 验证机台码信息是否正确保留
Console.WriteLine("\n5. 验证机台码信息是否正确保留:");
bool machineCodeFound = false;
bool machineCodeCommandFound = false;
bool machineCodeTypeFound = false;
var lines = reorderedDrillTape.Split(new[] { '\r', '\n' }, StringSplitOptions.None);
foreach (var line in lines)
{
if (line.Contains("M97") || line.Contains("M98"))
{
machineCodeFound = true;
if (line.Contains("M97") || line.Contains("M98"))
{
machineCodeCommandFound = true;
}
if (line.Contains("A*") || line.Contains("B*"))
{
machineCodeTypeFound = true;
}
Console.WriteLine($"找到机台码命令行: {line}");
}
}
Console.WriteLine($"\n验证结果:");
Console.WriteLine($"机台码命令存在: {machineCodeFound}");
Console.WriteLine($"机台码命令类型正确: {machineCodeCommandFound}");
Console.WriteLine($"机台码类型正确: {machineCodeTypeFound}");
if (machineCodeFound && machineCodeCommandFound && machineCodeTypeFound)
{
Console.WriteLine("\n✓ 机台码处理修复效果验证成功!");
}
else
{
Console.WriteLine("\n✗ 机台码处理修复效果验证失败!");
}
}
catch (Exception ex)
{
Console.WriteLine($"测试过程中发生异常: {ex.Message}");
Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
}
}
}
}