814 lines
39 KiB
C#
814 lines
39 KiB
C#
using IRaCIS.Core.Domain.Share;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using IRaCIS.Core.Application.Service.Reading.Dto;
|
|
using IRaCIS.Core.Infra.EFCore.Common;
|
|
using IRaCIS.Core.Application.Contracts;
|
|
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
|
using Panda.DynamicWebApi.Attributes;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using System.Linq.Expressions;
|
|
using IRaCIS.Core.Infrastructure;
|
|
|
|
namespace IRaCIS.Application.Services
|
|
{
|
|
/// <summary>
|
|
/// 阅片临床数据
|
|
/// </summary>
|
|
[ApiExplorerSettings(GroupName = "Reading")]
|
|
public class ReadingClinicalDataService : BaseService, IReadingClinicalDataService
|
|
{
|
|
private readonly IRepository<ReadingClinicalData> _readingClinicalDataRepository;
|
|
private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository;
|
|
private readonly IRepository<VisitTask> _visitTaskRepository;
|
|
private readonly IRepository<PreviousPDF> _previousPDFRepository;
|
|
|
|
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
|
|
private readonly IRepository<PreviousHistory> _previousHistoryRepository;
|
|
private readonly IRepository<PreviousOther> _previousOtherRepository;
|
|
private readonly IRepository<PreviousSurgery> _previousSurgeryRepository;
|
|
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
|
|
private readonly IServiceProvider iServiceProvider;
|
|
private readonly IRepository<Subject> _subjectRepository;
|
|
private readonly IRepository<ReadModule> _readModuleRepository;
|
|
private readonly IRepository<ReadingClinicalDataPDF> _readingClinicalDataPDFRepository;
|
|
|
|
public ReadingClinicalDataService(IRepository<ReadingClinicalData> readingClinicalDataRepository,
|
|
IRepository<ClinicalDataTrialSet> clinicalDataTrialSetRepository,
|
|
IRepository<PreviousPDF> previousPDFRepository,
|
|
IRepository<SubjectVisit> subjectVisitRepository,
|
|
IRepository<PreviousHistory> previousHistoryRepository,
|
|
|
|
IRepository<PreviousOther> previousOtherRepository,
|
|
IRepository<PreviousSurgery> previousSurgeryRepository,
|
|
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository,
|
|
IServiceProvider IServiceProvider,
|
|
IRepository<Subject> subjectRepository,
|
|
|
|
IRepository<ReadModule> readModuleRepository,
|
|
IRepository<ReadingClinicalDataPDF> readingClinicalDataPDFRepository,
|
|
IRepository<VisitTask> visitTaskRepository)
|
|
{
|
|
this._readingClinicalDataRepository = readingClinicalDataRepository;
|
|
this._clinicalDataTrialSetRepository = clinicalDataTrialSetRepository;
|
|
this._previousPDFRepository = previousPDFRepository;
|
|
this._subjectVisitRepository = subjectVisitRepository;
|
|
this._previousHistoryRepository = previousHistoryRepository;
|
|
this._previousOtherRepository = previousOtherRepository;
|
|
this._previousSurgeryRepository = previousSurgeryRepository;
|
|
this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
|
|
this.iServiceProvider = IServiceProvider;
|
|
this._subjectRepository = subjectRepository;
|
|
this._readModuleRepository = readModuleRepository;
|
|
this._readingClinicalDataPDFRepository = readingClinicalDataPDFRepository;
|
|
this._visitTaskRepository = visitTaskRepository;
|
|
}
|
|
|
|
|
|
#region 临床数据基本增删改
|
|
|
|
/// <summary>
|
|
/// 新增或者修改
|
|
/// </summary>
|
|
/// <param name="indto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<IResponseOutput> AddOrUpdateReadingClinicalData(AddOrUpdateReadingClinicalDataDto indto)
|
|
{
|
|
var existsQuery = _readingClinicalDataRepository
|
|
.WhereIf(indto.Id != null, x => x.Id != indto.Id)
|
|
.Where(x => x.ClinicalDataTrialSetId == indto.ClinicalDataTrialSetId && x.ReadingId == indto.ReadingId);
|
|
|
|
|
|
|
|
|
|
if (await existsQuery.AnyAsync())
|
|
{
|
|
//---存在同类型的临床数据,操作失败
|
|
return ResponseOutput.NotOk(_localizer["ReadingClinicalData_DupTypeFail"]);
|
|
}
|
|
var clinicalDataTrialSet = (await _clinicalDataTrialSetRepository.Where(x => x.Id == indto.ClinicalDataTrialSetId).FirstOrDefaultAsync()).IfNullThrowException();
|
|
|
|
//subject 或者访视级别的 都是在访视传
|
|
indto.IsVisit = clinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || clinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit;
|
|
|
|
if (indto.Id == null)
|
|
{
|
|
var entity = _mapper.Map<ReadingClinicalData>(indto);
|
|
entity.ReadingClinicalDataPDFList = indto.AddFileList.Select(x => new ReadingClinicalDataPDF()
|
|
{
|
|
|
|
FileName = x.FileName,
|
|
Path = x.Path,
|
|
|
|
}).ToList();
|
|
|
|
entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
|
|
entity.IsBlind = null;
|
|
entity.IsComplete = null;
|
|
entity.FileCount = entity.ReadingClinicalDataPDFList.Count();
|
|
await _readingClinicalDataRepository.AddAsync(entity, true);
|
|
var success = await _readingClinicalDataRepository.SaveChangesAsync();
|
|
return ResponseOutput.Ok(entity.Id);
|
|
}
|
|
else
|
|
{
|
|
var entity = (await _readingClinicalDataRepository.Where(t => t.Id == indto.Id, true).FirstOrDefaultAsync()).IfNullThrowException();
|
|
await _readingClinicalDataPDFRepository.BatchDeleteNoTrackingAsync(x => indto.DeleteFileIds.Contains(x.Id));
|
|
|
|
var addFileList = indto.AddFileList.Select(x => new ReadingClinicalDataPDF()
|
|
{
|
|
|
|
FileName = x.FileName,
|
|
Path = x.Path,
|
|
|
|
ReadingClinicalDataId = entity.Id,
|
|
}).ToList();
|
|
|
|
|
|
|
|
_mapper.Map(indto, entity);
|
|
|
|
//上传 或者删除了文件 核查状态需要重新确认
|
|
|
|
if (indto.AddFileList.Count > 0 || indto.AddFileList.Count > 0)
|
|
{
|
|
entity.IsComplete = null;
|
|
entity.IsBlind = null;
|
|
}
|
|
|
|
await _readingClinicalDataPDFRepository.AddRangeAsync(addFileList);
|
|
|
|
await _readingClinicalDataPDFRepository.SaveChangesAsync();
|
|
|
|
var fileCount = await _readingClinicalDataPDFRepository.Where(t => t.ReadingClinicalDataId == indto.Id).CountAsync();
|
|
entity.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded;
|
|
entity.FileCount = fileCount;
|
|
var success = await _readingClinicalDataRepository.SaveChangesAsync();
|
|
return ResponseOutput.Ok(entity.Id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 删除
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id:guid}")]
|
|
public async Task<IResponseOutput> DeleteReadingClinicalData(Guid id)
|
|
{
|
|
|
|
await _readingClinicalDataRepository.DeleteFromQueryAsync(x => x.Id == id, true);
|
|
await _readingClinicalDataPDFRepository.DeleteFromQueryAsync(x => x.ReadingClinicalDataId == id, true);
|
|
return ResponseOutput.Result(true);
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region 临床数据CRC 相关
|
|
|
|
/// <summary>
|
|
/// 获取CRC上传的文件
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<List<GetCRCClinicalDataOutDto>> GetCRCClinicalData(GetCRCClinicalDataInDto inDto)
|
|
{
|
|
//if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator)
|
|
//{
|
|
// await this.AddCRCClinicalData(inDto);
|
|
//}
|
|
|
|
|
|
List<GetCRCClinicalDataOutDto> cRCClinicalDataList = await _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.SubjectVisitId)
|
|
.WhereIf(inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
|
|
.WhereIf(!inDto.IsBaseline, x => x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
|
|
.Where(x => x.ClinicalDataTrialSet.TrialId == inDto.TrialId && x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC)
|
|
.Select(x => new GetCRCClinicalDataOutDto()
|
|
{
|
|
Id = x.Id,
|
|
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us) ,
|
|
ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
|
|
ClinicalDataSetEnName=x.ClinicalDataTrialSet.ClinicalDataSetEnName,
|
|
ClinicalDataTrialSetId = x.ClinicalDataTrialSet.Id,
|
|
FileName = x.ClinicalDataTrialSet.FileName,
|
|
UploadRole = x.ClinicalDataTrialSet.UploadRole,
|
|
Path = x.ClinicalDataTrialSet.Path,
|
|
IsBlind = x.IsBlind,
|
|
IsComplete = x.IsComplete,
|
|
PDFFileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
|
|
{
|
|
Id = y.Id,
|
|
FileName = y.FileName,
|
|
Path = y.Path,
|
|
CreateTime = y.CreateTime,
|
|
}).ToList()
|
|
}).ToListAsync();
|
|
|
|
List<GetReadingClinicalDataListOutDto> clinicalData = (await this.GetReadingClinicalDataList(new GetReadingClinicalDataListIndto()
|
|
{
|
|
SubjectId = inDto.SubjectId,
|
|
ReadingId = inDto.SubjectVisitId,
|
|
TrialId = inDto.TrialId,
|
|
})).Item1;
|
|
|
|
var previousHistoryList = await _previousHistoryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
var previousOtherList = await _previousOtherRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousOtherView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
var previousSurgeryList = await _previousSurgeryRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId).ProjectTo<PreviousSurgeryView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
|
|
foreach (var item in cRCClinicalDataList)
|
|
{
|
|
//item.PDFFileList = clinicalData.Where(y => y.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).SelectMany(x => x.FileList).ToList();
|
|
item.ClinicalTableData = new ClinicalDataTable()
|
|
{
|
|
PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
|
PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
|
PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
|
};
|
|
|
|
}
|
|
return cRCClinicalDataList;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 添加CRC数据类型
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private async Task AddCRCClinicalData(GetCRCClinicalDataInDto inDto)
|
|
{
|
|
var cRCClinicalDataIds = await _clinicalDataTrialSetRepository.Where(x => x.TrialId == inDto.TrialId && x.UploadRole == UploadRole.CRC && x.IsConfirm)
|
|
.WhereIf(inDto.IsBaseline, x => x.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
|
|
.WhereIf(!inDto.IsBaseline, x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
|
|
.Select(x => x.Id).ToListAsync();
|
|
|
|
var needAddIds = cRCClinicalDataIds.Where(x => _readingClinicalDataRepository.Where(y => y.ReadingId == inDto.SubjectVisitId && x == y.ClinicalDataTrialSetId).Count() == 0).ToList();
|
|
|
|
List<ReadingClinicalData> readingClinicals = needAddIds.Select(x => new ReadingClinicalData()
|
|
{
|
|
ClinicalDataTrialSetId = x,
|
|
IsVisit = true,
|
|
SubjectId = inDto.SubjectId,
|
|
ReadingId = inDto.SubjectVisitId,
|
|
TrialId = inDto.TrialId
|
|
}).ToList();
|
|
|
|
await _readingClinicalDataRepository.AddRangeAsync(readingClinicals);
|
|
|
|
await _readingClinicalDataRepository.SaveChangesAsync();
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region 临床数据签名 和确认
|
|
|
|
/// <summary>
|
|
/// 影像阅片临床数据签名
|
|
/// </summary>
|
|
// [HttpPost]
|
|
|
|
public async Task<IResponseOutput> ReadClinicalDataSign(ReadingClinicalDataSignIndto inDto)
|
|
{
|
|
|
|
|
|
var data = await _readingClinicalDataRepository.FirstOrDefaultAsync(t => t.Id == inDto.ReadingClinicalDataId);
|
|
|
|
//if (data.ReadingClinicalDataState != ReadingClinicalDataStatus.HaveChecked)
|
|
//{
|
|
// //---当前临床数据状态不是已核查状态,不允许签名!
|
|
// throw new BusinessValidationFailedException(_localizer["ReadingClinicalData_Unchecked"]);
|
|
//}
|
|
|
|
data.IsBlind = inDto.IsBlind;
|
|
data.IsComplete=inDto.IsComplete;
|
|
data.IsSign = true;
|
|
data.ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned;
|
|
|
|
//await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.ReadingClinicalDataId, x => new ReadingClinicalData()
|
|
//{
|
|
// IsSign = true,
|
|
// ReadingClinicalDataState = ReadingClinicalDataStatus.HaveSigned
|
|
//});
|
|
|
|
var result = await _readingClinicalDataRepository.SaveChangesAsync();
|
|
|
|
|
|
var readingId = await _readingClinicalDataRepository.Where(x => x.Id == inDto.ReadingClinicalDataId).Select(x => x.ReadingId).FirstOrDefaultAsync();
|
|
|
|
await this.iServiceProvider.GetService<IReadingImageTaskService>().AddOncologyTask(readingId);
|
|
|
|
await DealVisiTaskClinicalDataSignedAsync(data.TrialId, data.SubjectId, data.ReadingId, data.IsVisit, inDto.TrialReadingCriterionId);
|
|
|
|
return ResponseOutput.Result(result);
|
|
}
|
|
|
|
//处理 任务 临床数据是否签名
|
|
private async Task DealVisiTaskClinicalDataSignedAsync(Guid trialId, Guid subjectId, Guid readingId, bool isVisit, Guid trialReadingCritrialId)
|
|
{
|
|
//获取确认的临床数据配置
|
|
var trialClinicalDataSetList = _clinicalDataTrialSetRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList();
|
|
|
|
//var criterionType = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == trialReadingCritrialId).Select(t => t.CriterionType).FirstOrDefaultAsync();
|
|
|
|
// 获取确认的项目标准 废弃 签名的时候 传递标准Id
|
|
//var confirmedCtritrialList = _repository.Where<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId && t.ReadingInfoSignTime != null).Select(t => new { t.Id, t.CriterionType }).ToList();
|
|
|
|
var needSignCount = 0;
|
|
var haveSignedCount = _readingClinicalDataRepository.Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count();
|
|
|
|
|
|
if (isVisit)
|
|
{
|
|
var isBaseLine = await _subjectVisitRepository.Where(t => t.Id == readingId).Select(t => t.IsBaseLine).FirstOrDefaultAsync();
|
|
|
|
//判断是否基线
|
|
if (isBaseLine)
|
|
{
|
|
//CRC 的自动签名 不用管 只用处理PM 的就好
|
|
needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && (t.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataLevel == ClinicalLevel.SubjectVisit) && t.UploadRole == UploadRole.PM).Count();
|
|
}
|
|
else
|
|
{
|
|
needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.SubjectVisit && t.UploadRole == UploadRole.PM).Count();
|
|
}
|
|
|
|
//可能仅仅CRC 基线 没有PM
|
|
if (needSignCount == haveSignedCount /*&& needSignCount != 0*/)
|
|
{
|
|
|
|
//将该标准 该subject 该访视 任务临床数据状态变更
|
|
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCritrialId && t.SourceSubjectVisitId == readingId, u => new VisitTask()
|
|
{
|
|
IsClinicalDataSign = true
|
|
});
|
|
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
//判断是影像学 还是肿瘤学阅片
|
|
var readingSetType = await _readModuleRepository.Where(t => t.Id == readingId).Select(t => t.ReadingSetType).FirstOrDefaultAsync();
|
|
|
|
//影像学
|
|
if (readingSetType == ReadingSetType.ImageReading)
|
|
{
|
|
needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.ImageRead).Count();
|
|
}
|
|
//肿瘤学
|
|
else
|
|
{
|
|
needSignCount = trialClinicalDataSetList.Where(t => t.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == trialReadingCritrialId) && t.ClinicalDataLevel == ClinicalLevel.OncologyRead).Count();
|
|
}
|
|
|
|
//可能仅仅CRC 基线 没有PM
|
|
if (needSignCount == haveSignedCount /*&& needSignCount != 0*/)
|
|
{
|
|
//将该标准 该subject 该阅片期|肿瘤学 任务临床数据状态变更
|
|
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCritrialId && t.SouceReadModuleId == readingId, u => new VisitTask()
|
|
{
|
|
IsClinicalDataSign = true
|
|
});
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//有序阅片才维护 IsFrontTaskNeedSignButNotSign 这个状态
|
|
if (_readingQuestionCriterionTrialRepository.Any(t=>t.Id==trialReadingCritrialId && t.IsReadingTaskViewInOrder == true))
|
|
{
|
|
|
|
|
|
Expression<Func<VisitTask, bool>> visitTaskLambda = x => x.TrialId == trialId && x.SubjectId == subjectId && x.TrialReadingCriterionId == trialReadingCritrialId;
|
|
|
|
|
|
//维护 IsFrontTaskNeedSignButNotSign 在添加任务哪里用触发器也维护了
|
|
var visitTaskIdQueryable = _visitTaskRepository.Where(visitTaskLambda) //该Subject 该标准的任务
|
|
//小于自己任务号的任务 存在需要签名 但是没签名
|
|
.Where(t => t.IsFrontTaskNeedSignButNotSign == false &&
|
|
|
|
(t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)
|
|
|
|
// 前序存在 未一致性核查未通过的
|
|
|| t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum>sv.VisitNum)
|
|
|
|
))
|
|
.Select(t => t.Id);
|
|
|
|
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable.Contains(t.Id), u => new VisitTask()
|
|
{
|
|
IsFrontTaskNeedSignButNotSign = true
|
|
});
|
|
|
|
|
|
|
|
var visitTaskIdQueryable2 = _visitTaskRepository.Where(visitTaskLambda) //该Subject 该标准的任务
|
|
|
|
.Where(t => t.IsFrontTaskNeedSignButNotSign == true &&
|
|
|
|
//前序任务 不存在需要签名 但是没签名
|
|
!t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum)
|
|
|
|
// 前序 不存在 未一致性核查未通过的
|
|
&& !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)
|
|
)
|
|
.Select(t => t.Id);
|
|
|
|
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => visitTaskIdQueryable2.Contains(t.Id), u => new VisitTask()
|
|
{
|
|
IsFrontTaskNeedSignButNotSign = false
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 废弃 接口合并到签名哪里
|
|
|
|
[HttpPut]
|
|
public async Task<IResponseOutput> PMClinicalDataConfirm(PMClinicalDataConfirmCommand command)
|
|
{
|
|
await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(t => t.Id == command.Id, u => new ReadingClinicalData()
|
|
{
|
|
IsBlind = command.IsBlind,
|
|
IsComplete = command.IsComplete,
|
|
ReadingClinicalDataState = ReadingClinicalDataStatus.HaveChecked
|
|
});
|
|
|
|
await _readingClinicalDataRepository.SaveChangesAsync();
|
|
|
|
return ResponseOutput.Ok();
|
|
|
|
|
|
}
|
|
#endregion
|
|
|
|
|
|
#region 临床数据相关查询
|
|
/// <summary>
|
|
/// 获取下拉菜单
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<List<GetTrialClinicalDataSelectOutDto>> GetTrialClinicalDataSelect(GetTrialClinicalDataSelectIndto inDto)
|
|
{
|
|
var userTypes = new List<int>() {
|
|
(int)UserTypeEnum.ProjectManager,
|
|
(int)UserTypeEnum.SPM,
|
|
(int)UserTypeEnum.CPM,
|
|
(int)UserTypeEnum.IndependentReviewer,
|
|
};
|
|
|
|
|
|
|
|
if (userTypes.Contains(_userInfo.UserTypeEnumInt))
|
|
{
|
|
inDto.UploadRole = UploadRole.PM;
|
|
}
|
|
|
|
ReadModule readModule = null;
|
|
if (inDto.IsVisit == false)
|
|
{
|
|
readModule = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId).FirstOrDefaultAsync();
|
|
}
|
|
|
|
Dictionary<ModuleTypeEnum, ClinicalLevel> keyValuePairs = new Dictionary<ModuleTypeEnum, ClinicalLevel>();
|
|
keyValuePairs.Add(ModuleTypeEnum.Global, ClinicalLevel.ImageRead);
|
|
keyValuePairs.Add(ModuleTypeEnum.Oncology, ClinicalLevel.OncologyRead);
|
|
|
|
|
|
|
|
|
|
|
|
var usedIdsQuery = _readingClinicalDataRepository.Where(x => x.ReadingId == inDto.ReadingId && x.Id != inDto.ReadingClinicalDataId).Select(x => x.ClinicalDataTrialSetId);
|
|
|
|
List<GetTrialClinicalDataSelectOutDto> clinicalList = await _clinicalDataTrialSetRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm)
|
|
.WhereIf(inDto.UploadRole != null, x => x.UploadRole == inDto.UploadRole)
|
|
.Where(x => !usedIdsQuery.Contains(x.Id))
|
|
|
|
|
|
|
|
.WhereIf(inDto.IsVisit && inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.Subject || x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
|
|
.WhereIf(inDto.IsVisit && !inDto.IsBaseLine, x => x.ClinicalDataLevel == ClinicalLevel.SubjectVisit)
|
|
.WhereIf(!inDto.IsVisit, x => x.ClinicalDataLevel == ClinicalLevel.ImageRead || x.ClinicalDataLevel == ClinicalLevel.OncologyRead)
|
|
.WhereIf(readModule != null, x => x.ClinicalDataLevel == keyValuePairs[readModule.ModuleType])
|
|
.WhereIf(inDto.TrialReadingCriterionId!=null,x=>x.TrialClinicalDataSetCriteriaList.Any(y=>y.TrialReadingCriterionId== inDto.TrialReadingCriterionId))
|
|
//.WhereIf(criterion!=null,x=>x.CriterionEnumListStr.Contains($"|{(int)criterion.CriterionType}|"))
|
|
.Select(x => new GetTrialClinicalDataSelectOutDto()
|
|
{
|
|
ClinicalDataLevel = x.ClinicalDataLevel,
|
|
ClinicalDataSetName = x.ClinicalDataSetName.LanguageName(x.ClinicalDataSetEnName, _userInfo.IsEn_Us),
|
|
ClinicalDataSetEnName=x.ClinicalDataSetEnName,
|
|
ClinicalUploadType = x.ClinicalUploadType,
|
|
FileName = x.FileName,
|
|
Path = x.Path,
|
|
Id = x.Id,
|
|
CriterionEnumList = x.CriterionEnumList,
|
|
}).ToListAsync();
|
|
|
|
return clinicalList;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取访视 阅片或任务临床数据
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<(List<GetReadingClinicalDataListOutDto>, object)> GetReadingOrTaskClinicalDataList(GetReadingOrTaskClinicalDataListInDto inDto)
|
|
{
|
|
var readingNameOrTaskBlindName = string.Empty;
|
|
if (inDto.ReadingId == null)
|
|
{
|
|
var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId);
|
|
inDto.ReadingId = visitTask.SouceReadModuleId ?? visitTask.SourceSubjectVisitId;
|
|
readingNameOrTaskBlindName = visitTask.TaskBlindName;
|
|
}
|
|
|
|
if (readingNameOrTaskBlindName.IsNullOrEmpty())
|
|
{
|
|
readingNameOrTaskBlindName = await _subjectVisitRepository.Where(x => x.Id == inDto.ReadingId).Select(x => x.VisitName).FirstOrDefaultAsync();
|
|
if (readingNameOrTaskBlindName.IsNullOrEmpty())
|
|
{
|
|
readingNameOrTaskBlindName = await _readModuleRepository.Where(x => x.Id == inDto.ReadingId).Select(x => x.ModuleName).FirstOrDefaultAsync();
|
|
|
|
}
|
|
}
|
|
inDto.SelectIsSign = false;
|
|
var result = await GetClinicalDataList(inDto);
|
|
|
|
var readingIds = result.Select(x => x.ReadingId).ToList();
|
|
|
|
var previousHistoryList = await _previousHistoryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
var previousOtherList = await _previousOtherRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo<PreviousOtherView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
var previousSurgeryList = await _previousSurgeryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo<PreviousSurgeryView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
foreach (var item in result)
|
|
{
|
|
item.ClinicalTableData = new ClinicalDataTable()
|
|
{
|
|
PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
|
PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
|
PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
|
};
|
|
|
|
}
|
|
|
|
Dictionary<ClinicalLevel, int> keys = new Dictionary<ClinicalLevel, int>() {
|
|
{ClinicalLevel.SubjectVisit,0 },
|
|
{ClinicalLevel.ImageRead,2 },
|
|
{ClinicalLevel.OncologyRead,3 },
|
|
{ClinicalLevel.Subject,4 },
|
|
};
|
|
|
|
result = result.OrderBy(x => keys[x.ClinicalDataLevel]).ToList();
|
|
|
|
return (result, new
|
|
{
|
|
SubjectCode = await _subjectRepository.Where(x => x.Id == inDto.SubjectId).Select(x => x.Code).FirstOrDefaultAsync(),
|
|
ReadingNameOrTaskBlindName = readingNameOrTaskBlindName,
|
|
});
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取阅片临床数据列表
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<(List<GetReadingClinicalDataListOutDto>, object)> GetReadingClinicalDataList(GetReadingClinicalDataListIndto inDto)
|
|
{
|
|
var getTrialClinicalDataSelectIndto = new GetTrialClinicalDataSelectIndto()
|
|
{
|
|
ReadingId = inDto.ReadingId,
|
|
TrialId = inDto.TrialId,
|
|
IsBaseLine = inDto.IsBaseLine,
|
|
SubjectId = inDto.SubjectId,
|
|
IsVisit = inDto.IsVisit,
|
|
TrialReadingCriterionId = inDto.TrialReadingCriterionId
|
|
};
|
|
|
|
var clinicalDataList = await this.GetTrialClinicalDataSelect(getTrialClinicalDataSelectIndto);
|
|
|
|
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC)
|
|
{
|
|
inDto.UploadRole = UploadRole.CRC;
|
|
}
|
|
var isBaseLine = await _subjectVisitRepository.AnyAsync(x => x.Id == inDto.ReadingId && x.IsBaseLine);
|
|
|
|
|
|
var result = await this.GetReadingClinicalList(inDto);
|
|
var readingIds = result.Select(x => x.ReadingId).ToList();
|
|
|
|
var previousHistoryList = await _previousHistoryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo<PreviousHistoryView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
var previousOtherList = await _previousOtherRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo<PreviousOtherView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
var previousSurgeryList = await _previousSurgeryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).ProjectTo<PreviousSurgeryView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
foreach (var item in result)
|
|
{
|
|
item.ClinicalTableData = new ClinicalDataTable()
|
|
{
|
|
PreviousHistoryList = previousHistoryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
|
PreviousOtherList = previousOtherList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
|
PreviousSurgeryList = previousSurgeryList.Where(x => x.ClinicalDataTrialSetId == item.ClinicalDataTrialSetId).ToList(),
|
|
};
|
|
|
|
}
|
|
|
|
return (result, new
|
|
{
|
|
IsCanAddClinicalData = clinicalDataList.Count() > 0,
|
|
});
|
|
}
|
|
|
|
[NonDynamicMethod]
|
|
public async Task<List<GetReadingClinicalDataListOutDto>> GetClinicalDataList(GetReadingOrTaskClinicalDataListInDto inDto)
|
|
{
|
|
|
|
if (inDto.ReadingId == null)
|
|
{
|
|
var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId);
|
|
inDto.ReadingId = visitTask.SouceReadModuleId ?? visitTask.SourceSubjectVisitId;
|
|
}
|
|
|
|
|
|
var resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId)
|
|
.WhereIf(inDto.ReadingClinicalDataId != null, x => x.Id == inDto.ReadingClinicalDataId)
|
|
.WhereIf(inDto.SelectIsSign, x => x.IsSign == true)
|
|
.Where(x => x.ReadingId == inDto.ReadingId || (x.SubjectId == inDto.SubjectId && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject))
|
|
.Select(x => new GetReadingClinicalDataListOutDto()
|
|
{
|
|
ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
|
|
SubjectId = x.SubjectId,
|
|
ReadingId = x.ReadingId,
|
|
ClinicalDataSetEnName=x.ClinicalDataTrialSet.ClinicalDataSetEnName,
|
|
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
|
|
ClinicalDataTrialSetId = x.ClinicalDataTrialSetId,
|
|
IsSign = x.IsSign,
|
|
ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
|
|
CriterionEnumList = x.ClinicalDataTrialSet.CriterionEnumList,
|
|
TrialClinicalDataSetCriteriaList=x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList,
|
|
Id = x.Id,
|
|
UploadRole = x.ClinicalDataTrialSet.UploadRole,
|
|
IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC,
|
|
FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
|
|
{
|
|
Id = y.Id,
|
|
FileName = y.FileName,
|
|
Path = y.Path,
|
|
CreateTime = y.CreateTime,
|
|
}).ToList()
|
|
});
|
|
|
|
|
|
var result = await resultQuery.ToListAsync();
|
|
// 根据标准
|
|
if (inDto.VisitTaskId != null)
|
|
{
|
|
var visitTaskInfo = await _visitTaskRepository.FirstOrDefaultAsync(x => x.Id == inDto.VisitTaskId);
|
|
|
|
result = result.Where(x => x.TrialClinicalDataSetCriteriaList.Any(z=>z.TrialReadingCriterionId==visitTaskInfo.TrialReadingCriterionId)).ToList();
|
|
}
|
|
|
|
|
|
result = result.Where(x => !(x.ClinicalUploadType == ClinicalUploadType.PDF && x.FileList.Count() == 0)).ToList();
|
|
// 需要排除表格为空的数据
|
|
|
|
|
|
var readingIds = result.Select(x => x.ReadingId).ToList();
|
|
|
|
var tablecount = (await _previousHistoryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).CountAsync()) +
|
|
(await _previousOtherRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).CountAsync()) +
|
|
(await _previousSurgeryRepository.Where(x => readingIds.Contains(x.SubjectVisitId)).CountAsync());
|
|
|
|
if (tablecount == 0)
|
|
{
|
|
result = result.Where(x => x.ClinicalUploadType != ClinicalUploadType.Table).ToList();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取临床数据集合
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonDynamicMethod]
|
|
public async Task<List<GetReadingClinicalDataListOutDto>> GetReadingClinicalList(GetReadingClinicalDataListIndto inDto)
|
|
{
|
|
|
|
//var criterionType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => x.CriterionType).FirstNotNullAsync();
|
|
|
|
|
|
var resultQuery = _readingClinicalDataRepository.Where(x => x.SubjectId == inDto.SubjectId)
|
|
.Where(x => x.ReadingId == inDto.ReadingId || (x.SubjectId == inDto.SubjectId && x.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject))
|
|
//.WhereIf(inDto.UploadRole == UploadRole.CRC, x => x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC)
|
|
|
|
.Where(x => x.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(t=>t.TrialReadingCriterionId==inDto.TrialReadingCriterionId))
|
|
.Select(x => new GetReadingClinicalDataListOutDto()
|
|
{
|
|
ClinicalDataLevel = x.ClinicalDataTrialSet.ClinicalDataLevel,
|
|
SubjectId = x.SubjectId,
|
|
ReadingId = x.ReadingId,
|
|
ClinicalDataSetName = x.ClinicalDataTrialSet.ClinicalDataSetName.LanguageName(x.ClinicalDataTrialSet.ClinicalDataSetEnName, _userInfo.IsEn_Us),
|
|
ClinicalDataSetEnName =x.ClinicalDataTrialSet.ClinicalDataSetEnName,
|
|
ClinicalDataTrialSetId = x.ClinicalDataTrialSetId,
|
|
IsSign = x.IsSign,
|
|
ClinicalUploadType = x.ClinicalDataTrialSet.ClinicalUploadType,
|
|
Id = x.Id,
|
|
UploadRole = x.ClinicalDataTrialSet.UploadRole,
|
|
IsCRCUpload = x.ClinicalDataTrialSet.UploadRole == UploadRole.CRC,
|
|
IsBlind = x.IsBlind,
|
|
IsComplete = x.IsComplete,
|
|
FileCount = x.FileCount,
|
|
|
|
ReadingClinicalDataState = x.ReadingClinicalDataState,
|
|
|
|
FileList = x.ReadingClinicalDataPDFList.Select(y => new GetFileDto()
|
|
{
|
|
Id = y.Id,
|
|
FileName = y.FileName,
|
|
Path = y.Path,
|
|
CreateTime = y.CreateTime,
|
|
}).ToList()
|
|
});
|
|
|
|
var result = await resultQuery.ToListAsync();
|
|
//result = result.Where(x => !(x.UploadRole == UploadRole.CRC && x.ClinicalUploadType == ClinicalUploadType.PDF && x.FileList.Count() == 0)).ToList();
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region 阅片临床数据PDF
|
|
|
|
/// <summary>
|
|
/// 获取单个阅片临床数据的所有文件
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<PageOutput<GetReadingClinicalDataPDFListOutDto>> GetReadingClinicalDataPDFList(GetReadingClinicalDataPDFListIndto inDto)
|
|
{
|
|
|
|
var result = await _readingClinicalDataPDFRepository.Where(x => x.ReadingClinicalDataId == inDto.ReadingClinicalDataId).ProjectTo<GetReadingClinicalDataPDFListOutDto>(_mapper.ConfigurationProvider)
|
|
.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, inDto.SortField == null ? nameof(GetReadingClinicalDataPDFListOutDto.FileName) : inDto.SortField,
|
|
inDto.Asc);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 删除PDF单个文件
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
[HttpDelete("{id:guid}")]
|
|
public async Task<IResponseOutput> DeleteReadingClinicalDataPDF(Guid id)
|
|
{
|
|
var pdf = await _readingClinicalDataPDFRepository.FirstOrDefaultAsync(t => t.Id == id);
|
|
|
|
await _readingClinicalDataPDFRepository.DeleteAsync(pdf, true);
|
|
|
|
var fileCount = await _readingClinicalDataPDFRepository.Where(t => t.ReadingClinicalDataId == pdf.ReadingClinicalDataId).CountAsync();
|
|
|
|
await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(pdf.ReadingClinicalDataId, c => new ReadingClinicalData() { FileCount = fileCount }, true);
|
|
|
|
return ResponseOutput.Result(true);
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
///// <summary>
|
|
///// 设置临床数据是否盲化
|
|
///// </summary>
|
|
///// <returns></returns>
|
|
//[HttpPost]
|
|
//public async Task<IResponseOutput> SetReadingClinicalDataIsBlind(SetReadingClinicalDataIsBlind inDto)
|
|
//{
|
|
// await _readingClinicalDataRepository.UpdatePartialFromQueryAsync(inDto.Id, x=>new ReadingClinicalData() {
|
|
// IsBlind=inDto.IsBlind,
|
|
// });
|
|
// return ResponseOutput.Ok(await _readingClinicalDataRepository.SaveChangesAsync());
|
|
//}
|
|
|
|
}
|
|
}
|