MainWindowViewModel.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. using CommunityToolkit.Mvvm.ComponentModel;
  2. using ivf_tl_Entity.Entity;
  3. using ivf_tl_Entity.Entity.balance;
  4. using ivf_tl_Entity.Entity.DownLoad;
  5. using ivf_tl_Entity.Enums;
  6. using ivf_tl_Manage.Converts;
  7. using ivf_tl_Manage.Win;
  8. using ivf_tl_Service;
  9. using ivf_tl_Service.HttpProvider;
  10. using Newtonsoft.Json;
  11. using System;
  12. using System.Collections;
  13. using System.Collections.Concurrent;
  14. using System.Collections.Generic;
  15. using System.Collections.ObjectModel;
  16. using System.Diagnostics;
  17. using System.IO;
  18. using System.Linq;
  19. using System.Security.Policy;
  20. using System.Text;
  21. using System.Threading;
  22. using System.Threading.Channels;
  23. using System.Threading.Tasks;
  24. using System.Windows.Input;
  25. using System.Windows.Media.TextFormatting;
  26. using System.Windows.Threading;
  27. using static System.Windows.Forms.AxHost;
  28. using static System.Windows.Forms.VisualStyles.VisualStyleElement.Tab;
  29. namespace ivf_tl_Manage.ViewModels
  30. {
  31. public partial class MainWindowViewModel : BaseViewModel
  32. {
  33. [ObservableProperty]
  34. private BaseViewModel currentViewModle;
  35. [ObservableProperty]
  36. private bool dishRecordChecked = false;
  37. [ObservableProperty]
  38. private bool alarmHistoryChecked = false;
  39. [ObservableProperty]
  40. private bool houseChartChecked = false;
  41. //[ObservableProperty]
  42. //private int downLoadFileCount = 0;
  43. private int downLoadFileCount;
  44. public int DownLoadFileCount
  45. {
  46. get => Interlocked.CompareExchange(ref downLoadFileCount, 0, 0);
  47. set
  48. {
  49. Interlocked.Exchange(ref downLoadFileCount, value);
  50. OnPropertyChanged(nameof(DownLoadFileCount));
  51. //SetProperty(ref downLoadFileCount, value);
  52. }
  53. }
  54. [ObservableProperty]
  55. private ObservableCollection<EnvironmentTemperatureEntity> environmentTemperatureList = new ObservableCollection<EnvironmentTemperatureEntity>();
  56. public bool IsClick = true;
  57. public string CurrentTlSN = null;
  58. public int ClearLogDay = 5;
  59. public Queue<DownLoadEntity> DownLoadQueue = new Queue<DownLoadEntity>();
  60. [ObservableProperty]
  61. private ObservableCollection<DownLoadEntity> downLoadFileList = new ObservableCollection<DownLoadEntity>();
  62. [ObservableProperty]
  63. private ObservableConcurrentQueue<DownLoadEntity> newdownLoadFileList = new ObservableConcurrentQueue<DownLoadEntity>();
  64. [ObservableProperty]
  65. private List<DownLoadEntity> listdownLoadFileList = new List<DownLoadEntity>();
  66. /// <summary>
  67. /// 设备管理界面ViewModel
  68. /// </summary>
  69. public DevManageViewModel devManageViewModel = null;
  70. /// <summary>
  71. /// 患者管理界面ViewModel
  72. /// </summary>
  73. public PatientManageViewModel patientManageViewModel = null;
  74. [ObservableProperty]
  75. private bool maskVisibility = false;
  76. [ObservableProperty]
  77. private UserInfo userInfo = null;
  78. public MqttHelper MqttHelper { get; set; }
  79. private string MqttIp = "211.149.139.131";
  80. private int MqttPort = 61883;
  81. private string MqttUserName = "aivfo";
  82. private string MqttPassword = "aivfo";
  83. private string MqttClientId = "TL/House/pc";
  84. private string MqttTopicName = "TL/House/pc";
  85. int DownLoadNum = 3;
  86. public MainWindowViewModel(UserInfo userInfo, int downNum)
  87. {
  88. base.ViewModelName = nameof(MainWindowViewModel);
  89. devManageViewModel = new DevManageViewModel();
  90. patientManageViewModel = new PatientManageViewModel();
  91. MqttIp = AppData.Instance.MqttIp;
  92. MqttPort = AppData.Instance.MqttPort;
  93. MqttClientId = $"TL/Surafce/PC/{DateTime.Now}";
  94. MqttHelper = new MqttHelper(MqttIp, MqttPort, MqttUserName, MqttPassword, MqttClientId, MqttTopicName);
  95. MqttHelper.ErrorLogEvent += AppData.Instance.LogService.TLLog;
  96. MqttHelper.ExceptionLogEvent += AppData.Instance.LogService.ExceptionLog;
  97. MqttHelper.MessEvent += MqttHelper_MessEvent;
  98. UserInfo = userInfo;
  99. DownLoadNum = downNum;
  100. _semaphore = new SemaphoreSlim(DownLoadNum );
  101. DownLoadThread();
  102. }
  103. public MainWindowViewModel()
  104. {
  105. base.ViewModelName = nameof(MainWindowViewModel);
  106. }
  107. public void Start()
  108. {
  109. devManageViewModel.UpData();
  110. MqttHelper.StartMqtt();
  111. StartThread();
  112. }
  113. public void RefWindow()
  114. {
  115. devManageViewModel.UpData();
  116. }
  117. private void MqttHelper_MessEvent(string obj)
  118. {
  119. try
  120. {
  121. if (devManageViewModel.TlInfoList == null || !devManageViewModel.TlInfoList.Any()) return;
  122. List<MqttHouse> mqttHouses = JsonConvert.DeserializeObject<List<MqttHouse>>(obj);
  123. if (mqttHouses == null || !mqttHouses.Any()) return;
  124. TLInfo currentTL = devManageViewModel.TlInfoList.FirstOrDefault(x => x.tlSn == mqttHouses.First().tlSn);
  125. if (currentTL == null) return;
  126. MqttHouse mqttHouseItem = null;
  127. foreach (var item in currentTL.houses)
  128. {
  129. mqttHouseItem = mqttHouses.FirstOrDefault(x => x.houseSn == item.houseSn);
  130. if (mqttHouseItem == null) continue;
  131. if (mqttHouseItem.houseSn == 11)
  132. {
  133. string ss = "";
  134. }
  135. else
  136. {
  137. if (mqttHouseItem.cultureState == 0)
  138. {
  139. if (mqttHouseItem.houseState == (int)HouseStateEnum.AirSwapWorking)
  140. {
  141. item.HouseStateString1 = "气体";
  142. item.HouseStateString2 = "交换空闲";
  143. }
  144. else
  145. {
  146. //item.HouseStateString1 = "空闲监测";
  147. item.HouseStateString1 = KeyToStringConvert.GetLanguageStringByKey("0340");
  148. item.HouseStateString2 = "";
  149. }
  150. }
  151. else if (mqttHouseItem.cultureState == 1)
  152. {
  153. if (mqttHouseItem.houseState == (int)HouseStateEnum.AirSwapWorking)
  154. {
  155. //item.HouseStateString1 = "气体交换";
  156. item.HouseStateString1 = KeyToStringConvert.GetLanguageStringByKey("0341");
  157. }
  158. else if (mqttHouseItem.houseState == (int)HouseStateEnum.AutoFocusWorking)
  159. {
  160. //item.HouseStateString1 = "自动对焦";
  161. item.HouseStateString1 = KeyToStringConvert.GetLanguageStringByKey("0342");
  162. }
  163. else if (mqttHouseItem.houseState == (int)HouseStateEnum.CCDWorking)
  164. {
  165. //item.HouseStateString1 = "胚胎拍照";
  166. item.HouseStateString1 = KeyToStringConvert.GetLanguageStringByKey("0343");
  167. }
  168. else
  169. {
  170. //item.HouseStateString1 = "温压监测";
  171. item.HouseStateString1 = KeyToStringConvert.GetLanguageStringByKey("0344");
  172. }
  173. item.HouseStateString2 = "";
  174. }
  175. else if (mqttHouseItem.cultureState == 2)
  176. {
  177. if (mqttHouseItem.houseState == (int)HouseStateEnum.AirSwapWorking)
  178. {
  179. //item.HouseStateString1 = "气体";
  180. //item.HouseStateString2 = "交换平衡";
  181. item.HouseStateString1 = KeyToStringConvert.GetLanguageStringByKey("0536");
  182. item.HouseStateString2 = "";
  183. }
  184. else
  185. {
  186. //item.HouseStateString1 = "温压";
  187. //item.HouseStateString2 = "监测平衡";
  188. item.HouseStateString1 = KeyToStringConvert.GetLanguageStringByKey("0536");
  189. item.HouseStateString2 = "";
  190. }
  191. }
  192. else
  193. {
  194. //item.HouseStateString1 = "未知";
  195. item.HouseStateString1 = KeyToStringConvert.GetLanguageStringByKey("0246");
  196. item.HouseStateString2 = $"{mqttHouseItem.cultureState}";
  197. }
  198. }
  199. item.cultureState = mqttHouseItem.cultureState;
  200. item.houseState = mqttHouseItem.houseState;
  201. item.pressure = mqttHouseItem.pressure;
  202. item.temperature = mqttHouseItem.temperature;
  203. item.houseDoorState = mqttHouseItem.houseDoorState;
  204. item.pressureAlarm = mqttHouseItem.pressureAlarm;
  205. item.temperatureAlarm = mqttHouseItem.temperatureAlarm;
  206. }
  207. }
  208. catch (Exception ex)
  209. {
  210. ExLog(ex, "MqttHelper_MessEvent");
  211. }
  212. }
  213. /// <summary>
  214. /// 开启同步线程
  215. /// </summary>
  216. private void StartThread()
  217. {
  218. Task.Factory.StartNew(async () =>
  219. {
  220. await Task.Delay(5000);
  221. bool isAdd = false;
  222. while (true)
  223. {
  224. try
  225. {
  226. //ThreadPool.GetAvailableThreads(out int worker, out int io);
  227. //Debug.WriteLine($"可用工作线程:{worker}, IO线程:{io}");
  228. RefWindow();
  229. }
  230. catch (Exception ex)
  231. {
  232. ExLog(ex, "UpDataTLInfo");
  233. }
  234. finally
  235. {
  236. await Task.Delay(5000);
  237. }
  238. }
  239. }, TaskCreationOptions.LongRunning);
  240. Task.Factory.StartNew(async () =>
  241. {
  242. List<EnvironmentTemperatureEntity> currentList = new List<EnvironmentTemperatureEntity>();
  243. EnvironmentTemperatureEntity currentT = null;
  244. while (true)
  245. {
  246. try
  247. {
  248. currentList = AppData.Instance.HttpServiceCall.GetEnvironmentTemperatureApi();
  249. //Debug.WriteLine("--------------------------------------------------");
  250. foreach (var item in currentList)
  251. {
  252. currentT = EnvironmentTemperatureList.FirstOrDefault(x => x.tlSn == item.tlSn);
  253. if (currentT == null)
  254. {
  255. AppData.Instance.MainWindow.Dispatcher.Invoke(() =>
  256. {
  257. //Debug.WriteLine($"add {DateTime.Now.ToString("HH:mm:ss.fff")}:{item.collectName}:{item.temperature}");
  258. EnvironmentTemperatureList.Add(item);
  259. });
  260. }
  261. else
  262. {
  263. //Debug.WriteLine($"{currentT.collectName}:{currentT.temperature}");
  264. currentT.temperature = item.temperature;
  265. currentT.collectName = item.collectName;
  266. //if (item.collectName != "9900212203")
  267. //{
  268. // Debug.WriteLine($"{currentT.collectName}:{currentT.temperature}");
  269. //}
  270. }
  271. }
  272. }
  273. catch (Exception ex)
  274. {
  275. ExLog(ex, "GetEnvironmentTemperatureThread");
  276. }
  277. finally
  278. {
  279. await Task.Delay(60000);
  280. }
  281. }
  282. }, TaskCreationOptions.LongRunning);
  283. Task.Factory.StartNew(async () =>
  284. {
  285. string newPath = "";
  286. while (true)
  287. {
  288. try
  289. {
  290. newPath = $"{AppData.Instance.DefeatPan}:\\TLData\\ivf_tl_Manage_logs";
  291. DeleteLogDir(newPath);
  292. newPath = $"{AppData.Instance.DefeatPan}:\\TLData\\ivf_tl_Manage_logs\\Log";
  293. DeleteLogFile(newPath);
  294. newPath = $"{AppData.Instance.DefeatPan}:\\TLData\\ivf_tl_Manage_logs\\LogError";
  295. DeleteLogFile(newPath);
  296. }
  297. catch (Exception ex)
  298. {
  299. ExLog(ex, "DeleteLog");
  300. }
  301. finally
  302. {
  303. await Task.Delay(1000 * 60 * 60 * 12);
  304. }
  305. }
  306. }, TaskCreationOptions.LongRunning);
  307. }
  308. private void DeleteLogDir(string newPath)
  309. {
  310. var newDir = Directory.GetDirectories(newPath, "*", SearchOption.TopDirectoryOnly);
  311. string dirName = "";
  312. DateTime dirTime = DateTime.Now;
  313. DateTime nowTime = dirTime;
  314. foreach (var item in newDir)
  315. {
  316. dirName = System.IO.Path.GetFileName(item);
  317. if (DateTime.TryParse(dirName, out dirTime))
  318. {
  319. if (nowTime.Subtract(dirTime).Days >= ClearLogDay)
  320. {
  321. try
  322. {
  323. Directory.Delete(item, true);
  324. }
  325. catch (Exception)
  326. {
  327. continue;
  328. }
  329. }
  330. }
  331. }
  332. }
  333. private void DeleteLogFile(string newPath)
  334. {
  335. var newDir = Directory.GetFiles(newPath, "*.htm", SearchOption.TopDirectoryOnly);
  336. string fileName = "";
  337. DateTime fileTime = DateTime.Now;
  338. DateTime nowTime = fileTime;
  339. foreach (var item in newDir)
  340. {
  341. fileName = System.IO.Path.GetFileNameWithoutExtension(item);
  342. if (fileName.Length == 8)
  343. {
  344. fileName = fileName.Insert(6, "-");
  345. fileName = fileName.Insert(4, "-");
  346. if (DateTime.TryParse(fileName, out fileTime))
  347. {
  348. if (nowTime.Subtract(fileTime).Days >= ClearLogDay)
  349. {
  350. try
  351. {
  352. File.Delete(item);
  353. }
  354. catch (Exception)
  355. {
  356. continue;
  357. }
  358. }
  359. }
  360. }
  361. }
  362. }
  363. public void DownLoadStart(DownLoadEntity downLoadEntity)
  364. {
  365. try
  366. {
  367. lock (DownLoadQueue)
  368. {
  369. downLoadEntity.state = (int)DownLoadEnum.Await;
  370. //DownLoadQueue.Enqueue(downLoadEntity);
  371. _downloadQueue.Add(downLoadEntity);
  372. if (!DownLoadFileList.Contains(downLoadEntity))
  373. {
  374. DownLoadFileList.Add(downLoadEntity);
  375. }
  376. DownLoadFileCountAdd();
  377. //DownLoadFileCount = DownLoadFileList.Where(x => x.state == (int)DownLoadEnum.Await).Count();
  378. //DownLoadThread();
  379. //if (DownLoadFileCount <= 1) DownLoadThread();
  380. }
  381. return;
  382. }
  383. catch (Exception ex)
  384. {
  385. ExLog(ex, "DownLoadStart");
  386. }
  387. }
  388. private void DownLoadThread()
  389. {
  390. Debug.WriteLine($"创建下载线程开始{DownLoadNum}====================================================");
  391. for (int i = 0; i < DownLoadNum; i++)
  392. {
  393. Task.Factory.StartNew(
  394. () => DownloadWorkerAsync(),
  395. _cts.Token,
  396. TaskCreationOptions.LongRunning,
  397. TaskScheduler.Default
  398. );
  399. }
  400. Debug.WriteLine("创建下载线程结束====================================================");
  401. return;
  402. Debug.WriteLine("开启下载线程");
  403. Task.Run(async () =>
  404. {
  405. DownLoadEntity downLoadEntity = null;
  406. while (true)
  407. {
  408. try
  409. {
  410. lock (DownLoadQueue)
  411. {
  412. if (!DownLoadQueue.Any())
  413. {
  414. Debug.WriteLine("结束下载线程");
  415. return;
  416. }
  417. downLoadEntity = DownLoadQueue.First();
  418. }
  419. if (downLoadEntity == null) return;
  420. int downResult = 0;
  421. downLoadEntity.state = (int)DownLoadEnum.DownLoad;
  422. if (!string.IsNullOrEmpty(downLoadEntity.Body))
  423. {
  424. downResult = await AppData.Instance.HttpServiceCall.DownLoadFileAsync(downLoadEntity.DownLoadUrl, downLoadEntity.NewFileFullName, downLoadEntity.Body).ConfigureAwait(false);
  425. }
  426. else
  427. {
  428. downResult = await AppData.Instance.HttpServiceCall.DownLoadFileAsync(downLoadEntity.DownLoadUrl, downLoadEntity.NewFileFullName).ConfigureAwait(false);
  429. }
  430. if (downResult == 1)
  431. {
  432. AppData.Instance.MainWindow.Dispatcher.Invoke(() =>
  433. {
  434. downLoadEntity.state = (int)DownLoadEnum.Success;
  435. //ToastMessageShow($"{downLoadEntity.FileName} 下载完成");
  436. ToastMessageShow($"{downLoadEntity.FileName} {KeyToStringConvert.GetLanguageStringByKey("0540")}");
  437. });
  438. }
  439. else
  440. {
  441. AppData.Instance.MainWindow.Dispatcher.Invoke(() =>
  442. {
  443. downLoadEntity.state = (int)DownLoadEnum.Failed;
  444. //ToastMessageShow($"{downLoadEntity.FileName} 下载失败");
  445. ToastMessageShow($"{downLoadEntity.FileName} {KeyToStringConvert.GetLanguageStringByKey("0541")}");
  446. });
  447. }
  448. lock (DownLoadQueue)
  449. {
  450. DownLoadQueue.Dequeue();
  451. DownLoadFileCount = DownLoadQueue.Count;
  452. }
  453. }
  454. catch (Exception ex)
  455. {
  456. ExLog(ex, "文件下载");
  457. }
  458. }
  459. });
  460. }
  461. private void DownLoadFileCountAdd()
  462. {
  463. Interlocked.Increment(ref downLoadFileCount);
  464. Debug.WriteLine($"{DateTime.Now}Add当前下载数量{DownLoadFileCount}");
  465. System.Windows.Application.Current.Dispatcher.Invoke(() =>
  466. {
  467. OnPropertyChanged(nameof(DownLoadFileCount));
  468. });
  469. }
  470. private void DownLoadFileCountSub()
  471. {
  472. Interlocked.Decrement(ref downLoadFileCount);
  473. Debug.WriteLine($"{DateTime.Now}Sub当前下载数量{DownLoadFileCount}");
  474. System.Windows.Application.Current.Dispatcher.Invoke(() =>
  475. {
  476. OnPropertyChanged(nameof(DownLoadFileCount));
  477. });
  478. }
  479. public BlockingCollection<DownLoadEntity> _downloadQueue = new BlockingCollection<DownLoadEntity>();
  480. private SemaphoreSlim _semaphore; // N为最大并发数
  481. private CancellationTokenSource _cts = new CancellationTokenSource();
  482. private async Task DownloadWorkerAsync()
  483. {
  484. foreach (var item in _downloadQueue.GetConsumingEnumerable(_cts.Token))
  485. {
  486. Debug.WriteLine($"{DateTime.Now}排队等待数量{_downloadQueue.Count}、{item.FileName}====================================================");
  487. await _semaphore.WaitAsync(_cts.Token);
  488. try
  489. {
  490. await DownloadFileAsync(item);
  491. }
  492. finally
  493. {
  494. _semaphore.Release();
  495. }
  496. Debug.WriteLine($"{DateTime.Now}排队等待数量{_downloadQueue.Count}、{item.FileName}、结束====================================================");
  497. }
  498. }
  499. private async Task DownloadFileAsync(DownLoadEntity downLoadEntity)
  500. {
  501. //await Task.Delay(3000);
  502. //DownloadEndEvent(downLoadEntity, 1);
  503. //return;
  504. if (downLoadEntity == null) return;
  505. int downResult = 0;
  506. downLoadEntity.state = (int)DownLoadEnum.DownLoad;
  507. if (!string.IsNullOrEmpty(downLoadEntity.Body))
  508. {
  509. downResult = await AppData.Instance.HttpServiceCall.DownLoadFileAsync(downLoadEntity.DownLoadUrl, downLoadEntity.NewFileFullName, downLoadEntity.Body).ConfigureAwait(false);
  510. }
  511. else
  512. {
  513. downResult = await AppData.Instance.HttpServiceCall.DownLoadFileAsync(downLoadEntity.DownLoadUrl, downLoadEntity.NewFileFullName).ConfigureAwait(false);
  514. }
  515. DownloadEndEvent(downLoadEntity, downResult);
  516. }
  517. private void DownloadEndEvent(DownLoadEntity downLoadEntity, int result)
  518. {
  519. Task.Run(() =>
  520. {
  521. if (result == 1)
  522. {
  523. AppData.Instance.MainWindow.Dispatcher.Invoke(() =>
  524. {
  525. DownLoadFileCountSub();
  526. downLoadEntity.state = (int)DownLoadEnum.Success;
  527. //ToastMessageShow($"{downLoadEntity.FileName} 下载完成");
  528. ToastMessageShow($"{downLoadEntity.FileName} {KeyToStringConvert.GetLanguageStringByKey("0540")}");
  529. });
  530. }
  531. else
  532. {
  533. AppData.Instance.MainWindow.Dispatcher.Invoke(() =>
  534. {
  535. DownLoadFileCountSub();
  536. downLoadEntity.state = (int)DownLoadEnum.Failed;
  537. //ToastMessageShow($"{downLoadEntity.FileName} 下载失败");
  538. ToastMessageShow($"{downLoadEntity.FileName} {KeyToStringConvert.GetLanguageStringByKey("0541")}");
  539. });
  540. }
  541. });
  542. }
  543. }
  544. }