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("DicomFileArchivedPath"); //_fileStorePath = Directory.GetParent(_hostEnvironment.ContentRootPath).FullName; } /// /// 获取受试者访视 /// /// /// /// /// public IEnumerable 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 GetStudyList(StudyQueryDTO queryDto) { Expression> studyLambda = x => x.TrialId == queryDto.TrialId; Expression> 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> 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(queryDto.PageIndex, queryDto.PageSize, count, list); } /// 更新访视点和受试者 研究中心 项目的绑定关系 public async Task 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); } /// 删除项目访视点 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 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 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 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 GetStudyStatusDetailList(Guid studyId) { return _studyStatusDetailRepository.Find(s => s.StudyId == studyId).OrderByDescending(s => s.OptTime) .ProjectTo(_mapper.ConfigurationProvider).ToList(); } public PageOutput GetDistributeStudyList(StudyStatusQueryDTO studyStatusQueryDto) { Expression> 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(studyStatusQueryDto.PageIndex, studyStatusQueryDto.PageSize, count, list); } public IEnumerable 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 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 } }