diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index 12f4630f5..711c0940d 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -33,6 +33,7 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.StaticFiles; using Microsoft.AspNetCore.WebUtilities; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; using MiniExcelLibs; @@ -235,13 +236,17 @@ namespace IRaCIS.Core.API.Controllers public IUserInfo _userInfo { get; set; } private readonly IMediator _mediator; - private readonly IWebHostEnvironment _hostEnvironment; + + public IStringLocalizer _localizer { get; set; } + + + private readonly IWebHostEnvironment _hostEnvironment; private readonly IRepository _repository; private readonly IEasyCachingProvider _provider; private readonly QCCommon _qCCommon; - public StudyController(IMapper mapper, IUserInfo userInfo, IWebHostEnvironment hostEnvironment, IMediator mediator, IEasyCachingProvider provider, + public StudyController(IMapper mapper, IStringLocalizer localizer, IUserInfo userInfo, IWebHostEnvironment hostEnvironment, IMediator mediator, IEasyCachingProvider provider, QCCommon qCCommon, IRepository repository) { @@ -249,8 +254,8 @@ namespace IRaCIS.Core.API.Controllers _provider = provider; _hostEnvironment = hostEnvironment; _mediator = mediator; - - _mapper = mapper; + _localizer = localizer; + _mapper = mapper; _userInfo = userInfo; _repository = repository; } @@ -313,7 +318,7 @@ namespace IRaCIS.Core.API.Controllers string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value)) { //---不支持的MediaType - return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_UnsupportedMedia")); + return ResponseOutput.NotOk(_localizer["UploadDownLoad_UnsupportedMedia"]); } var archiveStudyCommand = new ArchiveStudyCommand() { AbandonStudyId = abandonStudyId, StudyInstanceUid = studyInstanceUid, SubjectVisitId = subjectVisitId }; @@ -407,7 +412,7 @@ namespace IRaCIS.Core.API.Controllers _provider.Remove($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}"); //---请求异常,请重试! - throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_RequestError")); + throw new BusinessValidationFailedException(_localizer["UploadDownLoad_RequestError"]); } studyMonitor.FileSize = (decimal)HttpContext.Request.ContentLength; @@ -559,7 +564,7 @@ namespace IRaCIS.Core.API.Controllers if (!fileName.EndsWith(".xlsx") && !fileName.EndsWith(".csv") && !fileName.EndsWith(".xls")) { //---支持.xlsx、.xls、.csv格式的文件上传。 - throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_SupportedFormats")); + throw new BusinessValidationFailedException(_localizer["UploadDownLoad_SupportedFormats"]); } fileStream.CopyTo(templateFileStream); @@ -609,7 +614,7 @@ namespace IRaCIS.Core.API.Controllers //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors)); - if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors)); + if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(_localizer["UploadDownLoad_TemplateErrors"]); etcCheckList = import.Data.ToList(); } @@ -697,7 +702,7 @@ namespace IRaCIS.Core.API.Controllers if (etcCheckList == null || etcCheckList.Count == 0) { //---请保证上传数据符合模板文件中的样式,且存在有效数据。 - return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData")); + return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]); } else { @@ -718,7 +723,7 @@ namespace IRaCIS.Core.API.Controllers if (etcCheckList.Count == 0) { //---请保证上传数据符合模板文件中的样式,且存在有效数据。 - return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData")); + return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]); } } @@ -962,13 +967,14 @@ namespace IRaCIS.Core.API.Controllers public IMapper _mapper { get; set; } public IUserInfo _userInfo { get; set; } private readonly IMediator _mediator; + public IStringLocalizer _localizer { get; set; } + private readonly IWebHostEnvironment _hostEnvironment; - private readonly IWebHostEnvironment _hostEnvironment; - - public UploadDownLoadController(IMapper mapper, IUserInfo userInfo, IMediator mediator, IWebHostEnvironment hostEnvironment) + public UploadDownLoadController(IMapper mapper, IUserInfo userInfo, IStringLocalizer localizer, IMediator mediator, IWebHostEnvironment hostEnvironment) { _hostEnvironment = hostEnvironment; - _mediator = mediator; + _localizer = localizer; + _mediator = mediator; _mapper = mapper; _userInfo = userInfo; } @@ -994,7 +1000,7 @@ namespace IRaCIS.Core.API.Controllers if (!realFileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase)) { // 请用提供格式的模板excel上传需要处理的数据 - throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData")); + throw new BusinessValidationFailedException(_localizer["UploadDownLoad_TemplateUploadData"]); } var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/SiteSurvey", realFileName); @@ -1015,7 +1021,7 @@ namespace IRaCIS.Core.API.Controllers if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr))) { //请确保Excel中 每一行的 中心编号,姓名,邮箱,用户类型数据记录完整再进行上传 - throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_EnsureCompleteData")); + throw new BusinessValidationFailedException(_localizer["UploadDownLoad_EnsureCompleteData"]); } var siteCodeList = excelList.Select(t => t.TrialSiteCode.Trim().ToUpper()).Distinct().ToList(); @@ -1023,31 +1029,31 @@ namespace IRaCIS.Core.API.Controllers if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count) { //在项目中未找到该Excel中部分或全部中心 - throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidCenters")); + throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidCenters"]); } if (excelList.GroupBy(t => new { t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1)) { // 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据 - throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_CheckDuplicateAccounts")); + throw new BusinessValidationFailedException(_localizer["UploadDownLoad_CheckDuplicateAccounts"]); } if (excelList.Any(t => !t.Email.Contains("@"))) { //有邮箱不符合邮箱格式,请核查Excel数据 - throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail")); + throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidEmail"]); } var generateUserTypeList = new List() { "CRC", "CRA" }; if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper()))) { //用户类型仅能为 CRC,SR,CRA 请核查Excel数据 - throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidUserType")); + throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidUserType"]); } if (excelList.Count == 0) { - throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_NoValiddata")); + throw new BusinessValidationFailedException(_localizer["UploadDownLoad_NoValiddata"]); } //处理好 用户类型 和用户类型枚举 var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList(); diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 602e97a4b..a37261aef 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -1310,6 +1310,13 @@ + + + 计算靶病灶状态 + + + + 获取Sod的值 @@ -4860,6 +4867,16 @@ 序号标记 + + + 融合的病灶 + + + + + 融向的病灶 + + 任务Id @@ -13413,6 +13430,13 @@ + + + 获取可合并的病灶 + + + + 保存影像质量 diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index 8cbbe14bb..89841ef0d 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -451,7 +451,8 @@ namespace IRaCIS.Core.Application.Image.QA //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) .ProjectTo(_mapper.ConfigurationProvider); - var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(QCVisitViewModel.AuditState) +" asc" }; + var defalutSortArray = new string[] { nameof(QCVisitViewModel.IsUrgent) + " desc", nameof(QCVisitViewModel.SubjectId), nameof(QCVisitViewModel.VisitNum) }; + //var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(QCVisitViewModel.AuditState) +" asc" }; var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray); diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index ace138aac..c6c8c9ddb 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -297,18 +297,50 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public List CrterionDictionaryGroup { get; set; } } - public class MergeLesionInDto + + public class GetCanMergeLesionOutDto + { + public Guid RowId { get; set; } + + public string OrderMarkName { get; set; } + + public Guid? OrganInfoId { get; set; } + + public decimal RowIndex { get; set; } + + public string Part { get; set; } + } + + + public class GetCanMergeLesionInDto + { + public Guid RowId { get; set; } + } + + public class MergeLesionInDto { public Guid VisitTaskId { get; set; } public Guid QuestionId { get; set; } - public Guid MainRowId { get; set; } - + + /// + /// 融合的病灶 + /// public Guid MergeRowId { get; set; } + /// + /// 融向的病灶 + /// + public List MeltingInToLesionList { get; set; } - } + ///// + ///// 融合后病灶状态 + ///// + //public string LesionState { get; set; } + + + } public class SplitLesionInDto { @@ -986,7 +1018,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public int? OtherNumberOfFrames { get; set; } - } + + public SplitOrMergeType? SplitOrMergeType { get; set; } + + } public class GetTableAnswerRowInfoInDto { diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 626f5effc..6e5d247f7 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -17,6 +17,7 @@ using IRaCIS.Core.Application.Filter; using DocumentFormat.OpenXml.Drawing; using EasyCaching.Core; using DocumentFormat.OpenXml.Drawing.Charts; +using IRaCIS.Core.Application.Service.ReadingCalculate.Interface; namespace IRaCIS.Application.Services { @@ -48,7 +49,8 @@ namespace IRaCIS.Application.Services private readonly IRepository _trialDocumentRepository; private readonly IRepository _userRepository; private readonly IEasyCachingProvider _provider; - private readonly IRepository _readingCustomTagRepository; + private readonly ILuganoCalculateService _luganoCalculateService; + private readonly IRepository _readingCustomTagRepository; private readonly IRepository _readingTaskQuestionMarkRepository; private readonly IRepository _readingCriterionDictionaryRepository; private readonly IRepository _readingTrialCriterionDictionaryRepository; @@ -88,7 +90,8 @@ namespace IRaCIS.Application.Services IRepository trialDocumentRepository, IRepository userRepository, IEasyCachingProvider provider, - IRepository readingCustomTagRepository, + ILuganoCalculateService luganoCalculateService, + IRepository readingCustomTagRepository, IRepository readingTaskQuestionMarkRepository, IRepository readingCriterionDictionaryRepository, IRepository readingTrialCriterionDictionaryRepository, @@ -126,7 +129,8 @@ namespace IRaCIS.Application.Services this._trialDocumentRepository = trialDocumentRepository; this._userRepository = userRepository; this._provider = provider; - this._readingCustomTagRepository = readingCustomTagRepository; + this._luganoCalculateService = luganoCalculateService; + this._readingCustomTagRepository = readingCustomTagRepository; this._readingTaskQuestionMarkRepository = readingTaskQuestionMarkRepository; this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository; this._tumorAssessmentRepository = tumorAssessmentRepository; @@ -1360,6 +1364,7 @@ namespace IRaCIS.Application.Services answers.Add("RowIndex", x.ToString()); answers.Add("RowId", rowInfo==null?string.Empty: rowInfo.Id.ToString()); answers.Add("MarkTool", rowInfo.MarkTool); + answers.Add("MeltingInToLesionMarks", rowInfo.MeltingInToLesionMarks); answers.Add("StudyId", rowInfo.StudyId.ToString()); answers.Add("OrganInfoId", rowInfo.OrganInfoId.ToString()); answers.Add("IsFristAdd", (rowInfo.FristAddTaskId== TaskId).ToString()); @@ -1461,69 +1466,109 @@ namespace IRaCIS.Application.Services [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task MergeLesion(MergeLesionInDto inDto) { - await VerifyTaskIsSign(inDto.VisitTaskId); - await this.VerifyIsBaseLineTask(inDto.VisitTaskId); + await VerifyTaskIsSign(inDto.VisitTaskId); + await this.VerifyIsBaseLineTask(inDto.VisitTaskId); + var mergeRow = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.MergeRowId).FirstNotNullAsync(); - var rowsInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && (x.Id == inDto.MainRowId || x.Id == inDto.MergeRowId)).ToListAsync(); + var meltingRows = await _readingTableAnswerRowInfoRepository.Where(x => inDto.MeltingInToLesionList.Contains(x.Id)).Include(x => x.ReadingQuestionTrial).ToListAsync(); - if (rowsInfo.Count != 2) + List marks = meltingRows.OrderBy(x => x.RowIndex).Select(x => x.ReadingQuestionTrial.OrderMark + x.RowIndex.GetLesionMark()).ToList(); + + await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.RowId == mergeRow.Id && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State, x => new ReadingTableQuestionAnswer() + { + Answer = TargetState.Loss.GetEnumInt(), + }); + + + await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(inDto.MergeRowId, x => new ReadingTableAnswerRowInfo() { - throw new BusinessValidationFailedException(_localizer["ReadingImage_NotaTask"]); - } + MeltingInToLesion = JsonConvert.SerializeObject(inDto.MeltingInToLesionList), + MeltingInToLesionMarks = string.Join(',', marks), - - var minaid = rowsInfo.Where(x => x.Id == inDto.MainRowId).Select(x => x.Id).FirstOrDefault(); - var mergeid = rowsInfo.Where(x => x.Id == inDto.MergeRowId).Select(x => x.Id).FirstOrDefault(); - - List needRemoveMark = new List() - { - QuestionMark.MajorAxis, - QuestionMark.ShortAxis, - }; - - var mainAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == minaid).Include(x => x.ReadingTableQuestionTrial).ToListAsync(); - - foreach (var item in mainAnswer) - { - await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.RowId == mergeid && x.TableQuestionId == item.TableQuestionId, x => new ReadingTableQuestionAnswer() - { - Answer = needRemoveMark.Contains(item.ReadingTableQuestionTrial.QuestionMark) ? string.Empty : item.Answer, - }); - } - - - - await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(mergeid, x => new ReadingTableAnswerRowInfo() - { - MergeRowId = minaid, SplitOrMergeType = SplitOrMergeType.Merge, - }); + }) ; + await _readingTableAnswerRowInfoRepository.SaveChangesAsync(); - - await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(mergeid, x => new ReadingTableAnswerRowInfo() - { - MergeRowId = minaid, - SplitOrMergeType = SplitOrMergeType.Merge, - }); - - await _readingTableAnswerRowInfoRepository.SaveChangesAsync(); - - - } - - - #endregion - - - - #region 访视任务 - Dicom 阅片 提交、修改 + await this._readingCalculateService.CalculateTask(new CalculateTaskInDto() + { + IsChangeOtherTask = false, + VisitTaskId = inDto.VisitTaskId, + ComputationTrigger = ComputationTrigger.Lesion, + }); + } /// - /// 保存影像质量 + /// 获取可合并的病灶 /// /// /// [HttpPost] + public async Task> GetCanMergeLesion(GetCanMergeLesionInDto inDto) + { + var rowinfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).Include(x=>x.ReadingQuestionTrial).FirstNotNullAsync(); + + // 需要排除的状态 + var needFilterState = new List(); + + switch (rowinfo.ReadingQuestionTrial.LesionType) + { + //状态为“消失”、“无法评估”的靶病灶不可融合; + case LesionType.TargetLesion: + needFilterState = new List() { + TargetState.Loss.GetEnumInt(), + TargetState.UnableEvaluate.GetEnumInt(), + }; + + break; + + } + + + var result = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == rowinfo.VisitTaskId && x.QuestionId == rowinfo.QuestionId && x.Id != rowinfo.Id) + // 筛选状态 + .Where(x => x.LesionAnswerList.Any(y => y.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && !needFilterState.Contains(y.Answer))) + .Where(x=>x.SplitOrMergeType!=SplitOrMergeType.Split&&x.SplitOrMergeType!=SplitOrMergeType.SplitMain) + .Select(x => new GetCanMergeLesionOutDto() + { + RowId = x.Id, + RowIndex = x.RowIndex, + OrderMarkName = x.ReadingQuestionTrial.OrderMark + x.RowIndex.GetLesionMark(), + OrganInfoId = x.OrganInfoId + }).OrderBy(x=>x.RowIndex).ToListAsync(); + + var organIds = result.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList(); + var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync(); + + result.ForEach(x => + { + + if (_userInfo.IsEn_Us) + { + x.Part = organList.Where(y => y.Id == x.OrganInfoId).Select(y => y.PartEN).FirstIsNullReturnEmpty(); + + } + else + { + x.Part = organList.Where(y => y.Id == x.OrganInfoId).Select(y => y.Part).FirstIsNullReturnEmpty(); + } + }); + + return result; + + } + + #endregion + + + + #region 访视任务 - Dicom 阅片 提交、修改 + + /// + /// 保存影像质量 + /// + /// + /// + [HttpPost] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task SaveImageQuality(ChangeDicomReadingQuestionAnswerInDto inDto) { @@ -1808,9 +1853,7 @@ namespace IRaCIS.Application.Services public async Task SubmitTableQuestion(SubmitTableQuestionInDto inDto) { SubmitTableQuestionOutDto result = new SubmitTableQuestionOutDto(); - await VerifyTaskIsSign(inDto.VisitTaskId); - if (inDto.InstanceId != null && inDto.IsDicomReading) { if (!(await _dicomInstanceRepository.AnyAsync(x => x.Id == inDto.InstanceId && x.SeriesId == inDto.SeriesId))) @@ -1968,24 +2011,20 @@ namespace IRaCIS.Application.Services break; } - var questionInfo = await _readingQuestionTrialRepository.Where(x => x.Id == inDto.QuestionId).FirstNotNullAsync(); var criterionId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.TrialReadingCriterionId).FirstOrDefaultAsync(); var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == criterionId).FirstNotNullAsync(); var tableQuestionIds = inDto.AnswerList.Select(x => x.TableQuestionId).ToList(); var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == inDto.RowId).ToListAsync(); - var tableQuestionIdGroup = tableQuestionIds.GroupBy(x => new { TableQuestionId = x }).Select(x => new TableQuestionData { TableQuestionId = x.Key.TableQuestionId, Count = x.Count() }).ToList(); - if (tableQuestionIdGroup.Any(x => x.Count > 1)) { throw new BusinessValidationFailedException(_localizer["ReadingImage_Twice"]); } - if (inDto.RowIndex % 1 == 0) { @@ -2105,15 +2144,11 @@ namespace IRaCIS.Application.Services { isCurrentTaskAdd = isCurrentTaskAddList[0]; } - - ReadingTableAnswerRowInfo? rowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == (inDto.RowId ?? default(Guid))).IgnoreAutoIncludes().FirstOrDefaultAsync(); - rowInfo = rowInfo == null ? new ReadingTableAnswerRowInfo() : rowInfo; //await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.RowId == (inDto.RowId ?? default(Guid))); //await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.Id == (inDto.RowId ?? default(Guid))); - _mapper.Map(inDto, rowInfo); rowInfo.Id = inDto.RowId == null ? NewId.NextGuid() : inDto.RowId.Value; result.RowId = rowInfo.Id; @@ -2145,7 +2180,6 @@ namespace IRaCIS.Application.Services await _readingTableQuestionAnswerRepository.AddRangeAsync(answerList); } - else { await _readingTableAnswerRowInfoRepository.UpdateFromDTOAsync(inDto) ; @@ -2180,7 +2214,6 @@ namespace IRaCIS.Application.Services } - await _readingTableAnswerRowInfoRepository.SaveChangesAsync(); await this._readingCalculateService.CalculateTask(new CalculateTaskInDto() { @@ -2189,10 +2222,23 @@ namespace IRaCIS.Application.Services ComputationTrigger = ComputationTrigger.Lesion, }); + // 保存完了计算疾病进展 + switch (taskinfo.TrialReadingCriterion.CriterionType) + { + case CriterionType.Lugano2014: + if (inDto.RowIndex % 1 != 0) + { + await _luganoCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto() + { + QuestionId = inDto.QuestionId, + VisitTaskId = inDto.VisitTaskId, + RowNumber = inDto.RowIndex + }); + } + break; + } - - - return result; + return result; } diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/Interface/ILuganoCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/Interface/ILuganoCalculateService.cs new file mode 100644 index 000000000..6ee6012e7 --- /dev/null +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/Interface/ILuganoCalculateService.cs @@ -0,0 +1,19 @@ +using IRaCIS.Core.Application.ViewModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.Service.ReadingCalculate.Interface +{ + public interface ILuganoCalculateService + { + /// + /// 计算靶病灶状态 + /// + /// + /// + Task CalculateTargetLesionStatus(CalculateTargetLesionStatusInDto inDto); + } +} diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs index c7d12d6c6..40a9ce076 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs @@ -14,13 +14,15 @@ using System.Reflection.Metadata.Ecma335; using System.Linq; using NPOI.SS.Formula.Functions; using DocumentFormat.OpenXml.Drawing.Charts; +using IRaCIS.Core.Application.Contracts; +using IRaCIS.Core.Application.Service.ReadingCalculate.Interface; namespace IRaCIS.Core.Application.Service.ReadingCalculate { [ApiExplorerSettings(GroupName = "Reading")] - public class LuganoCalculateService : BaseService, ICriterionCalculateService - { + public class LuganoCalculateService : BaseService, ICriterionCalculateService, ILuganoCalculateService + { private readonly IRepository _readingTableQuestionAnswerRepository; private readonly IRepository _visitTaskRepository; private readonly IRepository _readingQuestionCriterionTrialRepository; @@ -1096,6 +1098,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate tableRowAnswers.ForEach(x => { + x.SplitOrMergeType = x.SplitOrMergeType==SplitOrMergeType.Merge|| x.SplitOrMergeType == SplitOrMergeType.Merged? SplitOrMergeType.Merged : null; x.VisitTaskId = visitTaskId; x.IsCurrentTaskAdd = false; x.Id = NewId.NextGuid(); @@ -1103,7 +1106,9 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate x.InstanceId = null; x.MeasureData = string.Empty; x.PicturePath = string.Empty; - }); + + + }); tableRowAnswers.ForEach(x => { @@ -1168,20 +1173,32 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate }); } - var tableAnswers = copyTableAnswers.Select(x => new ReadingTableQuestionAnswer + var tableAnswers = new List(); + // 处理状态 + + var mergedRowIds = tableRowAnswers.Where(x => x.SplitOrMergeType == SplitOrMergeType.Merged).Select(x => x.Id).ToList(); + copyTableAnswers.ForEach(x => { - Id = NewId.NextGuid(), - Answer = needCopyMarks.Contains(x.QuestionMark) ? x.Answer : string.Empty, - QuestionId = x.QuestionId, - RowIndex = x.RowIndex, - RowId = tableRowAnswers.Where(y => y.OriginalId == x.RowId).Select(x => x.Id).FirstOrDefault(), - TableQuestionId = x.TableQuestionId, - TrialId = x.TrialId, - VisitTaskId = visitTaskId, + var tableAnswer = new ReadingTableQuestionAnswer() + { + Id = NewId.NextGuid(), + Answer = needCopyMarks.Contains(x.QuestionMark) ? x.Answer : string.Empty, + QuestionId = x.QuestionId, + RowIndex = x.RowIndex, + RowId = tableRowAnswers.Where(y => y.OriginalId == x.RowId).Select(x => x.Id).FirstOrDefault(), + TableQuestionId = x.TableQuestionId, + TrialId = x.TrialId, + VisitTaskId = visitTaskId, + }; + if (mergedRowIds.Contains(tableAnswer.RowId) && x.QuestionMark == QuestionMark.State) + { + tableAnswer.Answer = TargetState.Loss.GetEnumInt(); + + } + tableAnswers.Add(tableAnswer); }); - - var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == LastVisitTaskId).Select(x => new ReadingTaskQuestionMark() + var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == LastVisitTaskId).Select(x => new ReadingTaskQuestionMark() { VisitTaskId= visitTaskId, FirstAddTaskId=x.FirstAddTaskId, diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs index c403bbce3..07dca77ed 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs @@ -230,8 +230,12 @@ namespace IRaCIS.Application.Contracts public DateTime? DeletedTime { get; set; } + public DateTime? EnabledTime { get; set; } + public DateTime UpdateTime { get; set; } + public DateTime CreateTime { get; set; } + public string Site { get; set; } = String.Empty; public string SiteCode { get; set; } = String.Empty; diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteService.cs index f8f5ed306..31808a25a 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteService.cs @@ -278,6 +278,16 @@ namespace IRaCIS.Core.Application.Services _mapper.Map(editTrialSiteCommand, dbEntity); + if (editTrialSiteCommand.IsDeleted) + { + dbEntity.EnabledTime = null; + + } + else + { + dbEntity.EnabledTime = DateTime.Now; + } + await _trialSiteRepository.SaveChangesAsync(); return ResponseOutput.Ok(); diff --git a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs index d492b9a32..6040c46b6 100644 --- a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs +++ b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs @@ -644,7 +644,7 @@ namespace IRaCIS.Core.Domain.Share Split = 0, /// - /// 合并 + /// 融合 /// Merge = 1, @@ -653,6 +653,10 @@ namespace IRaCIS.Core.Domain.Share /// SplitMain = 2, + /// + /// 融合过 再之前任务融合了 + /// + Merged=3, } /// diff --git a/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingTableAnswerRowInfo.cs b/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingTableAnswerRowInfo.cs index 4670ad302..d919544ef 100644 --- a/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingTableAnswerRowInfo.cs +++ b/IRaCIS.Core.Domain/Reading/ReadingFormAnswer/ReadingTableAnswerRowInfo.cs @@ -207,6 +207,29 @@ namespace IRaCIS.Core.Domain.Models /// public string MarkTool { get; set; } = string.Empty; + /// + /// 融向的病灶 + /// + public string MeltingInToLesion { get; set; } = "[]"; + + /// + /// 融向病灶的名称 + /// + public string MeltingInToLesionMarks { get; set; } = string.Empty; + + public List MeltingInToLesionList { get { + + try + { + return JsonConvert.DeserializeObject>(this.MeltingInToLesion); + } + catch (Exception) + { + + return new List(); + } + } } + [JsonIgnore] [ForeignKey("VisitTaskId")] diff --git a/IRaCIS.Core.Domain/TrialSiteUser/TrialSite.cs b/IRaCIS.Core.Domain/TrialSiteUser/TrialSite.cs index 3dc6ef9a7..26597de4b 100644 --- a/IRaCIS.Core.Domain/TrialSiteUser/TrialSite.cs +++ b/IRaCIS.Core.Domain/TrialSiteUser/TrialSite.cs @@ -22,6 +22,7 @@ namespace IRaCIS.Core.Domain.Models public bool IsDeleted { get; set; } public DateTime? DeletedTime { get; set; } + public DateTime? EnabledTime { get; set; } public Guid? DeleteUserId { get; set; }