using IRaCIS.Application.Interfaces; using IRaCIS.Core.Application.Contracts; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Infra.EFCore; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using IRaCIS.Core.Domain.Share; using EasyCaching.Core; using IRaCIS.Core.Application.Filter; namespace IRaCIS.Core.Application { [ApiExplorerSettings(GroupName = "Trial")] public class TrialConfigService : BaseService, ITrialConfigService { private readonly IRepository _trialRepository; public TrialConfigService(IRepository trialRepository) { _trialRepository = trialRepository; } /// /// 获取签名文本 /// /// /// [HttpGet("{signCode}")] public async Task GetSignText(string signCode) { var signRawText = await _repository.Where(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) }); } /// /// 签名认证 + /// /// [HttpPost] public async Task VerifySignature(SignDTO signDTO) { var user = await _repository.FirstOrDefaultAsync(u => u.UserName == signDTO.UserName && u.Password == signDTO.PassWord); if (user == null) { return ResponseOutput.NotOk("password error"); } else if (user.Status == UserStateEnum.Disable) { return ResponseOutput.NotOk("The user has been disabled!"); } //if (signDTO.IsAddSignData) //{ // 记录签名信息 var add = await _repository.AddAsync(_mapper.Map(signDTO)); await _repository.SaveChangesAsync(); return ResponseOutput.Ok(add.Id); //} //return ResponseOutput.Ok(); } /// /// 业务接口操作成功后, 让签署数据生效 /// /// /// [HttpPut("{signId:guid}")] [Obsolete] public async Task MakeSignEffective(Guid signId) { var success = await _repository.BatchUpdateAsync(t => t.Id == signId, u => new TrialSign() { IsCompleted = true }); return ResponseOutput.Result(success); } /// /// 签名确认 包括项目的三组配置 + QC问题确认 后修改状态 (适用于不会回退的,项目废除、状态修改, 存在回退 不在这里弄,提供单独接口修改状态) /// /// public async Task TrialConfigSignatureConfirm(SignConfirmDTO signConfirmDTO) { if (!await _trialRepository.AnyAsync(t => t.Id == signConfirmDTO.TrialId && (t.TrialStatusStr == StaticData.TrialInitializing|| t.TrialStatusStr == StaticData.TrialOngoing))) { return ResponseOutput.NotOk("项目不在Initializing/Ongoing,不允许确认配置"); } if (signConfirmDTO.SignCode == ((int)SignEnum.TrialLogicConfim).ToString()) { await _trialRepository.BatchUpdateAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { IsTrialBasicLogicConfirmed = true }); } else if (signConfirmDTO.SignCode == ((int)SignEnum.TrialProcessConfim).ToString()) { await _trialRepository.BatchUpdateAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { IsTrialProcessConfirmed = true }); } else if (signConfirmDTO.SignCode == ((int)SignEnum.TrialUrgentConfim).ToString()) { await _trialRepository.BatchUpdateAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { IsTrialUrgentConfirmed = true }); } else if (signConfirmDTO.SignCode == ((int)SignEnum.TrialQCQuestionConfirm).ToString()) { var showOrderList = await _repository.Where(t => t.TrialId == signConfirmDTO.TrialId).Select(t => new { t.ShowOrder , ParentShowOrder=(int?) t.ParentQCQuestion.ShowOrder} ).ToListAsync(); if (showOrderList.Count() != showOrderList.Select(t=>t.ShowOrder).Distinct().Count()) { return ResponseOutput.NotOk("QC问题显示序号不允许重复"); } if (showOrderList.Where(t=>t.ParentShowOrder != null).Any(t => t.ParentShowOrder > t.ShowOrder)) { return ResponseOutput.NotOk("父问题的序号要比子问题序号小,请确认"); } await _trialRepository.BatchUpdateAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { QCQuestionConfirmedTime = DateTime.Now, QCQuestionConfirmedUserId = _userInfo.Id, IsQCQuestionConfirmed = true }); } return ResponseOutput.Ok(); } /// /// 配置 基础逻辑信息 /// /// /// [HttpPut] public async Task ConfigTrialBasicInfo(BasicTrialConfig trialConfig) { if (!await _trialRepository.Where(t => t.Id == trialConfig.TrialId).IgnoreQueryFilters().AnyAsync(t => t.TrialStatusStr == StaticData.TrialOngoing || t.TrialStatusStr == StaticData.TrialInitializing)) { return ResponseOutput.NotOk(" only in Initializing or Ongoing State can operate "); } var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialConfig.TrialId); if (trialInfo == null) return Null404NotFound(trialInfo); _mapper.Map(trialConfig, trialInfo); return ResponseOutput.Ok(await _repository.SaveChangesAsync()); } /// /// 更新项目状态 /// /// /// /// /// /// /// [HttpPut("{trialId:guid}/{signId:guid}/{trialStatusStr}/{reason?}")] [UnitOfWork] public async Task UpdateTrialState(Guid trialId, string trialStatusStr, Guid signId, string? reason, [FromServices] IEasyCachingProvider _provider) { var trial = await _trialRepository.Where(t => t.Id == trialId, true).IgnoreQueryFilters().FirstOrDefaultAsync().IfNullThrowException(); if (trialStatusStr == StaticData.TrialOngoing) { if (trial.IsTrialBasicLogicConfirmed && trial.IsTrialProcessConfirmed && trial.IsTrialUrgentConfirmed && trial.VisitPlanConfirmed) { } else { return ResponseOutput.NotOk("项目 基础配置、流程配置、加急配置 、访视计划,有未确认项"); } } trial.TrialStateChangeList.Add(new TrialStateChange() { OriginState = trial.TrialStatusStr, NowState = trialStatusStr, Reason = reason ?? String.Empty, TrialId = trialId }); trial.TrialStatusStr = trialStatusStr; //Paused、 添加工总量 算医生读片中 if (trialStatusStr.Contains(StaticData.TrialCompleted)) { await _repository.BatchUpdateAsync(u => u.TrialId == trialId, e => new Enroll { EnrollStatus = (int)EnrollStatus.Finished }); await _trialRepository.BatchUpdateAsync(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(t => t.Id == signId, u => new TrialSign() { IsCompleted = true }); return ResponseOutput.Result(success); } /// /// 项目状态 变更历史 /// /// /// [HttpGet("{trialId:guid}")] public async Task> GetTrialStateChangeList(Guid trialId) { return await _repository.Where(t => t.TrialId == trialId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); } /// /// 废除项目 /// /// /// /// /// [HttpPut("{trialId:guid}/{signId:guid}/{isAbandon:bool}")] public async Task AbandonTrial(Guid trialId, Guid signId, bool isAbandon) { await _trialRepository.BatchUpdateAsync(t => t.Id == trialId, u => new Trial() { IsDeleted = isAbandon }); var success = await _repository.BatchUpdateAsync(t => t.Id == signId, u => new TrialSign() { IsCompleted = true }); return ResponseOutput.Result(success); } /// /// 获取 配置的所有信息 没有分多个接口 /// /// /// [HttpGet("{trialId:guid}")] public async Task GetTrialConfigInfo(Guid trialId) { return await _trialRepository.Where(t => t.Id == trialId).ProjectTo(_mapper.ConfigurationProvider) .FirstOrDefaultAsync().IfNullThrowException(); } /// /// 配置流程 /// /// /// [HttpPut] public async Task ConfigTrialProcessInfo(TrialProcessConfig trialConfig) { if (!await _trialRepository.Where(t => t.Id == trialConfig.TrialId).IgnoreQueryFilters().AnyAsync(t => t.TrialStatusStr == StaticData.TrialInitializing)) { return ResponseOutput.NotOk(" only in Initializing State can operate "); } 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); return ResponseOutput.Ok(await _repository.SaveChangesAsync()); } /// /// 配置加急信息 /// /// /// [HttpPut] public async Task ConfigTrialUrgentInfo(TrialUrgentConfig trialConfig) { if (!await _repository.Where(t => t.Id == trialConfig.TrialId).IgnoreQueryFilters().AnyAsync(t => t.TrialStatusStr == StaticData.TrialOngoing || t.TrialStatusStr == StaticData.TrialInitializing)) { return ResponseOutput.NotOk(" only in Initializing or Ongoing State can operate "); } var trialInfo = await _trialRepository.FirstOrDefaultAsync(t => t.Id == trialConfig.TrialId); if (trialInfo == null) return Null404NotFound(trialInfo); //项目紧急 当前所有已提交,但未完成的访视,设置为加急。后续提交的访视也设置为加急 , if (trialConfig.IsUrgent) { await _repository.BatchUpdateAsync(t => t.TrialId == trialInfo.Id && t.SubmitState == SubmitStateEnum.Submitted && t.ForwardState < ForwardStateEnum.Forwarded, s => new SubjectVisit() { IsUrgent = trialConfig.IsUrgent }); } else //之前设置为加急的访视状态不变。后续提交的访视,为不加急。 { } _mapper.Map(trialConfig, trialInfo); return ResponseOutput.Ok(await _repository.SaveChangesAsync()); } [Obsolete] [HttpPost("{trialId:guid}/{type}")] public async Task UploadTrialFile(IFormFile file, string type, Guid trialId, [FromServices] IWebHostEnvironment _hostEnvironment) { var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).IfNullThrowException().FullName; //上传根路径 var _fileStorePath = Path.Combine(rootPath, StaticData.TrialDataFolder); //文件类型路径处理 var uploadFolderPath = Path.Combine(_fileStorePath, trialId.ToString(), type); if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath); var realName = file.FileName; var fileNameEX = Path.GetExtension(realName); var trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileNameEX; var relativePath = $"/{StaticData.TrialDataFolder}/{trialId}/{type}/{trustedFileNameForFileStorage}"; var filePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage); using (FileStream fs = System.IO.File.Create(filePath)) { await file.CopyToAsync(fs); fs.Flush(); } return ResponseOutput.Ok(new { FilePath = relativePath, FullFilePath = relativePath + "?access_token=" + _userInfo.UserToken }); } } }