修改导表结果

Test_IRC_Net8
hang 2025-12-19 17:06:39 +08:00
parent b4c884a367
commit 4aecfb3bed
3 changed files with 110 additions and 17 deletions

View File

@ -15707,7 +15707,7 @@
</member> </member>
<member name="M:IRaCIS.Core.Application.Helper.OSSService.DeleteFromPrefix(System.String,System.Boolean)"> <member name="M:IRaCIS.Core.Application.Helper.OSSService.DeleteFromPrefix(System.String,System.Boolean)">
<summary> <summary>
删除某个目录的文件 删除某个目录的文件 (包含单个文件oss单个文件需要去除前缀/)
</summary> </summary>
<param name="prefix"></param> <param name="prefix"></param>
<returns></returns> <returns></returns>

View File

@ -91,17 +91,48 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid? TrialSiteId { get; set; } public Guid? TrialSiteId { get; set; }
} }
public class FirstPdInfo
{
public string SubjectCode { get; set; }
public DateTime? EarliestScanDate { get; set; }
public DateTime? BaseLineLatestScanDate { get; set; }
// 新增属性:天数差
public double? DaysDiff
{
get
{
if (BaseLineLatestScanDate.HasValue && EarliestScanDate.HasValue)
{
return (EarliestScanDate.Value - BaseLineLatestScanDate.Value).TotalDays;
}
return null;
}
}
}
public class EfficacyEvaluationStatViewModel public class EfficacyEvaluationStatViewModel
{ {
public string? DictionaryCode { get; set; } public string? DictionaryCode { get; set; }
public string Code { get; set; }
public string OverallTumorEvaluation { get; set; } public string OverallTumorEvaluation { get; set; }
public int SubjectCount { get; set; } public int SubjectCount => SubjectCodeList.Count();
public List<string> SubjectCodeList { get; set; }
} }
public class EfficacyEvaluationExport public class EfficacyEvaluationExport
{ {
public DateTime? EarliestScanDate { get; set; }
public DateTime? LatestScanDate { get; set; }
public Guid Id { get; set; } public Guid Id { get; set; }

View File

@ -113,18 +113,18 @@ public class TrialStatService(
/// <param name="inQuery"></param> /// <param name="inQuery"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public async Task<List<EfficacyEvaluationStatViewModel>> GetTrialEfficacyEvaluationStatList(EfficacyEvaluationQuery inQuery) public async Task<IResponseOutput<List<EfficacyEvaluationStatViewModel>>> GetTrialEfficacyEvaluationStatList(EfficacyEvaluationQuery inQuery)
{ {
var trialReadingCriterionId = inQuery.TrialReadingCriterionId; 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) 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 if (criterion.CriterionType == CriterionType.RECIST1Point1 || criterion.CriterionType == CriterionType.RECIST1Pointt1_MB
|| criterion.CriterionType == CriterionType.IRECIST1Point1 || criterion.CriterionType == CriterionType.mRECISTHCC) || criterion.CriterionType == CriterionType.IRECIST1Point1 || criterion.CriterionType == CriterionType.mRECISTHCC)
{ {
questionType = QuestionType.Tumor; 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; questionType = QuestionType.ImgOncology;
} }
else if (criterion.CriterionType == CriterionType.Lugano2014WithoutPET)
{
questionType = QuestionType.CTandMRI;
}
else if (criterion.CriterionType == CriterionType.PCWG3) else if (criterion.CriterionType == CriterionType.PCWG3)
{ {
@ -164,6 +167,8 @@ public class TrialStatService(
ReadingCategory = t.ReadingCategory, ReadingCategory = t.ReadingCategory,
ArmEnum = t.ArmEnum, ArmEnum = t.ArmEnum,
JudgeArmEnum = t.JudgeResultTask.ArmEnum, JudgeArmEnum = t.JudgeResultTask.ArmEnum,
LatestScanDate = t.SourceSubjectVisit.LatestScanDate,
EarliestScanDate = t.SourceSubjectVisit.EarliestScanDate,
IsTrigerJudge = criterion.ArbitrationRule == ArbitrationRule.Visit ? t.JudgeVisitTaskId != null : IsTrigerJudge = criterion.ArbitrationRule == ArbitrationRule.Visit ? t.JudgeVisitTaskId != null :
(criterion.ArbitrationRule == ArbitrationRule.Reading ? (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(), 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); 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的逻辑需要确认这么多次访视任务有的符合有的不符合准则是什么 //判断subject的逻辑需要确认这么多次访视任务有的符合有的不符合准则是什么
@ -208,30 +231,69 @@ public class TrialStatService(
{ {
DictionaryCode = g.FirstOrDefault()?.DictionaryCode, DictionaryCode = g.FirstOrDefault()?.DictionaryCode,
OverallTumorEvaluation = g.Key, OverallTumorEvaluation = g.Key,
SubjectCount = g.Select(t => t.SubjectId).Distinct().Count() Code = g.Key,
SubjectCodeList = g.Select(t => t.SubjectCode).Distinct().ToList()
}).ToList(); }).ToList();
// 先把 resultList 转成内存字典 // 先把 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) .Where(t => t.Parent.Code == dicName)
.Select(t => new .Select(t => new
{ {
t.Code t.Code,
t.Value,
}) })
.ToList() .ToList()
.Select(t => new EfficacyEvaluationStatViewModel .Select(t => new EfficacyEvaluationStatViewModel
{ {
DictionaryCode = dicName, DictionaryCode = dicName,
OverallTumorEvaluation = t.Code, Code = t.Code, //方便找到首次PD的日期
SubjectCount = resultDict.ContainsKey(t.Code) ? resultDict[t.Code] : 0 OverallTumorEvaluation = t.Value,//翻译后的值
SubjectCodeList = resultDict.ContainsKey(t.Code) ? resultDict[t.Code] : new List<string>()
}) })
.ToList(); .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 });
} }