Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ public sealed class FailureReasonDetailExportItem
public string FailureReason { get; init; } = string.Empty;

[ExporterHeader(DisplayName = "预计发送时间")]
public DateTimeOffset? ExpectSendTime { get; init; }
public DateTime? ExpectSendTime { get; init; }

[ExporterHeader(DisplayName = "实际发送时间")]
public DateTimeOffset? SendTime { get; init; }
public DateTime? SendTime { get; init; }

[ExporterHeader(DisplayName = "消息ID")]
public string MessageId { get; init; } = string.Empty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,14 @@ public async Task ExportChannelFailureReasonDetailsAsync(ExportChannelFailureRea
var exportQuery = records
.Where(x => x.Success == false)
.OrderByDescending(x => x.SendTime ?? x.ExpectSendTime ?? DateTimeOffset.MinValue)
.Select(x => new FailureReasonDetailExportItem
.Select(x => new
{
DisplayName = x.DisplayName,
ChannelUserIdentity = x.ChannelUserIdentity,
FailureReason = string.IsNullOrWhiteSpace(x.FailureReason) ? "Unknown" : x.FailureReason,
ExpectSendTime = x.ExpectSendTime,
SendTime = x.SendTime,
MessageId = x.MessageId
x.DisplayName,
x.ChannelUserIdentity,
x.FailureReason,
x.ExpectSendTime,
x.SendTime,
x.MessageId
});

const int maxExportCount = 100000;
Expand All @@ -191,7 +191,17 @@ public async Task ExportChannelFailureReasonDetailsAsync(ExportChannelFailureRea
{
throw new UserFriendlyException("导出数据量过大,请缩小筛选范围");
}
var exportItems = await exportQuery.ToListAsync();
var exportRecords = await exportQuery.ToListAsync();
var exportTimeZone = CultureTimeZoneResolver.GetDefaultCultureTimeZone();
var exportItems = exportRecords.Select(x => new FailureReasonDetailExportItem
{
DisplayName = x.DisplayName,
ChannelUserIdentity = x.ChannelUserIdentity,
FailureReason = string.IsNullOrWhiteSpace(x.FailureReason) ? "Unknown" : x.FailureReason,
ExpectSendTime = CultureTimeZoneResolver.ConvertTime(x.ExpectSendTime, exportTimeZone),
SendTime = CultureTimeZoneResolver.ConvertTime(x.SendTime, exportTimeZone),
MessageId = x.MessageId
}).ToList();

query.Result = await _exporter.ExportAsByteArray(exportItems);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the Apache License. See LICENSE.txt in the project root for license information.

namespace Masa.Mc.Service.Admin.Infrastructure.Extensions;
namespace Masa.Mc.Service.Admin.Infrastructure.Culture;

public static class CultureConfiguration
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the Apache License. See LICENSE.txt in the project root for license information.

namespace Masa.Mc.Service.Admin.Infrastructure.Culture;

public static class CultureTimeZoneResolver
{
private static readonly IReadOnlyDictionary<string, string> RegionTimeZoneIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
["CN"] = "China Standard Time"
};

public static TimeZoneInfo GetDefaultCultureTimeZone()
{
var culture = System.Globalization.CultureInfo.DefaultThreadCurrentCulture
?? System.Globalization.CultureInfo.DefaultThreadCurrentUICulture
?? System.Globalization.CultureInfo.CurrentCulture;

return GetCultureTimeZone(culture);
}

public static DateTime? ConvertToDefaultCultureTime(DateTimeOffset? time)
{
return ConvertTime(time, GetDefaultCultureTimeZone());
}

public static DateTime? ConvertTime(DateTimeOffset? time, TimeZoneInfo timeZone)
{
if (!time.HasValue)
{
return null;
}

return TimeZoneInfo.ConvertTime(time.Value, timeZone).DateTime;
}

private static TimeZoneInfo GetCultureTimeZone(System.Globalization.CultureInfo culture)
{
if (TryGetRegionName(culture, out var regionName) &&
RegionTimeZoneIds.TryGetValue(regionName, out var timeZoneId))
{
return TimeZoneUtil.FindTimeZoneById(timeZoneId);
}

return TimeZoneInfo.Utc;
}

private static bool TryGetRegionName(System.Globalization.CultureInfo culture, out string regionName)
{
regionName = string.Empty;

if (culture.IsNeutralCulture || string.IsNullOrWhiteSpace(culture.Name))
{
return false;
}

try
{
regionName = new System.Globalization.RegionInfo(culture.Name).TwoLetterISORegionName;
return true;
}
catch (ArgumentException)
{
return false;
}
}

}
1 change: 1 addition & 0 deletions src/Services/Masa.Mc.Service/_Imports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
global using Masa.Mc.Service.Admin.EntityFrameworkCore;
global using Masa.Mc.Service.Admin.Infrastructure.Authentication;
global using Masa.Mc.Service.Admin.Infrastructure.ChannelUserFinder.Provider.Auth;
global using Masa.Mc.Service.Admin.Infrastructure.Culture;
global using Masa.Mc.Service.Admin.Infrastructure.Extensions;
global using Masa.Mc.Service.Admin.Infrastructure.MessageTaskJobService;
global using Masa.Mc.Service.Admin.Infrastructure.Middleware;
Expand Down
Loading