diff --git a/IRaCIS.Core.API/Controllers/InspectionController.cs b/IRaCIS.Core.API/Controllers/InspectionController.cs index 88534140b..f9798cd6b 100644 --- a/IRaCIS.Core.API/Controllers/InspectionController.cs +++ b/IRaCIS.Core.API/Controllers/InspectionController.cs @@ -351,6 +351,23 @@ namespace IRaCIS.Core.API.Controllers return result; } + /// + /// 提交阅片裁判表单 + /// + /// + /// + [HttpPost, Route("Inspection/ReadingImageTask/SubmitJudgeForm")] + [TrialGlobalLimit("AfterStopCannNotOpt")] + + [UnitOfWork] + + public async Task SubmitJudgeForm(DataInspectionDto opt) + { + var singid = await _inspectionService.RecordSing(opt.SignInfo); + var result = await _iReadingImageTaskService.SubmitJudgeForm(opt.Data); + await _inspectionService.CompletedSign(singid, result); + return result; + } /// /// 配置 基础逻辑信息并确认 diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 0ee98e373..0d195ab95 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -767,6 +767,7 @@ namespace IRaCIS.Core.Application.Service TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt, nameof(VisitTask)), ReadingCategory = ReadingCategory.Visit, + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId, IsNeedClinicalDataSign = isNeedClinicalDataSign, IsClinicalDataSign = isClinicalDataSign, @@ -1421,6 +1422,7 @@ namespace IRaCIS.Core.Application.Service // AllocateTime = DateTime.Now, //DoctorUserId = reReadingVisitTask.DoctorUserId, + IsIRImageDownloaded= reReadingVisitTask.IsIRImageDownloaded, }); generateTaskCommand.Action(newTask); diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 81092d152..34b68eac9 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -2199,6 +2199,21 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public DefaultSegmentNameDto DefaultSegmentName { get; set; } + /// + /// 仲裁模式 + /// + public JudgeMode JudgeModeEnum { get; set; } = JudgeMode.SelectOne; + + /// + /// 裁判规则 + /// + public JudgeRule JudgeRuleEnum { get; set; } = JudgeRule.Consistent; + + /// + /// 仲裁对象 + /// + public ArbitrationRule ArbitrationRule { get; set; } = ArbitrationRule.Reading; + } public class GetReadingImgInDto @@ -2437,6 +2452,81 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public Guid VisitTaskId { get; set; } } + public class GetSingleVisitJudgeAnswerInDto + { + [NotDefault] + public Guid VisitTaskId { get; set; } + } + + public class GetSingleVisitJudgeAnswerOutDto + { + public Guid R1VisitTaskId { get; set; } + public Guid R2VisitTaskId { get; set; } + public List QuestionList { get; set; } = new List(); + } + + public class SingleVisitJudgeAnswerItemDto + { + public Guid ReadingQuestionId { get; set; } + public string QuestionName { get; set; } = string.Empty; + public string Type { get; set; } = string.Empty; + public string TypeValue { get; set; } = string.Empty; + public int ShowOrder { get; set; } + public string R1Answer { get; set; } = string.Empty; + public string R2Answer { get; set; } = string.Empty; + public TableQuestionType? QuestionGenre { get; set; } + public string DictionaryCode { get; set; } = string.Empty; + public ValueUnit? Unit { get; set; } + public string? CustomUnit { get; set; } + public ValueOfType? ValueType { get; set; } + public JudgeReadingQuestionType QuestionType { get; set; } = JudgeReadingQuestionType.Question; + } + + public class GetJudgeFormInDto + { + [NotDefault] + public Guid VisitTaskId { get; set; } + } + + public class GetJudgeFormOutDto + { + public List QuestionList { get; set; } = new List(); + } + + public class JudgeFormQuestionDto + { + public Guid ReadingQuestionId { get; set; } + public string QuestionName { get; set; } = string.Empty; + public string Type { get; set; } = string.Empty; + public string TypeValue { get; set; } = string.Empty; + public int ShowOrder { get; set; } + public string Answer { get; set; } = string.Empty; + public TableQuestionType? QuestionGenre { get; set; } + public string DictionaryCode { get; set; } = string.Empty; + public ValueUnit? Unit { get; set; } + public string? CustomUnit { get; set; } + public ValueOfType? ValueType { get; set; } + public JudgeReadingQuestionType QuestionType { get; set; } = JudgeReadingQuestionType.Question; + } + + public class SetJudgeFormInDto + { + [NotDefault] + public Guid VisitTaskId { get; set; } + + public string JudgeResultRemark { get; set; } = string.Empty; + + public List JudgeResultImagePathList { get; set; } = new List(); + + public List QuestionList { get; set; } = new List(); + } + + public class JudgeFormAnswerDto + { + public Guid ReadingQuestionId { get; set; } + public string Answer { get; set; } = string.Empty; + } + public class JudgeReadingInfoDto { public string VisitName { get; set; } diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs index 6a130a511..75821232d 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs @@ -6,6 +6,43 @@ using System.ComponentModel.DataAnnotations.Schema; namespace IRaCIS.Core.Application.Service.Reading.Dto { + public class GetTrialQuestionVisitJudgeRuleInDto + { + [NotDefault] + public Guid TrialId { get; set; } + + [NotDefault] + public Guid TrialReadingCriterionId { get; set; } + + [NotDefault] + public decimal VisitNum { get; set; } + + public Guid? ReadingQuestionId { get; set; } + } + + public class SetTrialQuestionVisitJudgeRuleInDto + { + [NotDefault] + public Guid TrialReadingCriterionId { get; set; } + + [NotDefault] + public decimal VisitNum { get; set; } + + public List QuestionList { get; set; } = new List(); + } + + public class TrialQuestionVisitJudgeRuleItemDto + { + public Guid ReadingQuestionId { get; set; } + public string QuestionName { get; set; } = string.Empty; + public int ShowOrder { get; set; } + public List AnswerGroup { get; set; } = new List(); + public List AnswerCombination { get; set; } = new List(); + public JudgeTypeEnum JudgeType { get; set; } + public decimal? JudgeDifferenceValue { get; set; } + public JudgeDifferenceType JudgeDifferenceType { get; set; } + } + public class TumorAssessmentView : AddOrUpdateTumorAssessmentInDto { @@ -702,6 +739,16 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public Guid TrialReadingCriterionId { get; set; } } + public class SetTrialJudgeRuleInfoInDto + { + [NotDefault] + public Guid TrialReadingCriterionId { get; set; } + + public JudgeMode JudgeModeEnum { get; set; } = JudgeMode.SelectOne; + public JudgeRule JudgeRuleEnum { get; set; } = JudgeRule.Consistent; + public JudgeGenerate JudgeGenerateEnum { get; set; } = JudgeGenerate.Instant; + } + public class GetTrialJudgyInfoOutDto { public Guid TrialId { get; set; } @@ -717,6 +764,21 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// 仲裁规则 /// public ArbitrationRule ArbitrationRule { get; set; } + + /// + /// 仲裁模式 + /// + public JudgeMode JudgeModeEnum { get; set; } = JudgeMode.SelectOne; + + /// + /// 裁判规则 + /// + public JudgeRule JudgeRuleEnum { get; set; } = JudgeRule.Consistent; + + /// + /// 裁判任务生成 + /// + public JudgeGenerate JudgeGenerateEnum { get; set; } = JudgeGenerate.Instant; } public enum NeedSynchronize diff --git a/IRaCIS.Core.Application/Service/Reading/Interface/IReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/Interface/IReadingImageTaskService.cs index db9ca1114..dc3a3874d 100644 --- a/IRaCIS.Core.Application/Service/Reading/Interface/IReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/Interface/IReadingImageTaskService.cs @@ -15,6 +15,7 @@ namespace IRaCIS.Core.Application.Contracts Task TriggerJudgeQuestion(Guid visitTaskId); Task SubmitVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto); + Task SubmitJudgeForm(SetJudgeFormInDto inDto); Task SubmitJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto); Task GetOncologyReadingInfo(GetOncologyReadingInfoInDto inDto); diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingCriterionService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingCriterionService.cs index 1481e4766..b493d9e6a 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingCriterionService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingCriterionService.cs @@ -370,13 +370,32 @@ namespace IRaCIS.Core.Application.Service.RC TrialId = x.TrialId, IsReadingTaskViewInOrder = x.IsReadingTaskViewInOrder, ArbitrationRule = x.ArbitrationRule, - IsArbitrationReading = x.IsArbitrationReading + IsArbitrationReading = x.IsArbitrationReading, + JudgeModeEnum = x.JudgeModeEnum, + JudgeRuleEnum = x.JudgeRuleEnum, + JudgeGenerateEnum = x.JudgeGenerateEnum, }).FirstNotNullAsync(); return result; } + /// + /// 编辑裁判规则配置 + /// + [HttpPost] + public async Task SetTrialJudgeRuleInfo(SetTrialJudgeRuleInfoInDto inDto) + { + await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial() + { + JudgeModeEnum = inDto.JudgeModeEnum, + JudgeRuleEnum = inDto.JudgeRuleEnum, + JudgeGenerateEnum = inDto.JudgeGenerateEnum, + }); + + return ResponseOutput.Ok(await _readingQuestionCriterionTrialRepository.SaveChangesAsync()); + } + /// /// 新增修改项目问题标准(项目) /// @@ -482,7 +501,6 @@ namespace IRaCIS.Core.Application.Service.RC return ResponseOutput.Ok(result); } - #endregion #region 项目阅片标准问题分页 diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs index 53c1ba5fd..c76353280 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs @@ -33,10 +33,92 @@ namespace IRaCIS.Core.Application.Service IRepository _organInfoRepository, IRepository _readingTableQuestionSystemRepository, IRepository _readingTaskQuestionAnswer, - IRepository _previousPDFRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IReadingQuestionService + IRepository _previousPDFRepository, + IRepository _readingQuestionVisitJudgeRuleRepository, + IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IReadingQuestionService { + #region 项目访视裁判规则 + + /// + /// 获取项目阅片标准各访视的裁判规则配置。 + /// 未配置规则的访视问题也会返回,供前端直接进行配置。 + /// + [HttpPost] + public async Task> GetTrialQuestionVisitJudgeRule(GetTrialQuestionVisitJudgeRuleInDto inDto) + { + var questionList = await _readingQuestionTrialRepository + .Where(x=>!x.ExcludeShowVisitList.Contains(inDto.VisitNum)) + .Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion) + .WhereIf(inDto.ReadingQuestionId != null, x => x.Id == inDto.ReadingQuestionId) + .OrderBy(x => x.ShowOrder) + .Select(x => new TrialQuestionVisitJudgeRuleItemDto + { + ReadingQuestionId = x.Id, + QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), + ShowOrder = x.ShowOrder, + }) + .ToListAsync(); + + var questionIds = questionList.Select(x => x.ReadingQuestionId).ToList(); + var ruleList = await _readingQuestionVisitJudgeRuleRepository + .Where(x => x.VisitNum == inDto.VisitNum && questionIds.Contains(x.ReadingQuestionId)) + .ToListAsync(); + + return questionList.Select(question => + { + var rule = ruleList.FirstOrDefault(x => x.ReadingQuestionId == question.ReadingQuestionId); + return new TrialQuestionVisitJudgeRuleItemDto + { + ReadingQuestionId = question.ReadingQuestionId, + QuestionName = question.QuestionName, + ShowOrder = question.ShowOrder, + AnswerGroup = rule?.AnswerGroup ?? new List(), + AnswerCombination = rule?.AnswerCombination ?? new List(), + JudgeType = rule?.JudgeType ?? JudgeTypeEnum.None, + JudgeDifferenceValue = rule?.JudgeDifferenceValue, + JudgeDifferenceType = rule?.JudgeDifferenceType ?? default, + }; + }).ToList(); + } + + /// + /// 编辑项目阅片标准各访视的裁判规则配置。 + /// + [HttpPost] + public async Task SetTrialQuestionVisitJudgeRule(SetTrialQuestionVisitJudgeRuleInDto inDto) + { + var questionIds = await _readingQuestionTrialRepository + .Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion) + .Select(x => x.Id) + .ToListAsync(); + + await _readingQuestionVisitJudgeRuleRepository.BatchDeleteNoTrackingAsync(x => + x.VisitNum == inDto.VisitNum && questionIds.Contains(x.ReadingQuestionId)); + + var rules = inDto.QuestionList.Select(question => new ReadingQuestionVisitJudgeRule + { + Id = NewId.NextGuid(), + ReadingQuestionId = question.ReadingQuestionId, + VisitNum = inDto.VisitNum, + AnswerGroup = question.AnswerGroup ?? new List(), + AnswerCombination = question.AnswerCombination ?? new List(), + JudgeType = question.JudgeType, + JudgeDifferenceValue = question.JudgeDifferenceValue, + JudgeDifferenceType = question.JudgeDifferenceType, + }).ToList(); + + if (rules.Count > 0) + { + await _readingQuestionVisitJudgeRuleRepository.AddRangeAsync(rules); + } + + return ResponseOutput.Result(await _readingQuestionVisitJudgeRuleRepository.SaveChangesAsync()); + } + + #endregion + #region 获取计算问题 diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 2a2ce792d..636644bd0 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -66,6 +66,7 @@ namespace IRaCIS.Core.Application.Service IRepository _readingTableQuestionTrialRepository, IRepository _readingTaskQuestionAnswerRepository, IRepository _readingQuestionCriterionTrialRepository, + IRepository _readingQuestionVisitJudgeRuleRepository, IRepository _readingQuestionSystem, IRepository _criterionKeyFileReadRepository, IRepository _trialCriterionKeyFileRepository, @@ -3934,6 +3935,10 @@ namespace IRaCIS.Core.Application.Service x.ReadingToolList, x.CircleRadius, x.DefaultSegmentName, + x.JudgeGenerateEnum, + x.JudgeModeEnum, + x.JudgeRuleEnum, + x.ArbitrationRule, }).FirstNotNullAsync(); task.IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults; @@ -3997,6 +4002,9 @@ namespace IRaCIS.Core.Application.Service task.IsViewStudyPart = visitTaskInfo.ReadingCategory == ReadingCategory.Judge || visitTaskInfo.IsViewStudyPart; task.IsReadKeyFile = await _criterionKeyFileReadRepository.AnyAsync(x => x.IdentityUserId == _userInfo.IdentityUserId && x.TrialCriterionId == task.TrialReadingCriterionId); task.IsHaveKeyFile = await _trialCriterionKeyFileRepository.AnyAsync(x => x.TrialCriterionId == task.TrialReadingCriterionId); + task.JudgeModeEnum = criterionInfo.JudgeModeEnum; + task.JudgeRuleEnum = criterionInfo.JudgeRuleEnum; + task.ArbitrationRule = criterionInfo.ArbitrationRule; // 添加默认答案 if (inDto.VisitTaskId == null && visitTaskInfo.ReadingTaskState != ReadingTaskState.HaveSigned) { diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingJudgeTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingJudgeTaskService.cs index 7b6102a48..3fcac31fb 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingJudgeTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingJudgeTaskService.cs @@ -91,6 +91,198 @@ namespace IRaCIS.Core.Application.Service #region 获取裁判阅片任务信息 + + /// + /// 获取单访视裁判答案 + /// + /// + /// + [HttpPost] + public async Task GetSingleVisitJudgeAnswer(GetSingleVisitJudgeAnswerInDto inDto) + { + var judgeDataInfo = await _readingJudgeInfoRepository + .Where(x => x.JudgeTaskId == inDto.VisitTaskId) + .FirstNotNullAsync(); + + var taskIds = new List { judgeDataInfo.TaskIdOne, judgeDataInfo.TaskIdTwo }; + var readingTasks = await _visitTaskRepository + .Where(x => taskIds.Contains(x.Id)) + .Select(x => new + { + x.Id, + x.ArmEnum, + x.TrialReadingCriterionId, + x.VisitTaskNum, + }) + .ToListAsync(); + + var r1Task = readingTasks.First(x => x.ArmEnum == Arm.DoubleReadingArm1); + var r2Task = readingTasks.First(x => x.ArmEnum == Arm.DoubleReadingArm2); + + var judgeRule = await _readingQuestionCriterionTrialRepository + .Where(x => x.Id == r1Task.TrialReadingCriterionId) + .Select(x => x.JudgeRuleEnum) + .FirstNotNullAsync(); + + var displayQuestions = await GetJudgeDisplayQuestions(r1Task.TrialReadingCriterionId, r1Task.VisitTaskNum, judgeRule); + var judgeAnswers = displayQuestions + .Select(x => new SingleVisitJudgeAnswerItemDto + { + ReadingQuestionId = x.Id, + QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), + Type = x.Type, + TypeValue = x.TypeValue, + ShowOrder = x.ShowOrder, + QuestionGenre = x.QuestionGenre, + DictionaryCode = x.DictionaryCode, + Unit = x.Unit, + CustomUnit = x.CustomUnit, + ValueType = x.ValueType, + }) + .ToList(); + + var displayQuestionIds = judgeAnswers.Select(x => x.ReadingQuestionId).ToList(); + var answerList = await _readingTaskQuestionAnswerRepository + .Where(x => taskIds.Contains(x.VisitTaskId) && displayQuestionIds.Contains(x.ReadingQuestionTrialId)) + .Select(x => new + { + x.VisitTaskId, + x.ReadingQuestionTrialId, + x.Answer, + }) + .ToListAsync(); + + judgeAnswers.ForEach(question => + { + question.R1Answer = answerList.FirstOrDefault(x => x.VisitTaskId == r1Task.Id && x.ReadingQuestionTrialId == question.ReadingQuestionId)?.Answer ?? string.Empty; + question.R2Answer = answerList.FirstOrDefault(x => x.VisitTaskId == r2Task.Id && x.ReadingQuestionTrialId == question.ReadingQuestionId)?.Answer ?? string.Empty; + }); + + return new GetSingleVisitJudgeAnswerOutDto + { + R1VisitTaskId = r1Task.Id, + R2VisitTaskId = r2Task.Id, + QuestionList = judgeAnswers, + }; + } + + /// + /// 获取裁判表单 + /// + [HttpPost] + public async Task GetJudgeForm(GetJudgeFormInDto inDto) + { + var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); + var judgeRule = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => x.JudgeRuleEnum).FirstNotNullAsync(); + var questionList = await GetJudgeDisplayQuestions(taskInfo.TrialReadingCriterionId, taskInfo.VisitTaskNum, judgeRule); + var questionIds = questionList.Select(x => x.Id).ToList(); + var answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.ReadingQuestionTrialId)).ToListAsync(); + + return new GetJudgeFormOutDto + { + QuestionList = questionList.Select(x => new JudgeFormQuestionDto + { + ReadingQuestionId = x.Id, + QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), + Type = x.Type, + TypeValue = x.TypeValue, + ShowOrder = x.ShowOrder, + Answer = answers.FirstOrDefault(answer => answer.ReadingQuestionTrialId == x.Id)?.Answer ?? string.Empty, + QuestionGenre = x.QuestionGenre, + DictionaryCode = x.DictionaryCode, + Unit = x.Unit, + CustomUnit = x.CustomUnit, + ValueType = x.ValueType, + }).ToList(), + }; + } + + /// + /// 编辑裁判表单 + /// + [HttpPost] + public async Task SetJudgeForm(SetJudgeFormInDto inDto) + { + + await SaveJudgeForm(inDto); + await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask() + { + JudgeResultRemark = inDto.JudgeResultRemark, + JudgeResultImagePath = string.Join(',', inDto.JudgeResultImagePathList), + + }); + + return ResponseOutput.Result(await _readingTaskQuestionAnswerRepository.SaveChangesAsync()); + } + + + private async Task SaveJudgeForm(SetJudgeFormInDto inDto) + { + var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); + var judgeRule = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => x.JudgeRuleEnum).FirstNotNullAsync(); + var displayQuestionIds = (await GetJudgeDisplayQuestions(taskInfo.TrialReadingCriterionId, taskInfo.VisitTaskNum, judgeRule)).Select(x => x.Id).ToList(); + var submittedQuestionIds = inDto.QuestionList.Select(x => x.ReadingQuestionId).ToList(); + + + await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && submittedQuestionIds.Contains(x.ReadingQuestionTrialId)); + if (inDto.QuestionList.Count > 0) + { + await _readingTaskQuestionAnswerRepository.AddRangeAsync(inDto.QuestionList.Select(x => new ReadingTaskQuestionAnswer + { + ReadingQuestionTrialId = x.ReadingQuestionId, + ReadingQuestionCriterionTrialId = taskInfo.TrialReadingCriterionId, + TrialId = taskInfo.TrialId, + SubjectId = taskInfo.SubjectId, + VisitTaskId = inDto.VisitTaskId, + Answer = x.Answer, + }).ToList()); + } + + } + + /// + /// 提交裁判表单 + /// + /// + /// + [HttpPost] + public async Task SubmitJudgeForm(SetJudgeFormInDto inDto) + { + + await SaveJudgeForm(inDto); + await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask() + { + JudgeResultRemark = inDto.JudgeResultRemark, + ReadingTaskState = ReadingTaskState.HaveSigned, + SignTime=DateTime.Now, + JudgeResultImagePath = string.Join(',', inDto.JudgeResultImagePathList), + + }); + await _readingTaskQuestionAnswerRepository.SaveChangesAsync(); + + await SignatureAfter(inDto.VisitTaskId); + return ResponseOutput.Ok(); + } + + + private async Task> GetJudgeDisplayQuestions(Guid trialReadingCriterionId, decimal visitNum, JudgeRule judgeRule) + { + var questionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && x.IsJudgeQuestion) + .Where(x=>x.ShowQuestion== ShowQuestion.Show) + .OrderBy(x => x.ShowOrder).ToListAsync(); + var questionIds = questionList.Select(x => x.Id).ToList(); + var visitJudgeRules = judgeRule == JudgeRule.Difference + ? await _readingQuestionVisitJudgeRuleRepository.Where(x => questionIds.Contains(x.ReadingQuestionId) && (x.VisitNum == visitNum || x.VisitNum == -1)).ToListAsync() + : new List(); + + return questionList.Where(x => !x.ExcludeShowVisitList.Contains(visitNum)) + .Where(x => judgeRule == JudgeRule.Consistent + ? x.JudgeType != JudgeTypeEnum.NotApplicable + : (visitJudgeRules.FirstOrDefault(rule => rule.ReadingQuestionId == x.Id && rule.VisitNum == visitNum) + ?? visitJudgeRules.FirstOrDefault(rule => rule.ReadingQuestionId == x.Id && rule.VisitNum == -1))?.JudgeType != JudgeTypeEnum.NotApplicable) + .ToList(); + } + /// /// 获取裁判阅片任务信息 /// @@ -476,8 +668,15 @@ namespace IRaCIS.Core.Application.Service }); var result = await _visitTaskRepository.SaveChangesAsync(); + await SignatureAfter(inDto.VisitTaskId); + + return ResponseOutput.Ok(result); + } + + private async Task SignatureAfter(Guid visitTaskId) + { // 需要判断是否添加肿瘤学任务 - var taskInfo = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync(); + var taskInfo = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == visitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync(); if (taskInfo.ReadingCategory == ReadingCategory.Visit) { @@ -514,11 +713,9 @@ namespace IRaCIS.Core.Application.Service // 创建任务关联关系 - await this.CreateTaskRelated(inDto.VisitTaskId); + await this.CreateTaskRelated(visitTaskId); - await SafeMailHelper.Run(async () => await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(inDto.VisitTaskId)); - - return ResponseOutput.Ok(result); + await SafeMailHelper.Run(async () => await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(visitTaskId)); } /// @@ -624,6 +821,7 @@ namespace IRaCIS.Core.Application.Service x.ArbitrationRule, x.IsGlobalReading, x.IsReadingPeriod, + x.JudgeRuleEnum, }).FirstNotNullAsync(); var noteEqual = false; @@ -667,6 +865,7 @@ namespace IRaCIS.Core.Application.Service VisitTaskId = questionAnswer.VisitTaskId, }; var globalVisitAnswerlist = await globalVisitQuestionQuery.ToListAsync(); + await ApplyVisitJudgeRules(globalVisitAnswerlist, criterionInfo.JudgeRuleEnum); var taskNums = globalVisitAnswerlist.Select(x => x.VisitTaskNum).Distinct().OrderBy(x => x).ToList(); @@ -697,11 +896,13 @@ namespace IRaCIS.Core.Application.Service AnswerCombination = question.AnswerCombination, JudgeType = question.JudgeType, QuestionId = question.Id, - JudgeDifferenceValue = question.JudgeDifferenceValue, - JudgeDifferenceType = question.JudgeDifferenceType, - VisitTaskId = questionAnswet.VisitTaskId, - }; + JudgeDifferenceValue = question.JudgeDifferenceValue, + JudgeDifferenceType = question.JudgeDifferenceType, + VisitTaskId = questionAnswet.VisitTaskId, + VisitTaskNum = questionAnswet.VisitTask.VisitTaskNum, + }; var questionAnswerlist = await query.ToListAsync(); + await ApplyVisitJudgeRules(questionAnswerlist, criterionInfo.JudgeRuleEnum); // 将答案进行分组 List groupTasks = questionAnswerlist.GroupBy(x => new { x.JudgeDifferenceValue, x.JudgeDifferenceType, x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto @@ -749,6 +950,8 @@ namespace IRaCIS.Core.Application.Service } else { + await ApplyVisitJudgeRules(item.AfterQuestionList, item.VisitNum, criterionInfo.JudgeRuleEnum); + await ApplyVisitJudgeRules(twoItem.AfterQuestionList, twoItem.VisitNum, criterionInfo.JudgeRuleEnum); var newlist = item.AfterQuestionList.Where(x => x.QuestionId != null && x.IsJudgeQuestion).ToList().Union( twoItem.AfterQuestionList.Where(x => x.QuestionId != null && x.IsJudgeQuestion).ToList() ).ToList(); @@ -811,6 +1014,8 @@ namespace IRaCIS.Core.Application.Service }; var visitTaskQuestions = await query.ToListAsync(); + await ApplyVisitJudgeRules(visitTaskQuestions, lastTask.VisitNum, criterionInfo.JudgeRuleEnum); + await ApplyVisitJudgeRules(lastTask.AfterQuestionList, lastTask.VisitNum, criterionInfo.JudgeRuleEnum); var newlist = visitTaskQuestions.Where(x => x.QuestionId != null).ToList().Union( lastTask.AfterQuestionList.Where(x => x.QuestionId != null).ToList() @@ -929,6 +1134,102 @@ namespace IRaCIS.Core.Application.Service } + /// + /// 应用访视裁判规则 以及剔除排除的问题 + /// + private async Task ApplyVisitJudgeRules(List answerList, JudgeRule judgeRule) + { + if (answerList.Count == 0) + { + return; + } + + var questionIds = answerList.Select(x => x.QuestionId).Distinct().ToList(); + var questions = await _readingQuestionTrialRepository.Where(x => questionIds.Contains(x.Id)).Select(x => new + { + x.Id, + x.ExcludeShowVisitList, + }).ToListAsync(); + var excludedQuestionIds = answerList + .Where(x => questions.FirstOrDefault(question => question.Id == x.QuestionId)?.ExcludeShowVisitList.Contains(x.VisitTaskNum) == true) + .Select(x => x.QuestionId) + .Distinct() + .ToList(); + answerList.RemoveAll(x => excludedQuestionIds.Contains(x.QuestionId)); + + if (judgeRule != JudgeRule.Difference || answerList.Count == 0) + { + return; + } + + questionIds = answerList.Select(x => x.QuestionId).Distinct().ToList(); + var visitNums = answerList.Select(x => x.VisitTaskNum).Distinct().ToList(); + var visitRules = await _readingQuestionVisitJudgeRuleRepository + .Where(x => questionIds.Contains(x.ReadingQuestionId) && (visitNums.Contains(x.VisitNum) || x.VisitNum == -1)) + .ToListAsync(); + + answerList.ForEach(answer => + { + var rule = visitRules.FirstOrDefault(x => x.ReadingQuestionId == answer.QuestionId && x.VisitNum == answer.VisitTaskNum) + ?? visitRules.FirstOrDefault(x => x.ReadingQuestionId == answer.QuestionId && x.VisitNum == -1); + if (rule != null) + { + answer.AnswerGroup = JsonConvert.SerializeObject(rule.AnswerGroup); + answer.AnswerCombination = JsonConvert.SerializeObject(rule.AnswerCombination); + answer.JudgeType = rule.JudgeType; + answer.JudgeDifferenceValue = rule.JudgeDifferenceValue; + answer.JudgeDifferenceType = rule.JudgeDifferenceType; + } + }); + } + + /// + /// 应用访视裁判规则 以及剔除排除的问题 + /// + private async Task ApplyVisitJudgeRules(List questionList, decimal visitNum, JudgeRule judgeRule) + { + if (questionList.Count == 0) + { + return; + } + + var questionIds = questionList.Where(x => x.QuestionId != null).Select(x => x.QuestionId!.Value).Distinct().ToList(); + var excludedQuestionIds = await _readingQuestionTrialRepository + .Where(x => questionIds.Contains(x.Id) && x.ExcludeShowVisitList.Contains(visitNum)) + .Select(x => x.Id) + .ToListAsync(); + questionList.RemoveAll(x => x.QuestionId != null && excludedQuestionIds.Contains(x.QuestionId.Value)); + + if (judgeRule != JudgeRule.Difference || questionList.Count == 0) + { + return; + } + + questionIds = questionList.Where(x => x.QuestionId != null).Select(x => x.QuestionId!.Value).Distinct().ToList(); + var visitRules = await _readingQuestionVisitJudgeRuleRepository + .Where(x => questionIds.Contains(x.ReadingQuestionId) && (x.VisitNum == visitNum || x.VisitNum == -1)) + .ToListAsync(); + + questionList.ForEach(question => + { + if (question.QuestionId == null) + { + return; + } + + var rule = visitRules.FirstOrDefault(x => x.ReadingQuestionId == question.QuestionId && x.VisitNum == visitNum) + ?? visitRules.FirstOrDefault(x => x.ReadingQuestionId == question.QuestionId && x.VisitNum == -1); + if (rule != null) + { + question.AnswerGroup = JsonConvert.SerializeObject(rule.AnswerGroup); + question.AnswerCombination = JsonConvert.SerializeObject(rule.AnswerCombination); + question.JudgeType = rule.JudgeType; + question.JudgeDifferenceValue = rule.JudgeDifferenceValue; + question.JudgeDifferenceType = rule.JudgeDifferenceType; + } + }); + } + /// /// 发送微信通知 diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs index 23e704458..2bca8a9a7 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteSurveyViewModel.cs @@ -457,10 +457,13 @@ namespace IRaCIS.Core.Application.Contracts { [NotDefault] public Guid TrialSiteSurveyId { get; set; } + + public Guid? Id { get; set; } } public class SiteSurveyLogDTO { + public Guid Id { get; set; } public Guid TrialSiteSurveyId { get; set; } public string Name { get; set; } diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 23a027cf6..ef3201bfb 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -661,7 +661,7 @@ namespace IRaCIS.Core.Application.Contracts //找到最新的调研表 var currentLatest = await _trialSiteSurveyRepository.Where(t => t.TrialId == userInfo.TrialId && t.TrialSiteId == userInfo.TrialSiteId, true) - .Include(u => u.TrialSiteEquipmentSurveyList).Include(u => u.TrialSiteUserSurveyList).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync(); + .Include(u => u.TrialSiteEquipmentSurveyList).Include(u => u.TrialSiteUserSurveyList).Include(t => t.SiteSurveyLogList).OrderByDescending(t => t.CreateTime).FirstOrDefaultAsync(); if (currentLatest == null) { @@ -688,7 +688,7 @@ namespace IRaCIS.Core.Application.Contracts } //更新调研表日志 - 老的调研表 - currentLatest.SiteSurveyLogList.Add(new SiteSurveyLog() { Name = userInfo.ReplaceUserEmailOrPhone, OptType = SiteSurveyOptTyp.Over }); + //currentLatest.SiteSurveyLogList.Add(new SiteSurveyLog() { Name = userInfo.ReplaceUserEmailOrPhone, OptType = SiteSurveyOptTyp.Over }); var copy = currentLatest.Clone(); @@ -707,6 +707,7 @@ namespace IRaCIS.Core.Application.Contracts copy.Phone = String.Empty; //更新调研表日志 + var info = await GetSiteSurveyInfo(currentLatest.Id, currentLatest.TrialId); copy.SiteSurveyLogList.Add(new SiteSurveyLog() { Name = userInfo.ReplaceUserEmailOrPhone, OptType = SiteSurveyOptTyp.Update, OriginTrialSiteSurveyId = currentLatest.Id, Json = info.ToJsonStr() }); } @@ -1455,7 +1456,9 @@ namespace IRaCIS.Core.Application.Contracts [HttpPost] public async Task> GetSiteSurveyLogList(SiteSurveyLogQuery inQuery) { - return _siteSurveyLogRepository.Where(t => t.TrialSiteSurveyId == inQuery.TrialSiteSurveyId).ProjectTo(_mapper.ConfigurationProvider).ToList(); + return _siteSurveyLogRepository.Where(t => t.TrialSiteSurveyId == inQuery.TrialSiteSurveyId) + .WhereIf(inQuery.Id != null, t => t.Id == inQuery.Id) + .ProjectTo(_mapper.ConfigurationProvider).ToList(); } /// @@ -1467,7 +1470,7 @@ namespace IRaCIS.Core.Application.Contracts public async Task GetSiteSurveyEquipmentList(SiteSurveyEquipmentQuery inQuery) { var pageList = await _trialSiteEquipmentSurveyRepository.Where(t => t.TrialSiteSurvey.TrialId == inQuery.TrialId) - .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteSurvey.TrialSiteId==inQuery.TrialSiteId) + .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteSurvey.TrialSiteId == inQuery.TrialSiteId) .WhereIf(inQuery.TrialSiteCode.IsNotNullOrEmpty(), t => t.TrialSiteSurvey.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode)) .WhereIf(inQuery.TrialSiteName.IsNotNullOrEmpty(), t => t.TrialSiteSurvey.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteName) || t.TrialSiteSurvey.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteName))