irc-netcore-api/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs

257 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using IRaCIS.Core.Infrastructure.ExpressionExtend;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Inspection.Interface;
using Newtonsoft.Json;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Domain.Common;
namespace IRaCIS.Core.Application.Services
{
[ApiExplorerSettings(GroupName = "Trial")]
public class SubjectVisitService : BaseService, ISubjectVisitService
{
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IInspectionService _inspectionService;
private readonly IRepository<Subject> _subjectRepository;
public SubjectVisitService(IRepository<SubjectVisit> subjectVisitRepository, IInspectionService inspectionService,IRepository<Subject> subjectRepository)
{
_subjectVisitRepository = subjectVisitRepository;
this._inspectionService = inspectionService;
_subjectRepository = subjectRepository;
}
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter))]
[UnitOfWork]
public async Task<IResponseOutput<string>> AddOrUpdateSV(SubjectVisitCommand svCommand)
{
var verifyExp1 = new EntityVerifyExp<SubjectVisit>()
{
VerifyExp = t => t.VisitNum == svCommand.VisitNum && t.SubjectId == svCommand.SubjectId,
VerifyMsg = "This subject's visit plan already contains a visit with the same visitnum."
};
var verifyExp2 = new EntityVerifyExp<SubjectVisit>()
{
VerifyExp = t => t.SubjectId == svCommand.SubjectId && t.IsFinalVisit,
VerifyMsg = "该受试者已经有访视设置为末次访视,不允许将该访视设置为末次访视",
IsVerify=svCommand.IsFinalVisit
};
svCommand.BlindName = "B" + ((int)(svCommand.VisitNum * 10)).ToString("D3");
svCommand.VisitExecuted = svCommand.IsLostVisit ? VisitExecutedEnum.Executed : svCommand.VisitExecuted;
SubjectVisit dbBeforeEntity = null;
//Add
if (svCommand.Id == null)
{
//设置末次评估后,不允许添加计划外访视
if (svCommand.InPlan == false)
{
if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == svCommand.SubjectId && t.IsFinalVisit))
{
throw new BusinessValidationFailedException("设置末次评估后,不允许添加计划外访视");
}
}
dbBeforeEntity = await _subjectVisitRepository.InsertFromDTOAsync(svCommand, false, verifyExp1, verifyExp2);
}
else
{
dbBeforeEntity = await _subjectVisitRepository.UpdateFromDTOAsync(svCommand, false,false, verifyExp1, verifyExp2);
if (svCommand.PDState != dbBeforeEntity.PDState && dbBeforeEntity.SubmitState == SubmitStateEnum.Submitted)
{
throw new BusinessValidationFailedException("CRC提交后不允许修改PD确认状态");
}
if (svCommand.PDState != dbBeforeEntity.PDState && dbBeforeEntity.RequestBackState == RequestBackStateEnum.PM_AgressBack)
{
throw new BusinessValidationFailedException("回退的访视不允许修改PD确认状态");
}
if (svCommand.IsLostVisit )
{
if (await _subjectVisitRepository.AnyAsync(t => t.Id == svCommand.Id && t.SubmitState == SubmitStateEnum.ToSubmit))
{
throw new BusinessValidationFailedException("该受试者此访视有影像上传,不允许设置为失访");
}
}
}
//更新受试者 首次给药日期 是否入组确认
if (svCommand.SubjectFirstGiveMedicineTime != null && svCommand.IsBaseLine)
{
//await _subjectRepository.UpdatePartialSearchFirstAsync(svCommand.SubjectId,
// u => new Subject() { FirstGiveMedicineTime = svCommand.SubjectFirstGiveMedicineTime });
var subject = (await _subjectRepository.FirstOrDefaultAsync(t => t.Id == svCommand.SubjectId)).IfNullThrowException();
// 更新受试者
subject.FirstGiveMedicineTime = svCommand.SubjectFirstGiveMedicineTime;
List<DataInspection> datas = new List<DataInspection>();
datas.Add(new DataInspection()
{
SubjectId = subject.Id,
SiteId = subject.SiteId,
TrialId = subject.TrialId,
IsSign = false,
Identification = "Edit|Subject|Info|Subject",
CreateTime = DateTime.Now.AddSeconds(1),
JsonDetail = subject.ToJcJson(),
});
await _inspectionService.AddListInspectionRecordAsync(datas);
}
await _repository.SaveChangesAsync();
if (svCommand.Id == null)
{
List<DataInspection> dataInspection=new List<DataInspection>();
dataInspection.Add(new DataInspection()
{
TrialId = svCommand.TrialId,
SiteId = svCommand.SiteId,
SubjectId = svCommand.SubjectId,
SubjectVisitId = svCommand.Id,
SubjectVisitName = svCommand.VisitName,
IsSign = false,
CreateTime = DateTime.Now.AddSeconds(1),
Identification = "Init|Visit|Status|Visit-Image Upload",
JsonDetail = svCommand.ToJcJson()
});
await _inspectionService.AddListInspectionRecordAsync(dataInspection);
}
return ResponseOutput.Ok(dbBeforeEntity.Id.ToString());
}
[HttpPut("{trialId:guid}/{subjectVisitId:guid}/{isUrgent:bool}")]
public async Task<IResponseOutput> SetSubjectVisitUrgent(Guid subjectVisitId, bool isUrgent)
{
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { IsUrgent = isUrgent });
return ResponseOutput.Ok();
}
[HttpDelete, Route("{id:guid}/{trialId:guid}")]
[TrialAudit(AuditType.SubjectAudit, AuditOptType.DeleteSubjectOutPlanVisit)]
[TypeFilter(typeof(TrialResourceFilter))]
public async Task<IResponseOutput> DeleteSV(Guid id)
{
if (await _repository.AnyAsync<DicomStudy>(t => t.SubjectVisitId == id))
{
return ResponseOutput.NotOk("This visit is associated with the uploaded study images and couldn't be deleted.");
}
if (await _subjectVisitRepository.AnyAsync(t => t.Id == id && t.InPlan))
{
return ResponseOutput.NotOk("This visit is InPlan and couldn't be deleted.");
}
if (await _subjectVisitRepository.AnyAsync(t => t.OutPlanPreviousVisitId == id ))
{
return ResponseOutput.NotOk("This visit is OutPlanPreviousVisitId and couldn't be deleted.");
}
return ResponseOutput.Result(await _repository.BatchDeleteAsync<SubjectVisit>(s => s.Id == id));
}
/// <summary>
/// 设置受试者访视已执行 也就是将studyUploaded状态置为true 为了那些没有影像 人工设置准备
/// </summary>
/// <param name="subjectVisitId"></param>
/// <returns></returns>
[HttpPost("{subjectVisitId:guid}/{trialId:guid}")]
[TrialAudit(AuditType.SubjectAudit, AuditOptType.SetSVExecuted)]
[TypeFilter(typeof(TrialResourceFilter))]
public async Task<IResponseOutput> SetSVExecuted(Guid subjectVisitId)
{
return ResponseOutput.Result(await _subjectVisitRepository.BatchUpdateNoTrackingAsync(s => s.Id == subjectVisitId, u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.Executed }));
}
/// <summary>
/// 获取访视下的Dicom 检查信息 分所有的, 阅片的 不阅片 isReading : 0 查询所有 1 查询仅仅阅片的
/// </summary>
/// <param name="trialId"></param>
/// <param name="sujectVisitId"></param>
/// <param name="isReading"></param>
/// <returns></returns>
[HttpGet, Route("{trialId:guid}/{sujectVisitId:guid}/{isReading}")]
[AllowAnonymous]
public async Task<List<VisitStudyDTO>> GetVisitStudyList(Guid trialId, Guid sujectVisitId, int isReading)
{
var studyList = await _repository.Where<DicomStudy>(t => t.TrialId == trialId && t.SubjectVisitId == sujectVisitId).Select(k => new VisitStudyDTO()
{
InstanceCount = k.InstanceCount,
Modalities = k.Modalities,
SeriesCount = k.SeriesCount,
StudyCode = k.StudyCode,
StudyId = k.Id
}).ToListAsync();
var studyIds = studyList.Select(t => t.StudyId).ToList();
var instanceList = await _repository.Where<DicomInstance>(t => studyIds.Contains(t.StudyId))
.Select(t => new { t.SeriesId, t.Id, t.InstanceNumber }).ToListAsync();
foreach (var t in studyList)
{
t.SeriesList = await _repository.Where<DicomSeries>(s => s.StudyId == t.StudyId)
.WhereIf(isReading == 1, s => s.IsReading).OrderBy(s => s.SeriesNumber).
ThenBy(s => s.SeriesTime)
.ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
t.SeriesList.ForEach(series => series.InstanceList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k => k.Id).ToList());
//设置为阅片与否 不更改数据库检查 的instance数量 和 SeriesCount 所以这里要实时统计
t.SeriesCount = t.SeriesList.Count();
t.InstanceCount = t.SeriesList.SelectMany(t => t.InstanceList).Count();
}
return studyList;
//return ResponseOutput.Ok(studyList.Where(t => t.SeriesList.Count > 0).ToList());
}
}
}