Merge branch 'Test_IRC_Net8' of http://192.168.3.68:2000/XCKJ/irc-netcore-api into Test_IRC_Net8

IRC_NewDev
he 2024-03-05 14:49:55 +08:00
commit aac559e221
5 changed files with 183 additions and 15 deletions

View File

@ -24,7 +24,9 @@ namespace IRaCIS.Core.Application.ViewModel
public int? GeneratedSubjectCount { get; set; }
public int? MatchSubejctCount { get; set; }
public int? CanGeneratedSubejctCount => MatchSubejctCount - GeneratedSubjectCount;
}
@ -34,6 +36,13 @@ namespace IRaCIS.Core.Application.ViewModel
}
public class SubjectGeneratedTask
{
public Guid SubjectId { get; set; }
public bool IsHaveGeneratedTask { get; set; }
}
public class ConsistentQuery : PageInput
{
[NotDefault]
@ -46,6 +55,15 @@ namespace IRaCIS.Core.Application.ViewModel
}
public class GroupConsistentSimpleQuery
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
}
public class GroupConsistentQuery : PageInput
{
[NotDefault]
@ -56,13 +74,21 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid TrialReadingCriterionId { get; set; }
}
public class ConsistentConfirmGenerateCommand
public class SelfConsistentSimpleQuery
{
[NotDefault]
public Guid TaskConsistentRuleId { get; set; }
[NotDefault]
public Guid DoctorUserId { get; set; }
}
public class ConsistentConfirmGenerateCommand: SelfConsistentSimpleQuery
{
public List<Guid> SubejctIdList { get; set; }
public bool IsAutoAllocateGenerateTask { get; set; }
}
@ -70,7 +96,13 @@ namespace IRaCIS.Core.Application.ViewModel
{
[NotDefault]
public Guid TrialId { get; set; }
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
public List<Guid> SubejctIdList { get; set; }
public bool IsAutoAllocateGenerateTask { get; set; }
}
public class DoctorSelfConsistentSubjectView: ConsistentCommonView
@ -105,6 +137,8 @@ namespace IRaCIS.Core.Application.ViewModel
public List<VisitTaskGroupSimpleDTO> SubjectTaskVisitList => VisitTaskList.GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Select(g => g.First()).OrderBy(t=>t.VisitTaskNum).ToList();
public List<VisitTaskGroupSimpleDTO> VisitTaskList { get; set; } = new List<VisitTaskGroupSimpleDTO>();
public List<UserSimpleInfo> DoctorUserList { get; set; }=new List<UserSimpleInfo>();
}
public class VisitTaskGroupSimpleDTO

View File

@ -16,6 +16,9 @@ using System.Linq;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using Medallion.Threading;
using IRaCIS.Core.Infrastructure.Extention;
using System;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace IRaCIS.Core.Application.Service
{
@ -37,10 +40,11 @@ namespace IRaCIS.Core.Application.Service
private readonly IRepository<TrialVirtualSiteCodeUpdate> _trialVirtualSiteCodeUpdateRepository;
private readonly IVisitTaskHelpeService _visitTaskCommonService;
public TaskConsistentRuleService(IRepository<VisitTask> visitTaskRepository, IRepository<Enroll> enrollRepository, IRepository<TaskConsistentRule> taskConsistentRuleRepository, IRepository<SubjectUser> subjectUserRepository, IRepository<Subject> subjectRepository, IDistributedLockProvider distributedLockProvider,
IRepository<Trial> trialRepository, IRepository<TrialSite> trialSiteRepository, IRepository<TrialVirtualSiteCodeUpdate> trialVirtualSiteCodeUpdateRepository)
IRepository<Trial> trialRepository, IRepository<TrialSite> trialSiteRepository, IRepository<TrialVirtualSiteCodeUpdate> trialVirtualSiteCodeUpdateRepository, IVisitTaskHelpeService visitTaskCommonService)
{
_taskConsistentRuleRepository = taskConsistentRuleRepository;
_visitTaskRepository = visitTaskRepository;
@ -54,6 +58,8 @@ namespace IRaCIS.Core.Application.Service
_trialSiteRepository = trialSiteRepository;
_trialVirtualSiteCodeUpdateRepository = trialVirtualSiteCodeUpdateRepository;
_visitTaskCommonService = visitTaskCommonService;
}
/// <summary>
@ -136,13 +142,12 @@ namespace IRaCIS.Core.Application.Service
/// 确认生成自身一致性分析任务
/// </summary>
/// <param name="inCommand"></param>
/// <param name="_visitTaskCommonService"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
//[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ConfirmGenerateSelfConsistentTask(ConsistentConfirmGenerateCommand inCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
public async Task<IResponseOutput> ConfirmGenerateSelfConsistentTask(ConsistentConfirmGenerateCommand inCommand)
{
@ -150,6 +155,20 @@ namespace IRaCIS.Core.Application.Service
var doctorUserId = inCommand.DoctorUserId;
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
//随机分配
if (inCommand.IsAutoAllocateGenerateTask)
{
var subjectList = (await GetSelfConsistentRuleMatchSubjectIdListAsync(new SelfConsistentSimpleQuery() { TaskConsistentRuleId = inCommand.TaskConsistentRuleId, DoctorUserId = inCommand.DoctorUserId })).ToList();
if (subjectList.Any(t => t.IsHaveGeneratedTask))
{
//已手动分配,不允许自动分配
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]);
}
inCommand.SubejctIdList = GetRandomSubjectIdList(subjectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount);
}
var list = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, doctorUserId, inCommand.SubejctIdList).ToListAsync();
//var (group, query) = GetIQueryableDoctorSelfConsistentRuleSubjectView(filterObj, inCommand.SubejctIdList);
@ -284,20 +303,34 @@ namespace IRaCIS.Core.Application.Service
/// 确认生成组间一致性分析任务
/// </summary>
/// <param name="inCommand"></param>
/// <param name="_visitTaskCommonService"></param>
/// <returns></returns>
[HttpPost]
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ConfirmGenerateGroupConsistentTask(GroupConsistentConfirmGenrateCommand inCommand, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
public async Task<IResponseOutput> ConfirmGenerateGroupConsistentTask(GroupConsistentConfirmGenrateCommand inCommand)
{
var trialId = inCommand.TrialId;
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.IsSelfAnalysis == false);
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == trialId && t.TrialReadingCriterionId == inCommand.TrialReadingCriterionId && t.IsSelfAnalysis == false);
var trialReadingCriterionId = filterObj.TrialReadingCriterionId;
//随机分配
if (inCommand.IsAutoAllocateGenerateTask)
{
var subjectSelectList = (await GetGroupConsistentRuleMatchSubjectIdListAsync(new GroupConsistentSimpleQuery() { TrialId = inCommand.TrialId, TrialReadingCriterionId = inCommand.TrialReadingCriterionId })).ToList();
if (subjectSelectList.Any(t => t.IsHaveGeneratedTask))
{
//已手动分配过,不允许自动分配
throw new BusinessValidationFailedException(_localizer["TaskConsistent_NotAllowedGenerate"]);
}
inCommand.SubejctIdList = GetRandomSubjectIdList(subjectSelectList.Select(t => t.SubjectId).ToList(), filterObj.PlanSubjectCount);
}
var query = await GetGroupConsistentQueryAsync(filterObj, inCommand.SubejctIdList);
@ -578,7 +611,12 @@ namespace IRaCIS.Core.Application.Service
/// <summary>
/// 组间一致性分析 满足条件的subject 筛选
/// </summary>
/// <param name="filterObj"></param>
/// <param name="subejctIdList"></param>
/// <returns></returns>
private async Task<IQueryable<DoctorGroupConsistentSubjectView>> GetGroupConsistentQueryAsync(TaskConsistentRule filterObj, List<Guid>? subejctIdList = null)
{
@ -638,6 +676,13 @@ namespace IRaCIS.Core.Application.Service
IsHaveGeneratedTask = t.SubjectVisitTaskList.Any(c => c.IsSelfAnalysis == false && c.TrialReadingCriterionId == trialReadingCriterionId),
DoctorUserList = t.SubjectDoctorList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsConfirmed).Select(t => new UserSimpleInfo()
{
UserId = t.Id,
FullName = t.DoctorUser.FullName,
UserCode = t.DoctorUser.UserCode,
UserName = t.DoctorUser.UserName
}).ToList(),
ValidVisitCount = t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter).GroupBy(t => new { t.SubjectId, t.VisitTaskNum }).Where(g => g.Count() == 2).Count(),
@ -686,11 +731,21 @@ namespace IRaCIS.Core.Application.Service
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<TaskConsistentRuleView>> GetSelfConsistentDoctorStatList(TaskConsistentRuleQuery inQuery)
public async Task<IResponseOutput<List<TaskConsistentRuleView>>> GetSelfConsistentDoctorStatList(TaskConsistentRuleQuery inQuery)
{
var trialId = inQuery.TrialId;
var taskConsistentRuleQueryable = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId && t.EnrollStatus == EnrollStatus.ConfirmIntoGroup)
Expression<Func<VisitTask, bool>> comonTaskFilter = u => u.TrialId == trialId && u.IsAnalysisCreate == false && u.TaskState == TaskState.Effect && u.ReadingTaskState == ReadingTaskState.HaveSigned && (u.ReReadingApplyState == ReReadingApplyState.Default || u.ReReadingApplyState == ReReadingApplyState.Reject);
//&& u.TrialReadingCriterionId == trialReadingCriterionId &&u.SignTime!.Value.AddDays(filterObj.IntervalWeeks * 7) < DateTime.Now && u.DoctorUserId == doctorUserId;
Expression<Func<VisitTask, bool>> visitTaskFilter = comonTaskFilter.And(t => t.ReadingCategory == ReadingCategory.Visit);
var taskConsistentRuleQueryable = from enroll in _repository.Where<Enroll>(t => t.TrialId == trialId && t.EnrollStatus == EnrollStatus.ConfirmIntoGroup
&& t.EnrollReadingCriteriaList.Any(c => c.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && c.IsJoinAnalysis))
join user in _repository.Where<User>() on enroll.DoctorId equals user.DoctorId
join taskConsistentRule in _repository.Where<TaskConsistentRule>(t => t.TrialId == trialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis) on enroll.TrialId equals taskConsistentRule.TrialId
select new TaskConsistentRuleView()
@ -711,7 +766,26 @@ namespace IRaCIS.Core.Application.Service
IsHaveReadingPeriod = taskConsistentRule.IsHaveReadingPeriod,
PlanVisitCount = taskConsistentRule.PlanVisitCount,
GeneratedSubjectCount = taskConsistentRule.Trial.VisitTaskList.Where(t => t.IsAnalysisCreate && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == true && t.DoctorUserId == user.Id).Select(t => t.SubjectId).Distinct().Count(),
GeneratedSubjectCount = taskConsistentRule.TrialReadingCriterion.VisitTaskList.Where(t => t.IsAnalysisCreate && t.IsSelfAnalysis == true && t.DoctorUserId == user.Id).Select(t => t.SubjectId).Distinct().Count(),
//MatchSubejctCount = taskConsistentRule.Trial.SubjectList.Where(t => t.SubjectVisitTaskList.AsQueryable().Where(visitTaskFilter)
//.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.DoctorId)
//.Count() >= taskConsistentRule.PlanVisitCount)
//.WhereIf(taskConsistentRule.IsHaveReadingPeriod == true, u => u.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter)
//.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.DoctorId)
//.Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(taskConsistentRule.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global))
//.Count(),
MatchSubejctCount = taskConsistentRule.Trial.SubjectList.AsQueryable()
.Where(t => taskConsistentRule.IsHaveReadingPeriod == false ? t.SubjectVisitTaskList.AsQueryable()
.Where(visitTaskFilter).Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.DoctorId)
.Count() >= taskConsistentRule.PlanVisitCount :
t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter)
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SignTime!.Value.AddDays(taskConsistentRule.IntervalWeeks * 7) < DateTime.Now && t.DoctorUserId == user.DoctorId)
.Where(t => t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global).OrderBy(t => t.VisitTaskNum).Take(taskConsistentRule.PlanVisitCount + 1).Any(t => t.ReadingCategory == ReadingCategory.Global))
.Count(),
AnalysisDoctorUser = new UserSimpleInfo()
{
@ -738,7 +812,10 @@ namespace IRaCIS.Core.Application.Service
//var taskConsistentRuleQueryable = _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId)
// .ProjectTo<TaskConsistentRuleView>(_mapper.ConfigurationProvider);
return await taskConsistentRuleQueryable.ToListAsync();
var list= await taskConsistentRuleQueryable.ToListAsync();
var rule= await _taskConsistentRuleRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsSelfAnalysis == inQuery.IsSelfAnalysis && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).ProjectTo<TaskConsistentRuleBasic>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
return ResponseOutput.Ok(list, rule);
}
[HttpPost]
@ -831,8 +908,65 @@ namespace IRaCIS.Core.Application.Service
}
/// <summary>
/// 获取自身一致性分析 符合条件的subject 数组
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
public async Task<List<SubjectGeneratedTask>> GetSelfConsistentRuleMatchSubjectIdListAsync(SelfConsistentSimpleQuery inQuery)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.Id == inQuery.TaskConsistentRuleId);
var subjectList = await GetIQueryableDoctorSelfConsistentSubjectView(filterObj, inQuery.DoctorUserId).Select(t => new SubjectGeneratedTask() { SubjectId = t.SubjectId, IsHaveGeneratedTask = t.IsHaveGeneratedTask }).ToListAsync();
return subjectList;
}
/// <summary>
/// 获取组件一致性分析符合条件的subject 数组
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
public async Task<List<SubjectGeneratedTask>> GetGroupConsistentRuleMatchSubjectIdListAsync(GroupConsistentSimpleQuery inQuery)
{
var filterObj = await _taskConsistentRuleRepository.FirstOrDefaultAsync(t => t.TrialId == inQuery.TrialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsSelfAnalysis == false);
var subjectList = await (await GetGroupConsistentQueryAsync(filterObj)).Select(t => new SubjectGeneratedTask() { SubjectId = t.SubjectId, IsHaveGeneratedTask = t.IsHaveGeneratedTask }).ToListAsync();
return subjectList;
}
/// <summary>
/// 随机算法,选择指定数量的 subject
/// </summary>
/// <param name="matchSubjectIdList"></param>
/// <param name="countToSelect"></param>
/// <returns></returns>
public List<Guid> GetRandomSubjectIdList(List<Guid> matchSubjectIdList, int countToSelect)
{
// 使用 Fisher-Yates 随机置换算法来选择指定数量的 GUID
Random random = new Random();
for (int i = 0; i < countToSelect; i++)
{
// 生成一个随机索引
int randomIndex = random.Next(i, matchSubjectIdList.Count);
// 将选中的元素与当前元素交换位置
Guid temp = matchSubjectIdList[randomIndex];
matchSubjectIdList[randomIndex] = matchSubjectIdList[i];
matchSubjectIdList[i] = temp;
}
return matchSubjectIdList.Take(countToSelect).ToList();
// 使用洗牌算法来随机选择指定数量的GUID
//Random random = new Random();
//return matchSubjectIdList.OrderBy(g => random.Next()).Take(countToSelect).ToList();
}
}
}

View File

@ -440,7 +440,7 @@ namespace IRaCIS.Core.Application.Contracts
#endregion
public int? TotoalCount => TrialWaitSignDocCount + SysWaitSignDocCount
public int? TotalCount => TrialWaitSignDocCount + SysWaitSignDocCount
+ PM_SiteSurveryCount + PM_CheckCount + PM_ReviewerSelectCount + PM_ReReadingApprovalCount + PM_ClinicalDataCount
+ CRC_ImageSubmitCount + CRC_ImageQuestionCount + CRC_CheckQuestionCount + CRC_ImageReUploadCount + CRC_ClinicalDataTobeDoneCount + CRC_ClinialDataTobeConfirmCount
+ SPM_SiteSurveryCount + SPM_ReviewerApprovalCount + SPM_ReReadingApprovalCount

View File

@ -715,7 +715,7 @@ namespace IRaCIS.Core.Application
.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id))
.Where(u => u.SubmitState == SubmitStateEnum.ToSubmit).Count(),
}).Where(x => x.ToBeDealedCount > 0); ;
}).Where(x => x.ToBeDealedCount > 0);

View File

@ -359,7 +359,7 @@ namespace IRaCIS.Core.Domain.Models
public int IndicationEnum { get; set; } = -1;
public string VitrualSiteCode { get; set; }
public string VitrualSiteCode { get; set; }=string.Empty;
#region 邮件配置
/// <summary>