Files
irc-netcore-api/IRaCIS.Core.Application/Service/TrialSiteUser/TrialSiteService.cs
T
hang 6e22246555
continuous-integration/drone/push Build is running
中心接口增加参数
2026-06-16 17:16:57 +08:00

342 lines
15 KiB
C#

using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
namespace IRaCIS.Core.Application.Services
{
[ApiExplorerSettings(GroupName = "Trial")]
public class TrialMaintenanceService(IRepository<TrialSite> _trialSiteRepository,
IRepository<TrialSiteUserRole> _trialSiteUserRoleRepository,
IRepository<Site> _siteRepository,
IRepository<Subject> _subjectRepository,
IRepository<VisitTask> _visitTaskRepository,
IRepository<Trial> _trialRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ITrialSiteService
{
#region 账户修改已维护
/// <summary>获取某一Site下面的负责的CRC列表</summary>
[HttpGet, Route("{trialId:guid}/{siteId:guid}")]
public async Task<List<TrialSiteCRCListDTO>> GetTrialSiteCRCList(Guid trialId, Guid siteId)
{
var query = _trialSiteUserRoleRepository.Where(t => t.TrialId == trialId && t.TrialSiteId == siteId).IgnoreQueryFilters()
.ProjectTo<TrialSiteCRCListDTO>(_mapper.ConfigurationProvider);
var list = await query.ToListAsync();
foreach (var item in list)
{
item.TrialSiteId = siteId;
}
return list;
}
/// <summary> 批量添加Site下 CRC的负责人 </summary>
[HttpPost]
[TrialGlobalLimit("AfterStopCannNotOpt")]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> AssignSiteCRC(List<AssginSiteCRCCommand> trialSiteCRCList)
{
var addArray = _mapper.Map<List<TrialSiteUserRole>>(trialSiteCRCList);
await _trialSiteUserRoleRepository.AddRangeAsync(addArray);
await _trialSiteUserRoleRepository.SaveChangesAsync();
return ResponseOutput.Result(true);
}
/// <summary> 删除CRC人员</summary>
[HttpDelete, Route("{id:guid}/{trialId:guid}/{isDelete:bool}")]
[TrialGlobalLimit("AfterStopCannNotOpt")]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> DeleteSiteCRC(Guid id, bool isDelete)
{
await _trialSiteUserRoleRepository.UpdatePartialFromQueryAsync(t => t.Id == id, u => new TrialSiteUserRole() { IsDeleted = isDelete, DeletedTime = isDelete ? DateTime.Now : null }, true, true);
//删除又启用改授权时间
if (isDelete == false)
{
await _trialSiteUserRoleRepository.BatchUpdateNoTrackingAsync(t => t.Id == id, u => new TrialSiteUserRole() { CreateTime = DateTime.Now });
}
return ResponseOutput.Ok();
}
#endregion
/// <summary>Pannel 进去 SiteTab </summary>
[HttpPost]
public async Task<PageOutput<SiteStatDTO>> GetSiteCRCList(SiteCrcQueryDTO inQuery)
{
var siteStatQuery = _trialSiteRepository.Where(t => t.TrialId == inQuery.TrialId, ignoreQueryFilters: true)
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SiteName), t => t.TrialSiteName.Contains(inQuery.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteAliasName), t => t.TrialSiteAliasName.Contains(inQuery.TrialSiteAliasName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteCode), t => t.TrialSiteCode.Contains(inQuery.TrialSiteCode))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.CRCUserList.Any(k => k.UserId == _userInfo.UserRoleId))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.UserKeyInfo), t => t.CRCUserList.Any(k => (k.UserRole.FullName).Contains(inQuery.UserKeyInfo)
|| k.UserRole.IdentityUser.UserName.Contains(inQuery.UserKeyInfo) || k.UserRole.IdentityUser.EMail.Contains(inQuery.UserKeyInfo)))
.ProjectTo<SiteStatDTO>(_mapper.ConfigurationProvider);
return await siteStatQuery.ToPagedListAsync(inQuery);
}
/// <summary>[new] setting页面Site列表,和getSiteCRCList对比 没有统计数据,增加了一些site信息 </summary>
[HttpPost]
public async Task<IResponseOutput<PageOutput<SiteStatSimpleDTO>>> GetSiteCRCSimpleList(SiteCrcQueryDTO inQuery)
{
var trialinfo = await _trialRepository.Where(x => x.Id == inQuery.TrialId).FirstNotNullAsync();
var siteStatQuery = _trialSiteRepository.Where(t => t.TrialId == inQuery.TrialId).IgnoreQueryFilters()
.WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SiteName), t => t.TrialSiteName.Contains(inQuery.SiteName) || t.TrialSiteAliasName.Contains(inQuery.TrialSiteAliasName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteAliasName), t => t.TrialSiteAliasName.Contains(inQuery.TrialSiteAliasName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteCode), t => t.TrialSiteCode.Contains(inQuery.TrialSiteCode))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.Country), t => t.Country.Contains(inQuery.Country))
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.CRCUserList.Any(k => k.UserId == _userInfo.UserRoleId))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.UserKeyInfo), t => t.CRCUserList.Any(k => (k.UserRole.FullName).Contains(inQuery.UserKeyInfo)
|| k.UserRole.IdentityUser.UserName.Contains(inQuery.UserKeyInfo) || k.UserRole.IdentityUser.EMail.Contains(inQuery.UserKeyInfo)))
.ProjectTo<SiteStatSimpleDTO>(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us });
var result = await siteStatQuery.ToPagedListAsync(inQuery);
return ResponseOutput.Ok(result, new
{
IsPACSConnectAndIsTrialPACSConfirmed = trialinfo.IsPACSConnect && trialinfo.IsTrialPACSConfirmed,
});
}
/// <summary>[new] Setting页面 Site勾选列表( </summary>
[HttpPost]
public async Task<PageOutput<TrialSiteScreeningDTO>> GetTrialSiteScreeningList(TrialSiteQuery inQuery)
{
// 之前选择了的不能再次出现在列表,做的时候我就不建议这样搞,搞好了 现在又要改回去。。。 瞎折腾。。。。
var siteQueryable = _siteRepository.AsQueryable(true)
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SiteName), t => t.SiteName.Contains(inQuery.SiteName) || t.SiteNameCN.Contains(inQuery.SiteName) || t.AliasName.Contains(inQuery.SiteName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.AliasName), t => t.AliasName.Contains(inQuery.AliasName))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.City), t => t.City.Contains(inQuery.City))
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.Country), t => t.Country.Contains(inQuery.Country))
.ProjectTo<TrialSiteScreeningDTO>(_mapper.ConfigurationProvider, new { trialId = inQuery.TrialId, isEn_Us = _userInfo.IsEn_Us });
return await siteQueryable.ToPagedListAsync(inQuery);
}
public async Task<List<TrialSiteSelect>> GetTrialSiteSelectList(string? siteName)
{
var list = _siteRepository
.WhereIf(!string.IsNullOrWhiteSpace(siteName), t => t.SiteName.Contains(siteName) || t.SiteNameCN.Contains(siteName) || t.AliasName.Contains(siteName))
.Select(t => new TrialSiteSelect() { SiteId = t.Id, SiteName = _userInfo.IsEn_Us ? t.SiteName : t.SiteNameCN, AliasName = t.AliasName, Country = t.Country }).ToList()
.OrderBy(x => x.SiteName)
.ToList();
return list;
}
/// <summary>Setting页面 Site批量添加</summary>
[HttpPost]
[UnitOfWork]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
[TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> AddTrialSites(List<TrialSiteCommand> trialSites)
{
var addArray = _mapper.Map<List<TrialSite>>(trialSites);
foreach (var item in addArray)
{
if (item.IsDeleted == false)
{
item.EnabledTime = DateTime.Now;
}
if (await _trialSiteRepository.AnyAsync(t => t.TrialSiteCode == item.TrialSiteCode && t.TrialId == item.TrialId))
{
//---Code is not allowed to be repeated
return ResponseOutput.NotOk(_localizer["TrialSite_CodeDuplicate"]);
}
}
await _trialSiteRepository.AddRangeAsync(addArray);
return ResponseOutput.Result(await _trialSiteRepository.SaveChangesAsync());
}
/// <summary>
/// 项目site 编辑接口 New 可以设置为启用不启用 不启用 不会验证Code 重复
/// </summary>
/// <param name="editTrialSiteCommand"></param>
/// <returns></returns>
[HttpPut]
//[Authorize(Policy = IRaCISPolicy.PM_APM)]
public async Task<IResponseOutput> EditTrialSite(EditTrialSiteCommand editTrialSiteCommand)
{
var dbEntity = await _trialSiteRepository.FirstOrDefaultAsync(t => t.Id == editTrialSiteCommand.Id, true);
if (dbEntity == null) return Null404NotFound(dbEntity);
var trialId = dbEntity.TrialId;
var trialSiteId = dbEntity.Id;
if (editTrialSiteCommand.IsDeleted)
{
if (await _trialSiteUserRoleRepository.AnyAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId))
{
//---The site has been associated with CRC, and couldn't be deleted.
return ResponseOutput.NotOk(_localizer["TrialSite_CannotDeleteAssociatedCRC"]);
}
if (await _subjectRepository.AnyAsync(t => t.TrialSiteId == trialSiteId && t.TrialId == trialId))
{
//---The subjects has been added to this site, and couldn't be disable.
return ResponseOutput.NotOk(_localizer["TrialSite_ParticipantJoined"]);
}
}
else
{
if (await _trialSiteRepository.AnyAsync(t => t.Id != editTrialSiteCommand.Id && t.TrialSiteCode == editTrialSiteCommand.TrialSiteCode && t.TrialId == editTrialSiteCommand.TrialId))
{
//---Code is not allowed to be repeated
return ResponseOutput.NotOk(_localizer["TrialSite_CodeDuplicate"]);
}
if (!string.IsNullOrEmpty(editTrialSiteCommand.TrialSiteCode) && await _trialRepository.AnyAsync(t => t.Id == trialId && t.VitrualSiteCode == editTrialSiteCommand.TrialSiteCode, true))
{
return ResponseOutput.NotOk(_localizer["TrialSite_CodeDuplicate2"]);
}
}
_mapper.Map(editTrialSiteCommand, dbEntity);
if (editTrialSiteCommand.IsDeleted)
{
dbEntity.EnabledTime = null;
}
else if (editTrialSiteCommand.IsDeleted == false && dbEntity.EnabledTime == null)
{
dbEntity.EnabledTime = DateTime.Now;
}
await _trialSiteRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 获取项目下的 site 下拉框数据 CRC只看到他负责的
/// </summary>
/// <param name="trialId"></param>
/// <param name="ignoreDisable"></param>
/// <returns></returns>
[HttpGet("{trialId:guid}")]
public async Task<IEnumerable<TrialSiteForSelect>> GetTrialSiteSelect(Guid trialId, bool? ignoreDisable)
{
//CRC只看到他负责的
var query = _trialSiteRepository.Where(t => t.TrialId == trialId);
if (ignoreDisable == true)
{
query = query.IgnoreQueryFilters();
}
var list = await query
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.CRCUserList.Any(t => t.UserId == _userInfo.UserRoleId))
.ProjectTo<TrialSiteForSelect>(_mapper.ConfigurationProvider).OrderBy(t => t.TrialSiteCode).ToListAsync();
return list;
}
public async Task<IEnumerable<string>> GetTrialSiteCodeSelect(Guid trialId, bool isIncludeVirtualSite = true)
{
//CRC只看到他负责的
var list = await _trialSiteRepository.Where(t => t.TrialId == trialId)
.WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.CRCUserList.Any(t => t.UserId == _userInfo.UserRoleId))
.Select(t => t.TrialSiteCode).ToListAsync();
var virtualList = await _visitTaskRepository.Where(t => t.IsSelfAnalysis == true && t.TrialId == trialId).Select(t => t.BlindTrialSiteCode).Distinct().ToListAsync();
return isIncludeVirtualSite ? list.Concat(virtualList) : list;
}
/// <summary>删除 项目 下某一site </summary>
[HttpDelete("{id:guid}/{trialId:guid}")]
[TrialGlobalLimit("AfterStopCannNotOpt")]
[Obsolete]
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 trialSiteId = relation.Id;
if (await _trialSiteUserRoleRepository.AnyAsync(t => t.TrialId == trialId && t.TrialSiteId == trialSiteId))
{
//---The site has been associated with CRC, and couldn't be deleted.
return ResponseOutput.NotOk(_localizer["TrialSite_CannotDeleteAssociatedCRC"]);
}
if (await _subjectRepository.AnyAsync(t => t.TrialSiteId == trialSiteId && t.TrialId == trialId))
{
//---The subjects has been added to this site, and couldn't be deleted.
return ResponseOutput.NotOk(_localizer["TrialSite_CannotDeleteAssociatedSubject"]);
}
await _trialSiteRepository.DeleteAsync(relation);
return ResponseOutput.Result(await _trialSiteUserRoleRepository.SaveChangesAsync());
}
}
}