325 lines
10 KiB
C#
325 lines
10 KiB
C#
//--------------------------------------------------------------------
|
||
// 此代码由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
|
||
|
||
}
|
||
}
|