irc-netcore-api/IRaCIS.Core.Application/Service/Reading/ReadingCalculateService.cs

325 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2022-08-22 09:33:24
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using IRaCIS.Core.Domain.Models;
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
{
/// <summary>
/// 阅片计算
/// </summary>
[NonDynamicWebApi]
[ApiExplorerSettings(GroupName = "Reading")]
public class ReadingCalculateService : BaseService, IReadingCalculateService
{
private readonly IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<TumorAssessment> _tumorAssessmentRepository;
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
public ReadingCalculateService(
IRepository<ReadingTableQuestionAnswer> readingTableQuestionAnswerRepository,
IRepository<VisitTask> visitTaskRepository,
IRepository<TumorAssessment> tumorAssessmentRepository,
IRepository<ReadingTaskQuestionAnswer> ReadingTaskQuestionAnswerRepository
)
{
this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository;
this._visitTaskRepository = visitTaskRepository;
this._tumorAssessmentRepository = tumorAssessmentRepository;
this._readingTaskQuestionAnswerRepository = ReadingTaskQuestionAnswerRepository;
}
#region 获取SOD
/// <summary>
/// 获取SOD
/// </summary>
/// <remarks>
/// 靶病灶径线之和SOD
/// 非淋巴结的长径 和淋巴结的短径
/// </remarks>
/// <returns></returns>
public async Task<decimal> 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 非淋巴结靶病灶长径之和
/// <summary>
/// 非淋巴结靶病灶长径之和
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal> 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
/// <summary>
/// 与基线SOD相比变化量mm
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal> GetSODChange(ReadingCalculateDto inDto)
{
return await GetSODData(inDto) - await GetBaseLineSOD(inDto);
}
#endregion
#region 与整个访视期间最低点相比增加的百分比
/// <summary>
/// 与整个访视期间最低点相比增加的百分比
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal> 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
/// <summary>
/// 与整个访视期间最低点相比增加的值mm
/// </summary>
/// <param name="inDto"></param>
/// <remarks>
/// 要更新之前的
/// </remarks>
/// <returns></returns>
public async Task<decimal> 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 与整个访视期间最低点相比增加的百分比
/// <summary>
/// 与整个访视期间最低点相比增加的百分比
/// </summary>
/// <param name="inDto"></param>
/// <remarks>
/// 要更新之前的
/// </remarks>
/// <returns></returns>
public async Task<decimal> 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 整个访视期间最低点访视名称
/// <summary>
/// 整个访视期间最低点访视名称
/// </summary>
/// <param name="inDto"></param>
/// <remarks>
/// 要更新之前的
/// </remarks>
/// <returns></returns>
public async Task<string> GetLowVisit(ReadingCalculateDto inDto)
{
var decimalAnswerList = await GetVisitTaskAnswerList(inDto);
return decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.VisitName).FirstOrDefault() ?? string.Empty;
}
#endregion
#region 是否存在非淋巴结靶病灶
/// <summary>
/// 是否存在非淋巴结靶病灶
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> 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以上
/// <summary>
/// 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetIsAddFive(ReadingCalculateDto inDto)
{
return string.Empty;
}
#endregion
#region 被评估为NE的单个靶病灶
/// <summary>
/// 被评估为NE的单个靶病灶
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetNETarget(ReadingCalculateDto inDto)
{
var result = inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer == "NE");
return result ? "有" : "无";
}
#endregion
#region 整体肿瘤评估
/// <summary>
/// 整体肿瘤评估
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> 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
/// <summary>
/// 获取基线SOD
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
private async Task<decimal> 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 获取访视任务信息
/// <summary>
/// 获取访视任务信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
private async Task<List<VisitTaskAnswerInfo>> 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
}
}