using Microsoft.Win32;
using StationProbe;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace TestViewer
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow
{
private readonly Database? _db;
private DateTime _startDate = new(2023, 1, 1);
private DateTime _endDate = DateTime.Now;
private int _pageIndex = -1;
private int _pageCount;
private string _partKey = string.Empty;
private string _conclusionKey = string.Empty;
public MainWindow()
{
InitializeComponent();
CreateStart.SelectedDate = _startDate;
CreateStart.DisplayDate = _startDate;
CreateEnd.SelectedDate = _endDate;
CreateEnd.DisplayDate = _endDate;
CreateStart.SelectedDateChanged += (_, _) => { _startDate = CreateStart.SelectedDate.Value.Date; };
CreateEnd.SelectedDateChanged += (_, _) => { _endDate = CreateEnd.SelectedDate.Value.Date.AddDays(1); };
Loading.LoadingChanged += OnLoadingChanged;
var fileDialog = new OpenFileDialog
{
Title = "Open database file",
Filter = "*.db|*.db"
};
if (fileDialog.ShowDialog() == true)
{
_db = new Database(fileDialog.FileName);
PageIndex.Text = $"{_pageIndex + 1}/{_pageCount}";
var batchTasks = _db.GetBatchTasks();
foreach (var task in batchTasks)
{
BatchTaskList.Items.Add(task);
}
BatchTaskList.SelectionChanged += OnBatchTaskSelectionChanged;
ExamList.SelectionChanged += OnExamSelectionChanged;
}
else
{
Application.Current.Shutdown(0);
}
}
private void OnLoadingChanged(object? sender, bool e)
{
if (e)
{
Dispatcher.Invoke(() => { LoadingMask.Visibility = Visibility.Visible; });
}
else
{
Dispatcher.Invoke(() => { LoadingMask.Visibility = Visibility.Collapsed; });
}
}
private void OnBatchTaskSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (BatchTaskList.SelectedValue is BatchTask batchTask)
{
Loading.Run(() =>
{
_pageIndex = 0;
_pageCount = _db!.GetPageCount(batchTask.Id, _partKey, _conclusionKey,_startDate, _endDate);
var exams = _db.GetExams(batchTask.Id, _pageIndex, _partKey, _conclusionKey, _startDate, _endDate);
Dispatcher.Invoke(() =>
{
foreach (var exam in exams)
{
ExamList.Items.Add(exam);
}
PageIndex.Text = $"{_pageIndex + 1}/{_pageCount}";
});
});
}
}
private void OnExamSelectionChanged(object sender, SelectionChangedEventArgs e)
{
ExamScrollView.ScrollToHome();
ExamContent.Children.Clear();
if (ExamList.SelectedValue is Exam exam)
{
Dictionary? reportContent;
try
{
reportContent = JsonSerializer.Deserialize>(exam.Report);
}
catch
{
reportContent = null;
}
if (reportContent != null)
{
var partStackPanel = new StackPanel() { Margin = new Thickness(16), Orientation = Orientation.Horizontal };
partStackPanel.Children.Add(new TextBlock()
{
VerticalAlignment = VerticalAlignment.Center,
Text = "部位: ",
FontWeight = FontWeights.Bold,
FontSize = 16,
});
partStackPanel.Children.Add(new TextBlock()
{
VerticalAlignment = VerticalAlignment.Center,
Text = $"{reportContent["Part"]}",
FontSize = 16,
});
ExamContent.Children.Add(partStackPanel);
var deviceStackPanel = new StackPanel() { Margin = new Thickness(16), Orientation = Orientation.Horizontal };
deviceStackPanel.Children.Add(new TextBlock()
{
VerticalAlignment = VerticalAlignment.Center,
Text = "设备: ",
FontWeight = FontWeights.Bold,
FontSize = 16,
});
deviceStackPanel.Children.Add(new TextBlock()
{
VerticalAlignment = VerticalAlignment.Center,
Text = $"{reportContent["Device"]}",
FontSize = 16,
});
ExamContent.Children.Add(deviceStackPanel);
var conclusionStackPanel = new StackPanel() { Margin = new Thickness(16), Orientation = Orientation.Horizontal };
conclusionStackPanel.Children.Add(new TextBlock()
{
VerticalAlignment = VerticalAlignment.Center,
Text = "结论: ",
FontWeight = FontWeights.Bold,
FontSize = 16,
});
var conclusion = "无结论";
if (!string.IsNullOrEmpty(reportContent["Conclusion"]))
{
conclusion = reportContent["Conclusion"];
}
conclusionStackPanel.Children.Add(new TextBlock()
{
VerticalAlignment = VerticalAlignment.Center,
Text = conclusion,
FontSize = 16,
});
ExamContent.Children.Add(conclusionStackPanel);
ExamContent.Children.Add(new Border() { Height = 1, Width = 2000, BorderBrush = Brushes.Gray, Background = Brushes.Gray });
ExamContent.Children.Add(new TextBlock()
{
Width = 2000,
Margin = new Thickness(16, 16, 16, 8),
Text = "超声所见:",
FontSize = 16,
FontWeight = FontWeights.Bold,
});
ExamContent.Children.Add(new TextBlock()
{
Margin = new Thickness(16, 8, 16, 16),
Text = reportContent["Summary"].Replace(@"\n", Environment.NewLine),
FontSize = 16,
TextWrapping = TextWrapping.Wrap,
});
ExamContent.Children.Add(new TextBlock()
{
Width = 2000,
Margin = new Thickness(16, 16, 16, 8),
Text = "超声提示:",
FontSize = 16,
FontWeight = FontWeights.Bold,
});
ExamContent.Children.Add(new TextBlock()
{
Margin = new Thickness(16, 8, 16, 16),
Text = reportContent["Comment"].Replace(@"\n", Environment.NewLine),
FontSize = 16,
TextWrapping = TextWrapping.Wrap,
});
}
else
{
ExamContent.Children.Add(new TextBlock()
{
Margin = new Thickness(16),
Text = exam.Report,
FontSize = 20,
TextWrapping = TextWrapping.Wrap,
});
}
ExamContent.Children.Add(new Border() { Height = 1, Width = 2000, BorderBrush = Brushes.Gray, Background = Brushes.Gray });
var images = _db!.GetImages(exam.Id);
foreach (var image in images)
{
var img = new BitmapImage();
img.BeginInit();
img.StreamSource = new MemoryStream(image.Data);
img.EndInit();
var imageBorder = new Border
{
Margin = new Thickness(16),
Width = 200,
Height = 200,
Background = Brushes.Black,
Child = new System.Windows.Controls.Image()
{
Source = img
},
Cursor = Cursors.Hand
};
imageBorder.MouseDown += (_, _) =>
{
var viewImageWindow = new Window
{
Owner = this,
Background = Brushes.Black,
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
var width = img.Width + 16;
var height = img.Height + 16;
if (width >= SystemParameters.PrimaryScreenWidth || height >= SystemParameters.PrimaryScreenHeight)
{
viewImageWindow.WindowState = WindowState.Maximized;
}
else
{
viewImageWindow.Width = width;
viewImageWindow.Height = height;
}
viewImageWindow.Content = new System.Windows.Controls.Image()
{
Source = img
};
viewImageWindow.ShowDialog();
};
ExamContent.Children.Add(imageBorder);
}
}
}
private void OnNextPageClick(object sender, RoutedEventArgs e)
{
if (_pageIndex < _pageCount - 1)
{
if (BatchTaskList.SelectedValue is BatchTask batchTask)
{
ExamList.Items.Clear();
_pageIndex++;
Loading.Run(() =>
{
var exams = _db!.GetExams(batchTask.Id, _pageIndex, _partKey, _conclusionKey,_startDate, _endDate);
Dispatcher.Invoke(() =>
{
foreach (var exam in exams)
{
ExamList.Items.Add(exam);
}
PageIndex.Text = $"{_pageIndex + 1}/{_pageCount}";
});
});
}
}
}
private void OnPreviousPageClick(object sender, RoutedEventArgs e)
{
if (_pageIndex > 0)
{
if (BatchTaskList.SelectedValue is BatchTask batchTask)
{
ExamList.Items.Clear();
_pageIndex--;
Loading.Run(() =>
{
var exams = _db!.GetExams(batchTask.Id, _pageIndex, _partKey, _conclusionKey, _startDate, _endDate);
Dispatcher.Invoke(() =>
{
foreach (var exam in exams)
{
ExamList.Items.Add(exam);
}
PageIndex.Text = $"{_pageIndex + 1}/{_pageCount}";
});
});
}
}
}
private void OnSearchClick(object sender, RoutedEventArgs e)
{
_partKey = PartKey.Text;
_conclusionKey = ConclusionKey.Text;
if (BatchTaskList.SelectedValue is BatchTask batchTask)
{
ExamList.Items.Clear();
Exam[]? exams;
Loading.Run(() =>
{
_pageCount = _db!.GetPageCount(batchTask.Id, _partKey, _conclusionKey, _startDate, _endDate);
_pageIndex = 0;
exams = _db.GetExams(batchTask.Id, _pageIndex, _partKey, _conclusionKey,_startDate, _endDate);
Dispatcher.Invoke(() =>
{
foreach (var exam in exams)
{
ExamList.Items.Add(exam);
}
PageIndex.Text = $"{_pageIndex + 1}/{_pageCount}";
});
});
}
}
private void OnExportClick(object sender, RoutedEventArgs e)
{
var partKey = PartKey.Text;
var conclusionKey = ConclusionKey.Text;
if (BatchTaskList.SelectedValue is BatchTask batchTask)
{
FolderBrowserEx.FolderBrowserDialog dialog = new FolderBrowserEx.FolderBrowserDialog();
var result = dialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
var targetFolder = dialog.SelectedFolder;
var imageFolder = Path.Combine(targetFolder, "images");
if (!Directory.Exists(imageFolder))
{
Directory.CreateDirectory(imageFolder);
}
var reportFolder = Path.Combine(targetFolder, "reports");
if (!Directory.Exists(reportFolder))
{
Directory.CreateDirectory(reportFolder);
}
var progressWindow = new Window
{
Title = "导出中...",
WindowStartupLocation = WindowStartupLocation.CenterOwner,
WindowStyle = WindowStyle.ToolWindow,
ResizeMode = ResizeMode.NoResize,
Width = 320,
Height = 80,
Owner = this
};
var canClose = false;
progressWindow.Closing += (_, arg) => { arg.Cancel = !canClose; };
var progressBar = new ProgressBar
{
Minimum = 0,
Maximum = 100,
Value = 0
};
progressWindow.Content = progressBar;
Task.Run(() =>
{
JsonSerializerOptions opts = new JsonSerializerOptions
{
WriteIndented = true,
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
};
var pageCount = _db!.GetPageCount(batchTask.Id, partKey, conclusionKey,_startDate, _endDate);
if (pageCount > 0)
{
for (int i = 0; i < pageCount; i++)
{
var exams = _db.GetExams(batchTask.Id, i, partKey, conclusionKey,_startDate, _endDate);
foreach (var exam in exams)
{
var images = _db.GetImages(exam.Id);
foreach (var image in images)
{
var fileName = Path.Combine(imageFolder, $"{exam.Id}_{image.Id}.jpg");
File.WriteAllBytes(fileName, image.Data);
}
var reportDic = new Dictionary
{
{ "PatientName", exam.PatientName },
{ "PatientSex", exam.PatientSex },
{ "PatientAge", exam.PatientAge },
{ "ExamDate", exam.ExamDate }
};
Dictionary? reportContent;
try
{
reportContent = JsonSerializer.Deserialize>(exam.Report);
}
catch
{
reportContent = null;
}
if (reportContent != null)
{
reportDic.Add("Report", reportContent);
}
else
{
reportDic.Add("Report", exam.Report);
}
var reportFile = Path.Combine(reportFolder, $"{exam.Id}.txt");
File.WriteAllText(reportFile, JsonSerializer.Serialize(reportDic, opts));
}
var progress = (i + 1) / (double)pageCount * 100;
Dispatcher.Invoke(() =>
{
progressWindow.Title = $"导出中...{(int)progress}%";
progressBar.Value = progress;
});
}
canClose = true;
Dispatcher.Invoke(progressWindow.Close);
}
});
progressWindow.ShowDialog();
}
}
}
}
}