Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
commit
655ef79754
|
@ -1,196 +0,0 @@
|
||||||
using IRaCIS.Core.Application.Helper;
|
|
||||||
using IRaCIS.Core.Domain.Share;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
using Microsoft.Extensions.Localization;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using ZiggyCreatures.Caching.Fusion;
|
|
||||||
using static IRaCIS.Core.Domain.Share.StaticData;
|
|
||||||
|
|
||||||
namespace IRaCIS.Core.Application.Filter;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 主要为了 处理项目结束 锁库,不允许操作
|
|
||||||
/// </summary>
|
|
||||||
public class TrialResourceFilter : Attribute, IAsyncResourceFilter
|
|
||||||
{
|
|
||||||
private readonly IUserInfo _userInfo;
|
|
||||||
private readonly IFusionCache _fusionCache;
|
|
||||||
public IStringLocalizer _localizer;
|
|
||||||
private readonly IRepository<Trial> _trialRepository;
|
|
||||||
private readonly List<string> _trialOptList = new List<string>();
|
|
||||||
|
|
||||||
|
|
||||||
public TrialResourceFilter(IFusionCache fusionCache, IRepository<Trial> trialRepository, IStringLocalizer localizer, IUserInfo userInfo, string trialOpt = null, string trialOpt2 = null, string trialOpt3 = null)
|
|
||||||
{
|
|
||||||
_fusionCache = fusionCache;
|
|
||||||
_userInfo = userInfo;
|
|
||||||
_localizer = localizer;
|
|
||||||
_trialRepository = trialRepository;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(trialOpt)) _trialOptList.Add(trialOpt.Trim());
|
|
||||||
if (!string.IsNullOrWhiteSpace(trialOpt2)) _trialOptList.Add(trialOpt2.Trim());
|
|
||||||
if (!string.IsNullOrWhiteSpace(trialOpt3)) _trialOptList.Add(trialOpt3.Trim());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//优先选择异步的方法
|
|
||||||
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
|
|
||||||
{
|
|
||||||
// var typeFilter = context.ActionDescriptor.EndpointMetadata.Where(t => t.GetType() == typeof(TypeFilterAttribute)).Select(t => (TypeFilterAttribute)t).ToList().FirstOrDefault();
|
|
||||||
//var _trialOptList= typeFilter.Arguments.Select(t => t.ToString()).ToList();
|
|
||||||
|
|
||||||
// 获取当前请求的 Host 信息
|
|
||||||
var requestHost = context.HttpContext.Request.Host;
|
|
||||||
|
|
||||||
// 检查请求是否来自 localhost:6100
|
|
||||||
if (requestHost.Host == "localhost" && (requestHost.Port == 6100|| requestHost.Port==3305))
|
|
||||||
{
|
|
||||||
await next.Invoke();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region 处理新的用户类型,不能操作项目相关接口
|
|
||||||
|
|
||||||
// 后期列举出具体的类型,其他任何用户类型,都不允许操作
|
|
||||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower() != "TrialDocument/userConfirm".ToLower())
|
|
||||||
{
|
|
||||||
//---对不起,您的账户没有操作权限。
|
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_NoAccessPermission"]));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TrialId 传递的途径多种,可能在path 可能在body 可能在数组中,也可能在对象中,可能就在url
|
|
||||||
var trialIdStr = string.Empty;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(context.HttpContext.Request.Query["trialId"]))
|
|
||||||
{
|
|
||||||
trialIdStr = context.HttpContext.Request.Query["trialId"];
|
|
||||||
}
|
|
||||||
|
|
||||||
//先尝试从path中取TrialId
|
|
||||||
else if (context.RouteData.Values.Keys.Any(t => t.Contains("trialId")))
|
|
||||||
{
|
|
||||||
var index = context.RouteData.Values.Keys.ToList().IndexOf("trialId");
|
|
||||||
trialIdStr = context.RouteData.Values.Values.ToList()[index] as string;
|
|
||||||
}
|
|
||||||
else if (context.HttpContext.Request.Headers["Referer"].ToString().Contains("trialId"))
|
|
||||||
{
|
|
||||||
var headerStr = context.HttpContext.Request.Headers["Referer"].ToString();
|
|
||||||
|
|
||||||
var trialIdIndex = headerStr.IndexOf("trialId");
|
|
||||||
|
|
||||||
|
|
||||||
var matchResult = Regex.Match(headerStr.Substring(trialIdIndex), @"[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}");
|
|
||||||
|
|
||||||
if (matchResult.Success)
|
|
||||||
{
|
|
||||||
trialIdStr = matchResult.Value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//---正则取请求Refer 中trialId 失败,请联系开发人员核查
|
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#region body 中取数据
|
|
||||||
|
|
||||||
//设置可以多次读
|
|
||||||
context.HttpContext.Request.EnableBuffering();
|
|
||||||
var reader = new StreamReader(context.HttpContext.Request.Body);
|
|
||||||
var contentFromBody = await reader.ReadToEndAsync();
|
|
||||||
//读取后,流的位置还原
|
|
||||||
context.HttpContext.Request.Body.Seek(0, SeekOrigin.Begin);
|
|
||||||
//context.HttpContext.Request.Body.Position = 0;
|
|
||||||
|
|
||||||
//找到参数位置在字符串中的索引
|
|
||||||
var trialIdIndex = contentFromBody.IndexOf("\"TrialId\"", StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
if (trialIdIndex > -1)
|
|
||||||
{
|
|
||||||
// (?<="trialId" *: *").*?(?=",)
|
|
||||||
|
|
||||||
//使用正则 [0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}
|
|
||||||
|
|
||||||
var matchResult = Regex.Match(contentFromBody.Substring(trialIdIndex), @"[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}");
|
|
||||||
|
|
||||||
if (matchResult.Success)
|
|
||||||
{
|
|
||||||
//有可能匹配错误 "trialId":"","documentId":"b8180000-3e2c-0016-9fe0-08da33f96236" 从缓存里面验证下
|
|
||||||
|
|
||||||
trialIdStr = matchResult.Value;
|
|
||||||
|
|
||||||
var trialStatusStr = await _fusionCache.GetOrSetAsync(CacheKeys.Trial(trialIdStr), _ => CacheHelper.GetTrialStatusAsync(Guid.Parse(trialIdStr), _trialRepository), TimeSpan.FromDays(7));
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(trialStatusStr))
|
|
||||||
{
|
|
||||||
|
|
||||||
//数据库 检查该项目Id不对
|
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//---正则取请求Refer 中trialId 失败,请联系开发人员核查
|
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"]));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//使用字符串取 如果是swagger 可能有时取的不对 因为空格的原因
|
|
||||||
//trialIdStr = contentFromBody.Substring(trialIdIndex + "TrialId".Length + 4, 3
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
//通过path 或者body 找到trialId 了
|
|
||||||
if (!string.IsNullOrWhiteSpace(trialIdStr))
|
|
||||||
{
|
|
||||||
var trialStatusStr = await _fusionCache.GetOrSetAsync(CacheKeys.Trial(trialIdStr), _ => CacheHelper.GetTrialStatusAsync(Guid.Parse(trialIdStr), _trialRepository), TimeSpan.FromDays(7));
|
|
||||||
|
|
||||||
// 这里是统一拦截 项目有关的操作允许情况(特殊的地方,比如项目配置(有的在多种状态(初始化,ongoing)都可以操作,有的仅仅在Initializing)还有 项目添加和更新,不走这里,特殊处理,不然在这里显得很乱,判断是哪个接口)
|
|
||||||
if (trialStatusStr == StaticData.TrialState.TrialOngoing || _trialOptList.Any(t => t == TrialOpt.BeforeOngoingCantOpt))
|
|
||||||
{
|
|
||||||
|
|
||||||
await next.Invoke();
|
|
||||||
|
|
||||||
}
|
|
||||||
// 项目停止、或者完成 不允许操作
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//---本次请求被配置规则拦截:项目状态处于进行中时,才允许操作,若此处逻辑有误,请联系开发人员修改
|
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_InterceptedProjectStatusRule"]));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//添加项目 签名系统文档的时候 不做拦截 但是更新项目 签名项目文档的时候需要拦截
|
|
||||||
else if (_trialOptList.Any(t => t == TrialOpt.AddOrUpdateTrial || t == TrialOpt.SignSystemDocNoTrialId))
|
|
||||||
{
|
|
||||||
await next.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//如果项目相关接口没有传递trialId 会来到这里,提醒,以便修改
|
|
||||||
|
|
||||||
//---该接口参数中,没有传递项目编号,请核对。
|
|
||||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_MissingProjectNumber"]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -165,7 +165,7 @@ public static class ExcelExportHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
//中文替换项目术语
|
//中文替换项目术语
|
||||||
if (isEn_US == false)
|
if (isEn_US == false && data.TrialObjectNameList.Count > 0)
|
||||||
{
|
{
|
||||||
var replaceObjectList = data.TrialObjectNameList;
|
var replaceObjectList = data.TrialObjectNameList;
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ public static class ExcelExportHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
//中文替换项目术语
|
//中文替换项目术语
|
||||||
if (isEn_US == false)
|
if (isEn_US == false && data.TrialObjectNameList.Count > 0)
|
||||||
{
|
{
|
||||||
var replaceObjectList = data.TrialObjectNameList;
|
var replaceObjectList = data.TrialObjectNameList;
|
||||||
|
|
||||||
|
@ -526,6 +526,7 @@ public static class ExcelExportHelper
|
||||||
var name = dynamicColumnConfig.ColumnNameList[i - dynamicColunmStartIndex];
|
var name = dynamicColumnConfig.ColumnNameList[i - dynamicColunmStartIndex];
|
||||||
|
|
||||||
titelRow.GetCell(i).SetCellValue(name);
|
titelRow.GetCell(i).SetCellValue(name);
|
||||||
|
templateRow.GetCell(i).SetCellValue("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,7 +539,6 @@ public static class ExcelExportHelper
|
||||||
templateStream = memoryStream2;
|
templateStream = memoryStream2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -13038,11 +13038,6 @@
|
||||||
参考处理链接: https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0
|
参考处理链接: https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:IRaCIS.Core.Application.Filter.TrialResourceFilter">
|
|
||||||
<summary>
|
|
||||||
主要为了 处理项目结束 锁库,不允许操作
|
|
||||||
</summary>
|
|
||||||
</member>
|
|
||||||
<member name="M:IRaCIS.Core.Application.Helper.CacheKeys.UserLoginError(System.String)">
|
<member name="M:IRaCIS.Core.Application.Helper.CacheKeys.UserLoginError(System.String)">
|
||||||
<summary>
|
<summary>
|
||||||
用户登录错误 限制登录
|
用户登录错误 限制登录
|
||||||
|
|
|
@ -1840,8 +1840,11 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||||
|
|
||||||
list.Add(new ExportDocumentDes() { Code = StaticData.Export.CommonReadingDetail_Export, ExportCatogory = ExportResult.DetailedTableOfAssessmentResults });
|
list.Add(new ExportDocumentDes() { Code = StaticData.Export.CommonReadingDetail_Export, ExportCatogory = ExportResult.DetailedTableOfAssessmentResults });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
list.Add(new ExportDocumentDes() { Code = StaticData.Export.CommonJudgeReadingDetail_Export, ExportCatogory = ExportResult.DetailedTableOfAdjudicationResults });
|
list.Add(new ExportDocumentDes() { Code = StaticData.Export.CommonJudgeReadingDetail_Export, ExportCatogory = ExportResult.DetailedTableOfAdjudicationResults });
|
||||||
|
|
||||||
|
|
||||||
if (criterion.CriterionType == CriterionType.RECIST1Point1 || criterion.CriterionType == CriterionType.RECIST1Pointt1_MB
|
if (criterion.CriterionType == CriterionType.RECIST1Point1 || criterion.CriterionType == CriterionType.RECIST1Pointt1_MB
|
||||||
|| criterion.CriterionType == CriterionType.IRECIST1Point1 || criterion.CriterionType == CriterionType.Lugano2014
|
|| criterion.CriterionType == CriterionType.IRECIST1Point1 || criterion.CriterionType == CriterionType.Lugano2014
|
||||||
|| criterion.CriterionType == CriterionType.Lugano2014WithoutPET || criterion.CriterionType == CriterionType.PCWG3)
|
|| criterion.CriterionType == CriterionType.Lugano2014WithoutPET || criterion.CriterionType == CriterionType.PCWG3)
|
||||||
|
@ -1849,6 +1852,10 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||||
list.Add(new ExportDocumentDes() { Code = StaticData.Export.ReadingLession_Export, ExportCatogory = ExportResult.DetailedTableOfLesions });
|
list.Add(new ExportDocumentDes() { Code = StaticData.Export.ReadingLession_Export, ExportCatogory = ExportResult.DetailedTableOfLesions });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (criterion.CriterionType == CriterionType.OCT)
|
||||||
|
{
|
||||||
|
list.Add(new ExportDocumentDes() { Code = StaticData.Export.OCT_ReadingLession_Export, ExportCatogory = ExportResult.OCT_ReadingLession_Export });
|
||||||
|
}
|
||||||
|
|
||||||
switch (criterion.ArbitrationRule)
|
switch (criterion.ArbitrationRule)
|
||||||
{
|
{
|
||||||
|
@ -1966,11 +1973,14 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||||
{
|
{
|
||||||
//病灶明细表
|
//病灶明细表
|
||||||
export_Template = StaticData.Export.ReadingLession_Export;
|
export_Template = StaticData.Export.ReadingLession_Export;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//病灶明细表 需要单独处理
|
//病灶明细表 需要单独处理
|
||||||
if (inQuery.ReadingExportType != ExportResult.DetailedTableOfLesions)
|
if (inQuery.ReadingExportType != ExportResult.DetailedTableOfLesions && inQuery.ReadingExportType != ExportResult.OCT_ReadingLession_Export)
|
||||||
{
|
{
|
||||||
|
//其他可以统一处理
|
||||||
list = await query.ProjectTo<CommonEvaluationExport>(_mapper.ConfigurationProvider,
|
list = await query.ProjectTo<CommonEvaluationExport>(_mapper.ConfigurationProvider,
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
|
@ -1983,7 +1993,12 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//其他可以统一处理
|
//病灶明细表
|
||||||
|
if (inQuery.ReadingExportType == ExportResult.OCT_ReadingLession_Export)
|
||||||
|
{
|
||||||
|
export_Template = StaticData.Export.OCT_ReadingLession_Export;
|
||||||
|
}
|
||||||
|
|
||||||
var taskList = await query.ProjectTo<CommonLessionExport>(_mapper.ConfigurationProvider,
|
var taskList = await query.ProjectTo<CommonLessionExport>(_mapper.ConfigurationProvider,
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
|
@ -2055,11 +2070,17 @@ namespace IRaCIS.Core.Application.Service.Common
|
||||||
//有三部分组成 外层问题+ 没有配置病灶编号和类型+ 动态的表格问题
|
//有三部分组成 外层问题+ 没有配置病灶编号和类型+ 动态的表格问题
|
||||||
var dynamicLessionInfoList = addLessionInfoList.Union(dynamicPartialLessionInfoList).Union(item.QuestionAnswerList).ToList();
|
var dynamicLessionInfoList = addLessionInfoList.Union(dynamicPartialLessionInfoList).Union(item.QuestionAnswerList).ToList();
|
||||||
|
|
||||||
|
//OCT 多个表格,但是只导出一个表格,有的问题答案就是空的
|
||||||
|
if (dynamicLessionInfoList.Count > 0)
|
||||||
|
{
|
||||||
|
|
||||||
var cloneItem = item.Clone();
|
var cloneItem = item.Clone();
|
||||||
cloneItem.QuestionAnswerList = dynamicLessionInfoList;
|
cloneItem.QuestionAnswerList = dynamicLessionInfoList;
|
||||||
|
|
||||||
list.Add(cloneItem);
|
list.Add(cloneItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -231,6 +231,9 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
public DateTime? EarliestScanDate { get; set; }
|
public DateTime? EarliestScanDate { get; set; }
|
||||||
public DateTime? LatestScanDate { get; set; }
|
public DateTime? LatestScanDate { get; set; }
|
||||||
|
|
||||||
|
public string EarliestScanDateStr => EarliestScanDate?.ToString("yyyy-MM-dd") ?? string.Empty;
|
||||||
|
public string LatestScanDateStr => LatestScanDate?.ToString("yyyy-MM-dd") ?? string.Empty;
|
||||||
|
|
||||||
public DateTime? SubmitTime { get; set; }
|
public DateTime? SubmitTime { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,7 +296,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
public string LatestReplyUserName { get; set; } = String.Empty;
|
public string LatestReplyUserName { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string Content { get; set; } = string.Empty;
|
public string Content { get; set; } = string.Empty;
|
||||||
public string ContentReplaced => Content.Replace("<br>","").Replace("<br/>", "").Replace("<div style='margin-left:20px'>", "").Replace("</div>","");
|
public string ContentReplaced => Content.Replace("<br>", "").Replace("<br/>", "").Replace("<div style='margin-left:20px'>", "").Replace("</div>", "");
|
||||||
|
|
||||||
[DictionaryTranslateAttribute("ChallengeIsClosed")]
|
[DictionaryTranslateAttribute("ChallengeIsClosed")]
|
||||||
public bool IsClosed { get; set; }
|
public bool IsClosed { get; set; }
|
||||||
|
@ -377,7 +380,7 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
//public bool IsUrgent { get; set; }
|
//public bool IsUrgent { get; set; }
|
||||||
|
|
||||||
//[ExcelColumn(Name = "FirstGiveMedicineTime", Format = "yyyy-MM-dd")]
|
//[ExcelColumn(Name = "FirstGiveMedicineTime", Format = "yyyy-MM-dd")]
|
||||||
public DateTime? FirstGiveMedicineTime { get; set; }
|
public DateOnly? FirstGiveMedicineTime { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string FirstGiveMedicineTimeStr => FirstGiveMedicineTime?.ToString("yyyy-MM-dd");
|
public string FirstGiveMedicineTimeStr => FirstGiveMedicineTime?.ToString("yyyy-MM-dd");
|
||||||
|
@ -740,6 +743,8 @@ namespace IRaCIS.Core.Application.Contracts
|
||||||
|
|
||||||
public DateTime? LatestScanDate { get; set; }
|
public DateTime? LatestScanDate { get; set; }
|
||||||
|
|
||||||
|
public string LatestScanDateStr => LatestScanDate?.ToString("yyyy-MM-dd") ?? string.Empty;
|
||||||
|
|
||||||
public List<string> ModalityList { get; set; }
|
public List<string> ModalityList { get; set; }
|
||||||
|
|
||||||
public string Modalitys => string.Join(',', ModalityList);
|
public string Modalitys => string.Join(',', ModalityList);
|
||||||
|
|
|
@ -276,7 +276,7 @@ namespace IRaCIS.Core.Application.Service
|
||||||
CreateMap<ReadingTableAnswerRowInfo, CommonLessionInfo>()
|
CreateMap<ReadingTableAnswerRowInfo, CommonLessionInfo>()
|
||||||
.ForMember(o => o.LessionCode, t => t.MapFrom(u => u.RowMark))
|
.ForMember(o => o.LessionCode, t => t.MapFrom(u => u.RowMark))
|
||||||
.ForMember(o => o.LessionType, t => t.MapFrom(u => (int?)u.ReadingQuestionTrial.LesionType))
|
.ForMember(o => o.LessionType, t => t.MapFrom(u => (int?)u.ReadingQuestionTrial.LesionType))
|
||||||
.ForMember(o => o.LessionAnswerList, t => t.MapFrom(u => u.LesionAnswerList));
|
.ForMember(o => o.LessionAnswerList, t => t.MapFrom(u => u.LesionAnswerList.Where(c => c.ReadingTableQuestionTrial.ExportResultStr.Contains(((int)readingExportType).ToString()))));
|
||||||
|
|
||||||
CreateMap<ReadingTableQuestionAnswer, CommonLessionQuestionAnswerInfo>()
|
CreateMap<ReadingTableQuestionAnswer, CommonLessionQuestionAnswerInfo>()
|
||||||
.ForMember(o => o.LessionCode, t => t.MapFrom(u => u.Lesion.RowMark))
|
.ForMember(o => o.LessionCode, t => t.MapFrom(u => u.Lesion.RowMark))
|
||||||
|
|
|
@ -244,7 +244,7 @@ namespace IRaCIS.Core.Application.Service
|
||||||
/// <param name="inDto"></param>
|
/// <param name="inDto"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[TypeFilter(typeof(TrialResourceFilter))]
|
[TrialGlobalLimit("AfterStopCannNotOpt")]
|
||||||
public async Task<IResponseOutput> AddOrUpdateReadingMedicineTrialQuestion(ReadingMedicineTrialQuestionAddOrEdit inDto)
|
public async Task<IResponseOutput> AddOrUpdateReadingMedicineTrialQuestion(ReadingMedicineTrialQuestionAddOrEdit inDto)
|
||||||
{
|
{
|
||||||
var existsQuery = _readingMedicineTrialQuestionRepository
|
var existsQuery = _readingMedicineTrialQuestionRepository
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace IRaCIS.Application.Contracts
|
||||||
|
|
||||||
public string CriterionName { get; set; } = string.Empty;
|
public string CriterionName { get; set; } = string.Empty;
|
||||||
|
|
||||||
public List<TrialObjectNameConfig> TrialObjectNameList { get; set; }
|
public List<TrialObjectNameConfig> TrialObjectNameList { get; set; } = new List<TrialObjectNameConfig>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TrialModalitySelectDto
|
public class TrialModalitySelectDto
|
||||||
|
|
|
@ -88,11 +88,14 @@ namespace IRaCIS.Application.Contracts
|
||||||
[ExcelFormat("yyyy-MM-dd")]
|
[ExcelFormat("yyyy-MM-dd")]
|
||||||
public DateTime? RemoveTime { get; set; }
|
public DateTime? RemoveTime { get; set; }
|
||||||
|
|
||||||
|
public string RemoveTimeStr=> RemoveTime?.ToString("yyyy-MM-dd") ?? string.Empty;
|
||||||
|
|
||||||
|
|
||||||
//[ExporterHeader(Format = "yyyy-mm-DD")]
|
//[ExporterHeader(Format = "yyyy-mm-DD")]
|
||||||
[ExcelFormat("yyyy-MM-dd")]
|
[ExcelFormat("yyyy-MM-dd")]
|
||||||
public DateTime? JoinTime { get; set; }
|
public DateTime? JoinTime { get; set; }
|
||||||
|
|
||||||
|
public string JoinTimeStr => JoinTime?.ToString("yyyy-MM-dd") ?? string.Empty;
|
||||||
|
|
||||||
//[ExporterHeader(Format = "yyyy-mm-DD hh:mm:ss")]
|
//[ExporterHeader(Format = "yyyy-mm-DD hh:mm:ss")]
|
||||||
[ExcelFormat("yyyy-MM-dd HH:mm:ss")]
|
[ExcelFormat("yyyy-MM-dd HH:mm:ss")]
|
||||||
|
|
|
@ -466,12 +466,17 @@ namespace IRaCIS.Core.Domain.Share
|
||||||
DetailedTableOfInterReaderAnalysisResults = 6,
|
DetailedTableOfInterReaderAnalysisResults = 6,
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 斑块表
|
||||||
|
/// </summary>
|
||||||
|
OCT_ReadingLession_Export = 7,
|
||||||
|
|
||||||
|
|
||||||
//访视一致率
|
//访视一致率
|
||||||
VisitJudgeRatio_Export = 7,
|
VisitJudgeRatio_Export = 17,
|
||||||
|
|
||||||
//阅片期一致率
|
//阅片期一致率
|
||||||
ReadingPeriodJudgeRatio_Export = 8,
|
ReadingPeriodJudgeRatio_Export = 18,
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -263,8 +263,7 @@ public partial class Trial : BaseFullDeleteAuditEntity
|
||||||
[Comment("项目术语配置Json字符串")]
|
[Comment("项目术语配置Json字符串")]
|
||||||
[StringLength(2000)]
|
[StringLength(2000)]
|
||||||
public List<TrialObjectNameConfig> TrialObjectNameList { get; set; }
|
public List<TrialObjectNameConfig> TrialObjectNameList { get; set; }
|
||||||
//[NotMapped]
|
|
||||||
//public List<TrialObjectNameConfig> TrialObjectNameList => JsonConvert.DeserializeObject<List<TrialObjectNameConfig>>(TrialObjectNameConfigStr) ?? new List<TrialObjectNameConfig>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[ComplexType]
|
[ComplexType]
|
||||||
|
@ -275,5 +274,4 @@ public class TrialObjectNameConfig
|
||||||
public string TrialName { get; set; }
|
public string TrialName { get; set; }
|
||||||
|
|
||||||
public bool IsDefault { get; set; }
|
public bool IsDefault { get; set; }
|
||||||
|
|
||||||
}
|
}
|
|
@ -67,13 +67,13 @@ public class IRaCISDBContext : DbContext
|
||||||
// 使用部分加密值转换器,前 2 个字符不加密,方便模糊搜索
|
// 使用部分加密值转换器,前 2 个字符不加密,方便模糊搜索
|
||||||
entity.Property(e => e.Name).HasConversion(new PartialEncryptionConverter(2));
|
entity.Property(e => e.Name).HasConversion(new PartialEncryptionConverter(2));
|
||||||
|
|
||||||
entity.OwnsMany(x => x.TestJsonObjectLsit, ownedNavigationBuilder =>
|
//entity.OwnsMany(x => x.TestJsonObjectLsit, ownedNavigationBuilder =>
|
||||||
{
|
//{
|
||||||
ownedNavigationBuilder.ToJson();
|
// ownedNavigationBuilder.ToJson();
|
||||||
});
|
//});
|
||||||
|
|
||||||
//entity.Property(e => e.TestJsonObjectLsit).HasConversion(v => v == null ? "[]" : JsonConvert.SerializeObject(v),
|
entity.Property(e => e.TestJsonObjectLsit).HasConversion(v => v == null ? "[]" : JsonConvert.SerializeObject(v),
|
||||||
// v => string.IsNullOrEmpty(v) ? null : JsonConvert.DeserializeObject<List<TestJsonObject>>(v));
|
v => string.IsNullOrEmpty(v) ? null : JsonConvert.DeserializeObject<List<TestJsonObject>>(v));
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<Trial>(entity =>
|
modelBuilder.Entity<Trial>(entity =>
|
||||||
|
@ -81,7 +81,7 @@ public class IRaCISDBContext : DbContext
|
||||||
//项目术语配置
|
//项目术语配置
|
||||||
entity.OwnsMany(x => x.TrialObjectNameList, ownedNavigationBuilder =>
|
entity.OwnsMany(x => x.TrialObjectNameList, ownedNavigationBuilder =>
|
||||||
{
|
{
|
||||||
ownedNavigationBuilder.ToJson();
|
ownedNavigationBuilder.ToJson() ;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -595,8 +595,9 @@ public class TestLength : Entity
|
||||||
[StringLength(1000)]
|
[StringLength(1000)]
|
||||||
public List<TestEnum> TestEnumList { get; set; } = new List<TestEnum>();
|
public List<TestEnum> TestEnumList { get; set; } = new List<TestEnum>();
|
||||||
|
|
||||||
[MaxLength]
|
|
||||||
public List<TestJsonObject> TestJsonObjectLsit { get; set; }
|
public List<TestJsonObject> TestJsonObjectLsit { get; set; }
|
||||||
|
|
||||||
|
public DateOnly? TestDate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,44 @@
|
||||||
using IRaCIS.Core.Domain.Models;
|
using IRaCIS.Core.Domain.Models;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Infra.EFCore
|
namespace IRaCIS.Core.Infra.EFCore
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// modelBuilder.Entity<SubjectVisit>().HasQueryFilter(s => !s.IsDeleted);(这个是自动全局配置的)
|
||||||
|
/// modelBuilder.Entity<CheckChallengeDialog>().HasQueryFilter(c => !c.SubjectVisit.IsDeleted); (这个没有自动加) 所以有警告
|
||||||
|
/// </summary>
|
||||||
public static class SoftDeleteQueryExtension
|
public static class SoftDeleteQueryExtension
|
||||||
{
|
{
|
||||||
public static void AddSoftDeleteQueryFilter(
|
public static void AddSoftDeleteQueryFilter(
|
||||||
this IMutableEntityType entityData)
|
this IMutableEntityType entityType)
|
||||||
{
|
{
|
||||||
var methodToCall = typeof(SoftDeleteQueryExtension)
|
var methodToCall = typeof(SoftDeleteQueryExtension)
|
||||||
.GetMethod(nameof(GetSoftDeleteFilter),
|
.GetMethod(nameof(GetSoftDeleteFilter),
|
||||||
BindingFlags.NonPublic | BindingFlags.Static)
|
BindingFlags.NonPublic | BindingFlags.Static)
|
||||||
.MakeGenericMethod(entityData.ClrType);
|
.MakeGenericMethod(entityType.ClrType);
|
||||||
var filter = methodToCall.Invoke(null, new object[] { });
|
var filter = methodToCall.Invoke(null, new object[] { });
|
||||||
entityData.SetQueryFilter((LambdaExpression)filter);
|
entityType.SetQueryFilter((LambdaExpression)filter);
|
||||||
|
|
||||||
|
//foreach (var navigation in entityType.GetNavigations())
|
||||||
|
//{
|
||||||
|
// var targetEntityType = navigation.TargetEntityType;
|
||||||
|
|
||||||
|
// // 如果目标实体实现了 ISoftDelete 接口,递归添加过滤器
|
||||||
|
// if (typeof(ISoftDelete).IsAssignableFrom(targetEntityType.ClrType))
|
||||||
|
// {
|
||||||
|
// // 在当前实体的导航属性上添加过滤器
|
||||||
|
// var targetEntityFilterMethod = typeof(SoftDeleteQueryExtension)
|
||||||
|
// .GetMethod(nameof(GetSoftDeleteFilterForNavigation),
|
||||||
|
// BindingFlags.NonPublic | BindingFlags.Static)
|
||||||
|
// .MakeGenericMethod(entityType.ClrType, targetEntityType.ClrType);
|
||||||
|
|
||||||
|
// var navigationFilter = targetEntityFilterMethod.Invoke(null, new object[] { navigation });
|
||||||
|
// entityType.SetQueryFilter((LambdaExpression)navigationFilter);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,5 +48,27 @@ namespace IRaCIS.Core.Infra.EFCore
|
||||||
Expression<Func<TEntity, bool>> filter = x => !x.IsDeleted;
|
Expression<Func<TEntity, bool>> filter = x => !x.IsDeleted;
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取导航属性的软删除过滤器
|
||||||
|
private static LambdaExpression GetSoftDeleteFilterForNavigation<TEntity, TNavigationEntity>(
|
||||||
|
IMutableNavigation navigation)
|
||||||
|
where TEntity : class
|
||||||
|
where TNavigationEntity : class, ISoftDelete
|
||||||
|
{
|
||||||
|
// 获取导航属性的表达式
|
||||||
|
var parameter = Expression.Parameter(typeof(TEntity), "e");
|
||||||
|
var navigationExpression = Expression.Property(parameter, navigation.Name);
|
||||||
|
|
||||||
|
// 获取导航属性中的 IsDeleted 属性
|
||||||
|
var isDeletedProperty = Expression.Property(navigationExpression, nameof(ISoftDelete.IsDeleted));
|
||||||
|
|
||||||
|
// 生成过滤条件:导航属性不为空且未被软删除
|
||||||
|
var condition = Expression.AndAlso(
|
||||||
|
Expression.NotEqual(navigationExpression, Expression.Constant(null, navigationExpression.Type)), // 判断导航属性是否为null
|
||||||
|
Expression.Equal(isDeletedProperty, Expression.Constant(false)) // 判断导航属性的 IsDeleted 为 false
|
||||||
|
);
|
||||||
|
|
||||||
|
return Expression.Lambda<Func<TEntity, bool>>(condition, parameter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
|
||||||
return obj;
|
return obj;
|
||||||
|
|
||||||
// 将对象序列化为 JSON 字符串
|
// 将对象序列化为 JSON 字符串
|
||||||
string json = JsonConvert.SerializeObject(obj,new JsonSerializerSettings() { DateFormatString= "yyyy-MM-dd HH:mm:ss.fff" });
|
string json = JsonConvert.SerializeObject(obj, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-dd HH:mm:ss.fff" });
|
||||||
|
|
||||||
// 将 JSON 字符串反序列化回对象
|
// 将 JSON 字符串反序列化回对象
|
||||||
var deserializedObj = JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings
|
var deserializedObj = JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings
|
||||||
|
@ -80,7 +80,7 @@ namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
|
||||||
return deserializedObj!;
|
return deserializedObj!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string DateTimeInternationalToString(DateTime? dateTime, string? clientZoneId=null)
|
public static string DateTimeInternationalToString(DateTime? dateTime, string? clientZoneId = null)
|
||||||
{
|
{
|
||||||
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
|
||||||
|
|
||||||
|
@ -94,6 +94,12 @@ namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
|
||||||
needDealTime = TimeZoneInfo.ConvertTime(needDealTime, TimeZoneInfo.Local, TimeZoneInfo.FindSystemTimeZoneById(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 (isEn_US)
|
if (isEn_US)
|
||||||
{
|
{
|
||||||
//暂时保持一致,等需求确认,修改英文要展示的日期格式
|
//暂时保持一致,等需求确认,修改英文要展示的日期格式
|
||||||
|
@ -104,6 +110,9 @@ namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
|
||||||
return needDealTime.ToString("yyyy-MM-dd HH:mm:ss");
|
return needDealTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
|
@ -278,6 +278,10 @@ public static class StaticData
|
||||||
|
|
||||||
public const string ReadingLession_Export = "ReadingLession_Export";
|
public const string ReadingLession_Export = "ReadingLession_Export";
|
||||||
|
|
||||||
|
public const string OCT_ReadingLession_Export = "OCT_ReadingLession_Export";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public const string IVUSTheMeasuredValueOfEachMatchedFragment = "IVUS_TheMeasuredValueOfEachMatchedFragment";
|
public const string IVUSTheMeasuredValueOfEachMatchedFragment = "IVUS_TheMeasuredValueOfEachMatchedFragment";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue