using Avalonia.Controls; using fis.Helpers; using fis.Log; using fis.Managers.Interfaces; using fis.Utilities; using fis.Utilities.Entities; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Threading; using System.Threading.Tasks; using fis.Utilities.FFMPEG; using FFMpegWrapper; namespace fis.Managers { public enum ExportStatus { Downloading, Packaging, Finished } internal class FileExporterManager : IFileExporterManager { private int _fileCount = 0; private string _destnationName; private string _downloadFolder; private CancellationTokenSource _cancelTokenSource; private CancellationToken _cancelToken; private int _fileFinishCount = 0; private ExportStatus _exportStatus; public bool IsCancelled => _cancelToken.IsCancellationRequested; public ExportStatus ExportStatus { get { return _exportStatus; } set { _exportStatus = value; var progress = Math.Round((double)_fileFinishCount / (double)_fileCount, 2); if (_exportStatus == ExportStatus.Packaging) { NotifyTheProgress(progress, _exportStatus); DoPackaging(); return; } if (_exportStatus == ExportStatus.Finished) { progress = 1; } NotifyTheProgress(progress, _exportStatus); } } private void NotifyTheProgress(double progress, ExportStatus exportStatus) { var callString = PlatFormHelper.GetMethodStr(BrowserManager.NotificationName, TargetMethodName.UpdateExportProgess, new List() { progress.ToString(), ((int)exportStatus).ToString() }); BrowserManager.MainBrowser.ExecuteJavaScript(callString, null, 0); } private void DoPackaging() { FFmpegService.ForceCloseFFmpegIfStillAlive(); ZipFile.CreateFromDirectory(_downloadFolder, _destnationName); ExportStatus = ExportStatus.Finished; DeleteTheTemps(_downloadFolder); } public void Dispose() { throw new NotImplementedException(); } public bool AbortExportOperation() { _cancelTokenSource?.Cancel(); _fileFinishCount = 0; ExportStatus = ExportStatus.Downloading; Task.Run(() => { Thread.Sleep(500); DeleteTheTemps(_downloadFolder); } ); return true; } public bool ExportPatientZipFile(string data, string fileName) { var dataObj = JsonConvert.DeserializeObject(data); var accessFileCount = dataObj.CountTheDownLoadDataItem(); _fileCount = accessFileCount; fileName = String.Join("+",dataObj.SubFolders.ToArray())+DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"); _destnationName =Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),fileName+".zip"); _downloadFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,fileName); if (!Directory.Exists(_downloadFolder)) { Directory.CreateDirectory(_downloadFolder); } Task.Run(() => { try { DoExport(dataObj); } finally { } }); return true; } private void DoExport(ExportRemedicalZipFileInfo exportRemedicalZipFileInfo) { var subFolders = exportRemedicalZipFileInfo.SubFolders; _cancelTokenSource = new CancellationTokenSource(); _cancelToken = _cancelTokenSource.Token; _fileFinishCount = 0; ExportStatus = ExportStatus.Downloading; //下载报告 Task.Run(async () => { if (exportRemedicalZipFileInfo.ExportItems.Contains(0)) { var reportPath = exportRemedicalZipFileInfo.ExportItems.Count>1? Path.Combine(_downloadFolder, exportRemedicalZipFileInfo.SubFolders[0]):_downloadFolder; if (!Directory.Exists(reportPath)) { Directory.CreateDirectory(reportPath); } var reports = exportRemedicalZipFileInfo.ReportList; foreach (var c in reports) { var patientPath = Path.Combine(reportPath, c.PatientName); if (!Directory.Exists(patientPath)) { patientPath = patientPath.Replace("*", ""); Directory.CreateDirectory(patientPath); if (c.ReportItemList.Count == 0) { var fileName = Path.Combine(patientPath, "nodata.txt"); File.WriteAllText(fileName, "nodata"); return; } } foreach (var d in c.ReportItemList) { if (_cancelToken.IsCancellationRequested) { break; } var bytes = await HttpHelper.httpClient.GetByteArrayAsync(d.FileToken, _cancelToken); var fileName = Path.Combine(patientPath, GetFileNameFromToken(d.FileToken)); try { await File.WriteAllBytesAsync(fileName, bytes); } catch(Exception ex) { Logger.WriteShellLog(ex.ToString()); } finally { _fileFinishCount++; } } } } }); //下载图像 Task.Run(async () => { if (exportRemedicalZipFileInfo.ExportItems.Contains(2)) { var imagePath = exportRemedicalZipFileInfo.ExportItems.Count > 1 ? Path.Combine(_downloadFolder, exportRemedicalZipFileInfo.SubFolders[1]) :_downloadFolder; if (!Directory.Exists(imagePath)) { Directory.CreateDirectory(imagePath); } var remedicalData = exportRemedicalZipFileInfo.RemedicalList; foreach (var c in remedicalData) { var patientPath = Path.Combine(imagePath, c.PatientName); if (!Directory.Exists(patientPath)) { patientPath = patientPath.Replace("*", ""); Directory.CreateDirectory(patientPath); if (c.RemedicalItemList.Count == 0) { var fileName = Path.Combine(patientPath, "nodata.txt"); File.WriteAllText(fileName, "nodata"); return; } } foreach (var d in c.RemedicalItemList) { if (_cancelToken.IsCancellationRequested) { break; } var bytes = await HttpHelper.httpClient.GetByteArrayAsync(d.FileToken, _cancelToken); var fileName = Path.Combine(patientPath, GetFileNameFromToken(d.FileToken)); try { await File.WriteAllBytesAsync(fileName, bytes); var pathDest = Path.Combine(patientPath, GetFileNameWithoutExt(d.FileToken)); var converter = new VideoFFmpegHelper(fileName); converter.ConvertVidToMpeg4(pathDest); converter.Dispose(); File.Delete(fileName); } catch (Exception ex) { Logger.WriteShellLog(ex.ToString()); } finally { _fileFinishCount++; } } } } }); //刷新进度条 Task.Run(() => { if (_fileCount > 0) { while (ExportStatus != ExportStatus.Finished) { Thread.Sleep(1000); ExportStatus = _fileFinishCount == _fileCount ? ExportStatus.Packaging : ExportStatus.Downloading; } } else { Thread.Sleep(2000); ExportStatus = ExportStatus.Packaging; } }); } private string GetFileNameFromToken(string fileToken) { string[] fragments = fileToken.Split('/'); string lastFragment = fragments.Last(); return lastFragment; } private string GetFileNameWithoutExt(string fileToken) { string[] fragments = fileToken.Split('/'); string lastFragment = fragments.Last(); return lastFragment.Split('.')[0]; } public bool SetBytesToExport(string fileBinary, string fileName) { try{ var file = Convert.FromBase64String(fileBinary); if (file.Length > 0) {//转换后pdf存放的路径 ExportToNative(fileName,file); return true; } else { return false; } return true; } catch (Exception) { return false; } } private void DeleteTheTemps(String folder) { try { if (!Directory.Exists(folder)) { return; } var files = Directory.GetFiles(folder); foreach (var c in files) { File.Delete(c); } var directorys = Directory.GetDirectories(folder); foreach (var d in directorys) { DeleteTheTemps(d); } if (Directory.GetFiles(folder).Length <= 0 && Directory.GetDirectories(folder).Length <= 0) { Directory.Delete(folder); } } catch(Exception ex) { FFmpegService.ForceCloseFFmpegIfStillAlive(); DeleteTheTemps(_downloadFolder); } } private void ExportToNative(string fileName, byte[] file) { Task.Run(async () => { var filePath = await SaveFile(fileName); if (string.IsNullOrEmpty(filePath)) { return; } var writer = new BinaryWriter(File.Open(filePath, FileMode.CreateNew)); writer.Write(file); writer.Close(); }); } private async Task SaveFile(string fileName) { //用户自由选择指定路径保存文件 var savedialog = new SaveFileDialog(); savedialog.Title = ""; savedialog.InitialFileName = fileName; var fileExportedPath = await savedialog.ShowAsync(AppManager.ParentWindow); if (string.IsNullOrEmpty(fileExportedPath)) { return AppDomain.CurrentDomain.BaseDirectory; } return fileExportedPath; } } }