CostCalculationItem/IRaCIS.Core.Application/Trial/Subject/StudyService.cs

1069 lines
45 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using AutoMapper;
using AutoMapper.QueryableExtensions;
using Dicom;
using IRaCIS.Application.ExpressionExtend;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.ViewModels;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Contracts.RequestAndResponse;
using IRaCIS.Core.Application.Dicom;
using IRaCIS.Core.Domain.Interfaces;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Domain.Share.AuthUser;
using IRaCIS.Infra.Data.ExpressionExtend;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using IConfiguration = Microsoft.Extensions.Configuration.IConfiguration;
namespace IRaCIS.Application.Services
{
public class StudyService : IStudyService
{
private readonly IDicomStudyRepository _studyRepository;
private readonly IVisitStageRepository _visitStageRepository;
private readonly ISubjectRepository _subjectRepository;
private readonly ISiteRepository _siteRepository;
private readonly ITrialRepository _trialRepository;
private readonly ISubjectVisitRepository _subjectVisitRepository;
private readonly IDicomInstanceRepository _dicomInstanceRepository;
private readonly IDicomSeriesRepository _dicomSeriesRepository;
private readonly IStudyReviewerRepository _studyReviewerRepository;
private readonly IDoctorRepository _doctorRepository;
private readonly IEnrollRepository _enrollRepository;
//private readonly IDicomStudyRepository _dicomStudyRepository;
private readonly IStudyStatusDetailRepository _studyStatusDetailRepository;
private readonly IUserInfo _userInfo;
private readonly IUserRepository _userRepository;
private readonly IUserTrialRepository _userTrialRepository;
private readonly IDictionaryRepository _dictionaryRepository;
private readonly IWorkloadTPRepository _workloadTPRepository;
private readonly IMapper _mapper;
private readonly IHostEnvironment _hostEnvironment;
private readonly ISponsorRepository _sponsorRepository;
private static string _fileStorePath = string.Empty;
public StudyService(IDicomStudyRepository visitPointRepository,
IVisitStageRepository visitPlanRepository,
ISubjectRepository subjectRepository,
ISiteRepository siteRepository,
ITrialRepository trialRepository,
ISubjectVisitRepository subjectVisitRepository,
IDicomInstanceRepository dicomInstanceRepository,
IDicomSeriesRepository dicomSeriesRepository,
IHostEnvironment hostEnvironment,
ISponsorRepository sponsorRepository,
IStudyReviewerRepository studyReviewerRepository,
IDoctorRepository doctorRepository,
IEnrollRepository enrollRepository,
//IDicomStudyRepository dicomStudyRepository,
IStudyStatusDetailRepository studyStatusDetailRepository,
IUserInfo userInfo,
IUserRepository userRepository,
IUserTrialRepository userTrialRepository,
IDictionaryRepository dictionaryRepository,
IWorkloadTPRepository workloadTPRepository,
IConfiguration config,
IMapper mapper)
{
_enrollRepository = enrollRepository;
//_dicomStudyRepository = dicomStudyRepository;
_studyReviewerRepository = studyReviewerRepository;
_studyStatusDetailRepository = studyStatusDetailRepository;
_userInfo = userInfo;
_userRepository = userRepository;
_userTrialRepository = userTrialRepository;
_dictionaryRepository = dictionaryRepository;
_doctorRepository = doctorRepository;
_studyRepository = visitPointRepository;
_visitStageRepository = visitPlanRepository;
_subjectRepository = subjectRepository;
_siteRepository = siteRepository;
_trialRepository = trialRepository;
_subjectVisitRepository = subjectVisitRepository;
_dicomInstanceRepository = dicomInstanceRepository;
_dicomSeriesRepository = dicomSeriesRepository;
_mapper = mapper;
_hostEnvironment = hostEnvironment;
_sponsorRepository = sponsorRepository;
_workloadTPRepository = workloadTPRepository;
_fileStorePath = config.GetValue<string>("DicomFileArchivedPath");
//_fileStorePath = Directory.GetParent(_hostEnvironment.ContentRootPath).FullName;
}
/// <summary>
/// 获取受试者访视
/// </summary>
/// <param name="trialId"></param>
/// <param name="subjectId"></param>
/// <param name="siteId"></param>
/// <returns></returns>
public IEnumerable<StudyStatDTO> GetStudyStatList(Guid trialId, Guid subjectId, Guid siteId)
{
var query = from visitStage in _visitStageRepository.Find(u => u.TrialId == trialId)
join visit in (_studyRepository.GetAll()
.Where(t => t.TrialId == trialId && t.SubjectId == subjectId && t.SiteId == siteId)
.GroupBy(t => t.SubjectVisitId).Select(g => new
{
SubjectVisitId = g.Key,
VisitCount = g.Count()
}))
on visitStage.Id equals visit.SubjectVisitId into t
from visit in t.DefaultIfEmpty()
select new StudyStatDTO
{
StudyCount = visit.VisitCount,
TrialId = visitStage.TrialId,
VisitNum = visitStage.VisitNum,
VisitName = visitStage.VisitName,
VisitDay = visitStage.VisitDay,
Description = visitStage.Description,
SubjectVisitId = visitStage.Id
};
query = query.OrderBy(t => t.VisitNum);
var list = query.ToList();
return list;
}
public bool UpdateReUploadNewStudyCode(Guid studyId, Guid newStudyId)
{
var code = _studyRepository.GetAll().First(t => t.Id == studyId).StudyCode;
return _studyRepository.Update(t => t.Id == newStudyId, u => new DicomStudy()
{
//StudyCode = u.StudyCode+"("+code+")"
StudyCode = code
});
}
public VerifyStudyUploadResult VerifyStudyAllowUpload(string studyInstanceUid, Guid trialId, Guid? abandonStudyId)
{
Guid expectStudyId = IdentifierHelper.CreateGuid(studyInstanceUid.Trim(), trialId.ToString());
var result = new VerifyStudyUploadResult();
var query =
from study in _studyRepository.GetAll().Where(t => t.TrialId == trialId && t.Id == expectStudyId)
join subject in _subjectRepository.GetAll()
on study.SubjectId equals subject.Id
join trial in _trialRepository.GetAll() on study.TrialId equals trial.Id
join subjectVisit in _subjectVisitRepository.GetAll()
on study.SubjectVisitId equals subjectVisit.Id
join site in _siteRepository.GetAll() on study.SiteId equals site.Id
select new StudyDTO()
{
PatientAge = study.PatientAge,
PatientSex = study.PatientSex,
PatientName = study.PatientName,
SubjectAge = subject.Age,
SubjectCode = subject.Code,
SubjectId = subject.Id,
SubjectName = subject.Name,
SubjectSex = subject.Sex,
Id = study.Id,
TrialId = study.TrialId,
Modalities = study.Modalities,
StudyCode = study.StudyCode,
SeriesCount = study.SeriesCount,
InstanceCount = study.InstanceCount,
StudyStatus = study.Status,
StudyDate = study.StudyTime,
IsDoubleReview = study.IsDoubleReview,
StudyDescription = study.Description,
BodyPartExamined = study.BodyPartExamined,
Comment = study.Comment,
SiteId = study.SiteId,
SiteName = site.SiteName,
SubjectVisitId = study.SubjectVisitId,
VisitName = subjectVisit.VisitName,
VisitNum = subjectVisit.VisitNum,
VisitDay = subjectVisit.VisitDay,
SVUPDES = subjectVisit.SVUPDES,
SVENDTC = subjectVisit.SVENDTC,
SVSTDTC = subjectVisit.SVSTDTC
};
result.StudyInfo = query.FirstOrDefault();
//如果是上传 看当前项目有没有已经上传过该检查 存在就不允许上传
if (abandonStudyId == null || abandonStudyId == Guid.Empty)
{
result.AllowUpload = result.StudyInfo is null;
}
else
{
//如果是重传 已经上传的 在此传可以的,
if ( abandonStudyId.GetValueOrDefault()== expectStudyId)
{
result.AllowUpload = true;
}
//重传的时候换了新的影像 在数据库不存在该影像 也允许上传
else if(result.StudyInfo == null )
{
result.AllowUpload = true;
}
else
{
result.AllowUpload = false;
}
}
return result;
}
public PageOutput<StudyDTO> GetStudyList(StudyQueryDTO queryDto)
{
Expression<Func<DicomStudy, bool>> studyLambda = x => x.TrialId == queryDto.TrialId;
Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == queryDto.TrialId;
if (queryDto.SubjectId != null)
{
studyLambda = studyLambda.And(t => t.SubjectId == queryDto.SubjectId);
}
if (queryDto.Status != null)
{
studyLambda = studyLambda.And(t => t.Status == queryDto.Status);
}
if (queryDto.SubjectVisitId != null)
{
studyLambda = studyLambda.And(t => t.SubjectVisitId == queryDto.SubjectVisitId);
}
if (!string.IsNullOrWhiteSpace(queryDto.VisitPlanInfo))
{
var visitInfo = queryDto.VisitPlanInfo.Trim();
if (visitInfo.Contains('.'))
{
subjectVisitLambda = subjectVisitLambda.And(t => t.VisitNum.ToString().Contains("."));
}
else
{
if (int.TryParse(visitInfo, out var visitNum))
{
subjectVisitLambda = subjectVisitLambda.And(t => t.VisitNum == visitNum);
}
}
//if (int.TryParse(visitInfo, out var visitNum))
//{
// subjectVisitLambda = subjectVisitLambda.And(t => t.VisitNum==visitNum);
//}
//else
//{
// subjectVisitLambda = subjectVisitLambda.And(t => t.VisitName.Contains(visitInfo));
//}
}
if (queryDto.StudyTimeBegin != null)
{
studyLambda = studyLambda.And(t => t.StudyTime >= queryDto.StudyTimeBegin);
}
if (queryDto.StudyTimeEnd != null)
{
studyLambda = studyLambda.And(t => t.StudyTime <= queryDto.StudyTimeEnd);
}
if (queryDto.UpdateTimeBegin != null)
{
studyLambda = studyLambda.And(t => t.UpdateTime >= queryDto.UpdateTimeBegin);
}
if (queryDto.UpdateTimeEnd != null)
{
studyLambda = studyLambda.And(t => t.UpdateTime <= queryDto.UpdateTimeEnd);
}
if (queryDto.SiteId != null)
{
studyLambda = studyLambda.And(t => t.SiteId == queryDto.SiteId);
}
else
{
//是CRC 需要过滤
var userId = _userInfo.Id;
var exist = _userRepository.GetAll()
.Any(t => t.Id == userId && t.UserType.Contains(StaticData.CRC));
if (exist)
{
//找到CRC负责的site
var siteIds = _userTrialRepository.GetAll().Where(t => t.SiteId != Guid.Empty && t.UserId == userId && t.TrialId == queryDto.TrialId)
.Select(u => u.SiteId);
studyLambda = studyLambda.And(t => siteIds.Contains(t.SiteId));
}
}
Expression<Func<Subject, bool>> subjectLambda = x => true;
if (!string.IsNullOrWhiteSpace(queryDto.SubjectInfo))
{
var subjectInfo = queryDto.SubjectInfo.Trim();
subjectLambda = subjectLambda.And(t => t.Code.Contains(subjectInfo) || t.Name.Contains(subjectInfo));
}
var query =
from study in _studyRepository.GetAll().Where(studyLambda)
join subject in _subjectRepository.Find(subjectLambda)
on study.SubjectId equals subject.Id
join trial in _trialRepository.GetAll() on study.TrialId equals trial.Id
join subjectVisit in _subjectVisitRepository.GetAll().Where(subjectVisitLambda)
on study.SubjectVisitId equals subjectVisit.Id
join site in _siteRepository.GetAll() on study.SiteId equals site.Id
select new StudyDTO()
{
PatientId = study.PatientId,
PatientAge = study.PatientAge,
PatientSex = study.PatientSex,
PatientName = study.PatientName,
AccessionNumber = study.AccessionNumber,
PatientBirthDate = study.PatientBirthDate,
StudyId = study.StudyId,
SubjectAge = subject.Age,
SubjectCode = subject.Code,
SubjectId = subject.Id,
SubjectName = subject.Name,
SubjectSex = subject.Sex,
Id = study.Id,
TrialId = study.TrialId,
Modalities = study.Modalities,
StudyCode = study.StudyCode,
SeriesCount = study.SeriesCount,
InstanceCount = study.InstanceCount,
StudyStatus = study.Status,
StudyDate = study.StudyTime,
IsDoubleReview = study.IsDoubleReview,
StudyDescription = study.Description,
BodyPartExamined = study.BodyPartExamined,
Comment = study.Comment,
UpdateTime = study.UpdateTime,
SiteId = study.SiteId,
SiteName = site.SiteName,
SubjectVisitId = study.SubjectVisitId,
VisitName = subjectVisit.VisitName,
VisitNum = subjectVisit.VisitNum,
VisitDay = subjectVisit.VisitDay,
SVUPDES = subjectVisit.SVUPDES,
SVENDTC = subjectVisit.SVENDTC,
SVSTDTC = subjectVisit.SVSTDTC
};
var count = query.Count();
// 默认按照 StudyCode 降序
var propName = queryDto.SortField == string.Empty ? "StudyCode" : queryDto.SortField;
if (string.IsNullOrWhiteSpace(queryDto.SortField))
{
queryDto.Asc = false;
}
query = queryDto.Asc
? query.OrderBy(propName).ThenBy(t => t.StudyCode).ThenBy(t => t.SiteName).ThenBy(u => u.SubjectCode).ThenBy(u => u.VisitNum)
: query.OrderByDescending(propName).ThenBy(t => t.StudyCode).ThenBy(t => t.SiteName).ThenBy(u => u.SubjectCode).ThenBy(u => u.VisitNum);
query = query.Skip((queryDto.PageIndex - 1) * queryDto.PageSize).Take(queryDto.PageSize);
var list = query.ToList();
// 可以看到分配的医生
//var studyIds = list.Select(t => t.Id).ToList();
//var studyReviewerQuery =
// from studyReviewer in _studyReviewerRepository.GetAll().Where(t => studyIds.Contains(t.StudyId))
// join doctor in _doctorRepository.GetAll() on studyReviewer.ReviewerId equals doctor.Id
// select new DistributeReviewer()
// {
// ReviewerId = doctor.Id,
// StudyId = studyReviewer.StudyId,
// NameCN = doctor.ChineseName,
// Name = doctor.LastName + " / " + doctor.FirstName,
// Status = studyReviewer.WorkloadType
// };
//var studyReviewerList = studyReviewerQuery.ToList();
//list.ForEach(t =>
//{
// t.DistributeReviewers = studyReviewerList.Where(u => u.StudyId == t.Id).OrderBy(c => c.NameCN).ToList();
//});
return new PageOutput<StudyDTO>(queryDto.PageIndex,
queryDto.PageSize, count, list);
}
/// <summary> 更新访视点和受试者 研究中心 项目的绑定关系</summary>
public async Task<IResponseOutput> UpdateStudyBinding(StudyEditCommand model)
{
var dicomStudy = _studyRepository.FindSingleOrDefault(s => s.Id == model.Id);
//var reviewModel = (from trial in _trialRepository.GetAll().Where(t => t.Id == model.TrialId)
// join dic in _dictionaryRepository.GetAll() on trial.ReviewModeId equals dic.Id
// select dic.Value).ToList();
var saveInfo = GetSaveToDicomInfo(new StudyCommand()
{
SiteId = model.SiteId,
SubjectVisitId = model.SubjectVisitId,
SubjectId = model.SubjectId,
TrialId = model.TrialId
});
if (SystemConfig.AddClinicalInfo)
{
UpdateDicomFile(dicomStudy, saveInfo);
}
var isSuccess = _studyRepository.Update(t => t.Id == model.Id, u => new DicomStudy()
{
SiteId = model.SiteId,
SubjectId = model.SubjectId,
SubjectVisitId = model.SubjectVisitId,
Comment = model.Comment
});
var isSuccess2 = _dicomSeriesRepository.Update(t => t.StudyId == model.Id, u => new DicomSeries()
{
SiteId = model.SiteId,
SubjectId = model.SubjectId,
SubjectVisitId = model.SubjectVisitId,
});
var isSuccess3 = _dicomInstanceRepository.Update(t => t.StudyId == model.Id, u => new DicomInstance()
{
SiteId = model.SiteId,
SubjectId = model.SubjectId,
SubjectVisitId = model.SubjectVisitId
});
return ResponseOutput.Result(isSuccess || isSuccess2 || isSuccess3);
}
/// <summary> 删除项目访视点</summary>
public IResponseOutput DeleteStudy(Guid id)
{
var success1 = _studyRepository.Delete(t => t.Id == id);
var succeess2 = _dicomInstanceRepository.Delete(t => t.StudyId == id);
var success3 = _dicomSeriesRepository.Delete(t => t.StudyId == id);
return ResponseOutput.Result(success1 || succeess2 || success3);
}
public DicomTrialSiteSubjectInfo GetSaveToDicomInfo(StudyCommand addtionalCommand)
{
var query = from subject in _subjectRepository.GetAll()
.Where(t => t.TrialId == addtionalCommand.TrialId && t.SiteId == addtionalCommand.SiteId &&
t.Id == addtionalCommand.SubjectId)
join trial in _trialRepository.GetAll().Where(t => t.Id == addtionalCommand.TrialId) on subject.TrialId
equals trial.Id
//join subjectVisit in _subjectVisitRepository.GetAll()
// .Where(t => t.Id == addtionalCommand.SubjectVisitId) on subject.SubjectVisitId equals subjectVisit
// .Id
join site in _siteRepository.GetAll().Where(t => t.Id == addtionalCommand.SiteId) on subject.SiteId
equals site.Id
join sponsor in _sponsorRepository.GetAll() on trial.SponsorId equals sponsor.Id into tt
from sponsor in tt.DefaultIfEmpty()
join dictionary in _dictionaryRepository.GetAll() on trial.ReviewModeId equals dictionary.Id into cc
from dictionary in cc.DefaultIfEmpty()
select new DicomTrialSiteSubjectInfo
{
SiteName = site.SiteName,
SiteCode = site.SiteCode,
SubjectName = subject.Name,
SubjectCode = subject.Code,
SubjectSex = subject.Sex,
SubjectAge = subject.Age,
//SubjectVisitNum = subjectVisit.VisitNum,
//SubjectVisitSVUPDES = subjectVisit.SVUPDES,
//SubjectVisitVisitName = subjectVisit.VisitName,
TrialCode = trial.Code,
TrialIndication = trial.Indication,
ReviewMode = dictionary.Value,
Sponsor = sponsor.SponsorName,
TrialId = addtionalCommand.TrialId,
SiteId = addtionalCommand.SiteId,
SubjectId = addtionalCommand.SubjectId,
SubjectVisitId = addtionalCommand.SubjectVisitId
};
var result = query.First();
if (result.ReviewMode.Contains("Double"))
{
result.IsDoubleReview = true;
}
var subjectVisitInfo = _subjectVisitRepository.GetAll()
.First(t => t.Id == addtionalCommand.SubjectVisitId);
result.SubjectVisitNum = subjectVisitInfo.VisitNum;
result.SubjectVisitSVUPDES = subjectVisitInfo.SVUPDES;
result.SubjectVisitVisitName = subjectVisitInfo.VisitName;
return result;
}
public Guid AddSubjectVisit(Guid subjectId, Guid siteId, Guid visitStageId, DateTime? SVSTDTC, DateTime? SVENDTC)
{
var visitPlanItem = _visitStageRepository.GetAll().First(t => t.Id == visitStageId);
var subjectVisit = new SubjectVisit()
{
TrialId = visitPlanItem.TrialId,
SiteId = siteId,
SubjectId = subjectId,
VisitName = visitPlanItem.VisitName,
VisitDay = visitPlanItem.VisitDay,
VisitNum = visitPlanItem.VisitNum,
SVSTDTC = SVSTDTC,
SVENDTC = SVENDTC
};
_subjectVisitRepository.Add(subjectVisit);
_subjectVisitRepository.SaveChanges();
return subjectVisit.Id;
}
public void UpdateSubjectLatestInfo( Guid subjectId,Guid trialId )
{
//更新最新得受试者访视
var latest = _subjectVisitRepository.GetAll()
.Where(t => t.SubjectId == subjectId && t.TrialId == trialId)
.OrderByDescending(t => t.SVSTDTC).FirstOrDefault();
if (latest != null)
{
_subjectRepository.Update(t => t.Id == subjectId, u => new Subject()
{
SubjectVisitId = latest.Id
});
}
}
public bool UpdateSubjectVisit(Guid subjectVisitId, DateTime? SVSTDTC, DateTime? SVENDTC)
{
return _subjectVisitRepository.Update(t => t.Id == subjectVisitId, u => new SubjectVisit()
{
SVENDTC = SVENDTC,
SVSTDTC = SVSTDTC,
StudyUploaded = true
});
}
private async Task UpdateDicomFile(DicomStudy dicomStudy, DicomTrialSiteSubjectInfo addtionalInfo)
{
//string studyPath = string.Empty;
//if (SystemConfig.Share)
//{
// WNetAddConnectionHelper.Connect();
// studyPath = Path.Combine("W:\\IRC_DICOM_ARCHIVED", dicomStudy.CreateTime.Year.ToString(), dicomStudy.TrialId.ToString(),
// dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.Id.ToString());
//}
//else studyPath = Path.Combine(_fileStorePath, dicomStudy.CreateTime.Year.ToString(), dicomStudy.TrialId.ToString(),
// dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.Id.ToString());
var studyPath = Path.Combine(_fileStorePath, dicomStudy.CreateTime.Year.ToString(), dicomStudy.TrialId.ToString(),
dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.Id.ToString());
DirectoryInfo root = new DirectoryInfo(studyPath);
FileInfo[] files = root.GetFiles();
foreach (var file in files)
{
DicomFile dicomFile = await DicomFile.OpenAsync(file.FullName, Encoding.Default);
DicomDataset dataset = dicomFile.Dataset;
dataset.AddOrUpdate(DicomTag.ClinicalTrialProtocolID, addtionalInfo.TrialCode); //Trial
dataset.AddOrUpdate(DicomTag.ClinicalTrialProtocolName, addtionalInfo.TrialIndication); //indication
dataset.AddOrUpdate(DicomTag.ClinicalTrialSponsorName, addtionalInfo.Sponsor);//sponsor
dataset.AddOrUpdate(DicomTag.ClinicalTrialSiteID, addtionalInfo.SiteCode); //SiteId
dataset.AddOrUpdate(DicomTag.ClinicalTrialSiteName, addtionalInfo.SiteName);//SiteName
dataset.AddOrUpdate(DicomTag.ClinicalTrialSubjectID, addtionalInfo.SubjectCode + " " + addtionalInfo.SubjectName + " " + addtionalInfo.SubjectSex);//SubjectId
dataset.AddOrUpdate(DicomTag.ClinicalTrialTimePointID, addtionalInfo.SubjectVisitNum.ToString()); // TimePoint
dataset.AddOrUpdate(DicomTag.ClinicalTrialTimePointDescription, addtionalInfo.SubjectVisitVisitName + " " + addtionalInfo.SubjectVisitSVUPDES);
await dicomFile.SaveAsync(file.FullName);
}
}
#region Study 分配给 Reviewer
public bool DistributeStudy(StudyReviewerCommand studyReviewer)
{
//更新Study表中总的状态
// 插入中间表
studyReviewer.StudyList.ForEach(study =>
{
var workloadType = 1;
StudyStatus studyStatus = StudyStatus.Distributed;
if (study.Status >= (int)StudyStatus.NeedAd)
{
workloadType = 2;
studyStatus = StudyStatus.AdDistributed;
}
var tempStudy = _studyRepository.FindSingleOrDefault(s => s.Id == study.StudyId);
tempStudy.Status = (int)studyStatus;
_studyRepository.Update(tempStudy);
_studyReviewerRepository.Add(new StudyReviewer()
{
ReviewerId = studyReviewer.ReviewerId,
StudyId = study.StudyId,
WorkloadType = workloadType,
TrialId = studyReviewer.TrialId,
Status = (int)studyStatus
});
});
return _studyReviewerRepository.SaveChanges();
}
public IResponseOutput EditStudyReviewer(StudyReviewerEditCommand studyReviewerEditCommand)
{
_studyReviewerRepository.Delete(t => studyReviewerEditCommand.StudyId == t.StudyId);
if (studyReviewerEditCommand.IsDoubleReview)
{
if (studyReviewerEditCommand.ReviewerId1 != null)
{
_studyReviewerRepository.Add(
new StudyReviewer()
{
StudyId = studyReviewerEditCommand.StudyId,
TrialId = studyReviewerEditCommand.TrialId,
ReviewerId = studyReviewerEditCommand.ReviewerId1.Value,
WorkloadType = 1
});
}
if (studyReviewerEditCommand.ReviewerId2 != null)
{
_studyReviewerRepository.Add(
new StudyReviewer()
{
StudyId = studyReviewerEditCommand.StudyId,
TrialId = studyReviewerEditCommand.TrialId,
ReviewerId = studyReviewerEditCommand.ReviewerId2.Value,
WorkloadType = 1
});
}
if (studyReviewerEditCommand.ReviewerIdForAD != null)
{
_studyReviewerRepository.Add(
new StudyReviewer()
{
StudyId = studyReviewerEditCommand.StudyId,
TrialId = studyReviewerEditCommand.TrialId,
ReviewerId = studyReviewerEditCommand.ReviewerIdForAD.Value,
WorkloadType = 2
});
}
if (studyReviewerEditCommand.ReviewerId2 == null || studyReviewerEditCommand.ReviewerId1 == null)
{
_studyRepository.Update(t => t.Id == studyReviewerEditCommand.StudyId,
u => new DicomStudy()
{
Status = (int)StudyStatus.QAFinish
});
}
}
else
{
if (studyReviewerEditCommand.ReviewerId1 != null)
{
_studyReviewerRepository.Add(
new StudyReviewer()
{
StudyId = studyReviewerEditCommand.StudyId,
TrialId = studyReviewerEditCommand.TrialId,
ReviewerId = studyReviewerEditCommand.ReviewerId1.Value,
WorkloadType = 1
});
}
else
{
_studyRepository.Update(t => t.Id == studyReviewerEditCommand.StudyId,
u => new DicomStudy()
{
Status = (int)StudyStatus.QAFinish
});
}
}
var success = _studyReviewerRepository.SaveChanges();
return ResponseOutput.Result(success);
}
public List<ReviewerDistributionDTO> GetReviewerListByTrialId(Guid trialId)
{
var query = from enrollItem in _enrollRepository
.Find(t => t.TrialId == trialId && t.EnrollStatus >= 10)
join doctorItem in _doctorRepository.GetAll()
on enrollItem.DoctorId equals doctorItem.Id into g
from doctor in g.DefaultIfEmpty()
select new
{
Code = doctor.Code,
FirstName = doctor.FirstName,
LastName = doctor.LastName,
ReviewerId = enrollItem.DoctorId,
ActivelyReading = doctor.ActivelyReading,
};
return query.Where(s => s.ActivelyReading).Select(s => new ReviewerDistributionDTO
{
Code = s.Code,
FirstName = s.FirstName,
LastName = s.LastName,
ReviewerId = s.ReviewerId,
}).ToList();
}
#endregion
public bool UpdateStudyModaliyAndComment(Guid studyId, string modaliy,string comment)
{
return _studyRepository.Update(s => s.Id == studyId, u => new DicomStudy
{
Modalities = modaliy,
Comment = comment
});
}
#region 更新检查状态,并记录操作记录
public bool UpdateStudyStatus(StudyStatusDetailCommand studyStatus, string optUserName)
{
var study = _studyRepository.FindSingleOrDefault(u => u.Id == studyStatus.StudyId);
study.Status = studyStatus.Status;
if (studyStatus.Status == (int)StudyStatus.QAFInishNotPass)
{
study.QAComment = studyStatus.QAComment;
}
_studyRepository.Update(study);
//如果状态QA完成就要添加一条TP工作量待分配 QAFinish
//QA 完成后需要对Dicom文件进行匿名化
//if (studyStatus.Status == (int)StudyStatus.QAFinish)
//{
// _workloadTPRepository.Add(new WorkloadTP
// {
// SiteId = study.SiteId,
// StudyId = study.Id,
// SubjectId = study.SubjectId,
// SubjectVisitId = study.SubjectVisitId,
// Status = 0,
// ReviewerId = Guid.Empty,
// TrialId = study.TrialId,
// UpdateTime = DateTime.Now,
// TimepointCode = study.StudyCode + "T01"
// });
// if (study.IsDoubleReview)//双重阅片则再添加一条编号变为T02
// {
// _workloadTPRepository.Add(new WorkloadTP
// {
// SiteId = study.SiteId,
// StudyId = study.Id,
// SubjectId = study.SubjectId,
// SubjectVisitId = study.SubjectVisitId,
// Status = 0,
// ReviewerId = Guid.Empty,
// TrialId = study.TrialId,
// UpdateTime = DateTime.Now,
// TimepointCode = study.StudyCode + "T02"
// });
// }
//}
_studyStatusDetailRepository.Add(new StudyStatusDetail
{
Status = studyStatus.Status,
StudyId = studyStatus.StudyId,
Note = studyStatus.Note,
OptUserName = optUserName,
OptTime = DateTime.Now
});
return _studyStatusDetailRepository.SaveChanges();
}
public async Task<bool> DicomAnonymize(Guid studyId, string optUserName)
{
var study = _studyRepository.FindSingleOrDefault(u => u.Id == studyId);
study.Status = (int)StudyStatus.Anonymize;
_studyRepository.Update(study);
_studyStatusDetailRepository.Add(new StudyStatusDetail
{
Status = (int)StudyStatus.Anonymize,
StudyId = studyId,
Note = string.Empty,
OptUserName = optUserName,
OptTime = DateTime.Now
});
_workloadTPRepository.Add(new WorkloadTP
{
SiteId = study.SiteId,
StudyId = study.Id,
SubjectId = study.SubjectId,
SubjectVisitId = study.SubjectVisitId,
Status = 0,
ReviewerId = Guid.Empty,
TrialId = study.TrialId,
UpdateTime = DateTime.Now,
TimepointCode = study.StudyCode + "T01"
});
if (study.IsDoubleReview)//双重阅片则再添加一条编号变为T02
{
_workloadTPRepository.Add(new WorkloadTP
{
SiteId = study.SiteId,
StudyId = study.Id,
SubjectId = study.SubjectId,
SubjectVisitId = study.SubjectVisitId,
Status = 0,
ReviewerId = Guid.Empty,
TrialId = study.TrialId,
UpdateTime = DateTime.Now,
TimepointCode = study.StudyCode + "T02"
});
}
//读取Dicom 文件,匿名化
//按照配置文件 匿名化
var dicomSeries = _dicomSeriesRepository.Find(s => s.StudyId == studyId).ToList();
foreach (var seriesItem in dicomSeries)
{
var dicomInstances = _dicomInstanceRepository.Find(s => s.SeriesId == seriesItem.Id);
foreach (var instanceItem in dicomInstances)
{
try
{
string filePath = CreateInstanceFilePath(study, seriesItem.Id, instanceItem.Id);
DicomFile dicomFile = await DicomFile.OpenAsync(filePath, Encoding.Default);
//DicomDataset dataset = dicomFile.Dataset;
foreach (var anonymizeItem in SystemConfig.AnonymizeTagList)
{
if (anonymizeItem.Enable)
{
ushort group = Convert.ToUInt16(anonymizeItem.Group, 16);
ushort element = Convert.ToUInt16(anonymizeItem.Element, 16);
dicomFile.Dataset.AddOrUpdate(new DicomTag(group, element), anonymizeItem.ReplaceValue);
}
}
//string path = string.Empty;
//if (SystemConfig.Share)
//{
// WNetAddConnectionHelper.Connect();
// path = Path.Combine("W:\\IRC_DICOM_ARCHIVED", study.CreateTime.Year.ToString(), study.TrialId.ToString(),
// study.SiteId.ToString(), study.SubjectId.ToString(), study.Id.ToString());
//}
//else
//{
// path = Path.Combine(_fileStorePath, study.CreateTime.Year.ToString(), study.TrialId.ToString(),
// study.SiteId.ToString(), study.SubjectId.ToString(), study.Id.ToString(), study.ToString() + ".dcm");
//}
string path = Path.Combine(_fileStorePath, study.CreateTime.Year.ToString(), study.TrialId.ToString(),
study.SiteId.ToString(), study.SubjectId.ToString(), study.Id.ToString());
await dicomFile.SaveAsync(Path.Combine(path, instanceItem.Id.ToString() + ".Anonymize" + ".dcm"));
instanceItem.Anonymize = true;
_dicomInstanceRepository.Update(instanceItem);
}
catch (Exception ex)
{
}
}
}
return _dicomInstanceRepository.SaveChanges();
}
private string CreateInstanceFilePath(DicomStudy dicomStudy, Guid seriesId, Guid instanceId)
{
//string path = string.Empty;
//if (SystemConfig.Share)
//{
// WNetAddConnectionHelper.Connect();
// path = Path.Combine("W:\\IRC_DICOM_ARCHIVED", dicomStudy.CreateTime.Year.ToString(), dicomStudy.TrialId.ToString(),
// dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.Id.ToString());
//}
//else
//{
// path = Path.Combine(_fileStorePath, dicomStudy.CreateTime.Year.ToString(), dicomStudy.TrialId.ToString(),
// dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.Id.ToString(), instanceId.ToString() + ".dcm");
//}
string path = Path.Combine(_fileStorePath, dicomStudy.CreateTime.Year.ToString(), dicomStudy.TrialId.ToString(),
dicomStudy.SiteId.ToString(), dicomStudy.SubjectId.ToString(), dicomStudy.Id.ToString());
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
return Path.Combine(path, instanceId.ToString() + ".dcm");
}
public bool UpdateStudyStatus(List<StudyStatusDetailCommand> studyStatus, string optUserName)
{
foreach (var studyItem in studyStatus)
{
var study = _studyRepository.FindSingleOrDefault(u => u.Id == studyItem.StudyId);
study.Status = studyItem.Status;
_studyRepository.Update(study);
_studyStatusDetailRepository.Add(new StudyStatusDetail
{
Status = studyItem.Status,
StudyId = studyItem.StudyId,
OptUserName = optUserName,
OptTime = DateTime.Now,
Note = studyItem.Note
});
}
return _studyStatusDetailRepository.SaveChanges();
}
public List<StudyStatusDetailDTO> GetStudyStatusDetailList(Guid studyId)
{
return _studyStatusDetailRepository.Find(s => s.StudyId == studyId).OrderByDescending(s => s.OptTime)
.ProjectTo<StudyStatusDetailDTO>(_mapper.ConfigurationProvider).ToList();
}
public PageOutput<DistributeReviewerStudyStatusDTO> GetDistributeStudyList(StudyStatusQueryDTO studyStatusQueryDto)
{
Expression<Func<StudyReviewer, bool>> studyReviewerLambda = x => x.TrialId == studyStatusQueryDto.TrialId;
if (studyStatusQueryDto.ReviewerId != null)
{
studyReviewerLambda = studyReviewerLambda.And(t => t.ReviewerId == studyStatusQueryDto.ReviewerId);
}
if (studyStatusQueryDto.StudyStatus != null)
{
studyReviewerLambda = studyReviewerLambda.And(t => t.Status == studyStatusQueryDto.StudyStatus);
}
var query = from studyReviewer in _studyReviewerRepository.GetAll().Where(studyReviewerLambda)
join doctor in _doctorRepository.GetAll() on studyReviewer.ReviewerId equals doctor.Id
join study in _studyRepository.GetAll() on studyReviewer.StudyId equals study.Id
select new DistributeReviewerStudyStatusDTO()
{
Name = doctor.LastName + " / " + doctor.FirstName,
NameCN = doctor.ChineseName,
ReviewerCode = doctor.Code,
Status = studyReviewer.Status,
StudyCode = study.StudyCode
};
var count = query.Count();
var propName = studyStatusQueryDto.SortField == string.Empty ? "ReviewerCode" : studyStatusQueryDto.SortField;
query = studyStatusQueryDto.Asc
? query.OrderBy(propName)
: query.OrderByDescending(propName);
query = query.Skip((studyStatusQueryDto.PageIndex - 1) * studyStatusQueryDto.PageSize).Take(studyStatusQueryDto.PageSize);
var list = query.ToList();
return new PageOutput<DistributeReviewerStudyStatusDTO>(studyStatusQueryDto.PageIndex,
studyStatusQueryDto.PageSize, count, list);
}
public IEnumerable<RelationVisitDTO> GetRelationVisitList(decimal visitNum, string tpCode)
{
string tpGroup = tpCode.Substring(tpCode.Length - 3, 3);
var tp = _workloadTPRepository.FindSingleOrDefault(u => u.TimepointCode == tpCode);
var query = from workloadTp in _workloadTPRepository.GetAll().Where(u => u.SubjectId == tp.SubjectId
&& u.TrialId == tp.TrialId && u.TimepointCode.Contains(tpGroup))
join subjectVisit in _subjectVisitRepository.GetAll().Where(u => u.VisitNum <= visitNum)
on workloadTp.SubjectVisitId equals subjectVisit.Id
select new RelationVisitDTO
{
StudyId = workloadTp.StudyId,
TpCode = workloadTp.TimepointCode,
VisitName = subjectVisit.VisitName
};
return query.ToList();
}
public List<SubjectVisitStudyDTO> GetSubjectVisitStudyList(Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId)
{
var query = _studyRepository.GetAll().Where(t =>
t.TrialId == trialId && t.SiteId == siteId && t.SubjectId == t.SubjectId &&
t.SubjectVisitId == subjectVisitId)
.Select(u => new SubjectVisitStudyDTO()
{
Modalities = u.Modalities,
StudyCode = u.StudyCode,
StudyId = u.Id,
Status = u.Status
});
return query.ToList();
}
#endregion
}
}