Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing

This commit is contained in:
he
2025-06-19 14:16:54 +08:00
19 changed files with 20195 additions and 284 deletions
@@ -603,11 +603,10 @@
<param name="addOrEditBasic"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.DictionaryService.GetChildList(System.Guid)">
<member name="M:IRaCIS.Core.Application.Service.DictionaryService.GetChildList(IRaCIS.Application.Contracts.ChildInQuery)">
<summary>
获取子项数组
</summary>
<param name="parentId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.DictionaryService.DeleteDictionary(System.Guid)">
@@ -35,7 +35,7 @@ namespace IRaCIS.Core.Application.Service
IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository,
IRepository<ClinicalDataTrialSet> _trialClinicalDataSetRepository,
IRepository<ReadingClinicalData> _readingClinicalDataRepository,
IRepository<ReadingConsistentClinicalData> _readingConsistentClinicalDataRepository,
IRepository<ReadingConsistentClinicalData> _readingConsistentClinicalDataRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment, IFusionCache _fusionCache) : BaseService, IVisitTaskHelpeService
{
@@ -47,16 +47,16 @@ namespace IRaCIS.Core.Application.Service
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<FileResult> ExportTemplateAsync(ExportTemplateAsyncDto inDto)
public async Task<FileResult> ExportTemplateAsync(ExportTemplateAsyncDto inDto)
{
return await ExcelExportHelper.ExportTemplateAsync(new ExportTemplateServiceDto()
{
Data=inDto.Data,
commonDocumentRepository= _commonDocumentRepository,
TemplateCode=inDto.TemplateCode,
ExportFileName=inDto.ExportFileName,
hostEnvironment=_hostEnvironment,
IsEnglish=_userInfo.IsEn_Us,
Data = inDto.Data,
commonDocumentRepository = _commonDocumentRepository,
TemplateCode = inDto.TemplateCode,
ExportFileName = inDto.ExportFileName,
hostEnvironment = _hostEnvironment,
IsEnglish = _userInfo.IsEn_Us,
});
}
@@ -757,248 +757,30 @@ namespace IRaCIS.Core.Application.Service
if (trialReadingCriterionConfig.TaskAllocateObjEnum == TaskAllocateObj.Subject)
{
var allocateSubjectArmList = _visitTaskRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm)
.Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList();
//当前任务没有分配医生,初次分配 不处理 只生成任务,后续根据生成的任务 再进行分配
if (allocateSubjectArmList.Count == 0)
{
}
else
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
{
//并且配置了医生
if (assignConfigList.Count > 0 && trialReadingCriterionConfig.IsFollowVisitAutoAssign)
#region 访
//配置了医生
if (assignConfigList.Count > 0)
{
//之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的)
#region 访 (PM 退 PM )
var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
if (trialReadingCriterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
//之前有回退的,那么当前访视任务生成但是不分配
if (beforeBackVisitTask != null)
{
//之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的)
var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
//之前有回退的,那么当前访视任务生成但是不分配
if (beforeBackVisitTask != null)
{
//不用进行额外处理
//访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配
}
else
{
#region 访
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
{
task1.TaskAllocationState = defaultState;
//分配给对应Arm的人
task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1)!.DoctorUserId;
task1.AllocateTime = DateTime.Now;
task1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null)
{
task2.TaskAllocationState = defaultState;
task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2)!.DoctorUserId;
task2.AllocateTime = DateTime.Now;
task2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
#endregion
}
//后续最近的未一致性核查通过的访视任务
var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
//大于当前访视 同时小于最近的未一致性核查通过的访视任务分配 或者生成
//存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务
var followVisitTaskList = await _visitTaskRepository
.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true)
.WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask!.VisitTaskNum)
.ToListAsync();
var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum);
//每个访视去判断 是分配还是生成(因为影响哪里有些是取消分配,有些是重阅重置需要重新生成)
foreach (var visitGroup in followVisitGroup)
{
var visit = await _subjectVisitRepository.Where(x => x.Id == visitGroup.First().SourceSubjectVisitId).Select(x => new
{
x.PDState,
x.IsEnrollmentConfirm,
x.IsUrgent,
}).FirstNotNullAsync();
TaskUrgentType? urgentType = null;
if (subjectVisitInfo.PDState == PDStateEnum.PDProgress)
{
urgentType = TaskUrgentType.PDProgress;
}
else if (subjectVisitInfo.IsEnrollmentConfirm)
{
urgentType = TaskUrgentType.EnrollmentConfirm;
}
else if (subjectVisitInfo.IsUrgent)
{
urgentType = TaskUrgentType.VisitUrgent;
}
bool isCanEdit = urgentType == TaskUrgentType.EnrollmentConfirm || urgentType == TaskUrgentType.PDProgress ? false : true;
//如果后续访视已分配有效 就不用处理
if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm1))
{
//不做处理
}
else
{
var arm1 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm1);
if (arm1 != null)
{
//有可能仅仅只分配了一个Subject 未分配 那么
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
{
arm1.IsUrgent = visit.IsUrgent;
arm1.TaskUrgentType = urgentType;
arm1.IsCanEditUrgentState = isCanEdit;
arm1.TaskAllocationState = TaskAllocationState.Allocated;
arm1.AllocateTime = DateTime.Now;
arm1.DoctorUserId = task1.DoctorUserId;
arm1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
else
{
var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm1).OrderByDescending(t => t.CreateTime).First();
var taskOne = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = visit.IsUrgent,
TaskUrgentType = urgentType,
IsCanEditUrgentState = isCanEdit,
ArmEnum = Arm.DoubleReadingArm1,//特殊
Code = currentMaxCodeInt + 1,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit,
SourceSubjectVisitId = latestTask.SourceSubjectVisitId,
VisitTaskNum = latestTask.VisitTaskNum,
TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum),
TaskName = latestTask.TaskName,
BlindSubjectCode = latestTask.BlindSubjectCode,
BlindTrialSiteCode = latestTask.BlindTrialSiteCode,
IsAnalysisCreate = latestTask.IsAnalysisCreate,
IsSelfAnalysis = latestTask.IsSelfAnalysis,
TaskAllocationState = TaskAllocationState.Allocated,
AllocateTime = DateTime.Now,
DoctorUserId = task1!.DoctorUserId,
SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget),
TrialReadingCriterionId = latestTask.TrialReadingCriterionId,
IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign,
IsClinicalDataSign = latestTask.IsClinicalDataSign
});
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
//如果后续访视已分配有效 就不用处理
if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm2))
{
//不做处理
}
else
{
var arm2 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm2);
if (arm2 != null)
{
//有可能仅仅只分配了一个Subject
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null)
{
arm2.IsUrgent = visit.IsUrgent;
arm2.TaskUrgentType = urgentType;
arm2.IsCanEditUrgentState = isCanEdit;
arm2.TaskAllocationState = TaskAllocationState.Allocated;
arm2.AllocateTime = DateTime.Now;
arm2.DoctorUserId = task2.DoctorUserId;
arm2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
else
{
var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm2).OrderByDescending(t => t.CreateTime).First();
var taskTwo = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = visit.IsUrgent,
TaskUrgentType = urgentType,
IsCanEditUrgentState = isCanEdit,
//CheckPassedTime = subjectVisit.CheckPassedTime,
ArmEnum = Arm.DoubleReadingArm2,//特殊
Code = currentMaxCodeInt + 1,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit,
SourceSubjectVisitId = latestTask.SourceSubjectVisitId,
VisitTaskNum = latestTask.VisitTaskNum,
TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum),
TaskName = latestTask.TaskName,
BlindSubjectCode = latestTask.BlindSubjectCode,
BlindTrialSiteCode = latestTask.BlindTrialSiteCode,
IsAnalysisCreate = latestTask.IsAnalysisCreate,
IsSelfAnalysis = latestTask.IsSelfAnalysis,
TaskAllocationState = TaskAllocationState.Allocated,
AllocateTime = DateTime.Now,
DoctorUserId = task2!.DoctorUserId,
SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget),
TrialReadingCriterionId = latestTask.TrialReadingCriterionId,
IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign,
IsClinicalDataSign = latestTask.IsClinicalDataSign
});
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
}
//不用进行额外处理
//访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配
}
//无序的时候 生成任务并分配出去
else
{
#region 访
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
@@ -1019,21 +801,237 @@ namespace IRaCIS.Core.Application.Service
task2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
#endregion
}
#endregion
}
else
//后续访视不自动分配,或者配置的医生数量不足,就不进行分配
#endregion
#region 访
//后续最近的未一致性核查通过的访视任务
var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync();
//大于当前访视 同时小于最近的未一致性核查通过的访视任务分配 或者生成
//存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务
var followVisitTaskList = await _visitTaskRepository
.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true)
.WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask!.VisitTaskNum)
.ToListAsync();
var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum);
//每个访视去判断 是分配还是生成(因为影响哪里有些是取消分配,有些是重阅重置需要重新生成)
foreach (var visitGroup in followVisitGroup)
{
var visit = await _subjectVisitRepository.Where(x => x.Id == visitGroup.First().SourceSubjectVisitId).Select(x => new
{
x.PDState,
x.IsEnrollmentConfirm,
x.IsUrgent,
}).FirstNotNullAsync();
TaskUrgentType? urgentType = null;
if (subjectVisitInfo.PDState == PDStateEnum.PDProgress)
{
urgentType = TaskUrgentType.PDProgress;
}
else if (subjectVisitInfo.IsEnrollmentConfirm)
{
urgentType = TaskUrgentType.EnrollmentConfirm;
}
else if (subjectVisitInfo.IsUrgent)
{
urgentType = TaskUrgentType.VisitUrgent;
}
bool isCanEdit = urgentType == TaskUrgentType.EnrollmentConfirm || urgentType == TaskUrgentType.PDProgress ? false : true;
//如果后续访视已分配有效 就不用处理
if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm1))
{
//不做处理
}
else
{
var arm1 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm1);
if (arm1 != null)
{
arm1.IsUrgent = visit.IsUrgent;
arm1.TaskUrgentType = urgentType;
arm1.IsCanEditUrgentState = isCanEdit;
//有可能仅仅只分配了一个Subject 未分配 那么
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
{
arm1.TaskAllocationState = TaskAllocationState.Allocated;
arm1.AllocateTime = DateTime.Now;
arm1.DoctorUserId = task1.DoctorUserId;
arm1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
else
{
var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm1).OrderByDescending(t => t.CreateTime).First();
var taskOne = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = visit.IsUrgent,
TaskUrgentType = urgentType,
IsCanEditUrgentState = isCanEdit,
ArmEnum = Arm.DoubleReadingArm1,//特殊
Code = currentMaxCodeInt + 1,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit,
SourceSubjectVisitId = latestTask.SourceSubjectVisitId,
VisitTaskNum = latestTask.VisitTaskNum,
TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum),
TaskName = latestTask.TaskName,
BlindSubjectCode = latestTask.BlindSubjectCode,
BlindTrialSiteCode = latestTask.BlindTrialSiteCode,
IsAnalysisCreate = latestTask.IsAnalysisCreate,
IsSelfAnalysis = latestTask.IsSelfAnalysis,
TrialReadingCriterionId = latestTask.TrialReadingCriterionId,
IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign,
IsClinicalDataSign = latestTask.IsClinicalDataSign
});
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
{
taskOne.TaskAllocationState = TaskAllocationState.Allocated;
taskOne.AllocateTime = DateTime.Now;
taskOne. DoctorUserId = task1!.DoctorUserId;
taskOne. SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
//如果后续访视已分配有效 就不用处理
if (visitGroup.Any(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.ArmEnum == Arm.DoubleReadingArm2))
{
//不做处理
}
else
{
var arm2 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm2);
if (arm2 != null)
{
arm2.IsUrgent = visit.IsUrgent;
arm2.TaskUrgentType = urgentType;
arm2.IsCanEditUrgentState = isCanEdit;
//有可能仅仅只分配了一个Subject
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null)
{
arm2.TaskAllocationState = TaskAllocationState.Allocated;
arm2.AllocateTime = DateTime.Now;
arm2.DoctorUserId = task2.DoctorUserId;
arm2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
else
{
var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm2).OrderByDescending(t => t.CreateTime).First();
var taskTwo = await _visitTaskRepository.AddAsync(new VisitTask()
{
TrialId = trialId,
SubjectId = subjectVisit.SubjectId,
IsUrgent = visit.IsUrgent,
TaskUrgentType = urgentType,
IsCanEditUrgentState = isCanEdit,
//CheckPassedTime = subjectVisit.CheckPassedTime,
ArmEnum = Arm.DoubleReadingArm2,//特殊
Code = currentMaxCodeInt + 1,
TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)),
ReadingCategory = ReadingCategory.Visit,
SourceSubjectVisitId = latestTask.SourceSubjectVisitId,
VisitTaskNum = latestTask.VisitTaskNum,
TaskBlindName = visitBlindConfig.BlindFollowUpPrefix + " " + visitNumList.IndexOf(latestTask.VisitTaskNum),
TaskName = latestTask.TaskName,
BlindSubjectCode = latestTask.BlindSubjectCode,
BlindTrialSiteCode = latestTask.BlindTrialSiteCode,
IsAnalysisCreate = latestTask.IsAnalysisCreate,
IsSelfAnalysis = latestTask.IsSelfAnalysis,
TrialReadingCriterionId = latestTask.TrialReadingCriterionId,
IsNeedClinicalDataSign = latestTask.IsNeedClinicalDataSign,
IsClinicalDataSign = latestTask.IsClinicalDataSign
});
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null)
{
taskTwo.TaskAllocationState = TaskAllocationState.Allocated;
taskTwo.AllocateTime = DateTime.Now;
taskTwo.DoctorUserId = task2!.DoctorUserId;
taskTwo.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
currentMaxCodeInt = currentMaxCodeInt + 1;
_fusionCache.Set<int>(CacheKeys.TrialStudyMaxCode(trialId), currentMaxCodeInt, TimeSpan.FromMinutes(30));
}
}
}
}
#endregion
}
else
{
//无序的时候 生成任务并分配出去
if (assignConfigList.Count > 0 && trialReadingCriterionConfig.IsFollowVisitAutoAssign)
{
var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated;
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && task1 != null)
{
task1.TaskAllocationState = defaultState;
//分配给对应Arm的人
task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1)!.DoctorUserId;
task1.AllocateTime = DateTime.Now;
task1.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2) && task2 != null)
{
task2.TaskAllocationState = defaultState;
task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2)!.DoctorUserId;
task2.AllocateTime = DateTime.Now;
task2.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);
}
}
}
}
@@ -39,6 +39,10 @@ namespace IRaCIS.Application.Contracts
public string ValueCN { get; set; } = string.Empty;
}
public class ChildInQuery:SortInput
{
public Guid ParentId { get; set; }
}
public class AddOrEditBasicDic
{
@@ -96,9 +96,6 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsDeleted { get; set; }
public CriterionType? CriterionTypeEnum { get; set; }
/// <summary> 业务模块 /// </summary>
public int BusinessModuleEnum { get; set; }
@@ -140,6 +137,13 @@ namespace IRaCIS.Core.Application.Contracts
public int? EmailDelaySeconds { get; set; }
[Comment("邮件配置的多个标准")]
public List<CriterionType>? CriterionTypeList { get; set; }
//public CriterionType? CriterionTypeEnum { get; set; }
}
@@ -182,13 +182,12 @@ namespace IRaCIS.Core.Application.Service
/// <summary>
/// 获取子项数组
/// </summary>
/// <param name="parentId"></param>
/// <returns></returns>
[HttpGet("{parentId:guid}")]
public async Task<List<BasicDicView>> GetChildList(Guid parentId)
[HttpPost]
public async Task<List<BasicDicView>> GetChildList(ChildInQuery inQuery)
{
return await _dicRepository.Where(t => t.ParentId == parentId)
.OrderBy(t => t.ShowOrder).ProjectTo<BasicDicView>(_mapper.ConfigurationProvider).ToListAsync();
return await _dicRepository.Where(t => t.ParentId == inQuery.ParentId)
.ProjectTo<BasicDicView>(_mapper.ConfigurationProvider).SortToListAsync(inQuery);
}
@@ -28,7 +28,7 @@ namespace IRaCIS.Core.Application.Contracts
.WhereIf(inQuery.SystemLevel != null, t => t.SystemLevel == inQuery.SystemLevel)
.WhereIf(inQuery.IsDistinguishCriteria != null, t => t.IsDistinguishCriteria == inQuery.IsDistinguishCriteria)
.WhereIf(inQuery.BusinessLevelEnum != null, t => t.BusinessLevelEnum == inQuery.BusinessLevelEnum)
.WhereIf(inQuery.CriterionTypeEnum != null, t => t.CriterionTypeEnum == inQuery.CriterionTypeEnum)
.WhereIf(inQuery.CriterionTypeEnum != null, t => t.CriterionTypeList.Any(t=>t==inQuery.CriterionTypeEnum))
.WhereIf(inQuery.BusinessModuleEnum != null, t => t.BusinessModuleEnum == inQuery.BusinessModuleEnum)
.WhereIf(inQuery.BusinessScenarioEnum != null, t => t.BusinessScenarioEnum == inQuery.BusinessScenarioEnum)
.WhereIf(inQuery.IsReturnRequired != null, t => t.IsReturnRequired == inQuery.IsReturnRequired)
@@ -82,13 +82,36 @@ namespace IRaCIS.Core.Application.Contracts
public async Task<IResponseOutput> AddOrUpdateEmailNoticeConfig(EmailNoticeConfigAddOrEdit addOrEditEmailNoticeConfig)
{
var verifyExp1 = new EntityVerifyExp<EmailNoticeConfig>()
//var verifyExp1 = new EntityVerifyExp<EmailNoticeConfig>()
//{
// VerifyExp = t => t.BusinessScenarioEnum == addOrEditEmailNoticeConfig.BusinessScenarioEnum && t.CriterionTypeEnum == addOrEditEmailNoticeConfig.CriterionTypeEnum,
// VerifyMsg = _localizer["EmailNoticeConfig_RepeatEmailScenario"]
//};
var criterionList = _emailNoticeConfigrepository.Where(t => t.BusinessScenarioEnum == addOrEditEmailNoticeConfig.BusinessScenarioEnum && t.IsEnable == true)
.Where(t => t.CriterionTypeList != null)
.WhereIf(addOrEditEmailNoticeConfig.Id != null, t => t.Id != addOrEditEmailNoticeConfig.Id)
.Select(t => t.CriterionTypeList).ToList();//不能使用selectMany 会当成关联对象,不能当成字符串
if (addOrEditEmailNoticeConfig.CriterionTypeList != null)
{
VerifyExp = t => t.BusinessScenarioEnum == addOrEditEmailNoticeConfig.BusinessScenarioEnum && t.CriterionTypeEnum == addOrEditEmailNoticeConfig.CriterionTypeEnum,
foreach (var item in addOrEditEmailNoticeConfig.CriterionTypeList)
{
foreach (var itemList in criterionList)
{
if (itemList.Any(t => t == item))
{
return ResponseOutput.NotOk(_localizer["EmailNoticeConfig_RepeatEmailScenario"]);
}
}
}
}
VerifyMsg = _localizer["EmailNoticeConfig_RepeatEmailScenario"]
};
var verifyExp2 = new EntityVerifyExp<EmailNoticeConfig>()
{
@@ -132,7 +155,7 @@ namespace IRaCIS.Core.Application.Contracts
}
await _emailNoticeConfigrepository.AddAsync(entity, true, verifyExp1, verifyExp2);
await _emailNoticeConfigrepository.AddAsync(entity, true, verifyExp2);
}
@@ -155,7 +178,7 @@ namespace IRaCIS.Core.Application.Contracts
}
entity = await _emailNoticeConfigrepository.UpdateFromDTOAsync(addOrEditEmailNoticeConfig, true, false, verifyExp1, verifyExp2);
entity = await _emailNoticeConfigrepository.UpdateFromDTOAsync(addOrEditEmailNoticeConfig, true, false, verifyExp2);
@@ -409,7 +409,7 @@ namespace IRaCIS.Core.Application.Service.Common
var systemDocQuery =
from sysDoc in _systemDocumentRepository.AsQueryable(false)
.Where(t => inQuery.UserTypeId != null ? t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId) : true)
from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.Status == UserStateEnum.Enable && t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
.Where(t => inQuery.UserId != null ? t.Id == inQuery.UserId : true)
.Where(t => inQuery.UserTypeId != null ? t.UserRoleList.Any(t => t.UserTypeId == inQuery.UserTypeId && t.IsUserRoleDisabled == false) : true)
join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = identityUser.Id, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
@@ -146,9 +146,6 @@ namespace IRaCIS.Core.Application.ViewModel
public Guid TrialId { get; set; }
public CriterionType? CriterionTypeEnum { get; set; }
public List<UserTypeEnum> ToUserTypeList { get; set; }
public List<UserTypeEnum> CopyUserTypeList { get; set; }
@@ -197,6 +194,9 @@ namespace IRaCIS.Core.Application.ViewModel
public int? EmailDelaySeconds { get; set; }
[Comment("邮件配置的多个标准")]
public List<CriterionType>? CriterionTypeList { get; set; }
}
@@ -912,7 +912,7 @@ namespace IRaCIS.Core.Application.Services
var systemDocQuery =
from sysDoc in _systemDocumentRepository.AsQueryable(false)
.Where(t => inQuery.UserTypeId != null ? t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId) : true)
from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
from identityUser in _identityUserRepository.AsQueryable(false).Where(t =>t.Status== UserStateEnum.Enable && t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
.Where(t => inQuery.UserId != null ? t.Id == inQuery.UserId : true)
.Where(t => inQuery.UserTypeId != null ? t.UserRoleList.Any(t => t.UserTypeId == inQuery.UserTypeId && t.IsUserRoleDisabled == false) : true)
join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = identityUser.Id, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
@@ -602,7 +602,7 @@ namespace IRaCIS.Core.Application.Contracts
? $"{TotalImageSize.Value / 1024d / 1024d:F3} MB"
: "0.000 MB";
public string ImageTypeStr => $"{(IsHaveDicom ? "DICOM," : "")}{(IsHaveNoneDicom ? "Non-DICOM" : "")}";
public string ImageTypeStr => $"{(IsHaveDicom ? "DICOM" : "")}{(IsHaveNoneDicom&&IsHaveDicom?" , ":"")}{(IsHaveNoneDicom ? "Non-DICOM" : "")}";
public bool IsHaveDicom { get; set; }
@@ -13,6 +13,7 @@ using MassTransit.Initializers;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using System.Data;
using System.IO.Compression;
using System.Text;
@@ -901,8 +902,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
var query = _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
&& t.SourceSubjectVisitId != null && t.DoctorUserId == doctorUserId && t.TaskState == TaskState.Effect)
//满足 有序,或者随机只看到当前任务的dicom 非dicom检查
&& t.SourceSubjectVisitId != null && t.DoctorUserId == doctorUserId)
//满足 有序,或者随机只看到当前任务的dicom 非dicom检查
.WhereIf(inQuery.VisitTaskId == null, t => t.TaskState == TaskState.Effect)//从待阅列表进入,要筛选出有效的,任务可能重阅了,也要看到该任务的的
.WhereIf(criterionInfo.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
.ProjectTo<SubjectCRCImageUploadedDto>(_mapper.ConfigurationProvider);
@@ -1258,7 +1260,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
if (inCommand.IsKeyImage)
{
var downloadInfo = _visitTaskRepository.Where(t => t.TrialId == inCommand.TrialId && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false)
var downloadInfo = _visitTaskRepository.Where(t => t.TrialId == inCommand.TrialId && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.IsAnalysisCreate == false)
.Where(t => inCommand.SubjectVisitIdList.Contains((Guid)t.SourceSubjectVisitId))
.Select(t => new
{
@@ -1269,11 +1271,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
SubjectCode = t.Subject.Code,
VisitName = (string?)t.SourceSubjectVisit.VisitName,
ArmEnum= t.ArmEnum,
ArmEnum = t.ArmEnum,
QuestionMarkPictureList = t.ReadingTaskQuestionMarkList.Select(c => new { c.PicturePath, c.OtherPicturePath }).ToList(),
QuestionMarkPictureList = t.ReadingTaskQuestionMarkList.Select(c => new { c.PicturePath, c.OtherPicturePath }).ToList(),
TableQuestionRowPictureList = t.LesionList.Select(c => new { c.PicturePath, c.OtherPicturePath }).ToList(),
TableQuestionRowPictureList = t.LesionList.Select(c => new { c.PicturePath, c.OtherPicturePath }).ToList(),
IsJudgeSelect = t.JudgeResultTaskId == t.Id
@@ -3135,7 +3135,7 @@ namespace IRaCIS.Core.Application.Service
Random random = new Random();
var skipcount = 0;
var minRandomOrder = query.Where(t => t.RandomOrder != null).Select(t => t.RandomOrder).MinOrDefault();
//以随机序号优先,阅片中优先先给IR
@@ -3189,6 +3189,14 @@ namespace IRaCIS.Core.Application.Service
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
else
{
//触发任务随机编号
await _downloadAndUploadService.SubejctRandomReadingTaskNameDeal(task.SubjectId, task.TrialReadingCriterionId);
task.TaskBlindName = await _visitTaskRepository.Where(t => t.Id == task.VisitTaskId).Select(t => t.TaskBlindName).FirstOrDefaultAsync() ?? "";
}
if (task.SubjectCode.IsNullOrEmpty())
{