修改时间国际化

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()
{
AccessKeyId = ossOptions.accessKeyId,
AccessKeySecret = ossOptions.accessKeySecret,
//AccessKeyId = ossOptions.accessKeyId,
//AccessKeySecret = ossOptions.accessKeySecret,
AccessKeyId = "LTAI5tJV76pYX5yPg1N9QVE8",
AccessKeySecret = "roRNLa9YG1of4pYruJGCNKBXEWTAWa",
Endpoint = "sts.cn-hangzhou.aliyuncs.com"
});
@ -371,7 +374,8 @@ namespace IRaCIS.Api.Controllers
// 将<YOUR_ROLE_SESSION_NAME>设置为自定义的会话名称例如oss-role-session。
assumeRoleRequest.RoleSessionName = $"session-name-{NewId.NextGuid()}";
// 将<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;
var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
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>
public class JSONTimeZoneConverter : DateTimeConverterBase
public class JSONTimeZoneConverter(IHttpContextAccessor _httpContextAccessor) : DateTimeConverterBase
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly TimeZoneInfo _clientTimeZone;
public JSONTimeZoneConverter(IHttpContextAccessor httpContextAccessor)
private TimeZoneInfo _clientTimeZone;
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 = "Asia/Shanghai";
var timeZoneIdHeader = _httpContextAccessor?.HttpContext?.Request?.Headers["TimeZoneId"];
if (timeZoneIdHeader is not null && !string.IsNullOrEmpty(timeZoneIdHeader.Value))
@ -33,12 +53,12 @@ namespace IRaCIS.Core.API
_clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
}
#endregion
public override bool CanConvert(Type objectType)
{
// 仅支持 DateTime 类型的转换
return objectType == typeof(DateTime)|| objectType == typeof(DateTime?);
}
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);
writer.WriteValue(clientZoneTime);
//writer.WriteValue(clientZoneTime);
writer.WriteValue(clientZoneTime.ToString(_dateFormat));
}
else
{

View File

@ -1,10 +1,14 @@

using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Globalization;
namespace IRaCIS.Core.API
{
@ -12,37 +16,40 @@ namespace IRaCIS.Core.API
{
public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder, IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddScoped<JSONTimeZoneConverter>();
services.AddScoped<ObjectStorePathConvert>();
services.AddScoped<IOSSService,OSSService>();
builder.AddNewtonsoftJson(options =>
{
//options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
// 忽略循环引用
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//options.SerializerSettings.TypeNameHandling = TypeNameHandling.All;
//处理返回给前端 可空类型 给出默认值 比如in? 为null 设置 默认值0
options.SerializerSettings.ContractResolver = new NullToEmptyStringResolver(); //new DefaultContractResolver();// new NullToEmptyStringResolver();
// 设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.SerializerSettings.ContractResolver = new NullToEmptyStringResolver();
// 设置时间格式 isEn_US? "MM/dd/yyyy HH:mm:ss" :
//options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
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>());
//IsoDateTimeConverter
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
})
.AddControllersAsServices()//动态webApi属性注入需要
.ConfigureApiBehaviorOptions(o =>
{
{
o.SuppressModelStateInvalidFilter = true; //自己写验证
////这里是自定义验证结果和返回状态码 因为这里是在[ApiController]控制器层校验动态webApi的不会校验 所以需要单独写一个Filter

View File

@ -46,7 +46,7 @@ namespace IRaCIS.Core.Application.Contracts
public bool IsDicom { get; set; }
}
public class UnionStudyMonitorModel : UnionStudyBaseModel
@ -363,4 +363,21 @@ namespace IRaCIS.Core.Application.Contracts
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

@ -45,7 +45,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
IDistributedLockProvider _distributedLockProvider) : BaseService, IDownloadAndUploadService
{
/// <summary>
/// 受试者随机阅片,任务进行随机编号
@ -490,7 +490,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
var extralConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
var extralConfig = _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialExtraConfigJsonStr).FirstOrDefault() ?? string.Empty;
var config = JsonConvert.DeserializeObject<TrialExtraConfig>(extralConfig) ?? new TrialExtraConfig();
@ -608,7 +608,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
else if (inQuery.SubejctId != null)
{
var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubejctId).SelectMany(t=>t.SubjectVisitList)
var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubejctId).SelectMany(t => t.SubjectVisitList)
select new
@ -656,7 +656,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
}
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")]
[JsonIgnore]
public NoneDicomStudy NoneDicomStudy { get; set; }
[JsonIgnore]
public VisitTask VisitTask { get; set; }
//[ForeignKey("OriginNoneDicomStudyId")]
//[JsonIgnore]
//public NoneDicomStudy OriginNoneDicomStudy { get; set; }
#endregion
@ -31,7 +39,16 @@ namespace IRaCIS.Core.Domain.Models
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> { };
[JsonIgnore]
public List<TrialStatusDetail> ClinicalTrialProjectDetails { get; set; }
public List<TrialStatusDetail> ClinicalTrialProjectDetails { get; set; } = new List<TrialStatusDetail> { };
[JsonIgnore]
public List<TrialDictionary> TrialDicList { get; set; } = new List<TrialDictionary>();