|
|
|
|
@ -113,18 +113,18 @@ public class TrialStatService(
|
|
|
|
|
/// <param name="inQuery"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost]
|
|
|
|
|
public async Task<List<EfficacyEvaluationStatViewModel>> GetTrialEfficacyEvaluationStatList(EfficacyEvaluationQuery inQuery)
|
|
|
|
|
public async Task<IResponseOutput<List<EfficacyEvaluationStatViewModel>>> GetTrialEfficacyEvaluationStatList(EfficacyEvaluationQuery inQuery)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var trialReadingCriterionId = inQuery.TrialReadingCriterionId;
|
|
|
|
|
|
|
|
|
|
//每次查询必须是单标准的
|
|
|
|
|
var criterion = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == trialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionGroup, t.IsGlobalReading, t.IsArbitrationReading, t.IsOncologyReading, t.CriterionName, t.ArbitrationRule,t.TrialId }).FirstNotNullAsync();
|
|
|
|
|
var criterion = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == trialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionGroup, t.IsGlobalReading, t.IsArbitrationReading, t.IsOncologyReading, t.CriterionName, t.ArbitrationRule, t.TrialId }).FirstNotNullAsync();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (criterion.CriterionGroup == CriterionGroup.Nontumorous)
|
|
|
|
|
{
|
|
|
|
|
return new List<EfficacyEvaluationStatViewModel>();
|
|
|
|
|
return ResponseOutput.Ok(new List<EfficacyEvaluationStatViewModel>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -132,15 +132,18 @@ public class TrialStatService(
|
|
|
|
|
if (criterion.CriterionType == CriterionType.RECIST1Point1 || criterion.CriterionType == CriterionType.RECIST1Pointt1_MB
|
|
|
|
|
|| criterion.CriterionType == CriterionType.IRECIST1Point1 || criterion.CriterionType == CriterionType.mRECISTHCC)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
questionType = QuestionType.Tumor;
|
|
|
|
|
|
|
|
|
|
//iresist pfs 是icpd
|
|
|
|
|
}
|
|
|
|
|
else if (criterion.CriterionType == CriterionType.Lugano2014 || criterion.CriterionType == CriterionType.Lugano2014WithoutPET)
|
|
|
|
|
else if (criterion.CriterionType == CriterionType.Lugano2014)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
questionType = QuestionType.ImgOncology;
|
|
|
|
|
}
|
|
|
|
|
else if (criterion.CriterionType == CriterionType.Lugano2014WithoutPET)
|
|
|
|
|
{
|
|
|
|
|
questionType = QuestionType.CTandMRI;
|
|
|
|
|
}
|
|
|
|
|
else if (criterion.CriterionType == CriterionType.PCWG3)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
@ -164,6 +167,8 @@ public class TrialStatService(
|
|
|
|
|
ReadingCategory = t.ReadingCategory,
|
|
|
|
|
ArmEnum = t.ArmEnum,
|
|
|
|
|
JudgeArmEnum = t.JudgeResultTask.ArmEnum,
|
|
|
|
|
LatestScanDate = t.SourceSubjectVisit.LatestScanDate,
|
|
|
|
|
EarliestScanDate = t.SourceSubjectVisit.EarliestScanDate,
|
|
|
|
|
|
|
|
|
|
IsTrigerJudge = criterion.ArbitrationRule == ArbitrationRule.Visit ? t.JudgeVisitTaskId != null :
|
|
|
|
|
(criterion.ArbitrationRule == ArbitrationRule.Reading ?
|
|
|
|
|
@ -176,7 +181,7 @@ public class TrialStatService(
|
|
|
|
|
|
|
|
|
|
DictionaryCode = t.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == questionType).Select(t => t.ReadingQuestionTrial.DictionaryCode).FirstOrDefault(),
|
|
|
|
|
//整体肿瘤评估答案
|
|
|
|
|
OverallTumorEvaluation = t.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == questionType).FirstOrDefault()!.Answer
|
|
|
|
|
OverallTumorEvaluation = t.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == questionType).Select(t => t.IsGlobalChange ? t.GlobalChangeAnswer : t.Answer).FirstOrDefault()
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -201,6 +206,24 @@ public class TrialStatService(
|
|
|
|
|
//处理裁判标记
|
|
|
|
|
list = DealJudgeMark(criterion.ArbitrationRule, criterion.IsGlobalReading, list);
|
|
|
|
|
|
|
|
|
|
//基线(最晚拍片日期)-首次PD(所有触发PD的病灶的检查的最早拍片日期)的中位数,单位是天
|
|
|
|
|
|
|
|
|
|
// 构建字典:SubjectCode -> LatestScanDate
|
|
|
|
|
var baseLineDict = list.Where(t => t.VisitTaskNum == 0).GroupBy(t => t.SubjectCode)
|
|
|
|
|
.ToDictionary(
|
|
|
|
|
g => g.Key,
|
|
|
|
|
g => g.First().LatestScanDate // 如果同一个 SubjectCode 有多条记录,只取第一条
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
//一定要两个人做完了,产生了裁判并且有结果的,否则就不算,并且排除基线
|
|
|
|
|
list = list.Where(t => t.IsJudgeSelect == true && t.VisitTaskNum != 0 && t.ReadingCategory==ReadingCategory.Visit)//全局的答案已经放在对应访视上了
|
|
|
|
|
.GroupBy(t => t.SubjectCode).Select(g => g.OrderByDescending(t => t.VisitTaskNum).First()).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//总subject 数量
|
|
|
|
|
var totalSubjectCount = list.Select(t => t.SubjectId).Distinct().Count();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//判断subject的逻辑需要确认,这么多次访视任务,有的符合,有的不符合,准则是什么?
|
|
|
|
|
@ -208,30 +231,69 @@ public class TrialStatService(
|
|
|
|
|
{
|
|
|
|
|
DictionaryCode = g.FirstOrDefault()?.DictionaryCode,
|
|
|
|
|
OverallTumorEvaluation = g.Key,
|
|
|
|
|
SubjectCount = g.Select(t => t.SubjectId).Distinct().Count()
|
|
|
|
|
Code = g.Key,
|
|
|
|
|
SubjectCodeList = g.Select(t => t.SubjectCode).Distinct().ToList()
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 先把 resultList 转成内存字典
|
|
|
|
|
var resultDict = resultList.ToDictionary(r => r.OverallTumorEvaluation, r => r.SubjectCount);
|
|
|
|
|
var resultDict = resultList.ToDictionary(r => r.OverallTumorEvaluation, r => r.SubjectCodeList);
|
|
|
|
|
|
|
|
|
|
// 查询字典表,先把数据拉出来到内存,再合并
|
|
|
|
|
var dicList = _dictionaryRepository
|
|
|
|
|
var translateList = _dictionaryRepository
|
|
|
|
|
.Where(t => t.Parent.Code == dicName)
|
|
|
|
|
.Select(t => new
|
|
|
|
|
{
|
|
|
|
|
t.Code
|
|
|
|
|
t.Code,
|
|
|
|
|
t.Value,
|
|
|
|
|
})
|
|
|
|
|
.ToList()
|
|
|
|
|
.ToList()
|
|
|
|
|
.Select(t => new EfficacyEvaluationStatViewModel
|
|
|
|
|
{
|
|
|
|
|
DictionaryCode = dicName,
|
|
|
|
|
OverallTumorEvaluation = t.Code,
|
|
|
|
|
SubjectCount = resultDict.ContainsKey(t.Code) ? resultDict[t.Code] : 0
|
|
|
|
|
Code = t.Code, //方便找到首次PD的日期
|
|
|
|
|
OverallTumorEvaluation = t.Value,//翻译后的值
|
|
|
|
|
SubjectCodeList = resultDict.ContainsKey(t.Code) ? resultDict[t.Code] : new List<string>()
|
|
|
|
|
})
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
return dicList;
|
|
|
|
|
// (cr +pr) /总人数
|
|
|
|
|
|
|
|
|
|
var crAddPr = translateList.Where(t => t.OverallTumorEvaluation == "PR" || t.OverallTumorEvaluation == "CR").Sum(t => t.SubjectCount);
|
|
|
|
|
|
|
|
|
|
var orrPercent = totalSubjectCount > 0
|
|
|
|
|
? ((decimal)crAddPr / totalSubjectCount * 100).ToString("0.00") + "%"
|
|
|
|
|
: "0.00%";
|
|
|
|
|
|
|
|
|
|
var pdInfo = translateList
|
|
|
|
|
.WhereIf(criterion.CriterionType == CriterionType.IRECIST1Point1, t => t.OverallTumorEvaluation == "ICPD")
|
|
|
|
|
.WhereIf(criterion.CriterionType == CriterionType.IRECIST1Point1, t => t.OverallTumorEvaluation == "PD")
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
var firstPdList = new List<FirstPdInfo>();
|
|
|
|
|
if (pdInfo != null)
|
|
|
|
|
{
|
|
|
|
|
firstPdList = list.Where(t => t.OverallTumorEvaluation == pdInfo.Code).GroupBy(t => t.SubjectCode)
|
|
|
|
|
.Select(g => new FirstPdInfo
|
|
|
|
|
{
|
|
|
|
|
SubjectCode = g.Key,
|
|
|
|
|
EarliestScanDate = g.Where(t => t.OverallTumorEvaluation == pdInfo.Code).OrderBy(t => t.VisitTaskNum).First().EarliestScanDate
|
|
|
|
|
})
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
foreach (var item in firstPdList)
|
|
|
|
|
{
|
|
|
|
|
if (baseLineDict.TryGetValue(item.SubjectCode, out var latestScanDate))
|
|
|
|
|
{
|
|
|
|
|
item.BaseLineLatestScanDate = latestScanDate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ResponseOutput.Ok(translateList, new { PDList = firstPdList, ORR = orrPercent });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|