UCPatchGrid.xaml.cs 46 KB

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