AddScrewView.xaml.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. using Prism.Events;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows;
  10. using System.Windows.Controls;
  11. using System.Windows.Data;
  12. using System.Windows.Documents;
  13. using System.Windows.Input;
  14. using System.Windows.Media;
  15. using System.Windows.Media.Imaging;
  16. using System.Windows.Shapes;
  17. using TeamAAS_VP.Core.PLCs;
  18. using TeamAAS_VP.Enums;
  19. using TeamAAS_VP.Events;
  20. using TeamAAS_VP.Interfaces;
  21. using TeamAAS_VP.Models;
  22. using TeamAAS_VP.Resources.Languages;
  23. using TeamAAS_VP.Services;
  24. using TouchSocket.Core;
  25. namespace TeamAAS_VP.Views
  26. {
  27. /// <summary>
  28. /// AddScrewView.xaml 的交互逻辑
  29. /// </summary>
  30. public partial class AddScrewView : Window
  31. {
  32. IConfigService _configService;
  33. IEventAggregator _eventAggregator;
  34. IPlcService _plcService;
  35. public ICommand OkCommand { get; }
  36. public ICommand CancelCommand { get; }
  37. public string ScannedBarcode { get; private set; }
  38. public AddScrewView(IConfigService configService, IEventAggregator eventAggregator, IPlcService plcService)
  39. {
  40. InitializeComponent();
  41. _configService = configService;
  42. _eventAggregator = eventAggregator;
  43. _plcService=plcService;
  44. OkCommand = new RelayCommand(OkExecute);
  45. CancelCommand = new RelayCommand(CancelExecute);
  46. this.Loaded += (s, e) => { BarcodeTextBox.Focus(); };
  47. // 把Command赋值给DataContext,方便绑定
  48. DataContext = this;
  49. }
  50. ///// <summary>
  51. ///// PLC命令触发时
  52. ///// </summary>
  53. ///// <param name="tuple"></param>
  54. //private async void PlcCommandTrigger((string key, string nodeId, object value) tuple)
  55. //{
  56. // try
  57. // {
  58. // if (tuple.key != "AutoSensor")
  59. // {
  60. // return;
  61. // }
  62. // var addressConfig = _configService.GetPlcAddresses();
  63. // var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
  64. // string a = "";
  65. // var stationConfig = _configService.GetDeviceInfo(0);
  66. // ScannedBarcode = BarcodeTextBox.Text;
  67. // if (ScannedBarcode.Contains("|"))
  68. // {
  69. // string[] arr = ScannedBarcode.Split("|");
  70. // for (int i = 0; i < 16; i++)
  71. // {
  72. // a += arr[i];
  73. // }
  74. // }
  75. // else
  76. // {
  77. // a = ScannedBarcode;
  78. // }
  79. // if (string.IsNullOrWhiteSpace(ScannedBarcode))
  80. // {
  81. // MessageBox.Show("请先扫描螺丝条码", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
  82. // BarcodeTextBox.Focus(); // 重新聚焦
  83. // return;
  84. // }
  85. // if (a == stationConfig.DataInfo.Screwsize1 || a == stationConfig.DataInfo.Screwsize2)
  86. // {
  87. // MessageBox.Show("螺丝型号匹配成功", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
  88. // //SendTaskMessage($"螺丝型号匹配成功", MessageLevel.Info);
  89. // ExportDataToCsv(DateTime.Now.ToString("yyyy-MM-dd HH:mm"), a, true, @"D:\添加螺丝记录\螺丝上料Log.csv", appendMode: true);
  90. // await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, 1), (Int16)1);
  91. // }
  92. // else
  93. // {
  94. // MessageBox.Show("螺丝型号匹配失败", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
  95. // //SendTaskMessage($"螺丝型号匹配失败", MessageLevel.Error);
  96. // ExportDataToCsv(DateTime.Now.ToString("yyyy-MM-dd HH:mm"), a, false, @"D:\添加螺丝记录\螺丝上料Log.csv", appendMode: true);
  97. // await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, 1), (Int16)1);
  98. // }
  99. // DialogResult = true;
  100. // Close();
  101. // }
  102. // catch (Exception ex)
  103. // {
  104. // }
  105. //}
  106. private async void OkExecute(object sender)
  107. {
  108. try
  109. {
  110. var addressConfig = _configService.GetPlcAddresses();
  111. var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
  112. string a = "";
  113. var stationConfig = _configService.GetDeviceInfo(0);
  114. ScannedBarcode = BarcodeTextBox.Text;
  115. if (ScannedBarcode.Contains("|"))
  116. {
  117. string[] arr = ScannedBarcode.Split("|");
  118. for (int i = 0; i < 16; i++)
  119. {
  120. a += arr[i];
  121. }
  122. }
  123. else
  124. {
  125. a = ScannedBarcode;
  126. }
  127. if (string.IsNullOrWhiteSpace(ScannedBarcode))
  128. {
  129. MessageBox.Show("请先扫描螺丝条码", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
  130. BarcodeTextBox.Focus(); // 重新聚焦
  131. return;
  132. }
  133. if (a == stationConfig.DataInfo.Screwsize1 || a == stationConfig.DataInfo.Screwsize2)
  134. {
  135. await plc.WriteNodeAsync<bool>(addressConfig.Out_PlcFail.Address, false);
  136. MessageBox.Show("螺丝型号匹配成功", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
  137. //SendTaskMessage($"螺丝型号匹配成功", MessageLevel.Info);
  138. ExportDataToCsv(DateTime.Now.ToString("yyyy-MM-dd HH:mm"), a, stationConfig.DataInfo, true, @"D:\添加螺丝记录\螺丝上料Log.csv", appendMode: true);
  139. }
  140. else
  141. {
  142. await plc.WriteNodeAsync<bool>(addressConfig.Out_PlcFail.Address, true);
  143. MessageBox.Show("螺丝型号匹配失败", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
  144. //SendTaskMessage($"螺丝型号匹配失败", MessageLevel.Error);
  145. ExportDataToCsv(DateTime.Now.ToString("yyyy-MM-dd HH:mm"), a, stationConfig.DataInfo, false, @"D:\添加螺丝记录\螺丝上料Log.csv", appendMode: true);
  146. }
  147. DialogResult = true;
  148. Close();
  149. }
  150. catch (Exception ex)
  151. {
  152. }
  153. //PlcCommandTrigger(("AutoSensor", "", ""));
  154. //string a = "";
  155. //var stationConfig = _configService.GetDeviceInfo(0);
  156. //ScannedBarcode = BarcodeTextBox.Text;
  157. //if (ScannedBarcode.Contains("|"))
  158. //{
  159. // string[] arr = ScannedBarcode.Split("|");
  160. // for (int i = 0; i < 16; i++)
  161. // {
  162. // a += arr[i];
  163. // }
  164. //}
  165. //else
  166. //{
  167. // a = ScannedBarcode;
  168. //}
  169. //if (string.IsNullOrWhiteSpace(ScannedBarcode))
  170. //{
  171. // MessageBox.Show("请先扫描螺丝条码", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
  172. // BarcodeTextBox.Focus(); // 重新聚焦
  173. // return;
  174. //}
  175. //if (a == stationConfig.DataInfo.Screwsize1 || a == stationConfig.DataInfo.Screwsize2)
  176. //{
  177. // MessageBox.Show("螺丝型号匹配成功", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
  178. // //SendTaskMessage($"螺丝型号匹配成功", MessageLevel.Info);
  179. // ExportDataToCsv(DateTime.Now.ToString("yyyy-MM-dd HH:mm"), a, true, @"D:\添加螺丝记录\螺丝上料Log.csv", appendMode: true);
  180. //}
  181. //else
  182. //{
  183. // MessageBox.Show("螺丝型号匹配失败", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
  184. // //SendTaskMessage($"螺丝型号匹配失败", MessageLevel.Error);
  185. // ExportDataToCsv(DateTime.Now.ToString("yyyy-MM-dd HH:mm"), a, false, @"D:\添加螺丝记录\螺丝上料Log.csv", appendMode: true);
  186. //}
  187. //DialogResult = true;
  188. //Close();
  189. }
  190. private void CancelExecute(object sender)
  191. {
  192. DialogResult = false;
  193. Close();
  194. }
  195. //public void SendTaskMessage(string msg, MessageLevel level)
  196. //{
  197. // App.Current.Dispatcher.Invoke(() =>aZ
  198. // {
  199. // _eventAggregator.GetEvent<TaskMessageNotification>().Publish(new Models.MessageStruct() { Message = msg, level = level });
  200. // });
  201. //}
  202. public static void ExportDataToCsv(string dateTime, string model, CTQ_Data DataInfo, bool isMatch, string savePath, bool appendMode = false)
  203. {
  204. string directory = global::System.IO.Path.GetDirectoryName(savePath);
  205. // 如果目录路径不为空且不存在,则创建
  206. if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
  207. {
  208. Directory.CreateDirectory(directory);
  209. }
  210. // 构建CSV内容
  211. StringBuilder csvContent = new StringBuilder();
  212. // 处理表头:仅当文件不存在/非追加模式时,才写入表头
  213. if (!appendMode || !File.Exists(savePath))
  214. {
  215. csvContent.AppendLine("日期时间,目标螺丝型号1,螺丝型号2,添加螺丝型号,是否匹配");
  216. }
  217. // 处理数据行
  218. string matchStr = isMatch ? "是" : "否";
  219. // 如果型号中包含逗号,需要用引号包裹
  220. string safeModel = model;
  221. if (safeModel.Contains(","))
  222. {
  223. safeModel = $"\"{safeModel}\"";
  224. }
  225. csvContent.AppendLine($"{dateTime},{DataInfo.Screwsize1},{DataInfo.Screwsize2},{model},{matchStr}");
  226. // 写入文件:UTF-8带BOM编码,Excel打开无乱码
  227. if (appendMode && File.Exists(savePath))
  228. {
  229. // 追加模式:在文件末尾新增内容
  230. File.AppendAllText(savePath, csvContent.ToString(), Encoding.UTF8);
  231. }
  232. else
  233. {
  234. // 覆盖模式:新建/替换文件
  235. File.WriteAllText(savePath, csvContent.ToString(), Encoding.UTF8);
  236. }
  237. }
  238. }
  239. public class RelayCommand : ICommand
  240. {
  241. private readonly Action<object> _execute;
  242. private readonly Func<object, bool> _canExecute;
  243. public event EventHandler CanExecuteChanged
  244. {
  245. add { CommandManager.RequerySuggested += value; }
  246. remove { CommandManager.RequerySuggested -= value; }
  247. }
  248. public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
  249. {
  250. _execute = execute ?? throw new ArgumentNullException(nameof(execute));
  251. _canExecute = canExecute;
  252. }
  253. public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);
  254. public void Execute(object parameter) => _execute(parameter);
  255. }
  256. }