|
|
@ -3,11 +3,10 @@ using IRaCIS.Application.Contracts;
|
|
|
|
using IRaCIS.Core.Domain.Share;
|
|
|
|
using IRaCIS.Core.Domain.Share;
|
|
|
|
using EasyCaching.Core;
|
|
|
|
using EasyCaching.Core;
|
|
|
|
using IRaCIS.Core.Application.Filter;
|
|
|
|
using IRaCIS.Core.Application.Filter;
|
|
|
|
using IRaCIS.Core.Infra.EFCore;
|
|
|
|
|
|
|
|
using MassTransit;
|
|
|
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
using Panda.DynamicWebApi.Attributes;
|
|
|
|
using Panda.DynamicWebApi.Attributes;
|
|
|
|
using IRaCIS.Core.Infrastructure;
|
|
|
|
using IRaCIS.Core.Infrastructure;
|
|
|
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
|
|
|
|
|
|
|
namespace IRaCIS.Application.Services
|
|
|
|
namespace IRaCIS.Application.Services
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -20,14 +19,16 @@ namespace IRaCIS.Application.Services
|
|
|
|
private readonly IEasyCachingProvider _provider;
|
|
|
|
private readonly IEasyCachingProvider _provider;
|
|
|
|
private readonly IRepository<Trial> _trialRepository;
|
|
|
|
private readonly IRepository<Trial> _trialRepository;
|
|
|
|
private readonly IRepository<TrialUser> _trialUserRepository;
|
|
|
|
private readonly IRepository<TrialUser> _trialUserRepository;
|
|
|
|
|
|
|
|
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
|
|
|
|
|
|
|
|
|
|
|
|
public bool TrialExpeditedChange { get; set; } = false;
|
|
|
|
public bool TrialExpeditedChange { get; set; } = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public TrialService(IEasyCachingProvider provider,IRepository<Trial> trialRepository,
|
|
|
|
public TrialService(IEasyCachingProvider provider, IRepository<Trial> trialRepository,
|
|
|
|
IRepository<TrialUser> trialUserRepository
|
|
|
|
IRepository<TrialUser> trialUserRepository, IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
_verifyConfig = verifyConfig;
|
|
|
|
_provider = provider;
|
|
|
|
_provider = provider;
|
|
|
|
_trialRepository = trialRepository;
|
|
|
|
_trialRepository = trialRepository;
|
|
|
|
this._trialUserRepository = trialUserRepository;
|
|
|
|
this._trialUserRepository = trialUserRepository;
|
|
|
@ -74,12 +75,12 @@ namespace IRaCIS.Application.Services
|
|
|
|
//过滤废除的项目
|
|
|
|
//过滤废除的项目
|
|
|
|
public async Task<List<TrialSelectDTO>> GetTrialSelect()
|
|
|
|
public async Task<List<TrialSelectDTO>> GetTrialSelect()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return await _trialRepository.AsQueryable().IgnoreQueryFilters()
|
|
|
|
return await _trialRepository.AsQueryable().IgnoreQueryFilters()
|
|
|
|
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.IsDeleted == false)
|
|
|
|
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.IsDeleted == false)
|
|
|
|
|
|
|
|
|
|
|
|
.ProjectTo<TrialSelectDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
|
|
|
.ProjectTo<TrialSelectDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
@ -131,12 +132,10 @@ namespace IRaCIS.Application.Services
|
|
|
|
public virtual async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand trialAddModel)
|
|
|
|
public virtual async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand trialAddModel)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 到时候 策略授权 统一改 归类
|
|
|
|
// 到时候 策略授权 统一改 归类
|
|
|
|
if (!(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin))
|
|
|
|
if (!(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SuperAdmin))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
throw new BusinessValidationFailedException("仅PM/APM可以操作!");
|
|
|
|
throw new BusinessValidationFailedException("仅PM/APM可以操作!");
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (trialAddModel.Id == Guid.Empty || trialAddModel.Id == null)
|
|
|
|
if (trialAddModel.Id == Guid.Empty || trialAddModel.Id == null)
|
|
|
@ -164,7 +163,7 @@ namespace IRaCIS.Application.Services
|
|
|
|
trialAddModel.ModalityIds.ForEach(modalityId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = modalityId, KeyName = StaticData.Modality, TrialId = trial.Id }));
|
|
|
|
trialAddModel.ModalityIds.ForEach(modalityId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = modalityId, KeyName = StaticData.Modality, TrialId = trial.Id }));
|
|
|
|
trialAddModel.CriterionIds.ForEach(criterionId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = criterionId, KeyName = StaticData.Criterion, TrialId = trial.Id }));
|
|
|
|
trialAddModel.CriterionIds.ForEach(criterionId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = criterionId, KeyName = StaticData.Criterion, TrialId = trial.Id }));
|
|
|
|
trialAddModel.ReviewTypeIds.ForEach(ReviewTypeId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = ReviewTypeId, KeyName = StaticData.ReviewType, TrialId = trial.Id }));
|
|
|
|
trialAddModel.ReviewTypeIds.ForEach(ReviewTypeId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = ReviewTypeId, KeyName = StaticData.ReviewType, TrialId = trial.Id }));
|
|
|
|
|
|
|
|
|
|
|
|
//添加项目后 项目状态变更为申请下载简历
|
|
|
|
//添加项目后 项目状态变更为申请下载简历
|
|
|
|
trial.TrialEnrollStatus = (int)TrialEnrollStatus.ChooseDoctor;
|
|
|
|
trial.TrialEnrollStatus = (int)TrialEnrollStatus.ChooseDoctor;
|
|
|
|
//trial.TrialStatusStr = StaticData.TrialInitializing;
|
|
|
|
//trial.TrialStatusStr = StaticData.TrialInitializing;
|
|
|
@ -176,7 +175,7 @@ namespace IRaCIS.Application.Services
|
|
|
|
|
|
|
|
|
|
|
|
//如果是PM, 则需要将该人员添加到 运维人员表
|
|
|
|
//如果是PM, 则需要将该人员添加到 运维人员表
|
|
|
|
//添加运维人员PM
|
|
|
|
//添加运维人员PM
|
|
|
|
await _repository.AddAsync(new TrialUser() { TrialId = trial.Id, UserId = _userInfo.Id ,JoinTime = DateTime.Now});
|
|
|
|
await _repository.AddAsync(new TrialUser() { TrialId = trial.Id, UserId = _userInfo.Id, JoinTime = DateTime.Now });
|
|
|
|
|
|
|
|
|
|
|
|
// 添加扩展信息表记录
|
|
|
|
// 添加扩展信息表记录
|
|
|
|
await _repository.AddAsync(new TrialPaymentPrice() { TrialId = trial.Id });
|
|
|
|
await _repository.AddAsync(new TrialPaymentPrice() { TrialId = trial.Id });
|
|
|
@ -199,7 +198,7 @@ namespace IRaCIS.Application.Services
|
|
|
|
if (!await _repository.AnyAsync<Trial>(u => u.Id == trialAddModel.Id && (u.TrialStatusStr == StaticData.TrialInitializing || u.TrialStatusStr == StaticData.TrialOngoing)))
|
|
|
|
if (!await _repository.AnyAsync<Trial>(u => u.Id == trialAddModel.Id && (u.TrialStatusStr == StaticData.TrialInitializing || u.TrialStatusStr == StaticData.TrialOngoing)))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
throw new BusinessValidationFailedException("项目初始化或者进行中时 才允许操作");
|
|
|
|
throw new BusinessValidationFailedException("项目初始化或者进行中时 才允许操作");
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 判断项目Id 是否已经存在
|
|
|
|
// 判断项目Id 是否已经存在
|
|
|
|
if (await _repository.AnyAsync<Trial>(u => u.TrialCode == updateModel.TrialCode && u.Id != updateModel.Id))
|
|
|
|
if (await _repository.AnyAsync<Trial>(u => u.TrialCode == updateModel.TrialCode && u.Id != updateModel.Id))
|
|
|
@ -231,8 +230,6 @@ namespace IRaCIS.Application.Services
|
|
|
|
|
|
|
|
|
|
|
|
var success = await _repository.SaveChangesAsync();
|
|
|
|
var success = await _repository.SaveChangesAsync();
|
|
|
|
return ResponseOutput.Ok(trial);
|
|
|
|
return ResponseOutput.Ok(trial);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -348,50 +345,110 @@ namespace IRaCIS.Application.Services
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var trial = await _trialRepository.FirstOrDefaultAsync(u => u.Id == trialId);
|
|
|
|
var trial = (await _trialRepository.FirstOrDefaultAsync(u => u.Id == trialId)).IfNullThrowException();
|
|
|
|
if (trial == null) return Null404NotFound(trial);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (trial.VisitPlanConfirmed)
|
|
|
|
|
|
|
|
|
|
|
|
if (_verifyConfig.CurrentValue.OpenTrialRelationDelete )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return ResponseOutput.NotOk("Trial访视计划已经确认,无法删除");
|
|
|
|
|
|
|
|
|
|
|
|
#region 项目真删除废弃
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//if (trial.VisitPlanConfirmed)
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
// return ResponseOutput.NotOk("Trial访视计划已经确认,无法删除");
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//if (await _repository.AnyAsync<Enroll>(u => u.TrialId == trialId))
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
// return ResponseOutput.NotOk("该Trial有医生入组或在入组流程中,无法删除");
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//if (await _repository.AnyAsync<TrialSite>(u => u.TrialId == trialId))
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
// return ResponseOutput.NotOk("该Trial下面有Site,无法删除");
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////PM 可以删除项目 仅仅在没有site 参与者只有他自己的时候
|
|
|
|
|
|
|
|
//if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager)
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
// //参与者仅有他自己时,可以删除
|
|
|
|
|
|
|
|
// if (await _trialUserRepository.CountAsync(t => t.TrialId == trialId) == 1)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// var success1 = await _repository.BatchDeleteAsync<Trial>(o => o.Id == trialId) ||
|
|
|
|
|
|
|
|
// await _repository.BatchDeleteAsync<TrialUser>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
// await _repository.BatchDeleteAsync<TrialDictionary>(t => t.TrialId == trialId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return ResponseOutput.Result(success1);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//if (await _repository.AnyAsync<TrialUser>(u => u.TrialId == trialId))
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
// return ResponseOutput.NotOk("该Trial下面有参与者,无法删除");
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var success = await _repository.BatchDeleteAsync<Trial>(o => o.Id == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialStateChange>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialPaymentPrice>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialUser>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialDictionary>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialSiteUser>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<VisitStage>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialDocument>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialDocNeedConfirmedUserType>(t => t.TrialDocument.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialDocUserTypeConfirmedUser>(t => t.TrialDocument.TrialId == trialId) ||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialPaymentPrice>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialQCQuestion>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialQCQuestionAnswer>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialSiteSurvey>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialSiteUserSurvey>(t => t.TrialSiteSurvey.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialSiteEquipmentSurvey>(t => t.TrialSiteSurvey.TrialId == trialId) ||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<Subject>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<SubjectVisit>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialQCQuestion>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialQCQuestionAnswer>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<DicomStudy>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<StudyMonitor>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<DicomSeries>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<DicomInstance>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<StudyMonitor>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<PreviousHistory>(t => t.SubjectVisit.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<PreviousOther>(t => t.SubjectVisit.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<PreviousPDF>(t => t.SubjectVisit.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<NoneDicomStudyFile>(t => t.NoneDicomStudy.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<NoneDicomStudy>(t => t.TrialId == trialId)
|
|
|
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ResponseOutput.Result(success);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (await _repository.AnyAsync<Enroll>(u => u.TrialId == trialId))
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return ResponseOutput.NotOk("该Trial有医生入组或在入组流程中,无法删除");
|
|
|
|
return ResponseOutput.NotOk("该环境不允许真删除项目数据");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (await _repository.AnyAsync<TrialSite>(u => u.TrialId == trialId))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return ResponseOutput.NotOk("该Trial下面有Site,无法删除");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//PM 可以删除项目 仅仅在没有site 参与者只有他自己的时候
|
|
|
|
|
|
|
|
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//参与者仅有他自己时,可以删除
|
|
|
|
|
|
|
|
if (await _trialUserRepository.CountAsync(t => t.TrialId == trialId) == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var success1 = await _repository.BatchDeleteAsync<Trial>(o => o.Id == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialUser>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialDictionary>(t => t.TrialId == trialId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ResponseOutput.Result(success1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (await _repository.AnyAsync<TrialUser>(u => u.TrialId == trialId))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return ResponseOutput.NotOk("该Trial下面有参与者,无法删除");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var success = await _repository.BatchDeleteAsync<Trial>(o => o.Id == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialUser>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialDictionary>(t => t.TrialId == trialId) ||
|
|
|
|
|
|
|
|
await _repository.BatchDeleteAsync<TrialSiteUser>(t => t.TrialId == trialId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ResponseOutput.Result(success);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -414,7 +471,7 @@ namespace IRaCIS.Application.Services
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// 根据项目Id 获取医生Id,用于出发计算费用
|
|
|
|
/// 根据项目Id 获取医生Id,用于触发计算费用
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
public async Task<List<Guid>> GetTrialEnrollmentReviewerIds(Guid trialId)
|
|
|
|
public async Task<List<Guid>> GetTrialEnrollmentReviewerIds(Guid trialId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|