irc-netcore-api/IRaCIS.Core.Application/Service/Reading/ReadingImageTaskService.cs

475 lines
22 KiB
C#

using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Service.WorkLoad.DTO;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Service.Reading.Dto;
using MassTransit;
using IRaCIS.Core.Application.Service.Reading;
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;
namespace IRaCIS.Application.Services
{
/// <summary>
/// IR影像阅片
/// </summary>
[ApiExplorerSettings(GroupName = "Reading")]
public class ReadingImageTaskService : BaseService, IReadingImageTaskService
{
private readonly IMapper mapper;
private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IVisitTaskHelpeService _visitTaskHelpeService;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;
public ReadingImageTaskService(
IMapper mapper,
IRepository<NoneDicomStudy> noneDicomStudyRepository,
IRepository<VisitTask> visitTaskRepository,
IVisitTaskHelpeService visitTaskHelpeService,
IRepository<SubjectVisit> subjectVisitRepository,
IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository,
IRepository<ReadingQuestionTrial> readingQuestionTrialRepository
)
{
this.mapper = mapper;
this._noneDicomStudyRepository = noneDicomStudyRepository;
this._visitTaskRepository = visitTaskRepository;
this._visitTaskHelpeService = visitTaskHelpeService;
this._subjectVisitRepository = subjectVisitRepository;
this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
this._readingQuestionTrialRepository = readingQuestionTrialRepository;
}
/// <summary>
/// 获取下一个阅片任务
/// </summary>
/// <param name="subjectId"></param>
/// <param name="trialId"></param>
/// <returns></returns>
private async Task<GetReadingTaskDto> GetNextTaskId(Guid? subjectId,Guid trialId,Guid? visistTaskId)
{
GetReadingTaskDto? task = new GetReadingTaskDto();
if (visistTaskId != null)
{
task = await _visitTaskRepository.Where(x => x.Id==visistTaskId).Select(x => new GetReadingTaskDto()
{
VisistTaskId = x.Id,
ReadingCategory = x.ReadingCategory,
VisistId = x.ReadingCategory == ReadingCategory.Visit ? x.SourceSubjectVisitId.Value : x.ReadModule.SubjectVisitId,
VisitNum = x.ReadingCategory == ReadingCategory.Visit ? x.SubjectVisit.VisitNum : x.ReadModule.VisitNum
}).FirstOrDefaultAsync();
task.SubjectId = await _subjectVisitRepository.Where(x => x.Id == task.VisistId).Select(x => x.SubjectId).FirstOrDefaultAsync();
return task;
}
if (subjectId != null)
{
task = await _visitTaskRepository.Where(x => x.TrialId == trialId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.SubjectId == subjectId.Value&&x.DoctorUserId == _userInfo.Id).Select(x => new GetReadingTaskDto()
{
VisistTaskId=x.Id,
ReadingCategory = x.ReadingCategory,
VisistId = x.ReadingCategory == ReadingCategory.Visit ? x.SourceSubjectVisitId.Value : x.ReadModule.SubjectVisitId,
VisitNum = x.ReadingCategory == ReadingCategory.Visit ? x.SubjectVisit.VisitNum : x.ReadModule.VisitNum
}).OrderBy(x => x.VisitNum).ThenBy(x => x.ReadingCategory).FirstOrDefaultAsync();
if (task == null)
{
throw new BusinessValidationFailedException("任务都已经完成");
}
task.SubjectId = subjectId.Value;
}
else
{
task = await _visitTaskRepository.Where(x => x.TrialId == trialId && x.ReadingTaskState != ReadingTaskState.HaveSigned).Select(x => new GetReadingTaskDto()
{
VisistTaskId = x.Id,
ReadingCategory = x.ReadingCategory,
VisistId = x.ReadingCategory == ReadingCategory.Visit ? x.SourceSubjectVisitId.Value : x.ReadModule.SubjectVisitId,
VisitNum = x.ReadingCategory == ReadingCategory.Visit ? x.SubjectVisit.VisitNum : x.ReadModule.VisitNum
}).FirstOrDefaultAsync();
if (task == null)
{
throw new BusinessValidationFailedException("任务都已经完成");
}
task.SubjectId = await _subjectVisitRepository.Where(x => x.Id == task.VisistId).Select(x => x.SubjectId).FirstOrDefaultAsync();
}
return task;
}
/// <summary>
/// 获取阅片非Dicom文件
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<(List<NoneDicomStudyView>,object)> GetReadingImageFile(GetReadingImgInDto inDto)
{
var task=await GetNextTaskId(inDto.SubjectId, inDto.TrialId,inDto.VisistTaskId);
List<Guid> visitIds = new List<Guid>();
if (task.ReadingCategory == ReadingCategory.Visit)
{
visitIds.Add(task.VisistId);
}
else
{
// 阅片期取前面所有的图像
visitIds.AddRange(await _subjectVisitRepository.Where(x => x.VisitNum <= task.VisitNum && x.SubjectId == task.SubjectId).Select(x => x.Id).ToListAsync());
}
List<NoneDicomStudyView> result=await _noneDicomStudyRepository.Where(t => visitIds.Contains(t.SubjectVisitId))
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync();
return (result, new {
VisitTaskId= task.VisistTaskId
});
}
/// <summary>
/// 获取项目已确认的标准
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<GetTrialConfirmCriterionListOutDto>> GetTrialConfirmCriterionList(GetConfirmCriterionInDto inDto)
{
var result= await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == inDto.TrialId&&x.IsConfirm&&x.IsCompleteConfig)
.Select(x => new GetTrialConfirmCriterionListOutDto()
{
ReadingQuestionCriterionTrialId = x.Id,
ReadingQuestionCriterionTrialName = x.CriterionName
}).ToListAsync();
return result;
}
/// <summary>
/// 获取项目标准的裁判问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<GetTrialCriterionJudgeQuestionListOutDto>> GetTrialCriterionJudgeQuestionList(GetTrialCriterionJudgeQuestionListInDto inDto)
{
var result = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == inDto.ReadingQuestionCriterionTrialId && x.IsJudgeQuestion)
.Select(x => new GetTrialCriterionJudgeQuestionListOutDto()
{
AnswerGroup = JsonConvert.DeserializeObject<List<AnswerGroupDto>>(x.AnswerGroup.IsNullOrEmpty()?"[]": x.AnswerGroup),
QuestionName = x.QuestionName,
TypeValue =x.TypeValue,
ReadingQuestionTrialId = x.Id
}).ToListAsync();
return result;
}
/// <summary>
/// 设置裁判问题的答案分组
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetTrialCriterionJudgeQuestionAnswerGroup(SetTrialCriterionJudgeQuestionAnswerGroupInDto inDto)
{
await _readingQuestionTrialRepository.UpdatePartialFromQueryAsync(inDto.ReadingQuestionTrialId, x => new ReadingQuestionTrial()
{
AnswerGroup = JsonConvert.SerializeObject(inDto.AnswerGroup)
}) ;
var result = await _readingQuestionTrialRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 获取项目的阅片问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<(List<GetTrialReadingQuestionOutDto>, object)> GetTrialReadingQuestion(GetTrialReadingQuestionInDto inDto)
{
var readingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync();
var query= from data in _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId==inDto.ReadingQuestionCriterionTrialId )
join questionAnswer in _readingTaskQuestionAnswerRepository.Where(x=>x.VisitTaskId==inDto.VisitTaskId) on data.Id equals questionAnswer.ReadingQuestionTrialId into questionAnswerTemp
from leftquestionAnswer in questionAnswerTemp.DefaultIfEmpty()
select new GetTrialReadingQuestionOutDto()
{
ReadingQuestionTrialId=data.Id,
ReadingQuestionCriterionTrialId=data.ReadingQuestionCriterionTrialId,
TrialId=data.TrialId,
Type=data.Type,
ParentTriggerValue=data.ParentTriggerValue,
GroupName=data.GroupName,
QuestionName=data.QuestionName,
IsRequired=data.IsRequired,
ShowOrder=data.ShowOrder,
ParentId=data.ParentId,
TypeValue=data.TypeValue,
Answer= leftquestionAnswer.Answer
};
var qusetionList =await query.OrderBy(x=>x.ShowOrder).ToListAsync();
List<GetTrialReadingQuestionOutDto> groupList = qusetionList.Where(x => x.ParentId == null).ToList();
groupList.ForEach(x =>
{
FindChildQuestion(x, qusetionList);
});
return (groupList, new
{
readingTaskState = readingTaskState
});
}
/// <summary>
/// 找子问题
/// </summary>
/// <param name="trialReadingQuestion"></param>
/// <param name="questionlists"></param>
private void FindChildQuestion(GetTrialReadingQuestionOutDto trialReadingQuestion, List<GetTrialReadingQuestionOutDto> questionlists)
{
trialReadingQuestion.Childrens = questionlists.Where(x => x.ParentId == trialReadingQuestion.ReadingQuestionTrialId).ToList();
if (trialReadingQuestion.Childrens != null && trialReadingQuestion.Childrens.Count != 0)
{
trialReadingQuestion.Childrens.ForEach(x =>
{
FindChildQuestion(x, questionlists);
});
}
}
/// <summary>
/// 保存任务问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SaveVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto)
{
var subjectId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.SubjectId).FirstOrDefaultAsync();
await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingQuestionCriterionTrialId == inDto.ReadingQuestionCriterionTrialId);
List<ReadingTaskQuestionAnswer> readingTaskAnswerList = inDto.AnswerList.Select(x => new ReadingTaskQuestionAnswer()
{
Id = NewId.NextGuid(),
SubjectId = subjectId,
Answer = x.Answer,
ReadingQuestionCriterionTrialId = inDto.ReadingQuestionCriterionTrialId,
ReadingQuestionTrialId = x.ReadingQuestionTrialId,
VisitTaskId = inDto.VisitTaskId,
TrialId = inDto.TrialId
}).ToList();
await _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskAnswerList);
var result = await _visitTaskRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 提交问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[NonDynamicMethod]
public async Task<IResponseOutput> SubmitVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto)
{
await this.SaveVisitTaskQuestions(inDto);
await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
{
ReadingTaskState = ReadingTaskState.HaveSigned
});
var result = await _visitTaskRepository.SaveChangesAsync();
await this.TriggerJudgeQuestionNew(inDto.VisitTaskId);
return ResponseOutput.Ok(result);
}
/// <summary>
/// 添加阅片期任务
/// </summary>
/// <returns></returns>
private async Task AddReadingTask(Guid VisitTaskId)
{
}
/// <summary>
/// 触发裁判任务(新)
/// </summary>
/// <param name="VisitTaskId"></param>
/// <returns></returns>
private async Task TriggerJudgeQuestionNew(Guid VisitTaskId)
{
var visitTask = await _visitTaskRepository.Where(x => x.Id == VisitTaskId).FirstOrDefaultAsync();
var visitTaskids = await _visitTaskRepository.Where(x => x.ReadingTaskState == ReadingTaskState.HaveSigned && x.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && x.SouceReadModuleId == visitTask.SouceReadModuleId).Select(x => x.Id).ToListAsync();
if (visitTaskids.Count == 2)
{
var query = from questionAnswet in _readingTaskQuestionAnswerRepository.Where(x => visitTaskids.Contains(x.VisitTaskId))
join question in _readingQuestionTrialRepository.Where(x => x.IsJudgeQuestion) on new { ReadingQuestionTrialId = questionAnswet.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId = question.Id }
select new TaskAnswerDto()
{
Answer = questionAnswet.Answer,
AnswerGroup = question.AnswerGroup,
QuestionId = question.Id,
VisitTaskId = questionAnswet.VisitTaskId,
};
var questionAnswerlist = await query.ToListAsync();
List<GroupTaskAnswerDto> groupTasks = questionAnswerlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup }).Select(x => new GroupTaskAnswerDto
{
QuestionId = x.Key.QuestionId,
AnswerGroup = x.Key.AnswerGroup,
TaskAnswerList = x.ToList(),
}).ToList();
var verificationResults = false;
foreach (var item in groupTasks)
{
if (item.TaskAnswerList.Count() != 2)
{
verificationResults = true;
break;
}
else
{
var taskAnswer1 = item.TaskAnswerList[0];
var taskAnswer2 = item.TaskAnswerList[1];
if (taskAnswer1.Answer != taskAnswer2.Answer)
{
var answerGroup = JsonConvert.DeserializeObject<List<AnswerGroupDto>>(item.AnswerGroup==string.Empty?"[]": item.AnswerGroup).ToList();
answerGroup.ForEach(x =>
{
if (x.AnswerGroupA.Contains(taskAnswer1.Answer) && x.AnswerGroupB.Contains(taskAnswer2.Answer))
{
verificationResults = true;
}
if (x.AnswerGroupB.Contains(taskAnswer1.Answer) && x.AnswerGroupA.Contains(taskAnswer2.Answer))
{
verificationResults = true;
}
});
}
}
}
if (verificationResults)
{
await this.SaveJudgeTask(new SaveJudgeTaskDto()
{
VisitTaskIds = visitTaskids,
});
}
}
}
/// <summary>
/// 触发裁判任务(老)
/// </summary>
/// <param name="VisitTaskId"></param>
/// <returns></returns>
private async Task TriggerJudgeQuestionOld(Guid VisitTaskId)
{
var visitTask = await _visitTaskRepository.Where(x => x.Id == VisitTaskId).FirstOrDefaultAsync();
var visitTaskids = await _visitTaskRepository.Where(x => x.ReadingTaskState == ReadingTaskState.HaveSigned && x.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && x.SouceReadModuleId == visitTask.SouceReadModuleId).Select(x => x.Id).ToListAsync();
if (visitTaskids.Count == 2)
{
var query = from questionAnswet in _readingTaskQuestionAnswerRepository.Where(x=> visitTaskids.Contains(x.VisitTaskId))
join question in _readingQuestionTrialRepository.Where(x=>x.IsJudgeQuestion) on new { ReadingQuestionTrialId= questionAnswet.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId= question.Id }
select new TaskAnswerDto()
{
Answer= questionAnswet.Answer,
AnswerGroup= question.AnswerGroup,
QuestionId= question.Id,
VisitTaskId= questionAnswet.VisitTaskId,
};
var questionAnswerlist =await query.ToListAsync();
List<GroupTaskAnswerDto> groupTasks = questionAnswerlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup }).Select(x => new GroupTaskAnswerDto
{
QuestionId = x.Key.QuestionId,
AnswerGroup = x.Key.AnswerGroup,
TaskAnswerList = x.ToList(),
}).ToList();
var verificationResults = true;
foreach (var item in groupTasks)
{
if (item.TaskAnswerList.Count() != 2|| item.AnswerGroup==string.Empty)
{
verificationResults = false;
break;
}
else
{
var item1= item.TaskAnswerList[0];
var item2= item.TaskAnswerList[1];
if (item1.Answer != item2.Answer)
{
var answerGroup = JsonConvert.DeserializeObject<List<string>>(item.AnswerGroup).Select(x => new AnswerGroup()
{
GroupId = NewId.NextGuid(),
GroupValue = x
}).ToList();
var itemAnswerGroupsitem1 = answerGroup.Where(x => x.GroupValue.Contains($"|{item1.Answer}|"));
var itemAnswerGroupsitem2 = answerGroup.Where(x => x.GroupValue.Contains($"|{item2.Answer}|"));
var unionList = itemAnswerGroupsitem1.Intersect(itemAnswerGroupsitem2).ToList();
if (unionList.Count < 1)
{
verificationResults = false;
break;
}
}
}
}
if (!verificationResults)
{
await this.SaveJudgeTask(new SaveJudgeTaskDto() {
VisitTaskIds= visitTaskids,
});
}
}
}
/// <summary>
/// 添加裁判任务
/// </summary>
/// <returns></returns>
private async Task SaveJudgeTask(SaveJudgeTaskDto inDto)
{
var trialId = await _visitTaskRepository.Where(x => inDto.VisitTaskIds.Contains(x.Id)).Select(x => x.TrialId).FirstOrDefaultAsync();
await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
{
JudgeVisitTaskIdList= inDto.VisitTaskIds,
ReadingCategory= ReadingCategory.Judge,
TrialId= trialId
});
}
}
}