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.WebUtilities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using MiniExcelLibs;
@ -235,13 +236,17 @@ namespace IRaCIS.Core.API.Controllers
public IUserInfo _userInfo { get; set; }
private readonly IMediator _mediator;
private readonly IWebHostEnvironment _hostEnvironment;
public IStringLocalizer _localizer { get; set; }
private readonly IWebHostEnvironment _hostEnvironment;
private readonly IRepository _repository;
private readonly IEasyCachingProvider _provider;
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,
IRepository repository)
{
@ -249,8 +254,8 @@ namespace IRaCIS.Core.API.Controllers
_provider = provider;
_hostEnvironment = hostEnvironment;
_mediator = mediator;
_mapper = mapper;
_localizer = localizer;
_mapper = mapper;
_userInfo = userInfo;
_repository = repository;
}
@ -313,7 +318,7 @@ namespace IRaCIS.Core.API.Controllers
string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
{
//---不支持的MediaType
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_UnsupportedMedia"));
return ResponseOutput.NotOk(_localizer["UploadDownLoad_UnsupportedMedia"]);
}
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}");
//---请求异常,请重试!
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_RequestError"));
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_RequestError"]);
}
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"))
{
//---支持.xlsx、.xls、.csv格式的文件上传。
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_SupportedFormats"));
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_SupportedFormats"]);
}
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.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();
}
@ -697,7 +702,7 @@ namespace IRaCIS.Core.API.Controllers
if (etcCheckList == null || etcCheckList.Count == 0)
{
//---请保证上传数据符合模板文件中的样式,且存在有效数据。
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData"));
return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
}
else
{
@ -718,7 +723,7 @@ namespace IRaCIS.Core.API.Controllers
if (etcCheckList.Count == 0)
{
//---请保证上传数据符合模板文件中的样式,且存在有效数据。
return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_InvalidData"));
return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
}
}
@ -962,13 +967,14 @@ namespace IRaCIS.Core.API.Controllers
public IMapper _mapper { get; set; }
public IUserInfo _userInfo { get; set; }
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;
_mediator = mediator;
_localizer = localizer;
_mediator = mediator;
_mapper = mapper;
_userInfo = userInfo;
}
@ -994,7 +1000,7 @@ namespace IRaCIS.Core.API.Controllers
if (!realFileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
{
// 请用提供格式的模板excel上传需要处理的数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_TemplateUploadData"));
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_TemplateUploadData"]);
}
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)))
{
//请确保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();
@ -1023,31 +1029,31 @@ namespace IRaCIS.Core.API.Controllers
if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count)
{
//在项目中未找到该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))
{
// 同一邮箱,同一用户类型,只能生成一个账户,请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_CheckDuplicateAccounts"));
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_CheckDuplicateAccounts"]);
}
if (excelList.Any(t => !t.Email.Contains("@")))
{
//有邮箱不符合邮箱格式,请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidEmail"));
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidEmail"]);
}
var generateUserTypeList = new List<string>() { "CRC", "CRA" };
if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper())))
{
//用户类型仅能为 CRC,SR,CRA 请核查Excel数据
throw new BusinessValidationFailedException(StaticData.International("UploadDownLoad_InvalidUserType"));
throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidUserType"]);
}
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();

View File

@ -1310,6 +1310,13 @@
</summary>
<returns></returns>
</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">
<summary>
获取Sod的值
@ -4860,6 +4867,16 @@
序号标记
</summary>
</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">
<summary>
任务Id
@ -13413,6 +13430,13 @@
</summary>
<returns></returns>
</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)">
<summary>
保存影像质量

View File

@ -451,7 +451,8 @@ namespace IRaCIS.Core.Application.Image.QA
//.WhereIf(visitSearchDTO.ChallengeState != null, t => t.ChallengeState == visitSearchDTO.ChallengeState)
.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);

View File

@ -297,18 +297,50 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public List<CrterionDictionaryGroup> CrterionDictionaryGroup { get; set; }
}
public class MergeLesionInDto
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 Guid VisitTaskId { get; set; }
public Guid QuestionId { get; set; }
public Guid MainRowId { get; set; }
/// <summary>
/// 融合的病灶
/// </summary>
public Guid MergeRowId { get; set; }
/// <summary>
/// 融向的病灶
/// </summary>
public List<Guid> MeltingInToLesionList { get; set; }
}
///// <summary>
///// 融合后病灶状态
///// </summary>
//public string LesionState { get; set; }
}
public class SplitLesionInDto
{
@ -986,7 +1018,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
public int? OtherNumberOfFrames { get; set; }
}
public SplitOrMergeType? SplitOrMergeType { get; set; }
}
public class GetTableAnswerRowInfoInDto
{

View File

@ -17,6 +17,7 @@ using IRaCIS.Core.Application.Filter;
using DocumentFormat.OpenXml.Drawing;
using EasyCaching.Core;
using DocumentFormat.OpenXml.Drawing.Charts;
using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
namespace IRaCIS.Application.Services
{
@ -48,7 +49,8 @@ namespace IRaCIS.Application.Services
private readonly IRepository<TrialDocument> _trialDocumentRepository;
private readonly IRepository<User> _userRepository;
private readonly IEasyCachingProvider _provider;
private readonly IRepository<ReadingCustomTag> _readingCustomTagRepository;
private readonly ILuganoCalculateService _luganoCalculateService;
private readonly IRepository<ReadingCustomTag> _readingCustomTagRepository;
private readonly IRepository<ReadingTaskQuestionMark> _readingTaskQuestionMarkRepository;
private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository;
private readonly IRepository<ReadingTrialCriterionDictionary> _readingTrialCriterionDictionaryRepository;
@ -88,7 +90,8 @@ namespace IRaCIS.Application.Services
IRepository<TrialDocument> trialDocumentRepository,
IRepository<User> userRepository,
IEasyCachingProvider provider,
IRepository<ReadingCustomTag> readingCustomTagRepository,
ILuganoCalculateService luganoCalculateService,
IRepository<ReadingCustomTag> readingCustomTagRepository,
IRepository<ReadingTaskQuestionMark> readingTaskQuestionMarkRepository,
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository,
@ -126,7 +129,8 @@ namespace IRaCIS.Application.Services
this._trialDocumentRepository = trialDocumentRepository;
this._userRepository = userRepository;
this._provider = provider;
this._readingCustomTagRepository = readingCustomTagRepository;
this._luganoCalculateService = luganoCalculateService;
this._readingCustomTagRepository = readingCustomTagRepository;
this._readingTaskQuestionMarkRepository = readingTaskQuestionMarkRepository;
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
this._tumorAssessmentRepository = tumorAssessmentRepository;
@ -1360,6 +1364,7 @@ namespace IRaCIS.Application.Services
answers.Add("RowIndex", x.ToString());
answers.Add("RowId", rowInfo==null?string.Empty: rowInfo.Id.ToString());
answers.Add("MarkTool", rowInfo.MarkTool);
answers.Add("MeltingInToLesionMarks", rowInfo.MeltingInToLesionMarks);
answers.Add("StudyId", rowInfo.StudyId.ToString());
answers.Add("OrganInfoId", rowInfo.OrganInfoId.ToString());
answers.Add("IsFristAdd", (rowInfo.FristAddTaskId== TaskId).ToString());
@ -1461,69 +1466,109 @@ namespace IRaCIS.Application.Services
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task MergeLesion(MergeLesionInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
await this.VerifyIsBaseLineTask(inDto.VisitTaskId);
await VerifyTaskIsSign(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()
{
Answer = TargetState.Loss.GetEnumInt(),
});
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(inDto.MergeRowId, x => new ReadingTableAnswerRowInfo()
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_NotaTask"]);
}
MeltingInToLesion = JsonConvert.SerializeObject(inDto.MeltingInToLesionList),
MeltingInToLesionMarks = string.Join(',', marks),
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(mergeid, x => new ReadingTableAnswerRowInfo()
{
MergeRowId = minaid,
SplitOrMergeType = SplitOrMergeType.Merge,
});
}) ;
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(mergeid, x => new ReadingTableAnswerRowInfo()
{
MergeRowId = minaid,
SplitOrMergeType = SplitOrMergeType.Merge,
});
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
}
#endregion
#region 访视任务 - Dicom 阅片 提交、修改
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
#region 访视任务 - Dicom 阅片 提交、修改
/// <summary>
/// 保存影像质量
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> SaveImageQuality(ChangeDicomReadingQuestionAnswerInDto inDto)
{
@ -1808,9 +1853,7 @@ namespace IRaCIS.Application.Services
public async Task<SubmitTableQuestionOutDto> SubmitTableQuestion(SubmitTableQuestionInDto inDto)
{
SubmitTableQuestionOutDto result = new SubmitTableQuestionOutDto();
await VerifyTaskIsSign(inDto.VisitTaskId);
if (inDto.InstanceId != null && inDto.IsDicomReading)
{
if (!(await _dicomInstanceRepository.AnyAsync(x => x.Id == inDto.InstanceId && x.SeriesId == inDto.SeriesId)))
@ -1968,24 +2011,20 @@ namespace IRaCIS.Application.Services
break;
}
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 criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == criterionId).FirstNotNullAsync();
var tableQuestionIds = inDto.AnswerList.Select(x => x.TableQuestionId).ToList();
var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == inDto.RowId).ToListAsync();
var tableQuestionIdGroup = tableQuestionIds.GroupBy(x => new { TableQuestionId = x }).Select(x => new TableQuestionData
{
TableQuestionId = x.Key.TableQuestionId,
Count = x.Count()
}).ToList();
if (tableQuestionIdGroup.Any(x => x.Count > 1))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_Twice"]);
}
if (inDto.RowIndex % 1 == 0)
{
@ -2105,15 +2144,11 @@ namespace IRaCIS.Application.Services
{
isCurrentTaskAdd = isCurrentTaskAddList[0];
}
ReadingTableAnswerRowInfo? rowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == (inDto.RowId ?? default(Guid))).IgnoreAutoIncludes().FirstOrDefaultAsync();
rowInfo = rowInfo == null ? new ReadingTableAnswerRowInfo() : rowInfo;
//await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.RowId == (inDto.RowId ?? default(Guid)));
//await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.Id == (inDto.RowId ?? default(Guid)));
_mapper.Map(inDto, rowInfo);
rowInfo.Id = inDto.RowId == null ? NewId.NextGuid() : inDto.RowId.Value;
result.RowId = rowInfo.Id;
@ -2145,7 +2180,6 @@ namespace IRaCIS.Application.Services
await _readingTableQuestionAnswerRepository.AddRangeAsync(answerList);
}
else
{
await _readingTableAnswerRowInfoRepository.UpdateFromDTOAsync(inDto) ;
@ -2180,7 +2214,6 @@ namespace IRaCIS.Application.Services
}
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{
@ -2189,10 +2222,23 @@ namespace IRaCIS.Application.Services
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,13 +14,15 @@ using System.Reflection.Metadata.Ecma335;
using System.Linq;
using NPOI.SS.Formula.Functions;
using DocumentFormat.OpenXml.Drawing.Charts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
[ApiExplorerSettings(GroupName = "Reading")]
public class LuganoCalculateService : BaseService, ICriterionCalculateService
{
public class LuganoCalculateService : BaseService, ICriterionCalculateService, ILuganoCalculateService
{
private readonly IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
@ -1096,6 +1098,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
tableRowAnswers.ForEach(x =>
{
x.SplitOrMergeType = x.SplitOrMergeType==SplitOrMergeType.Merge|| x.SplitOrMergeType == SplitOrMergeType.Merged? SplitOrMergeType.Merged : null;
x.VisitTaskId = visitTaskId;
x.IsCurrentTaskAdd = false;
x.Id = NewId.NextGuid();
@ -1103,7 +1106,9 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate
x.InstanceId = null;
x.MeasureData = string.Empty;
x.PicturePath = string.Empty;
});
});
tableRowAnswers.ForEach(x =>
{
@ -1168,20 +1173,32 @@ 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 =>
{
Id = NewId.NextGuid(),
Answer = needCopyMarks.Contains(x.QuestionMark) ? x.Answer : string.Empty,
QuestionId = x.QuestionId,
RowIndex = x.RowIndex,
RowId = tableRowAnswers.Where(y => y.OriginalId == x.RowId).Select(x => x.Id).FirstOrDefault(),
TableQuestionId = x.TableQuestionId,
TrialId = x.TrialId,
VisitTaskId = visitTaskId,
var tableAnswer = new ReadingTableQuestionAnswer()
{
Id = NewId.NextGuid(),
Answer = needCopyMarks.Contains(x.QuestionMark) ? x.Answer : string.Empty,
QuestionId = x.QuestionId,
RowIndex = x.RowIndex,
RowId = tableRowAnswers.Where(y => y.OriginalId == x.RowId).Select(x => x.Id).FirstOrDefault(),
TableQuestionId = x.TableQuestionId,
TrialId = x.TrialId,
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()
{
VisitTaskId= visitTaskId,
FirstAddTaskId=x.FirstAddTaskId,

View File

@ -230,8 +230,12 @@ namespace IRaCIS.Application.Contracts
public DateTime? DeletedTime { get; set; }
public DateTime? EnabledTime { get; set; }
public DateTime UpdateTime { get; set; }
public DateTime CreateTime { get; set; }
public string Site { 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);
if (editTrialSiteCommand.IsDeleted)
{
dbEntity.EnabledTime = null;
}
else
{
dbEntity.EnabledTime = DateTime.Now;
}
await _trialSiteRepository.SaveChangesAsync();
return ResponseOutput.Ok();

View File

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

View File

@ -207,6 +207,29 @@ namespace IRaCIS.Core.Domain.Models
/// </summary>
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]
[ForeignKey("VisitTaskId")]

View File

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