using IRaCIS.Application.Contracts; using IRaCIS.Application.Interfaces; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Domain.Share; using Microsoft.AspNetCore.Mvc; namespace IRaCIS.Core.Application.Service { [ApiExplorerSettings(GroupName = "Trial")] public class SubjectService(IRepository _subjectRepository, IRepository _trialRepository, IRepository _subjectVisitRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ISubjectService { /// /// 添加或更新受试者信息[New] /// /// state:1-访视中,2-出组。0-全部 /// [TrialGlobalLimit( "AfterStopCannNotOpt" )] //[Authorize(Policy = IRaCISPolicy.PM_APM_CRC_QC)] public async Task> AddOrUpdateSubject([FromBody] SubjectCommand subjectCommand) { var svlist = new List(); if (await _trialRepository.AnyAsync(t => t.Id == subjectCommand.TrialId && !t.VisitPlanConfirmed)) { //---项目访视计划没有确认。请联系项目经理确认项目访视计划后,再添加受试者。 return ResponseOutput.NotOk(_localizer["Subject_NoConfirmedPlan"]); } var verifyExp1 = new EntityVerifyExp() { VerifyExp = u => u.Code == subjectCommand.Code && u.TrialId == subjectCommand.TrialId, //---已存在具有相关受试者编号的受试者。 VerifyMsg = _localizer["Subject_DuplicateSubjectNum"] }; Subject? mapedSubject = null; if (subjectCommand.Id == null) //insert { mapedSubject = await _subjectRepository.InsertFromDTOAsync(subjectCommand, false, verifyExp1); } else //update { mapedSubject = await _subjectRepository.UpdateFromDTOAsync(subjectCommand, false, false, verifyExp1/*, verifyExp2*/); } await _subjectRepository.SaveChangesAsync(); return ResponseOutput.Ok(mapedSubject.Id.ToString()); } [HttpPut] [UnitOfWork] //[Authorize(Policy = IRaCISPolicy.PM_APM_CRC_QC)] [TrialGlobalLimit( "AfterStopCannNotOpt" )] public async Task UpdateSubjectStatus(SubjectStatusChangeCommand subjectStatusChangeCommand) { await _subjectRepository.UpdateFromDTOAsync(subjectStatusChangeCommand, true); return ResponseOutput.Ok(); } [HttpDelete("{trialId:guid}/{id:guid}")] [TrialGlobalLimit( "AfterStopCannNotOpt" )] [UnitOfWork] //[Authorize(Policy = IRaCISPolicy.PM_APM_CRC)] public async Task DeleteSubject(Guid id) { if (await _subjectVisitRepository.AnyAsync(u => u.SubjectId == id && u.VisitExecuted == VisitExecutedEnum.Executed)) { //---该受试者已经有访视已经上传影像,不允许删除。 return ResponseOutput.NotOk(_localizer["Subject_UploadedVisitNoDelete"]); } await _subjectRepository.UpdatePartialFromQueryAsync(id, x => new Subject { IsDeleted = true, }); await _subjectVisitRepository.UpdatePartialFromQueryAsync(u => u.SubjectId == id, x => new SubjectVisit() { IsDeleted = true, }); var isSuccess = await _subjectRepository.SaveChangesAsync(); return ResponseOutput.Result(isSuccess); } /// 分页获取受试者列表[New] /// /// state:1-访视中,2-出组。0-全部 [HttpPost] public async Task>> GetSubjectList(SubjectQueryParam inQuery) { var subjectQuery = _subjectRepository.Where(u => u.TrialId == inQuery.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Code), t => t.Code.Contains(inQuery.Code)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Name), t => t.ShortName.Contains(inQuery.Name)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Sex), t => t.Sex.Contains(inQuery.Sex)) .WhereIf(inQuery.Status != null, t => t.Status == inQuery.Status) .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId) // CRC 只负责他管理site的受试者 .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.UserRoleId)) .ProjectTo(_mapper.ConfigurationProvider) .WhereIf(inQuery.IsMissingImages != null, t => t.IsMissingImages == inQuery.IsMissingImages); var pageList = await subjectQuery.ToPagedListAsync(inQuery, nameof(SubjectQueryView.Code)); var trialConfig = await _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return ResponseOutput.Ok(pageList, trialConfig); } /// /// 计划外访视 获取受试者选择下拉框列表 /// [HttpGet("{trialSiteId:guid}/{trialId:guid}")] public List GetSubjectListBySiteId(Guid trialSiteId, Guid trialId) { var query = _subjectRepository.Where(t => t.TrialSiteId == trialSiteId && t.TrialId == trialId && t.Status == SubjectStatus.OnVisit).Select(u => new SubjectSelect() { Code = u.Code, FirstName = u.FirstName, LastName = u.LastName, Sex = u.Sex, SubjectId = u.Id, Age = u.Age, MRN = u.MedicalNo, Status = u.Status, FirstGiveMedicineTime = u.FirstGiveMedicineTime }); return query.ToList(); } } }