From 292bcd71009e98c0ed10deafd75b1f081e84a6db Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 21 Feb 2024 13:58:34 +0800 Subject: [PATCH 1/3] =?UTF-8?q?[=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=97=B6=E5=8C=BA=E4=B8=8A=E7=BA=BF=E6=B5=8B=E8=AF=95?= =?UTF-8?q?]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.xml | 5 + .../TimeZoneAdjustmentMiddleware.cs | 115 ++++++++++++++++++ .../NewtonsoftJson/JSONCustomDateConverter.cs | 88 ++++++++------ .../NewtonsoftJson/NewtonsoftJsonSetup.cs | 7 +- .../Service/Common/ExcelExportService.cs | 103 ++++++++++------ .../TrialSiteUser/DTO/UserTrialViewModel.cs | 4 +- IRaCIS.Core.Infra.EFCore/AuthUser/UserInfo.cs | 4 +- .../ConvertToClientTimeResultFilter.cs | 60 +++++++++ .../Extention/ExportExcelDateConverter.cs | 83 +++++++++++++ 9 files changed, 391 insertions(+), 78 deletions(-) create mode 100644 IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs create mode 100644 IRaCIS.Core.Infrastructure/Extention/ConvertToClientTimeResultFilter.cs create mode 100644 IRaCIS.Core.Infrastructure/Extention/ExportExcelDateConverter.cs diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.xml b/IRaCIS.Core.API/IRaCIS.Core.API.xml index 008e1add6..cc66c1c02 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.xml +++ b/IRaCIS.Core.API/IRaCIS.Core.API.xml @@ -365,6 +365,11 @@ IPLimit限流 启动服务 + + + 废弃,没用,不用这种处理方式 + + 创建属性 diff --git a/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs b/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs new file mode 100644 index 000000000..d7975a395 --- /dev/null +++ b/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs @@ -0,0 +1,115 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Primitives; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +public class TimeZoneAdjustmentMiddleware +{ + private readonly RequestDelegate _next; + + public TimeZoneAdjustmentMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext context) + { + if (string.IsNullOrEmpty(context.Request.ContentType)) + { + // 请求没有内容体,可能是一个没有请求体的请求,比如 GET 请求 + await _next(context); + return; + } + + + var timeZoneId = "Asia/Shanghai"; // 客户端默认时区 + + var timeZoneIdHeaderValue = context.Request.Headers["TimeZoneId"]; + + if (!string.IsNullOrEmpty(timeZoneIdHeaderValue)) + { + timeZoneId = timeZoneIdHeaderValue; + } + + var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); + + + + // 处理 JSON 请求体中的时间字段 + if (context.Request.ContentType.StartsWith("application/json")) + { + var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync(); + + // 使用 JSON.NET 或 System.Text.Json 解析 JSON 请求体 + // 假设请求体中有一个名为 "dateTime" 的时间字段 + dynamic jsonData = JsonConvert.DeserializeObject(requestBody); + + if (jsonData.dateTime != null) + { + if (DateTime.TryParse((string)jsonData.dateTime, out DateTime dateTime)) + { + // 将 JSON 请求体中的时间字段转换为服务器时区的时间 + var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone); + jsonData.dateTime = serverTime; + } + } + + // 将修改后的 JSON 请求体重新写入请求流中 + var jsonBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonData)); + context.Request.Body = new MemoryStream(jsonBytes); + context.Request.ContentLength = jsonBytes.Length; + } + + + // 处理 URL 表单参数 + var modifiedQuery = new Dictionary(); + + foreach (var key in context.Request.Query.Keys) + { + if (DateTime.TryParse(context.Request.Query[key], out DateTime dateTime)) + { + // 将 URL 表单参数中的时间转换为服务器时区的时间 + var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone); + modifiedQuery[key] = new StringValues(serverTime.ToString()); + } + else + { + modifiedQuery[key] = context.Request.Query[key]; + } + } + + context.Request.Query = new QueryCollection(modifiedQuery); + + // 处理Form请求体中的参数 + if (context.Request.HasFormContentType) + { + var modifiedForm = new Dictionary(); + + foreach (var key in context.Request.Form.Keys) + { + if (DateTime.TryParse(context.Request.Form[key], out DateTime dateTime)) + { + // 将请求体中的时间转换为服务器时区的时间 + var serverTime = TimeZoneInfo.ConvertTime(dateTime, timeZone); + modifiedForm[key] = new StringValues(serverTime.ToString()); + } + else + { + modifiedForm[key] = context.Request.Form[key]; + } + } + + var newFormCollection = new FormCollection(modifiedForm); + + // 将新的表单集合设置回请求对象 + context.Request.Form = newFormCollection; + } + + await _next(context); + } + +} diff --git a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONCustomDateConverter.cs b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONCustomDateConverter.cs index 388f7053a..0bb4eb356 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONCustomDateConverter.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONCustomDateConverter.cs @@ -1,69 +1,87 @@ using IRaCIS.Core.Domain.Share; +using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using StackExchange.Redis; using System; +using System.Globalization; namespace IRaCIS.Core.API { + /// + /// 废弃,没用,不用这种处理方式 + /// public class JSONCustomDateConverter : DateTimeConverterBase { - private TimeZoneInfo _timeZoneInfo; - private string _dateFormat; + private readonly IHttpContextAccessor _httpContextAccessor; - private IUserInfo _userInfo; - public JSONCustomDateConverter(string dateFormat, TimeZoneInfo timeZoneInfo, IUserInfo userInfo) + private readonly string timeZoneId; + + private readonly TimeZoneInfo _clientTimeZone; + public JSONCustomDateConverter(IHttpContextAccessor httpContextAccessor) { - _dateFormat = dateFormat; - _timeZoneInfo = timeZoneInfo; + _httpContextAccessor = httpContextAccessor; + + //默认是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)) + { + timeZoneId = timeZoneIdHeader.Value; + } + + _clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); - _userInfo = userInfo; } - private static readonly TimeZoneInfo ChinaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Asia/Shanghai"); + private static readonly TimeZoneInfo ChinaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Etc/UTC"); + + 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) { - - - if (reader.ValueType == typeof(DateTime)) - { - DateTime dateTime = (DateTime)reader.Value; - - var zoneTime = TimeZoneInfo.ConvertTime(dateTime, ChinaTimeZone); - - return zoneTime; - } + if (reader.Value == null) + return null; else { - return reader.Value; - } + var dateTime = (DateTime)reader.Value; + // 将客户端时间转换为服务器时区的时间 + var serverZoneTime = TimeZoneInfo.ConvertTime(dateTime, _clientTimeZone, TimeZoneInfo.Local); + + return serverZoneTime; + } + + // 在反序列化时,我们不需要此转换器,因此不实现此方法 + //throw new NotImplementedException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - var timeZoneId = _userInfo.TimeZoneId; - //var needConvertUtcDateTime = Convert.ToDateTime(value); + + - //var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); + DateTime? nullableDateTime = value as DateTime?; - - //var dateTimeOffset = new DateTimeOffset(needConvertUtcDateTime); - - //var time = TimeZoneInfo.ConvertTimeFromUtc(needConvertUtcDateTime, tz).ToString(_dateFormat); - - //writer.WriteValue(time); - //writer.Flush(); - - - if (value is DateTime dateTime) + if (nullableDateTime != null && nullableDateTime.HasValue) { - DateTime chinaTime = TimeZoneInfo.ConvertTime(dateTime, ChinaTimeZone); + //第一个参数默认使用系统本地时区 也就是应用服务器的时区 + DateTime chinaTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, _clientTimeZone); writer.WriteValue(chinaTime); } - + else + { + writer.WriteNull(); + } } } diff --git a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/NewtonsoftJsonSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/NewtonsoftJsonSetup.cs index df8aad91f..0ffcf0384 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/NewtonsoftJsonSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/NewtonsoftJsonSetup.cs @@ -10,7 +10,8 @@ namespace IRaCIS.Core.API { public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder, IServiceCollection services) { - services.AddScoped(); + services.AddHttpContextAccessor(); + services.AddScoped(); builder.AddNewtonsoftJson(options => { @@ -24,8 +25,10 @@ namespace IRaCIS.Core.API // 设置时间格式 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; + options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; + //options.SerializerSettings.Converters.Add(new JSONCustomDateConverter()) ; - //options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService()); + options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService()); //IsoDateTimeConverter //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index f24d6bad2..6ccb8d139 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -3,6 +3,7 @@ using DocumentFormat.OpenXml.Presentation; using DocumentFormat.OpenXml.Spreadsheet; using IRaCIS.Application.Contracts; using IRaCIS.Application.Interfaces; +using IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.Service.Reading.Dto; @@ -59,7 +60,7 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = await _trialUseRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters() + var list = await _trialUseRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters() .WhereIf(param.UserTypeId != null, t => t.User.UserTypeId == param.UserTypeId) .WhereIf(!string.IsNullOrWhiteSpace(param.UserName), t => t.User.UserName.Contains(param.UserName)) @@ -70,8 +71,10 @@ namespace IRaCIS.Core.Application.Service.Common t => (t.User.FullName).Contains(param.UserRealName)) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); - + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialMaintenanceDTO)); @@ -90,7 +93,7 @@ namespace IRaCIS.Core.Application.Service.Common [HttpPost] [AllowAnonymous] public async Task TrialSiteUserListExport(SiteCRCExportQueryDTO param, - [FromServices] IRepository _commonDocumentRepository, + [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService, [FromServices] IRepository _trialRepository, [FromServices] IRepository _trialSiteUserRepository @@ -100,21 +103,26 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = await _trialSiteUserRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters() - .WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted) - .WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.Site.SiteName.Contains(param.SiteName)) - .WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName), - t => t.TrialSite.TrialSiteAliasName.Contains(param.TrialSiteAliasName)) - .WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteCode), - t => t.TrialSite.TrialSiteCode.Contains(param.TrialSiteCode)) - .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, - t => t.UserId == _userInfo.Id) - .WhereIf(!string.IsNullOrWhiteSpace(param.UserKeyInfo), t => (t.User.FullName).Contains(param.UserKeyInfo) - || t.User.UserName.Contains(param.UserKeyInfo) || t.User.EMail.Contains(param.UserKeyInfo)) + var list = await _trialSiteUserRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters() + .WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted) + .WhereIf(!string.IsNullOrWhiteSpace(param.SiteName), t => t.Site.SiteName.Contains(param.SiteName)) + .WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteAliasName), + t => t.TrialSite.TrialSiteAliasName.Contains(param.TrialSiteAliasName)) + .WhereIf(!string.IsNullOrWhiteSpace(param.TrialSiteCode), + t => t.TrialSite.TrialSiteCode.Contains(param.TrialSiteCode)) + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, + t => t.UserId == _userInfo.Id) + .WhereIf(!string.IsNullOrWhiteSpace(param.UserKeyInfo), t => (t.User.FullName).Contains(param.UserKeyInfo) + || t.User.UserName.Contains(param.UserKeyInfo) || t.User.EMail.Contains(param.UserKeyInfo)) - .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; + + + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SiteUserExportDTO)); } @@ -161,13 +169,14 @@ namespace IRaCIS.Core.Application.Service.Common .WhereIf(!string.IsNullOrEmpty(queryParam.OrganizationName), t => t.OrganizationName.Contains(queryParam.OrganizationName)) .ProjectTo(_mapper.ConfigurationProvider); - data.List = await query.ToListAsync(); - - + var list = await query.ToListAsync(); + data.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); var exportInfo = data; exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSiteUserSummary_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialSiteUserSummaryDto)); } @@ -230,8 +239,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == visitSearchDTO.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialCRCUploadImageList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CRCVisitExportDTO)); @@ -280,8 +290,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == challengeQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialQCImageChanllengeList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCChanllengeExportDto)); } @@ -317,8 +328,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectExportDTO)); @@ -425,8 +437,9 @@ namespace IRaCIS.Core.Application.Service.Common exportInfo.CriterionName = await _repository.Where(u => u.TrialId == dto.TrialId && u.IsConfirm && u.Id == dto.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; var (memoryStream, fileName) = await ExcelExportHelper.DataExport_NpoiTestAsync(StaticData.Export.TrialSubjectProgressList_Export, exportInfo, /*"", */_commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SubjectProgressDto)); @@ -491,7 +504,7 @@ namespace IRaCIS.Core.Application.Service.Common } var memoryStream2 = new MemoryStream(); - wb.Write(memoryStream2,true); + wb.Write(memoryStream2, true); memoryStream2.Seek(0, SeekOrigin.Begin); return new FileStreamResult(memoryStream2, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") @@ -565,8 +578,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialStudyUploadMonitor_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(UnionStudyMonitorExportDto)); @@ -601,8 +615,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectReadingPeriodList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadPeriodExportDto)); @@ -690,8 +705,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == studyQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialStudyList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(UnionStudyExportDTO)); } @@ -729,8 +745,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == checkQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectVisitCheckList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(PMKCheckEXportDTO)); } @@ -780,8 +797,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReadingTaskList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReadingTaskExportDto)); } @@ -831,8 +849,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialReReadingTaskList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(ReReadingTaskExportDto)); } @@ -873,8 +892,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == inQuery.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialMedicalReviewList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TaskMedicalReviewExportDto)); } @@ -957,8 +977,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.CriterionName = await _repository.Where(u => u.TrialId == queryVisitTask.TrialId && u.IsConfirm && u.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync(); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSelfAnalysisList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(SelftAnalysisExport)); } @@ -1060,8 +1081,9 @@ namespace IRaCIS.Core.Application.Service.Common var exportInfo = (await _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); exportInfo.CriterionName = await _repository.Where(u => u.TrialId == queryVisitTask.TrialId && u.IsConfirm && u.Id == queryVisitTask.TrialReadingCriterionId).Select(t => t.CriterionName).FirstOrDefaultAsync(); - exportInfo.List = newList; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(newList, _userInfo.TimeZoneId); ; exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialGroupAnalysisList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(GroupAnalysisExport)); } @@ -1145,7 +1167,7 @@ namespace IRaCIS.Core.Application.Service.Common { foreach (var item in resultList) { - item.IsGenerateJudge = list.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode && t.VisitTaskNum>item.VisitTaskNum + item.IsGenerateJudge = list.Where(t => t.ReadingCategory == ReadingCategory.Judge && t.SubjectCode == item.SubjectCode && t.VisitTaskNum > item.VisitTaskNum ).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault()?.JudgeArmEnum == item.ArmEnum ? true : false; } } @@ -1213,8 +1235,9 @@ namespace IRaCIS.Core.Application.Service.Common //处理裁判标记 list = DealJudgeMark(criterion.ArbitrationRule, list); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.OverallTumorEvaluation_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(OverallTumorEvaluationExport), criterion.CriterionType); @@ -1272,8 +1295,9 @@ namespace IRaCIS.Core.Application.Service.Common //处理裁判标记 list = DealJudgeMark(criterion.ArbitrationRule, list); - exportInfo.List = list; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.RECIST1Point1EvaluationOfTumorEfficacy_Export, exportInfo, $"{exportInfo.ResearchProgramNo}_{exportInfo.CriterionName}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1EvaluationOfTumorEfficacyExport), criterion.CriterionType); @@ -1305,7 +1329,7 @@ namespace IRaCIS.Core.Application.Service.Common { //每次查询必须是单标准的 - var criterion = await _repository.Where(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName,t.ArbitrationRule }).FirstOrDefaultAsync(); + var criterion = await _repository.Where(t => t.Id == queryVisitTask.TrialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionName, t.ArbitrationRule }).FirstOrDefaultAsync(); var query = _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned) @@ -1363,8 +1387,9 @@ namespace IRaCIS.Core.Application.Service.Common //处理裁判标记 list = DealJudgeMark(criterion.ArbitrationRule, list); - exportInfo.List = exportList; + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(exportList, _userInfo.TimeZoneId); exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.RECIST1Point1DetailedOfEvaluatedLesion_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(RECIST1Point1DetailedOfEvaluatedLesionExport), criterion.CriterionType); @@ -1396,8 +1421,10 @@ namespace IRaCIS.Core.Application.Service.Common //处理裁判标记 list = DealJudgeMark(criterion.ArbitrationRule, list); - exportInfo.List = exportList; + + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(exportList, _userInfo.TimeZoneId); ; exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; return await ExcelExportHelper.DataExportAsync(StaticData.Export.PCWG3Point1DetailedOfEvaluatedLesion_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(PCWG3DetailedOfEvaluatedLesionExport), criterion.CriterionType); diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs index 6e0e3fe84..c403bbce3 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/UserTrialViewModel.cs @@ -6,6 +6,7 @@ using MiniExcelLibs.Attributes; using Newtonsoft.Json; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Helper; +using System; namespace IRaCIS.Application.Contracts { @@ -119,10 +120,11 @@ namespace IRaCIS.Application.Contracts public class ExcelExportInfo : TrialSelectDTO { - public string CurrentTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + public string CurrentTime => TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.Local, TimeZoneInfo.FindSystemTimeZoneById(ClientZoneId)).ToString("yyyy-MM-dd HH:mm:ss"); public bool IsEn_US { get; set; } + public string ClientZoneId { get; set; } = string.Empty; public object List { get; set; } } diff --git a/IRaCIS.Core.Infra.EFCore/AuthUser/UserInfo.cs b/IRaCIS.Core.Infra.EFCore/AuthUser/UserInfo.cs index 45e0ab3ec..61521c667 100644 --- a/IRaCIS.Core.Infra.EFCore/AuthUser/UserInfo.cs +++ b/IRaCIS.Core.Infra.EFCore/AuthUser/UserInfo.cs @@ -278,8 +278,8 @@ namespace IRaCIS.Core.Domain.Share return timeZoneId.Value; } - return "Etc/UTC"; - //return "Asia/Shanghai"; + //return "Etc/UTC"; + return "Asia/Shanghai"; } diff --git a/IRaCIS.Core.Infrastructure/Extention/ConvertToClientTimeResultFilter.cs b/IRaCIS.Core.Infrastructure/Extention/ConvertToClientTimeResultFilter.cs new file mode 100644 index 000000000..5126ae86f --- /dev/null +++ b/IRaCIS.Core.Infrastructure/Extention/ConvertToClientTimeResultFilter.cs @@ -0,0 +1,60 @@ +//using Microsoft.AspNetCore.Mvc.Filters; +//using Microsoft.AspNetCore.Mvc; +//using Newtonsoft.Json; +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using System.Threading.Tasks; +//using System.Text.RegularExpressions; + +//namespace IRaCIS.Core.Application.BusinessFilter +//{ +// public class ConvertToClientTimeResultFilter : IAsyncResultFilter +// { + + +// public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) +// { + +// //JsonConvert.DeserializeObject(jsonStr, new JsonSerializerSettings +// //{ +// // DateTimeZoneHandling = DateTimeZoneHandling.Local +// //}); + +// if (context.Result is ObjectResult objectResult) +// { +// var statusCode = objectResult.StatusCode ?? context.HttpContext.Response.StatusCode; + +// if (statusCode == 200) +// { +// var result = objectResult.Value; + +// // 将数据中的 DateTime 值转换为 DateTimeOffset,指定时区为东八区 +// ConvertDateTimeToDateTimeOffset(result); + +// // 使用 Newtonsoft.Json 序列化转换后的数据 +// string json = JsonConvert.SerializeObject(result); + +// // 重新设置 JsonResult 的值为处理后的数据 +// context.Result = new JsonResult(json); + +// } +// } + + +// // 执行动作方法 +// await next(); +// } + +// private void ConvertDateTimeToDateTimeOffset(object data) +// { +// // 假设客户端时区为东八区 +// TimeZoneInfo clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"); + +// // 将对象中的 DateTime 值转换为 DateTimeOffset,指定时区为东八区 +// string json = JsonConvert.SerializeObject(data); +// data = json.Replace("\"DateTime\":", "\"DateTimeOffset\":"); +// } +// } +//} diff --git a/IRaCIS.Core.Infrastructure/Extention/ExportExcelDateConverter.cs b/IRaCIS.Core.Infrastructure/Extention/ExportExcelDateConverter.cs new file mode 100644 index 000000000..434152ca4 --- /dev/null +++ b/IRaCIS.Core.Infrastructure/Extention/ExportExcelDateConverter.cs @@ -0,0 +1,83 @@ +using Newtonsoft.Json.Converters; +using Newtonsoft.Json; +using System; +using SharpCompress.Writers; + +namespace IRaCIS.Core.API._ServiceExtensions.NewtonsoftJson +{ + + + public class ExportExcelDateConverter : DateTimeConverterBase + { + private readonly TimeZoneInfo _clientTimeZone; + + public ExportExcelDateConverter(TimeZoneInfo clientTimeZone) + { + _clientTimeZone = clientTimeZone; + } + public override bool CanConvert(Type objectType) + { + + return objectType == typeof(DateTime) || objectType == typeof(DateTime?); + } + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + DateTime? nullableDateTime = value as DateTime?; + + if (nullableDateTime != null && nullableDateTime.HasValue) + { + // 将服务器时间转换为客户端时间 + DateTime clientTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, TimeZoneInfo.Local, _clientTimeZone); + writer.WriteValue(clientTime); + } + else + { + writer.WriteNull(); + } + + + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + DateTime? nullableDateTime = reader.Value as DateTime?; + + if (nullableDateTime != null && nullableDateTime.HasValue) + + { // 服务器时区的时间转为客户端时间 + var clientZoneTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, TimeZoneInfo.Local, _clientTimeZone); + + return clientZoneTime; + } + return reader.Value; + + + } + + + } + public class ExportExcelConverterDate + { + public static T ConvertToClientTimeInObject(T obj, string timeZoneId) + { + var clientTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); + if (obj == null) + return obj; + + // 将对象序列化为 JSON 字符串 + string json = JsonConvert.SerializeObject(obj); + + // 将 JSON 字符串反序列化回对象 + var deserializedObj = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + Converters = { new ExportExcelDateConverter(clientTimeZone) } + }); + + return deserializedObj!; + } + } +} + + + + From a5899023b90a933e2a5a422e367be4534a0b6f60 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 21 Feb 2024 14:33:38 +0800 Subject: [PATCH 2/3] =?UTF-8?q?[=E6=97=B6=E5=8C=BA=E4=BF=AE=E6=94=B9-?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=90=8D=E7=A7=B0]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TimeZoneAdjustmentMiddleware.cs | 3 +++ ...eConverter.cs => JSONTimeZoneConverter.cs} | 21 ++++++------------- .../NewtonsoftJson/NewtonsoftJsonSetup.cs | 4 ++-- 3 files changed, 11 insertions(+), 17 deletions(-) rename IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/{JSONCustomDateConverter.cs => JSONTimeZoneConverter.cs} (81%) diff --git a/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs b/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs index d7975a395..c3c71da2a 100644 --- a/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs +++ b/IRaCIS.Core.API/Middleware/TimeZoneAdjustmentMiddleware.cs @@ -7,6 +7,9 @@ using System.IO; using System.Text; using System.Threading.Tasks; +/// +/// 废弃,没用 +/// public class TimeZoneAdjustmentMiddleware { private readonly RequestDelegate _next; diff --git a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONCustomDateConverter.cs b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs similarity index 81% rename from IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONCustomDateConverter.cs rename to IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs index 0bb4eb356..75c5525ab 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONCustomDateConverter.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs @@ -9,16 +9,14 @@ using System.Globalization; namespace IRaCIS.Core.API { /// - /// 废弃,没用,不用这种处理方式 + /// 序列化,反序列化的时候,处理时间 时区转换 /// - public class JSONCustomDateConverter : DateTimeConverterBase + public class JSONTimeZoneConverter : DateTimeConverterBase { private readonly IHttpContextAccessor _httpContextAccessor; - private readonly string timeZoneId; - private readonly TimeZoneInfo _clientTimeZone; - public JSONCustomDateConverter(IHttpContextAccessor httpContextAccessor) + public JSONTimeZoneConverter(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; @@ -37,8 +35,6 @@ namespace IRaCIS.Core.API } - private static readonly TimeZoneInfo ChinaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Etc/UTC"); - public override bool CanConvert(Type objectType) { // 仅支持 DateTime 类型的转换 @@ -64,19 +60,14 @@ namespace IRaCIS.Core.API } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - - - - - + { DateTime? nullableDateTime = value as DateTime?; if (nullableDateTime != null && nullableDateTime.HasValue) { //第一个参数默认使用系统本地时区 也就是应用服务器的时区 - DateTime chinaTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, _clientTimeZone); - writer.WriteValue(chinaTime); + DateTime clientZoneTime = TimeZoneInfo.ConvertTime(nullableDateTime.Value, _clientTimeZone); + writer.WriteValue(clientZoneTime); } else { diff --git a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/NewtonsoftJsonSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/NewtonsoftJsonSetup.cs index 0ffcf0384..853afe9d3 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/NewtonsoftJsonSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/NewtonsoftJsonSetup.cs @@ -11,7 +11,7 @@ namespace IRaCIS.Core.API public static void AddNewtonsoftJsonSetup(this IMvcBuilder builder, IServiceCollection services) { services.AddHttpContextAccessor(); - services.AddScoped(); + services.AddScoped(); builder.AddNewtonsoftJson(options => { @@ -28,7 +28,7 @@ namespace IRaCIS.Core.API options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; //options.SerializerSettings.Converters.Add(new JSONCustomDateConverter()) ; - options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService()); + options.SerializerSettings.Converters.Add(services.BuildServiceProvider().GetService()); //IsoDateTimeConverter //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; From cef07a5bff3e43b65356b0b35e88270d821f2810 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 21 Feb 2024 15:28:08 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E3=80=90=E6=97=B6=E5=8C=BA=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B93=20=20=E5=89=8D=E7=AB=AF=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E4=BC=A0=E9=80=92=E2=80=9C=E2=80=9D=20=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NewtonsoftJson/JSONTimeZoneConverter.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs index 75c5525ab..af0b905b6 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/JSONTimeZoneConverter.cs @@ -43,20 +43,22 @@ namespace IRaCIS.Core.API public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - if (reader.Value == null) - return null; - else + DateTime? nullableDateTime = reader.Value as DateTime?; + + if (nullableDateTime != null && nullableDateTime.HasValue) { var dateTime = (DateTime)reader.Value; // 将客户端时间转换为服务器时区的时间 var serverZoneTime = TimeZoneInfo.ConvertTime(dateTime, _clientTimeZone, TimeZoneInfo.Local); - + return serverZoneTime; } - - // 在反序列化时,我们不需要此转换器,因此不实现此方法 - //throw new NotImplementedException(); + else + { + return null; + } + } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)