irc-netcore-api/IRaCIS.Core.Application/Service/ReadingCalculate/General/GeneralCalculateService.cs

909 lines
38 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.

using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MiniExcelLibs;
using MiniSoftware;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using System.Data;
using System.IO;
using System.Reflection;
using System.Text;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
public class GeneralCalculateService(IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository,
IRepository<VisitTask> _visitTaskRepository,
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
ILogger<GeneralCalculateService> _logger,
IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository,
IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
IOptionsMonitor<ObjectStoreServiceOptions> _options,
IRepository<TumorAssessment_RECIST1Point1> _tumorAssessmentRepository,
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
IRepository<InspectionFile> _inspectionFileRepository,
IOSSService _oSSService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IGeneralCalculateService
{
/// <summary>
/// 从上传文件中获取Datatable
/// </summary>
/// <returns></returns>
public async Task<FileToDataTableDto> GetDataTableFromUpload(IFormFile file,string pathCode,Guid trialId)
{
FileToDataTableDto result=new FileToDataTableDto ();
result.DataTable = new DataTable();
var fileFolder = "Upload\\";
if (!Directory.Exists(fileFolder))
{
Directory.CreateDirectory(fileFolder);
}
var fileName = DateTime.Now.ToString("yyyyMMddHHmmss") +
Path.GetExtension(file.FileName);
var filePath = Path.Combine(fileFolder, fileName);
var fileStream = new MemoryStream();
try
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
file.CopyTo(stream);
await stream.CopyToAsync(fileStream);
result.SheetNames= stream.GetSheetNames();
stream.Position = 0;
result.DataTable = stream.QueryAsDataTable(useHeaderRow: false);
}
}
catch (Exception)
{
File.Delete(filePath);
}
try
{
var ossRelativePath = await _oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/"+ pathCode, file.FileName);
await _inspectionFileRepository.AddAsync(new InspectionFile() { FileName = file.FileName, RelativePath = ossRelativePath, TrialId = trialId });
}
catch (Exception)
{
}
File.Delete(filePath);
// 创建一个要删除的行集合
var rowsToRemove = new System.Collections.Generic.List<DataRow>();
// 遍历DataTable的每一行
foreach (DataRow row in result.DataTable.Rows)
{
bool allEmpty = true;
// 遍历每一列,检查值
foreach (var item in row.ItemArray)
{
if (item!=null&&!item.ToString().IsNullOrEmpty())
{
allEmpty = false;
break; // 只要有一个不为空,跳出循环
}
}
// 如果所有列都是空字符串,则添加到待删除的行集合中
if (allEmpty)
{
rowsToRemove.Add(row);
}
}
// 移除标记为待删除的行
foreach (var row in rowsToRemove)
{
result.DataTable.Rows.Remove(row);
}
return result;
}
/// <summary>
/// 添加计算错误日志
/// </summary>
/// <param name="inDto"></param>
/// <param name="lesionName"></param>
/// <param name="lesionType"></param>
/// <returns></returns>
public async Task LogRecord(ReadingCalculateDto inDto, string lesionName, LesionType lesionType)
{
// 这里是记录日志 不需要国际化
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Include(x => x.Trial).FirstNotNullAsync();
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).Include(x => x.DoctorUser).FirstNotNullAsync();
//错误级别日志:项目、标准、受试者、阅片人、任务。输出其它既往新病灶数据:
StringBuilder builder = new StringBuilder();
builder.AppendLine($"");
builder.AppendLine($"【项目】:【{criterionInfo.Trial.TrialCode}】");
builder.AppendLine($"【项目Id】:【{criterionInfo.TrialId}】");
builder.AppendLine($"【标准】:【{criterionInfo.CriterionName}】");
builder.AppendLine($"【标准Id】:【{criterionInfo.Id}】");
builder.AppendLine($"【受试者】:【{taskInfo.Subject.ShortName}】");
builder.AppendLine($"【受试者Id】:【{taskInfo.Subject.Id}】");
builder.AppendLine($"【阅片人】:【{taskInfo.DoctorUser.FirstName}】");
builder.AppendLine($"【阅片人Id】:【{taskInfo.DoctorUser.Id}】");
builder.AppendLine($"【任务】:【{taskInfo.TaskBlindName}】");
builder.AppendLine($"【任务Id】:【{taskInfo.Id}】");
builder.AppendLine($"【病灶类型】:【{lesionName}】");
var lesionInfo = inDto.QuestionInfo.Where(x => x.LesionType == lesionType).FirstOrDefault();
if (lesionInfo != null)
{
lesionInfo.TableRowInfoList.OrderBy(x => x.RowIndex).ForEach(x =>
{
builder.AppendLine(@$"【病灶编号】:【{x.RowIndex.ToString()}】,
【病灶长径】:【{x.TableQuestionList.Where(y => y.QuestionMark == QuestionMark.MajorAxis).Select(y => y.Answer).FirstIsNullReturnEmpty()}】,
【病灶短径】:【{x.TableQuestionList.Where(y => y.QuestionMark == QuestionMark.ShortAxis).Select(y => y.Answer).FirstIsNullReturnEmpty()}】,
【病灶状态】:【{x.TableQuestionList.Where(y => y.QuestionMark == QuestionMark.State).Select(y => y.Answer).FirstIsNullReturnEmpty()}】");
});
}
_logger.LogError(builder.ToString());
}
/// <summary>
/// 获取ReadingCalculateDto
/// </summary>
/// <param name="visitTaskId"></param>
/// <returns></returns>
public async Task<ReadingCalculateDto> GetReadingCalculateDto(Guid visitTaskId)
{
var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTask.TrialReadingCriterionId).FirstNotNullAsync();
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == (visitTask.SourceSubjectVisitId ?? default(Guid))).FirstOrDefaultAsync();
var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == visitTask.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();
var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == visitTaskId).ToListAsync();
var baseLinetaskId = await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == baseLineVisitId && x.TaskState == TaskState.Effect
&& x.TrialReadingCriterionId == visitTask.TrialReadingCriterionId
&& x.ArmEnum == visitTask.ArmEnum).Select(x => x.Id).FirstOrDefaultAsync();
List<QuestionInfo> questionInfos = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == visitTask.TrialReadingCriterionId).Select(x => new QuestionInfo()
{
LesionType = x.LesionType,
QuestionId = x.Id,
QuesionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
OrderMark = x.OrderMark,
QuestionType = x.QuestionType,
ValueType = x.ValueType,
}).ToListAsync();
var questionAnswers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Select(x => new
{
x.ReadingQuestionTrialId,
x.Answer
}).ToListAsync();
var tableQuestion = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Include(x => x.ReadingTableQuestionTrial).Select(x => new TableQuestionInfo()
{
Answer = x.Answer,
AnswerId = x.Id,
QuestionMark = x.ReadingTableQuestionTrial.QuestionMark,
TableQuestionId = x.TableQuestionId,
QuestionId = x.QuestionId,
QuestionType = x.ReadingQuestionTrial.QuestionType,
RowIndex = x.RowIndex,
RowId = x.RowId,
}).ToListAsync();
foreach (var item in questionInfos)
{
item.Answer = questionAnswers.Where(y => y.ReadingQuestionTrialId == item.QuestionId).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
var thisItemRowInfo = rowInfoList.Where(x => x.QuestionId == item.QuestionId).ToList();
var thisItemTableQuestions = tableQuestion.Where(x => x.QuestionId == item.QuestionId).ToList();
item.TableRowInfoList = thisItemRowInfo.Select(x => new TableRowInfo()
{
RowIndex = x.RowIndex,
MeasureData = x.MeasureData,
OtherMeasureData = x.OtherMeasureData,
FristAddTaskNum = x.FristAddTaskNum,
TableQuestionList = tableQuestion.Where(y => y.QuestionId == item.QuestionId && y.RowId == x.Id).ToList(),
}).ToList();
}
ReadingCalculateDto readingData = new ReadingCalculateDto()
{
SubjectId = visitTask.SubjectId,
TaskBlindName = visitTask.TaskBlindName,
IsConvertedTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(x => x.IsConvertedTask).FirstOrDefaultAsync(),
BeforeConvertedTaskId = visitTask.BeforeConvertedTaskId,
VisitTaskId = visitTaskId,
SubjectVisitId = visitTask.SourceSubjectVisitId!.Value,
QuestionInfo = questionInfos,
CriterionId = visitTask.TrialReadingCriterionId,
TrialId = visitTask.TrialId,
IsAnalysisCreate = visitTask.IsAnalysisCreate,
IsSelfAnalysis = visitTask.IsSelfAnalysis,
IsBaseLine = subjectVisit!.IsBaseLine,
DoctorUserId = visitTask.DoctorUserId,
TrialReadingCriterionId = visitTask.TrialReadingCriterionId,
BaseLineTaskId = baseLinetaskId,
ArmEnum = visitTask.ArmEnum,
VisitName = subjectVisit.VisitName,
BlindName = subjectVisit.BlindName,
VisitTaskNum = visitTask.VisitTaskNum,
DigitPlaces = criterionInfo.DigitPlaces ?? 2,
};
return readingData;
}
/// <summary>
/// 添加转化任务病灶信息
/// </summary>
/// <param name="visitTaskId"></param>
/// <param name="beforeConvertedTaskId"></param>
/// <returns></returns>
public async Task AddConvertedTaskFocus(Guid visitTaskId, Guid beforeConvertedTaskId)
{
var originalTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var taskAnswer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == beforeConvertedTaskId && x.ReadingQuestionTrial.QuestionType != QuestionType.AdjustReason && x.ReadingQuestionTrial.Type != "calculation").IgnoreAutoIncludes().AsNoTracking().ToListAsync();
taskAnswer.ForEach(x =>
{
x.VisitTaskId = visitTaskId;
x.Id = NewId.NextGuid();
});
var tableRowAnswers = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == beforeConvertedTaskId).AsNoTracking().ProjectTo<CopyTableAnswerRowInfo>(_mapper.ConfigurationProvider).IgnoreAutoIncludes().ToListAsync();
tableRowAnswers.ForEach(x =>
{
x.VisitTaskId = visitTaskId;
x.IsCurrentTaskAdd = false;
x.FristAddTaskId = x.FristAddTaskId == beforeConvertedTaskId ? visitTaskId : x.FristAddTaskId;
x.Id = NewId.NextGuid();
});
tableRowAnswers.ForEach(x =>
{
x.SplitRowId = tableRowAnswers.Where(y => y.OriginalId == x.SplitRowId).Select(y => y.Id).FirstOrDefault();
x.MergeRowId = tableRowAnswers.Where(y => y.OriginalId == x.MergeRowId).Select(y => y.Id).FirstOrDefault();
});
var tableAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == beforeConvertedTaskId).IgnoreAutoIncludes().AsNoTracking().ToListAsync();
tableAnswer.ForEach(x =>
{
x.Id = NewId.NextGuid();
x.VisitTaskId = visitTaskId;
x.RowId = tableRowAnswers.Where(y => y.OriginalId == x.RowId).Select(x => x.Id).FirstOrDefault();
});
var addrowInfo = _mapper.Map<List<ReadingTableAnswerRowInfo>>(tableRowAnswers);
switch (originalTask.TrialReadingCriterion.CriterionType)
{
case CriterionType.IRECIST1Point1:
//非靶病灶全部数据复制,不可更改。支持如果状态为:显著增大需要自动改为: 显著增大(iUPD)
var stateQuestionId = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == originalTask.TrialReadingCriterionId
&& x.ReadingQuestionTrial.LesionType == LesionType.NonTargetLesions && x.QuestionMark == QuestionMark.State).Select(x => x.Id).FirstOrDefaultAsync();
tableAnswer.ForEach(x =>
{
if (x.TableQuestionId == stateQuestionId && x.Answer.EqEnum(NoTargetState.Increase))
{
x.Answer = NoTargetState.IUPD.GetEnumInt();
}
});
// 新转换为其它既往新病灶: 状态为消失、疑似、无法评估的新病灶自动转换为:其它既往新病灶,且不可以编辑
// 找到新病灶问题
var newLesionQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == originalTask.TrialReadingCriterionId && x.LesionType == LesionType.NewLesions).FirstOrDefaultAsync();
// 找到其他既往新病灶
var otherLesionQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == originalTask.TrialReadingCriterionId && x.LesionType == LesionType.OtherPreviousNewLesion).FirstOrDefaultAsync();
if (newLesionQuestion != null && otherLesionQuestion != null)
{
// 找到表格问题
var newLesionTableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == newLesionQuestion.Id).ToListAsync();
// 找到表格问题
var otherLesionTableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == otherLesionQuestion.Id).ToListAsync();
// 找到病灶状态
var newstateQuestionId = newLesionTableQuestionList.Where(x => x.QuestionMark == QuestionMark.State).Select(x => x.Id).FirstOrDefault();
var stateAnswers = new List<string>() {
NewLesionState.Loss.GetEnumInt(),
NewLesionState.Suspected.GetEnumInt(),
NewLesionState.UnableEvaluate.GetEnumInt()
};
var needRowIds = tableAnswer.Where(x => x.TableQuestionId == newstateQuestionId && stateAnswers.Contains(x.Answer)).Select(x => x.RowId).Distinct().ToList();
var index = 0;
addrowInfo.ForEach(x =>
{
if (needRowIds.Contains(x.Id))
{
index++;
x.RowIndex = index;
x.RowMark = otherLesionQuestion.OrderMark + x.RowIndex.GetLesionMark();
var fristAddTaskId = x.FristAddTaskId.Clone();
x.FromMark = fristAddTaskId == beforeConvertedTaskId ? string.Empty : x.RowMark;
x.FristAddTaskId = fristAddTaskId == beforeConvertedTaskId ? visitTaskId : fristAddTaskId;
x.QuestionId = otherLesionQuestion.Id;
x.OrderMark = otherLesionQuestion.OrderMark;
x.ReportMark = x.RowMark;
}
});
tableAnswer.ForEach(x =>
{
if (needRowIds.Contains(x.RowId))
{
var row = addrowInfo.Where(y => y.Id == x.RowId).FirstOrDefault();
if (row != null)
{
x.RowIndex = row.RowIndex;
}
x.QuestionId = otherLesionQuestion.Id;
var newLesionTableQuestion = newLesionTableQuestionList.Where(y => y.Id == x.TableQuestionId).FirstOrDefault();
if (newLesionTableQuestion != null)
{
x.TableQuestionId = otherLesionTableQuestionList.Where(y => y.QuestionMark == newLesionTableQuestion.QuestionMark).Select(x => x.Id).FirstOrDefault();
}
}
});
}
break;
}
await _readingTaskQuestionAnswerRepository.AddRangeAsync(taskAnswer);
await _readingTableAnswerRowInfoRepository.AddRangeAsync(addrowInfo);
await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswer);
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
}
/// <summary>
/// 获取阅片报告任务List
/// </summary>
/// <param name="visitTaskId"></param>
/// <returns></returns>
public async Task<List<VisitTaskInfo>> GetReadingReportTaskList(Guid visitTaskId)
{
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var isAdditionalQuestionId = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == visitTaskInfo.TrialReadingCriterionId && x.IsAdditional).IgnoreQueryFilters().Select(x => x.Id).ToListAsync();
var taskquery = _visitTaskRepository
.Where(x => (x.SubjectId == visitTaskInfo.SubjectId
&& (x.TaskState == TaskState.Effect || x.TaskState == TaskState.Freeze)
&& x.IsAnalysisCreate == visitTaskInfo.IsAnalysisCreate
&& x.ArmEnum == visitTaskInfo.ArmEnum
&& x.IsSelfAnalysis == visitTaskInfo.IsSelfAnalysis
&& x.VisitTaskNum <= visitTaskInfo.VisitTaskNum
&& x.ArmEnum == visitTaskInfo.ArmEnum
&& x.TrialReadingCriterionId == visitTaskInfo.TrialReadingCriterionId
&& x.ReadingCategory == ReadingCategory.Visit && x.ReadingTaskState == ReadingTaskState.HaveSigned) || x.Id == visitTaskId
);
if (visitTaskInfo.ReadingTaskState == ReadingTaskState.HaveSigned)
{
taskquery = _visitTaskRepository.Where(x => visitTaskInfo.ReportRelatedTaskIdList.Contains(x.Id) || x.Id == visitTaskInfo.Id);
}
if (visitTaskInfo.TrialReadingCriterion.IsReadingTaskViewInOrder != ReadingOrder.InOrder)
{
taskquery = _visitTaskRepository.Where(x => x.Id == visitTaskInfo.Id);
}
var taskInfoList = await taskquery.OrderBy(x => x.VisitTaskNum).Select(x => new VisitTaskInfo()
{
BlindName = x.TaskBlindName,
IsBaseLine = x.SourceSubjectVisit.IsBaseLine,
VisitTaskId = x.Id,
TaskState = x.TaskState,
TaskName = x.TaskName,
LatestScanDate = x.SourceSubjectVisit != null ? x.SourceSubjectVisit.LatestScanDate : null,
VisitTaskNum = x.VisitTaskNum,
IsConvertedTask = x.IsConvertedTask,
BeforeConvertedTaskId = x.BeforeConvertedTaskId,
//CrterionDictionaryGroup = x.CrterionDictionaryGroup,
IsCurrentTask = x.Id == visitTaskId,
}).OrderBy(x => x.VisitTaskNum).ThenByDescending(x => x.TaskState).ToListAsync();
taskInfoList.ForEach(x =>
{
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(x.IsConvertedTask);
});
var taskIds = taskInfoList.Select(x => x.VisitTaskId).ToList();
var isHaveAdditionalTaskIds = await _readingTaskQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId) && isAdditionalQuestionId.Contains(x.ReadingQuestionTrialId)).Select(x => x.VisitTaskId).Distinct().ToListAsync();
taskInfoList.ForEach(x =>
{
x.IsHaveAdditionalQuestion = isHaveAdditionalTaskIds.Contains(x.VisitTaskId);
});
return taskInfoList;
}
/// <summary>
/// 空转为横线
/// </summary>
/// <param name="myDictionary"></param>
/// <returns></returns>
public Dictionary<string, object> StringEmptyTurnedLine(Dictionary<string, object> myDictionary)
{
foreach (var item in myDictionary)
{
if (item.Value == null)
{
myDictionary[item.Key] = "-";
}
else if (item.Value.GetType() == typeof(string))
{
if (item.Value.ToString() == string.Empty || item.Value == null)
{
myDictionary[item.Key] = "-";
};
}
else if (item.Value.GetType() == typeof(List<Dictionary<string, object>>))
{
var value = item.Value;
foreach (var column in value as List<Dictionary<string, object>>)
{
foreach (var item2 in column)
{
if (item2.Value.ToString() == string.Empty || item.Value == null)
{
column[item2.Key] = "-";
};
}
}
myDictionary[item.Key] = value;
}
}
return myDictionary;
}
/// <summary>
/// 获取word图片
/// </summary>
/// <param name="url"></param>
/// <param name="savePath"></param>
/// <param name="width"></param>
/// <returns></returns>
public async Task<MiniWordPicture> GetWordPicture(string url, string savePath, int width)
{
var resultUrl = await this.FileDownSave(url, savePath);
int picWidth = 0;
int picHeight = 0;
using (var bitmap = Image<Rgba32>.Load(resultUrl))
{
// 获取图片的宽度和高度
picWidth = bitmap.Width;
picHeight = bitmap.Height;
}
var height = width * picHeight / picWidth;
return new MiniWordPicture()
{
Path = resultUrl,
Height = height,
Width = width
};
}
/// <summary>
/// 获取word图片
/// </summary>
/// <param name="url"></param>
/// <param name="savePath"></param>
/// <param name="width"></param>
/// <returns></returns>
public async Task<MiniWordPicture> GetWordPicture(string url, string savePath, int width, int height)
{
var resultUrl = await this.FileDownSave(url, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"wwwroot/ReadReoprtTemplate/downLoad"));
return new MiniWordPicture()
{
Path = resultUrl,
Height = height,
Width = width
};
}
/// <summary>
/// 最大宽高
/// </summary>
/// <param name="url"></param>
/// <param name="savePath"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns></returns>
public async Task<MiniWordPicture> GetWordPictureMaxWL(string url, string savePath, int width, int height)
{
var resultUrl = await this.FileDownSave(url, savePath);
int picWidth = 0;
int picHeight = 0;
using (var bitmap = Image<Rgba32>.Load(resultUrl))
{
// 获取图片的宽度和高度
picWidth = bitmap.Width;
picHeight = bitmap.Height;
}
if (picWidth / picHeight > width / height)
{
height = width * picHeight / picWidth;
}
else
{
width = height * picWidth / picHeight;
}
return new MiniWordPicture()
{
Path = resultUrl,
Height = height,
Width = width
};
}
/// <summary>
/// 获取任务问题答案
/// </summary>
/// <param name="answerList">问题答案</param>
/// <param name="dictionList">字典数据</param>
/// <param name="unitDictionary">单位字典</param>
/// <param name="taskId">任务Id</param>
/// <param name="questionType">任务类型</param>
/// <returns></returns>
public string GetTaskanswer(List<ReadingTaskQuestionAnswer>? answerList, List<Dictionary>? dictionList, List<Dictionary>? unitDictionary, Guid taskId, QuestionType questionType)
{
var answerData = answerList.FirstOrDefault(x => x.VisitTaskId == taskId && x.ReadingQuestionTrial.QuestionType == questionType);
if (answerData == null || answerData.Answer == string.Empty)
{
return string.Empty;
}
var answer = string.Empty;
if (answerData.ReadingQuestionTrial.QuestionGenre == TableQuestionType.Dictionary)
{
answer = dictionList.Where(x => x.Code == answerData.ReadingQuestionTrial.DictionaryCode).SelectMany(x => x.ChildList).Where(x => x.Code == answerData.Answer).Select(x => x.ValueCN).FirstIsNullReturnEmpty();
}
else
{
answer = answerData.Answer;
}
if (answer != "NA" && answerData.ReadingQuestionTrial.Unit != null && answerData.ReadingQuestionTrial.Unit != ValueUnit.none)
{
answer += " " + unitDictionary.SelectMany(x => x.ChildList).Where(x => x.Code == ((int)answerData.ReadingQuestionTrial.Unit).ToString()).Select(x => x.ValueCN).FirstIsNullReturnEmpty();
}
if (answer != "NA" && answerData.ReadingQuestionTrial.ValueType == ValueOfType.Percentage)
{
answer += " %";
}
return answer;
}
public void SetPropertyDynamically(object targetObj, string targetPropName, object sourceObj, string prefix)
{
// 1. 解析目标属性名(如"CheckInfoStr"
string basePropName = targetPropName.Replace(prefix, "");
// 2. 获取源对象路径(如"VisitOne.CheckInfoStr"
string sourcePath = $"Visit{prefix}.{basePropName}";
object sourceValue = GetNestedPropertyValue(sourceObj, sourcePath);
// 3. 赋值给目标属性
PropertyInfo targetProp = targetObj.GetType().GetProperty(prefix+targetPropName);
if (targetProp != null && sourceValue != null)
{
targetProp.SetValue(targetObj, sourceValue);
}
}
public object GetNestedPropertyValue(object obj, string path)
{
foreach (string part in path.Split('.'))
{
if (obj == null) return null;
PropertyInfo prop = obj.GetType().GetProperty(part);
if (prop == null) return null;
obj = prop.GetValue(obj);
}
return obj;
}
/// <summary>
/// 获取报告No
/// </summary>
/// <param name="visitTaskInfo"></param>
/// <returns></returns>
public async Task<string> GetReportExportNo(VisitTask visitTaskInfo)
{
if (visitTaskInfo.ReportExportDate != null && visitTaskInfo.ReportExportNum != null)
{
return visitTaskInfo.ReportExportDate.Value.ToString("yyyyMMdd") + visitTaskInfo.ReportExportNum.ToString().PadLeft(4, '0');
}
else
{
DateTime today = DateTime.Today;
var reportExportNum = await _visitTaskRepository.Where(x => x.TrialId == visitTaskInfo.TrialId && x.ReportExportDate != null && x.ReportExportDate.Value.Date == today).MaxAsync(x => x.ReportExportNum);
reportExportNum = reportExportNum == null ? 0 : reportExportNum;
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTaskInfo.Id, x => new VisitTask()
{
ReportExportDate = today,
ReportExportNum = reportExportNum + 1
});
return today.ToString("yyyyMMdd") + (reportExportNum + 1).ToString().PadLeft(4, '0');
}
}
/// <summary>
/// 获取并复制文件流
/// </summary>
/// <param name="outputFilePath"></param>
/// <returns></returns>
public Stream ReadAndReturnStream(string outputFilePath)
{
byte[] data;
using (Stream stream = new FileStream(outputFilePath, FileMode.Open, FileAccess.Read))
{
// 从流中读取数据保存到内存中
using (MemoryStream memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
data = memoryStream.ToArray();
}
}
// 返回内存中的数据作为新的流
return new MemoryStream(data);
}
/// <summary>
/// 下载并保存
/// </summary>
/// <param name="url">网络路径</param>
/// <param name="savePath">保存本地的文件夹</param>
/// <returns><placeholder>A <see cref="Task"/>
public async Task<string> FileDownSave(string url, string savePath)
{
await _oSSService.DownLoadFromOSSAsync(url, savePath);
return savePath;
//try
//{
// HttpClient httpClient = new HttpClient();
// if (!string.IsNullOrWhiteSpace(url))
// {
// string[] strArry = url.Split('/');
// savePath = savePath + "/" + strArry[strArry.Length - 1];
// }
// var t = httpClient.GetByteArrayAsync(url);
// t.Wait();
// Stream responseStream = new MemoryStream(t.Result);
// Stream stream = new FileStream(savePath, FileMode.Create);
// byte[] bArr = new byte[1024];
// int size = responseStream.Read(bArr, 0, bArr.Length);
// while (size > 0)
// {
// stream.Write(bArr, 0, size);
// size = responseStream.Read(bArr, 0, bArr.Length);
// }
// stream.Close();
// responseStream.Close();
// return savePath;
//}
//catch (Exception)
//{
// throw new BusinessValidationFailedException(_localizer["ReadingCalculate_ImageNotExist"]);
//}
}
/// <summary>
/// 获取任务表格问题答案
/// </summary>
/// <param name="tableAnswerList">表格答案</param>
/// <param name="dictionList">字典</param>
/// <param name="unitDictionary">单位字典</param>
/// <param name="taskId">任务Id</param>
/// <param name="lesionType">病灶类型</param>
/// <param name="questionMark">问题标识</param>
/// <param name="rowIndex">索引</param>
/// <returns></returns>
public string GetTaskTableAnswer(List<ReadingTableQuestionAnswer>? tableAnswerList, List<Dictionary>? dictionList, List<Dictionary>? unitDictionary, Guid taskId, LesionType lesionType, QuestionMark questionMark, decimal rowIndex,bool AutoUnit=true)
{
var answerData = tableAnswerList.FirstOrDefault(x => x.VisitTaskId == taskId && x.ReadingQuestionTrial.LesionType == lesionType && x.ReadingTableQuestionTrial.QuestionMark == questionMark && x.RowIndex == rowIndex);
if (answerData == null || answerData.Answer == string.Empty)
{
return string.Empty;
}
var answer = string.Empty;
if (answerData.ReadingTableQuestionTrial.TableQuestionType == TableQuestionType.Dictionary)
{
answer = dictionList.Where(x => x.Code == answerData.ReadingTableQuestionTrial.DictionaryCode).SelectMany(x => x.ChildList).Where(x => x.Code == answerData.Answer).Select(x => x.ValueCN).FirstIsNullReturnEmpty();
}
else
{
answer = answerData.Answer;
}
if (AutoUnit)
{
if (answer != "NA" && answerData.ReadingTableQuestionTrial.Unit != null && answerData.ReadingTableQuestionTrial.Unit != ValueUnit.none)
{
answer += " " + unitDictionary.SelectMany(x => x.ChildList).Where(x => x.Code == ((int)answerData.ReadingTableQuestionTrial.Unit).ToString()).Select(x => x.ValueCN).FirstIsNullReturnEmpty();
}
if (answer != "NA" && answerData.ReadingTableQuestionTrial.ValueType == ValueOfType.Percentage)
{
answer += " %";
}
}
return answer;
}
/// <summary>
/// 获取病灶的图片 rowinfoList要带question的信息
/// </summary>
/// <param name="rowinfoList"></param>
/// <param name="lesionType"></param>
/// <returns></returns>
public async Task<List<Dictionary<string, object>>> GetLesionPic(List<ReadingTableAnswerRowInfo> rowinfoList, LesionType lesionType, Guid DownLoadGuid)
{
var lesionRowinfo = rowinfoList.Where(x => x.PicturePath != string.Empty && x.ReadingQuestionTrial.LesionType == lesionType).OrderBy(x => x.VisitTask.VisitTaskNum).OrderBy(x => x.RowIndex).ToList();
List<Dictionary<string, object>> lesionImage = new List<Dictionary<string, object>>();
var lesionCount = lesionRowinfo.Select(x => x.VisitTask.VisitTaskNum).Distinct().OrderBy(x => x).ToList();
int picNum = 0;
foreach (var num in lesionCount)
{
var picRowinfo = lesionRowinfo.Where(x => x.VisitTask.VisitTaskNum == num).OrderBy(x => x.RowIndex).ToList();
var picCount = picRowinfo.Count();
for (int i = 0; i < Math.Ceiling((double)picCount / 2); i++)
{
lesionImage.Add(new Dictionary<string, object>()
{
{ "ImageOneMark",getPicNum(true)+ picRowinfo[2*i].VisitTask.TaskName+" "+picRowinfo[2*i].RowMark},
{ "ImageOneUrl" ,await GetWordPictureMaxWL(_options.CurrentValue.MinIO.ViewEndpoint+picRowinfo[2*i].PicturePath ,System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@"wwwroot/ReadReoprtTemplate/downLoad/{DownLoadGuid}"),290,390) },
{ "ImageTwoMark",getPicNum(picCount>2*i+1) + (picCount<=2*i+1?string.Empty:picRowinfo[2*i+1].VisitTask.TaskName+" "+picRowinfo[2*i+1].RowMark) },
{ "ImageTwoUrl", picCount<=2*i+1?string.Empty:await GetWordPictureMaxWL(_options.CurrentValue.MinIO.ViewEndpoint+picRowinfo[2*i+1].PicturePath ,System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@"wwwroot/ReadReoprtTemplate/downLoad/{DownLoadGuid}"),290, 390) },
});
}
}
string getPicNum(bool isHavePic)
{
if (isHavePic)
{
picNum += 1;
return $"图{picNum} ";
}
else
{
return string.Empty;
}
}
return lesionImage;
}
}
}