using IRaCIS.Application.Contracts; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure.ExpressionExtend; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Infra.EFCore; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Interfaces; namespace IRaCIS.Core.Application.Services { [ApiExplorerSettings(GroupName = "Trial")] public class TrialMaintenanceService : BaseService, ITrialSiteService { private readonly IRepository _trialSiteRepository; public TrialMaintenanceService(IRepository trialSiteRepository) { _trialSiteRepository = trialSiteRepository; } /// Pannel 进去 SiteTab [HttpPost] public async Task> GetSiteCRCList(SiteCrcQueryDTO param) { var siteStatQuery = _trialSiteRepository.Where(t => t.TrialId == param.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.Site.SiteName.Contains(param.SiteName)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.CRCUserList.Any(k => k.UserId == _userInfo.Id)) .WhereIf(!string.IsNullOrWhiteSpace(param.UserRealName), t => t.CRCUserList.Any(k => (k.User.LastName + " / " + k.User.FirstName).Contains(param.UserRealName))) .ProjectTo(_mapper.ConfigurationProvider); #region 统计 废弃 //= from trialSite in // join site in _siteRepository.Where() on trialSite.SiteId equals site.Id // join userTrialStat in _userTrialSiteRepository // .Where(t => t.TrialId == param.TrialId).GroupBy(u => u.SiteId) // .Select(g => new { SiteId = g.Key, UserCount = g.Count() }) on site.Id equals userTrialStat.SiteId into kk // from userTrialStat in kk.DefaultIfEmpty() // join subjectStat in _subjectRepository.Where(t => t.TrialId == param.TrialId).GroupBy(u => u.SiteId) // .Select(g => new { SiteId = g.Key, SubjectCount = g.Count() }) on site.Id equals subjectStat // .SiteId // into ST // from subjectStatItem in ST.DefaultIfEmpty() // ////加入 Visit统计 通过site下的受试者过滤visit 加入siteId 后修改 不用通过site下的用户过滤 // //join subjectVisitStat in _subjectVisitRepository.Find(t=>t.TrialId==param.TrialId).GroupBy(t => t.SiteId).Select(g => new { SiteId = g.Key, VisitCount = g.Count() }) on site.Id equals subjectVisitStat.SiteId into SSV // //from subjectVisitStatItem in SSV.DefaultIfEmpty() // //join subjectVisitStat2 in _subjectVisitRepository.Find(t => t.TrialId == param.TrialId&&t.VisitExecuted).GroupBy(t => t.SiteId).Select(g => new { SiteId = g.Key, VisitCount = g.Count() }) on site.Id equals subjectVisitStat2.SiteId into SSV2 // //from subjectVisitStatItem2 in SSV2.DefaultIfEmpty() // join studyStat in _studyRepository.Where(t => t.TrialId == param.TrialId /*&& t.Status != (int)StudyStatus.Abandon*/).GroupBy(u => u.SiteId).Select(g => new { SiteId = g.Key, StudyCount = g.Count() }) on site.Id equals studyStat.SiteId into STT // from studyStatItem in STT.DefaultIfEmpty() // select new SiteStatDTO() // { // SiteId = site.Id, // Site = site.SiteName, // City = site.City, // Country = site.Country, // TrialSiteCode = trialSite.TrialSiteCode, // //VisitCount = subjectVisitStatItem2.VisitCount, // //PlanVisitCount = subjectVisitStatItem.VisitCount, // StudyCount = studyStatItem.StudyCount, // UserCount = userTrialStat.UserCount, // SubjectCount = subjectStatItem.SubjectCount, // UserList = trialSite.CRCUserList.Select(t => new UserTrialDTO() // { // Id = t.Id, // SiteId = t.SiteId, // UserId = t.UserId, // UserRealName = t.UserRealName, // TrialId = t.TrialId, // UserTypeId = t.UserTypeId, // UserType = t.UserType, // //OrganizationTypeId = userTrial.OrganizationTypeId, // //OrganizationType = userTrial.OrganizationType, // //OrganizationId = userTrial.OrganizationId, // OrganizationName = t.User.OrganizationName, // UserName = t.User.UserName, // Phone = t.User.Phone, // UpdateTime = t.UpdateTime, // }).ToList() // }; #endregion return await siteStatQuery.ToPagedListAsync(param.PageIndex, param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "SiteCode" : param.SortField, param.Asc); } /// [new] setting页面Site列表,和getSiteCRCList对比 没有统计数据,增加了一些site信息 [HttpPost] public async Task> GetSiteCRCSimpleList(SiteCrcQueryDTO param) { var siteStatQuery = _trialSiteRepository.Where(t => t.TrialId == param.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.Site.SiteName.Contains(param.SiteName)) .WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName), t => t.TrialSiteAliasName.Contains(param.TrialSiteAliasName)) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.CRCUserList.Any(k => k.UserId == _userInfo.Id)) .WhereIf(!string.IsNullOrWhiteSpace(param.UserRealName), t => t.CRCUserList.Any(k => (k.User.LastName + " / " + k.User.FirstName).Contains(param.UserRealName))) .ProjectTo(_mapper.ConfigurationProvider); #region 废弃 //IQueryable siteStatQuery = from trialSite in _trialSiteRepository.Where(t => t.TrialId == param.TrialId) // join site in _siteRepository.AsQueryable() on trialSite.SiteId equals site.Id // join hospital in _hospitalRepository.AsQueryable() on site.HospitalId equals hospital.Id // join userTrialStat in _userTrialSiteRepository // .Where(t => t.TrialId == param.TrialId).GroupBy(u => u.SiteId) // .Select(g => new { SiteId = g.Key, UserCount = g.Count() }) on site.Id equals userTrialStat.SiteId into kk // from userTrialStat in kk.DefaultIfEmpty() // select new SiteStatSimpleDTO() // { // Id = trialSite.Id, // SiteId = site.Id, // Site = site.SiteName, // SiteCode = site.SiteCode, // TrialSiteCode = trialSite.TrialSiteCode, // Hospital = hospital.HospitalName, // DirectorName = site.DirectorName, // DirectorPhone = site.DirectorPhone, // ContactName = site.ContactName, // ContactPhone = site.ContactPhone, // City = site.City, // Country = site.Country, // UpdateTime = trialSite.UpdateTime, // UserCount = userTrialStat.UserCount, // UserList = trialSite.CRCUserList.Select(t => new UserTrialDTO() // { // Id = t.Id, // SiteId = t.SiteId, // UserId = t.UserId, // UserRealName = t.UserRealName, // TrialId = t.TrialId, // UserTypeId = t.UserTypeId, // UserType = t.UserType, // //OrganizationTypeId = userTrial.OrganizationTypeId, // //OrganizationType = userTrial.OrganizationType, // //OrganizationId = userTrial.OrganizationId, // OrganizationName = t.User.OrganizationName, // UserName = t.User.UserName, // Phone = t.User.Phone, // UpdateTime = t.UpdateTime, // }).ToList() // }; #endregion var result = await siteStatQuery.ToPagedListAsync(param.PageIndex, param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "Site" : param.SortField, param.Asc); return result; } /// 获取某一Site下面的负责的CRC列表 [HttpGet, Route("{trialId:guid}/{siteId:guid}")] public async Task> GetTrialSiteCRCList(Guid trialId,Guid siteId) { var query = _repository.Where(t => t.TrialId == trialId && t.SiteId==siteId).IgnoreQueryFilters() .ProjectTo(_mapper.ConfigurationProvider); return await query.ToListAsync(); } /// [new] Setting页面 Site勾选列表( [HttpPost] public async Task> GetTrialSiteScreeningList(TrialSiteQuery trialSiteQuery) { // 之前选择了的不能再次出现在列表,做的时候我就不建议这样搞,搞好了 现在又要改回去。。。 瞎折腾。。。。 var siteQueryable = _repository.GetQueryable() .WhereIf(!string.IsNullOrWhiteSpace(trialSiteQuery.SiteName.Trim()), t => t.SiteName.Contains(trialSiteQuery.SiteName.Trim())) .ProjectTo(_mapper.ConfigurationProvider, new { trialId = trialSiteQuery.TrialId }); return await siteQueryable.ToPagedListAsync(trialSiteQuery.PageIndex, trialSiteQuery.PageSize, string.IsNullOrWhiteSpace(trialSiteQuery.SortField) ? "SiteName" : trialSiteQuery.SortField, trialSiteQuery.Asc); } /// Setting页面 Site批量添加 [HttpPost] [UnitOfWork] [TrialAudit(AuditType.TrialAudit, AuditOptType.AddTrialSite)] [TypeFilter(typeof(TrialResourceFilter))] public async Task AddTrialSites(List trialSites) { var addArray = _mapper.Map>(trialSites); await _repository.AddRangeAsync(addArray); return ResponseOutput.Result(await _repository.SaveChangesAsync()); } /// /// 编辑项目中Site 基本信息 /// /// /// /// /// /// [UnitOfWork] [HttpPost("{trialId:guid}/{id:guid}/{trialSiteCode}/{trialSiteAliasName?}")] [TypeFilter(typeof(TrialResourceFilter))] public async Task EditTrialSite(Guid id, Guid trialId, string trialSiteCode, string? trialSiteAliasName) { if (await _trialSiteRepository.AnyAsync(t => t.Id != id && t.TrialSiteCode == trialSiteCode && t.TrialId == trialId)) { return ResponseOutput.NotOk("Code is not allowed to be repeated"); } await _trialSiteRepository.UpdateFromQueryAsync(t => t.Id == id, u => new TrialSite() { TrialSiteCode = trialSiteCode, TrialSiteAliasName = trialSiteAliasName ?? String.Empty }); await _repository.SaveChangesAsync(); return ResponseOutput.Ok(); } /// 删除 项目 下某一site [HttpDelete("{id:guid}/{trialId:guid}")] [TrialAudit(AuditType.TrialAudit, AuditOptType.DeleteTrialSite)] [TypeFilter(typeof(TrialResourceFilter))] public async Task DeleteTrialSite(Guid id) { var relation = await _trialSiteRepository.FirstOrDefaultAsync(t => t.Id == id); if (relation == null) return Null404NotFound(relation); var trialId = relation.TrialId; var siteId = relation.SiteId; if (await _repository.AnyAsync(t => t.TrialId == trialId && t.SiteId == siteId)) { return ResponseOutput.NotOk("The site has been associated with CRC, and couldn't be deleted."); } if (await _repository.AnyAsync(t => t.SiteId == siteId && t.TrialId == trialId)) { return ResponseOutput.NotOk("The subjects has been added to this site, and couldn't be deleted."); } if (await _repository.AnyAsync(t => t.SiteId == siteId && t.TrialId == trialId)) { return ResponseOutput.NotOk("The site has been uploaded study, and couldn't be deleted."); } await _repository.DeleteAsync(relation); return ResponseOutput.Result(await _repository.SaveChangesAsync()); } /// 批量添加Site下 CRC的负责人 [HttpPost] [TrialAudit(AuditType.TrialAudit, AuditOptType.AddTrialSiteCRC)] [TypeFilter(typeof(TrialResourceFilter))] public async Task AssignSiteCRC(List trialSiteCRCList) { var addArray = _mapper.Map>(trialSiteCRCList); await _repository.AddRangeAsync(addArray); return ResponseOutput.Result(await _repository.SaveChangesAsync()); } /// 删除CRC人员 [HttpDelete, Route("{id:guid}/{trialId:guid}/{isDelete:bool}")] //[TrialAudit(AuditType.TrialAudit, AuditOptType.DeleteTrialSiteCRC)] [TypeFilter(typeof(TrialResourceFilter))] public async Task DeleteSiteCRC(Guid id, bool isDelete ) { var isSuccess = await _repository.UpdateFromQueryAsync(u => u.Id == id,u=>new TrialSiteUser() { IsDeleted = isDelete, RemoveTime = isDelete ? DateTime.Now : null }); return ResponseOutput.Result(isSuccess); } /// /// 获取项目下的 site 下拉框数据 CRC只看到他负责的 /// /// /// [HttpGet("{trialId:guid}")] public async Task> GetTrialSiteSelect(Guid trialId) { //CRC只看到他负责的 var list = await _trialSiteRepository.Where(t => t.TrialId == trialId) .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.CRCUserList.Any(t => t.UserId == _userInfo.Id)) .ProjectTo(_mapper.ConfigurationProvider).OrderBy(t => t.TrialSiteCode).ToListAsync(); return list; } } }