diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs
index bd7a5c2f..e0e1e796 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs
@@ -30,7 +30,9 @@ public class BatchUpsertTrackInput : OrderNosInfo
public DateTime TrackTime { get; set; }
///
- /// 更改后的轨迹发生时间,无需更改保持为空
+ /// 新的轨迹发生时间
+ /// 如果是新增,那么优先级高于TrackTime
+ /// 如果要修改TrackTime,请同时传递TrackTime(旧的用于匹配),和NewTrackTime
///
public DateTime? NewTrackTime { get; set; }
@@ -39,7 +41,7 @@ public class BatchUpsertTrackInput : OrderNosInfo
///
// [Required]
// [Range(-12, 12)]
- public float TrackTimeZone { get; set; }
+ public float? TrackTimeZone { get; set; }
///
/// 客户是否可见
@@ -136,6 +138,13 @@ public class BatchUpsertTrackInput : OrderNosInfo
///
public string? Extra { get; set; }
+ ///
+ /// 新的扩展信息,
+ /// 如果是新增,那么优先级高于Extra
+ /// 如果要修改Extra,请同时传递Extra(用于匹配旧的)和NewExtra
+ ///
+ public string? NewExtra { get; set; }
+
///
/// 是否强制推送
///
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs
index 961841a6..f8fb030b 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs
@@ -35,7 +35,9 @@ public class UpsertTrackInput : OrderNoInfo
public DateTime TrackTime { get; set; }
///
- /// 更改后的轨迹发生时间,无需更改保持为空
+ /// 新的轨迹发生时间
+ /// 如果是新增,那么优先级高于TrackTime
+ /// 如果要修改TrackTime,请同时传递TrackTime(旧的用于匹配),和NewTrackTime
///
public DateTime? NewTrackTime { get; set; }
@@ -145,6 +147,13 @@ public class UpsertTrackInput : OrderNoInfo
///
public string? Extra { get; set; }
+ ///
+ /// 新的扩展信息,
+ /// 如果是新增,那么优先级高于Extra
+ /// 如果要修改Extra,请同时传递Extra(用于匹配旧的)和NewExtra
+ ///
+ public string? NewExtra { get; set; }
+
///
/// 是否强制推送
///
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs
index 182672cb..d6df40bb 100644
--- a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs
+++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs
@@ -55,7 +55,9 @@ public class TrackUpsertEvent
public DateTime TrackTime { get; set; }
///
- /// 更改后的轨迹发生时间,无需更改保持为空
+ /// 新的轨迹发生时间
+ /// 如果是新增,那么优先级高于TrackTime
+ /// 如果要修改TrackTime,请同时传递TrackTime(旧的用于匹配),和NewTrackTime
///
public DateTime? NewTrackTime { get; set; }
@@ -162,6 +164,13 @@ public class TrackUpsertEvent
///
public string? Extra { get; set; }
+ ///
+ /// 新的扩展信息,
+ /// 如果是新增,那么优先级高于Extra
+ /// 如果要修改Extra,请同时传递Extra(用于匹配旧的)和NewExtra
+ ///
+ public string? NewExtra { get; set; }
+
///
/// 是否强制推送
///
diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs
index c5465d51..030eb361 100644
--- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs
+++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs
@@ -289,55 +289,26 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
var existTracks = tracks.Where(x => x.OrderId == order.OrderId).ToList();
- if (@event.CompareFields.IsNullOrEmpty())
+ // tips:如果没传时区则使用+8兜底进行过滤
+ var timezone = Math.Abs(@event.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 0.01f ? 8.0f : @event.TrackTimeZone;
+
+ // 根据时间过滤
+ existTracks = @event.IsAdd
+ ? existTracks.Where(x => x.GetUtc0TrackTime() == (@event.NewTrackTime ?? @event.TrackTime).Subtract(TimeSpan.FromHours(timezone))).ToList()
+ : existTracks.Where(x =>
+ x.GetUtc0TrackTime() == @event.TrackTime.Subtract(TimeSpan.FromHours(timezone))
+ // 修改了并且修改了时间
+ || (@event.NewTrackTime != null && x.GetUtc0TrackTime() == @event.NewTrackTime.Value.Subtract(TimeSpan.FromHours(timezone)))
+ ).ToList();
+
+ // 根据扩展信息过滤
+ existTracks = @event.IsAdd
+ ? existTracks.Where(x => x.Extra == (@event.NewExtra ?? @event.Extra)).ToList()
+ : existTracks.Where(x => x.Extra == @event.Extra || x.Extra == @event.NewExtra).ToList();
+
+ if (@event.IsAdd)
{
- existTracks = existTracks.Where(x => x.TrackTime == @event.TrackTime).ToList();
- }
- else
- {
- Debug.Assert(@event.CompareFields != null, "@event.CompareFields != null");
- var extraDict = TextJsonHelper.DeserializeToDictionary(@event.Extra);
- if (extraDict == null || !extraDict.TryGetValue(@event.CompareFields, out var compareValue))
- {
- throw new BusinessException(message: $"请检查拓展字段,为什么找不到比较字段:{@event.CompareFields}");
- }
-
- existTracks = existTracks.Where(x =>
- {
- var oldExtraDict = TextJsonHelper.DeserializeToDictionary(x.Extra);
- // tips:注意兼容性,历史轨迹的字段可能为空
- if (oldExtraDict == null || !oldExtraDict.TryGetValue(@event.CompareFields, out var oldValue))
- {
- return false;
- }
-
- return TextJsonHelper.EqJsonElement(oldValue, compareValue);
- }).ToList();
- }
-
- var track = existTracks.FirstOrDefault();
-
- if (!@event.IsAdd)
- {
- if (existTracks.Count > 1)
- {
- _logger.LogInformation("订单存在多条轨迹不允许修改:{@event}", @event);
- continue;
- }
-
- if (track == null)
- {
- _logger.LogInformation("订单不存在轨迹不允许修改:{@event}", @event);
- continue; // 不存在不让改
- }
-
- updateTracks.Add(BuiltUpdateTrack(@event, track, order, trackContent));
- operationRecords.Add(BuildOrderOperationRecord(@event, track, order));
- }
- else
- {
- // 不允许重复轨迹,跳过
- if (!trackContent.IsRepeatable && existTracks.Count > 0)
+ if (existTracks.Count > 0)
{
_logger.LogInformation("订单已经存在不允许重复的轨迹,不允许重复添加:{@event}", @event);
continue;
@@ -345,6 +316,26 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
insertTracks.Add(BuiltNewTrack(@event, order, trackContent));
}
+ else
+ {
+ // 不存在不让改
+ if (existTracks.Count == 0)
+ {
+ _logger.LogInformation("订单不存在轨迹,不允许修改:{@event}", @event);
+ continue;
+ }
+
+ if (existTracks.Count > 1)
+ {
+ _logger.LogInformation("订单存在多条轨迹不允许修改:{@event}", @event);
+ continue;
+ }
+
+ var track = existTracks.First();
+ updateTracks.Add(BuiltUpdateTrack(@event, track, order, trackContent));
+ operationRecords.Add(BuildOrderOperationRecord(@event, track, order));
+ }
+
canNextOrderIds.Add(order.OrderId);
}
@@ -406,7 +397,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
track.TrackPlacePostcode = @event.TrackPlacePostcode ?? GlobalConst.EmptyString;
track.DestinationTimeZone = @event.DestinationTimeZone;
track.EstimatedDeliveryDate = @event.EstimatedDeliveryDate;
- track.Extra = @event.Extra;
+ track.Extra = @event.NewExtra ?? @event.Extra;
return track;
}
@@ -456,7 +447,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
TrackPlacePostcode = @event.TrackPlacePostcode ?? GlobalConst.EmptyString,
DestinationTimeZone = @event.DestinationTimeZone,
EstimatedDeliveryDate = @event.EstimatedDeliveryDate,
- Extra = @event.Extra
+ Extra = @event.NewExtra ?? @event.Extra,
};
track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
index f74c501e..d0f5a4aa 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Http;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Application.Contract.Services.ProvideServices;
+using SJZY.Track.Application.Helpers;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
@@ -289,10 +290,12 @@ public partial class TrackService : ApplicationService, ITrackService
input.TrackCode,
input.Source,
input.TrackTime,
+ input.TrackTimeZone ?? 8.0f, //没传时区默认使用+8参与过滤
input.NewTrackTime,
input.EstimatedDeliveryDate,
input.DestinationTimeZone,
input.Extra,
+ input.NewExtra,
input.CompareFields);
var userInfo = await _requestCurrentUserService.Service.GetCurrentUserBasicInfoAsync();
@@ -308,6 +311,7 @@ public partial class TrackService : ApplicationService, ITrackService
var name = userInfo.Data.UserName;
// 新增/更新轨迹
+ input.TrackTimeZone ??= GlobalConst.NoneTrackTimeZone; //时区为空使用一个特殊值填充
var @event = ObjectMapper.Map(input);
@event.SubSystemId = input.SubSystemId;
@event.CustomId = order.CustomId;
@@ -366,10 +370,12 @@ public partial class TrackService : ApplicationService, ITrackService
input.TrackCode,
input.Source,
input.TrackTime,
+ input.TrackTimeZone ?? 8.0f, //没传时区默认使用+8参与过滤
input.NewTrackTime,
input.EstimatedDeliveryDate,
input.DestinationTimeZone,
input.Extra,
+ input.NewExtra,
input.CompareFields);
// 获取用户name
@@ -397,7 +403,7 @@ public partial class TrackService : ApplicationService, ITrackService
TrackPlace = input.TrackPlace,
TrackTime = input.TrackTime,
NewTrackTime = input.NewTrackTime,
- TrackTimeZone = input.TrackTimeZone,
+ TrackTimeZone = input.TrackTimeZone ?? GlobalConst.NoneTrackTimeZone, //时区为空使用一个特殊值填充
OperationMan = userInfo.Data.UserName,
OperationManId = userInfo.Data.UserId,
IsVisibility = input.IsVisibility,
@@ -418,6 +424,7 @@ public partial class TrackService : ApplicationService, ITrackService
DestinationTimeZone = input.DestinationTimeZone,
CompareFields = input.CompareFields,
Extra = input.Extra,
+ NewExtra = input.NewExtra,
ForcedPush = input.ForcedPush,
IsToMq = input.IsToMq,
};
@@ -436,10 +443,12 @@ public partial class TrackService : ApplicationService, ITrackService
string trackCode,
int source,
DateTime trackTime,
+ float trackTimezone,
DateTime? newTrackTime,
DateTime? estimatedDeliveryDate,
float? destinationTimeZone,
string? extra,
+ string? newExtra,
string? compareFields
)
{
@@ -505,10 +514,8 @@ public partial class TrackService : ApplicationService, ITrackService
//轨迹新增,不允许重复的轨迹提前拦截
if (isAdd)
{
- //允许重复,跳过检查
- if (trackContent.IsRepeatable) return;
//找到这个订单的这个轨迹code的所有轨迹
- var tracks = await RetryQueryTrackAsync(orderId, trackCode, trackTime, extra, compareFields, trackContent.IsRepeatable);
+ var tracks = await RetryQueryTrackAsync(isAdd, orderId, trackCode, trackTime, trackTimezone, newTrackTime, extra, newExtra, compareFields, trackContent.IsRepeatable);
if (tracks.Count > 0)
throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:{trackCode}不允许重复创建轨迹");
}
@@ -516,21 +523,45 @@ public partial class TrackService : ApplicationService, ITrackService
else
{
//找到这个订单的这个轨迹code的所有轨迹,
- var tracks = await RetryQueryTrackAsync(orderId, trackCode, trackTime, extra, compareFields, trackContent.IsRepeatable);
- //不存在需要更新的轨迹
+ var tracks = await RetryQueryTrackAsync(isAdd, orderId, trackCode, trackTime, trackTimezone, newTrackTime, extra, newExtra, compareFields, trackContent.IsRepeatable);
+
+ // 不存在需要更新的轨迹
if (tracks.Count == 0)
throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]没有要更新的记录");
- //更新轨迹,同一时间存在多条轨迹记录,理由:不清晰到底要修改哪一条或是全部修改
+ // 更新轨迹,同一时间存在多条轨迹记录,理由:不清晰到底要修改哪一条或是全部修改
if (tracks.Count > 1)
+ {
+ if (newTrackTime.HasValue && tracks.Any(track => DateTimeHelper.ConvertUtc0Compare(track.TrackTime, track.TrackTimeZone, newTrackTime.Value, trackTimezone) == 0))
+ {
+ throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]和现存轨迹时间重复,不允许修改,请检查轨迹NewTrackTime");
+ }
+
+ if (!string.IsNullOrWhiteSpace(extra) && tracks.Any(track => string.Equals(track.Extra, newExtra)))
+ {
+ throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]和现存轨迹Extra重复,不允许修改,请检查轨迹NewExtra");
+ }
+
throw new BusinessException(message: $"订单:{orderNo},轨迹代码:[{trackCode}]存在多条记录,不允许修改");
+ }
+
+ var track = tracks.First();
+ if (DateTimeHelper.ConvertUtc0Compare(track.TrackTime, track.TrackTimeZone, trackTime, trackTimezone) != 0)
+ {
+ throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]找不到要更新的记录,不允许修改,请检查轨迹TrackTime");
+ }
+
+ if (!string.Equals(track.Extra, extra))
+ {
+ throw new BusinessException(message: $"订单:[{orderNo}],轨迹代码:[{trackCode}]找不到要更新的记录,不允许修改,请检查轨迹Extra");
+ }
}
}
// 重试查询轨迹,直到存在符合要求的轨迹,或者超过最大重试次数
- private async Task> RetryQueryTrackAsync(int orderId, string trackCode, DateTime trackTime, string? extra, string? compareFields, bool isRepeatable)
+ private async Task> RetryQueryTrackAsync(bool isAdd, int orderId, string trackCode, DateTime trackTime, float trackTimezone, DateTime? newTrackTime, string? extra, string? newExtra, string? compareFields, bool isRepeatable)
{
- var tracks = await QueryAndFilterAsync(orderId, trackCode, trackTime, extra, compareFields, isRepeatable);
+ var tracks = await QueryAndFilterAsync(isAdd, orderId, trackCode, trackTime, trackTimezone, newTrackTime, extra, newExtra, compareFields, isRepeatable);
if (tracks.Count > 0)
return tracks;
@@ -540,7 +571,7 @@ public partial class TrackService : ApplicationService, ITrackService
{
try
{
- tracks = await QueryAndFilterAsync(orderId, trackCode, trackTime, extra, compareFields, isRepeatable);
+ tracks = await QueryAndFilterAsync(isAdd, orderId, trackCode, trackTime, trackTimezone, newTrackTime, extra, newExtra, compareFields, isRepeatable);
if (tracks.Count > 0)
return tracks;
//指数退避等待
@@ -559,28 +590,23 @@ public partial class TrackService : ApplicationService, ITrackService
//查询并按比较字段过滤轨迹,当比较字段为空时则使用轨迹发生时间过滤
//tips:后续进行投影缩参优化
- private async Task> QueryAndFilterAsync(int orderId, string trackCode, DateTime trackTime, string? extra, string? compareFields, bool isRepeatable)
+ private async Task> QueryAndFilterAsync(bool isAdd, int orderId, string trackCode, DateTime trackTime, float trackTimezone, DateTime? newTrackTime, string? extra, string? newExtra, string? compareFields, bool isRepeatable)
{
var tracks = await _trackDetailsEsRepository.GetListAsync(new[] { orderId }, trackCode, true);
// 如果不允许重复,则直接返回
if (!isRepeatable) return tracks;
- //无比较字段时使用轨迹时间参与过滤(兼容老版本)
- if (string.IsNullOrWhiteSpace(compareFields))
- {
- return tracks.Where(x => x.TrackTime == trackTime).ToList();
- }
+ tracks = isAdd
+ ? tracks.Where(x => x.GetUtc0TrackTime() == (newTrackTime ?? trackTime).Subtract(TimeSpan.FromHours(trackTimezone))).ToList()
+ : tracks.Where(x =>
+ x.GetUtc0TrackTime() == trackTime.Subtract(TimeSpan.FromHours(trackTimezone))
+ // 修改了并且修改了时间
+ || (newTrackTime != null && x.GetUtc0TrackTime() == newTrackTime.Value.Subtract(TimeSpan.FromHours(trackTimezone)))
+ ).ToList();
- return tracks.Where(x =>
- {
- if (string.IsNullOrWhiteSpace(x.Extra))
- throw new BusinessException(message: "轨迹extra为空无法使用比较字段比较,请检查轨迹");
- var extraJsonElement = TextJsonHelper.DeserializeToJsonElement(x.Extra);
- var inputExtraJsonElement = TextJsonHelper.DeserializeToJsonElement(extra);
-
- return TextJsonHelper.EqByJsonElementField(extraJsonElement, inputExtraJsonElement, compareFields);
- })
- .ToList();
+ return isAdd
+ ? tracks.Where(x => x.Extra == (newExtra ?? extra)).ToList()
+ : tracks.Where(x => x.Extra == extra || x.Extra == newExtra).ToList();
}
}