irc-netcore-api/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs

653 lines
31 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using IRaCIS.Core.Infrastructure.ExpressionExtend;
using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Magicodes.ExporterAndImporter.Excel.AspNetCore;
using IRaCIS.Core.Application.Service.Inspection.Interface;
using Newtonsoft.Json;
namespace IRaCIS.Application.Services
{
[ApiExplorerSettings(GroupName = "Trial")]
public class VisitPlanService : BaseService, IVisitPlanService
{
private readonly IRepository<VisitStage> _visitStageRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<VisitPlanInfluenceStat> _influnceStatRepository;
private readonly IRepository<VisitPlanInfluenceStudy> _influnceRepository;
private readonly IInspectionService _inspectionService;
public VisitPlanService(IRepository<VisitStage> visitStageRepository,IRepository<Trial> trialRepository, IRepository<SubjectVisit> subjectVisitRepository,
IRepository<VisitPlanInfluenceStat> influnceStatRepository,
IRepository<VisitPlanInfluenceStudy> visitPlanInfluenceStudy,
IInspectionService inspectionService)
{
_visitStageRepository = visitStageRepository;
_trialRepository = trialRepository;
this._subjectVisitRepository = subjectVisitRepository;
this._influnceStatRepository = influnceStatRepository;
this._influnceRepository = visitPlanInfluenceStudy;
this._inspectionService = inspectionService;
}
///暂时不用
/// <summary> 获取项目访视计划</summary>
public async Task<PageOutput<VisitStageDTO>> GetTrialVisitStageList(VisitPlanQueryDTO param)
{
var visitStageQuery = _visitStageRepository.AsQueryable(true).Where(u => u.TrialId == param.TrialId)
.WhereIf(!string.IsNullOrWhiteSpace(param.Keyword), t => t.VisitName.Contains(param.Keyword))
.ProjectTo<VisitStageDTO>(_mapper.ConfigurationProvider);
return await visitStageQuery.ToPagedListAsync(param.PageIndex, param.PageSize, "CreateTime", param.Asc);
}
/// <summary> 根据项目Id获取项目访视计划(不分页)[New]</summary>
[HttpGet("{trialId:guid}")]
public async Task<VisitPlanView> GetVisitStageList(Guid trialId)
{
var query = _visitStageRepository.AsQueryable(true).Where(u => u.TrialId == trialId)
.ProjectTo<VisitStageDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.VisitNum);
var list = await query.ToListAsync();
var trial = await _repository.FirstOrDefaultAsync<Trial>(t => t.Id == trialId).IfNullThrowException();
return new VisitPlanView()
{
VisitPlanList = list,
TimePointsPerPatient = trial.TimePointsPerPatient,
VisitPlanConfirmed = trial.VisitPlanConfirmed,
IsHaveFirstGiveMedicineDate = trial.IsHaveFirstGiveMedicineDate,
//SubjectHasAdded = _subjectVisitRepository.Any(t => t.TrialId == trialId)
};
}
/// <summary>
/// 获取访视计划下拉框列表
/// </summary>
/// <param name="trialId"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}")]
public async Task<IEnumerable<VisitStageSelectDTO>> GetTrialVisitStageSelect(Guid trialId)
{
var query = _visitStageRepository.Where(u => u.TrialId == trialId)
.ProjectTo<VisitStageSelectDTO>(_mapper.ConfigurationProvider).OrderBy(t => t.VisitNum);
var list = await query.ToListAsync();
return list;
}
/// <summary> 添加或更新访视计划某项[New]</summary>
[HttpPost]
[UnitOfWork]
public async Task<IResponseOutput<string>> AddOrUpdateVisitStage(VisitPlanCommand visitPlan)
{
DateTime createtime = DateTime.Now;
List<DataInspection> datas = new List<DataInspection>();
if (!await _trialRepository.Where(t => t.Id == visitPlan.TrialId).IgnoreQueryFilters().AnyAsync(t => t.TrialStatusStr == StaticData.TrialOngoing || t.TrialStatusStr == StaticData.TrialInitializing))
{
return ResponseOutput.NotOk(" only in Initializing or Ongoing State can operate ");
}
var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == visitPlan.TrialId,ignoreQueryFilters:true)
.Select(t => new { t.Id, t.VisitNum, t.VisitDay }).OrderBy(t => t.VisitNum).ToListAsync();
//更新的时候,需要排除自己
if (visitPlan.Id != null)
{
visitPlanList = visitPlanList.Where(t => t.Id != visitPlan.Id).ToList();
}
if (visitPlanList.Any(t => t.VisitNum < visitPlan.VisitNum))
{
//比当前 visitNum小的 visitDay的最大值 还小 不允许添加
if (visitPlan.VisitDay <= visitPlanList.Where(t => t.VisitNum < visitPlan.VisitNum).Select(t => t.VisitDay).Max())
{
return ResponseOutput.NotOk("For the visit plan, the VisitDay with a larger VisitNum should be larger than the VisitDay with a smaller VisitNum.");
}
}
if (visitPlanList.Any(t => t.VisitNum > visitPlan.VisitNum))
{
if (visitPlan.VisitDay >= visitPlanList.Where(t => t.VisitNum > visitPlan.VisitNum).Select(t => t.VisitDay).Min())
{
return ResponseOutput.NotOk("For the visit plan, the VisitDay with a larger VisitNum should be larger than the VisitDay with a smaller VisitNum.");
}
}
if (visitPlan.Id == Guid.Empty || visitPlan.Id == null)//add
{
if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && (t.VisitName == visitPlan.VisitName || t.VisitNum == visitPlan.VisitNum), true))
{
return ResponseOutput.NotOk("A visit with the same VisitName/VisitNum already existed in the current visit plan.");
}
if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && t.IsBaseLine, true) && visitPlan.IsBaseLine)
{
return ResponseOutput.NotOk("A visit already is baseline in the current visit plan.");
}
//已添加受试者 都不存在该新增的计划名称 那么该项目所有受试者都增加一个访视记录
if (!await _subjectVisitRepository.AnyAsync(t => t.VisitName == visitPlan.VisitName && t.TrialId == visitPlan.TrialId))
{
var subjectSVS = await _subjectVisitRepository.Where(t => t.TrialId == visitPlan.TrialId).Select(t => new { t.SubjectId, t.SiteId,t.IsFinalVisit }).Distinct().ToListAsync();
var subjects = subjectSVS.Select(t => new { t.SubjectId, t.SiteId }).Distinct().ToList();
foreach (var subject in subjects)
{
var svItem = _mapper.Map<SubjectVisit>(visitPlan);
svItem.SiteId = subject.SiteId;
svItem.SubjectId = subject.SubjectId;
svItem.Id = Guid.NewGuid();
//设置了末次访视,那么加访视计划的时候,设置为不可用
if (subjectSVS.Any(t => t.SubjectId == svItem.SubjectId && t.IsFinalVisit))
{
svItem.VisitExecuted = VisitExecutedEnum.Unavailable;
}
//datas.Add(new DataInspection()
//{
// SubjectVisitId = svItem.Id,
// SubjectVisitName = svItem.VisitName,
// BlindName = visitPlan.BlindName,
// Identification = "Add|Visit|Info|Visit-Image Upload",
// SiteId = svItem.SiteId,
// TrialId = svItem.TrialId,
// SubjectId = svItem.SubjectId,
// IsSign = false,
// CreateTime = createtime,
// JsonDetail = JsonConvert.SerializeObject(svItem)
//});
await _repository.AddAsync(svItem);
}
}
var visitPlanItem = _mapper.Map<VisitStage>(visitPlan);
visitPlanItem.BlindName = "B" + ((int)visitPlanItem.VisitNum * 10).ToString("D3");
var result = await _repository.AddAsync(visitPlanItem);
visitPlan.Id = result.Id;
//datas.Add(new DataInspection()
//{
// BlindName = visitPlan.BlindName,
// Identification = "Add|Visit|Info|Visit-Image Upload",
// TrialId = visitPlan.TrialId,
// IsSign = false,
// CreateTime = createtime.AddSeconds(1),
// VisitStageId = result.Id,
// JsonDetail = JsonConvert.SerializeObject(visitPlan)
//});
//更新项目访视计划状态为未确认
await _trialRepository.BatchUpdateAsync(u => u.Id == visitPlan.TrialId, t => new Trial() { VisitPlanConfirmed = false });
await _repository.SaveChangesAsync();
//return ResponseOutput.Ok(result.Id.ToString());
}
else//update
{
if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && (t.VisitName == visitPlan.VisitName || t.VisitNum == visitPlan.VisitNum) && t.Id != visitPlan.Id,true))
{
return ResponseOutput.NotOk("A visit with the same VisitName/VisitNum already existed in the current visit plan.");
}
if (await _visitStageRepository.AnyAsync(t => t.TrialId == visitPlan.TrialId && t.IsBaseLine && t.Id != visitPlan.Id,true) && visitPlan.IsBaseLine)
{
return ResponseOutput.NotOk("A visit already is baseline in the current visit plan.");
}
var stage = await _visitStageRepository.FirstOrDefaultAsync(t => t.Id == visitPlan.Id,true);
if (stage == null) return ResponseOutput.NotOk("None");
//修改是否是基线
if (stage.IsBaseLine && stage.IsBaseLine != visitPlan.IsBaseLine)
{
if (await _repository.Where<SubjectVisit>(t => t.TrialId == visitPlan.TrialId).AnyAsync(v => v.IsBaseLine && v.SubmitState >= SubmitStateEnum.ToSubmit))
{
return ResponseOutput.NotOk("有CRC已经为基线上传了影像数据,不允许修改基线");
}
}
_mapper.Map(visitPlan, stage);
stage.BlindName = "B" + ((int)visitPlan.VisitNum * 10).ToString("D3");
//更新项目访视计划状态为未确认
//await _trialRepository.UpdateFromQueryAsync(u => u.Id == visitPlan.TrialId, t => new Trial() { VisitPlanConfirmed = false });
await _repository.SaveChangesAsync();
//return ResponseOutput.Ok();
}
await _inspectionService.AddListInspectionRecordAsync(datas);
return ResponseOutput.Ok(visitPlan.Id.Value.ToString());
}
/// <summary> 删除项目计划某一项[New]</summary>
[HttpDelete("{id:guid}/{trialId:guid}")]
[TrialAudit(AuditType.TrialAudit, AuditOptType.DeleteTrialVisitPlanItem)]
[TypeFilter(typeof(TrialResourceFilter))]
public async Task<IResponseOutput> DeleteVisitStage(Guid id)
{
var visitPlan = await _visitStageRepository.FirstOrDefaultAsync(t => t.Id == id);
if (visitPlan == null) return Null404NotFound(visitPlan);
if (await _repository.AnyAsync<SubjectVisit>(t => t.VisitName == visitPlan.VisitName && t.TrialId == visitPlan.TrialId && t.VisitExecuted == VisitExecutedEnum.Executed))
{
return ResponseOutput.NotOk("The visit plan has been assigned to the subjects and executed.");
}
var list = await _subjectVisitRepository.Where(t => t.TrialId == visitPlan.TrialId && t.VisitName == visitPlan.VisitName).ToListAsync();
List<DataInspection> datas = new List<DataInspection>();
var createtime = DateTime.Now.AddSeconds(1);
list.ForEach(x =>
{
datas.Add(new DataInspection()
{
BlindName = x.BlindName,
IsSign = false,
SiteId = x.SiteId,
SubjectId = x.SubjectId,
SubjectVisitId = x.Id,
CreateTime = createtime,
SubjectVisitName = x.VisitName,
TrialId = x.TrialId,
JsonDetail = JsonConvert.SerializeObject(x),
Identification = "Delete|Visit|Data|Visit-Image Upload"
});
});
await _inspectionService.AddListInspectionRecordAsync(datas);
await _repository.BatchDeleteAsync<SubjectVisit>(t => t.TrialId == visitPlan.TrialId && t.VisitName == visitPlan.VisitName);
var result = await _visitStageRepository.BatchDeleteAsync(u => u.Id == id);
return ResponseOutput.Result(result);
}
[UnitOfWork]
[HttpPost("{trialId:guid}")]
[TrialAudit(AuditType.TrialAudit, AuditOptType.ConfirmTrialVisitPlan)]
public async Task<IResponseOutput> ConfirmTrialVisitPlan(Guid trialId)
{
if (!await _trialRepository.AnyAsync(t => t.Id == trialId &&( t.TrialStatusStr==StaticData.TrialInitializing || t.TrialStatusStr == StaticData.TrialOngoing)))
{
return ResponseOutput.NotOk("仅仅在项目初始化或者进行中时,才允许修改确认");
}
if (!await _visitStageRepository.AnyAsync(t => t.TrialId == trialId && t.IsBaseLine))
{
return ResponseOutput.NotOk("没有基线,不允许确认");
}
if (!await _trialRepository.AnyAsync(t => t.Id == trialId && t.IsTrialBasicLogicConfirmed && t.IsTrialProcessConfirmed && t.IsTrialUrgentConfirmed))
{
return ResponseOutput.NotOk("项目配置未确认,不允许确认访视计划");
}
var svList = await _visitStageRepository.Where(t => t.TrialId == trialId).Select(u => new { u.VisitDay, u.IsBaseLine }).ToListAsync();
if (svList.Min(t => t.VisitDay) != svList.Where(t => t.IsBaseLine).FirstOrDefault()?.VisitDay)
{
return ResponseOutput.NotOk("基线VisitDay 不是最小的, 不允许确认");
}
List<DataInspection> datas = new List<DataInspection>();
var addvisitStages = await _visitStageRepository.Where(x => !x.IsHaveFirstConfirmed&&x.TrialId== trialId).ToListAsync();
//更新项目访视计划状态为已确认
await _trialRepository.BatchUpdateAsync(u => u.Id == trialId, t => new Trial() { VisitPlanConfirmed = true });
//找到访视计划修改的Item
var changedList = await _visitStageRepository.Where(t => t.TrialId == trialId && t.IsConfirmed == false)
.Select(t => new { t.Trial.IsHaveFirstGiveMedicineDate, t.Id, t.VisitName, t.TrialId, t.VisitWindowLeft, t.VisitWindowRight, t.VisitDay, t.VisitNum, t.IsBaseLine }).ToListAsync();
var createtime = DateTime.Now.AddSeconds(1);
changedList.ForEach(x =>
{
datas.Add(new DataInspection()
{
IsSign = false,
CreateTime = createtime,
//SubjectVisitName = x.VisitName,
VisitStageId = x.Id,
TrialId = x.TrialId,
JsonDetail = JsonConvert.SerializeObject(x),
Identification = "Confirm|Visit Plan Template|Data|Trial Setting-Visit Plan"
});
});
//访视计划 整体状态变更为 确认
await _visitStageRepository.BatchUpdateAsync(u => u.TrialId == trialId, t => new VisitStage() { IsConfirmed = true ,IsHaveFirstConfirmed = true});
var stat = new VisitPlanInfluenceStat() { TrialId = trialId };
foreach (var changedItem in changedList)
{
//找到该项目 访视已经执行,并且配置了有首次给药日期 并且更新后超窗的访视,要把超窗之前的值也要查询出来
var qcPassedVisitList = await _repository.Where<SubjectVisit>(t => t.TrialId == trialId
&& t.VisitExecuted == VisitExecutedEnum.Executed
&& t.AuditState == AuditStateEnum.QCPassed
&& t.Trial.IsHaveFirstGiveMedicineDate == true
&& t.VisitStageId == changedItem.Id
&& t.Subject.FirstGiveMedicineTime != null
).Select(k => new
{
SubjectVisitId = k.Id,
SelfWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowLeft),
SelfWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowRight + 1).AddSeconds(-1),
NowWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft),
NowWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight + 1).AddSeconds(-1),
NoneDicomStudyList =
k.NoneDicomStudyList //之前是查询调整之后超窗的 现在调整前超窗 调整后 没超窗的也要记录
//.Where(study => study.ImageDate <k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft??0)
//|| study.ImageDate >k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
.Select(t => new { NoneDicomStudyId = t.Id, t.Modality, StudyTime = t.ImageDate }),
DicomStudyList = k.StudyList
//.Where(study => study.StudyTime <k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft??0)
// || study.StudyTime >k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
.Select(t => new { StudyId = t.Id, Modality = t.Modalities, t.StudyTime })
}).ToListAsync();
foreach (var visit in qcPassedVisitList)
{
//找到本身没有超窗的数据 修改后超窗的
visit.DicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
{
stat.InconsistentCount++;
stat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
{
IsOverWindowNowNotOverWindow = false,
Modality = t.Modality,
SubjectVisitId = visit.SubjectVisitId,
StudyId = t.StudyId,
IsDicomStudy = true,
StudyTime = t.StudyTime,
TrialId = trialId,
HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
});
});
visit.NoneDicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
{
stat.InconsistentCount++;
stat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
{
IsOverWindowNowNotOverWindow = false,
Modality = t.Modality,
SubjectVisitId = visit.SubjectVisitId,
StudyId = t.NoneDicomStudyId,
IsDicomStudy = false,
StudyTime = t.StudyTime,
TrialId = trialId,
HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
});
});
//本身超窗 修改后没超窗的
visit.DicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
{
stat.InconsistentCount++;
stat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
{
IsOverWindowNowNotOverWindow = true,
Modality = t.Modality,
SubjectVisitId = visit.SubjectVisitId,
StudyId = t.StudyId,
IsDicomStudy = true,
StudyTime = t.StudyTime,
TrialId = trialId,
HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
});
});
visit.NoneDicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
{
stat.InconsistentCount++;
stat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
{
IsOverWindowNowNotOverWindow = true,
Modality = t.Modality,
SubjectVisitId = visit.SubjectVisitId,
StudyId = t.NoneDicomStudyId,
IsDicomStudy = false,
StudyTime = t.StudyTime,
TrialId = trialId,
HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
});
});
}
var list = await _subjectVisitRepository.Where(t => t.TrialId == trialId && t.VisitStageId == changedItem.Id).ToListAsync();
list.ForEach(x =>
{
datas.Add(new DataInspection()
{
BlindName = x.BlindName,
IsSign = false,
SiteId = x.SiteId,
SubjectId = x.SubjectId,
SubjectVisitId = x.Id,
CreateTime = createtime,
SubjectVisitName = x.VisitName,
TrialId = x.TrialId,
JsonDetail = JsonConvert.SerializeObject(new {
IsBaseLine = changedItem.IsBaseLine,
VisitName = changedItem.VisitName,
VisitNum = changedItem.VisitNum,
VisitDay = changedItem.VisitDay,
VisitWindowLeft = changedItem.VisitWindowLeft,
VisitWindowRight = changedItem.VisitWindowRight
}),
Identification = "Edit|Visit|Info|Visit-Image Upload"
});
});
//变更某一访视计划Item 受试者访视相关字段
await _repository.BatchUpdateAsync<SubjectVisit>(t => t.TrialId == trialId && t.VisitStageId == changedItem.Id, k => new SubjectVisit()
{
IsBaseLine = changedItem.IsBaseLine,
VisitName = changedItem.VisitName,
VisitNum = changedItem.VisitNum,
VisitDay = changedItem.VisitDay,
VisitWindowLeft = changedItem.VisitWindowLeft,
VisitWindowRight = changedItem.VisitWindowRight
});
}
var subjectsids = _repository.GetQueryable<Subject>().Where(x => x.TrialId == trialId).Select(x => new
{
x.Code,
x.SiteId,
x.Id,
x.IsEnrollment,
x.IsUrgent
});
List<SubjectVisit> subjectVisits = new List<SubjectVisit>();
addvisitStages.ForEach(x =>
{
subjectsids.ForEach(y =>
{
var guid = new Guid();
// 新增受试者
datas.Add(new DataInspection()
{
BlindName = x.BlindName,
IsSign = false,
SiteId = y.SiteId,
SubjectId = y.Id,
SubjectVisitId = guid,
CreateTime = createtime.AddMilliseconds(200),
SubjectVisitName = x.VisitName,
TrialId = x.TrialId,
Identification = "Add|Visit|Info|Visit-Image Upload",
JsonDetail = JsonConvert.SerializeObject(new
{
IsBaseLine = x.IsBaseLine,
VisitName = x.VisitName,
VisitNum = x.VisitNum,
VisitDay = x.VisitDay,
VisitExecuted=false,
BlindName=x.BlindName,
VisitWindowLeft = x.VisitWindowLeft,
VisitWindowRight = x.VisitWindowRight,
IsEnrollment=y.IsEnrollment,
IsUrgent=y.IsUrgent,
}),
});
// 初始化受试者
datas.Add(new DataInspection()
{
SiteId = y.SiteId,
SubjectId = y.Id,
SubjectVisitId = guid,
TrialId = x.TrialId,
SubjectCode = y.Code,
BlindName = x.BlindName,
SubjectVisitName = x.VisitName,
IsSign = false,
CreateTime = createtime.AddMilliseconds(500),
Identification = "Init|Visit|Status|Visit-Image Upload",
JsonDetail = JsonConvert.SerializeObject(new
{
BlindName = x.BlindName,
VisitName = x.VisitName,
SubmitState = "",
AuditState = "",
IsBaseLine = x.IsBaseLine,
IsEnrollment = y.IsEnrollment,
IsUrgent = y.IsUrgent,
})
});
subjectVisits.Add(new SubjectVisit()
{
SiteId = y.SiteId,
SubjectId = y.Id,
Id = guid,
BlindName=x.BlindName,
IsBaseLine=x.IsBaseLine,
IsCheckBack=x.IsBaseLine,
IsUrgent=y.IsUrgent,
});
});
});
await _inspectionService.AddListInspectionRecordAsync(datas);
await _repository.AddAsync(stat);
await _repository.AddRangeAsync(subjectVisits);
await _repository.SaveChangesAsync();
return ResponseOutput.Ok();
}
[HttpGet("{trialId:guid}")]
public async Task<List<VisitPlanInfluenceSubjectVisitStatDTO>> GetInfluenceHistoryList(Guid trialId, [FromServices] IRepository<VisitPlanInfluenceStat> _influnceStatRepository)
{
var list = await _influnceStatRepository.Where(t => t.TrialId == trialId).ProjectTo<VisitPlanInfluenceSubjectVisitStatDTO>(_mapper.ConfigurationProvider).OrderByDescending(t => t.CreateTime).ToListAsync();
return list;
}
[HttpGet("{visitPlanInfluenceStatId:guid}")]
public async Task<IActionResult> DownloadInflunceStudyList(Guid visitPlanInfluenceStatId)
{
var list = _influnceRepository.Where(t => t.VisitPlanInfluenceStatId == visitPlanInfluenceStatId)
.ProjectTo<VisitPlanInfluenceSubjectVisitDTO>(_mapper.ConfigurationProvider).ToList();
IExporter exporter = new ExcelExporter();
var result = await exporter.ExportAsByteArray(list);
return new XlsxFileResult(bytes: result, fileDownloadName: $"检查导出_{DateTime.Now.ToString("yyyy-MM-dd:hh:mm:ss")}.xlsx");
}
}
}