diff --git a/IRaCIS.Core.Application/Helper/Attribute/DictionaryTranslateAttribute.cs b/IRaCIS.Core.Application/Helper/Attribute/DictionaryTranslateAttribute.cs new file mode 100644 index 000000000..6b9daff3d --- /dev/null +++ b/IRaCIS.Core.Application/Helper/Attribute/DictionaryTranslateAttribute.cs @@ -0,0 +1,23 @@ +using IRaCIS.Core.Domain.Share; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.Helper +{ + public class DictionaryTranslateAttribute : Attribute + { + + public string DicParentCode { get; set; } + + public DicDataTypeEnum DataTypeEnum { get; set; } + + + public DictionaryTranslateAttribute(string dicParentCode) + { + DicParentCode = dicParentCode; + } + } +} diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 93dbad1b7..60f1781b6 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -34,6 +34,45 @@ 主要为了 处理项目结束 锁库,不允许操作 + + + + + + + + + + + + + + + + + + + + + + + 写文件导到磁盘 + + 流 + 文件保存路径 + + + + + 通用获取文件路径 + + + + + + + + 替换表格Key @@ -4889,45 +4928,6 @@ - - - - - - - - - - - - - - - - - - - - - - - 写文件导到磁盘 - - 流 - 文件保存路径 - - - - - 通用获取文件路径 - - - - - - - - TaskAllocationRuleView 列表视图模型 diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index f0c36b266..b67a773d4 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -188,7 +188,7 @@ namespace IRaCIS.Core.Application.Service.Allocation .Where(t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId)) .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = trialReadingCriterionId }).ToListAsync(); - var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType }).FirstOrDefaultAsync()).IfNullThrowException(); + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType ,x.IsArbitrationReading,x.IsOncologyReading}).FirstOrDefaultAsync()).IfNullThrowException(); return (list, criterionConfig); } diff --git a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs index 7f7681103..133fc3318 100644 --- a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs @@ -69,10 +69,14 @@ namespace IRaCIS.Core.Application.Service CreateMap() .ForMember(o => o.DoctorUser, t => t.MapFrom(u => u.Enroll.DoctorUser)) .ForMember(o => o.CriterionReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Select(t => new TrialCriterionReadingCategory() { EnrollId = t.EnrollId, ReadingCategory = t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId }))) - .ForMember(o => o.TrialReadingCriterionList, t => t.MapFrom(u => u.Trial.ReadingQuestionCriterionTrialList.Where(t => t.IsConfirm).Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, TrialReadingCriterionName = t.CriterionName }))) + .ForMember(o => o.TrialReadingCriterionList, t => t.MapFrom(u => u.Trial.ReadingQuestionCriterionTrialList.Where(t => t.IsConfirm))) .ForMember(o => o.ReadingCategoryList, t => t.MapFrom(u => u.Enroll.EnrollReadingCategoryList.Where(t=>t.TrialReadingCriterionId== trialReadingCriterionId).OrderBy(t => t.ReadingCategory).Select(t => t.ReadingCategory).ToList())) ; + CreateMap() + .ForMember(t => t.TrialReadingCriterionId, u => u.MapFrom(c => c.Id)) + .ForMember(t => t.TrialReadingCriterionName, u => u.MapFrom(c => c.CriterionName)); + CreateMap().IncludeBase() .ForMember(o => o.AssignedSubjectCount, t => t.MapFrom(u => u.DoctorUser.VisitTaskList.Where(t => t.TrialId == u.TrialId).Select(t => t.SubjectId).Distinct().Count())) .ForMember(o => o.WaitDealTrialTaskCount, t => t.MapFrom(u => u.DoctorUser.VisitTaskList.Where(t => t.TrialId == u.TrialId).Where(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskState == TaskState.Effect).Count())) diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 906d72146..ed1d933fa 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -1,4 +1,5 @@ using IRaCIS.Core.Application.Contracts.DTO; +using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Domain.Share; using System.ComponentModel.DataAnnotations; @@ -117,6 +118,37 @@ namespace IRaCIS.Core.Application.Contracts } + public class CRCVisitExportDTO + { + public ChallengeStateEnum ChallengeState { get; set; } + public bool IsUrgent { get; set; } + public string BlindName { get; set; } = String.Empty; + public string VisitName { get; set; } = string.Empty; + + public string SubjectCode { get; set; } = String.Empty; + + public String TrialSiteCode { get; set; } = String.Empty; + + public DateTime? EarliestScanDate { get; set; } + public DateTime? LatestScanDate { get; set; } + + public DateTime? SubmitTime { get; set; } + + + [DictionaryTranslateAttribute("SubmitState")] + public SubmitStateEnum SubmitState { get; set; } + + [DictionaryTranslateAttribute("AuditStateRC")] + public AuditStateEnum AuditState { get; set; } + + [DictionaryTranslateAttribute("YesOrNo")] + public bool IsHaveClinicalData { get; set; } + + public string SubmitUserName { get; set; } + + } + + public class QCCRCVisitViewModel : QCVisitBasicListViewModel { diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index 42067f28c..2752a9e85 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -3,6 +3,8 @@ using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Service; +using Microsoft.AspNetCore.Authorization; +using IRaCIS.Core.Application.Helper; namespace IRaCIS.Core.Application.Image.QA { @@ -29,6 +31,53 @@ namespace IRaCIS.Core.Application.Image.QA + #region 导表查询 + + + //影像上传列表 + [HttpPost] + [AllowAnonymous] + public async Task CRCVisitListExport(CRCVisitSearchDTO visitSearchDTO, [FromServices] IRepository _commonDocumentRepository) + { + + //object[] objectList = typeof(CRCVisitExportDTO).GetProperties().Where(t=>t.CustomAttributes.Any(c=>c.AttributeType==typeof(DictionaryTranslateAttribute))) + // .Select(c=>new {c.Name,}) + // ; + + + var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); + + var list = _repository.Where(x => x.TrialId == visitSearchDTO.TrialId) + .Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true) + .WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId) + .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) + .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo)) + + .WhereIf(visitSearchDTO.VisitPlanArray != null && visitSearchDTO.VisitPlanArray?.Length > 0, svExpression) + //.WhereIf(!string.IsNullOrEmpty(visitSearchDTO.VisitPlanInfo), visitSearchDTO.VisitPlanInfo.Contains('.') ? t => t.InPlan == false : t => t.VisitNum == decimal.Parse(visitSearchDTO.VisitPlanInfo)) + .WhereIf(visitSearchDTO.AuditStateArray != null && visitSearchDTO.AuditStateArray?.Length > 0, t => visitSearchDTO.AuditStateArray!.Contains(t.AuditState)) + .WhereIf(visitSearchDTO.SubmitState != null, t => t.SubmitState == visitSearchDTO.SubmitState) + .WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) + .WhereIf(visitSearchDTO.IsUrgent != null, t => t.IsUrgent == visitSearchDTO.IsUrgent) + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) + .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + + + + + //var no = 1; + //exportInfo.TrialSiteUserList.ForEach(t => t.No = no++); + + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserList_Export, list, "", _commonDocumentRepository, _hostEnvironment); + + } + + + + #endregion + + #region CRC上传、质疑页面 /// @@ -42,7 +91,7 @@ namespace IRaCIS.Core.Application.Image.QA var svExpression = QCCommon.GetSubjectVisitFilter(visitSearchDTO.VisitPlanArray); var query = _repository.Where(x => x.TrialId == visitSearchDTO.TrialId) - .Where(t=>t.Subject.FinalSubjectVisitId !=null ?t.VisitNum<=t.Subject.FinalSubjectVisit.VisitNum:true) + .Where(t => t.Subject.FinalSubjectVisitId != null ? t.VisitNum <= t.Subject.FinalSubjectVisit.VisitNum : true) .WhereIf(visitSearchDTO.SiteId != null, t => t.SiteId == visitSearchDTO.SiteId) .WhereIf(visitSearchDTO.SubjectId != null, t => t.Subject.Id == visitSearchDTO.SubjectId) .WhereIf(!string.IsNullOrEmpty(visitSearchDTO.SubjectInfo), t => t.Subject.Code.Contains(visitSearchDTO.SubjectInfo)) @@ -57,7 +106,7 @@ namespace IRaCIS.Core.Application.Image.QA .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent)+ " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) }; + var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) }; var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray); var config = await _repository.Where(t => t.Id == visitSearchDTO.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); @@ -413,7 +462,7 @@ namespace IRaCIS.Core.Application.Image.QA var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(SubjectVisit.SubjectId), nameof(SubjectVisit.VisitNum) }; var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray); - + @@ -541,7 +590,7 @@ namespace IRaCIS.Core.Application.Image.QA //.WhereIf(_userInfo.UserTypeEnumInt == (int)UserType.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id))//CRC 过滤负责的site .ProjectTo(_mapper.ConfigurationProvider); - return await query.ToPagedListAsync(forwardQuery.PageIndex, forwardQuery.PageSize, forwardQuery.SortField, forwardQuery.Asc); + return await query.ToPagedListAsync(forwardQuery.PageIndex, forwardQuery.PageSize, forwardQuery.SortField, forwardQuery.Asc); } @@ -586,24 +635,25 @@ namespace IRaCIS.Core.Application.Image.QA [HttpPost] public async Task> GetQCQuestionAnswer(GetQCQuestionAnswerInDto inDto) { - var questionAnswerlist =await (from data in _trialQCQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.IsEnable) - join answer in _trialQCQuestionAnswerRepository.Where(x=>x.SubjectVisitId==inDto.SubjectVisitId&&x.QCProcessEnum==inDto.QCProcessEnum&&x.CurrentQCEnum==inDto.CurrentQCEnum).AsQueryable() on data.Id equals answer.TrialQCQuestionConfigureId into answertemp - from leftanswer in answertemp.DefaultIfEmpty() - select new QCQuestionAnswer() - { - Answer = leftanswer.Answer, - ShowOrder = data.ShowOrder, - QuestionName = data.QuestionName, - Id = data.Id, - IsRequired = data.IsRequired, - ParentId = data.ParentId, - ParentTriggerValue = data.ParentTriggerValue, - Type = data.Type, - TypeValue = data.TypeValue - }).ToListAsync(); + var questionAnswerlist = await (from data in _trialQCQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.IsEnable) + join answer in _trialQCQuestionAnswerRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId && x.QCProcessEnum == inDto.QCProcessEnum && x.CurrentQCEnum == inDto.CurrentQCEnum).AsQueryable() on data.Id equals answer.TrialQCQuestionConfigureId into answertemp + from leftanswer in answertemp.DefaultIfEmpty() + select new QCQuestionAnswer() + { + Answer = leftanswer.Answer, + ShowOrder = data.ShowOrder, + QuestionName = data.QuestionName, + Id = data.Id, + IsRequired = data.IsRequired, + ParentId = data.ParentId, + ParentTriggerValue = data.ParentTriggerValue, + Type = data.Type, + TypeValue = data.TypeValue + }).ToListAsync(); var result = questionAnswerlist.Where(x => x.ParentId == null).ToList(); - result.ForEach(x => { + result.ForEach(x => + { GetQuestionChild(x, questionAnswerlist); }); diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index cb158c074..959cd32c6 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -1179,6 +1179,7 @@ namespace IRaCIS.Core.Application.Image.QA { dbSubjectVisit.SubmitState = SubmitStateEnum.Submitted; dbSubjectVisit.SubmitTime = DateTime.Now; + dbSubjectVisit.SubmitUserId = _userInfo.Id; //维护统一状态 dbSubjectVisit.ReadingStatus = ReadingStatusEnum.ImageQuality; diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 08cd280fb..9c32dda77 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -10,6 +10,22 @@ namespace IRaCIS.Core.Application.Service { public QCConfig() { + + #region 导出列表 + + + + CreateMap() + .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode)) + + .ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.IsBaseLine ? t.PreviousHistoryList.Any() || t.PreviousOtherList.Any() + || t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count() > 0) + || t.PreviousSurgeryList.Any() : false)); + + #endregion + + + string token = string.Empty; //一致性核查 CreateMap(); diff --git a/IRaCIS.Core.Application/Service/WorkLoad/DTO/DoctorWorkLoadViewModel.cs b/IRaCIS.Core.Application/Service/WorkLoad/DTO/DoctorWorkLoadViewModel.cs index 26fcf1a67..27cf3b997 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/DTO/DoctorWorkLoadViewModel.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/DTO/DoctorWorkLoadViewModel.cs @@ -296,6 +296,14 @@ namespace IRaCIS.Application.Contracts public CriterionType? CriterionType { get; set; } public DateTime? ReadingInfoSignTime { get; set; } + + public bool IsGlobalReading { get; set; } = true; + + + public bool IsArbitrationReading { get; set; } = true; + + + public bool IsOncologyReading { get; set; } } public class TrialCriterionReadingCategory diff --git a/IRaCIS.Core.Application/Service/WorkLoad/DoctorWorkloadService.cs b/IRaCIS.Core.Application/Service/WorkLoad/DoctorWorkloadService.cs index 70c59f157..cb402cfe5 100644 --- a/IRaCIS.Core.Application/Service/WorkLoad/DoctorWorkloadService.cs +++ b/IRaCIS.Core.Application/Service/WorkLoad/DoctorWorkloadService.cs @@ -223,7 +223,7 @@ namespace IRaCIS.Application.Services EnrollId = intoGroup.Id, IsEnable = allocateRule.IsEnable, - TrialReadingCriterionList = intoGroup.Trial.ReadingQuestionCriterionTrialList.Where(t=>t.IsConfirm).Select(t=>new TrialReadingCriterionDto() { TrialReadingCriterionId=t.Id,TrialReadingCriterionName=t.CriterionName}).ToList(), + TrialReadingCriterionList = intoGroup.Trial.ReadingQuestionCriterionTrialList.Where(t=>t.IsConfirm).Select(t=>new TrialReadingCriterionDto() { TrialReadingCriterionId=t.Id,TrialReadingCriterionName=t.CriterionName,CriterionType=t.CriterionType,IsOncologyReading=t.IsOncologyReading,IsArbitrationReading=t.IsArbitrationReading,IsGlobalReading=t.IsGlobalReading,ReadingInfoSignTime=t.ReadingInfoSignTime,ReadingType=t.ReadingType}).ToList(), CriterionReadingCategoryList=intoGroup.EnrollReadingCategoryList.Select(t=>new TrialCriterionReadingCategory() { EnrollId=t.EnrollId,ReadingCategory=t.ReadingCategory, TrialReadingCriterionId = t.TrialReadingCriterionId }).ToList(), diff --git a/IRaCIS.Core.Domain/Visit/SubjectVisit.cs b/IRaCIS.Core.Domain/Visit/SubjectVisit.cs index 15e9533c5..6dec0d5bc 100644 --- a/IRaCIS.Core.Domain/Visit/SubjectVisit.cs +++ b/IRaCIS.Core.Domain/Visit/SubjectVisit.cs @@ -177,6 +177,12 @@ namespace IRaCIS.Core.Domain.Models public Guid? DeleteUserId { get; set; } + public Guid? SubmitUserId { get; set; } + + [JsonIgnore] + [ForeignKey("SubmitUserId")] + public User SubmitUser { get; set; } + //导航属性 [JsonIgnore] [ForeignKey("TrialId")]