380 lines
14 KiB
C#
380 lines
14 KiB
C#
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<Trial> _trialRepository;
|
||
|
||
public TrialConfigService(IRepository<Trial> trialRepository)
|
||
{
|
||
_trialRepository = trialRepository;
|
||
}
|
||
|
||
/// <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)
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 签名认证 +
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<IResponseOutput> VerifySignature(SignDTO signDTO)
|
||
{
|
||
|
||
var user = await _repository.FirstOrDefaultAsync<User>(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<TrialSign>(signDTO));
|
||
|
||
await _repository.SaveChangesAsync();
|
||
|
||
return ResponseOutput.Ok(add.Id);
|
||
//}
|
||
|
||
//return ResponseOutput.Ok();
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 业务接口操作成功后, 让签署数据生效
|
||
/// </summary>
|
||
/// <param name="signId"></param>
|
||
/// <returns></returns>
|
||
[HttpPut("{signId:guid}")]
|
||
[Obsolete]
|
||
public async Task<IResponseOutput> MakeSignEffective(Guid signId)
|
||
{
|
||
var success = await _repository.BatchUpdateAsync<TrialSign>(t => t.Id == signId, u => new TrialSign() { IsCompleted = true });
|
||
|
||
return ResponseOutput.Result(success);
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 签名确认 包括项目的三组配置 + QC问题确认 后修改状态 (适用于不会回退的,项目废除、状态修改, 存在回退 不在这里弄,提供单独接口修改状态)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<IResponseOutput> 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<TrialQCQuestion>(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();
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 配置 基础逻辑信息
|
||
/// </summary>
|
||
/// <param name="trialConfig"></param>
|
||
/// <returns></returns>
|
||
[HttpPut]
|
||
public async Task<IResponseOutput> 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());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新项目状态
|
||
/// </summary>
|
||
/// <param name="trialId"></param>
|
||
/// <param name="signId"></param>
|
||
/// <param name="trialStatusStr"></param>
|
||
/// <param name="reason"></param>
|
||
/// <param name="_provider"></param>
|
||
/// <returns></returns>
|
||
[HttpPut("{trialId:guid}/{signId:guid}/{trialStatusStr}/{reason?}")]
|
||
[UnitOfWork]
|
||
public async Task<IResponseOutput> 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<Enroll>(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<TrialSign>(t => t.Id == signId, u => new TrialSign() { IsCompleted = true });
|
||
|
||
|
||
return ResponseOutput.Result(success);
|
||
}
|
||
|
||
/// <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="signId"></param>
|
||
/// <param name="isAbandon"></param>
|
||
/// <returns></returns>
|
||
[HttpPut("{trialId:guid}/{signId:guid}/{isAbandon:bool}")]
|
||
public async Task<IResponseOutput> AbandonTrial(Guid trialId, Guid signId, bool isAbandon)
|
||
{
|
||
|
||
await _trialRepository.BatchUpdateAsync(t => t.Id == trialId, u => new Trial() { IsDeleted = isAbandon });
|
||
|
||
|
||
var success = await _repository.BatchUpdateAsync<TrialSign>(t => t.Id == signId, u => new TrialSign() { IsCompleted = true });
|
||
|
||
|
||
return ResponseOutput.Result(success);
|
||
}
|
||
|
||
|
||
|
||
|
||
/// <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> 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());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 配置加急信息
|
||
/// </summary>
|
||
/// <param name="trialConfig"></param>
|
||
/// <returns></returns>
|
||
[HttpPut]
|
||
public async Task<IResponseOutput> ConfigTrialUrgentInfo(TrialUrgentConfig trialConfig)
|
||
{
|
||
|
||
if (!await _repository.Where<Trial>(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<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);
|
||
|
||
return ResponseOutput.Ok(await _repository.SaveChangesAsync());
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
[Obsolete]
|
||
[HttpPost("{trialId:guid}/{type}")]
|
||
public async Task<IResponseOutput> 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
|
||
});
|
||
|
||
}
|
||
|
||
}
|
||
}
|