225 lines
13 KiB
C#
225 lines
13 KiB
C#
|
// Copyright (c) 2012-2021 fo-dicom contributors.
|
|||
|
// Licensed under the Microsoft Public License (MS-PL).
|
|||
|
|
|||
|
using FellowOakDicom;
|
|||
|
using Newtonsoft.Json.Linq;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Configuration;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
using System.Windows.Forms;
|
|||
|
using static System.Net.Mime.MediaTypeNames;
|
|||
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
|||
|
|
|||
|
namespace Worklist_SCP.Model
|
|||
|
{
|
|||
|
|
|||
|
public static class WorklistHandler
|
|||
|
{
|
|||
|
//static string getEncodingTxt(string text)
|
|||
|
//{
|
|||
|
// //string encodingStr= ConfigurationManager.AppSettings["MGYZZXWSY"].Split(',')[2];
|
|||
|
// //string originalText = text; // 假设这是UTF-8编码的文本
|
|||
|
// //byte[] utf8Bytes = Encoding.UTF8.GetBytes(originalText);
|
|||
|
// //// 将UTF-8字节转换为GB18030编码的字节
|
|||
|
// //byte[] gb18030Bytes = Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding(encodingStr), utf8Bytes);
|
|||
|
// //// 将GB18030字节转换为字符串
|
|||
|
// //string convertedText = Encoding.GetEncoding(encodingStr).GetString(gb18030Bytes);
|
|||
|
// //return convertedText;
|
|||
|
|
|||
|
|
|||
|
// string encodingStr = ConfigurationManager.AppSettings["MGYZZXWSY"].Split(',')[2];
|
|||
|
// string originalText = text; // 假设这是UTF-8编码的文本
|
|||
|
// byte[] utf8Bytes = Encoding.UTF8.GetBytes(originalText);
|
|||
|
// // 将UTF-8字节转换为GB18030编码的字节
|
|||
|
// byte[] gb18030Bytes = Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding("GB18030"), utf8Bytes);
|
|||
|
// // 将GB18030字节转换为字符串
|
|||
|
// string convertedText = Encoding.GetEncoding("GB18030").GetString(gb18030Bytes);
|
|||
|
// return convertedText;
|
|||
|
//}
|
|||
|
|
|||
|
|
|||
|
//static byte[] getEncodingTxt1(string originalText)
|
|||
|
//{
|
|||
|
// byte[] utf8Bytes = Encoding.UTF8.GetBytes(originalText);
|
|||
|
// // 将UTF-8字节转换为GB18030编码的字节
|
|||
|
// byte[] gb18030Bytes = Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding("GB18030"), utf8Bytes);
|
|||
|
// return gb18030Bytes;
|
|||
|
//}
|
|||
|
|
|||
|
public static IEnumerable<DicomDataset> FilterWorklistItems(DicomDataset request, List<WorklistItem> allWorklistItems)
|
|||
|
{
|
|||
|
logger.LogWriter("收到来自客户端的请求");
|
|||
|
DicomDataset procedureStep1 = request.GetSequence(DicomTag.ScheduledProcedureStepSequence).First();
|
|||
|
var ScheduledStationAETitle1 = procedureStep1.GetSingleValueOrDefault(DicomTag.ScheduledStationAETitle, string.Empty);
|
|||
|
var PerformedStationAETitle = procedureStep1.GetSingleValueOrDefault(DicomTag.PerformedStationAETitle, string.Empty);
|
|||
|
var RetrieveAETitle = procedureStep1.GetSingleValueOrDefault(DicomTag.RetrieveAETitle, string.Empty);
|
|||
|
var StationAETitle = procedureStep1.GetSingleValueOrDefault(DicomTag.StationAETitle, string.Empty);
|
|||
|
string val1 = ScheduledStationAETitle1 + "," + PerformedStationAETitle + "," + RetrieveAETitle + "," + StationAETitle;
|
|||
|
WorklistItemsProvider WIP = new WorklistItemsProvider();
|
|||
|
//allWorklistItems = WIP.GetAllCurrentWorklistItems(val1); //查询患者信息
|
|||
|
// MessageBox.Show(ScheduledStationAETitle1);
|
|||
|
allWorklistItems = WIP.GetAllCurrentWorklistItems(ScheduledStationAETitle1); //查询患者信息
|
|||
|
var exams = allWorklistItems.AsQueryable();
|
|||
|
if (request.TryGetSingleValue(DicomTag.PatientID, out string patientId))
|
|||
|
{
|
|||
|
exams = exams.Where(x => x.PatientID.Equals(patientId));
|
|||
|
}
|
|||
|
var patientName = request.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty);
|
|||
|
if (!string.IsNullOrEmpty(patientName))
|
|||
|
{
|
|||
|
exams = AddNameCondition(exams, patientName);
|
|||
|
}
|
|||
|
DicomDataset procedureStep = null;
|
|||
|
if (request.Contains(DicomTag.ScheduledProcedureStepSequence))
|
|||
|
{
|
|||
|
procedureStep = request.GetSequence(DicomTag.ScheduledProcedureStepSequence).First();
|
|||
|
var scheduledStationAET = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledStationAETitle, string.Empty);
|
|||
|
if (!string.IsNullOrEmpty(scheduledStationAET))
|
|||
|
{
|
|||
|
exams = exams.Where(x => x.ScheduledAET == scheduledStationAET);
|
|||
|
}
|
|||
|
var performingPhysician = procedureStep.GetSingleValueOrDefault(DicomTag.PerformingPhysicianName, string.Empty);
|
|||
|
if (!string.IsNullOrEmpty(performingPhysician))
|
|||
|
{
|
|||
|
exams = exams.Where(x => x.PerformingPhysician == performingPhysician);
|
|||
|
}
|
|||
|
var modality = procedureStep.GetSingleValueOrDefault(DicomTag.Modality, string.Empty);
|
|||
|
if (!string.IsNullOrEmpty(modality))
|
|||
|
{
|
|||
|
exams = exams.Where(x => x.Modality == modality);
|
|||
|
}
|
|||
|
// if only date is specified, then using standard matching
|
|||
|
// but if both are specified, then MWL defines a combined match
|
|||
|
var scheduledProcedureStepStartDateTime = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepStartDateTime, string.Empty);
|
|||
|
if (!string.IsNullOrEmpty(scheduledProcedureStepStartDateTime))
|
|||
|
{
|
|||
|
exams = AddDateCondition(exams, scheduledProcedureStepStartDateTime);
|
|||
|
}
|
|||
|
// Optional (but commonly used) matching keys.
|
|||
|
var procedureStepLocation = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepLocation, string.Empty);
|
|||
|
if (!string.IsNullOrEmpty(procedureStepLocation))
|
|||
|
{
|
|||
|
exams = exams.Where(x => x.ExamRoom.Equals(procedureStepLocation));
|
|||
|
}
|
|||
|
var procedureDescription = procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepDescription, string.Empty);
|
|||
|
if (!string.IsNullOrEmpty(procedureDescription))
|
|||
|
{
|
|||
|
exams = exams.Where(x => x.ExamDescription.Equals(procedureDescription));
|
|||
|
}
|
|||
|
}
|
|||
|
var results = exams.ToList();
|
|||
|
// Parsing result
|
|||
|
foreach (var result in results)
|
|||
|
{
|
|||
|
var resultingSPS = new DicomDataset();
|
|||
|
var resultDataset = new DicomDataset();
|
|||
|
var resultingSPSSequence = new DicomSequence(DicomTag.ScheduledProcedureStepSequence, resultingSPS);
|
|||
|
if (procedureStep != null)
|
|||
|
{
|
|||
|
resultDataset.Add(resultingSPSSequence);
|
|||
|
}
|
|||
|
// add results to "main" dataset
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.AccessionNumber, result.AccessionNumber); // T2
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.InstitutionName, result.HospitalName);
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.ReferringPhysicianName, result.ReferringPhysician); // T2
|
|||
|
// string encodingStr = ConfigurationManager.AppSettings["CurrentOrgInfo"].Split(',')[2];//影像设备的编码方式
|
|||
|
resultDataset.AddOrUpdate(DicomTag.SpecificCharacterSet, "GB18030");//李双自己添加的编码方式
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.PatientName, result.Surname + result.Forename); //T1
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.PatientID, result.PatientID); // T1
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.PatientBirthDate, result.DateOfBirth); // T2
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.PatientSex, result.Sex); //T2
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.StudyInstanceUID, result.StudyUID); // T1
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.RequestingPhysician, result.ReferringPhysician); //T2 转诊医生 申请医生 咨询医生
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.RequestedProcedureDescription, result.ExamDescription); //T1C //检查描述
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.RequestedProcedureID, result.ProcedureID); // T1
|
|||
|
// Scheduled Procedure Step sequence T1
|
|||
|
// add results to procedure step dataset
|
|||
|
// Return if requested
|
|||
|
if (procedureStep != null)
|
|||
|
{
|
|||
|
AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledStationAETitle, result.ScheduledAET); // T1
|
|||
|
AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepStartDate, result.ExamDateAndTime); //T1
|
|||
|
AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepStartTime, result.ExamDateAndTime); //T1
|
|||
|
AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.Modality, result.Modality); // T1
|
|||
|
|
|||
|
AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledPerformingPhysicianName, result.PerformingPhysician); //T2
|
|||
|
AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepDescription, result.ExamDescription); // T1C
|
|||
|
AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepID, result.ProcedureStepID); // T1
|
|||
|
AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledStationName, result.ExamRoom); //T2
|
|||
|
AddIfExistsInRequest(resultingSPS, procedureStep, DicomTag.ScheduledProcedureStepLocation, result.ExamRoom); //T2
|
|||
|
}
|
|||
|
|
|||
|
// Put blanks in for unsupported fields which are type 2 (i.e. must have a value even if NULL)
|
|||
|
// In a real server, you may wish to support some or all of these, but they are not commonly supported
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.ReferencedStudySequence, new DicomDataset()); // Ref//d Study Sequence
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.Priority, ""); // Priority
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.PatientTransportArrangements, ""); // Transport Arrangements
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.AdmissionID, ""); // Admission ID
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.CurrentPatientLocation, ""); // Patient Location
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.ReferencedPatientSequence, new DicomDataset()); // Ref//d Patient Sequence
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.PatientWeight, ""); // Weight
|
|||
|
AddIfExistsInRequest(resultDataset, request, DicomTag.ConfidentialityConstraintOnPatientDataDescription, ""); // Confidentiality Constraint
|
|||
|
|
|||
|
// Send Reponse Back
|
|||
|
yield return resultDataset;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//Splits patient name into 2 separte strings surname and forename and send then to the addstringcondition subroutine.
|
|||
|
internal static IQueryable<WorklistItem> AddNameCondition(IQueryable<WorklistItem> exams, string dicomName)
|
|||
|
{
|
|||
|
if (string.IsNullOrEmpty(dicomName) || dicomName == "*")
|
|||
|
{
|
|||
|
return exams;
|
|||
|
}
|
|||
|
|
|||
|
var personName = new DicomPersonName(DicomTag.PatientName, dicomName);
|
|||
|
if (dicomName.Contains("*"))
|
|||
|
{
|
|||
|
var firstNameRegex = new Regex("^" + Regex.Escape(personName.First).Replace("\\*", ".*") + "$");
|
|||
|
var lastNameRegex = new Regex("^" + Regex.Escape(personName.Last).Replace("\\*", ".*") + "$");
|
|||
|
exams = exams.Where(x => firstNameRegex.IsMatch(x.Forename) || lastNameRegex.IsMatch(x.Surname));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
exams = exams.Where(x => (x.Forename.Equals(personName.First) && x.Surname.Equals(personName.Last)));
|
|||
|
}
|
|||
|
|
|||
|
return exams;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
internal static IQueryable<WorklistItem> AddDateCondition(IQueryable<WorklistItem> exams, string dateCondition)
|
|||
|
{
|
|||
|
if (!string.IsNullOrEmpty(dateCondition) && dateCondition != "*")
|
|||
|
{
|
|||
|
var range = new DicomDateTime(DicomTag.ScheduledProcedureStepStartDate, dateCondition).Get<DicomDateRange>();
|
|||
|
exams = exams.Where(x => range.Contains(x.ExamDateAndTime));
|
|||
|
}
|
|||
|
return exams;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
internal static void AddIfExistsInRequest<T>(DicomDataset result, DicomDataset request, DicomTag tag, T value)
|
|||
|
{
|
|||
|
// Only send items which have been requested
|
|||
|
|
|||
|
// bool flag = request.Contains(tag);
|
|||
|
if (request.Contains(tag))
|
|||
|
{
|
|||
|
if (value == null)
|
|||
|
{
|
|||
|
value = default;
|
|||
|
}
|
|||
|
result.AddOrUpdate(tag, value);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
}
|