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

IRC_NewDev
hang 2024-02-21 13:58:36 +08:00
commit 61530be208
12 changed files with 301 additions and 111 deletions

View File

@ -33,6 +33,7 @@ using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.StaticFiles; using Microsoft.AspNetCore.StaticFiles;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using MiniExcelLibs; using MiniExcelLibs;
@ -235,13 +236,17 @@ namespace IRaCIS.Core.API.Controllers
public IUserInfo _userInfo { get; set; } public IUserInfo _userInfo { get; set; }
private readonly IMediator _mediator; private readonly IMediator _mediator;
public IStringLocalizer _localizer { get; set; }
private readonly IWebHostEnvironment _hostEnvironment; private readonly IWebHostEnvironment _hostEnvironment;
private readonly IRepository _repository; private readonly IRepository _repository;
private readonly IEasyCachingProvider _provider; private readonly IEasyCachingProvider _provider;
private readonly QCCommon _qCCommon; private readonly QCCommon _qCCommon;
public StudyController(IMapper mapper, IUserInfo userInfo, IWebHostEnvironment hostEnvironment, IMediator mediator, IEasyCachingProvider provider, public StudyController(IMapper mapper, IStringLocalizer localizer, IUserInfo userInfo, IWebHostEnvironment hostEnvironment, IMediator mediator, IEasyCachingProvider provider,
QCCommon qCCommon, QCCommon qCCommon,
IRepository repository) IRepository repository)
{ {
@ -249,7 +254,7 @@ namespace IRaCIS.Core.API.Controllers
_provider = provider; _provider = provider;
_hostEnvironment = hostEnvironment; _hostEnvironment = hostEnvironment;
_mediator = mediator; _mediator = mediator;
_localizer = localizer;
_mapper = mapper; _mapper = mapper;
_userInfo = userInfo; _userInfo = userInfo;
_repository = repository; _repository = repository;
@ -313,7 +318,7 @@ namespace IRaCIS.Core.API.Controllers
string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value)) string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
{ {
//---不支持的MediaType //---不支持的MediaType
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_UnsupportedMedia")); return ResponseOutput.NotOk(_localizer["UploadDownLoad_UnsupportedMedia"]);
} }
var archiveStudyCommand = new ArchiveStudyCommand() { AbandonStudyId = abandonStudyId, StudyInstanceUid = studyInstanceUid, SubjectVisitId = subjectVisitId }; var archiveStudyCommand = new ArchiveStudyCommand() { AbandonStudyId = abandonStudyId, StudyInstanceUid = studyInstanceUid, SubjectVisitId = subjectVisitId };
@ -407,7 +412,7 @@ namespace IRaCIS.Core.API.Controllers
_provider.Remove($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}"); _provider.Remove($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}");
//---请求异常,请重试! //---请求异常,请重试!
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_RequestError")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_RequestError"]);
} }
studyMonitor.FileSize = (decimal)HttpContext.Request.ContentLength; studyMonitor.FileSize = (decimal)HttpContext.Request.ContentLength;
@ -559,7 +564,7 @@ namespace IRaCIS.Core.API.Controllers
if (!fileName.EndsWith(".xlsx") && !fileName.EndsWith(".csv") && !fileName.EndsWith(".xls")) if (!fileName.EndsWith(".xlsx") && !fileName.EndsWith(".csv") && !fileName.EndsWith(".xls"))
{ {
//---支持.xlsx、.xls、.csv格式的文件上传。 //---支持.xlsx、.xls、.csv格式的文件上传。
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_SupportedFormats")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_SupportedFormats"]);
} }
fileStream.CopyTo(templateFileStream); fileStream.CopyTo(templateFileStream);
@ -609,7 +614,7 @@ namespace IRaCIS.Core.API.Controllers
//if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors)); //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors)); if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(_localizer["UploadDownLoad_TemplateErrors"]);
etcCheckList = import.Data.ToList(); etcCheckList = import.Data.ToList();
} }
@ -697,7 +702,7 @@ namespace IRaCIS.Core.API.Controllers
if (etcCheckList == null || etcCheckList.Count == 0) if (etcCheckList == null || etcCheckList.Count == 0)
{ {
//---请保证上传数据符合模板文件中的样式,且存在有效数据。 //---请保证上传数据符合模板文件中的样式,且存在有效数据。
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData")); return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
} }
else else
{ {
@ -718,7 +723,7 @@ namespace IRaCIS.Core.API.Controllers
if (etcCheckList.Count == 0) if (etcCheckList.Count == 0)
{ {
//---请保证上传数据符合模板文件中的样式,且存在有效数据。 //---请保证上传数据符合模板文件中的样式,且存在有效数据。
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData")); return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
} }
} }
@ -962,12 +967,13 @@ namespace IRaCIS.Core.API.Controllers
public IMapper _mapper { get; set; } public IMapper _mapper { get; set; }
public IUserInfo _userInfo { get; set; } public IUserInfo _userInfo { get; set; }
private readonly IMediator _mediator; private readonly IMediator _mediator;
public IStringLocalizer _localizer { get; set; }
private readonly IWebHostEnvironment _hostEnvironment; private readonly IWebHostEnvironment _hostEnvironment;
public UploadDownLoadController(IMapper mapper, IUserInfo userInfo, IMediator mediator, IWebHostEnvironment hostEnvironment) public UploadDownLoadController(IMapper mapper, IUserInfo userInfo, IStringLocalizer localizer, IMediator mediator, IWebHostEnvironment hostEnvironment)
{ {
_hostEnvironment = hostEnvironment; _hostEnvironment = hostEnvironment;
_localizer = localizer;
_mediator = mediator; _mediator = mediator;
_mapper = mapper; _mapper = mapper;
_userInfo = userInfo; _userInfo = userInfo;
@ -994,7 +1000,7 @@ namespace IRaCIS.Core.API.Controllers
if (!realFileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase)) if (!realFileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
{ {
// 请用提供格式的模板excel上传需要处理的数据 // 请用提供格式的模板excel上传需要处理的数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_TemplateUploadData"]);
} }
var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/SiteSurvey", realFileName); var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/SiteSurvey", realFileName);
@ -1015,7 +1021,7 @@ namespace IRaCIS.Core.API.Controllers
if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr))) if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr)))
{ {
//请确保Excel中 每一行的 中心编号,姓名,邮箱,用户类型数据记录完整再进行上传 //请确保Excel中 每一行的 中心编号,姓名,邮箱,用户类型数据记录完整再进行上传
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_EnsureCompleteData")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_EnsureCompleteData"]);
} }
var siteCodeList = excelList.Select(t => t.TrialSiteCode.Trim().ToUpper()).Distinct().ToList(); var siteCodeList = excelList.Select(t => t.TrialSiteCode.Trim().ToUpper()).Distinct().ToList();
@ -1023,31 +1029,31 @@ namespace IRaCIS.Core.API.Controllers
if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count) if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count)
{ {
//在项目中未找到该Excel中部分或全部中心 //在项目中未找到该Excel中部分或全部中心
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidCenters")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidCenters"]);
} }
if (excelList.GroupBy(t => new { t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1)) if (excelList.GroupBy(t => new { t.TrialSiteCode, t.UserTypeStr, t.Email }).Any(g => g.Count() > 1))
{ {
// 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据 // 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_CheckDuplicateAccounts")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_CheckDuplicateAccounts"]);
} }
if (excelList.Any(t => !t.Email.Contains("@"))) if (excelList.Any(t => !t.Email.Contains("@")))
{ {
//有邮箱不符合邮箱格式,请核查Excel数据 //有邮箱不符合邮箱格式,请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidEmail"]);
} }
var generateUserTypeList = new List<string>() { "CRC", "CRA" }; var generateUserTypeList = new List<string>() { "CRC", "CRA" };
if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper()))) if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper())))
{ {
//用户类型仅能为 CRC,SR,CRA 请核查Excel数据 //用户类型仅能为 CRC,SR,CRA 请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidUserType")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidUserType"]);
} }
if (excelList.Count == 0) if (excelList.Count == 0)
{ {
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_NoValiddata")); throw new BusinessValidationFailedException(_localizer["UploadDownLoad_NoValiddata"]);
} }
//处理好 用户类型 和用户类型枚举 //处理好 用户类型 和用户类型枚举
var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList(); var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList();

View File

@ -1310,6 +1310,13 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoCalculateService.CalculateTargetLesionStatus(IRaCIS.Core.Application.ViewModel.CalculateTargetLesionStatusInDto)">
<summary>
计算靶病灶状态
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="F:IRaCIS.Core.Application.Service.ReadingCalculate.IRECIST1Point1CalculateService.sODData"> <member name="F:IRaCIS.Core.Application.Service.ReadingCalculate.IRECIST1Point1CalculateService.sODData">
<summary> <summary>
获取Sod的值 获取Sod的值
@ -4860,6 +4867,16 @@
序号标记 序号标记
</summary> </summary>
</member> </member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.MergeLesionInDto.MergeRowId">
<summary>
融合的病灶
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.MergeLesionInDto.MeltingInToLesionList">
<summary>
融向的病灶
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetCustomTagInDto.VisitTaskId"> <member name="P:IRaCIS.Core.Application.Service.Reading.Dto.GetCustomTagInDto.VisitTaskId">
<summary> <summary>
任务Id 任务Id
@ -13413,6 +13430,13 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Application.Services.ReadingImageTaskService.GetCanMergeLesion(IRaCIS.Core.Application.Service.Reading.Dto.GetCanMergeLesionInDto)">
<summary>
获取可合并的病灶
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Application.Services.ReadingImageTaskService.SaveImageQuality(IRaCIS.Core.Application.Service.Reading.Dto.ChangeDicomReadingQuestionAnswerInDto)"> <member name="M:IRaCIS.Application.Services.ReadingImageTaskService.SaveImageQuality(IRaCIS.Core.Application.Service.Reading.Dto.ChangeDicomReadingQuestionAnswerInDto)">
<summary> <summary>
保存影像质量 保存影像质量

View File

@ -451,7 +451,8 @@ namespace IRaCIS.Core.Application.Image.QA
//.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState) //.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
.ProjectTo<QCVisitViewModel>(_mapper.ConfigurationProvider); .ProjectTo<QCVisitViewModel>(_mapper.ConfigurationProvider);
var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(QCVisitViewModel.AuditState) +" asc" }; var defalutSortArray = new string[] { nameof(QCVisitViewModel.IsUrgent) + " desc", nameof(QCVisitViewModel.SubjectId), nameof(QCVisitViewModel.VisitNum) };
//var defalutSortArray = new string[] { nameof(SubjectVisit.IsUrgent) + " desc", nameof(QCVisitViewModel.AuditState) +" asc" };
var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray); var pageList = await query.ToPagedListAsync(visitSearchDTO.PageIndex, visitSearchDTO.PageSize, visitSearchDTO.SortField, visitSearchDTO.Asc, string.IsNullOrWhiteSpace(visitSearchDTO.SortField), defalutSortArray);

View File

@ -297,16 +297,48 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<CrterionDictionaryGroup> CrterionDictionaryGroup { get; set; } public List<CrterionDictionaryGroup> CrterionDictionaryGroup { get; set; }
} }
public class GetCanMergeLesionOutDto
{
public Guid RowId { get; set; }
public string OrderMarkName { get; set; }
public Guid? OrganInfoId { get; set; }
public decimal RowIndex { get; set; }
public string Part { get; set; }
}
public class GetCanMergeLesionInDto
{
public Guid RowId { get; set; }
}
public class MergeLesionInDto public class MergeLesionInDto
{ {
public Guid VisitTaskId { get; set; } public Guid VisitTaskId { get; set; }
public Guid QuestionId { get; set; } public Guid QuestionId { get; set; }
public Guid MainRowId { get; set; }
/// <summary>
/// 融合的病灶
/// </summary>
public Guid MergeRowId { get; set; } public Guid MergeRowId { get; set; }
/// <summary>
/// 融向的病灶
/// </summary>
public List<Guid> MeltingInToLesionList { get; set; }
///// <summary>
///// 融合后病灶状态
///// </summary>
//public string LesionState { get; set; }
} }
@ -986,6 +1018,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public int? OtherNumberOfFrames { get; set; } public int? OtherNumberOfFrames { get; set; }
public SplitOrMergeType? SplitOrMergeType { get; set; }
} }
public class GetTableAnswerRowInfoInDto public class GetTableAnswerRowInfoInDto

View File

@ -17,6 +17,7 @@ using IRaCIS.Core.Application.Filter;
using DocumentFormat.OpenXml.Drawing; using DocumentFormat.OpenXml.Drawing;
using EasyCaching.Core; using EasyCaching.Core;
using DocumentFormat.OpenXml.Drawing.Charts; using DocumentFormat.OpenXml.Drawing.Charts;
using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
namespace IRaCIS.Application.Services namespace IRaCIS.Application.Services
{ {
@ -48,6 +49,7 @@ namespace IRaCIS.Application.Services
private readonly IRepository<TrialDocument> _trialDocumentRepository; private readonly IRepository<TrialDocument> _trialDocumentRepository;
private readonly IRepository<User> _userRepository; private readonly IRepository<User> _userRepository;
private readonly IEasyCachingProvider _provider; private readonly IEasyCachingProvider _provider;
private readonly ILuganoCalculateService _luganoCalculateService;
private readonly IRepository<ReadingCustomTag> _readingCustomTagRepository; private readonly IRepository<ReadingCustomTag> _readingCustomTagRepository;
private readonly IRepository<ReadingTaskQuestionMark> _readingTaskQuestionMarkRepository; private readonly IRepository<ReadingTaskQuestionMark> _readingTaskQuestionMarkRepository;
private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository; private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository;
@ -88,6 +90,7 @@ namespace IRaCIS.Application.Services
IRepository<TrialDocument> trialDocumentRepository, IRepository<TrialDocument> trialDocumentRepository,
IRepository<User> userRepository, IRepository<User> userRepository,
IEasyCachingProvider provider, IEasyCachingProvider provider,
ILuganoCalculateService luganoCalculateService,
IRepository<ReadingCustomTag> readingCustomTagRepository, IRepository<ReadingCustomTag> readingCustomTagRepository,
IRepository<ReadingTaskQuestionMark> readingTaskQuestionMarkRepository, IRepository<ReadingTaskQuestionMark> readingTaskQuestionMarkRepository,
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository, IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
@ -126,6 +129,7 @@ namespace IRaCIS.Application.Services
this._trialDocumentRepository = trialDocumentRepository; this._trialDocumentRepository = trialDocumentRepository;
this._userRepository = userRepository; this._userRepository = userRepository;
this._provider = provider; this._provider = provider;
this._luganoCalculateService = luganoCalculateService;
this._readingCustomTagRepository = readingCustomTagRepository; this._readingCustomTagRepository = readingCustomTagRepository;
this._readingTaskQuestionMarkRepository = readingTaskQuestionMarkRepository; this._readingTaskQuestionMarkRepository = readingTaskQuestionMarkRepository;
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository; this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
@ -1360,6 +1364,7 @@ namespace IRaCIS.Application.Services
answers.Add("RowIndex", x.ToString()); answers.Add("RowIndex", x.ToString());
answers.Add("RowId", rowInfo==null?string.Empty: rowInfo.Id.ToString()); answers.Add("RowId", rowInfo==null?string.Empty: rowInfo.Id.ToString());
answers.Add("MarkTool", rowInfo.MarkTool); answers.Add("MarkTool", rowInfo.MarkTool);
answers.Add("MeltingInToLesionMarks", rowInfo.MeltingInToLesionMarks);
answers.Add("StudyId", rowInfo.StudyId.ToString()); answers.Add("StudyId", rowInfo.StudyId.ToString());
answers.Add("OrganInfoId", rowInfo.OrganInfoId.ToString()); answers.Add("OrganInfoId", rowInfo.OrganInfoId.ToString());
answers.Add("IsFristAdd", (rowInfo.FristAddTaskId== TaskId).ToString()); answers.Add("IsFristAdd", (rowInfo.FristAddTaskId== TaskId).ToString());
@ -1463,55 +1468,95 @@ namespace IRaCIS.Application.Services
{ {
await VerifyTaskIsSign(inDto.VisitTaskId); await VerifyTaskIsSign(inDto.VisitTaskId);
await this.VerifyIsBaseLineTask(inDto.VisitTaskId); await this.VerifyIsBaseLineTask(inDto.VisitTaskId);
var mergeRow = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.MergeRowId).FirstNotNullAsync();
var rowsInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && (x.Id == inDto.MainRowId || x.Id == inDto.MergeRowId)).ToListAsync(); var meltingRows = await _readingTableAnswerRowInfoRepository.Where(x => inDto.MeltingInToLesionList.Contains(x.Id)).Include(x => x.ReadingQuestionTrial).ToListAsync();
if (rowsInfo.Count != 2) List<string> marks = meltingRows.OrderBy(x => x.RowIndex).Select(x => x.ReadingQuestionTrial.OrderMark + x.RowIndex.GetLesionMark()).ToList();
await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.RowId == mergeRow.Id && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State, x => new ReadingTableQuestionAnswer()
{ {
throw new BusinessValidationFailedException(_localizer["ReadingImage_NotaTask"]); Answer = TargetState.Loss.GetEnumInt(),
}
var minaid = rowsInfo.Where(x => x.Id == inDto.MainRowId).Select(x => x.Id).FirstOrDefault();
var mergeid = rowsInfo.Where(x => x.Id == inDto.MergeRowId).Select(x => x.Id).FirstOrDefault();
List<QuestionMark?> needRemoveMark = new List<QuestionMark?>()
{
QuestionMark.MajorAxis,
QuestionMark.ShortAxis,
};
var mainAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == minaid).Include(x => x.ReadingTableQuestionTrial).ToListAsync();
foreach (var item in mainAnswer)
{
await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.RowId == mergeid && x.TableQuestionId == item.TableQuestionId, x => new ReadingTableQuestionAnswer()
{
Answer = needRemoveMark.Contains(item.ReadingTableQuestionTrial.QuestionMark) ? string.Empty : item.Answer,
}); });
}
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(inDto.MergeRowId, x => new ReadingTableAnswerRowInfo()
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(mergeid, x => new ReadingTableAnswerRowInfo()
{ {
MergeRowId = minaid, MeltingInToLesion = JsonConvert.SerializeObject(inDto.MeltingInToLesionList),
MeltingInToLesionMarks = string.Join(',', marks),
SplitOrMergeType = SplitOrMergeType.Merge, SplitOrMergeType = SplitOrMergeType.Merge,
}) ; }) ;
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(mergeid, x => new ReadingTableAnswerRowInfo()
{
MergeRowId = minaid,
SplitOrMergeType = SplitOrMergeType.Merge,
});
await _readingTableAnswerRowInfoRepository.SaveChangesAsync(); await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{
IsChangeOtherTask = false,
VisitTaskId = inDto.VisitTaskId,
ComputationTrigger = ComputationTrigger.Lesion,
});
}
/// <summary>
/// 获取可合并的病灶
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<GetCanMergeLesionOutDto>> GetCanMergeLesion(GetCanMergeLesionInDto inDto)
{
var rowinfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).Include(x=>x.ReadingQuestionTrial).FirstNotNullAsync();
// 需要排除的状态
var needFilterState = new List<string>();
switch (rowinfo.ReadingQuestionTrial.LesionType)
{
//状态为“消失”、“无法评估”的靶病灶不可融合;
case LesionType.TargetLesion:
needFilterState = new List<string>() {
TargetState.Loss.GetEnumInt(),
TargetState.UnableEvaluate.GetEnumInt(),
};
break;
} }
var result = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == rowinfo.VisitTaskId && x.QuestionId == rowinfo.QuestionId && x.Id != rowinfo.Id)
// 筛选状态
.Where(x => x.LesionAnswerList.Any(y => y.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && !needFilterState.Contains(y.Answer)))
.Where(x=>x.SplitOrMergeType!=SplitOrMergeType.Split&&x.SplitOrMergeType!=SplitOrMergeType.SplitMain)
.Select(x => new GetCanMergeLesionOutDto()
{
RowId = x.Id,
RowIndex = x.RowIndex,
OrderMarkName = x.ReadingQuestionTrial.OrderMark + x.RowIndex.GetLesionMark(),
OrganInfoId = x.OrganInfoId
}).OrderBy(x=>x.RowIndex).ToListAsync();
var organIds = result.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList();
var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
result.ForEach(x =>
{
if (_userInfo.IsEn_Us)
{
x.Part = organList.Where(y => y.Id == x.OrganInfoId).Select(y => y.PartEN).FirstIsNullReturnEmpty();
}
else
{
x.Part = organList.Where(y => y.Id == x.OrganInfoId).Select(y => y.Part).FirstIsNullReturnEmpty();
}
});
return result;
}
#endregion #endregion
@ -1808,9 +1853,7 @@ namespace IRaCIS.Application.Services
public async Task<SubmitTableQuestionOutDto> SubmitTableQuestion(SubmitTableQuestionInDto inDto) public async Task<SubmitTableQuestionOutDto> SubmitTableQuestion(SubmitTableQuestionInDto inDto)
{ {
SubmitTableQuestionOutDto result = new SubmitTableQuestionOutDto(); SubmitTableQuestionOutDto result = new SubmitTableQuestionOutDto();
await VerifyTaskIsSign(inDto.VisitTaskId); await VerifyTaskIsSign(inDto.VisitTaskId);
if (inDto.InstanceId != null && inDto.IsDicomReading) if (inDto.InstanceId != null && inDto.IsDicomReading)
{ {
if (!(await _dicomInstanceRepository.AnyAsync(x => x.Id == inDto.InstanceId && x.SeriesId == inDto.SeriesId))) if (!(await _dicomInstanceRepository.AnyAsync(x => x.Id == inDto.InstanceId && x.SeriesId == inDto.SeriesId)))
@ -1968,24 +2011,20 @@ namespace IRaCIS.Application.Services
break; break;
} }
var questionInfo = await _readingQuestionTrialRepository.Where(x => x.Id == inDto.QuestionId).FirstNotNullAsync(); var questionInfo = await _readingQuestionTrialRepository.Where(x => x.Id == inDto.QuestionId).FirstNotNullAsync();
var criterionId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.TrialReadingCriterionId).FirstOrDefaultAsync(); var criterionId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.TrialReadingCriterionId).FirstOrDefaultAsync();
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == criterionId).FirstNotNullAsync(); var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == criterionId).FirstNotNullAsync();
var tableQuestionIds = inDto.AnswerList.Select(x => x.TableQuestionId).ToList(); var tableQuestionIds = inDto.AnswerList.Select(x => x.TableQuestionId).ToList();
var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == inDto.RowId).ToListAsync(); var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == inDto.RowId).ToListAsync();
var tableQuestionIdGroup = tableQuestionIds.GroupBy(x => new { TableQuestionId = x }).Select(x => new TableQuestionData var tableQuestionIdGroup = tableQuestionIds.GroupBy(x => new { TableQuestionId = x }).Select(x => new TableQuestionData
{ {
TableQuestionId = x.Key.TableQuestionId, TableQuestionId = x.Key.TableQuestionId,
Count = x.Count() Count = x.Count()
}).ToList(); }).ToList();
if (tableQuestionIdGroup.Any(x => x.Count > 1)) if (tableQuestionIdGroup.Any(x => x.Count > 1))
{ {
throw new BusinessValidationFailedException(_localizer["ReadingImage_Twice"]); throw new BusinessValidationFailedException(_localizer["ReadingImage_Twice"]);
} }
if (inDto.RowIndex % 1 == 0) if (inDto.RowIndex % 1 == 0)
{ {
@ -2105,15 +2144,11 @@ namespace IRaCIS.Application.Services
{ {
isCurrentTaskAdd = isCurrentTaskAddList[0]; isCurrentTaskAdd = isCurrentTaskAddList[0];
} }
ReadingTableAnswerRowInfo? rowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == (inDto.RowId ?? default(Guid))).IgnoreAutoIncludes().FirstOrDefaultAsync(); ReadingTableAnswerRowInfo? rowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == (inDto.RowId ?? default(Guid))).IgnoreAutoIncludes().FirstOrDefaultAsync();
rowInfo = rowInfo == null ? new ReadingTableAnswerRowInfo() : rowInfo; rowInfo = rowInfo == null ? new ReadingTableAnswerRowInfo() : rowInfo;
//await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.RowId == (inDto.RowId ?? default(Guid))); //await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.RowId == (inDto.RowId ?? default(Guid)));
//await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.Id == (inDto.RowId ?? default(Guid))); //await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.Id == (inDto.RowId ?? default(Guid)));
_mapper.Map(inDto, rowInfo); _mapper.Map(inDto, rowInfo);
rowInfo.Id = inDto.RowId == null ? NewId.NextGuid() : inDto.RowId.Value; rowInfo.Id = inDto.RowId == null ? NewId.NextGuid() : inDto.RowId.Value;
result.RowId = rowInfo.Id; result.RowId = rowInfo.Id;
@ -2145,7 +2180,6 @@ namespace IRaCIS.Application.Services
await _readingTableQuestionAnswerRepository.AddRangeAsync(answerList); await _readingTableQuestionAnswerRepository.AddRangeAsync(answerList);
} }
else else
{ {
await _readingTableAnswerRowInfoRepository.UpdateFromDTOAsync(inDto) ; await _readingTableAnswerRowInfoRepository.UpdateFromDTOAsync(inDto) ;
@ -2180,7 +2214,6 @@ namespace IRaCIS.Application.Services
} }
await _readingTableAnswerRowInfoRepository.SaveChangesAsync(); await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto() await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{ {
@ -2189,8 +2222,21 @@ namespace IRaCIS.Application.Services
ComputationTrigger = ComputationTrigger.Lesion, ComputationTrigger = ComputationTrigger.Lesion,
}); });
// 保存完了计算疾病进展
switch (taskinfo.TrialReadingCriterion.CriterionType)
{
case CriterionType.Lugano2014:
if (inDto.RowIndex % 1 != 0)
{
await _luganoCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto()
{
QuestionId = inDto.QuestionId,
VisitTaskId = inDto.VisitTaskId,
RowNumber = inDto.RowIndex
});
}
break;
}
return result; return result;
} }

View File

@ -0,0 +1,19 @@
using IRaCIS.Core.Application.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Application.Service.ReadingCalculate.Interface
{
public interface ILuganoCalculateService
{
/// <summary>
/// 计算靶病灶状态
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
Task CalculateTargetLesionStatus(CalculateTargetLesionStatusInDto inDto);
}
}

View File

@ -14,12 +14,14 @@ using System.Reflection.Metadata.Ecma335;
using System.Linq; using System.Linq;
using NPOI.SS.Formula.Functions; using NPOI.SS.Formula.Functions;
using DocumentFormat.OpenXml.Drawing.Charts; using DocumentFormat.OpenXml.Drawing.Charts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
namespace IRaCIS.Core.Application.Service.ReadingCalculate namespace IRaCIS.Core.Application.Service.ReadingCalculate
{ {
[ApiExplorerSettings(GroupName = "Reading")] [ApiExplorerSettings(GroupName = "Reading")]
public class LuganoCalculateService : BaseService, ICriterionCalculateService public class LuganoCalculateService : BaseService, ICriterionCalculateService, ILuganoCalculateService
{ {
private readonly IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository; private readonly IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository;
private readonly IRepository<VisitTask> _visitTaskRepository; private readonly IRepository<VisitTask> _visitTaskRepository;
@ -1096,6 +1098,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
tableRowAnswers.ForEach(x => tableRowAnswers.ForEach(x =>
{ {
x.SplitOrMergeType = x.SplitOrMergeType==SplitOrMergeType.Merge|| x.SplitOrMergeType == SplitOrMergeType.Merged? SplitOrMergeType.Merged : null;
x.VisitTaskId = visitTaskId; x.VisitTaskId = visitTaskId;
x.IsCurrentTaskAdd = false; x.IsCurrentTaskAdd = false;
x.Id = NewId.NextGuid(); x.Id = NewId.NextGuid();
@ -1103,6 +1106,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
x.InstanceId = null; x.InstanceId = null;
x.MeasureData = string.Empty; x.MeasureData = string.Empty;
x.PicturePath = string.Empty; x.PicturePath = string.Empty;
}); });
tableRowAnswers.ForEach(x => tableRowAnswers.ForEach(x =>
@ -1168,7 +1173,13 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
}); });
} }
var tableAnswers = copyTableAnswers.Select(x => new ReadingTableQuestionAnswer var tableAnswers = new List<ReadingTableQuestionAnswer>();
// 处理状态
var mergedRowIds = tableRowAnswers.Where(x => x.SplitOrMergeType == SplitOrMergeType.Merged).Select(x => x.Id).ToList();
copyTableAnswers.ForEach(x =>
{
var tableAnswer = new ReadingTableQuestionAnswer()
{ {
Id = NewId.NextGuid(), Id = NewId.NextGuid(),
Answer = needCopyMarks.Contains(x.QuestionMark) ? x.Answer : string.Empty, Answer = needCopyMarks.Contains(x.QuestionMark) ? x.Answer : string.Empty,
@ -1178,8 +1189,14 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
TableQuestionId = x.TableQuestionId, TableQuestionId = x.TableQuestionId,
TrialId = x.TrialId, TrialId = x.TrialId,
VisitTaskId = visitTaskId, VisitTaskId = visitTaskId,
}); };
if (mergedRowIds.Contains(tableAnswer.RowId) && x.QuestionMark == QuestionMark.State)
{
tableAnswer.Answer = TargetState.Loss.GetEnumInt();
}
tableAnswers.Add(tableAnswer);
});
var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == LastVisitTaskId).Select(x => new ReadingTaskQuestionMark() var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == LastVisitTaskId).Select(x => new ReadingTaskQuestionMark()
{ {

View File

@ -230,8 +230,12 @@ namespace IRaCIS.Application.Contracts
public DateTime? DeletedTime { get; set; } public DateTime? DeletedTime { get; set; }
public DateTime? EnabledTime { get; set; }
public DateTime UpdateTime { get; set; } public DateTime UpdateTime { get; set; }
public DateTime CreateTime { get; set; }
public string Site { get; set; } = String.Empty; public string Site { get; set; } = String.Empty;
public string SiteCode { get; set; } = String.Empty; public string SiteCode { get; set; } = String.Empty;

View File

@ -278,6 +278,16 @@ namespace IRaCIS.Core.Application.Services
_mapper.Map(editTrialSiteCommand, dbEntity); _mapper.Map(editTrialSiteCommand, dbEntity);
if (editTrialSiteCommand.IsDeleted)
{
dbEntity.EnabledTime = null;
}
else
{
dbEntity.EnabledTime = DateTime.Now;
}
await _trialSiteRepository.SaveChangesAsync(); await _trialSiteRepository.SaveChangesAsync();
return ResponseOutput.Ok(); return ResponseOutput.Ok();

View File

@ -644,7 +644,7 @@ namespace IRaCIS.Core.Domain.Share
Split = 0, Split = 0,
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
Merge = 1, Merge = 1,
@ -653,6 +653,10 @@ namespace IRaCIS.Core.Domain.Share
/// </summary> /// </summary>
SplitMain = 2, SplitMain = 2,
/// <summary>
/// 融合过 再之前任务融合了
/// </summary>
Merged=3,
} }
/// <summary> /// <summary>

View File

@ -207,6 +207,29 @@ namespace IRaCIS.Core.Domain.Models
/// </summary> /// </summary>
public string MarkTool { get; set; } = string.Empty; public string MarkTool { get; set; } = string.Empty;
/// <summary>
/// 融向的病灶
/// </summary>
public string MeltingInToLesion { get; set; } = "[]";
/// <summary>
/// 融向病灶的名称
/// </summary>
public string MeltingInToLesionMarks { get; set; } = string.Empty;
public List<Guid> MeltingInToLesionList { get {
try
{
return JsonConvert.DeserializeObject<List<Guid>>(this.MeltingInToLesion);
}
catch (Exception)
{
return new List<Guid>();
}
} }
[JsonIgnore] [JsonIgnore]
[ForeignKey("VisitTaskId")] [ForeignKey("VisitTaskId")]

View File

@ -22,6 +22,7 @@ namespace IRaCIS.Core.Domain.Models
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
public DateTime? DeletedTime { get; set; } public DateTime? DeletedTime { get; set; }
public DateTime? EnabledTime { get; set; }
public Guid? DeleteUserId { get; set; } public Guid? DeleteUserId { get; set; }