diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
index d497e69d9..14dda6423 100644
--- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
+++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
@@ -4847,11 +4847,26 @@
-
+
+
+ 获取肿瘤评估 逻辑抽离 这里还要返回上一次的结果
+
+
+
+
+
+
+
+ 前端获取访视点肿瘤评估
+
+
+
+
修改上一次访视结果 并且计算是不是PD
+
diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs
index b6451ed74..f455f55a7 100644
--- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs
+++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs
@@ -319,8 +319,42 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
}
+ public class FrontGetSiteVisitForTumorEvaluationInDto
+ {
+ public Guid VisitTaskId { get; set; }
+ public int NumberOfDaysBetween { get; set; }
+ }
+ public class FrontGetSiteVisitForTumorEvaluationOutDto
+ {
+ public List ResultList { get; set; }
+ }
+ public class FrontGetSiteVisitForTumor
+ {
+ public Guid VisitTaskId { get; set; }
+
+ public string TumorEvaluationResult { get; set; }=string.Empty;
+ }
+
+ public class SiteVisitForTumorEvaluationByDayOutDto
+ {
+ public string Result{ get; set; }=string.Empty;
+
+ public string? LastTaskResult { get; set; }
+
+ public Guid? LastTaskId { get; set; }
+
+ }
+
+ public class PCWGSiteVisitForTumor
+ {
+ public bool IsPD { get; set; }
+
+ public string? LastTaskResult { get; set; }
+
+ public Guid? LastTaskId { get; set; }
+ }
///
/// 阅片计算Dto
@@ -399,6 +433,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
///
public string Answer { get; set; }
+ public string PCWGInterimAnswer { get; set; }
+
///
/// 问题名称
///
diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/General/GeneralCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/General/GeneralCalculateService.cs
index d042403ea..17fa0e2cf 100644
--- a/IRaCIS.Core.Application/Service/ReadingCalculate/General/GeneralCalculateService.cs
+++ b/IRaCIS.Core.Application/Service/ReadingCalculate/General/GeneralCalculateService.cs
@@ -207,7 +207,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
var questionAnswers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Select(x => new
{
x.ReadingQuestionTrialId,
- x.Answer
+ x.Answer,
+ x.PCWGInterimAnswer,
}).ToListAsync();
var tableQuestion = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Include(x => x.ReadingTableQuestionTrial).Select(x => new TableQuestionInfo()
@@ -226,7 +227,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
item.Answer = questionAnswers.Where(y => y.ReadingQuestionTrialId == item.QuestionId).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
-
+ item.PCWGInterimAnswer = questionAnswers.Where(y => y.ReadingQuestionTrialId == item.QuestionId).Select(x => x.PCWGInterimAnswer).FirstOrDefault() ?? string.Empty;
var thisItemRowInfo = rowInfoList.Where(x => x.QuestionId == item.QuestionId).ToList();
var thisItemTableQuestions = tableQuestion.Where(x => x.QuestionId == item.QuestionId).ToList();
diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/PCWG3CalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/PCWG3CalculateService.cs
index 090b46956..76b639edf 100644
--- a/IRaCIS.Core.Application/Service/ReadingCalculate/PCWG3CalculateService.cs
+++ b/IRaCIS.Core.Application/Service/ReadingCalculate/PCWG3CalculateService.cs
@@ -1,8 +1,11 @@
-using IRaCIS.Application.Contracts;
+using DocumentFormat.OpenXml.Spreadsheet;
+using DocumentFormat.OpenXml.Vml.Spreadsheet;
+using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
+using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
@@ -12,6 +15,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using MiniSoftware;
+using NPOI.SS.Formula.Functions;
using System.Runtime.InteropServices;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
@@ -753,6 +757,14 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
public async Task TestCalculate(Guid visitTaskId, QuestionType type)
{
ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(visitTaskId);
+ // 只获取当前的 不会获取上一次临时修改的结果
+ foreach (var item in readingData.QuestionInfo)
+ {
+ if (item.PCWGInterimAnswer != string.Empty)
+ {
+ item.Answer = item.PCWGInterimAnswer;
+ }
+ }
await ReadingCalculate(readingData, new List() { type });
}
@@ -765,6 +777,14 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
public async Task CalculateTask(CalculateTaskInDto inDto)
{
ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId);
+ // 只获取当前的 不会获取上一次临时修改的结果
+ foreach (var item in readingData.QuestionInfo)
+ {
+ if (item.PCWGInterimAnswer != string.Empty)
+ {
+ item.Answer = item.PCWGInterimAnswer;
+ }
+ }
readingData.IsChangeOtherTask = inDto.IsChangeOtherTask;
await ReadingCalculate(readingData);
}
@@ -1049,6 +1069,14 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
return -1;
}
+
+ // 这里的answer可能是临时结果了 有的话就不计算了
+ var daysBetween = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.DaysBetween).Select(x => x.Answer).FirstIsNullReturnEmpty();
+ if (daysBetween!=string.Empty)
+ {
+ return int.Parse(daysBetween);
+ }
+
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var taskList = await GetSiteVisitForTumorList(inDto);
var lastTask = taskList.Where(x => x.VisitTaskNum < taskinfo.VisitTaskNum && x.VisitTaskId != inDto.VisitTaskId).OrderByDescending(x => x.VisitTaskNum).FirstOrDefault();
@@ -1084,57 +1112,122 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
///
public async Task GetSiteVisitForTumorEvaluation(ReadingCalculateDto inDto)
{
+ return (await GetSiteVisitForTumorEvaluationByDay(inDto)).Result;
+ }
+
+ ///
+ /// 获取肿瘤评估 逻辑抽离 这里还要返回上一次的结果
+ ///
+ ///
+ ///
+ ///
+ public async Task GetSiteVisitForTumorEvaluationByDay(ReadingCalculateDto inDto, int? daysBetween = null)
+ {
+ SiteVisitForTumorEvaluationByDayOutDto result= new SiteVisitForTumorEvaluationByDayOutDto();
if (inDto.IsBaseLine)
{
- return VisitTumorEvaluation.NA.GetEnumInt();
+ result.Result= VisitTumorEvaluation.NA.GetEnumInt();
+ return result;
}
//如果日期未知,不需要计算肿瘤评估结果;
if (await GetNumberOfDaysBetween(inDto) == -1)
{
- return string.Empty;
+ result.Result = string.Empty;
+ return result;
}
if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ImageQualityAssessment && x.Answer == ImageQualityEvaluation.Abnormal.GetEnumInt()))
{
//影像质量不正常
- return VisitTumorEvaluation.NE.GetEnumInt();
+ result.Result = VisitTumorEvaluation.NE.GetEnumInt();
+ return result;
}
- var isPD = await ChangeLastTaskSiteVisitForTumorEvaluation(inDto);
+ var pdResult = await ChangeLastTaskSiteVisitForTumorEvaluation(inDto, daysBetween);
+
+ // 这里为什么要这样写 因为要把上一次的也返回前端去 前端要修改
+ result.LastTaskResult = pdResult.LastTaskResult;
+ result.LastTaskId = pdResult.LastTaskId;
+
var newLesionsCount = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesionsCount).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
var baseLineLesionsCount = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.BaseLineLesionsCount).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
var alwaysNewLesionsCount = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.AlwaysNewLesionsCount).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
- if (isPD)
+ if (pdResult.IsPD)
{
- return VisitTumorEvaluation.PD.GetEnumInt();
+ result.Result = VisitTumorEvaluation.PD.GetEnumInt();
}
else if (newLesionsCount == 0 &&
baseLineLesionsCount == 0 &&
alwaysNewLesionsCount == 0)
{
- return VisitTumorEvaluation.ND.GetEnumInt();
+ result.Result = VisitTumorEvaluation.ND.GetEnumInt();
}
else
{
- return VisitTumorEvaluation.NoPD.GetEnumInt();
+ result.Result = VisitTumorEvaluation.NoPD.GetEnumInt();
}
+
+ return result;
}
+ ///
+ /// 前端获取访视点肿瘤评估
+ ///
+ ///
+ [HttpPost]
+ public async Task FrontGetSiteVisitForTumorEvaluation(FrontGetSiteVisitForTumorEvaluationInDto inDto)
+ {
+ ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId);
+ // 只获取当前的 不会获取上一次临时修改的结果
+ foreach (var item in readingData.QuestionInfo)
+ {
+ if (item.PCWGInterimAnswer != string.Empty)
+ {
+ item.Answer = item.PCWGInterimAnswer;
+ }
+ }
+ FrontGetSiteVisitForTumorEvaluationOutDto result = new FrontGetSiteVisitForTumorEvaluationOutDto();
+
+
+
+ var tumorEvaluation= await GetSiteVisitForTumorEvaluationByDay(readingData, inDto.NumberOfDaysBetween);
+
+ result.ResultList = new List() {
+ new FrontGetSiteVisitForTumor(){
+ VisitTaskId=inDto.VisitTaskId,
+ TumorEvaluationResult=tumorEvaluation.Result,
+ }
+ };
+ if (tumorEvaluation.LastTaskResult != null && tumorEvaluation.LastTaskId != null)
+ {
+ result.ResultList.Add(new FrontGetSiteVisitForTumor()
+ {
+ VisitTaskId = tumorEvaluation.LastTaskId.Value,
+ TumorEvaluationResult = tumorEvaluation.LastTaskResult,
+ });
+ }
+
+ return result;
+ }
+
+
///
/// 修改上一次访视结果 并且计算是不是PD
///
///
+ ///
///
- public async Task ChangeLastTaskSiteVisitForTumorEvaluation(ReadingCalculateDto inDto)
+ public async Task ChangeLastTaskSiteVisitForTumorEvaluation(ReadingCalculateDto inDto, int? numOfDaysBetween)
{
+ PCWGSiteVisitForTumor result = new PCWGSiteVisitForTumor() {
+ IsPD=false,
+ };
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var taskList = await GetSiteVisitForTumorList(inDto);
var lastTask = taskList.Where(x => x.VisitTaskNum < taskinfo.VisitTaskNum && x.VisitTaskId != inDto.VisitTaskId).OrderByDescending(x => x.VisitTaskNum).FirstOrDefault();
var baseLineTask = taskList.OrderBy(x => x.VisitTaskNum).FirstOrDefault();
- var newLesionsCountQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesionsCount).Select(x => x.QuestionId).FirstOrDefault();
- var isPDResult = false;
// 先判断有没有上一个任务
if (lastTask != null)
@@ -1142,63 +1235,129 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
// 查看历史有没有PD
var taskIdList = taskList.Select(x => x.VisitTaskId).ToList();
- var pdTaskList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId!=inDto.VisitTaskId&& taskIdList.Contains(x.VisitTaskId) && x.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation && x.Answer == VisitTumorEvaluation.PD.GetEnumInt()).OrderByDescending(x=>x.VisitTask.VisitTaskNum).ToListAsync();
-
+ // pd的任务列表
+ var pdTaskList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId != inDto.VisitTaskId && taskIdList.Contains(x.VisitTaskId) && x.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation && x.Answer == VisitTumorEvaluation.PD.GetEnumInt()).OrderByDescending(x => x.VisitTask.VisitTaskNum).ToListAsync();
+
+ // 自治疗后第二个访视点以来持续的新骨变数量
+ var thisNewBoneLesionsCount = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewBoneLesionsCount).Select(x => x.Answer).FirstIsNullReturnEmpty().IsNullOrEmptyReturn0();
+
+ // 当前任务的BL-BTN
+ var thisBTN = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.BaseLineLesionsCount).Select(x => x.Answer).FirstIsNullReturnEmpty().IsNullOrEmptyReturn0();
+
// 当前访视新病灶数量
- var thisNewLesionsCount = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesionsCount).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
+ var thisNewLesionsCount = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesionsCount).Select(x => x.Answer).FirstIsNullReturnEmpty().IsNullOrEmptyReturn0();
+
+ // 其他访视的BTN
+ var otherBTNStrList =await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId != inDto.VisitTaskId && taskIdList.Contains(x.VisitTaskId) && x.ReadingQuestionTrial.QuestionType == QuestionType.BaseLineLesionsCount).Select(x=>new {
+ x.VisitTask.VisitTaskNum,
+ x.Answer,
+ }).ToListAsync();
+
+ // 最小的BTN 这个时候再转为int 避免查询报错
+ var othenMinBTNCount= otherBTNStrList.Select(x => x.Answer.IsNullOrEmptyReturn0()).Min();
+
// 历史有PD
- if (pdTaskList.Count() > 0&& thisNewLesionsCount >= 2)
+ if (pdTaskList.Count() > 0)
{
- // 满足以下所有条件:1、前序访视已经确定为PD;2、当前访视,新病灶≥2个;
- isPDResult = true;
- }
- else
- {
- // 满足以下所有条件:1、前序访视没有评估为PD,2、前一个访视:新病灶计数≥2个;3、当前访视:新病灶2个:4.前后2个访视间隔6周以上。
-
- var lastStudyDate = taskList.Where(x=>x.VisitTaskId==lastTask.VisitTaskId).Select(x=>x.StudyTime).FirstOrDefault();
- var thisStudyDate= taskList.Where(x => x.VisitTaskId == inDto.VisitTaskId).Select(x => x.StudyTime).FirstOrDefault();
-
- var lastNewLesionsStr=await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTask.VisitTaskId && x.ReadingQuestionTrialId == newLesionsCountQuestionId).Select(x => x.Answer).FirstOrDefaultAsync();
-
- var lastNewLesionsCount = lastNewLesionsStr.IsNullOrEmptyReturn0();
- if (lastStudyDate != null && thisStudyDate != null)
+ // 当前访视:自治疗后第二个访视点以来持续的新骨变数量 + [(V3 - BTN - Min(V2 - BTN、V1 - BTN、BL - BTN)] + 新病灶 >= 2
+ if (thisNewBoneLesionsCount + thisBTN - othenMinBTNCount + thisNewLesionsCount >= 2)
{
- if (lastNewLesionsCount >= 2 && thisNewLesionsCount >= 2 && thisStudyDate.Value > lastStudyDate.Value.AddDays(42))
+ result.IsPD = true;
+ }
+
+
+ }
+ else
+ {
+ // 间隔天数
+ var daysBetween = numOfDaysBetween != null ? numOfDaysBetween.Value : await GetNumberOfDaysBetween(inDto);
+
+
+ // 上一次访视的新病灶数量
+ var lastNewLesionsCount = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTask.VisitTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.NewLesionsCount).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0();
+
+ // 之前不存在pd 又分为两种情况 在访视2 和 访视2以后
+ if (inDto.VisitTaskNum == 2)
+ {
+ // V1:新病灶计数>=2; V2:新病灶计数 >= 2; V2与V1的间隔 >= 6周
+ if (lastNewLesionsCount >= 2 && thisNewLesionsCount >= 2 && daysBetween >= 42)
+ {
+
+ result.IsPD = true;
+ }
+
+ }
+ else if (inDto.VisitTaskNum > 2)
+ {
+ // 上一个访视的BTN
+ var lastBTN = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTask.VisitTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.BaseLineLesionsCount).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0();
+
+ // 上上个访视的 最小BTN
+ var lastTwoBTN = otherBTNStrList.Where(x => x.VisitTaskNum < lastTask.VisitTaskNum).Select(x => x.Answer.IsNullOrEmptyReturn0()).Min();
+
+
+ // V2:新病灶计数+[(V2-BTN- Min(V1-BTN、BL-BTN)]>=2;
+ // V3:自治疗后第二个访视点以来持续的新骨变数量 + [(V3 - BTN - Min(V2 - BTN、V1 - BTN、BL - BTN)] + 新病灶 >= 2
+ // V3与V2的间隔 >= 6周
+
+ // 按上面条件写三个if看着清晰点
+ if (lastNewLesionsCount + lastBTN - lastTwoBTN >= 2)
+ {
+ if (thisNewBoneLesionsCount + thisBTN - othenMinBTNCount + thisNewLesionsCount >= 2)
+ {
+ if (daysBetween >= 42)
+ {
+ result.IsPD = true;
+ }
+ }
+ }
+
+ }
+
+
+ if (result.IsPD)
+ {
+ // 为 null 说明不是前端传的
+ if (numOfDaysBetween == null)
{
var visitForTumorEvaluationQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SiteVisitForTumorEvaluation).Select(x => x.QuestionId).FirstOrDefault();
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == lastTask.VisitTaskId && x.ReadingQuestionTrialId == visitForTumorEvaluationQuestionId, x => new ReadingTaskQuestionAnswer
{
PCWGInterimAnswer = VisitTumorEvaluation.PD.GetEnumInt(),
});
- isPDResult = true;
}
+ result.LastTaskResult= VisitTumorEvaluation.PD.GetEnumInt();
+ result.LastTaskId= lastTask.VisitTaskId;
+
+
}
-
- }
-
- }
-
- if (!isPDResult)
- {
- if (lastTask != null)
- {
- // 如果不是PD 需要把上一次的PD改为NoPD
- var visitForTumorEvaluationQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SiteVisitForTumorEvaluation).Select(x => x.QuestionId).FirstOrDefault();
-
- var lastAnswer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTask.VisitTaskId && x.ReadingQuestionTrialId == visitForTumorEvaluationQuestionId).FirstOrDefaultAsync();
- if (lastAnswer != null)
+ else
{
- await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.Id == lastAnswer.Id, x => new ReadingTaskQuestionAnswer
+ if (lastTask != null)
{
- PCWGInterimAnswer = string.Empty,
- });
+ if (numOfDaysBetween == null)
+ {
+ // 如果不是PD 需要把上一次的PD改为NoPD 这里去掉临时答案就是原始答案
+ await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == lastTask.VisitTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation, x => new ReadingTaskQuestionAnswer
+ {
+ PCWGInterimAnswer = string.Empty,
+ });
+ }
+
+ var lastTaskResult = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTask.VisitTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SiteVisitForTumorEvaluation).Select(x => x.Answer).FirstOrDefaultAsync();
+ result.LastTaskResult = lastTaskResult;
+ result.LastTaskId = lastTask.VisitTaskId;
+
+ }
+
}
-
+
}
-
+
}
- return isPDResult;
+
+
+ return result;
}
#endregion