From a56319d8b6675d5c5eaff9fdf804928f73cebfe1 Mon Sep 17 00:00:00 2001 From: hardstylewyl <827778732@qq.com> Date: Mon, 24 Mar 2025 09:23:49 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E6=8C=89=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=9F=A5=E8=AF=A2=E8=BF=90=E8=BE=93=E6=97=B6=E6=95=88?= =?UTF-8?q?=E9=A2=84=E8=AD=A6=E6=98=8E=E7=BB=86=E5=8F=8D=E5=8F=82=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=20=20-=20=E7=94=B1=E4=BA=8E=E5=B7=B2=E8=B6=85?= =?UTF-8?q?=E6=97=B6=E7=8A=B6=E6=80=81=E4=B8=8D=E5=AE=9E=E6=97=B6=E7=BB=B4?= =?UTF-8?q?=E6=8A=A4=EF=BC=8C=E5=88=99=E9=9C=80=E8=A6=81=E6=9F=A5=E5=87=BA?= =?UTF-8?q?=E5=8D=B3=E5=B0=86=E8=B6=85=E6=97=B6=E7=9A=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=84=B6=E5=90=8E=E8=AE=A1=E7=AE=97=E7=8A=B6=E6=80=81=E5=90=8E?= =?UTF-8?q?=E5=9C=A8=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Transport/TransportWarningDetailsDto.cs | 222 +++++++++--------- .../Handlers/TransportWarningHandler.cs | 2 - .../Warning/TransportWarningService.cs | 15 +- 3 files changed, 122 insertions(+), 117 deletions(-) diff --git a/src/SJZY.Track.Application.Contract/Dtos/Warning/Transport/TransportWarningDetailsDto.cs b/src/SJZY.Track.Application.Contract/Dtos/Warning/Transport/TransportWarningDetailsDto.cs index 1ef707f3..55dfafeb 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/Warning/Transport/TransportWarningDetailsDto.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/Warning/Transport/TransportWarningDetailsDto.cs @@ -3,147 +3,147 @@ namespace SJZY.Track.Application.Contract.Dtos.Warning.Transport; /// /// 运输时效预警明细 /// -public sealed class TransportWarningDetailsDto // todo:需要根据状态排序 +public sealed class TransportWarningDetailsDto { - /// - /// 预警明细唯一id - /// - public string EsId { get; set; } + /// + /// 预警明细唯一id + /// + public string EsId { get; set; } - /// - /// 子系统id - /// - public int SubSystemId { get; set; } + /// + /// 子系统id + /// + public int SubSystemId { get; set; } - /// - /// 子系统名称 - /// - public string SubSystemName { get; set; } // todo:id换名称 + /// + /// 子系统名称 + /// + public string SubSystemName { get; set; } - /// - /// 客户id - /// - public int CustomId { get; set; } + /// + /// 客户id + /// + public int CustomId { get; set; } - /// - /// 客户简称 - /// - public string CustomName { get; set; } // todo:id换名称 + /// + /// 客户简称 + /// + public string CustomName { get; set; } - /// - /// 订单id - /// - public int OrderId { get; set; } + /// + /// 订单id + /// + public int OrderId { get; set; } - /// - /// 订单号 - /// - public string OrderNo { get; set; } + /// + /// 订单号 + /// + public string OrderNo { get; set; } - /// - /// 订单类型 - /// - public int OrderType { get; set; } + /// + /// 订单类型 + /// + public int OrderType { get; set; } - /// - /// 订单类型名称 - /// - public string OrderTypeName { get; set; } // todo:type换名称 + /// + /// 订单类型名称 + /// + public string OrderTypeName { get; set; } - // 实时属性 todo:从es查询 + // 实时属性 tips:从es查询 - /// - /// 最新轨迹内容 - /// - public string? LatestTrackContent { get; set; } + /// + /// 最新轨迹内容 + /// + public string? LatestTrackContent { get; set; } - /// - /// 最新轨迹时间 - /// - public DateTime? LatestTrackTime { get; set; } + /// + /// 最新轨迹时间 + /// + public DateTime? LatestTrackTime { get; set; } - /// - /// 最新轨迹发生时区 - /// - public float? LatestTrackTimeZone { get; set; } + /// + /// 最新轨迹发生时区 + /// + public float? LatestTrackTimeZone { get; set; } - /// - /// 最新轨迹发生地 - /// - public string? LatestTrackPlace { get; set; } + /// + /// 最新轨迹发生地 + /// + public string? LatestTrackPlace { get; set; } - /// - /// 通知对象 - /// - public string NotifyUserNames { get; set; } + /// + /// 通知对象 + /// + public string NotifyUserNames { get; set; } - /// - /// 起始轨迹状态 - /// - public string StartTrackStatus { get; set; } + /// + /// 起始轨迹状态 + /// + public string StartTrackStatus { get; set; } - /// - /// 起始轨迹内容 - /// - public string StartTrackContent { get; set; } + /// + /// 起始轨迹内容 + /// + public string StartTrackContent { get; set; } - /// - /// 起始轨迹发生时间 - /// - public DateTime StartTrackTime { get; set; } + /// + /// 起始轨迹发生时间 + /// + public DateTime StartTrackTime { get; set; } - /// - /// 起始轨迹时区 - /// - public float StartTrackTimeZone { get; set; } + /// + /// 起始轨迹时区 + /// + public float StartTrackTimeZone { get; set; } - /// - /// 截止轨迹状态 - /// - public string EndTrackStatus { get; set; } + /// + /// 截止轨迹状态 + /// + public string EndTrackStatus { get; set; } - /// - /// 截止轨迹内容 - /// - public string? EndTrackContent { get; set; } + /// + /// 截止轨迹内容 + /// + public string? EndTrackContent { get; set; } - /// - /// 截止轨迹发生时间 - /// - public DateTime? EndTrackTime { get; set; } + /// + /// 截止轨迹发生时间 + /// + public DateTime? EndTrackTime { get; set; } - /// - /// 截止轨迹时区 - /// - public float? EndTrackTimeZone { get; set; } + /// + /// 截止轨迹时区 + /// + public float? EndTrackTimeZone { get; set; } - /// - /// 预警名称 (预警主体名称 如字节全程时效) - /// - public string WarningName { get; set; } + /// + /// 预警名称 (预警主体名称 如字节全程时效) + /// + public string WarningName { get; set; } - /// - /// 预警规则描述(用于tooltip展示) - /// - public string WarningRuleDescription { get; set; } + /// + /// 预警规则描述(用于tooltip展示) + /// + public string WarningRuleDescription { get; set; } - /// - /// 累计运输时间 - /// - public string CumulativeTimeSpan { get; set; } // todo:需要转换为某个格式 + /// + /// 累计运输时间 + /// + public string CumulativeTimeSpan { get; set; } - /// - /// 预警状态 (根据key展示对应名称,即将超时需要标红) - /// 1:即将超时 2:已超时 3:已完成 4:超时完成 5:已关闭,初始为【即将超时】 - /// - public int Status { get; set; } + /// + /// 预警状态 (根据key展示对应名称,即将超时需要标红) + /// 1:即将超时 2:已超时 3:已完成 4:超时完成 5:已关闭,初始为【即将超时】 + /// + public int Status { get; set; } - /// - /// 预警创建时间 - /// - public DateTime CreateTime { get; set; } + /// + /// 预警创建时间 + /// + public DateTime CreateTime { get; set; } } diff --git a/src/SJZY.Track.Application/Services/Warning/Handlers/TransportWarningHandler.cs b/src/SJZY.Track.Application/Services/Warning/Handlers/TransportWarningHandler.cs index cc167d95..7d25b21e 100644 --- a/src/SJZY.Track.Application/Services/Warning/Handlers/TransportWarningHandler.cs +++ b/src/SJZY.Track.Application/Services/Warning/Handlers/TransportWarningHandler.cs @@ -1235,8 +1235,6 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen CreateTime = DateTime.Now, }; - // 一开始创建预警就可能为已超时的状态 - detail.Status = detail.CalcStatus(); return detail; } diff --git a/src/SJZY.Track.Application/Services/Warning/TransportWarningService.cs b/src/SJZY.Track.Application/Services/Warning/TransportWarningService.cs index cd0bbc28..5cc3abba 100644 --- a/src/SJZY.Track.Application/Services/Warning/TransportWarningService.cs +++ b/src/SJZY.Track.Application/Services/Warning/TransportWarningService.cs @@ -171,6 +171,9 @@ public class TransportWarningService : ApplicationService public async Task> GetPageTransportWarningDetails(GetPageTransportWarningDetailsInput input) { var vo = ObjectMapper.Map(input); + // 存储只存即将超时,对于已超时的则是查出计算后过滤 + if (input.Status == (int) TransportWarningStatus.已超时) + vo.Status = (int) TransportWarningStatus.即将超时; var result = await _warningDetailsEsRepository.GetPageTransportWarningDetailsAsync(vo); if (result.List.Count == 0) { @@ -247,19 +250,23 @@ public class TransportWarningService : ApplicationService }; }); - var sorted = map.OrderBy(x => + // 计算后的状态过滤 + var filtered = map.WhereIf(input.Status > 0, x => x.Status == input.Status); + + // 按状态排序 + var sorted = filtered.OrderBy(x => { // 即将超时,已超时置顶 if (x.Status is 1 or 2) return x.Status; // 其他按创建时间从早到晚 return DateTimeHelper.ConvertToUnixTimestamp(x.CreateTime); - }); + }).ToList(); return new UnifyPageResultDto( - sorted.ToList(), + sorted, result.Pagination.PageIndex, result.Pagination.PageSize, - result.Pagination.Total); + sorted.Count); // 通知用户提取用户名称 string ToUserNames(string notifyUsers) From b93386d19cafb19982ab93de55078fe5e70f9c9c Mon Sep 17 00:00:00 2001 From: hardstylewyl <827778732@qq.com> Date: Mon, 24 Mar 2025 10:43:34 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E8=BF=90=E8=BE=93=E6=97=B6=E6=95=88?= =?UTF-8?q?=E9=A2=84=E8=AD=A6=20=20-=20=E8=A1=A5=E5=85=85=E6=98=8E?= =?UTF-8?q?=E7=BB=86=E6=88=AA=E6=AD=A2=E8=BD=A8=E8=BF=B9=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E7=9A=84=E6=9B=B4=E6=96=B0=20=20-=20=E9=A2=84=E8=AD=A6?= =?UTF-8?q?=E6=98=8E=E7=BB=86=E6=A0=BC=E5=BC=8F=E5=8C=96=E6=97=B6=E5=8C=BA?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=20=20-=20=E9=A2=84=E8=AD=A6=E6=98=8E?= =?UTF-8?q?=E7=BB=86=E6=8E=92=E5=BA=8F=E4=BF=AE=E5=A4=8D=20=20-=20?= =?UTF-8?q?=E6=98=8E=E7=BB=86=E5=A7=8B=E7=BB=88=E5=AD=98=E5=82=A8=E8=B5=B7?= =?UTF-8?q?=E5=A7=8B=E8=BD=A8=E8=BF=B9=E7=8A=B6=E6=80=81=E7=9A=84=E6=9C=80?= =?UTF-8?q?=E6=97=A9=E8=BD=A8=E8=BF=B9=20=20-=20=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E8=A7=84=E5=88=99=E5=8F=98=E6=9B=B4=E5=90=8C=E6=AD=A5=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E9=A2=84=E8=AD=A6=E6=98=8E=E7=BB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Transport/TransportWarningDetailsDto.cs | 10 ++--- .../EventHandlers/TrackDeleteEventHandler.cs | 2 +- .../Handlers/TransportWarningHandler.cs | 32 +++++++++------ .../Warning/TransportWarningService.cs | 41 ++++++++++++++----- .../Transport/TransportWarningDetailsIndex.cs | 2 +- .../WarningDetailsEsRepository.cs | 3 ++ 6 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/SJZY.Track.Application.Contract/Dtos/Warning/Transport/TransportWarningDetailsDto.cs b/src/SJZY.Track.Application.Contract/Dtos/Warning/Transport/TransportWarningDetailsDto.cs index 55dfafeb..15aada78 100644 --- a/src/SJZY.Track.Application.Contract/Dtos/Warning/Transport/TransportWarningDetailsDto.cs +++ b/src/SJZY.Track.Application.Contract/Dtos/Warning/Transport/TransportWarningDetailsDto.cs @@ -66,7 +66,7 @@ public sealed class TransportWarningDetailsDto /// /// 最新轨迹发生时区 /// - public float? LatestTrackTimeZone { get; set; } + public string LatestTrackTimeZone { get; set; } /// /// 最新轨迹发生地 @@ -94,9 +94,9 @@ public sealed class TransportWarningDetailsDto public DateTime StartTrackTime { get; set; } /// - /// 起始轨迹时区 + /// 起始轨迹时区 e.g GMT +8:00 / -- /// - public float StartTrackTimeZone { get; set; } + public string StartTrackTimeZone { get; set; } /// @@ -115,9 +115,9 @@ public sealed class TransportWarningDetailsDto public DateTime? EndTrackTime { get; set; } /// - /// 截止轨迹时区 + /// 截止轨迹时区 e.g GMT +8:00 / -- /// - public float? EndTrackTimeZone { get; set; } + public string EndTrackTimeZone { get; set; } /// diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs index 281e01e8..d4cabf99 100644 --- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs +++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs @@ -393,8 +393,8 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe var handler3 = scope.ServiceProvider.GetRequiredService(); await Task.Delay(1500); //确保落盘 - await handler2.TrackDeletedHandleAsync(signals); await handler.TrackDeletedHandleAsync(signals); + await handler2.TrackDeletedHandleAsync(signals); await handler3.TrackUpdatedOrDeletedHandleAsync(signals.Cast().ToList()); } finally diff --git a/src/SJZY.Track.Application/Services/Warning/Handlers/TransportWarningHandler.cs b/src/SJZY.Track.Application/Services/Warning/Handlers/TransportWarningHandler.cs index 7d25b21e..03f7dde2 100644 --- a/src/SJZY.Track.Application/Services/Warning/Handlers/TransportWarningHandler.cs +++ b/src/SJZY.Track.Application/Services/Warning/Handlers/TransportWarningHandler.cs @@ -183,30 +183,30 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen // 存在起始状态最早轨迹? // 最早轨迹如果早于预警明细中的起始轨迹时间,则修改预警明细 // todo:时区信息如果未提供则比较时间无意义!!,出现一个有时区一个无时区(后续可能强约束时区必填)? - var updateDetails = details - .Where(d => earliestTrack.GetUtc0TrackTime() < d.GetUtc0StartTrackTime()) - .ToList(); - foreach (var detail in updateDetails) + foreach (var detail in details) { - //剩余轨迹中的最早发生时间早于轨迹明细中,修改明细信息 + //保持预警明细中始终为起始状态的最早轨迹 detail.StartTrackContentId = earliestTrack.TrackContentId; detail.StartTrackContent = earliestTrack.TrackContent; detail.StartTrackTime = earliestTrack.TrackTime; detail.StartTrackTimeZone = earliestTrack.TrackTimeZone; } - needUpdateDetails.AddRange(updateDetails); + needUpdateDetails.AddRange(details); } } // 批量处理 - await _warningTaskRepository.BulkUpdateTransportWarningDetailsGenerateTaskAsync(needUpdateGenerateTask); - await _warningDetailsEsRepository.BulkUpdateTransportWarningDetailsAsync(needUpdateDetails); - await _warningTaskRepository.CloseWarningNotifyTaskAsync(x => - !x.IsClosed - && x.WarningType == WarningRuleType.运输时效预警.GetHashCode() - && needCloseNotifyWarningDetailsIds.Contains(x.WarningDetailsId) - ); + if (needUpdateGenerateTask.Count > 0) + await _warningTaskRepository.BulkUpdateTransportWarningDetailsGenerateTaskAsync(needUpdateGenerateTask); + if (needUpdateDetails.Count > 0) + await _warningDetailsEsRepository.BulkUpdateTransportWarningDetailsAsync(needUpdateDetails); + if (needCloseNotifyWarningDetailsIds.Count > 0) + await _warningTaskRepository.CloseWarningNotifyTaskAsync(x => + !x.IsClosed + && x.WarningType == WarningRuleType.运输时效预警.GetHashCode() + && needCloseNotifyWarningDetailsIds.Contains(x.WarningDetailsId) + ); } #endregion @@ -579,6 +579,7 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen } // 4.仍然命中场景的订单需要修改明细中的内容(预警名称,预警规则描述) + var needUpdateDetails = new List(); if (reHitSceneOrderIds.Count != 0) { // 明细->规则 @@ -598,9 +599,14 @@ public class TransportWarningHandler : ITransportWarningHandler, ITransientDepen var ruleItem = ruleItemDict[detail.WarningSceneRuleItemId]; detail.WarningName = rule.Name; detail.WarningRuleDescription = detail.GetWarningRuleDescription(postScene.ToEntity(), ruleItem, ruleArea); + needUpdateDetails.Add(detail); } } + // 更新预警明细 + if (needUpdateDetails.Count > 0) + await _warningDetailsEsRepository.BulkUpdateTransportWarningDetailsAsync(needUpdateDetails); + if (noHitSceneOrderIds.Count == 0) return; diff --git a/src/SJZY.Track.Application/Services/Warning/TransportWarningService.cs b/src/SJZY.Track.Application/Services/Warning/TransportWarningService.cs index 5cc3abba..fd54a481 100644 --- a/src/SJZY.Track.Application/Services/Warning/TransportWarningService.cs +++ b/src/SJZY.Track.Application/Services/Warning/TransportWarningService.cs @@ -223,20 +223,20 @@ public class TransportWarningService : ApplicationService // 最新轨迹 (不冗余) LatestTrackContent = orderIdTrack?.TrackContent, LatestTrackTime = orderIdTrack?.TrackTime, - LatestTrackTimeZone = orderIdTrack?.TrackTimeZone, + LatestTrackTimeZone = FormatTimeZone(orderIdTrack?.TrackTimeZone), LatestTrackPlace = orderIdTrack?.TrackContent, // 起始轨迹 StartTrackStatus = x.StartTrackStatus, StartTrackContent = x.StartTrackContent, StartTrackTime = x.StartTrackTime, - StartTrackTimeZone = x.StartTrackTimeZone, + StartTrackTimeZone = FormatTimeZone(x.StartTrackTimeZone), // 截止轨迹 EndTrackStatus = x.EndTrackStatus, EndTrackContent = x.EndTrackContent, EndTrackTime = x.EndTrackTime, - EndTrackTimeZone = x.EndTrackTimeZone, + EndTrackTimeZone = FormatTimeZone(x.EndTrackTimeZone), WarningName = x.WarningName, WarningRuleDescription = x.WarningRuleDescription, @@ -253,14 +253,17 @@ public class TransportWarningService : ApplicationService // 计算后的状态过滤 var filtered = map.WhereIf(input.Status > 0, x => x.Status == input.Status); - // 按状态排序 - var sorted = filtered.OrderBy(x => - { - // 即将超时,已超时置顶 - if (x.Status is 1 or 2) return x.Status; - // 其他按创建时间从早到晚 - return DateTimeHelper.ConvertToUnixTimestamp(x.CreateTime); - }).ToList(); + // 按状态+时间排序 + var sorted = filtered + .OrderBy(x => + { + // 即将超时,已超时置顶 + if (x.Status is 1 or 2) return x.Status; + // 其他按创建时间从早到晚 + return DateTimeHelper.ConvertToUnixTimestamp(x.CreateTime); + }) + .ThenByDescending(x => x.CreateTime) //同状态(即将超时/已超时)按创建时间从晚到早 + .ToList(); return new UnifyPageResultDto( sorted, @@ -286,6 +289,22 @@ public class TransportWarningService : ApplicationService return $"{timeSpan.Days:00}天{timeSpan.Hours:00}小时{timeSpan.Minutes:00}分钟"; } + + // 格式化时区 + string FormatTimeZone(float? timezone) + { + if (timezone == null) return "--"; + + if (Math.Abs(timezone.Value - GlobalConst.NoneTrackTimeZone) < 1) return "--"; + + // 将小数形式的小时转换为时区偏移量 + var hours = (int) timezone.Value; // 提取整数部分作为小时 + var minutes = (int) ((timezone.Value - hours) * 60); // 将小数部分乘以 60 转换为分钟 + var offset = new TimeSpan(hours, minutes, 0); + var timeZoneStr = offset.ToString(); + var flag = timezone > 0f ? "+" : ""; + return $"GMT {flag}{timeZoneStr.RemovePostFix(":00")}"; + } } /// diff --git a/src/SJZY.Track.Domain/Aggregates/WarningAggregate/Transport/TransportWarningDetailsIndex.cs b/src/SJZY.Track.Domain/Aggregates/WarningAggregate/Transport/TransportWarningDetailsIndex.cs index 5d2a0429..bd8f35ee 100644 --- a/src/SJZY.Track.Domain/Aggregates/WarningAggregate/Transport/TransportWarningDetailsIndex.cs +++ b/src/SJZY.Track.Domain/Aggregates/WarningAggregate/Transport/TransportWarningDetailsIndex.cs @@ -133,7 +133,7 @@ public sealed class TransportWarningDetailsIndex : IdBaseIndex // 规则配置信息 res.Append($",生成预警时间{ruleItem.StartTrackWarningTimeSpan}小时" + - $",提醒时效{ruleItem.TransportTimeSpan}}}"); + $",时效{ruleItem.TransportTimeSpan}}}小时"); return res.ToString(); } diff --git a/src/SJZY.Track.Repository/Repositories/WarningDetailsEsRepository.cs b/src/SJZY.Track.Repository/Repositories/WarningDetailsEsRepository.cs index 2a3f1029..c5021853 100644 --- a/src/SJZY.Track.Repository/Repositories/WarningDetailsEsRepository.cs +++ b/src/SJZY.Track.Repository/Repositories/WarningDetailsEsRepository.cs @@ -144,6 +144,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien detail.StartTrackTimeZone, detail.EndTrackStatusId, detail.EndTrackContentId, + detail.EndTrackContent, detail.EndTrackTime, detail.EndTrackTimeZone, // detail.LatestTrackContentId, @@ -193,6 +194,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien ctx._source.startTrackTimeZone = params.StartTrackTimeZone; ctx._source.endTrackStatusId = params.EndTrackStatusId; ctx._source.endTrackContentId = params.EndTrackContentId; + ctx._source.endTrackContent = params.EndTrackContent; ctx._source.endTrackTime = params.EndTrackTime; ctx._source.endTrackTimeZone = params.EndTrackTimeZone; //ctx._source.latestTrackContentId = params.LatestTrackContentId; @@ -225,6 +227,7 @@ public class WarningDetailsEsRepository : IWarningDetailsEsRepository, ITransien .Add("StartTrackTimeZone", detail.StartTrackTimeZone) .Add("EndTrackStatusId", detail.EndTrackStatusId) .Add("EndTrackContentId", detail.EndTrackContentId) + .Add("EndTrackContent", detail.EndTrackContent) .Add("EndTrackTime", detail.EndTrackTime) .Add("EndTrackTimeZone", detail.EndTrackTimeZone) // .Add("LatestTrackContentId", detail.LatestTrackContentId)