diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index 9c63cd9b1..5513be6f7 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -71,7 +71,7 @@ "CompanyShortName": "Extensive Imaging", "CompanyShortNameCN": "展影医疗", "IsEnv_US": false, - "IsOpenErrorNoticeEmail": true, + "IsOpenErrorNoticeEmail": false, "ErrorNoticeEmailList": [ "872297557@qq.com" ] }, "SystemPacsConfig": { diff --git a/IRaCIS.Core.Application/Helper/FileDocProcess/ExcelExportHelper.cs b/IRaCIS.Core.Application/Helper/FileDocProcess/ExcelExportHelper.cs index b97c0e8b4..48700c78c 100644 --- a/IRaCIS.Core.Application/Helper/FileDocProcess/ExcelExportHelper.cs +++ b/IRaCIS.Core.Application/Helper/FileDocProcess/ExcelExportHelper.cs @@ -64,7 +64,7 @@ public static class ExcelExportHelper foreach (var key in dic.Keys) { //是数组 那么找到对应的属性 进行翻译 - if (dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>))) + if (dic[key]!=null && dic[key].GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>))) { var newObjList = new List(); @@ -74,15 +74,15 @@ public static class ExcelExportHelper { var itemDic = item.ConvertToDictionary(); - //处理集合里面时间类型,根据当前语言将时间转变为字符串 - foreach (var itemValuePair in itemDic) - { - // 临床数据 1,1 会变成2024-01-01 - if (itemValuePair.Value?.ToString().Length > 4 && DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result)) - { - itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result); - } - } + ////处理集合里面时间类型,根据当前语言将时间转变为字符串 + //foreach (var itemValuePair in itemDic) + //{ + // // 临床数据 1,1 会变成2024-01-01 + // if (itemValuePair.Value?.ToString().Length > 8 && DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result)) + // { + // itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result); + // } + //} foreach (var needTranslateProperty in needTranslatePropertyList) @@ -166,7 +166,7 @@ public static class ExcelExportHelper } //中文替换项目术语 - if (data.TrialObjectNameList.Count > 0) + if (data.TrialObjectNameList?.Count > 0) { var replaceObjectList = data.TrialObjectNameList; @@ -335,14 +335,14 @@ public static class ExcelExportHelper //var itemDic = JsonConvert.DeserializeObject>(item.ToJsonNotIgnoreNull()); var itemDic = item.ConvertToDictionary(); - //处理集合里面时间类型,根据当前语言将时间转变为字符串 - foreach (var itemValuePair in itemDic) - { - if (itemValuePair.Value?.ToString().Length > 4 && DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result)) - { - itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result); - } - } + ////处理集合里面时间类型,根据当前语言将时间转变为字符串 + //foreach (var itemValuePair in itemDic) + //{ + // if (itemValuePair.Value?.ToString().Length > 8 && DateTime.TryParse(itemValuePair.Value?.ToString(), out DateTime result)) + // { + // itemDic[itemValuePair.Key] = ExportExcelConverterDate.DateTimeInternationalToString(result); + // } + //} foreach (var needTranslateProperty in needTranslatePropertyList) { diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 5f91adc12..c9bfa490c 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -933,7 +933,7 @@ - + 裁判一致率导出 diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 4e48f05b5..2a35844f8 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -8,6 +8,7 @@ using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore.Common; +using IRaCIS.Core.Infra.EFCore.Migrations; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; @@ -2347,6 +2348,7 @@ namespace IRaCIS.Core.Application.Service.Common public async Task GetCommonJudgeRatioList_Export(VisitTaskQuery inQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService, + [FromServices] IRepository _subjectUserRepository, [FromServices] IRepository _trialRepository) { //每次查询必须是单标准的 @@ -2425,39 +2427,164 @@ namespace IRaCIS.Core.Application.Service.Common .Where(g => g.Count() == 2).Any()) .Count(); - //最后一个已完成的全局 没产生裁判 (之前有裁判),不算入裁判量 - exportInfo.judgeSubjectCount = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) - .Where(t => t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) + #region 废弃 + ////最后一个已完成的全局 没产生裁判 (之前有裁判),不算入裁判量 + //exportInfo.judgeSubjectCount = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) + // .Where(t => t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) + // .Where(t => t.Subject.ReadModuleList.Any(c => c.SubjectVisit.VisitNum == (t.VisitTaskNum - addReadingPeriodNum) && c.TrialReadingCriterionId == trialReadingCriterionId)) + // .GroupBy(t => new { t.SubjectId, t.VisitTaskNum }) + // .Where(g => g.Count() == 2 ) + // .Any(g => g.Any(t => t.JudgeVisitTaskId != null))) + // .Count(); + + //exportInfo.judgeSubjectCount = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) + // .Where(t => t.SubjectVisitTaskList.AsQueryable().Where(comonTaskFilter).Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) + // .Where(t => t.Subject.ReadModuleList.Any(c => c.SubjectVisit.VisitNum == (t.VisitTaskNum - addReadingPeriodNum) && c.TrialReadingCriterionId == trialReadingCriterionId)) + // .GroupBy(t => new { t.SubjectId, t.VisitTaskNum }) + // .Where(g => g.Count() == 2) + // .Any(g => g.OrderByDescending(c => c.VisitTaskNum).FirstOrDefault().JudgeVisitTaskId != null) + // ) + // .Count(); + + //exportInfo.DoctorSubjectStatList = _visitTaskRepository.Where(comonTaskFilter).Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) + // //筛选全局 已完成的任务 + // .Where(t => t.Subject.ReadModuleList.Any(c => c.SubjectVisit.VisitNum == (t.VisitTaskNum - addReadingPeriodNum) && c.TrialReadingCriterionId == trialReadingCriterionId)) + // .GroupBy(t => new { t.DoctorUserId, t.DoctorUser.UserName, t.DoctorUser.FullName }) + // .Select(g => new DoctorJudgeRatio() + // { + // DoctorUserId = g.Key.DoctorUserId, + // UserName = g.Key.UserName, + // FullName = g.Key.FullName, + + // //最后一个阅片期触发裁判 且裁判已阅 + // TotalJudgeCount = g.Where(t => t.JudgeVisitTaskId != null && t.JudgeVisitTask.ReadingTaskState == ReadingTaskState.HaveSigned) + // .Where(t => t.VisitTaskNum == g.Where(c => c.SubjectId == t.SubjectId && c.JudgeVisitTaskId != null && c.JudgeVisitTask.ReadingTaskState == ReadingTaskState.HaveSigned) + // .Max(t => t.VisitTaskNum)) + // .Select(t => t.SubjectId).Distinct().Count(), + + // // G-2 G-4 可能选择的是不同的医生,要以最后一次选择的为准 + // JudgeAgreeCount = g.Where(t => t.JudgeVisitTaskId != null && t.JudgeVisitTask.ReadingTaskState == ReadingTaskState.HaveSigned) + // .Where(t => t.VisitTaskNum == g.Where(c => c.SubjectId == t.SubjectId && c.JudgeVisitTaskId != null && c.JudgeVisitTask.ReadingTaskState == ReadingTaskState.HaveSigned) + // .Max(t => t.VisitTaskNum)) + // .Where(t => t.JudgeVisitTask.JudgeResultTaskId == t.Id) + // .Select(t => t.SubjectId).Distinct().Count(), + + // }).ToList(); + #endregion + + // subject(G1 产生裁判 G2 不产生裁判 那么该患者不计入总量) + var subjectReadingPeriodList = _visitTaskRepository.Where(comonTaskFilter).Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) + .Where(t => t.Subject.ReadModuleList.Any(c => c.SubjectVisit.VisitNum == (t.VisitTaskNum - addReadingPeriodNum) && c.TrialReadingCriterionId == trialReadingCriterionId)) + .GroupBy(t => new { t.SubjectId, t.VisitTaskNum, t.JudgeVisitTaskId }) + .Where(g => g.Count() == 2) + .Select(g => new { g.Key.SubjectId, g.Key.VisitTaskNum, g.Key.JudgeVisitTaskId }) + .ToList(); + + exportInfo.judgeSubjectCount = subjectReadingPeriodList.GroupBy(x => x.SubjectId) // 按 SubjectId 分组 + .Select(g => g.OrderByDescending(x => x.VisitTaskNum).First()) // 每组取 VisitTaskNum 最大的记录 + .Where(t => t.JudgeVisitTaskId != null) + .Count(); + + var subjectReadingPeriodDoctorList = _visitTaskRepository.Where(comonTaskFilter).Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) .Where(t => t.Subject.ReadModuleList.Any(c => c.SubjectVisit.VisitNum == (t.VisitTaskNum - addReadingPeriodNum) && c.TrialReadingCriterionId == trialReadingCriterionId)) .GroupBy(t => new { t.SubjectId, t.VisitTaskNum }) - .Where(g => g.Count() == 2 && g.Key.VisitTaskNum == g.Max(t => t.VisitTaskNum)) - .Any(g => g.Any(t => t.JudgeVisitTaskId != null))) - .Count(); - - exportInfo.DoctorSubjectStatList = _visitTaskRepository.Where(comonTaskFilter).Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned) - //筛选全局 已完成的任务 - .Where(t => t.Subject.ReadModuleList.Any(c => c.SubjectVisit.VisitNum == (t.VisitTaskNum - addReadingPeriodNum) && c.TrialReadingCriterionId == trialReadingCriterionId)) - .GroupBy(t => new { t.DoctorUserId, t.DoctorUser.UserName, t.DoctorUser.FullName }) - .Select(g => new DoctorJudgeRatio() + .Where(g => g.Count() == 2) + .Select(g => new { - DoctorUserId = g.Key.DoctorUserId, - UserName = g.Key.UserName, - FullName = g.Key.FullName, + g.Key.SubjectId, + g.Key.VisitTaskNum, - //最后一个阅片期触发裁判 且裁判已阅 - TotalJudgeCount = g.Where(t => t.JudgeVisitTaskId != null && t.JudgeVisitTask.ReadingTaskState == ReadingTaskState.HaveSigned) - .Where(t => t.VisitTaskNum == g.Where(c => c.SubjectId == t.SubjectId && c.JudgeVisitTaskId != null && c.JudgeVisitTask.ReadingTaskState == ReadingTaskState.HaveSigned) - .Max(t => t.VisitTaskNum)) - .Select(t => t.SubjectId).Distinct().Count(), + GlobalList = g.Select(t => new + { + t.Id, + t.VisitTaskNum, + t.DoctorUserId, + t.DoctorUser.UserName, + t.DoctorUser.FullName, + t.JudgeVisitTaskId, + t.ReadingTaskState, + t.JudgeVisitTask.JudgeResultTaskId, + JudgeTaskState = (ReadingTaskState?)t.JudgeVisitTask.ReadingTaskState + }).ToList() + }) + .ToList(); - // G-2 G-4 可能选择的是不同的医生,要以最后一次选择的为准 - JudgeAgreeCount = g.Where(t => t.JudgeVisitTaskId != null && t.JudgeVisitTask.ReadingTaskState == ReadingTaskState.HaveSigned) - .Where(t => t.VisitTaskNum == g.Where(c => c.SubjectId == t.SubjectId && c.JudgeVisitTaskId != null && c.JudgeVisitTask.ReadingTaskState == ReadingTaskState.HaveSigned) - .Max(t => t.VisitTaskNum)) - .Where(t => t.JudgeVisitTask.JudgeResultTaskId == t.Id) - .Select(t => t.SubjectId).Distinct().Count(), + #region 调试注释 + //var cc = subjectReadingPeriodDoctorList.GroupBy(x => x.SubjectId) // 按 SubjectId 分组 + + // .Where(g => g.OrderByDescending(x => x.VisitTaskNum).First().GlobalList.Any(c => c.JudgeVisitTaskId != null)) + + // .ToList(); + + //var ss = subjectReadingPeriodDoctorList.GroupBy(x => x.SubjectId) // 按 SubjectId 分组 + // //最后一个全局没有产生裁判的subject要过滤掉 过滤后 + // .Where(g => g.OrderByDescending(x => x.VisitTaskNum).First().GlobalList.Any(c => c.JudgeVisitTaskId != null)) + + // .Select(g => g.Where(c => c.GlobalList.Any(k => k.JudgeTaskState == ReadingTaskState.HaveSigned)).OrderByDescending(c => c.VisitTaskNum).FirstOrDefault()) + + // .ToList(); + + + //var kk = subjectReadingPeriodDoctorList.GroupBy(x => x.SubjectId) // 按 SubjectId 分组 + // //最后一个全局没有产生裁判的subject要过滤掉 过滤后 + // .Where(g => g.OrderByDescending(x => x.VisitTaskNum).First().GlobalList.Any(c => c.JudgeVisitTaskId != null)) + // // 存在 已完成的全局裁判 + // .Where(subg => subg.Any(t => t.GlobalList.Any(c => c.JudgeTaskState == ReadingTaskState.HaveSigned))) + // .Select(g => g.Where(c => c.GlobalList.Any(k => k.JudgeTaskState == ReadingTaskState.HaveSigned)).OrderByDescending(c => c.VisitTaskNum).FirstOrDefault()) + + // .ToList(); + #endregion + + + + var filteredList = subjectReadingPeriodDoctorList.GroupBy(x => x.SubjectId) // 按 SubjectId 分组 + //最后一个全局没有产生裁判的subject要过滤掉 过滤后 + .Where(g => g.OrderByDescending(x => x.VisitTaskNum).First().GlobalList.Any(c => c.JudgeVisitTaskId != null)) + // subject 存在 已完成的全局裁判 + .Where(subg => subg.Any(t => t.GlobalList.Any(c => c.JudgeTaskState == ReadingTaskState.HaveSigned))) + //找到最大完成裁判的阅片期 // 每个subject 仅仅留最后一个已完成的全局 + .Select(g => g.Where(c => c.GlobalList.Any(k => k.JudgeTaskState == ReadingTaskState.HaveSigned)).OrderByDescending(c => c.VisitTaskNum).FirstOrDefault()) + .SelectMany(t => t.GlobalList.Select(u => new + { + t.SubjectId, + t.VisitTaskNum, + u.JudgeVisitTaskId, + u.DoctorUserId, + u.UserName, + u.FullName, + u.JudgeResultTaskId, + VisitTaskId = u.Id + })) + .ToList(); + + + + //找到该标准的阅片人 + var armList = new List() { Arm.SingleReadingArm, Arm.DoubleReadingArm1, Arm.DoubleReadingArm2 }; + + exportInfo.DoctorSubjectStatList = _subjectUserRepository.Where(t => t.TrialId == inQuery.TrialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && armList.Contains(t.ArmEnum)) + .Select(t => new DoctorJudgeRatio() + { + DoctorUserId = t.DoctorUserId, + UserName = t.DoctorUser.UserName, + FullName = t.DoctorUser.FullName, + + TotalJudgeCount = 0, + + JudgeAgreeCount = 0 + + }).Distinct().ToList(); + + foreach (var doctor in exportInfo.DoctorSubjectStatList) + { + if (filteredList.Any(t => t.DoctorUserId == doctor.DoctorUserId)) + { + doctor.TotalJudgeCount= filteredList.Where(t=>t.DoctorUserId==doctor.DoctorUserId).Count(); + + doctor.JudgeAgreeCount= filteredList.Where(t => t.DoctorUserId == doctor.DoctorUserId).Count(t => t.JudgeResultTaskId == t.VisitTaskId); + } + } - }).ToList(); #endregion #region 阅片期部分 diff --git a/IRaCIS.Core.Infrastructure/Extention/ExportExcelDateConverter.cs b/IRaCIS.Core.Infrastructure/Extention/ExportExcelDateConverter.cs index 281ececa9..1f1c59326 100644 --- a/IRaCIS.Core.Infrastructure/Extention/ExportExcelDateConverter.cs +++ b/IRaCIS.Core.Infrastructure/Extention/ExportExcelDateConverter.cs @@ -89,17 +89,17 @@ namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson var needDealTime = dateTime.Value; - if (!string.IsNullOrWhiteSpace(clientZoneId)) - { - needDealTime = TimeZoneInfo.ConvertTime(needDealTime, TimeZoneInfo.Local, TimeZoneInfo.FindSystemTimeZoneById(clientZoneId)); - } - if (needDealTime.Hour == 0 && needDealTime.Minute == 0 && needDealTime.Second == 0 && needDealTime.Millisecond==0) { return needDealTime.ToString("yyyy-MM-dd"); } else { + if (!string.IsNullOrWhiteSpace(clientZoneId)) + { + needDealTime = TimeZoneInfo.ConvertTime(needDealTime, TimeZoneInfo.Local, TimeZoneInfo.FindSystemTimeZoneById(clientZoneId)); + } + if (isEn_US) { //暂时保持一致,等需求确认,修改英文要展示的日期格式 diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/ObjectExtension.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/ObjectExtension.cs index 0e08f7634..56be0b871 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/ObjectExtension.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/ObjectExtension.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Reflection; @@ -8,29 +9,29 @@ namespace IRaCIS.Core.Infrastructure.Extention public static class ObjectExtension { - public static T Clone(this T source) - { - // Don't serialize a null object, simply return the default for that object - if (Object.ReferenceEquals(source, null)) - { - return default(T); - } + public static T Clone(this T source) + { + // Don't serialize a null object, simply return the default for that object + if (Object.ReferenceEquals(source, null)) + { + return default(T); + } - var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace }; - var serializeSettings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; - return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source, serializeSettings), deserializeSettings); - } + var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace }; + var serializeSettings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; + return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source, serializeSettings), deserializeSettings); + } - /// - /// 将对象序列化成稽查需要的Json字符串 - /// - /// - /// - public static string ToJsonStr(this object obj) - { - - return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss", ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Ignore }); - } + /// + /// 将对象序列化成稽查需要的Json字符串 + /// + /// + /// + public static string ToJsonStr(this object obj) + { + + return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss", ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Ignore }); + } /// /// 通过类型参数反序列化 JSON 字符串为指定类型的对象 @@ -55,12 +56,12 @@ namespace IRaCIS.Core.Infrastructure.Extention /// /// public static string ToJsonNotIgnoreNull(this object obj) - { + { - return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss", Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Include }); - } + return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss", Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Include }); + } - public static Dictionary ConvertToDictionary(this object obj) + public static Dictionary ConvertToDictionary(this object obj) { if (obj == null) { @@ -77,10 +78,19 @@ namespace IRaCIS.Core.Infrastructure.Extention string propertyName = property.Name; object propertyValue = property.GetValue(obj); // 如果属性的类型是枚举,将其值保留为整数 - if (property.PropertyType.IsEnum || (Nullable.GetUnderlyingType(property.PropertyType)?.IsEnum == true && propertyValue!=null) ) + if (property.PropertyType.IsEnum || (Nullable.GetUnderlyingType(property.PropertyType)?.IsEnum == true && propertyValue != null)) { dictionary.Add(propertyName, (int)propertyValue); } + // 检查属性是否是时间类型 + else if (property.PropertyType == typeof(DateTime) || + property.PropertyType == typeof(DateTime?) && propertyValue != null) + { + DateTime.TryParse(propertyValue.ToString(), out DateTime result); + var dt = ExportExcelConverterDate.DateTimeInternationalToString(result); + // 如果需要,可以对时间值进行特定的处理 + dictionary.Add(propertyName, dt); + } else { dictionary.Add(propertyName, propertyValue);