体检系统架构
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

2267 lines
85 KiB

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Printing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraPrinting.Native;
using DevExpress.XtraTab;
using PEIS.Base;
using PEIS.Entity;
using PEIS.Event;
using PEIS.Model.Exam;
using PEIS.Presenter;
using PEIS.Utils;
using PEIS.View.UControl;
using static PEIS.Utils.ColorHelper;
using static PEIS.Utils.Global;
#region
/*
* 命名规则:小驼峰
* 缩写前缀:
* lbl:Label标签控件
* txt:TextBox文本框控件
* btn:Button按钮控件
* chk:CheckBox复选框控件
* rdo:RadioButton单选框控件
* lst:ListBox列表框控件
* cmb:ComboBox下拉框控件
* dgv:DataGridView数据表格控件
* pn1:Panel面板控件
* grp:GroupBox分组框控件
* pic:PictureBox图像控件
* img:ImageList图像列表控件
* scb:VScrollBar或HScrollBar滚动条控件
* trk:TrackBar滑动条控件
* prb:ProgressBar进度条控件
* tab:TabControl标签页控件
* mn1:MenuStrip菜单栏控件
* tbr:ToolStrip工具栏控件
* sta:StatusStrip状态栏控件
*/
#endregion
namespace PEIS.View.Exam
{
public partial class PartForm : ViewBase, IPartView
{
// 定义一个委托
public delegate void SelectedPatientDelegate(long? eid);
// 声明一个事件,供父窗体订阅
public event SelectedPatientDelegate SelectedPatientEvent;
// 医技科室-自动保存并生成小结结论
private bool IsAutoSaveSummary = false;
// PACS图片最大选择项数
private const int MaxSelectionCount = 3;
private readonly string _watermarkTeam = @"团检号或团队名称";
private readonly string _watermarkInfo = @"体检号或体检者姓名";
private User _currentDept;
private ImageList _pacsImgList;
private HistoryView historyView;
#region 基础方法
/// <summary>
/// 0.创建Presenter
/// </summary>
/// <returns></returns>
protected override object CreatePresenter()
{
return new PartPresenter(this);
}
/// <summary>
/// 页面初始化 事件绑定
/// </summary>
public PartForm()
{
InitializeComponent();
//页面显示
Shown += PartForm_Shown;
dgvDept.CustomDrawCell += DgvDept_CustomDrawCell;
dgvDept.RowCellClick += DgvDept_RowCellClick;
//体检者登记信息列表
dgvPatients.CustomDrawCell += DgvPatient_CustomDrawCell;
dgvPatients.RowClick += DgvEnrollmentPatient_RowClick;
//行号
DgvExamResult.CustomDrawRowIndicator += (sender, e) =>
{
if (e.RowHandle >= 0)
e.Info.DisplayText = (e.RowHandle + 1).ToString();
};
Common.Dgv_Initialize(dgvPatients);
Common.Dgv_Initialize(DgvLisReport);
Common.Dgv_Initialize(DgvRptPacs);
Common.Dgv_Initialize(DgvRptExt);
//RadioButtonClick
rdoStatus1.Click += RadioButton_Click;
// rdoStatus2.Click += RadioButton_Click;
// rdoStatus3.Click += RadioButton_Click;
rdoStatus4.Click += RadioButton_Click;
btnRefresh.Click += (s, e) => { OnGetPatients(); };
// 菜单-重新提取检查结果
tsmiPick.Click += TsmiPick_Click;
//菜单-保存
tsmiSave.Click += TsmiSave_Click;
//菜单-生成小结结论
tsmiConclusion.Click += TsmiConclusion_Click;
//菜单-审核
tsmiReview.Click += TsmiReview_Click;
//菜单-取消审核
tsmiCancel.Click += TsmiReviewCancel_Click;
//菜单-收费项目
menuGiveUp1.Click += MenuGiveUp1_Click;
//菜单-科室取消弃检
menuGiveUp2.Click += MenuGiveUp2_Click;
//菜单-科室弃检
menuGiveUp3.Click += MenuGiveUp3_Click;
//菜单-科室取消弃检
menuGiveUp4.Click += MenuGiveUp4_Click;
//隐藏刷新
opsConclusion.TsmiRefresh.Visible = false;
//结论-添加
opsConclusion.TsmiAdd.Click += ConclusionAdd_Click;
//结论-删除
opsConclusion.TsmiDelete.Click += ConclusionDelete_Click;
//结论-保存
opsConclusion.TsmiSave.Click += ConclusionSave_Click;
CmbSearchConclusion.DisplayMember = "ConclusionName"; // 替换为您的显示字段名
CmbSearchConclusion.ValueMember = "ConclusionName"; // 替换为您的值字段名
CmbSearchConclusion.DataSource = _lstConclusion;
CmbSearchConclusion.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;
CmbSearchConclusion.CloseUp += CmbSearchConclusion_CloseUp;
//切换Tab页加载数据
TabPart.SelectedPageChanged += TabPart_SelectedPageChanged;
//1.1.1.检查结果列表-加载单元格为输入框/选择框
DgvExamResult.CustomRowCellEdit += DgvExamResult_CustomRowCellEdit;
//1.1.2.检查结果列表-焦点列改变
DgvExamResult.FocusedColumnChanged += DgvExamResult_FocusedColumnChanged;
//1.1.3.检查结果列表-焦点行改变
DgvExamResult.FocusedRowChanged += DgvExamResult_FocusedRowChanged;
//1.1.4.检查结果列表-单元格值修改
DgvExamResult.CellValueChanged += DgvExamResult_CellValueChanged;
//1.1.5 按下回车-跳转下一行
DgvExamResult.KeyUp += DgvExamResult_KeyUp;
//1.2.1.PACS
DgvRptPacs.RowClick += DgvReportPacs_RowClick;
//1.2.2.PACS图片选择列表-限制选中项数
ListViewPacsImg.ItemCheck += ListViewPacsImg_ItemCheck;
//1.2.3.单击选中
ListViewPacsImg.MouseDown += ListViewPacsImg_ItemClick;
//1.2.4.菜单
OpsPacsImg.TsmiRefresh.Visible = false;
OpsPacsImg.TsmiAdd.Text = @"选择图片";
OpsPacsImg.TsmiDelete.Text = @"取消";
OpsPacsImg.TsmiAdd.Click += PacsTsmiAdd_Click;
OpsPacsImg.TsmiDelete.Click += PacsTsmiCancel_Click;
OpsPacsImg.TsmiSave.Click += PacsTsmiSave_Click;
//1.3.1.其他报告
DgvRptExt.RowClick += (o, e) =>
{
if (DgvRptExt.GetFocusedRow() is ReportExt selected) SetPicReportExt(selected);
};
//分科检查 颜色提示
DgvDeptExamResult.CustomDrawCell += DgvExamResult_CustomDrawCell;
DgvLisReport.CustomDrawCell += DgvLisReport_CustomDrawCell;
// Combobox医师切换
cmbInputer.SelectedIndexChanged += ComboInputer_SelectedIndexChanged;
cmbChecker.SelectedIndexChanged += ComboChecker_SelectedIndexChanged;
cmbVerifier.SelectedIndexChanged += ComboVerifier_SelectedIndexChanged;
popupContainerEdit1.Popup += Properties_Popup;
popupContainerEdit1.CloseUp += Properties_CloseUp;
// 回车查询
txtTeam.KeyDown += (s, e) =>
{
if (e.KeyCode == Keys.Enter) OnGetPatients();
};
txtPatient.KeyDown += (s, e) =>
{
if (e.KeyCode == Keys.Enter) OnGetPatients();
};
// pacs报告打印
PrintPacs.Click += PrintPacs_Click;
}
#region 【part01】.体检者列表
/// <summary>
/// 【part01】.获取体检者列表
/// </summary>
public event EventHandler<Args<string>> GetPatients;
public event EventHandler<Args<object>> GetPatientInfo;
/// <summary>
/// 【part01】 获取体检者列表
/// </summary>
private void OnGetPatients()
{
if (dateEditBeg?.Value == null || dateEditEnd?.Value == null ||
!DateTime.TryParse(dateEditBeg.Value.ToString(CultureInfo.InvariantCulture), out var _) ||
!DateTime.TryParse(dateEditEnd.Value.ToString(CultureInfo.InvariantCulture), out var _))
return;
var dateType = cmbDate?.SelectedItem as QueryDateType;
if ((txtTeam.Text != _watermarkTeam || txtPatient.Text != _watermarkInfo)
&& dateEditBeg.Value.Date == DateTime.Now.AddDays(-3).Date &&
dateEditEnd.Value.Date == DateTime.Now.Date)
{
dateEditBeg.Value = DateTime.Now.AddDays(-15);
}
// 1日期类型、2开始日期、3结束日期、4体检团队、5个人信息
GetPatients?.Invoke(this, new Args<string>()
{
Items = new List<string>()
{
dateType?.Code,
$"{Convert.ToDateTime(dateEditBeg.Value):yyyy-MM-dd}",
$"{Convert.ToDateTime(dateEditEnd.Value).AddDays(1):yyyy-MM-dd}",
txtTeam.Text == _watermarkTeam ? "" : txtTeam.Text,
txtPatient.Text == _watermarkInfo ? "" : txtPatient.Text,
}
});
}
/// <summary>
/// 【part01】.查询体检者列表-已发送未打印
/// 刷新列表,修改当前体检者为列表[0]
/// ShowPatients(PartModel.GetPatients)
/// </summary>
/// <param name="items"></param>
public void ShowPatients(List<EnrollmentPatient> items)
{
_patientList = items;
dgcPatients.Invoke(() =>
{
dgcPatients.DataSource = null;
dgcPatients.DataSource = _patientList;
dgvPatients.BestFitColumns();
});
this.Invoke(() => rdoStatus1.Checked = false);
// this.Invoke(() => rdoStatus2.Checked = false);
// this.Invoke(() => rdoStatus3.Checked = false);
this.Invoke(() => rdoStatus4.Checked = true);
if (_patient.ID <= 0 || items.All(p => p.ID != _patient.ID)) return;
GetPatientInfo?.Invoke(this, new Args<object>()
{
ID = _patient.ID,
});
RefreshExamStatus();
OnGetExamPart();
}
/// <summary>
/// 【part01】.根据体检状态筛选体检者列表-科室分检/总检/报告
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RadioButton_Click(object sender, EventArgs e)
{
var dataSource = _patientList;
if (rdoStatus4.Checked)
{
dataSource = _patientList.ToList();
}
// else if (rdoStatus3.Checked)
// {
// dataSource = _patientList.Where(p => p.Status == "打印").ToList();
// }
// else if (rdoStatus2.Checked)
// {
// dataSource = _patientList.Where(p => p.Status == "总检").ToList();
// }
else if (rdoStatus1.Checked)
{
dataSource = _patientList.Where(p => p.Status == "科室分检")
.ToList();
}
Invoke(new Action(() => dgcPatients.DataSource = null));
Invoke(new Action(() => dgcPatients.DataSource = dataSource));
}
#endregion
#region 【part02】.科室列表
/// <summary>
/// 【part02】.科室列表
/// </summary>
private void OnGetDeptList()
{
if (_patient.ID > 0)
{
GetDeptList?.Invoke(this, new Args<string>()
{
ID = _patient.ID,
});
}
else
{
ShowDeptList(Global._lstAllDept);
}
}
/// <summary>
/// 【part02】体检科室列表-当前体检者有效时获取对应科室-默认显示全部科室
/// </summary>
public event EventHandler<Args<string>> GetDeptList;
/// <summary>
/// 【part02】显示科室列表状态
/// </summary>
/// <param name="items"></param>
public void ShowDeptList(List<User> items)
{
// items.ForEach(i =>
// {
// i.IsSelected=false;
// });
var index = dgvDept.GetFocusedDataSourceRowIndex();
if (index < 0 || index >= items.Count)
{
index = 0;
}
if (string.IsNullOrEmpty(items[index].Status))
{
items[index].IsSelected = false;
index = items.FindIndex(p => !string.IsNullOrEmpty(p.Status));
}
index = index == -1 ? 0 : index;
items[index].IsSelected = true;
_currentDept = items[index];
dgcDept.Invoke(() =>
{
dgcDept.DataSource = null;
dgcDept.DataSource = items;
dgvDept.UnselectRow(index);
dgvDept.FocusedRowHandle = index;
dgvDept.SelectRow(index);
});
SelectedDept(_currentDept);
}
/// <summary>
/// 【part02】自定义绘制单元格
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvDept_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e)
{
var gridView = (GridView)sender;
if (e.RowHandle < 0 || e.Column == null) return;
var rowData = gridView.GetRow(e.RowHandle) as User;
switch (rowData?.Status)
{
case "科室分检":
e.Appearance.ForeColor = Color.Black;
e.Appearance.BackColor = ColorTranslator.FromHtml("#26c6da");//BackInfo;//Color.White;00dcb4
break;
case "总检":
e.Appearance.ForeColor = ForeMain;
e.Appearance.BackColor = BackMain;
break;
case "打印":
e.Appearance.ForeColor = ForeSuccess;
e.Appearance.BackColor = BackSuccess;
break;
case "弃检":
e.Appearance.ForeColor = ForeWarning;
e.Appearance.BackColor = BackWarning;
break;
default:
e.Appearance.ForeColor = Color.Gray;//ForeInfo;
e.Appearance.BackColor = Color.White; //BackInfo;
break;
}
}
/// <summary>
/// 单击行单元格
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvDept_RowCellClick(object sender, RowCellClickEventArgs e)
{
var rowHandle = e.RowHandle;
dgvDept.SetRowCellValue(rowHandle, colDeptSelected, true);
//ResetView();
// 取消其他行的选中状态
for (var i = 0; i < dgvDept.RowCount; i++)
{
if (i != rowHandle)
{
dgvDept.SetRowCellValue(i, colDeptSelected, false);
}
}
// 查询数据
if (!(dgvDept.GetFocusedRow() is User dept)) return;
SelectedDept(dept);
}
/// <summary>
/// 选中科室
/// </summary>
/// <param name="dept"></param>
private void SelectedDept(User dept)
{
_currentDept = dept;
_patient.DeptCode = dept.DeptCode;
_currentDept.DeptName = dept.DeptName;
stripLblDept.Text = _currentDept.DeptName;
//ShowPatients(new List<EnrollmentPatient>());
if (_patient?.ID > 0)
{
OnGetExamPart();
//OnGetPatients();
// 选中检查科室提取结果按钮显示
if (_currentDept.DeptCode == "3201" || _currentDept.DeptCode == "3203" || _currentDept.DeptCode == "3204" || _currentDept.DeptCode == "3101")
{
tsmiPick.Visible = true;
}
else
{
tsmiPick.Visible = false;
}
}
// else
// {
// Global.MsgInfo("请选中体检者!");
// }
}
#endregion
private void Properties_Popup(object sender, EventArgs e)
{
if (!(DgvExamResult.GetFocusedRow() is ExamResult examResult)) return;
var data = Global._lstSign.Where(p => p.RID == examResult.RID).ToList();
if (data.Count == 0) return;
dgcSign.SetDataSource(data);
for (var i = 0; i < data.Count; i++)
{
if (_examResultList.Any(p => p.SID == data[i].ID))
{
dgvSign.SelectRow(i);
}
}
}
private void Properties_CloseUp(object sender, EventArgs e)
{
// 调用 CloseEditor 方法来关闭单元格的编辑器并使单元格失去焦点
dgvSign.CloseEditor();
// 将焦点设置到其他控件,使 DataGrid 控件的单元格失去焦点
DgvExamResult.Focus();
if (!(DgvExamResult.GetFocusedRow() is ExamResult examResult)) return;
var rows = this.dgvSign.GetSelectedRows(); //先获取选择行的行号
_examResultList.RemoveAll(p => p.RID == examResult.RID);
if (rows.Length == 0)
{
_examResultList.Add(new ExamResult()
{
FID = examResult.FID,
FeeItemName = examResult.FeeItemName,
IsSelection = examResult.IsSelection,
ItemClass = examResult.ItemClass,
PID = examResult.PID,
RID = examResult.RID,
RptItemName = examResult.RptItemName,
SeqReport = examResult.SeqReport,
TextResult = "",
});
}
var data = Global._lstSign.Where(p => p.RID == examResult.RID).ToList();
rows.ForEach(i =>
{
var sign = data[i]; //dgvSign.GetRow(i) as Sign;//获取行 ;
_examResultList.Add(new ExamResult()
{
FID = examResult.FID,
FeeItemName = examResult.FeeItemName,
IsSelection = examResult.IsSelection,
ItemClass = examResult.ItemClass,
PID = examResult.PID,
RID = examResult.RID,
RptItemName = examResult.RptItemName,
SeqReport = examResult.SeqReport,
SID = sign?.ID,
SeqSign = sign?.Seq,
TextResult = sign?.SignName,
});
});
ShowExamResultList();
}
/// <summary>
/// 只要窗体是首次显示就发生
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PartForm_Shown(object sender, EventArgs e)
{
Debug.WriteLine("PartForm_Shown");
OnGetDeptList();
//赋值
//查询日期
dateEditBeg.Value = DateTime.Now.AddDays(-3);
dateEditEnd.Value = DateTime.Now;
//科室分检状态
stripLblStatus.Text = @"未审核";
stripLblStatus.BackColor = BackInfo;
stripLblStatus.ForeColor = ForeInfo;
//查询条件初始化
cmbDate.DataSource = new QueryDateType().List();
cmbDate.DisplayMember = "Name";
cmbDate.ValueMember = "Code";
txtTeam.WatermarkText = _watermarkTeam;
txtTeam.Text = _watermarkTeam;
txtPatient.WatermarkText = _watermarkInfo;
txtPatient.Text = _watermarkInfo;
OnGetPatients();
}
#endregion
#region 体检者列表
/// <summary>
/// 体检者列表
/// </summary>
private List<EnrollmentPatient> _patientList = new List<EnrollmentPatient>();
/// <summary>
/// 当前选中体检者
/// </summary>
private EnrollmentPatient _patient = new EnrollmentPatient();
/// <summary>
/// 体检者列表单击
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvEnrollmentPatient_RowClick(object sender, EventArgs e)
{
if (dgvPatients.GetFocusedRow() is EnrollmentPatient selected)
{
GetPatientInfo?.Invoke(this, new Args<object>()
{
ID = selected.ID,
});
RefreshExamStatus();
OnGetExamPart();
}
else
{
_patient = new EnrollmentPatient();
}
}
#endregion
#region 科室分检信息
public void OnGetExamPart()
{
IsAutoSaveSummary = false;
if (string.IsNullOrEmpty(_currentDept.DeptCode) || _patient.ID == 0)
{
ShowExamPart(new ExamPart());
return;
}
GetExamPart?.Invoke(this, new Args<object>()
{
ID = _patient.ID,
Code = _currentDept.DeptCode,
});
GetDoctorList?.Invoke(this, new Args<object>()
{
Code = _currentDept?.DeptCode,
});
SelectedPatientEvent?.Invoke(_patient?.ID);
}
#endregion
#region 属性
/// <summary>
/// 当前科室分检信息
/// </summary>
private ExamPart _examPart = new ExamPart();
/// <summary>
/// 当前科室体检者科室分检结果
/// </summary>
private static List<ExamResult> _examResultList = new List<ExamResult>();
/// <summary>
/// 录入医师列表
/// </summary>
private List<User> _inputerList = new List<User>();
/// <summary>
/// 检查医师列表
/// </summary>
private List<User> _checkerList = new List<User>();
/// <summary>
/// 审核医师列表
/// </summary>
private List<User> _verifierList = new List<User>();
/// <summary>
/// 结论
/// </summary>
private List<ExamConclusion> _conclusion = new List<ExamConclusion>();
/// <summary>
/// 检验报告结果
/// </summary>
private List<ExamResult> _lisReport = new List<ExamResult>();
/// <summary>
/// 检查报告选中图片ID
/// </summary>
private List<string> _pacsSelectedImgId = new List<string>();
#endregion 属性
private void CmbSearchConclusion_CloseUp(object sender, DevExpress.XtraEditors.Controls.CloseUpEventArgs e)
{
if (e.AcceptValue)
{
SearchLookUpEdit editor = sender as SearchLookUpEdit;
if (editor != null)
{
// 获取选中的行数据
var rowData = editor.Properties.View.GetFocusedRow() as Conclusion;
if (rowData != null)
{
var conclusion = DgvConclusion.GetFocusedRow() as ExamConclusion;
if (rowData == null || conclusion == null) return;
var index = _conclusion.IndexOf(conclusion);
_conclusion[index].Conclusion = rowData.ConclusionName;
_conclusion[index].Suggestion = rowData.Suggestion;
ShowConclusion(_conclusion);
}
}
}
//
// var rowData = _lstConclusion.FirstOrDefault(p => p.ConclusionName == e.Value?.ToString());
// var conclusion = DgvConclusion.GetFocusedRow() as ExamConclusion;
// if (rowData == null || conclusion == null) return;
// var index = _conclusion.IndexOf(conclusion);
// _conclusion[index].Conclusion = rowData.ConclusionName;
// _conclusion[index].Suggestion = rowData.Suggestion;
// ShowConclusion(_conclusion);
}
#region IView事件实现
/// <summary>
/// 3.获取当前科室体检者 科室分检信息
/// </summary>
public event EventHandler<Args<object>> GetExamPart;
/// <summary>
/// 4.获取科室医师列表
/// </summary>
public event EventHandler<Args<object>> GetDoctorList;
public void ShowDoctorList(List<List<User>> items)
{
Invoke(new Action(() =>
{
_inputerList = items[0];
_checkerList = items[1];
_verifierList = items[2];
}));
RefreshDoctorList();
}
public void RefreshDoctorList()
{
var part = _examPart;
//cmbInputer
{
var user = new User()
{
Code = part.InputerCode,
Name = part.Inputer,
};
var list = new List<User>();
list.AddRange(_inputerList);
if (!_inputerList.Contains(user))
{
list.Add(user);
}
Invoke(new Action(() =>
{
cmbInputer.DataSource = null;
cmbInputer.DataSource = list;
cmbInputer.DisplayMember = "Name";
cmbInputer.SelectedItem = user;
cmbInputer.SelectedItem = !string.IsNullOrEmpty(part.Inputer) ? user : Global.currentUser;
}));
}
//cmbChecker
{
var user = new User()
{
Code = part.CheckerCode,
Name = part.Checker,
};
Invoke(new Action(() =>
{
var list = new List<User>();
list.AddRange(_checkerList);
if (!_checkerList.Contains(user))
{
list.Add(user);
}
cmbChecker.DataSource = null;
cmbChecker.DataSource = list;
cmbChecker.DisplayMember = "Name";
cmbChecker.SelectedItem = user;
}));
cmbChecker.SelectedItem = !string.IsNullOrEmpty(part.Checker) ? user : Global.currentUser;
}
//cmbVerifier
// if (!string.IsNullOrEmpty(part.Verifier))
{
var user = new User()
{
Code = part.VerifyCode,
Name = part.Verifier,
};
Invoke(new Action(() =>
{
var list = new List<User>();
list.AddRange(_verifierList);
if (!_verifierList.Contains(user))
{
list.Add(user);
}
cmbVerifier.DataSource = null;
cmbVerifier.DataSource = list;
cmbVerifier.DisplayMember = "Name";
cmbVerifier.SelectedItem = !string.IsNullOrEmpty(part.Verifier) ? user : Global.currentUser;
}));
}
cmbInputer.Enabled = string.IsNullOrEmpty(part.Verifier);
cmbChecker.Enabled = string.IsNullOrEmpty(part.Verifier);
cmbVerifier.Enabled = string.IsNullOrEmpty(part.Verifier);
// else
// {
// cmbVerifier.SelectedItem = Global.currentUser;
// }
}
/// <summary>
/// 5.获取科室分检结果列表
/// </summary>
public event EventHandler<Args<bool>> GetExamResultList;
/// <summary>
/// 显示检查结果列表
/// </summary>
/// <param name="items"></param>
/// <param name="topRowIndex"></param>
public void ShowExamResultList(List<ExamResult> items = null, int topRowIndex = 0)
{
if (items != null)
{
var items1 = items;
Invoke(new Action(() => _examResultList = items1));
}
items = _examResultList.OrderBy(o => o.SeqReport).ThenBy(t => t.SeqSign).Distinct().ToList();
var isHeight = items.All(p => p.ItemClass == "检查") && items.Any(p => p.TextResult?.Length > 30);
DgvExamResult.RowHeight = items.Any(p => p.TextResult?.Length > 200) ? 250 : isHeight ? 90 : 35;
DgvExamResult.OptionsView.RowAutoHeight = true;
var data = new List<ExamResult>();
foreach (var item in items.GroupBy(g => g.RID))
{
var first = item.FirstOrDefault();
if (item.Count() > 1 && first?.RID != null)
{
data.Add(new ExamResult()
{
FID = first.FID,
FeeItemName = first.FeeItemName,
IsSelection = first.IsSelection,
ItemClass = first.ItemClass,
PID = first.PID,
RID = first.RID,
RptItemName = first.RptItemName,
SeqReport = first.SeqReport,
TextResult = string.Join(",", item.Select(s => s.TextResult).Distinct().ToList())
});
continue;
}
data.AddRange(item);
}
dgcExamResult.SetDataSource(data);
Invoke(new Action(() => DgvExamResult.ExpandAllGroups()));
//恢复滚动位置
Invoke(new Action(() => DgvExamResult.TopRowIndex = topRowIndex));
// 检验检查心电科室Code
var deptCodeList = new List<string>()
{
"3001", //检验科
"3002", //金域检验
"3201", //放射科
"3202", //超声科
};
if (deptCodeList.Contains(_currentDept.DeptCode) && _examPart.VerifyTime == null &&
_examPart.GiveUpTime == null && _examPart.ID == 0)
{
IsAutoSaveSummary = true;
}
//检验/检查科室 自动保存
if (false) // IsAutoSaveSummary // 停用自动保存
{
// 检验/检查科室,未审核且未弃检,自动保存结果,自动生成小结和结论
if (_patient.ID <= 0 || _patient.FinishTime != null || _examPart.VerifyTime != null ||
_examPart.GiveUpTime != null) return;
var time = DateTime.Now;
_examPart.InputTime = time;
_examPart.Inputer = currentUser.Name;
_examPart.InputerCode = currentUser.Code;
_examPart.CheckTime = time;
_examPart.Checker = currentUser.Name;
_examPart.CheckerCode = currentUser.Code;
_examPart.CreateTime = _examPart.CreateTime ?? time;
_examPart.Summary = txtSummary.Text;
SaveExamPart?.Invoke(this, new Args<ExamResult>()
{
Part = _examPart,
Items = _examResultList
});
}
// 获取结论
if (_examPart?.ID > 0)
GetConclusion?.Invoke(this, new Args<object>(_examPart.ID));
}
/// <summary>
/// 7.保存科室分检信息
/// </summary>
public event EventHandler<Args<ExamResult>> SaveExamPart;
public void ShowSaveExamPart(bool succeed)
{
if (dgvPatients.GetFocusedRow() is EnrollmentPatient selected)
{
if (IsAutoSaveSummary)
{
SetConclusion?.Invoke(this, new Args<ExamConclusion>()
{
ID = _patient.ID,
Code = _currentDept.DeptCode,
//Items = _selectedSign
});
}
GetPatientInfo?.Invoke(this, new Args<object>()
{
ID = selected.ID,
});
RefreshExamStatus();
OnGetExamPart();
}
else
{
_patient = new EnrollmentPatient();
}
}
/// <summary>
/// 8.生成小结/结论
/// </summary>
public event EventHandler<Args<object>> GetConclusion;
public event EventHandler<Args<ExamConclusion>> SetConclusion;
public void ShowSetConclusion(bool succeed)
{
OnGetExamPart();
}
public event EventHandler<Args<ExamConclusion>> SaveConclusion;
public void ShowConclusion(List<ExamConclusion> items)
{
_conclusion = items;
Invoke(new Action(() => dgcConclusion.DataSource = null));
Invoke(new Action(() => dgcConclusion.DataSource = _conclusion));
}
public void ShowSaveConclusion(bool succeed)
{
OnGetExamPart();
}
/// <summary>
/// 9.审核
/// 时间为NULL则审核
/// </summary>
public event EventHandler<Args<DateTime?>> Review;
public void ShowReview(bool succeed)
{
OnGetExamPart();
}
/// <summary>
/// 10.弃检
/// 时间为NULL则取消弃检
/// </summary>
public event EventHandler<Args<DateTime?>> GiveUp;
public void ShowGiveUp(bool succeed)
{
OnGetExamPart();
}
/// <summary>
/// 收费项目弃检
/// </summary>
public event EventHandler<Args<DateTime?>> GiveUpFeeItem;
public void ShowGiveUpFeeItem(bool succeed)
{
OnGetExamPart();
}
/// <summary>
/// 11.获取科室分检结果列表
/// </summary>
public event EventHandler<Args<object>> GetLisReport;
public void ShowLisReport(List<ExamResult> items)
{
_lisReport = items;
Invoke(new Action(() => dgcLisReport.DataSource = null));
Invoke(new Action(() => dgcLisReport.DataSource = _lisReport));
//Invoke(new Action(() => DgvLisReport.ExpandAllGroups()));
}
/// <summary>
/// 获取第三方报告
/// </summary>
public event EventHandler<Args<object>> GetReportExtList;
public void ShowReportExtList(List<ReportExt> items)
{
Invoke(new Action(() => picReportExt.Image = null));
Invoke(new Action(() => dgcRptExt.DataSource = null));
if (items.Count == 0) return;
Invoke(new Action(() => dgcRptExt.DataSource = items));
Invoke(new Action(() => DgvRptExt.BestFitColumns()));
Invoke(new Action(() => picReportExt.Image = null));
SetPicReportExt(items[0]);
}
private void SetPicReportExt(ReportExt item)
{
Invoke(new Action(() => picReportExt.Image = null));
if (item.ReportImg == null) return;
try
{
if (item.Class == "十二通道心电图检查")
{
var img = ReportHelper.PdfToImg(item.ReportImg);
if (img != null)
{
var newImg = ReportHelper.RotateImage(img);
Invoke(new Action(() => { picReportExt.Image = newImg; }));
}
return;
}
Invoke(new Action(() =>
{
using (var ms = new MemoryStream(item.ReportImg, 0, item.ReportImg.Length))
{
Invoke(new Action(() =>
{
var img = Image.FromStream(ms, true);
picReportExt.Image = img;
}));
}
}));
}
catch (Exception e)
{
Global.MsgErr(e.Message);
}
}
#endregion IView事件实现
#region 页面控件事件
/// <summary>
/// 体检者列表-自定义绘制单元格
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvPatient_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e)
{
if (e.Column.Caption != @"状态")
{
return;
}
var gridView = (GridView)sender;
if (e.RowHandle < 0 || e.Column == null) return;
// 获取当前单元格所在行的数据
var rowData = gridView.GetRow(e.RowHandle) as EnrollmentPatient;
switch (rowData?.Status)
{
case "总检":
e.Appearance.ForeColor = ForeMain;
e.Appearance.BackColor = BackMain;
break;
case "报告":
e.Appearance.ForeColor = ForeSuccess;
e.Appearance.BackColor = BackSuccess;
break;
case "打印":
e.Appearance.ForeColor = ForeSuccess;
e.Appearance.BackColor = BackSuccess;
break;
case "已弃检":
e.Appearance.ForeColor = ForeWarning;
e.Appearance.BackColor = BackWarning;
break;
}
}
/// <summary>
/// 重新提取检查结果
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TsmiPick_Click(object sender, EventArgs e)
{
if (_patient.ID <= 0 || _patient.FinishTime != null || _examPart.VerifyTime != null || _examPart.GiveUpTime != null) return;
DAOHelp.ExecuteSql($@"DELETE FROM Report WHERE ID IN (
SELECT a.ID
FROM Report a
LEFT JOIN Enrollment_FeeItem b ON (a.ReportNo = b.ID OR a.ReportNo = b.OldId)
WHERE a.EID = {_patient.ID} AND b.DeptCode = '{_examPart.DeptCode}')");
DAOHelp.ExecuteSql($@"EXEC sp_PacsRptInsert {_patient.ID}");
}
/// <summary>
/// 保存科室分检
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TsmiSave_Click(object sender, EventArgs e)
{
Debug.WriteLine("TsmiSave_Click");
//未失去焦点时数据绑定未刷新需要收到修改焦点
// 调用 CloseEditor 方法来关闭单元格的编辑器并使单元格失去焦点
DgvExamResult.CloseEditor();
// 将焦点设置到其他控件,使 DataGrid 控件的单元格失去焦点
opsConclusion.Focus();
if (_patient.ID <= 0)
{
MessageBox.Show(@"请刷新后重试!", @"保存失败");
return;
}
if (_patient.ID <= 0 || _patient.FinishTime != null || _examPart.VerifyTime != null ||
_examPart.GiveUpTime != null) return;
var result = MessageBox.Show(@"是否保存当前检查结果?", @"保存", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
var time = DateTime.Now;
_examPart.InputTime = time;
_examPart.Inputer = currentUser.Name;
_examPart.InputerCode = currentUser.Code;
_examPart.CheckTime = _examPart.CheckTime ?? time;
_examPart.Checker = string.IsNullOrEmpty(_examPart.Checker) ? currentUser.Name : _examPart.Checker;
_examPart.CheckerCode = string.IsNullOrEmpty(_examPart.CheckerCode) ? currentUser.Code : _examPart.CheckerCode;
_examPart.CreateTime = _examPart.CreateTime ?? time;
_examPart.Summary = txtSummary.Text;
SaveExamPart?.Invoke(this, new Args<ExamResult>()
{
Part = _examPart,
Items = _examResultList
});
}
/// <summary>
/// 生成小结/结论
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TsmiConclusion_Click(object sender, EventArgs e)
{
if (_examPart.ID <= 0 || _patient.ID <= 0)
{
MessageBox.Show(@"请保存后重试!", @"生成结论失败");
return;
}
if (_patient.ID <= 0 || _patient.FinishTime != null || _examPart.VerifyTime != null ||
_examPart.GiveUpTime != null) return;
var result = MessageBox.Show(@"将覆盖现有小结或结论,是否继续?", @"生成小结或结论确认", MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
SetConclusion?.Invoke(this, new Args<ExamConclusion>()
{
ID = _patient.ID,
Code = _currentDept.DeptCode,
//Items = _selectedSign
});
}
/// <summary>
/// 审核
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TsmiReview_Click(object sender, EventArgs e)
{
if (_patient.ID <= 0 || _patient.FinishTime != null || _examPart.VerifyTime != null ||
_examPart.GiveUpTime != null || _examPart.ID <= 0) return;
var result = MessageBox.Show(@"是否确认审核?", @"审核", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
Review?.Invoke(this, new Args<DateTime?>
{
ID = _examPart.ID,
Code = currentUser.Code,
Name = currentUser.Name,
Item = DateTime.Now
});
}
/// <summary>
/// 取消审核
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TsmiReviewCancel_Click(object sender, EventArgs e)
{
if (_patient.ID <= 0 || _patient.FinishTime != null || _examPart.VerifyTime == null ||
_examPart.GiveUpTime != null || _examPart.ID <= 0) return;
var result = MessageBox.Show(@"是否取消审核?", @"审核", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
Review?.Invoke(this, new Args<DateTime?>
{
ID = _examPart.ID,
Code = currentUser.Code,
Name = currentUser.Name
});
}
/// <summary>
/// 弃检-收费项目
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MenuGiveUp1_Click(object sender, EventArgs e)
{
if (!(DgvExamResult.GetFocusedRow() is ExamResult examResult)) return;
var result = MessageBox.Show($@"是否弃检:{examResult.FeeItemName}?", @"弃检收费项目", MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
if (_patient.ID <= 0
|| _patient.FinishTime != null
|| _examPart.VerifyTime != null
|| _examPart.GiveUpTime != null
|| _examPart.ID <= 0) return;
var fid = examResult.FID ?? 0;
var eid = _examPart.EID ?? 0;
GiveUpFeeItem?.Invoke(this, new Args<DateTime?>
{
ID = fid,
DeptCode = _examPart.DeptCode,
Eid = eid,
Code = currentUser.Code,
Name = currentUser.Name,
Item = DateTime.Now
});
}
/// <summary>
/// 取消弃检-收费项目
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MenuGiveUp2_Click(object sender, EventArgs e)
{
if (!(DgvExamResult.GetFocusedRow() is ExamResult examResult)) return;
var result = MessageBox.Show($@"是否取消弃检:{examResult.FeeItemName}?", @"取消弃检收费项目", MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
if (_patient.ID <= 0 || _patient.FinishTime != null || _examPart.VerifyTime != null ||
_examPart.GiveUpTime != null || _examPart.ID <= 0 || examResult.GiveUpTime == null)
return;
var fid = examResult.FID ?? 0;
var eid = _examPart.EID ?? 0;
GiveUpFeeItem?.Invoke(this, new Args<DateTime?>
{
ID = fid,
DeptCode = _examPart.DeptCode,
Eid = eid,
Code = currentUser.Code,
Name = currentUser.Name,
Item = null
});
}
/// <summary>
/// 弃检
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MenuGiveUp3_Click(object sender, EventArgs e)
{
var result = MessageBox.Show(@"是否弃检当前科室所有项目?", @"科室弃检", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
if (_patient.ID <= 0 || _patient.FinishTime != null || _examPart.VerifyTime != null ||
_examPart.GiveUpTime != null || _examPart.ID <= 0) return;
GiveUp?.Invoke(this, new Args<DateTime?>
{
ID = _examPart.ID,
Code = currentUser.Code,
Name = currentUser.Name,
Item = DateTime.Now
});
}
/// <summary>
/// 取消弃检
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MenuGiveUp4_Click(object sender, EventArgs e)
{
var result = MessageBox.Show(@"是否取消弃检?", @"科室弃检", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
if (_patient.ID <= 0 || _patient.FinishTime != null || _examPart.VerifyTime != null ||
_examPart.GiveUpTime == null || _examPart.ID <= 0) return;
GiveUp?.Invoke(this, new Args<DateTime?>
{
ID = _examPart.ID,
Code = currentUser.Code,
Name = currentUser.Name
});
}
/// <summary>
/// 科室医师切换
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ComboInputer_SelectedIndexChanged(object sender, EventArgs e)
{
var doctor = cmbInputer.SelectedItem as User ?? new User();
if (_examPart.InputerCode == doctor.Code) return;
_examPart.Inputer = doctor.Name;
_examPart.InputerCode = doctor.Code;
RefreshExamStatus();
}
private void ComboChecker_SelectedIndexChanged(object sender, EventArgs e)
{
var doctor = cmbChecker.SelectedItem as User ?? new User();
if (_examPart.CheckerCode == doctor.Code) return;
_examPart.Checker = doctor.Name;
_examPart.CheckerCode = doctor.Code;
RefreshExamStatus();
}
private void ComboVerifier_SelectedIndexChanged(object sender, EventArgs e)
{
var doctor = cmbVerifier.SelectedItem as User ?? new User();
if (_examPart.VerifyCode == doctor.Code) return;
_examPart.Verifier = doctor.Name;
_examPart.VerifyCode = doctor.Code;
RefreshExamStatus();
}
private void TabPart_SelectedPageChanged(object sender, TabPageChangedEventArgs e)
{
RefreshTabPageData(e.Page.Text);
}
/// <summary>
/// 添加结论
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConclusionAdd_Click(object sender, EventArgs e)
{
if (_examPart.VerifyTime != null || _examPart.GiveUpTime != null || _examPart.ID <= 0) return;
if (_patient.FinishTime != null || _patient.ID <= 0) return;
_conclusion.Insert(0, new ExamConclusion()
{
PID = _examPart.ID,
EID = _examPart.EID,
Seq = _conclusion.Count() + 1
});
ShowConclusion(_conclusion);
}
/// <summary>
/// 删除结论
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConclusionDelete_Click(object sender, EventArgs e)
{
if (_examPart.VerifyTime != null || _examPart.GiveUpTime != null || _examPart.ID <= 0) return;
if (_patient.FinishTime != null || _patient.ID <= 0) return;
if (DgvConclusion.GetSelectedRows().Length == 0) return;
var item = DgvConclusion.GetRow(DgvConclusion.FocusedRowHandle) as ExamConclusion;
_conclusion.Remove(item);
if (item?.ID > 0)
item.Delete();
ShowConclusion(_conclusion);
}
/// <summary>
/// 保存结论
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConclusionSave_Click(object sender, EventArgs e)
{
//未失去焦点时数据绑定未刷新需要收到修改焦点
// 调用 CloseEditor 方法来关闭单元格的编辑器并使单元格失去焦点
DgvConclusion.CloseEditor();
// 将焦点设置到其他控件,使 DataGrid 控件的单元格失去焦点
opsConclusion.Focus();
if (_examPart.VerifyTime != null || _examPart.GiveUpTime != null) return;
if (_patient.FinishTime != null || _patient.ID <= 0) return;
if (_examPart == null || _examPart?.ID <= 0)
{
MessageBox.Show(@"请先保存科室分检结果,再保存结论!");
return;
}
var result = MessageBox.Show(@"是否保存结论?", @"保存结论", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
if (_examPart != null)
SaveConclusion?.Invoke(this, new Args<ExamConclusion>()
{
ID = _examPart.ID,
Items = _conclusion
});
}
#endregion 页面控件事件
#region Refresh
private void RefreshTabPageData(string pageName)
{
// 显示两个面板 //设置第二个面板折叠,显示第一个面板
splitContainerExam.PanelVisibility =
pageName == @"一般项目" ? SplitPanelVisibility.Both : SplitPanelVisibility.Panel1;
switch (pageName)
{
case @"检验报告" when _patient.ID > 0:
GetLisReport?.Invoke(this, new Args<object>()
{
ID = _patient.ID
});
break;
case @"检查报告":
ListViewPacsImg.Width = 0;
picPacsRpt.Image = null;
GetPacsRptList?.Invoke(this, new Args<object>()
{
ID = _patient.ID
});
break;
case @"其他报告":
picReportExt.Image = null;
GetReportExtList?.Invoke(this, new Args<object>(_patient.ID));
break;
case @"分科结果":
GetDeptExamResultList?.Invoke(this, new Args<object>(_patient.ID));
break;
case @"历史结果":
AddHistoryView();
historyView.SearchHistory(_patient.CardNo);
break;
}
}
private void AddHistoryView()
{
tabPageHistory.Controls.Clear();
historyView = new HistoryView(_patient.CardNo);
// 设置子窗体的Dock属性为Fill,使其填充满选项卡页
historyView.Dock = DockStyle.Fill;
// 设置子窗体的父级为当前TabPage
historyView.Parent = tabPageHistory;
// 将子窗体添加到选项卡页中
tabPageHistory.Controls.Add(historyView);
historyView.Show();
}
/// <summary>
/// 5.获取科室分检结果列表
/// </summary>
public event EventHandler<Args<object>> GetDeptExamResultList;
public void ShowDeptExamResultList(List<ExamResult> items)
{
Invoke(new Action(() => dgcDeptResult.DataSource = null));
Invoke(new Action(() => dgcDeptResult.DataSource = items));
Invoke(new Action(() => DgvDeptExamResult.ExpandAllGroups()));
Invoke(new Action(() => DgvDeptExamResult.BestFitColumns()));
}
public event EventHandler<Args<object>> GetPacsRptList;
private void DgvLisReport_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e)
{
var gridView = (GridView)sender;
if (e.RowHandle < 0 || e.Column == null) return;
// 获取当前单元格所在行的数据
var rowData = gridView.GetRow(e.RowHandle) as ExamResult;
if (string.IsNullOrEmpty(rowData?.UnusualFlag)) return;
switch (rowData.UnusualFlag)
{
case "↑":
e.Appearance.ForeColor = ForeDanger;
e.Appearance.BackColor = BackDanger;
break;
case "↓":
e.Appearance.ForeColor = ForeMain;
e.Appearance.BackColor = BackMain;
break;
}
}
private void DgvExamResult_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e)
{
if (e.Column.Caption != @"科室") return;
var gridView = (GridView)sender;
if (e.RowHandle < 0 || e.Column == null) return;
// 获取当前单元格所在行的数据
var rowData = gridView.GetRow(e.RowHandle) as ExamResult;
if (rowData?.VerifyTime != null) return;
e.Appearance.ForeColor = ForeWarning;
e.Appearance.BackColor = BackWarning;
}
public void ShowGetPatientInfo(EnrollmentPatient item)
{
RefreshPatient(item);
}
/// <summary>
/// 刷新当前体检者信息
/// </summary>
/// <param name="item"></param>
private void RefreshPatient(EnrollmentPatient item = null)
{
Invoke(new Action(() => _patient = item ?? _patient));
Invoke(new Action(() => stripTxtEid.Text = _patient?.ID.ToString()));
// Invoke(new Action(() => patientInfo.Values = item ?? _patient));
SetPatientInfo(item ?? _patient);
OnGetDeptList();
}
/// <summary>
/// 刷新当前科室分检信息
/// </summary>
/// <param name="item"></param>
private void RefreshExamPart(ExamPart item = null)
{
item = item ?? _examPart;
item = item ?? new ExamPart();
Invoke(new Action(() => _examPart = item));
// 启用ComboBox
// var isEnabled = _patient?.FinishTime == null && item?.VerifyTime == null && item?.GiveUpTime == null;
if (item == null) return;
// RefreshComboboxDoctor(cmbInputer, isEnabled, _inputerList, item.Inputer, item.InputTime);
// RefreshComboboxDoctor(cmbChecker, isEnabled, _checkerList, item.Checker, item.CheckTime);
// RefreshComboboxDoctor(cmbVerifier, isEnabled, _verifierList, item.Verifier, item.VerifyTime);
RefreshTsmi(item);
RefreshExamStatus(item);
}
/// <summary>
/// 刷新科室分检状态
/// </summary>
private void RefreshExamStatus(ExamPart part = null)
{
part = part ?? _examPart;
if (_patient?.FinishTime != null)
{
Invoke(new Action(() =>
{
stripLblStatus.Text = @"已完结";
stripLblStatus.BackColor = BackSuccess;
stripLblStatus.ForeColor = ForeSuccess;
}));
return;
}
//"未保存" Warning;"未审核" Info;"已审核" Success;"弃检" Danger;
Invoke(new Action(() =>
{
stripLblStatus.Text =
part.GiveUpTime != null ? @"已弃检" : //已弃检
part.VerifyTime != null ? @"已审核" : @"未审核"; //已保存
//_isModified ? @"未保存" : @"未审核";//已修改
stripLblStatus.BackColor =
part.GiveUpTime != null ? BackDanger : //已弃检
part.VerifyTime != null ? BackMain : BackInfo; //已保存
// _isModified ? BackColorWarning : BackColorInfo;//已修改
stripLblStatus.ForeColor =
part.GiveUpTime != null ? ForeDanger : //已弃检
part.VerifyTime != null ? ForeMain : ForeInfo; //已保存
//_isModified ? ForeColorWarning : ForeColorInfo;//已修改
}));
}
/// <summary>
/// 刷新科室分检状态
/// </summary>
private void RefreshTsmi(ExamPart item = null)
{
item = item ?? _examPart;
//保存:未审核+未弃检
Invoke(new Action(() => tsmiSave.Enabled = (item.GiveUpTime == null && item.VerifyTime == null)));
//结论:已保存+未审核+未弃检
Invoke(new Action(() =>
tsmiConclusion.Enabled =
(item.GiveUpTime == null && item.VerifyTime == null))); //&& _isModified == false
//审核:已保存+未审核+未弃检
Invoke(new Action(() =>
tsmiReview.Enabled = (item.VerifyTime == null && item.GiveUpTime == null))); // && _isModified == false
//取消审核:已审核
Invoke(new Action(() => tsmiCancel.Enabled = item.VerifyTime != null));
//弃检:未弃检+未审核
//Invoke(new Action(() => TsmiAbandoned.Enabled = item.VerifyTime == null && item.GiveUpTime == null));
//取消弃检:已弃检
//Invoke(new Action(() => TsmiAbandonedCancel.Enabled = item.GiveUpTime != null));
}
#endregion Refresh
#region 1.检查结果列表相关
/// <summary>
/// 1.1.1.检查结果列表-加载单元格为输入框/选择框
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvExamResult_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
if (e.RowHandle < 0 || e.Column.FieldName != "TextResult") return;
if (DgvExamResult.GetRow(e.RowHandle) is ExamResult rowData && rowData.IsSelection)
{
if (rowData.GiveUpTime != null)
{
var item = new RepositoryItemTextEdit();
item.ReadOnly = true;
item.Appearance.ForeColor = Color.Red;
e.RepositoryItem = item;
return;
}
if (_examPart.VerifyTime == null && _examPart.GiveUpTime == null) return;
{
var item = new RepositoryItemTextEdit();
item.ReadOnly = true;
e.RepositoryItem = item;
}
}
else
{
if (_examResultList.All(p => p.ItemClass == "检查"))
{
e.RepositoryItem = new RepositoryItemMemoEdit
{
WordWrap = true
};
return;
}
e.RepositoryItem = new RepositoryItemTextEdit();
}
}
/// <summary>
/// 1.1.2.检查结果列表-焦点列改变-计算检查结果/体征词
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvExamResult_FocusedColumnChanged(object sender, FocusedColumnChangedEventArgs e)
{
Debug.WriteLine("DgvExamResult_FocusedColumnChanged");
// 获取当前聚焦的行行号
int rowHandle = DgvExamResult.FocusedRowHandle;
rowHandle = rowHandle + 1;
if (e.FocusedColumn.Name != "colExamTextResult") return;
if (!(DgvExamResult.GetFocusedRow() is ExamResult rowData)) return;
var parameters = new Dictionary<string, string>() { { "sex", _patient.Sex == "女" ? "2" : "1" } };
// 如果表达式不为空 则计算检查项目结果
if (!string.IsNullOrEmpty(rowData.ValueFormat))
{
var result = CalculateResult(rowData.ValueFormat, _examResultList, parameters);
rowData.TextResult = result;
if (decimal.TryParse(result, out var resultDecimal))
{
rowData.Result = resultDecimal;
}
}
// 体征词表达式 获取体征词
if (string.IsNullOrEmpty(rowData.SignFormat)) return;
var signId = CalculateSign(rowData.SignFormat, rowData.TextResult, parameters);
var sign = _lstSign.FirstOrDefault(p => p.ID == signId);
if (sign != null)
{
rowData.SeqReport = _examResultList.FirstOrDefault()?.SeqReport;
rowData.SeqSign = _examResultList.FirstOrDefault()?.SeqSign;
_examResultList.RemoveAll(p => p.RID == rowData.RID);
rowData.TextResult = $@"{sign.SignName}({rowData.TextResult})";
rowData.SID = sign.ID;
_examResultList.Add(rowData);
}
ShowExamResultList(null, DgvExamResult.TopRowIndex);
if (rowHandle >= DgvExamResult.RowCount)
{
SetFocuse(DgvExamResult, 0, "colExamTextResult");
}
else
{
SetFocuse(DgvExamResult, rowHandle, "colExamTextResult");
}
}
/// <summary>
/// 1.1.3.检查结果列表-焦点行改变
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvExamResult_FocusedRowChanged(object sender, FocusedRowChangedEventArgs e)
{
Debug.WriteLine("DgvExamResult_FocusedRowChanged");
// 获取当前聚焦的行行号
int rowHandle = DgvExamResult.FocusedRowHandle;
rowHandle = rowHandle + 1;
if (e.FocusedRowHandle < 0) return;
// 获取当前聚焦的行
if (!(DgvExamResult.GetRow(e.FocusedRowHandle) is ExamResult rowData)) return;
//var parameters = new Dictionary<string, string>() { { "sex", _patient.Sex == "女" ? "2" : "1" } };
var parameters = new Dictionary<string, string>() { { "sex", "1" } };
// 如果表达式不为空 则计算检查项目结果
if (!string.IsNullOrEmpty(rowData.ValueFormat))
{
var result = CalculateResult(rowData.ValueFormat, _examResultList, parameters);
rowData.TextResult = result;
if (decimal.TryParse(result, out var resultDecimal))
{
rowData.Result = resultDecimal;
}
}
// 体征词表达式 获取体征词
if (string.IsNullOrEmpty(rowData.SignFormat)) return;
var signId = CalculateSign(rowData.SignFormat, rowData.TextResult, parameters);
var sign = _lstSign.FirstOrDefault(p => p.ID == signId);
if (sign != null)
{
_examResultList.RemoveAll(p => p.RID == rowData.RID);
rowData.TextResult = $@"{sign.SignName}({rowData.TextResult})";
rowData.SID = sign.ID;
_examResultList.Add(rowData);
}
ShowExamResultList(null, DgvExamResult.TopRowIndex);
if (rowHandle >= DgvExamResult.RowCount)
{
SetFocuse(DgvExamResult, 0, "colExamTextResult");
}
else
{
SetFocuse(DgvExamResult, rowHandle, "colExamTextResult");
}
}
/// <summary>
/// 1.1.4.检查结果列表-单元格值修改
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvExamResult_CellValueChanged(object sender, CellValueChangedEventArgs e)
{
Debug.WriteLine("DgvExamResult_CellValueChanged");
if (e.Column.FieldName != "TextResult") return;
var item = DgvExamResult.GetRow(e.RowHandle) as ExamResult;
if (item?.ItemClass == "检验") return;
var update = _examResultList.FindIndex(p => p.RID == item?.RID);
_examResultList[update].TextResult = e.Value.ToString();
}
/// <summary>
/// 体征词计算
/// </summary>
/// <param name="expression"></param>
/// <param name="examResult"></param>
/// <param name="parameter"></param>
/// <returns></returns>
public long CalculateSign(string expression, string examResult, Dictionary<string, string> parameter = null)
{
if (string.IsNullOrEmpty(examResult) || string.IsNullOrEmpty(expression)) return 0;
var expr = new NCalc.Expression(expression);
expr.Parameters["value"] = examResult;
parameter?.ForEach(p => { expr.Parameters[p.Key] = p.Value; });
var calculateResult = expr.Evaluate().ToString();
return Int64.TryParse(calculateResult, out var id) ? id : 0;
}
/// <summary>
/// 检查结果计算
/// </summary>
/// <param name="exp"></param>
/// <param name="parameter">参数:Sex</param>
/// <param name="results"></param>
/// <returns></returns>
public string CalculateResult(string exp, List<ExamResult> results, Dictionary<string, string> parameter = null)
{
var hasValue = true;
// 替换[n] 为result(rid=n).Result
var expression = Regex.Replace(exp, @"\[(\d+)\]", m =>
{
var rid = int.Parse(m.Groups[1].Value);
var value = results.FirstOrDefault(p => p.RID == rid)?.TextResult;
hasValue = !string.IsNullOrEmpty(value);
if (decimal.TryParse(value, out var resultValue))
{
return $@"{resultValue:F2}";
}
hasValue = false;
return "";
});
if (!hasValue) return "";
var expr = new NCalc.Expression(expression);
parameter?.ForEach(p => { expr.Parameters[p.Key] = p.Value; });
var result = expr.Evaluate();
return result.ToString();
}
/// <summary>
/// 1.1.5.按下回车-跳转下一行
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvExamResult_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
int rowHandle = DgvExamResult.FocusedRowHandle;
rowHandle = rowHandle + 1;
if(rowHandle >= DgvExamResult.RowCount)
{
SetFocuse(DgvExamResult, 0, "colExamTextResult");
}
else
{
SetFocuse(DgvExamResult, rowHandle, "colExamTextResult");
}
}
}
/// <summary>
/// 重新聚焦
/// </summary>
/// <param name="view"></param>
/// <param name="rowHandle"></param>
/// <param name="columnName"></param>
private void SetFocuse(GridView view, Int32 rowHandle, string columnName)
{
view.Focus();
view.FocusedRowHandle = rowHandle;
view.FocusedColumn.Name = columnName;
view.ShowEditor();
}
#endregion 1.检查结果列表相关
#region PACS
public void ShowPacsRptList(List<Report> items)
{
Invoke(new Action(() => dgcRptPacs.DataSource = items));
Invoke(new Action(() => DgvRptPacs.BestFitColumns()));
if (items.Count > 0)
{
ShowPacsReportImg(items[0]);
}
}
public List<ExamPacsImage> GetExamPacsImage(long eid, string reportNo)
{
var pacsReportList = DAOHelp.GetDataBySQL<ExamPacsImage>($@"
SELECT * FROM Exam_PacsImage WHERE eid = {eid} and reportNo='{reportNo}'").ToList();
ShowExamPacsImage(pacsReportList);
return pacsReportList;
}
private void ShowExamPacsImage(List<ExamPacsImage> items)
{
flowLayoutPanelPacsImg.Controls.Clear();
items.ForEach(item =>
{
var picture = new PictureBox()
{
Size = new Size(280, 250),
SizeMode = PictureBoxSizeMode.Zoom,
Margin = new Padding(5)
};
try
{
using (var memoryStream = new MemoryStream(item.Image))
{
picture.Image = Image.FromStream(memoryStream);
}
flowLayoutPanelPacsImg.Controls.Add(picture);
}
catch (Exception ex)
{
Global.MsgErr($"获取检查报告图片失败:{ex.Message}");
}
});
}
/// <summary>
/// Pacs检查报告列表
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgvReportPacs_RowClick(object sender, EventArgs e)
{
picPacsRpt.Image = null;
flowLayoutPanelPacsImg.Controls.Clear();
Invoke(new Action(() => ListViewPacsImg.Width = 0));
//Invoke(new Action(() => TxtPacsImage.Visible = true));
Invoke(new Action(() => _pacsImgList = null));
Invoke(new Action(() => _pacsSelectedImgId = new List<string>()));
Invoke(new Action(() => ListViewPacsImg.LargeImageList = null));
if (!(DgvRptPacs.GetFocusedRow() is Report selected)) return;
ShowPacsReportImg(selected);
}
private void ShowPacsReportImg(Report selected)
{
Invoke(new Action(() => ListViewPacsImg.Width = 0));
Invoke(new Action(() => _pacsImgList = null));
Invoke(new Action(() => _pacsSelectedImgId = new List<string>()));
Invoke(new Action(() => ListViewPacsImg.LargeImageList = null));
var rpt = DAOHelp.Query<Report>($@"SELECT TOP 1 ReportImage FROM [dbo].[Report] WHERE ID={selected.ID}")
?.FirstOrDefault();
if (rpt?.ReportImage != null)
try
{
using (var ms = new MemoryStream(rpt.ReportImage))
{
picPacsRpt.Image = Image.FromStream(ms);
}
}
catch (Exception e)
{
Debug.Write(e.Message);
picPacsRpt.Image = null;
}
//排列方式为水平
ListViewPacsImg.Alignment = ListViewAlignment.Left;
//大小调整方式为自动调整列宽
ListViewPacsImg.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
ListViewPacsImg.CheckBoxes = true;
//获取选中的图片
GetExamPacsImage(selected.EID, selected.ReportNo);
}
/// <summary>
/// 保存PACS选中图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PacsTsmiSave_Click(object sender, EventArgs e)
{
if (!(DgvRptPacs.GetFocusedRow() is Report selected)) return;
if (string.IsNullOrEmpty(selected.ReportNo)) return;
DAOHelp.ExecuteSql(
$@"DELETE Exam_PacsImage WHERE ReportNo={selected.ReportNo}");
if (_pacsSelectedImgId.Count > 0)
{
var idList = string.Join(",", _pacsSelectedImgId);
var count = DAOHelp.ExecuteSql(
$@"INSERT INTO Exam_PacsImage (EID, ReportNo, Image,InTime)
SELECT EID, ReportNo, Image,InTime FROM Report_Pacs
WHERE ID IN ({idList})");
if (count == _pacsSelectedImgId.Count)
{
MessageBox.Show(@"保存检查图片成功!");
}
ListViewPacsImg.Width = 0;
//TxtPacsImage.Visible = true;
}
}
/// <summary>
/// PACS图片选则-取消修改
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PacsTsmiCancel_Click(object sender, EventArgs e)
{
ListViewPacsImg.Width = 0;
//TxtPacsImage.Visible = true;
if (!(DgvRptPacs.GetFocusedRow() is Report selected)) return;
if (string.IsNullOrEmpty(selected.ReportNo)) return;
GetExamPacsImage(selected.EID, selected.ReportNo);
}
/// <summary>
/// PACS图片选则-修改
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PacsTsmiAdd_Click(object sender, EventArgs e)
{
_pacsImgList = null;
_pacsSelectedImgId = new List<string>();
ListViewPacsImg.LargeImageList = null;
ListViewPacsImg.Items.Clear();
if (!(DgvRptPacs.GetFocusedRow() is Report selected) || selected.EID <= 0 ||
string.IsNullOrEmpty(selected.ReportNo)) return;
//TxtPacsImage.Visible = false;
ListViewPacsImg.Width = 420;
var pacsImageList = DAOHelp.GetDataBySQL<ReportPacs>(
$@"SELECT * FROM Report_Pacs WHERE eid = {selected.EID} and reportNo={selected.ReportNo}"
).ToList();
var imageList = new ImageList();
imageList.ImageSize = new Size(150, 150);
// 将ImageList关联到ListView控件
ListViewPacsImg.LargeImageList = imageList;
try
{
pacsImageList.ForEach(item =>
{
//var img = Convert.FromBase64String();
using (var ms = new MemoryStream(item.Image))
{
ms.Seek(0, SeekOrigin.Begin); // 重置内存流的位置
// 使用内存流创建图像对象
var image = Image.FromStream(ms);
// 添加图片到ImageList
imageList.Images.Add(item.ID.ToString(), image);
var imgItem = new ListViewItem(item.ID.ToString(), item.ID.ToString());
// 创建ListView的项,并设置图像索引
ListViewPacsImg.Items.Add(imgItem);
}
});
_pacsImgList = imageList;
}
catch (Exception ex)
{
Global.MsgErr($"获取检查报告图片失败:{ex.Message}");
}
}
/// <summary>
/// 限制报告最多选择3个图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListViewPacsImg_ItemCheck(object sender, System.Windows.Forms.ItemCheckEventArgs e)
{
Invoke(new Action(() => { ListViewPacsImg.Refresh(); }));
if (ListViewPacsImg.CheckedItems.Count >= MaxSelectionCount && e.NewValue == CheckState.Checked)
{
// 取消当前项的选择
e.NewValue = CheckState.Unchecked;
return;
}
var listView = (ListView)sender;
var item = listView.Items[e.Index];
if (e.NewValue == CheckState.Checked)
{
_pacsSelectedImgId.Add(item.Text);
}
if (e.NewValue == CheckState.Unchecked)
{
_pacsSelectedImgId.Remove(item.Text);
}
RefreshPacsSelectedImg();
}
/// <summary>
/// 单击项目选中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListViewPacsImg_ItemClick(object sender, EventArgs e)
{
Invoke(new Action(() => { ListViewPacsImg.Refresh(); }));
}
private void RefreshPacsSelectedImg()
{
flowLayoutPanelPacsImg.Controls.Clear();
_pacsSelectedImgId.ForEach(id =>
{
var picture = new PictureBox()
{
Size = new Size(280, 250),
SizeMode = PictureBoxSizeMode.Zoom,
Margin = new Padding(5),
Image = _pacsImgList.Images[id]
};
flowLayoutPanelPacsImg.Controls.Add(picture);
});
}
/// <summary>
/// 其他报告双击
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DgcRptExt_RowClick(object sender, EventArgs e)
{
}
/// <summary>
/// pacs报告打印
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PrintPacs_Click(object sender, EventArgs e)
{
if (!(DgvRptPacs.GetFocusedRow() is Report selected)) return;
var rpt = DAOHelp.Query<Report>($@"SELECT TOP 1 ReportImage FROM [dbo].[Report] WHERE ID={selected.ID}")?.FirstOrDefault();
if (rpt?.ReportImage != null)
{
try
{
using (var ms = new MemoryStream(rpt.ReportImage))
{
Image img = Image.FromStream(ms);
System.Windows.Forms.PrintDialog printDialog = new System.Windows.Forms.PrintDialog();
printDialog.Document = new PrintDocument();
printDialog.Document.PrintPage += (a, b) =>
{
// 计算图像的宽度和高度
int imageWidth = img.Width;
int imageHeight = img.Height;
// 获取打印区域的宽度和高度(考虑到页边距)
float marginBoundsWidth = b.MarginBounds.Width;
float marginBoundsHeight = b.MarginBounds.Height;
// 计算绘制起点的坐标,使图像居中
float left = (marginBoundsWidth - imageWidth) / 2;
float top = (marginBoundsHeight - imageHeight) / 2;
// 确保坐标值不为负数
left = left < 0 ? 0 : left;
top = top < 0 ? 0 : top;
b.Graphics.DrawImage(img, left, top, imageWidth, imageHeight);
};
printDialog.UseEXDialog = true; // 显示增强的打印对话框
if (printDialog.ShowDialog() == DialogResult.OK)
{
printDialog.Document.Print(); // 执行打印操作
}
}
}
catch (Exception ex)
{
Global.MsgWarn(ex.Message);
Debug.Write(ex.Message);
}
}
}
#endregion PACS
#region 数据关联获取
public void ShowExamPart(ExamPart item)
{
item = item ?? new ExamPart()
{
EID = _patient.ID,
DeptCode = _currentDept.DeptCode,
DeptName = _currentDept.DeptName,
Creator = currentUser.Name,
CreatorCode = currentUser.Code,
};
Invoke(new Action(() => _examPart = item));
Invoke(new Action(() => txtSummary.Text = item.Summary));
RefreshExamPart(item);
//获取检查结果
GetExamResultList?.Invoke(this, new Args<bool>()
{
ID = _patient.ID,
Code = _currentDept.DeptCode,
Item = (item?.VerifyTime != null || _patient?.FinishTime != null)
});
// 获取结论
GetConclusion?.Invoke(this, new Args<object>(item.ID));
//_isModified = false;
RefreshExamStatus(item);
RefreshTsmi(item);
RefreshTabPageData(TabPart.SelectedTabPage.Text);
GetDoctorList?.Invoke(this, new Args<object>()
{
Code = _currentDept?.DeptCode,
});
}
#endregion 数据关联获取
/// <summary>
/// 显示体检者信息
/// </summary>
/// <param name="patient"></param>
private void SetPatientInfo(EnrollmentPatient patient = null)
{
patient = patient ?? new EnrollmentPatient();
lblName.Invoke(() => lblName.Text = patient.Name);
lblSex.Text = patient.Sex == "1" ? "男" : patient.Sex == "2" ? "女" : "";
lblAge.Text = (patient.Age.ToString() == "0") ? "" : patient.Age + $@"{patient.AgeClass}";
lblNation.Text = patient.Nation;
lblEid.Text = (patient.ID.ToString() == "0") ? "" : patient.ID.ToString();
lblType.Text = patient.Type;
lblExamDate.Text = $@"{patient.ExamDate:yyyy-MM-dd}";
lblSignTime.Text = $@"{patient.SignTime:yyyy-MM-dd HH:mm}";
lblOccupation.Text = patient.Occupation;
lblMarriage.Text = patient.Marriage;
lblEducation.Text = patient.Education;
lblTel.Text = $@"{patient.Tel1}";
lblAddress.Text = patient.Address1;
lblOeid.Text = patient.OEID.ToString();
lblOrgName.Text = patient.OrgName;
lblGroupName.Text = patient.GroupName;
lblCardNo.Text = patient.CardNo;
picAvatar.Image = null;
if (string.IsNullOrEmpty(patient.Photo))
{
var photo = DAOHelp.GetDataBySQL<EnrollmentPatient>(
$@"SELECT Photo FROM Enrollment_Patient WHERE ID={patient.ID}").ToList()?.FirstOrDefault()?.Photo;
patient.Photo = photo;
}
if (!string.IsNullOrEmpty(patient.Photo))
{
var imageBytes = Convert.FromBase64String(patient.Photo);
using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
Invoke(new Action(() => { picAvatar.Image = Image.FromStream(ms, true); }));
Invoke(new Action(() => { picAvatar.BorderStyle = BorderStyle.None; }));
}
}
else
{
Invoke(new Action(() => { picAvatar.BorderStyle = BorderStyle.FixedSingle; }));
// FixedSingle
}
Invalidate(); // 使控件无效以重绘
}
}
}