修改时间国际化

IRC_NewDev
hang 2024-08-27 14:47:20 +08:00
parent f52b09e5e8
commit 633abdf0f4
8 changed files with 359 additions and 31 deletions

View File

@ -362,8 +362,11 @@ namespace IRaCIS.Api.Controllers
var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config() var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config()
{ {
AccessKeyId = ossOptions.accessKeyId, //AccessKeyId = ossOptions.accessKeyId,
AccessKeySecret = ossOptions.accessKeySecret, //AccessKeySecret = ossOptions.accessKeySecret,
AccessKeyId = "LTAI5tJV76pYX5yPg1N9QVE8",
AccessKeySecret = "roRNLa9YG1of4pYruJGCNKBXEWTAWa",
Endpoint = "sts.cn-hangzhou.aliyuncs.com" Endpoint = "sts.cn-hangzhou.aliyuncs.com"
}); });
@ -371,7 +374,8 @@ namespace IRaCIS.Api.Controllers
// 将<YOUR_ROLE_SESSION_NAME>设置为自定义的会话名称例如oss-role-session。 // 将<YOUR_ROLE_SESSION_NAME>设置为自定义的会话名称例如oss-role-session。
assumeRoleRequest.RoleSessionName = $"session-name-{NewId.NextGuid()}"; assumeRoleRequest.RoleSessionName = $"session-name-{NewId.NextGuid()}";
// 将<YOUR_ROLE_ARN>替换为拥有上传文件到指定OSS Bucket权限的RAM角色的ARN。 // 将<YOUR_ROLE_ARN>替换为拥有上传文件到指定OSS Bucket权限的RAM角色的ARN。
assumeRoleRequest.RoleArn = ossOptions.roleArn; //assumeRoleRequest.RoleArn = ossOptions.roleArn;
assumeRoleRequest.RoleArn = "acs:ram::1899121822495495:role/webdirect";
assumeRoleRequest.DurationSeconds = 3600; assumeRoleRequest.DurationSeconds = 3600;
var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions(); var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
var response = client.AssumeRoleWithOptions(assumeRoleRequest, runtime); var response = client.AssumeRoleWithOptions(assumeRoleRequest, runtime);

View File

@ -0,0 +1,125 @@
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Globalization;
using System.Threading.Tasks;
namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson
{
public class CustomJsonResult : JsonResult
{
public CustomJsonResult(object value) : base(value) { }
public override void ExecuteResult(ActionContext context)
{
var converter = context.HttpContext.RequestServices.GetService<JSONTimeZoneConverter>();
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
string dateFormat;
if (!isEn_US)
{
// Chinese date format
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
else
{
// Default or English date format
dateFormat = "MM/dd/yyyy HH:mm:ss";
}
var serializerSettings = new JsonSerializerSettings
{
DateFormatString = dateFormat,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new NullToEmptyStringResolver(),
DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind,
};
serializerSettings.Converters.Add(converter);
var json = JsonConvert.SerializeObject(Value, serializerSettings);
context.HttpContext.Response.ContentType = "application/json";
context.HttpContext.Response.WriteAsync(json);
}
}
public class MyDateTimeConverter : JsonConverter<DateTime>
{
public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return reader.ReadAsDateTime().Value;
}
public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
string dateFormat;
if (!isEn_US)
{
// Chinese date format
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
else
{
// Default or English date format
dateFormat = "MM/dd/yyyy HH:mm:ss";
}
writer.WriteValue(value.ToString(dateFormat));
}
}
public class MyNullableDateTimeConverter : JsonConverter<DateTime?>
{
public override DateTime? ReadJson(JsonReader reader, Type objectType, DateTime? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var val = reader.ReadAsDateTime();
return val;
}
public override void WriteJson(JsonWriter writer, DateTime? value, JsonSerializer serializer)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
string dateFormat;
if (!isEn_US)
{
// Chinese date format
dateFormat = "yyyy-MM-dd HH:mm:ss";
}
else
{
// Default or English date format
dateFormat = "MM/dd/yyyy HH:mm:ss";
}
if (value.HasValue)
{
writer.WriteValue(value.Value.ToString(dateFormat));
}
else
{
writer.WriteValue(default(DateTime?));
}
}
}
}

View File

@ -11,19 +11,39 @@ namespace IRaCIS.Core.API
/// <summary> /// <summary>
/// 序列化,反序列化的时候,处理时间 时区转换 /// 序列化,反序列化的时候,处理时间 时区转换
/// </summary> /// </summary>
public class JSONTimeZoneConverter : DateTimeConverterBase public class JSONTimeZoneConverter(IHttpContextAccessor _httpContextAccessor) : DateTimeConverterBase
{ {
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly TimeZoneInfo _clientTimeZone; private TimeZoneInfo _clientTimeZone;
public JSONTimeZoneConverter(IHttpContextAccessor httpContextAccessor)
private string _dateFormat;
public override bool CanConvert(Type objectType)
{ {
_httpContextAccessor = httpContextAccessor; #region 设置语言格式化方式,放在构造函数里面做不到动态切换
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
if (!isEn_US)
{
// Chinese date format
_dateFormat = "yyyy-MM-dd HH:mm:ss";
}
else
{
// Default or English date format
_dateFormat = "MM/dd/yyyy HH:mm:ss";
}
#endregion
#region 获取当前请求的客户端时区
//默认是UTC
//var timeZoneId = "Etc/UTC"; //var timeZoneId = "Etc/UTC";
var timeZoneId = "Asia/Shanghai"; var timeZoneId = "Asia/Shanghai";
var timeZoneIdHeader = _httpContextAccessor?.HttpContext?.Request?.Headers["TimeZoneId"]; var timeZoneIdHeader = _httpContextAccessor?.HttpContext?.Request?.Headers["TimeZoneId"];
if (timeZoneIdHeader is not null && !string.IsNullOrEmpty(timeZoneIdHeader.Value)) if (timeZoneIdHeader is not null && !string.IsNullOrEmpty(timeZoneIdHeader.Value))
@ -33,12 +53,12 @@ namespace IRaCIS.Core.API
_clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); _clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
} #endregion
public override bool CanConvert(Type objectType)
{
// 仅支持 DateTime 类型的转换 // 仅支持 DateTime 类型的转换
return objectType == typeof(DateTime)|| objectType == typeof(DateTime?); return objectType == typeof(DateTime)|| objectType == typeof(DateTime?);
} }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
@ -91,7 +111,10 @@ namespace IRaCIS.Core.API
{ {
//第一个参数默认使用系统本地时区 也就是应用服务器的时区 //第一个参数默认使用系统本地时区 也就是应用服务器的时区
DateTime clientZoneTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, _clientTimeZone); DateTime clientZoneTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, _clientTimeZone);
writer.WriteValue(clientZoneTime);
//writer.WriteValue(clientZoneTime);
writer.WriteValue(clientZoneTime.ToString(_dateFormat));
} }
else else
{ {

View File

@ -1,10 +1,14 @@
 
using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson; using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using System; using System;
using System.Globalization;
namespace IRaCIS.Core.API namespace IRaCIS.Core.API
{ {
@ -12,33 +16,36 @@ namespace IRaCIS.Core.API
{ {
public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder, IServiceCollection services) public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder, IServiceCollection services)
{ {
services.AddHttpContextAccessor(); services.AddHttpContextAccessor();
services.AddScoped<JSONTimeZoneConverter>(); services.AddScoped<JSONTimeZoneConverter>();
services.AddScoped<ObjectStorePathConvert>(); services.AddScoped<ObjectStorePathConvert>();
services.AddScoped<IOSSService,OSSService>(); services.AddScoped<IOSSService,OSSService>();
builder.AddNewtonsoftJson(options => builder.AddNewtonsoftJson(options =>
{ {
//options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
// 忽略循环引用 // 忽略循环引用
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//options.SerializerSettings.TypeNameHandling = TypeNameHandling.All;
//处理返回给前端 可空类型 给出默认值 比如in? 为null 设置 默认值0 //处理返回给前端 可空类型 给出默认值 比如in? 为null 设置 默认值0
options.SerializerSettings.ContractResolver = new NullToEmptyStringResolver(); //new DefaultContractResolver();// new NullToEmptyStringResolver(); options.SerializerSettings.ContractResolver = new NullToEmptyStringResolver();
// 设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; // 设置时间格式 isEn_US? "MM/dd/yyyy HH:mm:ss" :
//options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
//二者只能取其一
//options.SerializerSettings.Converters.Add(new MyDateTimeConverter());
//options.SerializerSettings.Converters.Add(new MyNullableDateTimeConverter());
//必须放在后面
options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<JSONTimeZoneConverter>()); options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService<JSONTimeZoneConverter>());
//IsoDateTimeConverter
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
}) })
.AddControllersAsServices()//动态webApi属性注入需要 .AddControllersAsServices()//动态webApi属性注入需要
.ConfigureApiBehaviorOptions(o => .ConfigureApiBehaviorOptions(o =>

View File

@ -363,4 +363,21 @@ namespace IRaCIS.Core.Application.Contracts
public decimal FileFize { get; set; } public decimal FileFize { get; set; }
} }
public class CRCUploadedStudyQuqry
{
[NotDefault]
public Guid SubjectVisitId { get; set; }
public List<Guid> DicomStudyIdList { get; set; }
public List<Guid> NoneDicomStudyIdList { get; set; }
}
public class IRReadingDownloadQuery
{
[NotDefault]
public Guid VisitTaskId { get; set; }
}
} }

View File

@ -656,7 +656,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
else else
{ {
return ResponseOutput.NotOk("不允许 subjectId subjectId 都不传递"); return ResponseOutput.NotOk("不允许 subjectId SubejectVisitId 都不传递");
} }
@ -894,5 +894,140 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
} }
/// <summary>
/// IQC 获取CRC 上传到某一个访视的的检查信息 (原始影像信息 包含dicom 非dicom)
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> GetCRCUploadedStudyInfo(CRCUploadedStudyQuqry inQuery)
{
var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0;
var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId)
select new
{
SubjectCode = sv.Subject.Code,
VisitName = sv.VisitName,
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id):false)
.Select(u => new
{
u.PatientId,
u.StudyTime,
u.StudyCode,
SeriesList = u.SeriesList.Select(z => new
{
z.Modality,
InstanceList = z.DicomInstanceList.Select(k => new
{
k.Path,
k.FileSize
})
})
}).ToList(),
NoneDicomStudyList = sv.NoneDicomStudyList.Where( t => isQueryNoneDicom?inQuery.NoneDicomStudyIdList.Contains(t.Id):false)
.Select(nd => new
{
nd.Modality,
nd.StudyCode,
nd.ImageDate,
FileList = nd.NoneDicomFileList.Select(file => new
{
file.FileName,
file.Path,
file.FileType
})
}).ToList()
};
var result = query.ToList();
return ResponseOutput.Ok(result);
} }
/// <summary>
/// IR 阅片页面获取下载检查的信息 会根据标准进行过滤检查,(后端要考虑到一致性分析 subjectCode的问题
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> GetIRReadingDownloadStudyInfo(IRReadingDownloadQuery inQuery)
{
var taskInfo = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
.Select(t => new
{
t.BlindSubjectCode,
t.IsAnalysisCreate,
t.SourceSubjectVisitId,
t.TrialReadingCriterion.IsImageFilter,
t.TrialReadingCriterion.CriterionModalitys
})
.FirstNotNullAsync();
if (taskInfo.SourceSubjectVisitId == null)
{
return ResponseOutput.NotOk("请开发核实传递的参数该查询任务关联访视Id没有值");
}
var query = from sv in _subjectVisitRepository.Where(t => t.Id == taskInfo.SourceSubjectVisitId)
select new
{
SubjectCode = sv.Subject.Code,
VisitName = sv.VisitName,
StudyList = sv.StudyList.AsQueryable().WhereIf(taskInfo.IsImageFilter, t => ("|" + taskInfo.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|"))
.Select(u => new
{
u.PatientId,
u.StudyTime,
u.StudyCode,
SeriesList = u.SeriesList.Select(z => new
{
z.Modality,
InstancePathList = z.DicomInstanceList.Select(k => new
{
k.Path
})
})
}),
NoneDicomStudyList = sv.NoneDicomStudyList.AsQueryable().WhereIf(taskInfo.IsImageFilter, t => ("|" + taskInfo.CriterionModalitys + "|").Contains("|" + t.Modality + "|"))
.Select(nd => new
{
nd.Modality,
nd.StudyCode,
nd.ImageDate,
FileList = nd.NoneDicomFileList.Select(file => new
{
file.FileName,
file.Path,
file.FileType
})
})
};
return ResponseOutput.Ok();
}
}
} }

View File

@ -18,6 +18,14 @@ namespace IRaCIS.Core.Domain.Models
[ForeignKey("NoneDicomStudyId")] [ForeignKey("NoneDicomStudyId")]
[JsonIgnore] [JsonIgnore]
public NoneDicomStudy NoneDicomStudy { get; set; } public NoneDicomStudy NoneDicomStudy { get; set; }
[JsonIgnore]
public VisitTask VisitTask { get; set; }
//[ForeignKey("OriginNoneDicomStudyId")]
//[JsonIgnore]
//public NoneDicomStudy OriginNoneDicomStudy { get; set; }
#endregion #endregion
@ -31,7 +39,16 @@ namespace IRaCIS.Core.Domain.Models
public string FileType { get; set; } public string FileType { get; set; }
public decimal? FileSize { get; set; } public long? FileSize { get; set; }
#region 跟任务绑定 同时区分检查
public Guid? VisitTaskId { get; set; }
public Guid? OriginNoneDicomStudyId { get; set; }
#endregion
} }

View File

@ -79,7 +79,7 @@ namespace IRaCIS.Core.Domain.Models
public List<ClinicalDataTrialSet> clinicalDataTrialSets { get; set; } = new List<ClinicalDataTrialSet> { }; public List<ClinicalDataTrialSet> clinicalDataTrialSets { get; set; } = new List<ClinicalDataTrialSet> { };
[JsonIgnore] [JsonIgnore]
public List<TrialStatusDetail> ClinicalTrialProjectDetails { get; set; } public List<TrialStatusDetail> ClinicalTrialProjectDetails { get; set; } = new List<TrialStatusDetail> { };
[JsonIgnore] [JsonIgnore]
public List<TrialDictionary> TrialDicList { get; set; } = new List<TrialDictionary>(); public List<TrialDictionary> TrialDicList { get; set; } = new List<TrialDictionary>();