DownloadImageWorker.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. 
  2. using System;
  3. using System.Net.Http;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using Vinno.IUS.Common.Log;
  8. using System.Collections.Generic;
  9. using Vinno.vCloud.Common.Vid2;
  10. using Vinno.IUS.Common.Network.Transfer;
  11. using Vinno.IUS.Common.Network.Leaf;
  12. using Vinno.IUS.Common.Network.Tcp;
  13. using Vinno.vCloud.Protocol.Messages;
  14. using Vinno.vCloud.Protocol.Infrastructures;
  15. using Vinno.vCloud.Protocol.Messages.Client.Account;
  16. using Vinno.vCloud.Protocol.Messages.Client.Remedical.TerminialReords;
  17. using Vinno.vCloud.Protocol.Messages.Client.Remedical.TerminalDatas;
  18. using Vinno.vCloud.Protocol.Messages.Client.AfterSales;
  19. using Vinno.vCloud.Protocol.Messages.Client.AssignTermianl;
  20. using System.Collections.Concurrent;
  21. using System.Threading;
  22. namespace DownloadImagesTool
  23. {
  24. class DownloadArgs
  25. {
  26. public string DownloadPath { get; set; }
  27. public string DownloadUrl { get; set; }
  28. }
  29. class ConvertArgs
  30. {
  31. public string FilePath { get; set; }
  32. }
  33. internal class DownloadImageWorker
  34. {
  35. private ConcurrentQueue<DownloadArgs> _downloadQueue = new ConcurrentQueue<DownloadArgs>();
  36. private SemaphoreSlim _downloadSlim = new SemaphoreSlim(5);
  37. private ConcurrentQueue<ConvertArgs> _convertQueue = new ConcurrentQueue<ConvertArgs>();
  38. private SemaphoreSlim _convertSlim = new SemaphoreSlim(5);
  39. private readonly SpinThread _downloadThread;
  40. private readonly SpinThread _convertThread;
  41. private ClientLeaf _leaf;
  42. private HttpClient _httpClient = new HttpClient();
  43. private string _url = "127.0.0.1:9096";
  44. private string _tempAccoundId;
  45. private string _tempAccoundName;
  46. private Action<string> _setQueue;
  47. public DownloadImageWorker()
  48. {
  49. _downloadThread = new SpinThread("DownloadQueueThread1", TimeSpan.FromMilliseconds(10), RunDownloadVid);
  50. _downloadThread.Start();
  51. _convertThread = new SpinThread("ConvertQueueThread1", TimeSpan.FromMilliseconds(10), RunConvertVid);
  52. _convertThread.Start();
  53. }
  54. private async void RunDownloadVid(object item)
  55. {
  56. if (_downloadSlim.Wait(10))
  57. {
  58. await Task.Run(async () =>
  59. {
  60. try
  61. {
  62. if (_downloadQueue.TryDequeue(out DownloadArgs parms))
  63. {
  64. await DownVid(parms.DownloadUrl.Replace("1!U$", "").Replace("http://cdn-bj.fis.plus", "https://flyinsono-bj-1300984704.cos.ap-beijing.myqcloud.com"), parms.DownloadPath);
  65. _convertQueue.Enqueue(new ConvertArgs { FilePath = parms.DownloadPath });
  66. _setQueue($"Downing Queue:{_downloadQueue.Count}");
  67. }
  68. }
  69. catch (Exception ex)
  70. {
  71. Logger.WriteLineError($"RunDownloadVid error {ex}");
  72. }
  73. finally
  74. {
  75. _downloadSlim.Release();
  76. }
  77. });
  78. }
  79. }
  80. private async void RunConvertVid(object item)
  81. {
  82. if (_convertSlim.Wait(10))
  83. {
  84. await Task.Run(() =>
  85. {
  86. try
  87. {
  88. if (_convertQueue.TryDequeue(out ConvertArgs parms))
  89. {
  90. ConvertImage(parms.FilePath);
  91. }
  92. }
  93. catch (Exception ex)
  94. {
  95. Logger.WriteLineError($"RunConvertVid error {ex}");
  96. }
  97. finally
  98. {
  99. _convertSlim.Release();
  100. }
  101. });
  102. }
  103. }
  104. /// <summary>
  105. /// 根据用户Id下载对应的图像
  106. /// </summary>
  107. /// <param name="UserId">用户Id</param>
  108. public async Task StartDownload(string url, Action<string> writeLog, Action<string> setQueue, params string[] userNames)
  109. {
  110. _url = url;
  111. _setQueue = setQueue;
  112. CreateLeaf();
  113. var vidPath = Path.Combine(Environment.CurrentDirectory, "Vid");
  114. if (!Directory.Exists(vidPath))
  115. {
  116. Directory.CreateDirectory(vidPath);
  117. }
  118. writeLog($"设置了Vid路径:{vidPath}");
  119. var logFile = Path.Combine(Environment.CurrentDirectory, "DownloadFileLog.txt");
  120. if (!File.Exists(logFile))
  121. {
  122. File.Create(logFile);
  123. }
  124. writeLog($"设置了Token记录文件路径:{logFile}");
  125. writeLog("正在查找用户...");
  126. //查找用户
  127. List<string> userIds = new List<string>();
  128. foreach (var name in userNames)
  129. {
  130. using (var request = MessagePool.GetMessage<SearchAccurateUserRequest>())
  131. {
  132. request.Keyword = name;
  133. var resultMessage = _leaf.Send(request);
  134. var result = SearchAccurateUserResult.Convert(resultMessage);
  135. if (result == null)
  136. {
  137. writeLog("查找用户失败,请检查账号");
  138. Logger.WriteLineInfo($"SearchAccurateUserRequest fail");
  139. return;
  140. }
  141. var userInfo = result.Users.FirstOrDefault(f => f.Name.ToLower() == name.ToLower());
  142. if (userInfo != null)
  143. {
  144. userIds.Add(userInfo.Id);
  145. _tempAccoundId = userInfo.Id;
  146. _tempAccoundName = userInfo.Name;
  147. }
  148. }
  149. }
  150. writeLog("正在查找用户超声机...");
  151. //查找用户
  152. List<string> terminalIds = new List<string>();
  153. List<string> organizationNames = new List<string>();
  154. foreach (var userId in userIds)
  155. {
  156. using (var request = MessagePool.GetMessage<FindTerminalsBySalesUserRequest2>())
  157. {
  158. request.UserId = userId;
  159. var resultMessage = _leaf.Send(request);
  160. var result = FindTerminalsBySalesUserResult2.Convert(resultMessage);
  161. if (result == null)
  162. {
  163. writeLog("查找用户失败,请检查账号");
  164. Logger.WriteLineInfo($"SearchAccurateUserRequest fail");
  165. return;
  166. }
  167. var tempTerminalIds = result.EntityMessages?.Select(f => f.Id);
  168. organizationNames = result.EntityMessages?.Select(f => f.OrganizationDescription).ToList();
  169. if (tempTerminalIds != null)
  170. {
  171. terminalIds.AddRange(tempTerminalIds);
  172. }
  173. }
  174. }
  175. writeLog("正在查找用户组织...");
  176. //查找用户
  177. List<string> organizationIds = new List<string>();
  178. foreach (var name in organizationNames)
  179. {
  180. using (var request = MessagePool.GetMessage<FindOrganizationByKeyWordRequest>())
  181. {
  182. request.KeyWord = name;
  183. var resultMessage = _leaf.Send(request);
  184. var result = FindOrganizationInfosResult.Convert(resultMessage);
  185. if (result == null)
  186. {
  187. writeLog("查找用户失败,请检查账号");
  188. Logger.WriteLineInfo($"SearchAccurateUserRequest fail");
  189. return;
  190. }
  191. var tempOrganizationIds = result.OrganizationInfos.Select(f => f.OrganizationId);
  192. if (tempOrganizationIds != null)
  193. {
  194. organizationIds.AddRange(tempOrganizationIds);
  195. }
  196. }
  197. }
  198. writeLog($"userIds:{userIds.Count}\n获取所有检查记录...");
  199. //获取所有检查记录
  200. List<string> terminlalRecords = new List<string>();
  201. foreach (var userId in userIds)
  202. {
  203. using (var request = MessagePool.GetMessage<GetRecordsRequest>())
  204. {
  205. request.Filter = new RecordFilterMessage();
  206. request.Filter.StartDateTime = DateTime.MinValue;
  207. request.Filter.EndDateTime = DateTime.Now;
  208. request.Filter.FilterType = RecordFilterType.All;
  209. request.Filter.OrganizationIds = organizationIds;
  210. request.Filter.TerminalIds = terminalIds;
  211. request.PageIndex = 0;
  212. request.PageSize = 9000000;
  213. //SetAccountDataToMessage(request, _tempAccoundId, _tempAccoundName);
  214. request.UserId = userId;
  215. var resultMessage = _leaf.Send(request, 100000);
  216. var result = GetRecordsSuccess.Convert(resultMessage);
  217. if (result == null)
  218. {
  219. writeLog("获取所有检查数据失败,请检查账号");
  220. Logger.WriteLineInfo($"GetRecordsRequest fail");
  221. return;
  222. }
  223. var records = result.TerminalRecords.Select(f => f.Id).ToList();
  224. if (records != null && records.Count > 0)
  225. {
  226. terminlalRecords.AddRange(records);
  227. }
  228. }
  229. }
  230. writeLog($"terminlalRecords:{terminlalRecords.Count}\n获取所有检查数据...");
  231. //获取所有检查数据
  232. List<string> imageUrls = new List<string>();
  233. var directories = Directory.GetDirectories(vidPath);
  234. //foreach(var dir in directories)
  235. foreach (var recordId in terminlalRecords)
  236. {
  237. try
  238. {
  239. var savePath = Path.Combine(vidPath, recordId);
  240. var fPan = Path.Combine("F:\\DataGet\\Vid", recordId);
  241. if (Directory.Exists(fPan))
  242. {
  243. savePath = fPan;
  244. }
  245. if (!Directory.Exists(savePath) || Directory.GetFiles(savePath).Length == 0)
  246. {
  247. using (var request = MessagePool.GetMessage<GetRecordDatasRequest>())
  248. {
  249. request.TerminalRecordId = recordId;
  250. var resultMessage = _leaf.Send(request, 1000000);
  251. var result = GetRecordDatasSuccess.Convert(resultMessage);
  252. if (result == null)
  253. {
  254. continue;
  255. }
  256. var recordDatas = result.Datas.Select(f =>
  257. {
  258. var fileData = f.Files.FirstOrDefault(f => f.ImageQuality == 0);
  259. return (recordId, fileData?.FileName);
  260. }).ToList();
  261. if (recordDatas != null && recordDatas.Count > 0)
  262. {
  263. foreach (var imageInfo in recordDatas)
  264. {
  265. if (string.IsNullOrWhiteSpace(imageInfo.FileName))
  266. {
  267. continue;
  268. }
  269. var filePath = Path.Combine(savePath, Path.GetFileName(imageInfo.FileName));
  270. if (!File.Exists(filePath))
  271. {
  272. _downloadQueue.Enqueue(new DownloadArgs { DownloadUrl = imageInfo.FileName.Replace("1!U$", ""), DownloadPath = filePath });
  273. Logger.WriteLineInfo($"Download file token {imageInfo.FileName}");
  274. imageUrls.Add($"Token:{imageInfo.FileName}");
  275. }
  276. }
  277. }
  278. }
  279. }
  280. else
  281. {
  282. var files = Directory.GetFiles(savePath, "*.dat");
  283. foreach (var file in files)
  284. {
  285. if (File.Exists(file.Replace(".dat", ".jpeg")) || File.Exists(file.Replace(".dat", ".mp4")))
  286. {
  287. File.Delete(file);
  288. continue;
  289. }
  290. _convertQueue.Enqueue(new ConvertArgs { FilePath = file });
  291. }
  292. }
  293. }
  294. catch
  295. {
  296. File.AppendAllLines(logFile, imageUrls);
  297. imageUrls.Clear();
  298. continue;
  299. }
  300. }
  301. File.AppendAllLines(logFile, imageUrls);
  302. await Task.CompletedTask;
  303. }
  304. private async Task DownVid(string url, string filePath, int times = 0)
  305. {
  306. try
  307. {
  308. if (File.Exists(filePath)){
  309. return;
  310. }
  311. var parentDir = Directory.GetParent(filePath).FullName;
  312. if (!Directory.Exists(parentDir))
  313. {
  314. Directory.CreateDirectory(parentDir);
  315. }
  316. using (var webStream = await _httpClient.GetStreamAsync(url))
  317. {
  318. using (var fileStream = File.Create(filePath))
  319. {
  320. var readLength = 0;
  321. byte[] bytes = new byte[10240];
  322. do
  323. {
  324. readLength = webStream.Read(bytes, 0, bytes.Length);
  325. if (readLength != 0)
  326. {
  327. if (readLength == bytes.Length)
  328. {
  329. fileStream.Write(bytes);
  330. }
  331. else
  332. {
  333. fileStream.Write(bytes.Take(readLength).ToArray());
  334. }
  335. }
  336. }
  337. while (readLength != 0);
  338. fileStream.Flush();
  339. }
  340. }
  341. }
  342. catch (Exception ex)
  343. {
  344. if (times < 3)
  345. {
  346. times++;
  347. await DownVid(url, filePath, times);
  348. }
  349. }
  350. }
  351. private void ConvertImage(string vidFile)
  352. {
  353. try
  354. {
  355. var vinnoImageData = new VinnoImageData(vidFile, OperationMode.Open);
  356. if (vinnoImageData.ImageCount > 1)
  357. {
  358. var destFile = vidFile.Replace(".dat", ".mp4");
  359. if (!File.Exists(destFile))
  360. {
  361. Mpeg4Converter.ConvertVidToMpeg4(vinnoImageData, destFile);
  362. }
  363. return;
  364. }
  365. else
  366. {
  367. var destFile = vidFile.Replace(".dat", ".jpeg");
  368. File.WriteAllBytes(destFile, vinnoImageData.GetImage(0)?.ImageData);
  369. return;
  370. }
  371. }
  372. catch (Exception ex)
  373. {
  374. Logger.WriteLineError($"Convert fail! {ex}");
  375. return;
  376. }
  377. }
  378. /// <summary>
  379. /// Create a leaf to connect to the server.
  380. /// </summary>
  381. private void CreateLeaf()
  382. {
  383. if (_leaf != null)
  384. {
  385. _leaf.Close();
  386. }
  387. _leaf = new ClientLeaf(new LeafIdContext(), LeafMode.Dual, new TcpCreator(_url), "Terminal upgrade:");
  388. if (!_leaf.Online)
  389. {
  390. _leaf.Close();
  391. }
  392. else
  393. {
  394. _leaf.RegisterSetAccountDataMessageFunc(SetAccountDataToMessage);
  395. }
  396. }
  397. private void CloseLeaf()
  398. {
  399. _leaf?.Close();
  400. }
  401. private Message SetAccountDataToMessage(Message message)
  402. {
  403. if (message is ClientRequestMessage clientRequestMessage)
  404. {
  405. clientRequestMessage.AccountData = GetAccountDataMessage() as ClientAccountMessage;
  406. return clientRequestMessage;
  407. }
  408. return message;
  409. }
  410. private Message SetAccountDataToMessage(Message message, string accoundId, string accoundName)
  411. {
  412. if (message is ClientRequestMessage clientRequestMessage)
  413. {
  414. clientRequestMessage.AccountData = new ClientAccountMessage
  415. {
  416. AccountId = accoundId,
  417. AccountName = accoundName
  418. };
  419. return clientRequestMessage;
  420. }
  421. return message;
  422. }
  423. private Message GetAccountDataMessage()
  424. {
  425. var accountData = MessagePool.GetMessage<ClientAccountMessage>();
  426. accountData.AccountId = "TerminalUpgradeId";
  427. accountData.AccountName = "TerminalUpgrade";
  428. accountData.Source = LoginSource.UltrasoundMachine;
  429. return accountData;
  430. }
  431. }
  432. }