457 lines
21 KiB
C#
457 lines
21 KiB
C#
using IRaCIS.Core.Domain.Share;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using IRaCIS.Core.Application.Service.Reading.Dto;
|
|
using MassTransit;
|
|
using IRaCIS.Core.Infra.EFCore.Common;
|
|
using Panda.DynamicWebApi.Attributes;
|
|
using AutoMapper;
|
|
using IRaCIS.Core.Application.Contracts;
|
|
using IRaCIS.Core.Infrastructure;
|
|
using Newtonsoft.Json;
|
|
using IRaCIS.Core.Application.Service;
|
|
using IRaCIS.Core.Application.ViewModel;
|
|
using IRaCIS.Core.Application.Filter;
|
|
|
|
namespace IRaCIS.Application.Services
|
|
{
|
|
|
|
/// <summary>
|
|
/// 全局阅片
|
|
/// </summary>
|
|
public partial class ReadingImageTaskService : BaseService, IReadingImageTaskService
|
|
{
|
|
/// <summary>
|
|
/// 提交全局阅片结果
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
//[NonDynamicMethod]
|
|
public async Task<IResponseOutput> SubmitGlobalReadingInfo(SubmitGlobalReadingInfoInDto inDto)
|
|
{
|
|
//var result = await this.SaveGlobalReadingInfo(inDto);
|
|
await VerifyTaskIsSign(inDto.GlobalTaskId);
|
|
await this.SubmitTaskChangeState(inDto.GlobalTaskId);
|
|
|
|
return ResponseOutput.Ok(true);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 批量提交全局阅片信息
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
|
public async Task<IResponseOutput> BatchSubmitGlobalReadingInfo(BatchSubmitGlobalReadingInfo inDto)
|
|
{
|
|
await VerifyTaskIsSign(inDto.GlobalTaskId);
|
|
|
|
var criterionType = await _visitTaskRepository.Where(x => x.Id == inDto.GlobalTaskId).Select(x => x.TrialReadingCriterion.CriterionType).FirstNotNullAsync();
|
|
foreach (var item in inDto.VisitTaskAnswerList)
|
|
{
|
|
foreach (var answer in item.AnswerList)
|
|
{
|
|
await _readingGlobalTaskInfoRepository.BatchDeleteNoTrackingAsync(x => x.GlobalTaskId == inDto.GlobalTaskId && x.TaskId == item.VisitTaskId && x.GlobalAnswerType == answer.GlobalAnswerType && x.QuestionId == answer.QuestionId);
|
|
|
|
|
|
if (criterionType == CriterionType.PCWG3)
|
|
{
|
|
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == answer.QuestionId
|
|
&& x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null
|
|
, x => new ReadingTaskQuestionAnswer()
|
|
{
|
|
Answer= answer.Answer,
|
|
GlobalChangeAnswer = answer.Answer,
|
|
IsGlobalChange = true,
|
|
});
|
|
}
|
|
else
|
|
{
|
|
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == answer.QuestionId
|
|
&& x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null
|
|
, x => new ReadingTaskQuestionAnswer()
|
|
{
|
|
GlobalChangeAnswer = answer.Answer,
|
|
IsGlobalChange = true,
|
|
});
|
|
}
|
|
|
|
}
|
|
}
|
|
var answers= inDto.VisitTaskAnswerList.SelectMany(x => x.AnswerList.Select(y => new ReadingGlobalTaskInfo()
|
|
{
|
|
Answer = y.Answer,
|
|
QuestionId = y.QuestionId,
|
|
SubjectId = inDto.SubjectId,
|
|
GlobalTaskId = inDto.GlobalTaskId,
|
|
GlobalAnswerType = y.GlobalAnswerType,
|
|
TaskId = x.VisitTaskId,
|
|
TrialId = inDto.TrialId,
|
|
})).ToList();
|
|
|
|
await _readingGlobalTaskInfoRepository.AddRangeAsync(answers);
|
|
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == inDto.GlobalTaskId, u => new VisitTask() { ReadingTaskState = ReadingTaskState.Reading });
|
|
var result = await _readingGlobalTaskInfoRepository.SaveChangesAsync();
|
|
return ResponseOutput.Ok(result);
|
|
}
|
|
|
|
|
|
#region 全局阅片相关
|
|
/// <summary>
|
|
/// 保存全局阅片结果
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
|
public async Task<IResponseOutput> SaveGlobalReadingInfo(SaveGlobalReadingInfoInDto inDto)
|
|
{
|
|
await VerifyTaskIsSign(inDto.GlobalTaskId);
|
|
var visitTaskId = inDto.QuestionList.Select(x => x.VisitTaskId).FirstOrDefault();
|
|
|
|
foreach (var item in inDto.QuestionList)
|
|
{
|
|
|
|
await _readingGlobalTaskInfoRepository.BatchDeleteNoTrackingAsync(x => x.GlobalTaskId == inDto.GlobalTaskId && x.TaskId == visitTaskId && x.GlobalAnswerType == item.GlobalAnswerType && x.QuestionId == item.QuestionId);
|
|
|
|
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == item.QuestionId
|
|
&& x.Answer != item.Answer && item.Answer != string.Empty && item.Answer != null
|
|
, x => new ReadingTaskQuestionAnswer()
|
|
{
|
|
GlobalChangeAnswer = item.Answer,
|
|
IsGlobalChange = true,
|
|
});
|
|
}
|
|
|
|
await _readingGlobalTaskInfoRepository.AddRangeAsync(inDto.QuestionList.Select(x => new ReadingGlobalTaskInfo()
|
|
{
|
|
Answer = x.Answer,
|
|
QuestionId = x.QuestionId,
|
|
SubjectId = inDto.SubjectId,
|
|
GlobalTaskId = inDto.GlobalTaskId,
|
|
GlobalAnswerType = x.GlobalAnswerType,
|
|
TaskId = x.VisitTaskId,
|
|
TrialId = inDto.TrialId,
|
|
}).ToList());
|
|
|
|
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == inDto.GlobalTaskId, u => new VisitTask() { ReadingTaskState = ReadingTaskState.Reading });
|
|
|
|
var result = await _readingGlobalTaskInfoRepository.SaveChangesAsync();
|
|
return ResponseOutput.Ok(result);
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取全局阅片信息
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<GetGlobalReadingInfoOutDto> GetGlobalReadingInfo(GetGlobalReadingInfoInDto inDto)
|
|
{
|
|
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x=>x.Subject).FirstNotNullAsync();
|
|
if (taskInfo.ReadingCategory != ReadingCategory.Global)
|
|
{
|
|
throw new BusinessValidationFailedException(_localizer["ReadingGlobal_NotGlobal"]);
|
|
}
|
|
GetGlobalReadingInfoOutDto result = new GetGlobalReadingInfoOutDto()
|
|
{
|
|
GlobalTaskId = inDto.VisitTaskId,
|
|
ReadingTaskState = taskInfo.ReadingTaskState,
|
|
|
|
};
|
|
result.OtherGlobalTaskId = await _visitTaskRepository.Where(x => x.SouceReadModuleId == taskInfo.SouceReadModuleId && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate
|
|
&& x.IsSelfAnalysis == taskInfo.IsSelfAnalysis && x.TaskState == TaskState.Effect && x.DoctorUserId != taskInfo.DoctorUserId
|
|
).Select(x => x.Id).FirstOrDefaultAsync();
|
|
|
|
result.TaskBlindName = taskInfo.TaskBlindName;
|
|
if (taskInfo.IsAnalysisCreate)
|
|
{
|
|
result.SubjectCode = taskInfo.BlindSubjectCode;
|
|
|
|
}
|
|
else
|
|
{
|
|
result.SubjectCode = taskInfo.Subject.Code;
|
|
}
|
|
|
|
var judgeInfo = await _visitTaskRepository.Where(x =>
|
|
x.SubjectId == taskInfo.SubjectId
|
|
&& x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
|
|
&& x.TaskState == TaskState.Effect
|
|
&& x.ArmEnum == taskInfo.ArmEnum
|
|
&& x.ReadingCategory == ReadingCategory.Judge
|
|
&& x.IsAnalysisCreate == taskInfo.IsAnalysisCreate
|
|
&& x.IsSelfAnalysis == taskInfo.IsSelfAnalysis
|
|
&& x.DoctorUserId == taskInfo.DoctorUserId
|
|
&& x.ReadingTaskState == ReadingTaskState.HaveSigned
|
|
&& x.VisitTaskNum == taskInfo.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]
|
|
&& x.ReReadingApplyState != ReReadingApplyState.Agree).FirstOrDefaultAsync();
|
|
if (judgeInfo != null)
|
|
{
|
|
result.JudgeTaskId = judgeInfo.Id;
|
|
result.JudgeTaskName = judgeInfo.TaskBlindName;
|
|
}
|
|
|
|
|
|
// 一致性分析按照doctorId 其他按照分组
|
|
|
|
|
|
var queruTask = _visitTaskRepository.Where(x =>
|
|
x.TrialId == taskInfo.TrialId &&
|
|
x.SubjectId == taskInfo.SubjectId &&
|
|
x.ReadingCategory == ReadingCategory.Visit &&
|
|
x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
|
|
x.ReadingTaskState == ReadingTaskState.HaveSigned &&
|
|
x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
|
|
x.ArmEnum == taskInfo.ArmEnum &&
|
|
x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
|
|
x.DoctorUserId == taskInfo.DoctorUserId &&
|
|
x.TaskState == TaskState.Effect &&
|
|
x.VisitTaskNum < taskInfo.VisitTaskNum);
|
|
|
|
|
|
if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned)
|
|
{
|
|
queruTask = _visitTaskRepository.Where(x => taskInfo.RelatedVisitTaskIdList.Contains(x.Id));
|
|
}
|
|
|
|
result.TaskList = await queruTask
|
|
.OrderBy(x => x.VisitTaskNum).Select(x => new GlobalVisitInfo()
|
|
{
|
|
VisitName = x.TaskName,
|
|
BlindName = x.TaskBlindName,
|
|
VisitTaskId = x.Id,
|
|
ArmEnum = taskInfo.ArmEnum,
|
|
VisitNum = x.SourceSubjectVisit.VisitNum,
|
|
IsBaseLine=x.SourceSubjectVisit.IsBaseLine,
|
|
VisitId = x.SourceSubjectVisitId.Value,
|
|
|
|
BeforeQuestionList = x.ReadingTaskQuestionAnswerList.Where(y => y.ReadingQuestionTrial.GlobalReadingShowType!=GlobalReadingShowType.NotShow).OrderBy(y => y.ReadingQuestionTrial.ShowOrder)
|
|
.Select(y => new GlobalQuestionInfo()
|
|
{
|
|
|
|
QuestionId = y.ReadingQuestionTrialId,
|
|
QuestionName = y.ReadingQuestionTrial.QuestionName.LanguageName(y.ReadingQuestionTrial.QuestionEnName, _userInfo.IsEn_Us),
|
|
AnswerGroup = y.ReadingQuestionTrial.AnswerGroup,
|
|
QuestionType = y.ReadingQuestionTrial.QuestionType,
|
|
LimitEdit= y.ReadingQuestionTrial.LimitEdit,
|
|
MaxAnswerLength=y.ReadingQuestionTrial.MaxAnswerLength,
|
|
FileType=y.ReadingQuestionTrial.FileType,
|
|
QuestionGenre = y.ReadingQuestionTrial.QuestionGenre,
|
|
DictionaryCode = y.ReadingQuestionTrial.DictionaryCode,
|
|
GlobalReadingShowType=y.ReadingQuestionTrial.GlobalReadingShowType,
|
|
AnswerCombination = y.ReadingQuestionTrial.AnswerCombination,
|
|
JudgeType = y.ReadingQuestionTrial.JudgeType,
|
|
Type = y.ReadingQuestionTrial.Type,
|
|
TypeValue = y.ReadingQuestionTrial.TypeValue,
|
|
ValueType = y.ReadingQuestionTrial.ValueType,
|
|
IsJudgeQuestion =y.ReadingQuestionTrial.IsJudgeQuestion,
|
|
Answer =y.Answer,
|
|
}).ToList()
|
|
}).ToListAsync();
|
|
|
|
|
|
|
|
var globalReadingQuestion = await _readingGlobalTaskInfoRepository.Where(x => x.GlobalTaskId == inDto.VisitTaskId).ToListAsync();
|
|
var criterionType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => x.CriterionType).FirstOrDefaultAsync();
|
|
|
|
// Before的Answer取自于 上一次全局阅片的结果, 如果没有上一次全局阅片的结果 取检查批次的答案
|
|
|
|
var lastGlobalTask = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Global &&
|
|
x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
|
|
x.SubjectId == taskInfo.SubjectId && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.TaskState == TaskState.Effect && x.VisitTaskNum < taskInfo.VisitTaskNum)
|
|
.Where(x => x.DoctorUserId == taskInfo.DoctorUserId)
|
|
.OrderByDescending(x=>x.VisitTaskNum)
|
|
.FirstOrDefaultAsync();
|
|
|
|
List<ReadingGlobalTaskInfo>? globalAnswers = new List<ReadingGlobalTaskInfo>();
|
|
if (lastGlobalTask != null)
|
|
{
|
|
globalAnswers = await _readingGlobalTaskInfoRepository.Where(x => x.GlobalTaskId == lastGlobalTask.Id).ToListAsync();
|
|
}
|
|
|
|
if (criterionType != CriterionType.PCWG3)
|
|
{
|
|
result.TaskList.ForEach(x =>
|
|
{
|
|
|
|
x.BeforeQuestionList.ForEach(y =>
|
|
{
|
|
|
|
var globalAnswer = globalAnswers.Where(z => z.QuestionId == y.QuestionId&&z.TaskId==x.VisitTaskId).Select(z => z.Answer).FirstOrDefault();
|
|
if (!globalAnswer.IsNullOrEmpty())
|
|
{
|
|
y.Answer = globalAnswer;
|
|
y.IsGlobalAnswer = true;
|
|
}
|
|
|
|
});
|
|
});
|
|
}
|
|
|
|
result.TaskList.ForEach(x =>
|
|
{
|
|
x.AfterQuestionList = x.BeforeQuestionList.Where(x=>x.IsJudgeQuestion).GroupJoin(
|
|
globalReadingQuestion
|
|
, l => new { a = l.QuestionId, b = x.VisitTaskId }
|
|
, r => new { a = r.QuestionId, b = r.TaskId }
|
|
, (l, r) => new { question = l, global = r })
|
|
.SelectMany(lr => lr.global.DefaultIfEmpty(), (lr, r) => new GlobalQuestionInfo
|
|
{
|
|
Answer = lr.global == null || lr.global.Count() == 0 ?
|
|
(inDto.UsingOriginalData ? lr.question.Answer : string.Empty) :
|
|
(lr.global.Select(x => x.Answer).FirstOrDefault().IsNullOrEmpty() && inDto.UsingOriginalData ?
|
|
lr.question.Answer : lr.global.Select(x => x.Answer).FirstOrDefault()
|
|
),
|
|
VisitAnswer = lr.question.Answer,
|
|
IsHaveChange = lr.global.Any(x=>x.QuestionId!=null&&!x.Answer.IsNullOrEmpty()) ? true : false,
|
|
QuestionId = lr.question.QuestionId,
|
|
QuestionName = lr.question.QuestionName,
|
|
QuestionType = lr.question.QuestionType,
|
|
LimitEdit=lr.question.LimitEdit,
|
|
MaxAnswerLength=lr.question.MaxAnswerLength,
|
|
FileType=lr.question.FileType,
|
|
QuestionGenre = lr.question.QuestionGenre,
|
|
DictionaryCode = lr.question.DictionaryCode,
|
|
GlobalReadingShowType = lr.question.GlobalReadingShowType,
|
|
Type = lr.question.Type,
|
|
GlobalAnswerType = GlobalAnswerType.Question,
|
|
AnswerGroup = lr.question.AnswerGroup,
|
|
AnswerCombination = lr.question.AnswerCombination,
|
|
IsJudgeQuestion=lr.question.IsJudgeQuestion,
|
|
JudgeType = lr.question.JudgeType,
|
|
TypeValue = lr.question.TypeValue,
|
|
ValueType= lr.question.ValueType,
|
|
|
|
}).ToList();
|
|
|
|
|
|
List<GetGlobalQuestionType> questionTypes = new List<GetGlobalQuestionType>()
|
|
{
|
|
};
|
|
if (criterionType != CriterionType.PCWG3)
|
|
{
|
|
var agreeOrNotAnswer = globalReadingQuestion.Where(y => y.TaskId == x.VisitTaskId && y.GlobalAnswerType == GlobalAnswerType.AgreeOrNot).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
|
|
|
|
if (agreeOrNotAnswer.IsNullOrEmpty()&& lastGlobalTask!=null&& lastGlobalTask.RelatedVisitTaskIdList.Contains(x.VisitTaskId))
|
|
{
|
|
agreeOrNotAnswer = "1";
|
|
}
|
|
|
|
x.AgreeOrNot = new List<GlobalQuestionInfo>()
|
|
{
|
|
new GlobalQuestionInfo()
|
|
{
|
|
Answer = agreeOrNotAnswer,
|
|
QuestionName = "",
|
|
Type = "input",
|
|
GlobalAnswerType=GlobalAnswerType.AgreeOrNot,
|
|
GlobalReadingShowType= GlobalReadingShowType.AllShow,
|
|
}
|
|
|
|
};
|
|
|
|
questionTypes.Add(new GetGlobalQuestionType() { GlobalAnswerType = GlobalAnswerType.UpdateType, QuestionName = "评估更新类型" });
|
|
}
|
|
else
|
|
{
|
|
x.AgreeOrNot = new List<GlobalQuestionInfo>() { };
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
questionTypes.Add(new GetGlobalQuestionType() { GlobalAnswerType = GlobalAnswerType.Reason, QuestionName = "全局阅片备注" });
|
|
foreach (var item in questionTypes)
|
|
{
|
|
x.AfterQuestionList.Add(new GlobalQuestionInfo()
|
|
{
|
|
Answer = globalReadingQuestion.Where(y => y.TaskId == x.VisitTaskId && y.GlobalAnswerType == item.GlobalAnswerType).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
|
|
QuestionName = item.QuestionName,
|
|
Type = "input",
|
|
GlobalAnswerType = item.GlobalAnswerType,
|
|
GlobalReadingShowType= GlobalReadingShowType.AllShow,
|
|
|
|
});
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
if (criterionType == CriterionType.PCWG3)
|
|
{
|
|
|
|
|
|
// 找到上一个全局阅片
|
|
|
|
|
|
|
|
result.TaskList.ForEach(x =>
|
|
{
|
|
foreach (var item in x.AfterQuestionList.Where(x => x.QuestionType == QuestionType.SiteVisitForTumorEvaluation))
|
|
{
|
|
var answer = item.Answer;
|
|
|
|
var globalanswer = globalAnswers.Where(y => y.TaskId == x.VisitTaskId && y.QuestionId == item.QuestionId).FirstOrDefault();
|
|
|
|
if (globalanswer != null)
|
|
{
|
|
answer = globalanswer.Answer;
|
|
}
|
|
else
|
|
{
|
|
answer = x.BeforeQuestionList.Where(x => x.QuestionType == QuestionType.SiteVisitForTumorEvaluation).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
|
|
}
|
|
|
|
if (item.Answer.IsNullOrEmpty())
|
|
{
|
|
item.Answer = answer;
|
|
}
|
|
|
|
item.VisitAnswer = answer;
|
|
|
|
}
|
|
|
|
|
|
// 在修改前 去除这个问题
|
|
x.BeforeQuestionList = x.BeforeQuestionList.Where(x => x.QuestionType != QuestionType.SiteVisitForTumorEvaluation).ToList();
|
|
|
|
});
|
|
}
|
|
|
|
|
|
|
|
var subjectVisitId = await _readModuleRepository.Where(x => x.Id == taskInfo.SouceReadModuleId).Select(x => x.SubjectVisitId).FirstOrDefaultAsync();
|
|
var isBaseLine = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Select(x => x.IsBaseLine).FirstOrDefaultAsync();
|
|
List<CriterionDictionaryInfo> assessTypeList = await _readingCriterionDictionaryRepository.Where(x => x.CriterionId == taskInfo.TrialReadingCriterionId
|
|
&& x.ParentCode == ReadingCommon.CriterionDictionary.GlobalAssess
|
|
)
|
|
//.WhereIf(isBaseLine,x=>x.IsBaseLineUse)
|
|
//.WhereIf(!isBaseLine,x=>x.IsFollowVisitUse)
|
|
.Select(x => new CriterionDictionaryInfo()
|
|
{
|
|
Id = x.Id,
|
|
DictionaryId = x.DictionaryId,
|
|
ChildGroup = x.Dictionary.ChildGroup,
|
|
IsBaseLineUse=x.IsBaseLineUse,
|
|
IsFollowVisitUse=x.IsFollowVisitUse,
|
|
Code = x.Dictionary.Code,
|
|
Description = x.Dictionary.Description,
|
|
ShowOrder = x.Dictionary.ShowOrder,
|
|
ParentCode = x.Dictionary.Parent.Code,
|
|
Value = x.Dictionary.Value,
|
|
ValueCN = x.Dictionary.ValueCN
|
|
}).OrderBy(x => x.ParentCode).ThenBy(x => x.ShowOrder).ToListAsync();
|
|
result.AssessTypeList = assessTypeList;
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|