UCPatchGrid.xaml.cs 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  1. using MeterVision.Config;
  2. using MeterVision.db;
  3. using MeterVision.Dlg;
  4. using MeterVision.FreeAi;
  5. using MeterVision.model;
  6. using MeterVision.Util;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Collections.ObjectModel;
  10. using System.ComponentModel;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. using System.Windows;
  17. using System.Windows.Controls;
  18. using System.Windows.Data;
  19. using System.Windows.Documents;
  20. using System.Windows.Input;
  21. using System.Windows.Media;
  22. using System.Windows.Media.Imaging;
  23. using System.Windows.Navigation;
  24. using System.Windows.Shapes;
  25. namespace MeterVision.Patch
  26. {
  27. /// <summary>
  28. /// UCPatchGrid.xaml 的交互逻辑
  29. /// </summary>
  30. public partial class UCPatchGrid : UserControl, INotifyPropertyChanged
  31. {
  32. public event PropertyChangedEventHandler PropertyChanged;
  33. protected void OnPropertyChanged(string propertyName)
  34. {
  35. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  36. }
  37. //定义任务详情数据源
  38. public ObservableCollection<PatchDetailItem> PatchDetailItemList { get; set; }
  39. // 定义事件,用于通知外部组件选中项已更改
  40. public event EventHandler<PatchDetailItemChangedEventArgs> OnSelectedPatchDetailItemChanged;
  41. public event Action<string> OnRefreshPatchItem;
  42. //删除标准模板明细事件
  43. public static event Action<string> OnDeleteStandDetail;
  44. //修改标准模板值事件
  45. public static event Action<string,string> OnUpdateStandValue;
  46. private PatchDetailItem _selectedPatchDetailItem;
  47. //定义SelectedDataItem属性,并在值变化时触发事件
  48. public PatchDetailItem SelectedPatchDetailItem
  49. {
  50. get => _selectedPatchDetailItem;
  51. set
  52. {
  53. if (_selectedPatchDetailItem != value)
  54. {
  55. _selectedPatchDetailItem = value;
  56. OnPropertyChanged(nameof(SelectedPatchDetailItem));
  57. OnSelectedPatchDetailItemChanged?.Invoke(this, new PatchDetailItemChangedEventArgs(value));
  58. }
  59. }
  60. }
  61. private PatchItem _curPatchItem;
  62. private PatchItem CurPatchItem
  63. {
  64. get => _curPatchItem;
  65. set
  66. {
  67. if (_curPatchItem != value)
  68. {
  69. _curPatchItem = value;
  70. //PatchDetailPage.InitDefaulValue(mConfigItem.PatchPageSize);
  71. //PatchDetailPage.InitDefaulValue();
  72. //LoadPatchDetailItemList();
  73. }
  74. }
  75. }
  76. //此属性只在函数内部调用
  77. private VPatchStation _curStationItem;
  78. private VPatchStation CurStationItem
  79. {
  80. get => _curStationItem;
  81. set
  82. {
  83. if (_curStationItem != value)
  84. {
  85. _curStationItem = value;
  86. //PatchDetailPage.InitDefaulValue(mConfigItem.StandPageSize);
  87. //LoadStandDetailItemList();
  88. }
  89. }
  90. }
  91. private PatchFindType _selectedPatchFindType;
  92. private PatchFindType SelectedPatchFindType
  93. {
  94. get => _selectedPatchFindType;
  95. set
  96. {
  97. if (_selectedPatchFindType != value)
  98. {
  99. _selectedPatchFindType = value;
  100. //OnPropertyChanged(nameof(SelectedPatchFindType));
  101. //PatchDetailPage.InitDefaulValue();
  102. }
  103. }
  104. }
  105. //改变PatchItem或PatchFinType
  106. public async void ChangePatchItemOrFinType(PatchItem curPatchItem,VPatchStation curStationItem,PatchFindType patchFindType)
  107. {
  108. bool blPatchItemChanged = false;
  109. bool blPatchFindTypeChanged = false;
  110. bool blStationChanged = false;
  111. //判断是否数据发生变化
  112. if(curPatchItem != _curPatchItem)
  113. {
  114. CurPatchItem = curPatchItem;
  115. blPatchItemChanged = true;
  116. }
  117. if(curStationItem != _curStationItem)
  118. {
  119. CurStationItem = curStationItem;
  120. blStationChanged = true;
  121. }
  122. if(patchFindType != _selectedPatchFindType)
  123. {
  124. SelectedPatchFindType = patchFindType;
  125. blPatchFindTypeChanged = true;
  126. }
  127. //if(blPatchItemChanged || blPatchFindTypeChanged || blStationChanged)
  128. {
  129. PatchDetailPage.InitDefaulValue();
  130. await LoadPatchDetailItemList(true);
  131. }
  132. }
  133. public CfginiItem mConfigItem { get; set; }
  134. public PageModel PatchDetailPage { get; set; }
  135. private int _totalRecord;
  136. public int TotalRecords
  137. {
  138. get => _totalRecord;
  139. set
  140. {
  141. if (_totalRecord != value)
  142. {
  143. _totalRecord = value;
  144. OnPropertyChanged(nameof(TotalRecords));
  145. }
  146. }
  147. }
  148. public UCPatchGrid()
  149. {
  150. InitializeComponent();
  151. PatchDetailItemList = new ObservableCollection<PatchDetailItem>();
  152. dgPatchDetail.ItemsSource = PatchDetailItemList;
  153. mConfigItem = CfginiItem.GetConfigItem();
  154. PatchDetailPage = new PageModel
  155. {
  156. PageSize = mConfigItem.PageSize3, //mConfigItem.PatchPageSize,
  157. PageNumber = 1
  158. };
  159. //mConfigItem.OnPatchPageSizeChanged += MConfigItem_OnPatchPageSizeChanged;
  160. //mConfigItem.OnPatchPageSizeChanged += MConfigItem_OnPatchPageSizeChanged;
  161. mConfigItem.OnPageSize3Changed += MConfigItem_OnPageSize3Changed;
  162. this.DataContext = this;
  163. }
  164. private async void MConfigItem_OnPageSize3Changed(int pageSize3)
  165. {
  166. //throw new NotImplementedException();
  167. PatchDetailPage.InitDefaulValue(pageSize3);
  168. await LoadPatchDetailItemList(true);
  169. }
  170. //private void MConfigItem_OnPatchPageSizeChanged(int pageSize)
  171. //{
  172. // PatchDetailPage.InitDefaulValue(pageSize);
  173. // LoadPatchDetailItemList(true);
  174. //}
  175. //private void MConfigItem_OnPatchPageSizeChanged(object sender, PageSizeChangedEventArgs e)
  176. //{
  177. // PatchDetailPage.InitDefaulValue(e.PageSize);
  178. // LoadPatchDetailItemList(true);
  179. //}
  180. private async Task<bool> LoadPatchDetailItemList(bool scrollTop)
  181. //private void LoadPatchDetailItemList(bool scrollTop)
  182. {
  183. PatchDetailItemList.Clear();
  184. //if (CurPatchItem != null )
  185. if(CurStationItem != null)
  186. {
  187. try
  188. {
  189. var result = await Task.Run(() =>
  190. {
  191. //数据库查询
  192. //return DBPatch.GetPagedPatchDetails(
  193. // PatchDetailPage.PageNumber, PatchDetailPage.PageSize, CurPatchItem.PatchId);
  194. string stationId = CurStationItem == null ? "" : CurStationItem.StationId;
  195. PatchFindModel findModel = new PatchFindModel(PatchDetailPage.PageNumber, PatchDetailPage.PageSize,
  196. CurPatchItem.PatchId,stationId ,SelectedPatchFindType);
  197. return DBPatch.GetPagedPatchDetails(findModel);
  198. });
  199. //var result = DBPatch.GetPagedPatchDetails(findModel);
  200. //更新分页信息
  201. TotalRecords = result.Item1;
  202. PatchDetailPage.PageCount = result.Item2;
  203. List<TPatchDetail> patchDetails = result.Item3;
  204. //更新数据需要在主线中进行
  205. Application.Current.Dispatcher.Invoke(() =>
  206. {
  207. int index = 0;
  208. foreach (TPatchDetail patchDetail in patchDetails)
  209. {
  210. index++;
  211. PatchDetailItem item = new PatchDetailItem(patchDetail);
  212. item.Index = index + ((PatchDetailPage.PageNumber - 1) * PatchDetailPage.PageSize);
  213. PatchDetailItemList.Add(item);
  214. }//foreach
  215. SelectedPatchDetailItem = null;
  216. if (PatchDetailItemList.Count > 0 && scrollTop)
  217. {
  218. dgPatchDetail.ScrollIntoView(dgPatchDetail.Items[0]);
  219. }
  220. });
  221. }
  222. catch (Exception ex)
  223. {
  224. MessageBox.Show(Application.Current.MainWindow,
  225. $"加载数据时发生错误:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  226. return false;
  227. }
  228. }
  229. if(PatchDetailItemList.Count > 0)
  230. {
  231. SelectedPatchDetailItem = PatchDetailItemList[0];
  232. }
  233. else
  234. {
  235. SelectedPatchDetailItem = null;
  236. }
  237. return true;
  238. }
  239. private void StandResultTextBlock_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  240. {
  241. // 检查是否是双击
  242. if (e.ClickCount == 2)
  243. {
  244. // 获取当前行的数据上下文
  245. var textBlock = sender as TextBlock;
  246. if (textBlock == null) return;
  247. var dataContext = textBlock.DataContext as PatchDetailItem; // 替换为你的数据类型
  248. if (dataContext == null) return;
  249. SelectedPatchDetailItem = dataContext;
  250. StandValueModel standValueModel = new StandValueModel(dataContext);
  251. var dialog = new EditStandValueDlg(standValueModel)
  252. {
  253. Owner = Application.Current.MainWindow,
  254. WindowStartupLocation = WindowStartupLocation.CenterOwner
  255. };
  256. //if(dialog.ShowDialog() == true)
  257. //{
  258. // UpdatePatchDetailStandValue(dataContext, standValueModel);
  259. //}//if showDialog
  260. dialog.OnEditStandValue += (value) =>
  261. {
  262. UpdatePatchDetailStandValue(dataContext, standValueModel);
  263. };
  264. dialog.Show();
  265. }//e.clickCount
  266. }
  267. private void UpdateStandvalue(PatchDetailItem detailItem)
  268. {
  269. StandValueModel standValueModel = new StandValueModel(detailItem);
  270. var dialog = new EditStandValueDlg(standValueModel)
  271. {
  272. Owner = Application.Current.MainWindow,
  273. WindowStartupLocation = WindowStartupLocation.CenterOwner
  274. };
  275. //if (dialog.ShowDialog() == true)
  276. //{
  277. // UpdatePatchDetailStandValue(detailItem, standValueModel);
  278. //}//if showDialog
  279. dialog.OnEditStandValue += (value) =>
  280. {
  281. UpdatePatchDetailStandValue(detailItem, standValueModel);
  282. };
  283. dialog.Show();
  284. }
  285. private void UpdatePatchDetailStandValue(PatchDetailItem detailItem, StandValueModel standValueModel)
  286. {
  287. try
  288. {
  289. //修改数据库
  290. //判断detailItem中的FinalValue与标准值是否相等
  291. int equalFlag = 0;
  292. if (string.IsNullOrWhiteSpace(standValueModel.StandValue))
  293. {
  294. equalFlag = 3;
  295. }
  296. else
  297. {
  298. if (double.TryParse(standValueModel.StandValue, out double dStandValue))
  299. {
  300. equalFlag = detailItem.GetEqualFlag(dStandValue, detailItem.FinalValue);
  301. }
  302. }
  303. bool updateStandValue1 = DBPatch.UpdatePatchDetailStandValue(detailItem.PatchDetailId, standValueModel.StandValue,equalFlag);
  304. bool updateStandValue2 = DBStand.UpdateStandDetailStandValue(detailItem.SrcImage, standValueModel.StandValue);
  305. if (updateStandValue1 && updateStandValue2)
  306. {
  307. detailItem.StandValue = standValueModel.StandValue;
  308. detailItem.EqualFlag = equalFlag;
  309. //MessageBox.Show(Application.Current.MainWindow, "修改标准值完成。", "提示", MessageBoxButton.OK,
  310. // MessageBoxImage.Information);
  311. //应该更新目录内容
  312. OnRefreshPatchItem?.Invoke(detailItem.PatchId);
  313. OnUpdateStandValue?.Invoke(detailItem.StandDetailId, detailItem.StandValue);
  314. }
  315. else
  316. {
  317. MessageBox.Show(Application.Current.MainWindow, "修改标准值失败。", "警告", MessageBoxButton.OK,
  318. MessageBoxImage.Warning);
  319. }
  320. }
  321. catch (Exception ex)
  322. {
  323. MessageBox.Show(Application.Current.MainWindow, $"修改标准值错误:{ex.Message}!", "警告", MessageBoxButton.OK,
  324. MessageBoxImage.Warning);
  325. }
  326. }
  327. private void SrcImage_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  328. {
  329. var image = sender as Image;
  330. if (image == null) return;
  331. var dataContext = image.DataContext as PatchDetailItem;
  332. if (dataContext == null) return;
  333. //var dialog = new ImageViewerWindow(dataContext.SourceImagePath)
  334. if (!File.Exists(dataContext.SrcImage)) return;
  335. var dialog = new imgWindow(dataContext.SrcImage)
  336. {
  337. Owner = Application.Current.MainWindow
  338. };
  339. dialog.Show();
  340. }
  341. private void DstImage_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  342. {
  343. var image = sender as Image;
  344. if (image == null) return;
  345. var dataContext = image.DataContext as PatchDetailItem;
  346. if (dataContext == null) return;
  347. //var dialog = new ImageViewerWindow(dataContext.SourceImagePath)
  348. if (!File.Exists(dataContext.DstImage)) return;
  349. var dialog = new imgWindow(dataContext.DstImage)
  350. {
  351. Owner = Application.Current.MainWindow
  352. };
  353. dialog.Show();
  354. }
  355. public async void NextPage()
  356. {
  357. if (PatchDetailPage.PageNumber < PatchDetailPage.PageCount)
  358. {
  359. PatchDetailPage.PageNumber += 1;
  360. await LoadPatchDetailItemList(true);
  361. }
  362. }
  363. public async void PrePage()
  364. {
  365. if (PatchDetailPage.PageNumber > 1)
  366. {
  367. PatchDetailPage.PageNumber -= 1;
  368. await LoadPatchDetailItemList(true);
  369. }
  370. }
  371. public async void FirstPage()
  372. {
  373. if (PatchDetailPage.PageNumber > 1)
  374. {
  375. PatchDetailPage.PageNumber = 1;
  376. await LoadPatchDetailItemList(true);
  377. }
  378. }
  379. public async void LastPage()
  380. {
  381. if (PatchDetailPage.PageNumber < PatchDetailPage.PageCount)
  382. {
  383. PatchDetailPage.PageNumber = PatchDetailPage.PageCount;
  384. await LoadPatchDetailItemList(true);
  385. }
  386. }
  387. public async void SpeciPage(int pageNumber)
  388. {
  389. if (pageNumber != PatchDetailPage.PageNumber &&
  390. pageNumber > 0 && pageNumber <= PatchDetailPage.PageCount)
  391. {
  392. PatchDetailPage.PageNumber = pageNumber;
  393. await LoadPatchDetailItemList(true);
  394. }
  395. }
  396. private bool IsProcessingTask = false;
  397. public async Task<bool> StartPatchTask()
  398. {
  399. if (CurPatchItem == null) return false;
  400. int taskCount = await GetTaskCount();
  401. if(taskCount == 0)
  402. {
  403. MessageBox.Show(Application.Current.MainWindow, "没有任务可执行。", "提示",
  404. MessageBoxButton.OK, MessageBoxImage.Information);
  405. return false;
  406. }
  407. //先查询是否有需要识别的任务
  408. PatchTaskDlg patchTaskDlg = new PatchTaskDlg()
  409. {
  410. Owner = Application.Current.MainWindow,
  411. WindowStartupLocation = WindowStartupLocation.CenterOwner
  412. };
  413. patchTaskDlg.OnStopTask += PatchTaskDlg_OnStopTask;
  414. patchTaskDlg.Show();
  415. Application.Current.MainWindow.IsEnabled = false;
  416. try
  417. {
  418. IsProcessingTask = true;
  419. int runCount = 0;
  420. await Task.Run(() =>
  421. {
  422. string stationId = CurStationItem == null ? "" : CurStationItem.StationId;
  423. //查询任务
  424. List<TPatchDetail> patchDetails = DBPatch.GetPatchDetailsWithRunFlag(CurPatchItem.PatchId,stationId,0);
  425. for(int i = 0; i < patchDetails.Count; i++)
  426. {
  427. if (!IsProcessingTask)
  428. {
  429. return;
  430. }
  431. FaRun faRun = new FaRun();
  432. ResultModel resultModel = null;
  433. try
  434. {
  435. resultModel = faRun.StartRecognition(patchDetails[i]);
  436. }
  437. catch(Exception ex)
  438. {
  439. Console.WriteLine(ex.Message);
  440. }
  441. if (resultModel == null) continue;
  442. patchDetails[i].SetResult(resultModel);
  443. bool blUpdate = DBPatch.UpdatePatchDetailWithResult(patchDetails[i]);
  444. //修改下一条记录的最近一次正确值(判断下一条数据的站点与本站点相同)
  445. if( i + 1 < patchDetails.Count && patchDetails[i + 1].StationId == patchDetails[i].StationId)
  446. {
  447. patchDetails[i + 1].LastCompress = resultModel.CompressIndex;
  448. if (patchDetails[i].IsGoodResult())
  449. {
  450. patchDetails[i+1].LatestValue = (long)resultModel.FinalValue;
  451. patchDetails[i+1].LatestComplete = (long)resultModel.CompleteValue;
  452. patchDetails[i+1].LatestTime = patchDetails[i].SampleTime;
  453. }
  454. else
  455. {
  456. patchDetails[i+1].LatestValue = patchDetails[i].LatestValue;
  457. patchDetails[i+1].LatestComplete = patchDetails[i].LatestComplete;
  458. patchDetails[i+1].LatestTime = patchDetails[i].LatestTime;
  459. }
  460. //更新改变了Latest的数据
  461. if (DBPatch.UpdatePatchDetails_Latest(patchDetails[i + 1]))
  462. {
  463. foreach (PatchDetailItem detailItem in PatchDetailItemList)
  464. {
  465. if (detailItem.PatchDetailId == patchDetails[i + 1].PatchDetailId)
  466. {
  467. ObjectHelper.CopyMatchingFields(patchDetails[i + 1], detailItem);
  468. break;
  469. }
  470. }//foreach
  471. }
  472. }//i+1
  473. if (blUpdate)
  474. {
  475. runCount++;
  476. }
  477. //根据结果更新表内容,暂且模拟
  478. //Thread.Sleep(300);
  479. Application.Current.Dispatcher.Invoke(() =>
  480. {
  481. patchTaskDlg.UpdateProgress(i + 1, taskCount);
  482. //更新背后的数据
  483. if (blUpdate)
  484. {
  485. //如果界面中存在本条数据,则更新。意义不大
  486. foreach (PatchDetailItem detailItem in PatchDetailItemList)
  487. {
  488. if(detailItem.PatchDetailId == patchDetails[i].PatchDetailId)
  489. {
  490. ObjectHelper.CopyMatchingFields(patchDetails[i], detailItem);
  491. break;
  492. }
  493. }//foreach
  494. }//if
  495. });
  496. //Thread.Sleep(3000);
  497. }//for i
  498. });
  499. return runCount > 0;
  500. }
  501. catch(Exception ex)
  502. {
  503. MessageBox.Show(Application.Current.MainWindow, $"执行批量识别任务:{ex.Message}", "错误",
  504. MessageBoxButton.OK, MessageBoxImage.Error);
  505. return false;
  506. }
  507. finally
  508. {
  509. // 执行完毕后恢复主界面交互
  510. Application.Current.MainWindow.IsEnabled = true;
  511. patchTaskDlg.Close();
  512. }
  513. }
  514. //如果是存在已执行的任务,恢复未执行任务的数据状态
  515. public async Task<bool> ResetPatchTask()
  516. {
  517. if (CurPatchItem == null) return false;
  518. string titleInfo = "正在恢复为任务未执行的状态,请稍后...";
  519. WaitWindow waitWindow = new WaitWindow(titleInfo)
  520. {
  521. Owner = Application.Current.MainWindow,
  522. WindowStartupLocation = WindowStartupLocation.CenterOwner
  523. };
  524. waitWindow.Show();
  525. try
  526. {
  527. List<TPatchDetail> patchDetails = null;
  528. bool blUpdate = false;
  529. await Task.Run(() =>
  530. {
  531. string stationId = CurStationItem == null ? "" : CurStationItem.StationId;
  532. //查询数据
  533. patchDetails = DBPatch.GetPatchDetailsWithRunFlag(CurPatchItem.PatchId, stationId,1);
  534. foreach(var patchDetail in patchDetails)
  535. {
  536. //删除目标图像及识别日志
  537. try
  538. {
  539. if (File.Exists(patchDetail.DstImage))
  540. {
  541. File.Delete(patchDetail.DstImage);
  542. }
  543. if (File.Exists(patchDetail.LogPath))
  544. {
  545. File.Delete(patchDetail.LogPath);
  546. }
  547. }
  548. catch
  549. {
  550. }
  551. patchDetail.ResetRunValue(); //恢复初始值
  552. }
  553. if (patchDetails.Count > 0)
  554. {
  555. blUpdate = DBPatch.UpdatePatchDetails(patchDetails);
  556. }
  557. });
  558. if (blUpdate && patchDetails != null)
  559. {
  560. foreach (PatchDetailItem detailItem in PatchDetailItemList)
  561. {
  562. var findItem = patchDetails.Find((a) => a.PatchDetailId == detailItem.PatchDetailId);
  563. if(findItem!= null)
  564. {
  565. ObjectHelper.CopyMatchingFields(findItem, detailItem);
  566. }
  567. }//foreach
  568. }
  569. return true;
  570. }
  571. catch(Exception ex)
  572. {
  573. MessageBox.Show(Application.Current.MainWindow, $"失败:{ex.Message}", "错误",
  574. MessageBoxButton.OK, MessageBoxImage.Error);
  575. return false;
  576. }
  577. finally
  578. {
  579. waitWindow.Close();
  580. }
  581. }
  582. private void PatchTaskDlg_OnStopTask()
  583. {
  584. IsProcessingTask = false;
  585. //throw new NotImplementedException();
  586. }
  587. //获取任务数量
  588. private async Task<int> GetTaskCount()
  589. {
  590. if (CurPatchItem == null) return 0;
  591. string titleInfo = "正在获取任务数量,请稍后...";
  592. WaitWindow waitWindow = new WaitWindow(titleInfo)
  593. {
  594. Owner = Application.Current.MainWindow,
  595. WindowStartupLocation = WindowStartupLocation.CenterOwner
  596. };
  597. waitWindow.Show();
  598. try
  599. {
  600. int taskCount = await Task.Run(() =>
  601. {
  602. string stationId = CurStationItem == null ? "" : CurStationItem.StationId;
  603. return DBPatch.GetPatchDetailsCountWithRunFlagZero(CurPatchItem.PatchId,stationId);
  604. });
  605. return taskCount;
  606. }
  607. catch (Exception ex)
  608. {
  609. MessageBox.Show(Application.Current.MainWindow, $"获取任务数量:{ex.Message}", "错误",
  610. MessageBoxButton.OK, MessageBoxImage.Error);
  611. return 0;
  612. }
  613. finally
  614. {
  615. waitWindow.Close();
  616. }
  617. }
  618. private void BtnLogViewer_Click(object sender, RoutedEventArgs e)
  619. {
  620. Button button = sender as Button;
  621. if (button == null) return;
  622. DataGridRow row = FindAncestor<DataGridRow>(button);
  623. if (row == null) return;
  624. //获取当前行绑定的数据项
  625. PatchDetailItem selectedItem = row.Item as PatchDetailItem;
  626. ShowLogViewer(selectedItem);
  627. }
  628. private void ShowLogViewer(PatchDetailItem selectedItem)
  629. {
  630. if (selectedItem.LogPath != null && File.Exists(selectedItem.LogPath))
  631. {
  632. //LogViewerWindow dialog = new LogViewerWindow(selectedItem.DstImage, selectedItem.LogPath)
  633. var dialog = new LogViewerWindow(selectedItem)
  634. {
  635. Owner = Application.Current.MainWindow,
  636. WindowStartupLocation = WindowStartupLocation.CenterOwner
  637. };
  638. //dialog.ShowDialog();
  639. dialog.Show();
  640. }
  641. }
  642. private void BtnDelDetailItem_Click(object sender, RoutedEventArgs e)
  643. {
  644. //删除选中项
  645. Button button = sender as Button;
  646. if (button == null) return;
  647. DataGridRow row = FindAncestor<DataGridRow>(button);
  648. if (row == null) return;
  649. //获取当前行绑定的数据项
  650. PatchDetailItem selectedItem = row.Item as PatchDetailItem;
  651. DeleteSelectedItem(selectedItem);
  652. }
  653. private async void DeleteSelectedItem(PatchDetailItem selectedItem)
  654. {
  655. if (selectedItem == null) return;
  656. MessageBoxResult result = MessageBox.Show("确定要删除此条目吗?", "确认删除", MessageBoxButton.YesNo, MessageBoxImage.Question);
  657. if (result != MessageBoxResult.Yes) return;
  658. string titleInfo = "正在删除,请稍后...";
  659. WaitWindow waitWindow = new WaitWindow(titleInfo)
  660. {
  661. Owner = Application.Current.MainWindow,
  662. WindowStartupLocation = WindowStartupLocation.CenterOwner
  663. };
  664. waitWindow.Show();
  665. try
  666. {
  667. bool deleteSuccess = false;
  668. await Task.Run(() =>
  669. {
  670. deleteSuccess = DBPatch.Delete_TPatchDetail_TStandDetail_ByStand(selectedItem.StandDetailId);
  671. //deleteSuccess = DBPatch.DeleteTPatchDetailById(selectedItem.PatchDetailId);
  672. });
  673. if (deleteSuccess)
  674. {
  675. //Application.Current.Dispatcher.Invoke(() =>
  676. //{
  677. // 从数据源中移除该条目
  678. int selectedIndex = PatchDetailItemList.IndexOf(selectedItem);
  679. //PatchDetailItemList.Remove(selectedItem); 改为从新加载页面
  680. SelectedPatchDetailItem = null;
  681. OnRefreshPatchItem?.Invoke(selectedItem.PatchId);
  682. OnDeleteStandDetail?.Invoke(selectedItem.StandDetailId);
  683. //重新加载数据
  684. await LoadPatchDetailItemList(false);
  685. //if (PatchDetailItemList.Count > selectedIndex)
  686. //{
  687. // dgPatchDetail.ScrollIntoView(dgPatchDetail.Items[selectedIndex]);
  688. //}
  689. //});
  690. }
  691. }
  692. catch (Exception ex)
  693. {
  694. MessageBox.Show(Application.Current.MainWindow, $"删除失败:{ex.Message}", "错误",
  695. MessageBoxButton.OK, MessageBoxImage.Error);
  696. }
  697. finally
  698. {
  699. waitWindow.Close();
  700. }
  701. }
  702. public static T FindAncestor<T>(DependencyObject dependencyObject) where T : DependencyObject
  703. {
  704. var parent = VisualTreeHelper.GetParent(dependencyObject);
  705. if (parent == null) return null;
  706. var parentT = parent as T;
  707. return parentT ?? FindAncestor<T>(parent);
  708. }
  709. private void MiViewLog_Click(object sender, RoutedEventArgs e)
  710. {
  711. if(SelectedPatchDetailItem != null)
  712. {
  713. ShowLogViewer(SelectedPatchDetailItem);
  714. }
  715. }
  716. private void MiDelteRow_Click(object sender, RoutedEventArgs e)
  717. {
  718. //获取当前行绑定的数据项
  719. if(SelectedPatchDetailItem != null)
  720. {
  721. DeleteSelectedItem(SelectedPatchDetailItem);
  722. }
  723. }
  724. private void BtnUpdateStandvalue_Click(object sender, RoutedEventArgs e)
  725. {
  726. Button button = sender as Button;
  727. if (button == null) return;
  728. DataGridRow row = FindAncestor<DataGridRow>(button);
  729. if (row == null) return;
  730. //获取当前行绑定的数据项
  731. var selectedItem = row.Item as PatchDetailItem;
  732. UpdateStandvalue(selectedItem);
  733. }
  734. private void MiUpdateStandvalue_Click(object sender, RoutedEventArgs e)
  735. {
  736. if (SelectedPatchDetailItem == null) return;
  737. UpdateStandvalue(SelectedPatchDetailItem);
  738. }
  739. private void MiAddMemo_Click(object sender, RoutedEventArgs e)
  740. {
  741. if (SelectedPatchDetailItem == null) return;
  742. AddMemo(SelectedPatchDetailItem);
  743. }
  744. private void AddMemo(PatchDetailItem detailItem)
  745. {
  746. if (detailItem == null) return;
  747. EditMemo editMemo = new EditMemo(detailItem.Memo)
  748. {
  749. Owner = Application.Current.MainWindow,
  750. WindowStartupLocation = WindowStartupLocation.CenterOwner
  751. };
  752. if (editMemo.ShowDialog() == true)
  753. {
  754. string memo = editMemo.Memo;
  755. if (DBPatch.UpdatePatchDetailMemo(detailItem.PatchDetailId, memo))
  756. {
  757. detailItem.Memo = memo;
  758. }
  759. }
  760. }
  761. private void Memo_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  762. {
  763. if (e.ClickCount == 2)
  764. {
  765. if (SelectedPatchDetailItem == null) return;
  766. AddMemo(SelectedPatchDetailItem);
  767. }
  768. }
  769. private void FaRun_OnAiRealLogInfo(object sender, AiRealLogEventArgs e)
  770. {
  771. Console.Write(e.mLogInfo);
  772. }
  773. private void MiRecong_Click(object sender, RoutedEventArgs e)
  774. {
  775. if (SelectedPatchDetailItem == null) return;
  776. RecongPatchDetail(SelectedPatchDetailItem);
  777. }
  778. private async void RecongPatchDetail(PatchDetailItem patchDetailItem)
  779. {
  780. string jpgFile = patchDetailItem.SrcImage;
  781. if (!File.Exists(jpgFile))
  782. {
  783. MessageBox.Show(Application.Current.MainWindow, $"文件:{jpgFile}不存在!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
  784. return;
  785. }
  786. bool blRun = await RunAI(patchDetailItem);
  787. if (blRun)
  788. {
  789. //MessageBox.Show(Application.Current.MainWindow, "识别成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
  790. }
  791. else
  792. {
  793. MessageBox.Show(Application.Current.MainWindow, "识别失败!", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  794. }
  795. }
  796. private async Task<bool> RunAI(PatchDetailItem patchDetailItem)
  797. {
  798. FaRun faRun = new FaRun();
  799. faRun.OnAiRealLogInfo += FaRun_OnAiRealLogInfo;
  800. string titleInfo = "正在识别,请稍后...";
  801. WaitWindow waitWindow = new WaitWindow(titleInfo)
  802. {
  803. Owner = Application.Current.MainWindow,
  804. WindowStartupLocation = WindowStartupLocation.CenterOwner
  805. };
  806. waitWindow.Show();
  807. try
  808. {
  809. TPatchDetail newPatchDetail = null;
  810. bool blRun = await Task.Run(() =>
  811. {
  812. try
  813. {
  814. ResultModel resultModel = null;
  815. try
  816. {
  817. resultModel = faRun.StartRecognition(patchDetailItem);
  818. }
  819. catch (Exception ex)
  820. {
  821. Console.WriteLine(ex.Message);
  822. }
  823. if (resultModel == null) return false;
  824. newPatchDetail = new TPatchDetail(patchDetailItem, resultModel);
  825. //更新数据
  826. bool blUpdate = DBPatch.UpdatePatchDetailWithResult(newPatchDetail);
  827. return blUpdate;
  828. }
  829. catch (Exception ex)
  830. {
  831. Application.Current.Dispatcher.Invoke(() =>
  832. {
  833. MessageBox.Show(Application.Current.MainWindow, $"{ex.Message}", "错误",
  834. MessageBoxButton.OK, MessageBoxImage.Error);
  835. });
  836. return false;
  837. }
  838. });
  839. //------
  840. //在主线程中更新DataGrid的Row数据
  841. if (blRun && newPatchDetail != null)
  842. {
  843. ObjectHelper.CopyMatchingFields(newPatchDetail, patchDetailItem);
  844. }
  845. return blRun;
  846. }
  847. catch (Exception ex)
  848. {
  849. MessageBox.Show(Application.Current.MainWindow, $"识别[{patchDetailItem.SrcImage}]时出错:{ex.Message}", "错误",
  850. MessageBoxButton.OK, MessageBoxImage.Error);
  851. return false;
  852. }
  853. finally
  854. {
  855. waitWindow.Close();
  856. }
  857. }
  858. ////-------------以下代码被作废,暂不使用此方法-------------------
  859. //private PatchPrgDialog PatchPrgDialog; // 用于弹出进度对话框
  860. //public event Action<int,int> OnProcessingProgressChanged; // 用于通知进度
  861. //public event Action OnProcessingCompleted; // 用于通知完成
  862. //public event Action OnProcessingStopped; // 用于通知停止
  863. //private BackgroundWorker worker;
  864. ////private bool isProcessing;
  865. //private bool cancelRequested;
  866. //private int TotalImages;
  867. ////开始批量识别任务
  868. //public void StartPatchTask2()
  869. //{
  870. // worker = new BackgroundWorker();
  871. // worker.DoWork += Worker_DoWork;
  872. // worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
  873. // worker.ProgressChanged += Worker_ProgressChanged;
  874. // worker.WorkerReportsProgress = true;
  875. // worker.WorkerSupportsCancellation = true;
  876. // PatchPrgDialog = new PatchPrgDialog(this); // 传递 UserControl 实例给对话框
  877. // PatchPrgDialog.StartProcessing();
  878. //}
  879. //// 启动处理
  880. //public void StartProcessing()
  881. //{
  882. // //isProcessing = true;
  883. // cancelRequested = false;
  884. // worker.RunWorkerAsync();
  885. //}
  886. //// 停止处理
  887. //public void StopProcessing()
  888. //{
  889. // cancelRequested = true;
  890. // worker.CancelAsync();
  891. //}
  892. //// 执行后台处理任务
  893. //private void Worker_DoWork(object sender, DoWorkEventArgs e)
  894. //{
  895. // //int totalImages = 100; // 假设有100张图片要处理
  896. // TotalImages = 100;
  897. // for (int i = 1; i <= TotalImages; i++)
  898. // {
  899. // if (cancelRequested)
  900. // {
  901. // e.Cancel = true;
  902. // break;
  903. // }
  904. // // 模拟处理图片
  905. // Thread.Sleep(1000); // 这里模拟了图片处理的延迟
  906. // // 更新进度
  907. // //worker.ReportProgress((i * 100) / totalImages);
  908. // worker.ReportProgress(i);
  909. // }
  910. //}
  911. //// 更新进度条
  912. //private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
  913. //{
  914. // //progressBar.Value = e.ProgressPercentage;
  915. // OnProcessingProgressChanged?.Invoke(e.ProgressPercentage,TotalImages);
  916. //}
  917. //// 处理完成或被取消
  918. //private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  919. //{
  920. // if (e.Cancelled)
  921. // {
  922. // OnProcessingStopped?.Invoke();
  923. // }
  924. // else
  925. // {
  926. // OnProcessingCompleted?.Invoke();
  927. // }
  928. //}
  929. //-----------------------------------------------------------------------------------
  930. }
  931. // 自定义事件参数类
  932. public class PatchDetailItemChangedEventArgs : EventArgs
  933. {
  934. public PatchDetailItem SelectedPatchDetailItem { get; }
  935. public PatchDetailItemChangedEventArgs(PatchDetailItem selectedData)
  936. {
  937. SelectedPatchDetailItem = selectedData;
  938. }
  939. }
  940. }