diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
index 4fd242949..cc50e8291 100644
--- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
+++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
@@ -3170,6 +3170,109 @@
阅片计算
+
+
+ 获取SOD
+
+
+ 靶病灶径线之和(SOD)
+ 非淋巴结的长径 和淋巴结的短径
+
+
+
+
+
+ 非淋巴结靶病灶长径之和
+
+
+
+
+
+
+ 与基线SOD相比变化量(mm)
+
+
+
+
+
+
+ 与整个访视期间最低点相比增加的百分比
+
+
+
+
+
+
+ 与整个访视期间最低点相比增加的值(mm)
+
+
+
+ 要更新之前的
+
+
+
+
+
+ 与整个访视期间最低点相比增加的百分比
+
+
+
+ 要更新之前的
+
+
+
+
+
+ 整个访视期间最低点访视名称
+
+
+
+ 要更新之前的
+
+
+
+
+
+ 是否存在非淋巴结靶病灶
+
+
+
+
+
+
+ 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上
+
+
+
+
+
+
+ 被评估为NE的单个靶病灶
+
+
+
+
+
+
+ 整体肿瘤评估
+
+
+
+
+
+
+ 获取基线SOD
+
+
+
+
+
+
+ 获取访视任务信息
+
+
+
+
阅片医学审核
@@ -3789,6 +3892,36 @@
标准 病灶类型
+
+
+ 阅片计算Dto
+
+
+
+
+ 答案
+
+
+
+
+ 病灶类型
+
+
+
+
+ 答案
+
+
+
+
+ 问题Id
+
+
+
+
+ 问题标识
+
+
类型
diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs
index f1d63b2c3..231a57382 100644
--- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs
+++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs
@@ -7,8 +7,85 @@ using System;
using IRaCIS.Core.Domain.Share;
using System.Collections.Generic;
namespace IRaCIS.Core.Application.ViewModel
-{
-
+{
+ ///
+ /// 阅片计算Dto
+ ///
+ public class ReadingCalculateDto
+ {
+
+ public Guid SubjectId { get; set; }
+
+ public Guid VisitTaskId { get; set; }
+
+ public List QuestionInfo { get; set; } = new List();
+
+
+ }
+
+
+
+ public class QuestionInfo
+ {
+
+ public Guid QuestionId { get; set; }
+
+ ///
+ /// 答案
+ ///
+ public string Answer { get; set; }
+
+
+ ///
+ /// 病灶类型
+ ///
+ public LesionType? LesionType { get; set; }
+
+ public QuestionType? QuestionType { get; set; }
+
+
+
+ public List TableRowInfoList = new List();
+
+
+ }
+
+
+ public class TableRowInfo
+ {
+ public int RowIndex { get; set; }
+
+ public List TableQuestionList { get; set; } = new List();
+ }
+
+ public class TableQuestionInfo
+ {
+ ///
+ /// 答案
+ ///
+ public string Answer { get; set; }
+
+ ///
+ /// 问题Id
+ ///
+ public Guid TableQuestionId { get; set; }
+
+
+ ///
+ /// 问题标识
+ ///
+ public QuestionMark? QuestionMark { get; set; }
+
+ }
+
+
+
+ public class VisitTaskAnswerInfo
+ {
+ public string VisitName { get; set; }
+
+ public decimal SOD { get; set; }
+ }
}
diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingCalculateService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingCalculateService.cs
index 7e5304db6..a12cc6b84 100644
--- a/IRaCIS.Core.Application/Service/Reading/ReadingCalculateService.cs
+++ b/IRaCIS.Core.Application/Service/Reading/ReadingCalculateService.cs
@@ -9,23 +9,317 @@ using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using Panda.DynamicWebApi.Attributes;
+using IRaCIS.Core.Domain.Share;
namespace IRaCIS.Core.Application.Service
-{
+{
///
/// 阅片计算
///
[NonDynamicWebApi]
- [ ApiExplorerSettings(GroupName = "Reading")]
+ [ApiExplorerSettings(GroupName = "Reading")]
public class ReadingCalculateService : BaseService, IReadingCalculateService
{
private readonly IRepository _readingTableQuestionAnswerRepository;
+ private readonly IRepository _visitTaskRepository;
+ private readonly IRepository _tumorAssessmentRepository;
+ private readonly IRepository _readingTaskQuestionAnswerRepository;
- public ReadingCalculateService(IRepository readingTableQuestionAnswerRepository)
+ public ReadingCalculateService(
+ IRepository readingTableQuestionAnswerRepository,
+ IRepository visitTaskRepository,
+ IRepository tumorAssessmentRepository,
+ IRepository ReadingTaskQuestionAnswerRepository
+ )
{
- _readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository;
+ this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository;
+ this._visitTaskRepository = visitTaskRepository;
+ this._tumorAssessmentRepository = tumorAssessmentRepository;
+ this._readingTaskQuestionAnswerRepository = ReadingTaskQuestionAnswerRepository;
}
- }
-}
+
+ #region 获取SOD
+
+ ///
+ /// 获取SOD
+ ///
+ ///
+ /// 靶病灶径线之和(SOD)
+ /// 非淋巴结的长径 和淋巴结的短径
+ ///
+ ///
+ public async Task GetSODData(ReadingCalculateDto inDto)
+ {
+ var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
+
+ decimal result = 0;
+
+ foreach (var item in tableQuestion)
+ {
+ if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer == "是"))
+ {
+ // 淋巴结的短径
+ result += decimal.Parse(item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault() ?? "0");
+ }
+
+ if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer == "否"))
+ {
+ // 非淋巴结的长径
+ result += decimal.Parse(item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault() ?? "0");
+ }
+ }
+
+
+ return result;
+
+
+ }
+ #endregion
+
+ #region 非淋巴结靶病灶长径之和
+ ///
+ /// 非淋巴结靶病灶长径之和
+ ///
+ ///
+ ///
+ public async Task GetSumOfDiameter(ReadingCalculateDto inDto)
+ {
+ var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
+
+ decimal result = 0;
+
+ foreach (var item in tableQuestion)
+ {
+ if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer == "否"))
+ {
+ // 非淋巴结的长径
+ result += decimal.Parse(item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault() ?? "0");
+ }
+ }
+
+
+ return result;
+ }
+ #endregion
+
+ #region 与基线SOD相比变化量(mm)
+ ///
+ /// 与基线SOD相比变化量(mm)
+ ///
+ ///
+ ///
+ public async Task GetSODChange(ReadingCalculateDto inDto)
+ {
+ return await GetSODData(inDto) - await GetBaseLineSOD(inDto);
+ }
+ #endregion
+
+ #region 与整个访视期间最低点相比增加的百分比
+ ///
+ /// 与整个访视期间最低点相比增加的百分比
+ ///
+ ///
+ ///
+ public async Task GetSODPercent(ReadingCalculateDto inDto)
+ {
+ var thisSOD = await GetSODData(inDto);
+ var baseLineSOD = await GetBaseLineSOD(inDto);
+
+ if (baseLineSOD == 0)
+ {
+ return 100;
+ }
+ else
+ {
+ return decimal.Round(thisSOD * 100 / baseLineSOD, 2);
+ }
+ }
+ #endregion
+
+ #region 与整个访视期间最低点相比增加的值(mm)
+ ///
+ /// 与整个访视期间最低点相比增加的值(mm)
+ ///
+ ///
+ ///
+ /// 要更新之前的
+ ///
+ ///
+ public async Task GetLowestIncrease(ReadingCalculateDto inDto)
+ {
+ var decimalAnswerList = await GetVisitTaskAnswerList(inDto);
+ var minSOD = decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.SOD).FirstOrDefault();
+ return await GetSODData(inDto) - minSOD;
+ }
+ #endregion
+
+ #region 与整个访视期间最低点相比增加的百分比
+ ///
+ /// 与整个访视期间最低点相比增加的百分比
+ ///
+ ///
+ ///
+ /// 要更新之前的
+ ///
+ ///
+ public async Task GetLowPercent(ReadingCalculateDto inDto)
+ {
+ var thisSOD = await GetSODData(inDto);
+ var decimalAnswerList = await GetVisitTaskAnswerList(inDto);
+ var minSOD = decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.SOD).FirstOrDefault();
+
+ if (minSOD == 0)
+ {
+ return 100;
+ }
+ else
+ {
+ return decimal.Round(thisSOD * 100 / minSOD, 2);
+ }
+
+
+ }
+ #endregion
+
+ #region 整个访视期间最低点访视名称
+ ///
+ /// 整个访视期间最低点访视名称
+ ///
+ ///
+ ///
+ /// 要更新之前的
+ ///
+ ///
+ public async Task GetLowVisit(ReadingCalculateDto inDto)
+ {
+ var decimalAnswerList = await GetVisitTaskAnswerList(inDto);
+ return decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.VisitName).FirstOrDefault() ?? string.Empty;
+ }
+ #endregion
+
+ #region 是否存在非淋巴结靶病灶
+ ///
+ /// 是否存在非淋巴结靶病灶
+ ///
+ ///
+ ///
+ public async Task GetIsLymphTarget(ReadingCalculateDto inDto)
+ {
+ var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
+
+ foreach (var item in tableQuestion)
+ {
+ if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer == "是"))
+ {
+ return "是";
+ }
+ }
+
+ return "否";
+ }
+ #endregion
+
+ #region 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上
+ ///
+ /// 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上
+ ///
+ ///
+ ///
+ public async Task GetIsAddFive(ReadingCalculateDto inDto)
+ {
+ return string.Empty;
+ }
+ #endregion
+
+ #region 被评估为NE的单个靶病灶
+ ///
+ /// 被评估为NE的单个靶病灶
+ ///
+ ///
+ ///
+ public async Task GetNETarget(ReadingCalculateDto inDto)
+ {
+ var result = inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer == "NE");
+
+ return result ? "有" : "无";
+ }
+ #endregion
+
+ #region 整体肿瘤评估
+
+ ///
+ /// 整体肿瘤评估
+ ///
+ ///
+ ///
+ public async Task GetTumor(ReadingCalculateDto inDto)
+ {
+ var targetLesion = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.TargetLesion).Select(x => x.Answer).FirstOrDefault();
+ var noTargetLesion = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NoTargetLesion).Select(x => x.Answer).FirstOrDefault();
+ var newLesions = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesions).Select(x => x.Answer).FirstOrDefault();
+ var result = await _tumorAssessmentRepository.Where(x => x.TargetLesion == targetLesion && x.NonTargetLesions == noTargetLesion && x.NewLesion == newLesions).Select(x => x.OverallEfficacy).FirstOrDefaultAsync();
+
+ return result ?? string.Empty;
+
+ }
+ #endregion
+
+ #region 通用方法
+
+ #region 获取基线SOD
+ ///
+ /// 获取基线SOD
+ ///
+ ///
+ ///
+ private async Task GetBaseLineSOD(ReadingCalculateDto inDto)
+ {
+ if (await _visitTaskRepository.AnyAsync(x => x.Id == inDto.VisitTaskId && x.SourceSubjectVisit.IsBaseLine))
+ {
+ return 0;
+ }
+
+ // 先找到基线的任务
+ var baseLineTaskId = await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingCategory == ReadingCategory.Visit
+ && x.SourceSubjectVisit.IsBaseLine && x.TaskState == TaskState.Effect)
+ .Select(x => x.Id).FirstOrDefaultAsync();
+
+
+ var baseLineSOD = decimal.Parse(await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SOD).Select(x => x.Answer).FirstOrDefaultAsync() ?? "0");
+ return baseLineSOD;
+ }
+ #endregion
+
+ #region 获取访视任务信息
+ ///
+ /// 获取访视任务信息
+ ///
+ ///
+ ///
+ private async Task> GetVisitTaskAnswerList(ReadingCalculateDto inDto)
+ {
+ var answerList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTask.ReadingCategory == ReadingCategory.Visit
+ && x.SubjectId == inDto.SubjectId && x.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned && x.VisitTask.TaskState == TaskState.Effect && x.ReadingQuestionTrial.QuestionType == QuestionType.SOD)
+ .Select(x => new
+ {
+ VisitName = x.VisitTask.SourceSubjectVisit.VisitName,
+ SOD = x.Answer
+ }).ToListAsync();
+
+ var decimalAnswerList = answerList.Select(x => new VisitTaskAnswerInfo
+ {
+ VisitName = x.VisitName,
+ SOD = decimal.Parse(x.SOD ?? "0"),
+ }).ToList();
+
+ return decimalAnswerList;
+ }
+ #endregion
+
+
+ #endregion
+
+ }
+}