using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Contracts;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Domain.Share;
using EasyCaching.Core;
using IRaCIS.Core.Infrastructure;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using Panda.DynamicWebApi.Attributes;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
namespace IRaCIS.Core.Application
{
[ApiExplorerSettings(GroupName = "Trial")]
public class TrialConfigService : BaseService, ITrialConfigService
{
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<TrialQCQuestion> _trialQCQuestionRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;
private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository;
private readonly IRepository<ReadingCriterionPage> _readingCriterionPageRepository;
private readonly IEasyCachingProvider _provider;
private readonly IOrganInfoService _iOrganInfoService;
private readonly IRepository<TaskAllocationRule> _taskAllocationRuleRepository;
private readonly IRepository<ReadingCriterionDictionary> _readingCriterionDictionaryRepository;
private readonly IReadingQuestionService iReadingQuestionService;
public TrialConfigService(IRepository<Trial> trialRepository,
IRepository<TrialQCQuestion> trialQCQuestionRepository,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository,
IRepository<ReadingQuestionTrial> readingQuestionTrialRepository,
IRepository<ClinicalDataTrialSet> clinicalDataTrialSetRepository,
IRepository<ReadingCriterionPage> readingCriterionPageRepository,
IRepository<TaskAllocationRule> taskAllocationRuleRepository,
IRepository<ReadingCriterionDictionary> readingCriterionDictionaryRepository,
IReadingQuestionService iReadingQuestionService,
IEasyCachingProvider provider,
IOrganInfoService iOrganInfoService
)
{
_trialRepository = trialRepository;
_taskAllocationRuleRepository = taskAllocationRuleRepository;
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
this.iReadingQuestionService = iReadingQuestionService;
this._trialQCQuestionRepository = trialQCQuestionRepository;
this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
this._readingQuestionTrialRepository = readingQuestionTrialRepository;
this._clinicalDataTrialSetRepository = clinicalDataTrialSetRepository;
this._readingCriterionPageRepository = readingCriterionPageRepository;
this._provider = provider;
this._iOrganInfoService = iOrganInfoService;
}
/// <summary>
/// 阅片信息签名验证接口
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPost]
public async Task<IResponseOutput> TrialReadingInfoSignVerify(TrialReadingInfoSignInDto inDto)
{
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstOrDefaultAsync();
var existsJudge = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialCriterion.Id && x.IsJudgeQuestion && x.JudgeType == JudgeTypeEnum.None)
.WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null)
.WhereIf(trialCriterion.FormType == FormType.MultiplePage, x => x.ReadingCriterionPageId != null)
.AnyAsync();
if (existsJudge)
{
throw new BusinessValidationFailedException("有裁判问题未配置产生裁判阅片任务的条件,操作失败!");
}
return ResponseOutput.Ok(true);
}
/// <summary>
/// 获取项目已经确认的标准
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<List<GetTrialConfirmCriterionOutDto>> GetTrialConfirmCriterionList(GetTrialConfirmCriterionListInDto inDto)
{
List<GetTrialConfirmCriterionOutDto> result = await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm)
.Select(x => new GetTrialConfirmCriterionOutDto()
{
TrialCriterionId = x.Id,
CriterionName = x.CriterionName
}).ToListAsync();
return result;
}
/// <summary>
/// 阅片信息签名
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[NonDynamicMethod]
public async Task<IResponseOutput> TrialReadingInfoSign(TrialReadingInfoSignInDto inDto)
{
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id==inDto.TrialReadingCriterionId).FirstOrDefaultAsync();
var existsJudge = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialCriterion.Id && x.IsJudgeQuestion && x.JudgeType == JudgeTypeEnum.None)
.WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null)
.WhereIf(trialCriterion.FormType == FormType.MultiplePage, x => x.ReadingCriterionPageId != null)
.AnyAsync();
if (existsJudge)
{
throw new BusinessValidationFailedException("有裁判问题未配置产生裁判阅片任务的条件,操作失败!");
}
await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial()
{
ReadingInfoSignTime = DateTime.Now
});
var result = await _trialRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 获取项目阅片信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetTrialReadingInfoOutDto> GetCriterionReadingInfo(GetTrialReadingInfoInDto inDto)
{
GetTrialReadingInfoOutDto trialInfo= await _readingQuestionCriterionTrialRepository.Where(x=>x.Id==inDto.TrialReadingCriterionId).ProjectTo<GetTrialReadingInfoOutDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
trialInfo.GlobalAssessTypeIds = await _readingCriterionDictionaryRepository.Where(x => x.CriterionId == inDto.TrialReadingCriterionId && x.ParentCode == "GlobalAssessType").Select(x => x.DictionaryId).ToListAsync();
return trialInfo;
}
/// <summary>
/// 获取项目肿瘤学配置
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetOncologySetOutDto> GetOncologySet(GetOncologySetInDto inDto)
{
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstOrDefaultAsync();
return new GetOncologySetOutDto
{
EvaluationReason = trialCriterion.EvaluationReason.IsNullOrEmpty()? ReadingCommon.EvaluationReason : trialCriterion.EvaluationReason,
OncologyAssessIds = await _readingCriterionDictionaryRepository.Where(x => x.CriterionId == inDto.TrialReadingCriterionId && x.ParentCode == "OncologyAssess").Select(x => x.DictionaryId).ToListAsync(),
IsSystemCriterion= trialCriterion.ReadingQuestionCriterionSystemId!=null,
IsSign = trialCriterion.ReadingInfoSignTime != null,
};
}
/// <summary>
/// 设置项目肿瘤学配置
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetOncologySet(SetOncologySetInDto inDto)
{
await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial()
{
EvaluationResult = inDto.EvaluationResult,
EvaluationReason = inDto.EvaluationReason,
IsShowDetail=inDto.IsShowDetail,
});
await _readingCriterionDictionaryRepository.BatchDeleteNoTrackingAsync(x => x.CriterionId == inDto.TrialReadingCriterionId && x.ParentCode == "OncologyAssess");
await _readingCriterionDictionaryRepository.AddRangeAsync(inDto.OncologyAssessIds.Select(x => new ReadingCriterionDictionary
{
CriterionId = inDto.TrialReadingCriterionId,
DictionaryId = x,
IsSystemCriterion = false,
ParentCode = "OncologyAssess"
}));
var result = await _readingQuestionCriterionTrialRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 获取项目裁判信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<(List<TrialJudgeQuestion>,object)> GetTrialReadingJudgeList(GetTrialReadingInfoInDto inDto)
{
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstOrDefaultAsync();
var judgeQuestionList= await _readingQuestionTrialRepository
.WhereIf(trialCriterion.FormType==FormType.SinglePage,x=>x.ReadingCriterionPageId==null)
.WhereIf(trialCriterion.FormType == FormType.MultiplePage, x => x.ReadingCriterionPageId != null)
.Where(x => x.ReadingQuestionCriterionTrial.IsConfirm && x.IsJudgeQuestion && x.TrialId == inDto.TrialId&&x.ReadingQuestionCriterionTrialId== trialCriterion.Id)
.Select(x => new TrialJudgeQuestion()
{
AnswerCombination = x.AnswerCombination,
AnswerGroup = x.AnswerGroup,
JudgeType = x.JudgeType,
QuestionId = x.Id,
PageName=x.ReadingCriterionPage.PageName,
QuestionName = x.QuestionName,
ReadingQuestionCriterionTrialId = x.ReadingQuestionCriterionTrialId
}).ToListAsync();
return (judgeQuestionList, new
{
IsSign= trialCriterion.ReadingInfoSignTime!= null,
});
}
/// <summary>
/// 获取项目标准分页信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<ReadingCriterionPageDto>> GetReadingCriterionPageList(GetTrialReadingInfoInDto inDto)
{
return await _readingCriterionPageRepository.Where(x => x.TrialId == inDto.TrialId).ProjectTo<ReadingCriterionPageDto>(_mapper.ConfigurationProvider).ToListAsync();
}
/// <summary>
/// 获取项目阅片标准信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetTrialReadingCriterionInfoOutDto> GetTrialReadingCriterionInfo(GetTrialReadingInfoInDto inDto)
{
GetTrialReadingCriterionInfoOutDto result = new GetTrialReadingCriterionInfoOutDto();
result.ReadingCriterionPageList = await _readingCriterionPageRepository.Where(x => x.TrialId == inDto.TrialId).ProjectTo<ReadingCriterionPageDto>(_mapper.ConfigurationProvider).OrderBy(x=>x.ShowOrder).ToListAsync();
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id==inDto.TrialReadingCriterionId).FirstOrDefaultAsync();
result.ReadingInfoSignTime = trialCriterion.ReadingInfoSignTime;
if (trialCriterion != null)
{
result.DigitPlaces = trialCriterion.DigitPlaces;
result.TrialCriterionId = trialCriterion.Id;
result.FormType = trialCriterion.FormType;
result.IsFromSystem = trialCriterion.ReadingQuestionCriterionSystemId != null;
if (trialCriterion.SynchronizeOriginalTime == null && trialCriterion.ReadingQuestionCriterionSystemId != null)
{
// 同步器官
await _iOrganInfoService.SynchronizeSystemOrganToTrial(new SynchronizeSystemOrganToTrialInDto()
{
TrialReadingCriterionId = inDto.TrialReadingCriterionId,
SystemCriterionId = trialCriterion.ReadingQuestionCriterionSystemId
});
// 同步问题
await iReadingQuestionService.SynchronizeCriterion(new SynchronizeCriterionInDto()
{
TrialReadingCriterionId = inDto.TrialReadingCriterionId,
});
}
};
result.TrialQuestionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrial.IsConfirm && x.TrialId == inDto.TrialId&&x.ReadingQuestionCriterionTrialId == result.TrialCriterionId
&&x.ReadingCriterionPageId==null)
.ProjectTo<TrialReadQuestion>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();
IsSystemCriterion = trialCriterion.ReadingQuestionCriterionSystemId != null;
return result;
}
/// <summary>
/// 设置项目阅片标准
/// </summary>
/// <returns></returns>
public async Task<IResponseOutput> SetTrialReadingCriterion(SetTrialReadingCriterionInDto inDto)
{
if (inDto.IsSignSave)
{
var criterionFormType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Select(x => x.FormType).FirstOrDefaultAsync();
var count = _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId)
.WhereIf(criterionFormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null)
.WhereIf(criterionFormType == FormType.MultiplePage, x => x.ReadingCriterionPageId != null).Count();
if (count == 0)
{
throw new BusinessValidationFailedException("当前标准下未配置问题");
}
}
await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial()
{
FormType = inDto.FormType,
DigitPlaces = inDto.DigitPlaces,
});
await _readingCriterionDictionaryRepository.BatchDeleteNoTrackingAsync(x => x.CriterionId == inDto.TrialReadingCriterionId && x.ParentCode == "GlobalAssessType");
await _readingCriterionDictionaryRepository.AddRangeAsync(inDto.GlobalAssessTypeIds.Select(x => new ReadingCriterionDictionary
{
CriterionId = inDto.TrialReadingCriterionId,
DictionaryId = x,
IsSystemCriterion = false,
ParentCode = "GlobalAssessType"
}));
var result = await _trialRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 设置项目阅片信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SetCriterionReadingInfo(SetCriterionReadingInfoInDto inDto)
{
ArbitrationRule arbitration = ArbitrationRule.NA;
if (inDto.IsArbitrationReading)
{
arbitration = inDto.IsGlobalReading ? ArbitrationRule.Reading : ArbitrationRule.Visit;
}
await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial()
{
ReadingTool=inDto.ReadingTool,
//DigitPlaces=inDto.DigitPlaces,
IsReadingTaskViewInOrder=inDto.IsReadingTaskViewInOrder,
ReadingTaskViewEnum = inDto.ReadingTaskViewEnum,
//IsImageIabeled = inDto.IsImageIabeled,
IsReadingShowSubjectInfo = inDto.IsReadingShowSubjectInfo,
IsReadingShowPreviousResults = inDto.IsReadingShowPreviousResults,
GlobalUpdateType=inDto.GlobalUpdateType,
ImagePlatform=inDto.ImagePlatform,
ArbitrationRule= arbitration,
ReadingType = inDto.ReadingType,
IsGlobalReading = inDto.IsGlobalReading,
IsArbitrationReading = inDto.IsArbitrationReading,
IsOncologyReading = inDto.IsOncologyReading,
});
var result = await _readingQuestionCriterionTrialRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
/// <summary>
/// 获取签名文本
/// </summary>
/// <param name="signCode"></param>
/// <returns></returns>
[HttpGet("{signCode}")]
public async Task<IResponseOutput> GetSignText(string signCode)
{
var signRawText = await _repository.Where<SystemBasicData>(t => t.Code == signCode).Select(t => new { t.Code, t.Value, t.Id, ParentValue = t.Parent.Value, ParentValueCN = t.Parent.ValueCN }).FirstOrDefaultAsync();
if (signRawText == null)
{
return ResponseOutput.NotOk("该操作需要电子签名确认,但未在系统中找到该场景的签名模板。");
}
return ResponseOutput.Ok(new
{
SignCodeId = signRawText.Id,
SignCode = signRawText.Code,
SignText = signRawText.ParentValue.Replace("xxx", signRawText.Value),
SignTextCN = signRawText.ParentValueCN.Replace("xxx", signRawText.Value)
});
}
//验证 仅仅在 Initializing/Ongoing 才可以操作
private async Task VerifyOnlyInOngoingOrInitialIzingOptAsync(Guid trialId)
{
if (!await _trialRepository.AnyAsync(t => t.Id == trialId && (t.TrialStatusStr == StaticData.TrialState.TrialInitializing || t.TrialStatusStr == StaticData.TrialState.TrialOngoing)))
{
throw new BusinessValidationFailedException("该项目已结束或停止,不允许修改配置。");
}
}
/// <summary>
/// 验证签名确认
/// </summary>
/// <param name="signConfirmDTO"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPost]
public async Task<IResponseOutput> VerifyTrialConfigSignatureConfirm(SignConfirmDTO signConfirmDTO)
{
var trialConfig = (await _trialRepository
.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification })
.FirstOrDefaultAsync(t => t.TrialId == signConfirmDTO.TrialId))
.IfNullThrowException();
var showOrderList = await _repository.Where<TrialQCQuestion>(t => t.TrialId == signConfirmDTO.TrialId).Select(t =>
new { t.ShowOrder, ParentShowOrder = (int?)t.ParentQCQuestion.ShowOrder }).ToListAsync();
if (trialConfig.QCProcessEnum ==
TrialQCProcess.DoubleAudit || trialConfig.QCProcessEnum == TrialQCProcess.SingleAudit)
{
if (showOrderList.Count == 0)
{
throw new BusinessValidationFailedException("当前未添加影像质控审核问题。请先添加影像质控审核问题,再进行确认。");
}
}
if (showOrderList.Count() != showOrderList.Select(t => t.ShowOrder).Distinct().Count())
{
throw new BusinessValidationFailedException("影像质控审核问题显示序号不能重复。");
}
if (showOrderList.Where(t => t.ParentShowOrder != null).Any(t => t.ParentShowOrder > t.ShowOrder))
{
throw new BusinessValidationFailedException("父问题的显示序号要比子问题的显示序号小,请确认。");
}
if (await _trialRepository.AnyAsync(t => t.Id == signConfirmDTO.TrialId && t.QCQuestionConfirmedUserId != null && t.QCQuestionConfirmedUserId != _userInfo.Id))
{
throw new BusinessValidationFailedException("影像质控审核问题已被其他人员确认,不允许再次确认。");
}
return ResponseOutput.Ok();
}
/// <summary>
/// 签名确认 包括项目的三组配置 + QC问题确认 后修改状态 (适用于不会回退的,项目废除、状态修改, 存在回退 不在这里弄,提供单独接口修改状态)
/// </summary>
/// <returns></returns>
[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> TrialConfigSignatureConfirm(SignConfirmDTO signConfirmDTO)
{
await VerifyOnlyInOngoingOrInitialIzingOptAsync(signConfirmDTO.TrialId);
if (signConfirmDTO.SignCode == ((int)SignEnum.TrialLogicConfim).ToString())
{
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { IsTrialBasicLogicConfirmed = true });
}
else if (signConfirmDTO.SignCode == ((int)SignEnum.TrialProcessConfim).ToString())
{
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { IsTrialProcessConfirmed = true });
}
else if (signConfirmDTO.SignCode == ((int)SignEnum.TrialUrgentConfim).ToString())
{
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { IsTrialUrgentConfirmed = true });
}
else
if (signConfirmDTO.SignCode == ((int)SignEnum.TrialQCQuestionConfirm).ToString())
{
var trialConfig = (await _trialRepository
.Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification })
.FirstOrDefaultAsync(t => t.TrialId == signConfirmDTO.TrialId))
.IfNullThrowException();
var showOrderList = await _repository.Where<TrialQCQuestion>(t => t.TrialId == signConfirmDTO.TrialId).Select(t =>
new { t.ShowOrder, ParentShowOrder = (int?)t.ParentQCQuestion.ShowOrder }).ToListAsync();
if (trialConfig.QCProcessEnum ==
TrialQCProcess.DoubleAudit || trialConfig.QCProcessEnum == TrialQCProcess.SingleAudit)
{
if (showOrderList.Count == 0)
{
throw new BusinessValidationFailedException("当前未添加影像质控审核问题。请先添加影像质控审核问题,再进行确认。");
}
}
if (showOrderList.Count() != showOrderList.Select(t => t.ShowOrder).Distinct().Count())
{
throw new BusinessValidationFailedException("影像质控审核问题显示序号不能重复。");
}
if (showOrderList.Where(t => t.ParentShowOrder != null).Any(t => t.ParentShowOrder > t.ShowOrder))
{
throw new BusinessValidationFailedException("父问题的显示序号要比子问题的显示序号小,请确认。");
}
if (await _trialRepository.AnyAsync(t => t.Id == signConfirmDTO.TrialId && t.QCQuestionConfirmedUserId != null && t.QCQuestionConfirmedUserId != _userInfo.Id))
{
throw new BusinessValidationFailedException("影像质控审核问题已被其他人员确认,不允许再次确认。");
}
await _trialQCQuestionRepository.UpdatePartialFromQueryAsync(t => t.TrialId == signConfirmDTO.TrialId, x => new TrialQCQuestion
{
IsConfirm = true
});
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { QCQuestionConfirmedTime = DateTime.Now, QCQuestionConfirmedUserId = _userInfo.Id, IsQCQuestionConfirmed = true });
await _trialRepository.SaveChangesAsync();
}
return ResponseOutput.Ok();
}
/// <summary>
/// 配置 基础逻辑信息
/// </summary>
/// <param name="trialConfig"></param>
/// <returns></returns>
[HttpPut]
[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> ConfigTrialBasicInfo(BasicTrialConfig trialConfig)
{
await VerifyOnlyInOngoingOrInitialIzingOptAsync(trialConfig.TrialId);
var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialConfig.TrialId)).IfNullThrowException();
_mapper.Map(trialConfig, trialInfo);
trialInfo.UpdateTime = DateTime.Now;
return ResponseOutput.Ok(await _repository.SaveChangesAsync());
}
/// <summary>
/// 配置流程
/// </summary>
/// <param name="trialConfig"></param>
/// <returns></returns>
[HttpPut]
[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> ConfigTrialProcessInfo(TrialProcessConfig trialConfig)
{
if (!await _trialRepository.Where(t => t.Id == trialConfig.TrialId).IgnoreQueryFilters().AnyAsync(t => t.TrialStatusStr == StaticData.TrialState.TrialInitializing))
{
return ResponseOutput.NotOk("该项目当前状态不是初始化,不允许进行该操作。");
}
var trialInfo = await _trialRepository.Where(t => t.Id == trialConfig.TrialId, true).Include(t => t.TrialDicList.Where(u => u.KeyName == StaticData.Criterion)).FirstOrDefaultAsync();
if (trialInfo == null) return Null404NotFound(trialInfo);
_mapper.Map(trialConfig, trialInfo);
//if (trialInfo.IsGlobalReading && (trialInfo.IsArbitrationReading ?? false))
//{
// trialInfo.ArbitrationRule = ArbitrationRule.Reading;
//}
//if (!trialInfo.IsGlobalReading && (trialInfo.IsArbitrationReading ?? false))
//{
// trialInfo.ArbitrationRule = ArbitrationRule.Visit;
//}
trialInfo.UpdateTime = DateTime.Now;
// 修改临床数据
var noconfirmids = await _clinicalDataTrialSetRepository.Where(x => x.TrialId == trialConfig.TrialId && !trialConfig.ClinicalDataTrialSetIds.Contains(x.Id)).Select(x => x.Id).ToListAsync();
foreach (var item in trialConfig.ClinicalDataTrialSetIds)
{
await _clinicalDataTrialSetRepository.UpdatePartialFromQueryAsync(item, x => new ClinicalDataTrialSet()
{
IsConfirm = true
});
}
foreach (var item in noconfirmids)
{
await _clinicalDataTrialSetRepository.UpdatePartialFromQueryAsync(item, x => new ClinicalDataTrialSet()
{
IsConfirm = false
});
}
// 修改阅片标准
var cancelConfirmCriterionIds = await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == trialConfig.TrialId && x.IsConfirm && !trialConfig.TrialCriterionIds.Contains(x.Id)).Select(x => x.Id).ToListAsync();
await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(x => cancelConfirmCriterionIds.Contains(x.Id), x => new ReadingQuestionCriterionTrial()
{
IsConfirm = false
});
await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(x => trialConfig.TrialCriterionIds.Contains(x.Id), x => new ReadingQuestionCriterionTrial()
{
IsConfirm = true
}); ;
return ResponseOutput.Ok(await _repository.SaveChangesAsync());
}
/// <summary>
/// 配置加急信息
/// </summary>
/// <param name="trialConfig"></param>
/// <returns></returns>
[HttpPut]
[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> ConfigTrialUrgentInfo(TrialUrgentConfig trialConfig)
{
await VerifyOnlyInOngoingOrInitialIzingOptAsync(trialConfig.TrialId);
var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialConfig.TrialId)).IfNullThrowException();
//项目紧急 当前所有已提交,但未完成的访视,设置为加急。后续提交的访视也设置为加急 (在提交的时候,回去判断 项目加急,Subject加急,是否入组确认,是否Pd,从而设置访视是否加急)
if (trialConfig.IsUrgent)
{
await _repository.BatchUpdateAsync<SubjectVisit>(t => t.TrialId == trialInfo.Id && t.SubmitState == SubmitStateEnum.Submitted && t.ForwardState < ForwardStateEnum.Forwarded,
s => new SubjectVisit() { IsUrgent = trialConfig.IsUrgent });
}
else //之前设置为加急的访视状态不变。后续提交的访视,为不加急。
{
}
_mapper.Map(trialConfig, trialInfo);
trialInfo.UpdateTime = DateTime.Now;
return ResponseOutput.Ok(await _repository.SaveChangesAsync());
}
[HttpGet("{trialId:guid}")]
public async Task<IResponseOutput> IfTrialCanOngoing(Guid trialId)
{
var canOPt = await _trialRepository.AnyAsync(trial =>
trial.Id == trialId && trial.IsTrialBasicLogicConfirmed && trial.IsTrialProcessConfirmed &&
trial.IsTrialUrgentConfirmed && trial.VisitPlanConfirmed);
return ResponseOutput.Ok(canOPt, msg: canOPt ? "" : "该项目的项目配置(基础配置、流程配置、加急配置) 、访视管理,有配置未确认,不能设置项目状态为启动。");
}
/// <summary>
/// 更新项目状态
/// </summary>
/// <param name="trialId"></param>
/// <param name="trialStatusStr"></param>
/// <param name="reason"></param>
/// <returns></returns>
[HttpPut("{trialId:guid}/{trialStatusStr}/{reason?}")]
[UnitOfWork]
[Authorize(Policy = IRaCISPolicy.PM)]
public async Task<IResponseOutput> UpdateTrialState(Guid trialId, string trialStatusStr, string? reason)
{
var trial = (await _trialRepository.Where(t => t.Id == trialId, true).IgnoreQueryFilters().FirstOrDefaultAsync()).IfNullThrowException();
if (trialStatusStr == StaticData.TrialState.TrialOngoing)
{
if (trial.IsTrialBasicLogicConfirmed && trial.IsTrialProcessConfirmed && trial.IsTrialUrgentConfirmed && trial.VisitPlanConfirmed)
{
}
else
{
return ResponseOutput.NotOk("无法变更项目状态。该项目的项目配置、访视管理中,有未确认项");
}
}
if ((trialStatusStr == StaticData.TrialState.TrialStopped || trialStatusStr == StaticData.TrialState.TrialCompleted) && trial.TrialStatusStr != StaticData.TrialState.TrialOngoing)
{
return ResponseOutput.NotOk("项目没有进入启动状态,不能设置为停止或完成状态");
}
if (trialStatusStr != StaticData.TrialState.TrialOngoing)
{
trial.TrialFinishTime = DateTime.Now;
}
trial.TrialStateChangeList.Add(new TrialStateChange() { OriginState = trial.TrialStatusStr, NowState = trialStatusStr, Reason = reason ?? String.Empty, TrialId = trialId });
trial.TrialStatusStr = trialStatusStr;
//Paused、 添加工总量 算医生读片中
if (trialStatusStr.Contains(StaticData.TrialState.TrialCompleted))
{
await _repository.BatchUpdateAsync<Enroll>(u => u.TrialId == trialId, e => new Enroll
{
EnrollStatus = EnrollStatus.Finished
});
await _trialRepository.BatchUpdateNoTrackingAsync(u => u.Id == trialId, s => new Trial { TrialFinishedTime = DateTime.UtcNow.AddHours(8) });
}
await _provider.SetAsync(trialId.ToString(), trialStatusStr, TimeSpan.FromDays(7));
await _repository.SaveChangesAsync();
//var success = await _repository.BatchUpdateAsync<TrialSign>(t => t.Id == signId, u => new TrialSign() { IsCompleted = true });
return ResponseOutput.Ok();
}
/// <summary>
/// 项目状态 变更历史
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}")]
public async Task<List<TrialStateChangeDTO>> GetTrialStateChangeList(Guid trialId)
{
return await _repository.Where<TrialStateChange>(t => t.TrialId == trialId).ProjectTo<TrialStateChangeDTO>(_mapper.ConfigurationProvider).ToListAsync();
}
/// <summary>
/// 废除项目
/// </summary>
/// <param name="trialId"></param>
/// <param name="isAbandon"></param>
/// <returns></returns>
[HttpPut("{trialId:guid}/{isAbandon:bool}")]
[Authorize(Policy = IRaCISPolicy.PM)]
public async Task<IResponseOutput> AbandonTrial(Guid trialId, /*Guid? signId,*/ bool isAbandon)
{
await _trialRepository.UpdatePartialFromQueryAsync(trialId, u => new Trial()
{
IsDeleted = isAbandon,
TrialFinishTime = isAbandon ? DateTime.Now : null
}, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 获取 配置的所有信息 没有分多个接口
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}")]
public async Task<TrialConfigDTO> GetTrialConfigInfo(Guid trialId)
{
return await _trialRepository.Where(t => t.Id == trialId).ProjectTo<TrialConfigDTO>(_mapper.ConfigurationProvider)
.FirstOrDefaultAsync().IfNullThrowException();
}
/// <summary>
/// 配置项目任务信息
/// </summary>
/// <param name="trialConfig"></param>
/// <returns></returns>
[HttpPut]
public async Task<IResponseOutput> ConfigTrialTaskInfo(TrialTaskConfig trialConfig)
{
var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialConfig.TrialId)).IfNullThrowException();
_mapper.Map(trialConfig, trialInfo);
return ResponseOutput.Ok(await _trialRepository.SaveChangesAsync());
}
/// <summary>
/// 配置项目读片查看规则
/// </summary>
/// <param name="trialConfig"></param>
/// <returns></returns>
[HttpPut]
public async Task<IResponseOutput> ConfigTrialReadingTaskViewRule(TrialReadingTaskViewConfig trialConfig)
{
var trialInfo = (await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialConfig.TrialId)).IfNullThrowException();
_mapper.Map(trialConfig, trialInfo);
return ResponseOutput.Ok(await _trialRepository.SaveChangesAsync());
}
}
}