Compare commits

..

No commits in common. "a7394e71192b30142379fc21900f3815932958b0" and "be8b730ee4dd05c2c86d022501674547a1fde28d" have entirely different histories.

20 changed files with 48 additions and 293 deletions

View File

@ -429,21 +429,11 @@ namespace IRaCIS.Core.API.Controllers
public async Task<IResponseOutput> QCPassedOrFailed(DataInspectionDto<QCPassedOrFailedDto> opt)
{
var singid = await _inspectionService.RecordSing(opt.SignInfo);
if (opt.Data.IsSecondPass != null)
{
var result = await _qCOperationService.QCSecondReviewPassedOrFailed(opt.Data.trialId, opt.Data.subjectVisitId, (bool)opt.Data.IsSecondPass);
await _inspectionService.CompletedSign(singid, result);
return result;
}
else
{
var result = await _qCOperationService.QCPassedOrFailed(opt.Data.trialId, opt.Data.subjectVisitId, opt.Data.auditState);
await _inspectionService.CompletedSign(singid, result);
return result;
}
}
/// <summary>
/// 一致性核查 回退 对话记录不清除 只允许PM回退
/// </summary>

View File

@ -1116,7 +1116,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
HtmlPath = k.HtmlPath,
Path = k.Path,
InstanceNumber = k.InstanceNumber,
FileSize=k.FileSize,
}).ToList()
})
});

View File

@ -199,8 +199,6 @@ namespace IRaCIS.Core.Application.Service.Inspection.DTO
public Guid subjectVisitId { get; set; }
public AuditStateEnum auditState { get; set; }
public bool? IsSecondPass { get; set; }
}
public class SetSeriesStateDto

View File

@ -251,13 +251,7 @@ namespace IRaCIS.Core.Application.Contracts.DTO
}
public class SecondReviewDto
{
public DateTime? SecondReviewTime { get; set; }
public string FullName { get; set; }
public string UserName { get; set; }
public DateTime? SignTime { get; set; }
}
public class TrialVisitQADTO
@ -276,7 +270,6 @@ namespace IRaCIS.Core.Application.Contracts.DTO
public QARelationInfo RelationInfo { get; set; } = new QARelationInfo();
public List<SecondReviewDto> SecondReviewList { get; set; }
}

View File

@ -1949,7 +1949,6 @@ namespace IRaCIS.Core.Application.Contracts
public class QCQuestionAnswer
{
public Guid? AnswerId { get; set; }
public Guid Id { get; set; }
public string QuestionName { get; set; } = String.Empty;
public bool IsRequired { get; set; }
@ -1978,8 +1977,6 @@ namespace IRaCIS.Core.Application.Contracts
// 1代表第一个人QC数据 2 代表第二个人QC数据
public CurrentQC CurrentQCEnum { get; set; }
public DateTime? SecondReviewTime { get; set; }
}
public class ForwardQuery : PageInput
@ -2133,8 +2130,6 @@ namespace IRaCIS.Core.Application.Contracts
public class QCVisitBasicListViewModel
{
public SecondReviewState SecondReviewState { get; set; }
public bool IsSubjectQuit { get; set; }
public ChallengeStateEnum ChallengeState { get; set; }
public bool? IsConfirmedClinicalData { get; set; }
public bool IsQCConfirmedReupload { get; set; }

View File

@ -35,8 +35,6 @@ namespace IRaCIS.Core.Application.Contracts
public DateTime UpdateTime { get; set; }
public Guid UpdateUserId { get; set; }
public bool IsQuestionQCAuditPassed { get; set; }
}
public class QCQuestionFilterSelect

View File

@ -13,7 +13,7 @@ namespace IRaCIS.Core.Application.Image.QA
Task<IResponseOutput> QCPassedOrFailed(Guid trialId, Guid subjectVisitId, [FromRoute] AuditStateEnum auditState);
Task<IResponseOutput> SetCheckPass(SetCheckPassDt data);
Task<IResponseOutput> QCSecondReviewPassedOrFailed(Guid trialId, Guid subjectVisitId, bool isSecondPass);
Task<IResponseOutput> AddCheckChallengeReply(CheckChallengeDialogCommand checkDialogCommand);

View File

@ -7,8 +7,6 @@ using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit.Initializers;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using System.Linq;
namespace IRaCIS.Core.Application.Image.QA
{
@ -26,7 +24,6 @@ namespace IRaCIS.Core.Application.Image.QA
IRepository<NoneDicomStudy> _noneDicomStudyRepository,
IRepository<QCChallenge> _qcChallengeRepository,
IRepository<SubjectVisitImageBackRecord> _subjectVisitImageBackRecordReposiotry,
IRepository<UserRole> _userRoleReposiotry,
IReadingImageTaskService _IReadingImageTaskService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IQCListService
{
@ -412,50 +409,10 @@ namespace IRaCIS.Core.Application.Image.QA
var qacheckList = await GetQCQuestionAnswerList(subjectVisitId, sv.TrialId, trialQCProcess, currentQCType);
List<SecondReviewDto> secondReviewList = new List<SecondReviewDto>();
if (sv.SecondReviewState != SecondReviewState.None)
{
var trialConfirmTime = _trialRepository.Where(t => t.Id == sv.TrialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
secondReviewList = (from answer in _trialQCQuestionAnswerRepository.Where(t => t.SubjectVisitId == subjectVisitId && t.CurrentQCEnum == CurrentQC.SecondReview).Where(t => t.SecondReviewTime != null)
join userRole in _userRoleReposiotry.Where() on answer.UpdateUserId equals userRole.Id
select new SecondReviewDto { SecondReviewTime = answer.SecondReviewTime, SignTime = answer.UpdateTime, FullName = userRole.FullName, UserName = userRole.UserName })
.Distinct().ToList();
var secondReviewTimeList = secondReviewList.Select(t => t.SecondReviewTime).Distinct().ToList();
//首次加入
if (!secondReviewTimeList.Contains(trialConfirmTime))
{
secondReviewList.Add(new SecondReviewDto() { SecondReviewTime = trialConfirmTime });
}
else
{
if (sv.SecondReviewState == SecondReviewState.WaitAudit)
{
foreach (var item in secondReviewList)
{
if (item.SecondReviewTime == trialConfirmTime)
{
item.SignTime = null;
item.FullName = "";
item.UserName = "";
}
}
}
}
secondReviewList = secondReviewList.OrderByDescending(t => t.SecondReviewTime).ToList();
}
return new TrialVisitQADTO
{
QCQuestionAnswerList = qacheckList,
SecondReviewList = secondReviewList,
IsHaveStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.IsConfirm && x.TrialId == sv.TrialId && x.ClinicalDataLevel == ClinicalLevel.Study),
StudyList = temp.StudyList,
ExistsManual = (await _IReadingImageTaskService.GetManualList(new GetManualListInDto() { TrialId = sv.TrialId })).Count() > 0,
@ -475,50 +432,11 @@ namespace IRaCIS.Core.Application.Image.QA
[HttpPost]
public async Task<List<QCQuestionAnswer>> GetQCQuestionAnswer(GetQCQuestionAnswerInDto inDto)
{
var subjectVisitId = inDto.SubjectVisitId;
List<QCQuestionAnswer> questionAnswerlist = new List<QCQuestionAnswer>();
//判断当前访视质控是否完成,再判断复审是完成查看,还是添加编辑
var sv = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).FirstNotNullAsync();
if (sv.SecondReviewState == SecondReviewState.None && sv.AuditState == AuditStateEnum.QCPassed)
{
//现在之前历史质控的展示要从答案为主表取数据,添加和编辑按照之前方式
questionAnswerlist = await _trialQCQuestionAnswerRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId && x.QCProcessEnum == inDto.QCProcessEnum && x.CurrentQCEnum == inDto.CurrentQCEnum)
.Select(data => new QCQuestionAnswer()
{
AnswerId=data.Id,
Answer = data.Answer,
ShowOrder = data.TrialQCQuestionConfigure.ShowOrder,
QuestionName = data.TrialQCQuestionConfigure.QuestionName,
Id = data.TrialQCQuestionConfigure.Id,
IsRequired = data.TrialQCQuestionConfigure.IsRequired,
ParentId = data.TrialQCQuestionConfigure.ParentId,
ParentTriggerValue = data.TrialQCQuestionConfigure.ParentTriggerValue,
Type = data.TrialQCQuestionConfigure.Type,
TypeValue = data.TrialQCQuestionConfigure.TypeValue
}).OrderBy(t => t.ShowOrder).ToListAsync();
}
else
{
var secondReviewTime = inDto.SecondReviewTime != null ? (DateTime)inDto.SecondReviewTime : DateTime.Now;
#region 之前编辑和审核通过后展示都是通过这个接口
questionAnswerlist = await (from data in _trialQCQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.IsEnable)
join answer in _trialQCQuestionAnswerRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId && x.QCProcessEnum == inDto.QCProcessEnum && x.CurrentQCEnum == inDto.CurrentQCEnum)
.Where(t => inDto.CurrentQCEnum == CurrentQC.SecondReview ? t.SecondReviewTime >= secondReviewTime && t.SecondReviewTime <= secondReviewTime.AddSeconds(1) : true)
on data.Id equals answer.TrialQCQuestionConfigureId into answertemp
var questionAnswerlist = await (from data in _trialQCQuestionRepository.Where(x => x.TrialId == inDto.TrialId && x.IsEnable)
join answer in _trialQCQuestionAnswerRepository.Where(x => x.SubjectVisitId == inDto.SubjectVisitId && x.QCProcessEnum == inDto.QCProcessEnum && x.CurrentQCEnum == inDto.CurrentQCEnum).AsQueryable() on data.Id equals answer.TrialQCQuestionConfigureId into answertemp
from leftanswer in answertemp.DefaultIfEmpty()
select new QCQuestionAnswer()
{
AnswerId= leftanswer.Id,
Answer = leftanswer.Answer,
ShowOrder = data.ShowOrder,
QuestionName = data.QuestionName,
@ -529,17 +447,6 @@ namespace IRaCIS.Core.Application.Image.QA
Type = data.Type,
TypeValue = data.TypeValue
}).OrderBy(t => t.ShowOrder).ToListAsync();
#endregion
}
var result = questionAnswerlist.Where(x => x.ParentId == null).OrderBy(t => t.ShowOrder).ToList();
result.ForEach(x =>

View File

@ -727,17 +727,9 @@ namespace IRaCIS.Core.Application.Image.QA
//[Authorize(Policy = IRaCISPolicy.IQC)]
public async Task<IResponseOutput> AddOrUpdateQCQuestionAnswerList(QCQuestionAnswerCommand[] qcQuestionAnswerCommands, Guid trialId, Guid subjectVisitId, [FromRoute] TrialQCProcess trialQCProcess, [FromRoute] CurrentQC currentQCType)
{
if (currentQCType == CurrentQC.SecondReview)
{
//二次复核自动领取,如果有人先领取了,那么后续不能操作
await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId && t.CurrentActionUserId == null, u => new SubjectVisit() { CurrentActionUserId = _userInfo.UserRoleId }, true);
}
//验证是否能操作
await VerifyIsCanQCAsync(null, subjectVisitId);
var trialConfirmTime = _trialRepository.Where(t => t.Id == trialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
//更新
if (qcQuestionAnswerCommands.Any(t => t.Id != null))
{
@ -782,13 +774,11 @@ namespace IRaCIS.Core.Application.Image.QA
{
var addlist = _mapper.Map<List<TrialQCQuestionAnswer>>(qcQuestionAnswerCommands);
addlist.ForEach(t => { t.TrialId = trialId; t.SubjectVisitId = subjectVisitId; t.CurrentQCEnum = currentQCType; t.QCProcessEnum = trialQCProcess; t.SecondReviewTime = currentQCType == CurrentQC.SecondReview ? trialConfirmTime : null; });
addlist.ForEach(t => { t.TrialId = trialId; t.SubjectVisitId = subjectVisitId; t.CurrentQCEnum = currentQCType; t.QCProcessEnum = trialQCProcess; });
await _trialQCQuestionAnswerRepository.AddRangeAsync(addlist);
return ResponseOutput.Ok(await _trialQCQuestionAnswerRepository.SaveChangesAsync());
return ResponseOutput.Result(await _trialQCQuestionAnswerRepository.SaveChangesAsync());
}
@ -1183,7 +1173,7 @@ namespace IRaCIS.Core.Application.Image.QA
[HttpPut("{trialId:guid}/{subjectVisitId:guid}")]
//[Authorize(Policy = IRaCISPolicy.IQC)]
[TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task<IResponseOutput> ReplaceQCTaskActionUser(Guid trialId, Guid subjectVisitId, Guid? replaceUserRoleId)
public async Task<IResponseOutput> ReplaceQCTaskActionUser(Guid trialId, Guid subjectVisitId)
{
var dbSubjectVisit = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();
@ -1197,7 +1187,7 @@ namespace IRaCIS.Core.Application.Image.QA
dbSubjectVisit.IsTake = true;
dbSubjectVisit.CurrentActionUserId = replaceUserRoleId == null || replaceUserRoleId == Guid.Empty ? _userInfo.UserRoleId : replaceUserRoleId;
dbSubjectVisit.CurrentActionUserId = _userInfo.UserRoleId;
dbSubjectVisit.CurrentActionUserExpireTime = DateTime.Now.AddHours(1);
@ -2087,43 +2077,8 @@ namespace IRaCIS.Core.Application.Image.QA
}
public async Task<IResponseOutput> QCSecondReviewPassedOrFailed(Guid trialId, Guid subjectVisitId, bool isSecondPass)
{
if (!await _trialUserRoleRepository.AnyAsync(t => t.TrialId == trialId && t.UserId == _userInfo.UserRoleId))
{
//---您已经被移出项目,没有操作权限。
return ResponseOutput.NotOk(_localizer["QCOperation_RemoveItem"]);
}
var sv = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
await VerifyIsCanQCAsync(sv);
var trialConfirmTime = _trialRepository.Where(t => t.Id == sv.TrialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
if (sv.SecondReviewState == SecondReviewState.WaitAudit)
{
if (isSecondPass)
{
sv.SecondReviewState = SecondReviewState.AuditPassed;
}
else
{
sv.SecondReviewState = SecondReviewState.AuditFailed;
}
await _trialQCQuestionAnswerRepository.BatchUpdateNoTrackingAsync(t => t.SubjectVisitId == sv.Id && t.CurrentQCEnum == CurrentQC.SecondReview && t.SecondReviewTime == trialConfirmTime, u => new TrialQCQuestionAnswer()
{
UpdateUserId = _userInfo.UserRoleId,
UpdateTime = DateTime.Now
});
}
await _subjectVisitRepository.SaveChangesAsync();
return ResponseOutput.Ok();
}
/// <summary>
/// 设置、取消 访视紧急

View File

@ -472,7 +472,6 @@ namespace IRaCIS.Core.Application.Service
CreateMap<TrialQCQuestion, TrialQCQuestionAddOrEdit>();
CreateMap<TrialQCQuestion, TrialQCQuestionConfigureView>()
.ForMember(d => d.IsQuestionQCAuditPassed, u => u.MapFrom(s => s.TrialQCQuestionAnswerList.Any(c => c.TrialQCQuestionConfigureId == s.Id && c.SubjectVisit.AuditState == AuditStateEnum.QCPassed)))
.ForMember(d => d.ParentShowOrder, u => u.MapFrom(s => s.ParentQCQuestion.ShowOrder));
CreateMap<TrialQCQuestionSelect, TrialQCQuestionConfigureView>();

View File

@ -139,16 +139,5 @@ namespace IRaCIS.Core.Application.Contracts.DTO
}
public class TrialSelectUserBasicInfo
{
public Guid UserRoleId { get; set; }
public string FullName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
}

View File

@ -6,7 +6,6 @@ using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
@ -42,7 +41,6 @@ namespace IRaCIS.Core.Application
IRepository<SystemBasicData> _systemBasicDataRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<Enroll> _enrollRepository,
IRepository<TrialQCQuestionAnswer> _qcQuestionAnswerRepository,
IRepository<TrialStateChange> _trialStateChangeRepository,
IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, ITrialConfigService
@ -839,22 +837,9 @@ namespace IRaCIS.Core.Application
{
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { IsTrialUrgentConfirmed = true });
}
else if (signConfirmDTO.SignCode == ((int)SignEnum.TrialQCQuestionConfirmUpdate).ToString())
{
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { QCQuestionConfirmedTime = null, QCQuestionConfirmedUserId = null, IsQCQuestionConfirmed = false });
}
else if (signConfirmDTO.SignCode == ((int)SignEnum.SecondReviewConfirm).ToString())
{
var trialConfirmTime = _trialRepository.Where(t => t.Id == signConfirmDTO.TrialId).Select(t => t.QCQuestionConfirmedTime).FirstOrDefault();
else
//重复二次复核签名
await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == signConfirmDTO.TrialId && t.AuditState == AuditStateEnum.QCPassed
&& !t.TrialQCQuestionAnswerList.Any(t => t.SecondReviewTime == trialConfirmTime), u => new SubjectVisit() { SecondReviewState = SecondReviewState.WaitAudit });
//删除复审中间临时数据
await _qcQuestionAnswerRepository.BatchDeleteNoTrackingAsync(t => t.SubjectVisit.TrialId == signConfirmDTO.TrialId && t.SubjectVisit.SecondReviewState != SecondReviewState.AuditPassed && t.CurrentQCEnum == CurrentQC.SecondReview);
}
else if (signConfirmDTO.SignCode == ((int)SignEnum.TrialQCQuestionConfirm).ToString())
if (signConfirmDTO.SignCode == ((int)SignEnum.TrialQCQuestionConfirm).ToString())
{
var trialConfig = (await _trialRepository
@ -899,9 +884,9 @@ namespace IRaCIS.Core.Application
IsConfirm = true
});
await _trialRepository.UpdatePartialFromQueryAsync(t => t.Id == signConfirmDTO.TrialId, u => new Trial() { QCQuestionConfirmedTime = DateTime.Now, QCQuestionConfirmedUserId = _userInfo.UserRoleId, IsQCQuestionConfirmed = true });
await _trialRepository.SaveChangesAsync();
}
await _trialRepository.SaveChangesAsync();
return ResponseOutput.Ok();

View File

@ -315,24 +315,7 @@ namespace IRaCIS.Core.Application.Service
}
public async Task<List<TrialSelectUserBasicInfo>> GetTrialUserRoleList(Guid trialId, UserTypeEnum? userTypeEnum)
{
var list = await _trialIdentityUserRepository.Where(t => t.TrialId == trialId)
.SelectMany(t => t.TrialUserRoleList)
.WhereIf(userTypeEnum != null, t => t.UserRole.UserTypeEnum == userTypeEnum)
.Where(t => t.UserRole.Id != _userInfo.UserRoleId)//iQC 指派过滤自己
.Select(t => new TrialSelectUserBasicInfo()
{
FullName = t.TrialUser.IdentityUser.FullName,
UserRoleId = t.UserRole.Id,
UserName = t.TrialUser.IdentityUser.UserName,
Phone = t.TrialUser.IdentityUser.Phone,
Email = t.TrialUser.IdentityUser.EMail
})
.ToListAsync();
return list;
}
}
}

View File

@ -29,13 +29,6 @@ namespace IRaCIS.Core.Domain.Share
TrialQCQuestionConfirm=107,
//重置质控问题配置
TrialQCQuestionConfirmUpdate=112,
SecondReviewConfirm = 113,
}
}

View File

@ -19,14 +19,4 @@ namespace IRaCIS.Core.Domain.Share
}
public enum SecondReviewState
{
None = 0,
WaitAudit=1,
AuditPassed=2,
AuditFailed=3,
}
}

View File

@ -14,11 +14,7 @@
First = 1,
Second = 2,
//二次复核,只会一个人
SecondReview=3,
Second = 2
}

View File

@ -108,7 +108,6 @@ public abstract class BaseFullAuditEntity : Entity, IAuditUpdate, IAuditAdd
[ForeignKey("CreateUserId")]
[JsonIgnore]
public UserRole CreateUserRole { get; set; }
}
public abstract class BaseFullDeleteAuditEntity : Entity, IAuditUpdate, IAuditAdd, ISoftDelete
{

View File

@ -8,9 +8,6 @@ public class TrialQCQuestionAnswer : BaseFullAuditEntity
#region 导航属性
[JsonIgnore]
public TrialQCQuestion TrialQCQuestionConfigure { get; set; }
[JsonIgnore]
public SubjectVisit SubjectVisit { get; set; }
#endregion
public Guid TrialId { get; set; }
@ -23,7 +20,4 @@ public class TrialQCQuestionAnswer : BaseFullAuditEntity
public Guid SubjectVisitId { get; set; }
public Guid TrialQCQuestionConfigureId { get; set; }
public DateTime? SecondReviewTime { get; set; }
}

View File

@ -6,8 +6,6 @@ namespace IRaCIS.Core.Domain.Models;
public class SubjectVisit : BaseFullDeleteAuditEntity
{
#region 导航属性
[JsonIgnore]
public List<TrialQCQuestionAnswer> TrialQCQuestionAnswerList { get; set; }
[JsonIgnore]
public TrialSite TrialSite { get; set; }
@ -187,7 +185,7 @@ public class SubjectVisit : BaseFullDeleteAuditEntity
public Guid? SubmitUserId { get; set; }
public ReadingStatusEnum ReadingStatus { get; set; }
public SecondReviewState SecondReviewState { get; set; }
}
[Comment("受试者访视影像回退记录表")]

View File

@ -198,13 +198,6 @@ namespace IRaCIS.Core.Infra.EFCore.Common
extraIdentification = oldentity.IsConfigureEmail ? "/EmailUpdate" : "/EmailSave";
break;
case "configTrialBasicInfo/TrialConfigSignatureConfirm":
if (entity.IsQCQuestionConfirmed == false)
{
extraIdentification = $"/ConfirmReset";
}
break;
}