696 lines
35 KiB
C#
696 lines
35 KiB
C#
using IRaCIS.Application.Interfaces;
|
||
using IRaCIS.Application.Contracts;
|
||
using IRaCIS.Core.Domain.Share;
|
||
using EasyCaching.Core;
|
||
using IRaCIS.Core.Application.Filter;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Panda.DynamicWebApi.Attributes;
|
||
using IRaCIS.Core.Infrastructure;
|
||
using Microsoft.Extensions.Options;
|
||
using static IRaCIS.Core.Domain.Share.StaticData;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using System.Linq.Expressions;
|
||
using System.Linq;
|
||
using IRaCIS.Core.Domain.Models;
|
||
using IRaCIS.Core.Application.Helper;
|
||
using ZiggyCreatures.Caching.Fusion;
|
||
|
||
namespace IRaCIS.Application.Services
|
||
{
|
||
|
||
[ApiExplorerSettings(GroupName = "Trial")]
|
||
|
||
public class TrialService : BaseService, ITrialService
|
||
{
|
||
|
||
private readonly IRepository<Trial> _trialRepository;
|
||
private readonly IRepository<TrialUser> _trialUserRepository;
|
||
private readonly IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig;
|
||
|
||
public bool TrialExpeditedChange { get; set; } = false;
|
||
|
||
|
||
public TrialService(IRepository<Trial> trialRepository,
|
||
IRepository<TrialUser> trialUserRepository, IOptionsMonitor<ServiceVerifyConfigOption> verifyConfig
|
||
)
|
||
{
|
||
_verifyConfig = verifyConfig;
|
||
_trialRepository = trialRepository;
|
||
this._trialUserRepository = trialUserRepository;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 分页获取临床项目列表 默认后台加急状态为3 查所有的
|
||
/// </summary>
|
||
/// <param name="searchParam"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<PageOutput<TrialDetailDTO>> GetTrialList(TrialQueryDTO searchParam)
|
||
{
|
||
|
||
var multiModalityIdSelectCount = searchParam.ModalityIds.Count;
|
||
var multiCriteriaSelectCount = searchParam.CriterionIds.Count;
|
||
var multiReviewTypeSelectCount = searchParam.ReviewTypeIds.Count;
|
||
|
||
Expression<Func<Trial, bool>> trialDeclarationTypeExpression = x => true;
|
||
|
||
|
||
|
||
foreach (var item in searchParam.DeclarationTypeEnumList)
|
||
{
|
||
trialDeclarationTypeExpression = trialDeclarationTypeExpression.And(t => t.DeclarationTypes.Contains($"|{item}|"));
|
||
}
|
||
|
||
Expression<Func<Trial, bool>> trialAttendedReviewerTypeExpression = x => true;
|
||
|
||
foreach (var item in searchParam.AttendedReviewerTypeEnumList)
|
||
{
|
||
trialAttendedReviewerTypeExpression = trialAttendedReviewerTypeExpression.And(t => t.AttendedReviewerTypes.Contains($"|{item}|"));
|
||
}
|
||
|
||
|
||
var query = _trialRepository.AsQueryable()
|
||
.WhereIf(!string.IsNullOrEmpty(searchParam.TrialStatusStr), o => o.TrialStatusStr.Contains(searchParam.TrialStatusStr))
|
||
.WhereIf(searchParam.SponsorId != null, o => o.SponsorId == searchParam.SponsorId)
|
||
.WhereIf(searchParam.Expedited != null, o => o.Expedited == searchParam.Expedited)
|
||
.WhereIf(!string.IsNullOrEmpty(searchParam.Code), o => o.TrialCode.Contains(searchParam.Code))
|
||
.WhereIf(!string.IsNullOrWhiteSpace(searchParam.Indication), o => o.Indication.Contains(searchParam.Indication))
|
||
.WhereIf(!string.IsNullOrEmpty(searchParam.ResearchProgramNo), o => o.ResearchProgramNo.Contains(searchParam.ResearchProgramNo))
|
||
.WhereIf(!string.IsNullOrWhiteSpace(searchParam.ExperimentName), o => o.ExperimentName.Contains(searchParam.ExperimentName))
|
||
.WhereIf(searchParam.PhaseId != null, o => o.PhaseId == searchParam.PhaseId)
|
||
|
||
.WhereIf(searchParam.DeclarationTypeEnumList.Count > 0, trialDeclarationTypeExpression)
|
||
.WhereIf(searchParam.AttendedReviewerTypeEnumList.Count > 0, trialAttendedReviewerTypeExpression)
|
||
|
||
//.WhereIf(searchParam.AttendedReviewerType != null, o => o.AttendedReviewerType == searchParam.AttendedReviewerType)
|
||
|
||
.WhereIf(searchParam.IndicationTypeId != null, o => o.IndicationTypeId == searchParam.IndicationTypeId)
|
||
.WhereIf(searchParam.CROId != null, o => o.CROId == searchParam.CROId)
|
||
.WhereIf(searchParam.BeginDate != null, o => o.CreateTime >= searchParam.BeginDate)
|
||
.WhereIf(searchParam.EndDate != null, o => o.CreateTime <= searchParam.EndDate)
|
||
|
||
.WhereIf(multiModalityIdSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.Modality) == multiModalityIdSelectCount)
|
||
.WhereIf(multiCriteriaSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.Criterion) == multiCriteriaSelectCount)
|
||
.WhereIf(multiReviewTypeSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.ReviewType) == multiReviewTypeSelectCount)
|
||
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id && t.IsDeleted == false) && t.IsDeleted == false)
|
||
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id, isEn_Us = _userInfo.IsEn_Us });
|
||
|
||
return await query.ToPagedListAsync(searchParam.PageIndex, searchParam.PageSize, string.IsNullOrWhiteSpace(searchParam.SortField) ? "CreateTime" : searchParam.SortField, searchParam.Asc);
|
||
|
||
|
||
}
|
||
|
||
//过滤废除的项目
|
||
public async Task<List<TrialSelectDTO>> GetTrialSelect()
|
||
{
|
||
return await _trialRepository.AsQueryable()
|
||
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id) && t.IsDeleted == false)
|
||
|
||
.ProjectTo<TrialSelectDTO>(_mapper.ConfigurationProvider).ToListAsync();
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 获取项目基本信息
|
||
/// </summary>
|
||
/// <param name="projectId"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("{projectId:guid}")]
|
||
public async Task<TrialDetailDTO> GetTrialInfoAndLockState(Guid projectId)
|
||
{
|
||
return (await _trialRepository.Where(o => o.Id == projectId).ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync()).IfNullThrowException();
|
||
|
||
}
|
||
|
||
|
||
[NonDynamicMethod]
|
||
public async Task<int> GetTrialMaxState(Guid trialId)
|
||
{
|
||
return await _repository.Where<EnrollDetail>(t => t.TrialId == trialId).MaxAsync(u => (int?)u.EnrollStatus) ?? 0;
|
||
}
|
||
|
||
[HttpGet("{trialId:guid}")]
|
||
public async Task<TrialAndTrialStateVieModel> GetTrialInfoAndMaxTrialState(Guid trialId)
|
||
{
|
||
return new TrialAndTrialStateVieModel()
|
||
{
|
||
TrialView = await GetTrialInfoAndLockState(trialId),
|
||
TrialMaxState = await GetTrialMaxState(trialId)
|
||
};
|
||
}
|
||
|
||
|
||
[HttpGet("{trialId:guid}")]
|
||
public async Task<int> GetTrialExpeditedState(Guid trialId)
|
||
{
|
||
var trial = (await _trialRepository.FirstOrDefaultAsync(u => u.Id == trialId)).IfNullThrowException();
|
||
|
||
return trial.Expedited;
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 添加项目
|
||
/// </summary>
|
||
/// <param name="trialAddModel"></param>
|
||
/// <returns></returns>
|
||
[NonDynamicMethod]
|
||
public virtual async Task<IResponseOutput<Trial>> AddOrUpdateTrial(TrialCommand trialAddModel)
|
||
{
|
||
|
||
|
||
|
||
//测试用户 只能创建非正式项目
|
||
if (_userInfo.IsTestUser && trialAddModel.TrialType != TrialType.NoneOfficial)
|
||
{
|
||
//---测试用户 只能创建非正式项目
|
||
throw new BusinessValidationFailedException(_localizer["Trial_TestUserCreateOnlyNonFormal"]);
|
||
}
|
||
|
||
if (trialAddModel.Id == Guid.Empty || trialAddModel.Id == null)
|
||
{
|
||
if (await _trialRepository.AnyAsync(u => u.TrialCode == trialAddModel.TrialCode))
|
||
{
|
||
//---已经存在相同的项目编号。
|
||
throw new BusinessValidationFailedException(_localizer["Trial_DuplicateProjectNumber"]);
|
||
}
|
||
|
||
var dbMaxCode = await _trialRepository.Where(t => t.CreateTime.Year == DateTime.Now.Year && t.TrialType == trialAddModel.TrialType).Select(t => t.Code).DefaultIfEmpty().MaxAsync();
|
||
|
||
var currentYearMaxCodeNext = dbMaxCode + 1;
|
||
|
||
//var test = _trialRepository.Where(t => t.CreateTime.Year == DateTime.Now.Year + 1).Select(t => t.Code).DefaultIfEmpty(1).ToList();
|
||
|
||
var trial = _mapper.Map<Trial>(trialAddModel);
|
||
//trial.Id = NewId.NextGuid();
|
||
var yearStr = DateTime.Now.Year.ToString();
|
||
|
||
trial.Code = currentYearMaxCodeNext;
|
||
trial.TrialCode = (trial.TrialType == TrialType.NoneOfficial ? "T0" : yearStr.Substring(yearStr.Length - 2)) + trial.TrialCode + currentYearMaxCodeNext.ToString("D3");
|
||
|
||
|
||
trial.DeclarationTypes = $"|{string.Join('|', trialAddModel.DeclarationTypeEnumList.Select(x => ((int)x).ToString()).ToList())}|";
|
||
trial.AttendedReviewerTypes = $"|{string.Join('|', trialAddModel.AttendedReviewerTypeEnumList.Select(x => ((int)x).ToString()).ToList())}|";
|
||
|
||
//多选信息
|
||
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.ReviewTypeIds.ForEach(ReviewTypeId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = ReviewTypeId, KeyName = StaticData.ReviewType, TrialId = trial.Id }));
|
||
|
||
//添加项目后 项目状态变更为申请下载简历
|
||
trial.TrialEnrollStatus = (int)TrialEnrollStatus.ChooseDoctor;
|
||
//trial.TrialStatusStr = StaticData.TrialInitializing;
|
||
|
||
//状态变更详细表
|
||
trial.ClinicalTrialProjectDetails.Add(new TrialStatusDetail() { TrialId = trial.Id, TrialStatus = (int)TrialEnrollStatus.ChooseDoctor });
|
||
|
||
trial = await _trialRepository.AddAsync(trial);
|
||
|
||
//如果是PM, 则需要将该人员添加到 运维人员表
|
||
//添加运维人员PM
|
||
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 VisitStage { TrialId = trial.Id, VisitNum = 0, BlindName = "B" + 0.ToString("D3"), VisitDay = 0, VisitName = "Baseline", IsBaseLine = true, VisitWindowLeft = -28, VisitWindowRight = 0 });
|
||
await _repository.AddAsync(new VisitStage { TrialId = trial.Id, VisitNum = 1, BlindName = "B" + 10.ToString("D3"), VisitDay = 30, VisitName = "Visit 1", VisitWindowLeft = -5, VisitWindowRight = 5 });
|
||
|
||
|
||
var success = await _repository.SaveChangesAsync();
|
||
|
||
//维护CRO Sponsor
|
||
await DealSponsorAndCROAsync(trial);
|
||
|
||
//维护部位到项目表
|
||
var searchList = await _repository.Where<Dictionary>(t => t.Parent.Code == "BodyPart" && t.ParentId != null && t.IsEnable).ProjectTo<BasicDicSelect>(_mapper.ConfigurationProvider).ToListAsync();
|
||
|
||
var needAddBodyPartList = searchList.Select(t => new TrialBodyPart() { Code = t.Code, Name = t.Value, NameCN = t.ValueCN }).ToList();
|
||
|
||
foreach (var item in needAddBodyPartList)
|
||
{
|
||
item.TrialId = trial.Id;
|
||
}
|
||
|
||
|
||
await _repository.AddRangeAsync(needAddBodyPartList, true);
|
||
|
||
await _fusionCache.SetAsync(CacheKeys.Trial(trial.Id.ToString()), StaticData.TrialState.TrialInitializing, TimeSpan.FromDays(7));
|
||
|
||
return ResponseOutput.Ok(trial);
|
||
}
|
||
else
|
||
{
|
||
var updateModel = trialAddModel;
|
||
|
||
if (!await _repository.AnyAsync<Trial>(u => u.Id == trialAddModel.Id && (u.TrialStatusStr == StaticData.TrialState.TrialInitializing || u.TrialStatusStr == StaticData.TrialState.TrialOngoing)))
|
||
{
|
||
//---项目状态只有处于:初始化或者进行中时,才允许操作。
|
||
throw new BusinessValidationFailedException(_localizer["Trial_InvalidProjectStatus"]);
|
||
|
||
}
|
||
// 判断项目Id 是否已经存在
|
||
if (await _repository.AnyAsync<Trial>(u => u.TrialCode == updateModel.TrialCode && u.Id != updateModel.Id))
|
||
{
|
||
//---已经存在相同的项目编号。
|
||
throw new BusinessValidationFailedException(_localizer["Trial_DuplicateProjectNumber"]);
|
||
}
|
||
|
||
|
||
|
||
var trial = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == updateModel.Id);
|
||
|
||
|
||
//删除中间表 Title对应的记录
|
||
await _repository.BatchDeleteAsync<TrialDictionary>(t => t.TrialId == updateModel.Id);
|
||
|
||
//重新插入新的 Title记录
|
||
|
||
updateModel.ModalityIds.ForEach(modalityId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = modalityId, KeyName = StaticData.Modality, TrialId = trial.Id }));
|
||
updateModel.CriterionIds.ForEach(criterionId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = criterionId, KeyName = StaticData.Criterion, TrialId = trial.Id }));
|
||
updateModel.ReviewTypeIds.ForEach(ReviewTypeId => trial.TrialDicList.Add(new TrialDictionary() { DictionaryId = ReviewTypeId, KeyName = StaticData.ReviewType, TrialId = trial.Id }));
|
||
|
||
|
||
if (updateModel.Expedited != trial.Expedited && updateModel.Expedited != null)
|
||
{
|
||
TrialExpeditedChange = true;
|
||
await TrialExpeditedStatusChange(trial.Id, trial.Expedited, (int)updateModel.Expedited);
|
||
}
|
||
_mapper.Map(updateModel, trial);
|
||
|
||
trial.DeclarationTypes = $"|{string.Join('|', updateModel.DeclarationTypeEnumList.Select(x => ((int)x).ToString()).ToList())}|";
|
||
trial.AttendedReviewerTypes = $"|{string.Join('|', updateModel.AttendedReviewerTypeEnumList.Select(x => ((int)x).ToString()).ToList())}|";
|
||
|
||
var success = await _repository.SaveChangesAsync();
|
||
|
||
//维护CRO Sponsor
|
||
await DealSponsorAndCROAsync(trial);
|
||
|
||
return ResponseOutput.Ok(trial);
|
||
|
||
}
|
||
}
|
||
|
||
|
||
private async Task DealSponsorAndCROAsync(Trial trial)
|
||
{
|
||
if (trial.SponsorId != null)
|
||
{
|
||
if (await _repository.AnyAsync<Sponsor>(t => t.Id == trial.SponsorId && t.IsTrialLevel))
|
||
{
|
||
await _repository.BatchUpdateAsync<Sponsor>(t => t.Id == trial.SponsorId, u => new Sponsor() { TrialId = trial.Id });
|
||
}
|
||
}
|
||
|
||
if (trial.CROId != null)
|
||
{
|
||
if (await _repository.AnyAsync<CRO>(t => t.Id == trial.CROId && t.IsTrialLevel))
|
||
{
|
||
await _repository.BatchUpdateAsync<CRO>(t => t.Id == trial.CROId, u => new CRO() { TrialId = trial.Id });
|
||
}
|
||
}
|
||
}
|
||
|
||
// TODO: 需要优化,嵌套两层 switch case ?
|
||
[NonDynamicMethod]
|
||
private async Task TrialExpeditedStatusChange(Guid trialId, int oldState, int newState)
|
||
{
|
||
switch (oldState)
|
||
{
|
||
case (int)TrialExpedited.None:
|
||
switch (newState)
|
||
{
|
||
case (int)TrialExpedited.ExpeditedIn24H:
|
||
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
|
||
{
|
||
TimepointIn24H = u.Timepoint,
|
||
AdjudicationIn24H = u.Adjudication,
|
||
Timepoint = 0,
|
||
Adjudication = 0
|
||
});
|
||
break;
|
||
case (int)TrialExpedited.ExpeditedIn48H:
|
||
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
|
||
{
|
||
TimepointIn48H = u.Timepoint,
|
||
AdjudicationIn48H = u.Adjudication,
|
||
Timepoint = 0,
|
||
Adjudication = 0
|
||
});
|
||
break;
|
||
}
|
||
//_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
|
||
//{
|
||
// Timepoint = 0,
|
||
// Adjudication = 0
|
||
//});
|
||
|
||
break;
|
||
case (int)TrialExpedited.ExpeditedIn24H:
|
||
|
||
switch (newState)
|
||
{
|
||
case (int)TrialExpedited.None:
|
||
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
|
||
{
|
||
Timepoint = u.TimepointIn24H,
|
||
Adjudication = u.AdjudicationIn24H,
|
||
TimepointIn24H = 0,
|
||
AdjudicationIn24H = 0
|
||
});
|
||
break;
|
||
case (int)TrialExpedited.ExpeditedIn48H:
|
||
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
|
||
{
|
||
TimepointIn48H = u.TimepointIn24H,
|
||
AdjudicationIn48H = u.AdjudicationIn24H,
|
||
TimepointIn24H = 0,
|
||
AdjudicationIn24H = 0
|
||
});
|
||
|
||
break;
|
||
}
|
||
|
||
//_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
|
||
//{
|
||
// TimepointIn24H = 0,
|
||
// AdjudicationIn24H = 0
|
||
//});
|
||
|
||
break;
|
||
case (int)TrialExpedited.ExpeditedIn48H:
|
||
switch (newState)
|
||
{
|
||
case (int)TrialExpedited.None:
|
||
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
|
||
{
|
||
Timepoint = u.TimepointIn48H,
|
||
Adjudication = u.AdjudicationIn48H,
|
||
TimepointIn48H = 0,
|
||
AdjudicationIn48H = 0
|
||
});
|
||
break;
|
||
case (int)TrialExpedited.ExpeditedIn24H:
|
||
await _repository.BatchUpdateAsync<Workload>(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
|
||
{
|
||
TimepointIn24H = u.TimepointIn48H,
|
||
AdjudicationIn24H = u.AdjudicationIn48H,
|
||
TimepointIn48H = 0,
|
||
AdjudicationIn48H = 0
|
||
});
|
||
break;
|
||
}
|
||
|
||
//_workloadRepository.Update(t => t.IsLock == false && t.TrialId == trialId, u => new Workload()
|
||
//{
|
||
// TimepointIn48H = 0,
|
||
// AdjudicationIn48H = 0
|
||
//});
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary> 真删除项目 方便清理测试数据 </summary>
|
||
/// <param name="trialId">临床试验项目Id</param>
|
||
[AllowAnonymous]
|
||
[HttpDelete, Route("{trialId:guid}")]
|
||
public async Task<IResponseOutput> DeleteTrial(Guid trialId)
|
||
{
|
||
|
||
|
||
var trial = (await _trialRepository.FirstOrDefaultAsync(u => u.Id == trialId, true)).IfNullThrowException();
|
||
|
||
|
||
if (_verifyConfig.CurrentValue.OpenTrialRelationDelete)
|
||
{
|
||
|
||
#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
|
||
|
||
|
||
|
||
await _repository.BatchDeleteAsync<CheckChallengeDialog>(o => o.SubjectVisit.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ClinicalDataTrialSet>(o => o.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<InspectionFile>(o => o.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<CriterionNidusSystem>(o => o.TrialReadingCriterion.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<DataInspection>(o => o.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<EnrollReadingCategory>(t => t.Enroll.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<Enroll>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<EnrollDetail>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<NoneDicomStudyFile>(t => t.NoneDicomStudy.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<NoneDicomStudy>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<OrganTrialInfo>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<PaymentAdjustment>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<PaymentDetail>(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<QCChallengeDialog>(t => t.QCChallenge.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<QCChallenge>(t => t.TrialId == trialId);
|
||
|
||
|
||
|
||
await _repository.BatchDeleteAsync<ReadingClinicalDataPDF>(t => t.ReadingClinicalData.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingClinicalData>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingGlobalTaskInfo>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingJudgeInfo>(t => t.TrialId == trialId);
|
||
|
||
|
||
await _repository.BatchDeleteAsync<ReadingMedicalReviewDialog>(t => t.TaskMedicalReview.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingMedicineQuestionAnswer>(t => t.TaskMedicalReview.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingMedicineTrialQuestion>(t => t.TrialId == trialId);
|
||
|
||
|
||
await _repository.BatchDeleteAsync<ReadingOncologyTaskInfo>(t => t.VisitTask.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingPeriodPlan>(t => t.ReadingPeriodSet.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingPeriodSet>(t => t.TrialId == trialId);
|
||
|
||
|
||
await _repository.BatchDeleteAsync<ReadingQuestionTrial>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingTableAnswerRowInfo>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<ReadingTableQuestionAnswer>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingTableQuestionTrial>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingTaskQuestionAnswer>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<ReadingTaskRelation>(t => t.VisitTask.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadModule>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingTaskQuestionAnswer>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<SubjectCanceDoctor>(t => t.Subject.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<SubjectUser>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<Subject>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<SubjectVisit>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<TaskAllocationRule>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TaskConsistentRule>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TaskInfluence>(t => t.InfluenceTask.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TaskMedicalReview>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TaskMedicalReviewRule>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<TrialStateChange>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialPaymentPrice>(t => t.TrialId == trialId);
|
||
|
||
|
||
await _repository.BatchDeleteAsync<Trial>(o => o.Id == trialId);
|
||
await _repository.BatchDeleteAsync<TrialClinicalDataSetCriterion>(t => t.TrialReadingCriterion.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialCriterionDictionaryCode>(t => t.TrialReadingCriterion.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<ReadingQuestionCriterionTrial>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialDictionary>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialDocConfirmedUser>(t => t.TrialDocument.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<TrialDocument>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialDocNeedConfirmedUserType>(t => t.TrialDocument.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<TrialEmailNoticeUser>(t => t.TrialEmailNoticeConfig.TrialId == trialId);
|
||
|
||
//await _repository.BatchDeleteAsync<TrialExperience>(t => t.TrialId == trialId) ;
|
||
await _repository.BatchDeleteAsync<TrialEmailNoticeUser>(t => t.TrialEmailNoticeConfig.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialEmailNoticeConfig>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<TrialExternalUser>(t => t.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<TrialRevenuesPrice>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialRevenuesPriceVerification>(t => t.TrialId == trialId);
|
||
|
||
|
||
|
||
await _repository.BatchDeleteAsync<TrialSign>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialSite>(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<TrialUser>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialSiteUser>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<VisitStage>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<VisitPlanInfluenceStat>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<VisitPlanInfluenceStudy>(t => t.TrialId == trialId);
|
||
|
||
await _repository.BatchDeleteAsync<VisitTaskReReading>(t => t.OriginalReReadingTask.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<VisitTask>(t => t.TrialId == trialId);
|
||
await _repository.BatchDeleteAsync<TrialStateChange>(t => t.TrialId == trialId);
|
||
|
||
return ResponseOutput.Ok();
|
||
|
||
}
|
||
|
||
else
|
||
{
|
||
//---当前运行环境下,不允许删除项目数据。
|
||
return ResponseOutput.NotOk(_localizer["Trial_CannotDeleteProject"]);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
[HttpPost]
|
||
public async Task<PageOutput<TrialDetailDTO>> GetReviewerTrialListByEnrollmentStatus(TrialByStatusQueryDTO param)
|
||
{
|
||
|
||
var query = _trialRepository.AsQueryable()
|
||
.WhereIf(param.Status == 5, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO))
|
||
.WhereIf(param.Status == 8, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.InviteIntoGroup))
|
||
.WhereIf(param.Status == 10, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.DoctorReading))
|
||
.WhereIf(param.Status == 14, t => t.EnrollList.Any(u => u.EnrollStatus == EnrollStatus.Finished))
|
||
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id, isEn_Us = _userInfo.IsEn_Us });
|
||
|
||
return await query.ToPagedListAsync(param.PageIndex, param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "CreateTime" : param.SortField, param.Asc);
|
||
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 根据项目Id 获取医生Id,用于触发计算费用
|
||
/// </summary>
|
||
public async Task<List<Guid>> GetTrialEnrollmentReviewerIds(Guid trialId)
|
||
{
|
||
return await _repository.Where<Enroll>(u => u.TrialId == trialId &&
|
||
u.EnrollStatus >= EnrollStatus.DoctorReading).Select(u => u.DoctorId).Distinct().ToListAsync();
|
||
}
|
||
|
||
|
||
|
||
|
||
#region 医生用户接口
|
||
|
||
/// <summary> 分页获取医生参与的临床实验项目列表(查询条件)</summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<PageOutput<TrialDetailDTO>> GetTrialListByReviewer(ReviewerTrialQueryDTO searchModel)
|
||
{
|
||
var query = _trialRepository
|
||
.WhereIf(searchModel.EnrollStatus != null, o => (int)searchModel.EnrollStatus! == 10 ?
|
||
o.EnrollList.Any(o => o.EnrollStatus >= EnrollStatus.ConfirmIntoGroup && o.EnrollStatus <= EnrollStatus.DoctorReading && o.DoctorId == _userInfo.Id) :
|
||
o.EnrollList.Any(o => o.EnrollStatus == searchModel.EnrollStatus && o.DoctorId == _userInfo.Id))
|
||
.WhereIf(searchModel.Expedited != null, o => o.Expedited == searchModel.Expedited)
|
||
.WhereIf(!string.IsNullOrEmpty(searchModel.Code), o => o.TrialCode.Contains(searchModel.Code))
|
||
.WhereIf(!string.IsNullOrWhiteSpace(searchModel.Indication), o => o.Indication.Contains(searchModel.Indication))
|
||
.WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id))
|
||
.ProjectTo<TrialDetailDTO>(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id, isEn_Us = _userInfo.IsEn_Us });
|
||
|
||
|
||
return await query.ToPagedListAsync(searchModel.PageIndex, searchModel.PageSize, string.IsNullOrWhiteSpace(searchModel.SortField) ? "CreateTime" : searchModel.SortField, searchModel.Asc);
|
||
|
||
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 医生确认入组或拒绝入组
|
||
/// </summary>
|
||
/// <param name="trialId">项目Id</param>
|
||
/// <param name="status">9-拒绝入组,10-确认入组</param>
|
||
/// <returns></returns>
|
||
[HttpPost("{trialId:guid}/{status:int}")]
|
||
|
||
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
|
||
public async Task<IResponseOutput> UpdateEnrollStatus(Guid trialId, EnrollStatus status)
|
||
{
|
||
await _repository.AddAsync(new EnrollDetail()
|
||
{
|
||
DoctorId = _userInfo.Id,
|
||
TrialId = trialId,
|
||
EnrollStatus = status,
|
||
OptUserType = (int)SystemUserType.DoctorUser,
|
||
});
|
||
return ResponseOutput.Result(await _repository.BatchUpdateAsync<Enroll>(u => u.TrialId == trialId && u.DoctorId == _userInfo.Id, e => new Enroll
|
||
{
|
||
EnrollStatus = status
|
||
}));
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
|
||
|
||
|
||
|
||
}
|
||
|
||
}
|