using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore.Common; using IRaCIS.Core.Infrastructure; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Panda.DynamicWebApi.Attributes; namespace IRaCIS.Core.Application.Service { /// /// 阅片医学审核 /// [ApiExplorerSettings(GroupName = "Reading")] public class ReadingMedicalReviewService(IRepository _readingMedicineTrialQuestionRepository, IRepository _trialRepository, IRepository _visitTaskRepository, IRepository _readingTaskQuestionAnswerRepository, IRepository _readingGlobalTaskInfoRepository, IReadingImageTaskService _iReadingImageTaskService, IVisitTaskService _visitTaskService, IReadingClinicalDataService _readingClinicalDataService, IRepository _taskMedicalReviewRepository, IRepository _readingMedicalReviewDialogRepository, IRepository _readingQuestionCriterionTrial, IRepository _readingMedicineQuestionAnswerRepository, ITrialEmailNoticeConfigService _trialEmailNoticeConfigService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IReadingMedicalReviewService { /// /// 获取医学审核任务信息 /// /// /// [HttpPost] public async Task GetMedicalReviewReadingTask(GetMedicalReviewReadingTaskInDto inDto) { MedicalReviewInfo reviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId) .ProjectTo(_mapper.ConfigurationProvider).FirstNotNullAsync(); var taskInfo = await _visitTaskRepository.Where(x => x.Id == reviewInfo.VisitTaskId).Include(x => x.DoctorUser).Include(x => x.Subject).FirstNotNullAsync(); //if (taskInfo.TaskState != TaskState.Effect) //{ // throw new BusinessValidationFailedException("当前医学审核已失效!"); //} inDto.TrialReadingCriterionId = taskInfo.TrialReadingCriterionId; var medicalReviewInfo = await _readingQuestionCriterionTrial.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => new GetMedicalReviewReadingTaskOutDto() { ReadingType = x.ReadingType, IsReadingTaskViewInOrder = x.IsReadingTaskViewInOrder, }).FirstNotNullAsync(); medicalReviewInfo.MedicalReviewInfo = reviewInfo; medicalReviewInfo.VisitTaskId = taskInfo.Id; var clinicalDataList = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto() { SubjectId = taskInfo.SubjectId, TrialId = taskInfo.TrialId, VisitTaskId = taskInfo.Id, }); medicalReviewInfo.IsExistsClinicalData = clinicalDataList.Count > 0; medicalReviewInfo.ArmEnum = taskInfo.ArmEnum; medicalReviewInfo.SubjectCode = taskInfo.IsAnalysisCreate ? taskInfo.BlindSubjectCode : taskInfo.Subject.Code; medicalReviewInfo.TaskBlindName = taskInfo.TaskBlindName; medicalReviewInfo.ReadingUser = taskInfo.DoctorUser.FirstName + taskInfo.DoctorUser.LastName; medicalReviewInfo.SubjectId = taskInfo.SubjectId; medicalReviewInfo.IsClosedDialog = medicalReviewInfo.MedicalReviewInfo.IsClosedDialog; medicalReviewInfo.AuditState = medicalReviewInfo.MedicalReviewInfo.AuditState; medicalReviewInfo.IsSendMessage = medicalReviewInfo.MedicalReviewInfo.IsSendMessage; medicalReviewInfo.QuestionAnswerList = await this.GetMedicalQuestionAnswer(inDto); var result = await _readingMedicineQuestionAnswerRepository.SaveChangesAsync(); #region 取任务 switch (taskInfo.ReadingCategory) { case ReadingCategory.Oncology: medicalReviewInfo.OncologyInfo = await _iReadingImageTaskService.GetOncologyReadingInfo(new GetOncologyReadingInfoInDto() { VisitTaskId = taskInfo.Id }); break; case ReadingCategory.Judge: medicalReviewInfo.JudgeInfo = await _iReadingImageTaskService.GetJudgeReadingInfo(new GetJudgeReadingInfo() { VisitTaskId = taskInfo.Id }); break; case ReadingCategory.Global: medicalReviewInfo.GlobalInfo = await _iReadingImageTaskService.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto() { VisitTaskId = taskInfo.Id }); break; case ReadingCategory.Visit: // 有序 if (medicalReviewInfo.IsReadingTaskViewInOrder == ReadingOrder.InOrder) { medicalReviewInfo.TaskList = await _visitTaskRepository .Where(x => x.IsAnalysisCreate == taskInfo.IsAnalysisCreate) .Where(x => x.TaskState == TaskState.Effect || x.Id == taskInfo.Id) .Where(x => x.SubjectId == taskInfo.SubjectId && x.ArmEnum == taskInfo.ArmEnum && x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && x.DoctorUserId == taskInfo.DoctorUserId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReReadingApplyState != ReReadingApplyState.Agree ).OrderBy(x => x.VisitTaskNum).Select(x => new TaskInfo() { TaskId = x.Id, VisitTaskNum = x.VisitTaskNum, //JudgeTaskId=x.JudgeVisitTaskId, // 在下面赋值 要去已完成的 IsCurrentTask = x.Id == taskInfo.Id, ReadingCategory = x.ReadingCategory, TaskBlindName = x.TaskBlindName, ArmEnum = x.ArmEnum, TaskName = x.TaskName, SouceReadModuleId = x.SouceReadModuleId, SourceSubjectVisitId = x.SourceSubjectVisitId, //JudgeVisitTaskId = x.JudgeVisitTaskId, JudgeResultArm = x.JudgeResultTask.ArmEnum, SubjectId = x.SubjectId, }).ToListAsync(); List otherTask = await _visitTaskRepository.Where(x => x.SubjectId == taskInfo.SubjectId && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && x.TaskState == TaskState.Effect && x.ReadingCategory == ReadingCategory.Visit && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis && x.DoctorUserId != taskInfo.DoctorUserId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReReadingApplyState != ReReadingApplyState.Agree) .OrderBy(x => x.VisitTaskNum).Select(x => new TaskInfo() { TaskId = x.Id, IsCurrentTask = x.Id == taskInfo.Id, ReadingCategory = x.ReadingCategory, TaskBlindName = x.TaskBlindName, ArmEnum = x.ArmEnum, TaskName = x.TaskName, SouceReadModuleId = x.SouceReadModuleId, SourceSubjectVisitId = x.SourceSubjectVisitId, }).ToListAsync(); medicalReviewInfo.TaskList.ForEach(x => { var otherTaskInfo = otherTask.Where(y => y.SouceReadModuleId == x.SouceReadModuleId && y.SourceSubjectVisitId == x.SourceSubjectVisitId).FirstOrDefault(); if (otherTaskInfo != null) { x.OtherTaskId = otherTaskInfo.TaskId; x.OtherArmEnum = otherTaskInfo.ArmEnum; } }); } // 无序 else { medicalReviewInfo.TaskList = await _visitTaskRepository.Where(x => x.Id == taskInfo.Id).Select(x => new TaskInfo() { TaskId = x.Id, VisitTaskNum = x.VisitTaskNum, //JudgeTaskId = x.JudgeVisitTaskId, // 在下面赋值 要去已完成的 IsCurrentTask = x.Id == taskInfo.Id, ReadingCategory = x.ReadingCategory, TaskBlindName = x.TaskBlindName, ArmEnum = x.ArmEnum, TaskName = x.TaskName, SouceReadModuleId = x.SouceReadModuleId, SourceSubjectVisitId = x.SourceSubjectVisitId, SubjectId = x.SubjectId, }).ToListAsync(); List otherTask = await _visitTaskRepository.Where(x => x.SouceReadModuleId == taskInfo.SouceReadModuleId && x.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && x.DoctorUserId != taskInfo.DoctorUserId && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReReadingApplyState != ReReadingApplyState.Agree && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && x.TaskState == TaskState.Effect ) .OrderBy(x => x.VisitTaskNum).Select(x => new TaskInfo() { TaskId = x.Id, IsCurrentTask = x.Id == taskInfo.Id, ReadingCategory = x.ReadingCategory, TaskBlindName = x.TaskBlindName, ArmEnum = x.ArmEnum, TaskName = x.TaskName, SouceReadModuleId = x.SouceReadModuleId, SourceSubjectVisitId = x.SourceSubjectVisitId, }).ToListAsync(); medicalReviewInfo.TaskList.ForEach(x => { var otherTaskInfo = otherTask.Where(y => y.SouceReadModuleId == x.SouceReadModuleId && y.SourceSubjectVisitId == x.SourceSubjectVisitId).FirstOrDefault(); if (otherTaskInfo != null) { x.OtherTaskId = otherTaskInfo.TaskId; x.OtherArmEnum = otherTaskInfo.ArmEnum; } }); } var taskIds = medicalReviewInfo.TaskList.Select(x => x.TaskId).ToList(); // 找访视 var visitTaskAnswer = await _readingTaskQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId) && x.ReadingQuestionTrial.IsJudgeQuestion).Select(x => new JudgeQuestionAnswerInfo { Answer = x.Answer, VisitTaskId = x.VisitTaskId, DictionaryCode = x.ReadingQuestionTrial.DictionaryCode, ShowOrder = x.ReadingQuestionTrial.ShowOrder, QuestionGenre = x.ReadingQuestionTrial.QuestionGenre, QuestionName = x.ReadingQuestionTrial.QuestionName.LanguageName(x.ReadingQuestionTrial.QuestionEnName, _userInfo.IsEn_Us) }).ToListAsync(); var globalChangeAnswer = await _readingGlobalTaskInfoRepository.Where(x => taskIds.Contains(x.GlobalTaskId) && x.Answer != string.Empty && x.GlobalAnswerType == GlobalAnswerType.Question && x.GlobalVisitTask.TaskState == TaskState.Effect).ToListAsync(); // 找全局阅片 和裁判 var globalTask = await _visitTaskRepository.Where(x => x.SubjectId == taskInfo.SubjectId && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && x.TaskState == TaskState.Effect && x.ArmEnum == taskInfo.ArmEnum && (x.ReadingCategory == ReadingCategory.Global || x.ReadingCategory == ReadingCategory.Judge) && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis && x.DoctorUserId == taskInfo.DoctorUserId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReReadingApplyState != ReReadingApplyState.Agree) .Select(x => new { x.VisitTaskNum, x.TaskBlindName, x.Id }).ToListAsync(); medicalReviewInfo.TaskList.ForEach(x => { var visitGlobalInfo = globalTask.Where(y => y.VisitTaskNum == x.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Global]).FirstOrDefault(); if (visitGlobalInfo != null) { x.GlobalTaskId = visitGlobalInfo.Id; x.GlobalTaskName = visitGlobalInfo.TaskBlindName; } var visitJudgeInfo = globalTask.Where(y => y.VisitTaskNum == x.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]).FirstOrDefault(); if (visitJudgeInfo != null) { x.JudgeTaskId = visitJudgeInfo.Id; x.JudgeTaskName = visitJudgeInfo.TaskBlindName; } x.IsGlobalChange = globalChangeAnswer.Any(y => y.TaskId == x.TaskId); x.JudgeQuestionAnswerInfoList = visitTaskAnswer.Where(y => y.VisitTaskId == x.TaskId).OrderBy(y => y.ShowOrder).ToList(); }); medicalReviewInfo.TaskList.ForEach(x => { x.IsCurrentTask = x.TaskId == taskInfo.Id; }); break; } #endregion return medicalReviewInfo; } #region 问题 private async Task> GetMedicalQuestionAnswer(GetMedicalReviewReadingTaskInDto inDto) { var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); var taskInfo = await _visitTaskRepository.Where(x => x.Id == medicalReview.VisitTaskId).FirstNotNullAsync(); var questionQuery = from data in _readingMedicineTrialQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm && x.IsEnable && x.ReadingCategory == taskInfo.ReadingCategory && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId) join questionAnswer in _readingMedicineQuestionAnswerRepository.Where(x => x.TaskMedicalReviewId == inDto.TaskMedicalReviewId) on data.Id equals questionAnswer.ReadingMedicineQuestionId into questionAnswerTemp from leftquestionAnswer in questionAnswerTemp.DefaultIfEmpty() select new ReadingMedicineQuestion() { Id = data.Id, Type = data.Type, ParentTriggerValue = data.ParentTriggerValue, LanguageType = data.LanguageType, IsEnable = data.IsEnable, IsConfirm = data.IsConfirm, QuestionName = data.QuestionName, IsRequired = data.IsRequired, ShowOrder = data.ShowOrder, ParentId = data.ParentId, TypeValue = data.TypeValue, Answer = leftquestionAnswer.Answer }; var questionList = await questionQuery.OrderBy(x => x.ShowOrder).ToListAsync(); List medicineQuestionList = questionList.Where(x => x.ParentId == null).ToList(); medicineQuestionList.ForEach(x => { FindChildQuestion(x, questionList); }); return medicineQuestionList; } private void FindChildQuestion(ReadingMedicineQuestion medicineQuestionList, List questionlists) { medicineQuestionList.Childrens = questionlists.Where(x => x.ParentId == medicineQuestionList.Id).ToList(); if (medicineQuestionList.Childrens != null && medicineQuestionList.Childrens.Count != 0) { medicineQuestionList.Childrens.ForEach(x => { this.FindChildQuestion(x, questionlists); }); } } #endregion /// /// 保存医学审核问题 答案 /// /// [HttpPost] [TrialGlobalLimit( "AfterStopCannNotOpt" )] public async Task SaveMedicineQuestion(SaveMedicineQuestionInDto inDto) { var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); if (medicalReviewInfo.IsInvalid) { throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]); } await _readingMedicineQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.TaskMedicalReviewId == inDto.TaskMedicalReviewId); List questionAnswerList = inDto.QuestionAnswerList.Select(x => new ReadingMedicineQuestionAnswer() { Answer = x.Answer, ReadingMedicineQuestionId = x.Id, TaskMedicalReviewId = inDto.TaskMedicalReviewId, VisitTaskId = medicalReviewInfo.VisitTaskId, }).ToList(); await _readingMedicineQuestionAnswerRepository.AddRangeAsync(questionAnswerList); await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() { SaveQuestionTime = DateTime.Now, AuditState = MedicalReviewAuditState.Auditing, }); var result = await _readingMedicineQuestionAnswerRepository.SaveChangesAsync(); return ResponseOutput.Result(result); } /// /// 保存医学审核 结论 /// /// /// [TrialGlobalLimit( "AfterStopCannNotOpt" )] public async Task SaveMedicalReviewInfo(SaveMedicalReviewInfoInDto inDto) { var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); if (medicalReviewInfo.IsInvalid) { throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]); } if ((await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.SaveQuestionTime).FirstOrDefaultAsync()) == null) { throw new BusinessValidationFailedException(_localizer["MedicalReview_SaveQuestion"]); } var medicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() { LatestReplyUserId = (inDto.IsSendDialog && !medicalReview.IsSendMessage && inDto.IsHaveQuestion) ? _userInfo.UserRoleId : null, IsHaveQuestion = inDto.IsHaveQuestion, Questioning = inDto.Questioning, IsSendMessage = inDto.IsSendDialog && inDto.IsHaveQuestion, ImagePath = JsonConvert.SerializeObject(inDto.FileList), AuditAdviceEnum = inDto.AuditAdviceEnum, SaveConclusionTime = DateTime.Now, }); ; if (inDto.IsSendDialog && !medicalReview.IsSendMessage && inDto.IsHaveQuestion) { await _readingMedicalReviewDialogRepository.AddAsync(new ReadingMedicalReviewDialog() { AuditAdviceEnum = inDto.AuditAdviceEnum, TaskMedicalReviewId = inDto.TaskMedicalReviewId, UserTypeShortName = _userInfo.UserTypeShortName, IsHaveQuestion = inDto.IsHaveQuestion, Questioning = inDto.Questioning, VisitTaskId = medicalReview.VisitTaskId, UserTypeEnumInt = _userInfo.UserTypeEnumInt, ImagePath = JsonConvert.SerializeObject(inDto.FileList), }); } var result = await _taskMedicalReviewRepository.SaveChangesAsync(); return ResponseOutput.Result(result); } /// /// 关闭医学审核对话 /// /// [HttpPost] [TrialGlobalLimit( "AfterStopCannNotOpt" )] public async Task ClosedMedicalReviewDialog(ClosedMedicalReviewDialogInDto inDto) { await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() { LatestReplyUserId = _userInfo.UserRoleId, IsClosedDialog = inDto.IsClosedDialog, MedicalDialogCloseEnum = inDto.MedicalDialogCloseEnum, DialogCloseReason = inDto.DialogCloseReason, }); var taskMedical = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog() { TaskMedicalReviewId = inDto.TaskMedicalReviewId, VisitTaskId = taskMedical.VisitTaskId, UserTypeShortName = _userInfo.UserTypeShortName, MedicalDialogCloseEnum = inDto.MedicalDialogCloseEnum, Content = inDto.DialogCloseReason, UserTypeEnumInt = _userInfo.UserTypeEnumInt, }; await _readingMedicalReviewDialogRepository.AddAsync(dialog); var result = await _taskMedicalReviewRepository.SaveChangesAsync(); return ResponseOutput.Result(result); } /// /// 发送对话消息 /// /// /// [TrialGlobalLimit( "AfterStopCannNotOpt" )] public async Task SendMedicalReviewDialog(SendMedicalReviewDialogInDto inDto) { var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); if (medicalReviewInfo.IsInvalid) { throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]); } await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() { LatestReplyUserId = _userInfo.UserRoleId, }); var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync(); ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog() { TaskMedicalReviewId = inDto.TaskMedicalReviewId, UserTypeShortName = _userInfo.UserTypeShortName, Content = inDto.Content, UserTypeEnumInt = _userInfo.UserTypeEnumInt, VisitTaskId = visitTaskId, AuditAdviceEnum = inDto.AuditAdviceEnum, IsHaveQuestion = inDto.IsHaveQuestion, Questioning = inDto.Questioning, }; await _readingMedicalReviewDialogRepository.AddAsync(dialog); var result = await _readingMedicalReviewDialogRepository.SaveChangesAsync(); return ResponseOutput.Result(result); } /// /// IR发送消息 /// /// /// [UnitOfWork] [TrialGlobalLimit( "AfterStopCannNotOpt" )] public async Task IRSendMedicalReviewDialog(IRSendMedicalReviewDialogInDto inDto) { var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); if (medicalReviewInfo.IsInvalid) { throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]); } var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync(); if (inDto.IsApplyHeavyReading ?? false) { await _visitTaskService.ApplyReReading(new ApplyReReadingCommand() { IsCopyOrigenalForms = inDto.IsCopyOrigenalForms ?? false, IsCopyFollowForms = inDto.IsCopyFollowForms ?? false, RequestReReadingReason = inDto.RequestReReadingReason, RequestReReadingType = RequestReReadingType.DocotorApply, TrialId = inDto.TrialId, TaskIdList = new List() { visitTaskId } }); await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(x => !x.IsClosedDialog && x.Id == inDto.TaskMedicalReviewId, x => new TaskMedicalReview() { LatestReplyUserId = _userInfo.UserRoleId, IsClosedDialog = true, MedicalDialogCloseEnum = MedicalDialogClose.IRApplyReReading, IsApplyHeavyReading = true, FileName = inDto.FileName, ImagePath = JsonConvert.SerializeObject(inDto.FileList), DisagreeReason = inDto.DisagreeReason, }); } await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() { LatestReplyUserId = _userInfo.UserRoleId, DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum, }); ReadingMedicalReviewDialog dialog = new ReadingMedicalReviewDialog() { TaskMedicalReviewId = inDto.TaskMedicalReviewId, UserTypeShortName = _userInfo.UserTypeShortName, Content = inDto.Content, ImagePath = JsonConvert.SerializeObject(inDto.FileList), UserTypeEnumInt = _userInfo.UserTypeEnumInt, VisitTaskId = visitTaskId, FileName = inDto.FileName, DisagreeReason = inDto.DisagreeReason, DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum, IsApplyHeavyReading = inDto.IsApplyHeavyReading, }; await _readingMedicalReviewDialogRepository.AddAsync(dialog); var result = await _readingMedicalReviewDialogRepository.SaveChangesAsync(); return ResponseOutput.Result(result); } /// /// 获取医学审核对话 /// /// /// [HttpPost] public async Task<(List, object)> GetMedicalReviewDialog(GetMedicalReviewDialogInDto inDto) { var taskMedicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); List result = await _readingMedicalReviewDialogRepository.Where(x => x.TaskMedicalReviewId == inDto.TaskMedicalReviewId) .ProjectTo(_mapper.ConfigurationProvider) .OrderBy(x => x.CreateTime).ToListAsync(); result.ForEach(x => { x.IsCurrentUser = x.CreateUserId == _userInfo.UserRoleId; }); return (result, new { IsIRReply = result.Any(x => x.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer), taskMedicalReview.IsClosedDialog, taskMedicalReview.IsHaveQuestion, }); } /// /// 完成医学审核 /// /// /// [NonDynamicMethod] public async Task FinishMedicalReview(FinishMedicalReviewInDto inDto) { var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); if (medicalReviewInfo.IsInvalid) { throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]); } var taskmedicalReview = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => new { x.SaveConclusionTime, x.SaveQuestionTime, x.IsClosedDialog, x.IsHaveQuestion }).FirstNotNullAsync(); if (taskmedicalReview.SaveQuestionTime == null || taskmedicalReview.SaveConclusionTime == null) { throw new BusinessValidationFailedException(_localizer["MedicalReview_NeedSave"]); } if (taskmedicalReview.IsHaveQuestion && !taskmedicalReview.IsClosedDialog) { throw new BusinessValidationFailedException(_localizer["MedicalReview_NotClosed"]); } await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() { AuditState = MedicalReviewAuditState.HaveSigned, AuditSignTime = DateTime.Now, }); var result = await _taskMedicalReviewRepository.SaveChangesAsync(); //自动发送邮件逻辑 if (medicalReviewInfo.IsAutoGenerate) { var allMedicalAuditList = await _taskMedicalReviewRepository.Where(x => medicalReviewInfo.PDRelationTaskIdList.Contains(x.VisitTaskId) && x.IsAutoGenerate && x.IsInvalid == false).ToListAsync(); if (allMedicalAuditList.All(t => t.IsApplyHeavyReading == false && t.AuditSignTime != null && t.AuditState == MedicalReviewAuditState.HaveSigned)) { //自动发送 await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(medicalReviewInfo.VisitTaskId, false); } } return ResponseOutput.Result(result); } /// /// IR回复确认医学审核 /// /// /// [HttpPost] [UnitOfWork] [TrialGlobalLimit( "AfterStopCannNotOpt" )] public async Task IRConfirmMedicalReview(IRConfirmMedicalReviewInDto inDto) { var medicalReviewInfo = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).FirstNotNullAsync(); if (medicalReviewInfo.IsInvalid) { throw new BusinessValidationFailedException(_localizer["MedicalReview_invalid"]); } await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(inDto.TaskMedicalReviewId, x => new TaskMedicalReview() { LatestReplyUserId = _userInfo.UserRoleId, DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum, DisagreeReason = inDto.DisagreeReason, IsApplyHeavyReading = inDto.IsApplyHeavyReading, }); ; var visitTaskId = await _taskMedicalReviewRepository.Where(x => x.Id == inDto.TaskMedicalReviewId).Select(x => x.VisitTaskId).FirstOrDefaultAsync(); await _readingMedicalReviewDialogRepository.AddAsync(new ReadingMedicalReviewDialog() { TaskMedicalReviewId = inDto.TaskMedicalReviewId, UserTypeShortName = _userInfo.UserTypeShortName, DoctorUserIdeaEnum = inDto.DoctorUserIdeaEnum, DisagreeReason = inDto.DisagreeReason, IsApplyHeavyReading = inDto.IsApplyHeavyReading, VisitTaskId = visitTaskId, UserTypeEnumInt = _userInfo.UserTypeEnumInt, }); var result = await _taskMedicalReviewRepository.SaveChangesAsync(); return ResponseOutput.Result(result); } /// /// 获取下一个IR医学反馈 /// /// /// /// [HttpPost] public async Task GetNextIRMedicalFeedback(GetNextIRMedicalFeedbackInDto inDto) { var list = await GetIRMedicalFeedbackList(new GetIRMedicalFeedbackListInDto() { TrialId = inDto.TrialId, TrialReadingCriterionId = inDto.TrialReadingCriterionId, PageIndex = 1, AuditState = MedicalReviewAuditState.Auditing, PageSize = 99999, }); var index = list.CurrentPageData.ToList().FindIndex(x => x.Id == inDto.TaskMedicalReviewId); var result = new GetIRMedicalFeedbackListOutDto() { }; if (index + 1 == list.CurrentPageData.Count()) // 最后一个 { throw new BusinessValidationFailedException(_localizer["MedicalReview_IRFinish"]); } else if (index == -1 || list.CurrentPageData.Count == 1) // 第一个或者只有一个 { if (list.CurrentPageData[0].Id == inDto.TaskMedicalReviewId) { throw new BusinessValidationFailedException(_localizer["MedicalReview_IRFinish"]); } result = list.CurrentPageData[0]; } else { result = list.CurrentPageData.Skip(index + 1).Take(1).First(); } return result; } /// /// 获取IR医学审核信息 /// /// /// [HttpPost] public async Task> GetIRMedicalFeedbackList(GetIRMedicalFeedbackListInDto inDto) { var taskMedicalReviewquery = _taskMedicalReviewRepository.Where(x => x.TrialId == inDto.TrialId).Include(x => x.VisitTask) .Where(x => x.VisitTask.DoctorUserId == _userInfo.UserRoleId) .Where(x => x.IsHaveQuestion) .WhereIf(!inDto.TaskBlindName.IsNullOrEmpty(), x => x.VisitTask.TaskBlindName == inDto.TaskBlindName) .WhereIf(inDto.SubjectId != null, x => x.VisitTask.SubjectId == inDto.SubjectId!) .WhereIf(inDto.IsUrgent != null, x => x.VisitTask.IsUrgent == inDto.IsUrgent!) .WhereIf(inDto.AuditState != null, x => x.AuditState == inDto.AuditState!) .WhereIf(inDto.IsNotHaveSigned, x => x.AuditState != MedicalReviewAuditState.HaveSigned) .WhereIf(inDto.ReadingCategory != null, x => x.VisitTask.ReadingCategory == inDto.ReadingCategory!) .WhereIf(inDto.AuditAdviceEnum != null, x => x.AuditAdviceEnum == inDto.AuditAdviceEnum!) .WhereIf(inDto.DoctorUserIdeaEnum != null, x => x.DoctorUserIdeaEnum == inDto.DoctorUserIdeaEnum!) .WhereIf(inDto.IsClosedDialog != null, x => x.IsClosedDialog == inDto.IsClosedDialog!) .WhereIf(inDto.IsHaveQuestion != null, x => x.IsHaveQuestion == inDto.IsHaveQuestion!) .WhereIf(inDto.MedicalDialogCloseEnum != null, x => x.MedicalDialogCloseEnum == inDto.MedicalDialogCloseEnum!) .WhereIf(inDto.IsInvalid != null, x => x.IsInvalid == inDto.IsInvalid!) .WhereIf(inDto.TrialReadingCriterionId != null, x => x.VisitTask.TrialReadingCriterionId == inDto.TrialReadingCriterionId!) .Select(x => new GetIRMedicalFeedbackListOutDto { TaskState = x.VisitTask.TaskState, Id = x.Id, VisitTaskId = x.VisitTaskId, IsUrgent = x.VisitTask.IsUrgent, AuditState = x.AuditState, SubjectCode = x.VisitTask.BlindSubjectCode == string.Empty ? x.VisitTask.Subject.Code : x.VisitTask.BlindSubjectCode, TaskBlindName = x.VisitTask.TaskBlindName, ReadingCategory = x.VisitTask.ReadingCategory, FirstReplyTime = x.ReadingMedicalReviewDialogList.Min(x => x.CreateTime), LastReplyTime = x.ReadingMedicalReviewDialogList.Max(x => x.CreateTime), AuditAdviceEnum = x.AuditAdviceEnum, DoctorUserIdeaEnum = x.DoctorUserIdeaEnum, SaveConclusionTime = x.SaveConclusionTime, IsClosedDialog = x.IsClosedDialog, IsHaveQuestion = x.IsHaveQuestion, MedicalDialogCloseEnum = x.MedicalDialogCloseEnum, IsInvalid = x.IsInvalid, SubjectId = x.VisitTask.SubjectId, TrialReadingCriterionId = x.VisitTask.TrialReadingCriterion.Id, TrialReadingCriterionName = x.VisitTask.TrialReadingCriterion.CriterionName, ReadingTool = x.VisitTask.TrialReadingCriterion.ReadingTool, IsReadingTaskViewInOrder = x.VisitTask.TrialReadingCriterion.IsReadingTaskViewInOrder, IsReadingShowSubjectInfo = x.VisitTask.TrialReadingCriterion.IsReadingShowSubjectInfo, IsReadingShowPreviousResults = x.VisitTask.TrialReadingCriterion.IsReadingShowPreviousResults, DigitPlaces = x.VisitTask.TrialReadingCriterion.DigitPlaces, IseCRFShowInDicomReading = x.VisitTask.TrialReadingCriterion.IseCRFShowInDicomReading, CriterionType = x.VisitTask.TrialReadingCriterion.CriterionType, }).WhereIf(!inDto.SubjectCode.IsNullOrEmpty(), x => x.SubjectCode == inDto.SubjectCode); var result = await taskMedicalReviewquery.ToPagedListAsync(inDto, nameof(GetIRMedicalFeedbackListOutDto.AuditState)); return result; } } }