330 lines
17 KiB
C#
330 lines
17 KiB
C#
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<TrialSite> _trialSiteRepository;
|
||
|
||
public TrialMaintenanceService(IRepository<TrialSite> trialSiteRepository)
|
||
{
|
||
_trialSiteRepository = trialSiteRepository;
|
||
}
|
||
|
||
/// <summary>Pannel 进去 SiteTab </summary>
|
||
[HttpPost]
|
||
public async Task<PageOutput<SiteStatDTO>> 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<SiteStatDTO>(_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);
|
||
|
||
|
||
}
|
||
|
||
|
||
/// <summary>[new] setting页面Site列表,和getSiteCRCList对比 没有统计数据,增加了一些site信息 </summary>
|
||
[HttpPost]
|
||
public async Task<PageOutput<SiteStatSimpleDTO>> 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<SiteStatSimpleDTO>(_mapper.ConfigurationProvider);
|
||
|
||
#region 废弃
|
||
//IQueryable<SiteStatSimpleDTO> 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;
|
||
}
|
||
|
||
|
||
/// <summary>获取某一Site下面的负责的CRC列表</summary>
|
||
[HttpGet, Route("{trialId:guid}/{siteId:guid}")]
|
||
public async Task<List<UserTrialDTO>> GetTrialSiteCRCList(Guid trialId,Guid siteId)
|
||
{
|
||
var query = _repository.Where<TrialSiteUser>(t => t.TrialId == trialId && t.SiteId==siteId).IgnoreQueryFilters()
|
||
.ProjectTo<UserTrialDTO>(_mapper.ConfigurationProvider);
|
||
|
||
return await query.ToListAsync();
|
||
}
|
||
|
||
|
||
/// <summary>[new] Setting页面 Site勾选列表( </summary>
|
||
[HttpPost]
|
||
public async Task<PageOutput<TrialSiteScreeningDTO>> GetTrialSiteScreeningList(TrialSiteQuery trialSiteQuery)
|
||
{
|
||
// 之前选择了的不能再次出现在列表,做的时候我就不建议这样搞,搞好了 现在又要改回去。。。 瞎折腾。。。。
|
||
|
||
|
||
var siteQueryable = _repository.GetQueryable<Site>()
|
||
.WhereIf(!string.IsNullOrWhiteSpace(trialSiteQuery.SiteName.Trim()), t => t.SiteName.Contains(trialSiteQuery.SiteName.Trim()))
|
||
.ProjectTo<TrialSiteScreeningDTO>(_mapper.ConfigurationProvider, new { trialId = trialSiteQuery.TrialId });
|
||
|
||
|
||
return await siteQueryable.ToPagedListAsync(trialSiteQuery.PageIndex,
|
||
trialSiteQuery.PageSize, string.IsNullOrWhiteSpace(trialSiteQuery.SortField) ? "SiteName" : trialSiteQuery.SortField, trialSiteQuery.Asc);
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
/// <summary>Setting页面 Site批量添加</summary>
|
||
[HttpPost]
|
||
[UnitOfWork]
|
||
[TrialAudit(AuditType.TrialAudit, AuditOptType.AddTrialSite)]
|
||
[TypeFilter(typeof(TrialResourceFilter))]
|
||
public async Task<IResponseOutput> AddTrialSites(List<TrialSiteCommand> trialSites)
|
||
{
|
||
var addArray = _mapper.Map<List<TrialSite>>(trialSites);
|
||
|
||
await _repository.AddRangeAsync(addArray);
|
||
|
||
|
||
return ResponseOutput.Result(await _repository.SaveChangesAsync());
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 编辑项目中Site 基本信息
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <param name="trialId"></param>
|
||
/// <param name="trialSiteCode"></param>
|
||
/// <param name="trialSiteAliasName"></param>
|
||
/// <returns></returns>
|
||
[UnitOfWork]
|
||
[HttpPost("{trialId:guid}/{id:guid}/{trialSiteCode}/{trialSiteAliasName?}")]
|
||
[TypeFilter(typeof(TrialResourceFilter))]
|
||
public async Task<IResponseOutput> 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();
|
||
}
|
||
|
||
|
||
/// <summary>删除 项目 下某一site </summary>
|
||
[HttpDelete("{id:guid}/{trialId:guid}")]
|
||
[TrialAudit(AuditType.TrialAudit, AuditOptType.DeleteTrialSite)]
|
||
[TypeFilter(typeof(TrialResourceFilter))]
|
||
public async Task<IResponseOutput> 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<TrialSiteUser>(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<Subject>(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<DicomStudy>(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());
|
||
}
|
||
|
||
|
||
|
||
/// <summary> 批量添加Site下 CRC的负责人 </summary>
|
||
[HttpPost]
|
||
[TrialAudit(AuditType.TrialAudit, AuditOptType.AddTrialSiteCRC)]
|
||
[TypeFilter(typeof(TrialResourceFilter))]
|
||
public async Task<IResponseOutput> AssignSiteCRC(List<AssginSiteCRCCommand> trialSiteCRCList)
|
||
{
|
||
var addArray = _mapper.Map<List<TrialSiteUser>>(trialSiteCRCList);
|
||
|
||
await _repository.AddRangeAsync(addArray);
|
||
|
||
return ResponseOutput.Result(await _repository.SaveChangesAsync());
|
||
}
|
||
|
||
/// <summary> 删除CRC人员</summary>
|
||
[HttpDelete, Route("{id:guid}/{trialId:guid}/{isDelete:bool}")]
|
||
|
||
//[TrialAudit(AuditType.TrialAudit, AuditOptType.DeleteTrialSiteCRC)]
|
||
[TypeFilter(typeof(TrialResourceFilter))]
|
||
public async Task<IResponseOutput> DeleteSiteCRC(Guid id, bool isDelete )
|
||
{
|
||
var isSuccess = await _repository.UpdateFromQueryAsync<TrialSiteUser>(u => u.Id == id,u=>new TrialSiteUser()
|
||
{ IsDeleted = isDelete, RemoveTime = isDelete ? DateTime.Now : null });
|
||
|
||
return ResponseOutput.Result(isSuccess);
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取项目下的 site 下拉框数据 CRC只看到他负责的
|
||
/// </summary>
|
||
/// <param name="trialId"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("{trialId:guid}")]
|
||
public async Task<IEnumerable<TrialSiteForSelect>> 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<TrialSiteForSelect>(_mapper.ConfigurationProvider).OrderBy(t => t.TrialSiteCode).ToListAsync();
|
||
|
||
|
||
return list;
|
||
}
|
||
|
||
|
||
}
|
||
} |