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

Uat_IRC_Net10
hang 2026-08-18 17:03:02 +08:00
commit 40a98048bb
7 changed files with 216 additions and 11 deletions

View File

@ -2500,6 +2500,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public Guid ReadingQuestionId { get; set; }
public string QuestionName { get; set; } = string.Empty;
public string Type { get; set; } = string.Empty;
public ShowQuestion ShowQuestion { get; set; }
public string TypeValue { get; set; } = string.Empty;
public int ShowOrder { get; set; }
public string Answer { get; set; } = string.Empty;
@ -2508,6 +2510,13 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public ValueUnit? Unit { get; set; }
public string? CustomUnit { get; set; }
public ValueOfType? ValueType { get; set; }
public string ClassifyAlgorithms { get; set; }
public ClassifyType? ClassifyType { get; set; }
public Guid? ClassifyQuestionId { get; set; }
public JudgeReadingQuestionType QuestionType { get; set; } = JudgeReadingQuestionType.Question;
}

View File

@ -29,6 +29,22 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<TrialQuestionVisitJudgeRuleItemDto> QuestionList { get; set; } = new List<TrialQuestionVisitJudgeRuleItemDto>();
}
public class CopyTrialQuestionVisitJudgeRuleInDto
{
[NotDefault]
public Guid TrialReadingCriterionId { get; set; }
/// <summary>
/// 来源访视
/// </summary>
public decimal SourceVisitNum { get; set; }
/// <summary>
/// 目标访视
/// </summary>
public decimal TargetVisitNum { get; set; }
}
public class TrialQuestionVisitJudgeRuleItemDto
{
public Guid ReadingQuestionTrialId { get; set; }

View File

@ -386,6 +386,36 @@ namespace IRaCIS.Core.Application.Service.RC
[HttpPost]
public async Task<IResponseOutput> SetTrialJudgeRuleInfo(SetTrialJudgeRuleInfoInDto inDto)
{
if (inDto.JudgeRuleEnum == JudgeRule.Consistent)
{
if (await _readingQuestionTrialRepository.AnyAsync(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId&& x.IsJudgeQuestion && x.LimitShow != LimitShow.AllShow))
{
var questionList = await _readingQuestionTrialRepository
.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion && x.LimitShow != LimitShow.AllShow)
.OrderBy(x => x.ShowOrder)
.Select(x => new TrialQuestionVisitJudgeRuleItemDto
{
ReadingQuestionTrialId = x.Id,
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
ShowOrder = x.ShowOrder,
Type = x.Type,
TypeValue = x.TypeValue,
QuestionGenre = x.QuestionGenre,
DictionaryCode = x.DictionaryCode,
Unit = x.Unit,
CustomUnit = x.CustomUnit,
})
.ToListAsync();
var questionName=string.Join(",", questionList.Select(x => x.QuestionName));
//---当前标准裁判规则为一致性,但存在非全部显示的裁判问题,操作失败
throw new BusinessValidationFailedException(_localizer["JudgeCanNotLimitShow", questionName]);
}
}
await _readingQuestionCriterionTrialRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.TrialReadingCriterionId, x => new ReadingQuestionCriterionTrial()
{
JudgeModeEnum = inDto.JudgeModeEnum,

View File

@ -36,12 +36,16 @@ namespace IRaCIS.Core.Application.Service
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswer,
IRepository<PreviousPDF> _previousPDFRepository,
IRepository<ReadingQuestionVisitJudgeRule> _readingQuestionVisitJudgeRuleRepository,
IRepository<VisitStage> _visitStageRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IReadingQuestionService
{
#region 项目访视裁判规则
/// <summary>
/// 获取项目阅片标准各访视的裁判规则配置。
/// 未配置规则的访视问题也会返回,供前端直接进行配置。
@ -50,8 +54,11 @@ namespace IRaCIS.Core.Application.Service
public async Task<List<TrialQuestionVisitJudgeRuleItemDto>> GetTrialQuestionVisitJudgeRule(GetTrialQuestionVisitJudgeRuleInDto inDto)
{
var questionList = await _readingQuestionTrialRepository
.Where(x=>!x.ExcludeShowVisitList.Contains(inDto.VisitNum))
.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion)
.Where(x => x.LimitShow == LimitShow.AllShow
|| (x.LimitShow == LimitShow.BaseLineShow && inDto.VisitNum == 0)
|| (x.LimitShow == LimitShow.FollowShow && inDto.VisitNum != 0)
|| (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(inDto.VisitNum)))
.WhereIf(inDto.ReadingQuestionId != null, x => x.Id == inDto.ReadingQuestionId)
.OrderBy(x => x.ShowOrder)
.Select(x => new TrialQuestionVisitJudgeRuleItemDto
@ -128,6 +135,54 @@ namespace IRaCIS.Core.Application.Service
return ResponseOutput.Result(await _readingQuestionVisitJudgeRuleRepository.SaveChangesAsync());
}
/// <summary>
/// 复制其他访视的项目阅片标准裁判规则配置。
/// 目标访视不适用的问题保留其已有的不适用规则,不参与复制。
/// </summary>
[HttpPost]
public async Task<IResponseOutput> CopyTrialQuestionVisitJudgeRule(CopyTrialQuestionVisitJudgeRuleInDto inDto)
{
var targetQuestionIds = await _readingQuestionTrialRepository
.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion)
.Where(x => x.LimitShow == LimitShow.AllShow
|| (x.LimitShow == LimitShow.BaseLineShow && inDto.TargetVisitNum == 0)
|| (x.LimitShow == LimitShow.FollowShow && inDto.TargetVisitNum != 0)
|| (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(inDto.TargetVisitNum)))
.Select(x => x.Id)
.ToListAsync();
if (targetQuestionIds.Count == 0)
{
return ResponseOutput.Ok();
}
var sourceRules = await _readingQuestionVisitJudgeRuleRepository
.Where(x => x.VisitNum == inDto.SourceVisitNum && targetQuestionIds.Contains(x.ReadingQuestionId))
.ToListAsync();
await _readingQuestionVisitJudgeRuleRepository.BatchDeleteNoTrackingAsync(x =>
x.VisitNum == inDto.TargetVisitNum && targetQuestionIds.Contains(x.ReadingQuestionId));
var targetRules = sourceRules.Select(rule => new ReadingQuestionVisitJudgeRule
{
Id = NewId.NextGuid(),
ReadingQuestionId = rule.ReadingQuestionId,
VisitNum = inDto.TargetVisitNum,
AnswerGroup = rule.AnswerGroup,
AnswerCombination = rule.AnswerCombination,
JudgeType = rule.JudgeType,
JudgeDifferenceValue = rule.JudgeDifferenceValue,
JudgeDifferenceType = rule.JudgeDifferenceType,
}).ToList();
if (targetRules.Count > 0)
{
await _readingQuestionVisitJudgeRuleRepository.AddRangeAsync(targetRules);
}
return ResponseOutput.Result(await _readingQuestionVisitJudgeRuleRepository.SaveChangesAsync());
}
#endregion
@ -713,9 +768,61 @@ namespace IRaCIS.Core.Application.Service
}
var entity = await _readingQuestionTrialRepository.InsertOrUpdateAsync(indto, true);
await AddNAJudgeRule(entity);
return ResponseOutput.Ok(entity.Id.ToString());
}
/// <summary>
/// 添加问题的不适用规则
/// </summary>
/// <returns></returns>
private async Task AddNAJudgeRule(ReadingQuestionTrial entity)
{
List<decimal> visitNums = new List<decimal>();
if (entity.IsJudgeQuestion)
{
var visitStageNums = await _visitStageRepository
.Where(x => x.TrialId == entity.TrialId)
.Select(x => x.VisitNum)
.Distinct()
.ToListAsync();
switch (entity.LimitShow)
{
case LimitShow.BaseLineShow:
visitNums = visitStageNums.Where(x => x > 0).ToList();
visitNums.Add(-1);
break;
case LimitShow.FollowShow:
visitNums.Add(0);
break;
case LimitShow.ExcludeSomeVisits:
visitNums = entity.ExcludeShowVisitList;
break;
}
}
if (visitNums.Count==0)
{
return;
}
await _readingQuestionVisitJudgeRuleRepository.BatchDeleteNoTrackingAsync(x =>
x.ReadingQuestionId == entity.Id && visitNums.Contains(x.VisitNum));
var rules = visitNums.Select(visitNum => new ReadingQuestionVisitJudgeRule
{
Id = NewId.NextGuid(),
ReadingQuestionId = entity.Id,
VisitNum = visitNum,
JudgeType = JudgeTypeEnum.None,
}).ToList();
await _readingQuestionVisitJudgeRuleRepository.AddRangeAsync(rules);
await _readingQuestionVisitJudgeRuleRepository.SaveChangesAsync();
}
/// <summary>
/// 获取项目问题(项目)
/// </summary>

View File

@ -125,7 +125,7 @@ namespace IRaCIS.Core.Application.Service
.Select(x => x.JudgeRuleEnum)
.FirstNotNullAsync();
var displayQuestions = await GetJudgeDisplayQuestions(r1Task.TrialReadingCriterionId, r1Task.VisitTaskNum, judgeRule);
var displayQuestions = await GetJudgeDisplayQuestions(r1Task.TrialReadingCriterionId, r1Task.VisitTaskNum, judgeRule, false);
var judgeAnswers = displayQuestions
.Select(x => new SingleVisitJudgeAnswerItemDto
{
@ -175,7 +175,7 @@ namespace IRaCIS.Core.Application.Service
{
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var judgeRule = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => x.JudgeRuleEnum).FirstNotNullAsync();
var questionList = await GetJudgeDisplayQuestions(taskInfo.TrialReadingCriterionId, taskInfo.VisitTaskNum, judgeRule);
var questionList = await GetJudgeDisplayQuestions(taskInfo.TrialReadingCriterionId, taskInfo.VisitTaskNum, judgeRule, true);
var questionIds = questionList.Select(x => x.Id).ToList();
var answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.ReadingQuestionTrialId)).ToListAsync();
@ -188,6 +188,7 @@ namespace IRaCIS.Core.Application.Service
ReadingQuestionId = x.Id,
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
Type = x.Type,
ShowQuestion = x.ShowQuestion,
TypeValue = x.TypeValue,
ShowOrder = x.ShowOrder,
Answer = answers.FirstOrDefault(answer => answer.ReadingQuestionTrialId == x.Id)?.Answer ?? string.Empty,
@ -196,6 +197,11 @@ namespace IRaCIS.Core.Application.Service
Unit = x.Unit,
CustomUnit = x.CustomUnit,
ValueType = x.ValueType,
ClassifyQuestionId = x.ClassifyQuestionId,
ClassifyAlgorithms = x.ClassifyAlgorithms,
ClassifyType = x.ClassifyType
}).ToList(),
};
}
@ -223,7 +229,7 @@ namespace IRaCIS.Core.Application.Service
{
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var judgeRule = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => x.JudgeRuleEnum).FirstNotNullAsync();
var displayQuestionIds = (await GetJudgeDisplayQuestions(taskInfo.TrialReadingCriterionId, taskInfo.VisitTaskNum, judgeRule)).Select(x => x.Id).ToList();
var displayQuestionIds = (await GetJudgeDisplayQuestions(taskInfo.TrialReadingCriterionId, taskInfo.VisitTaskNum, judgeRule, true)).Select(x => x.Id).ToList();
var submittedQuestionIds = inDto.QuestionList.Select(x => x.ReadingQuestionId).ToList();
@ -268,9 +274,10 @@ namespace IRaCIS.Core.Application.Service
}
private async Task<List<ReadingQuestionTrial>> GetJudgeDisplayQuestions(Guid trialReadingCriterionId, decimal visitNum, JudgeRule judgeRule)
private async Task<List<ReadingQuestionTrial>> GetJudgeDisplayQuestions(Guid trialReadingCriterionId, decimal visitNum, JudgeRule judgeRule,bool isGetShowQuestion)
{
var questionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && x.IsJudgeQuestion)
.WhereIf(!isGetShowQuestion,x=>x.ShowQuestion!= ShowQuestion.Hide)
.WhereIf(visitNum == 0, x => x.LimitShow != LimitShow.FollowShow)
.WhereIf(visitNum != 0, x => x.LimitShow != LimitShow.BaseLineShow)
.Where(x=>x.LimitShow!=LimitShow.ExcludeSomeVisits||x.ExcludeShowVisitList.Contains(visitNum))
@ -308,6 +315,7 @@ namespace IRaCIS.Core.Application.Service
return questionList
.Where(x => visitJudgeRules.FirstOrDefault(rule => rule.ReadingQuestionId == x.Id && rule.VisitNum == -1)?.JudgeType != JudgeTypeEnum.NotApplicable)
.OrderBy(x=>x.ShowOrder)
.ToList();
}

View File

@ -27,15 +27,16 @@ namespace IRaCIS.Core.Application
IRepository<TrialQCQuestion> _trialQCQuestionRepository,
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
IRepository<ReadingQuestionVisitJudgeRule> _readingQuestionVisitJudgeRuleRepository,
IRepository<TrialCriterionDictionaryCode> _trialCriterionDictionaryCode,
IRepository<SystemCriterionDictionaryCode> _systemCriterionDictionaryCode,
IRepository<ReadingQuestionCriterionSystem> _readingQuestionCriterionSystemRepository,
IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository,
IRepository<ReadingCriterionPage> _readingCriterionPageRepository,
IRepository<SystemCriterionKeyFile> _systemCriterionKeyFileRepository,
IOSSService _oSSService,
IRepository<TrialCriterionKeyFile> _trialCriterionKeyFileRepository,
IRepository<SystemCriterionKeyFile> _systemCriterionKeyFileRepository,
IOSSService _oSSService,
IRepository<VisitStage> _visitStageRepository,
IRepository<TrialCriterionKeyFile> _trialCriterionKeyFileRepository,
IOrganInfoService _iOrganInfoService,
IRepository<TrialBodyPart> _trialBodyPartRepository,
IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository,
@ -48,7 +49,7 @@ namespace IRaCIS.Core.Application
IRepository<SystemBasicData> _systemBasicDataRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Enroll> _enrollRepository,
IRepository<TrialQCQuestionAnswer> _qcQuestionAnswerRepository,
IRepository<TrialQCQuestionAnswer> _qcQuestionAnswerRepository,
IRepository<TrialStateChange> _trialStateChangeRepository,
IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository, IRepository<TrialDicomAE> _dicomAERepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, ITrialConfigService
@ -105,6 +106,40 @@ namespace IRaCIS.Core.Application
throw new BusinessValidationFailedException(_localizer["TrialConfig_JudgeTaskFail"]);
}
if (trialCriterion.JudgeRuleEnum == JudgeRule.Difference)
{
var visitStageList = await _visitStageRepository.Where(x => x.TrialId == trialCriterion.TrialId).ToListAsync();
visitStageList.Add(new VisitStage()
{
VisitName = "Out of Plan",
VisitNum=-1,
});
var judgeCount = await _readingQuestionTrialRepository.CountAsync(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion);
var ruleList = await _readingQuestionVisitJudgeRuleRepository.Where(x => x.ReadingQuestionTrial.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId).ToListAsync();
var errorList = new List<string>();
visitStageList.ForEach(x =>
{
if (judgeCount != ruleList.Count(y => y.VisitNum == x.VisitNum))
{
errorList.Add(x.VisitName);
}
});
if (errorList.Count() > 0)
{
throw new BusinessValidationFailedException(_localizer["TrialConfig_VisitjudgeDeficiency", string.Join(",", errorList)]);
}
}
return ResponseOutput.Ok(true);
}

View File

@ -21,7 +21,7 @@ public class ReadingQuestionVisitJudgeRule : BaseAddAuditEntity
public Guid ReadingQuestionId { get; set; }
/// <summary>
/// 访视Num
/// 访视Num (计划外是-1)
/// </summary>
public decimal VisitNum { get; set; }