This commit is contained in:
李鹏军 2024-04-24 17:49:31 +08:00
parent 9bf4150990
commit 5ab91c3d8c
24 changed files with 436 additions and 319 deletions

View File

@ -5,6 +5,17 @@ public class TrackPushInput
public string OrderNo { get; set; } = null!; public string OrderNo { get; set; } = null!;
public List<TrackItem> Data { get; set; } = new(); public List<TrackItem> Data { get; set; } = new();
public string Log { get; set; }
}
public class TrackUpdateInput
{
public string OrderNo { get; set; } = null!;
public List<TrackItem> Data { get; set; } = new();
public string Log { get; set; }
} }
public class TrackItem public class TrackItem

View File

@ -5,4 +5,6 @@ public struct OrderIdentifier
public int OrderId { get; set; } 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 int CustomId { get; set; }
} }

View File

@ -2,45 +2,58 @@
public class TrackPushEvent public class TrackPushEvent
{ {
/// <summary>
/// 重试次数
/// </summary>
public int RetryNum { get; set; }
/// <summary> /// <summary>
/// 操作类型 /// 操作类型
/// </summary> /// </summary>
public OptionType OptionType { get; set; } public OptionType OptionType { get; set; }
/// <summary>
/// 子系统id
/// </summary>
public int SubSystemId { get; set; }
/// <summary>
/// 客户id
/// </summary>
public int CustomId { get; set; }
/// <summary> /// <summary>
/// 订单id /// 订单id
/// </summary> /// </summary>
public int OrderId { get; set; } public int[] OrderIds { get; set; } = null!;
/// <summary>
/// 订单号
/// </summary>
public string OrderNo { get; set; } = null!;
/// <summary>
/// 轨迹状态
/// </summary>
public string TrackStatus { get; set; } = null!;
/// <summary> /// <summary>
/// 轨迹代码(我们系统的) /// 轨迹代码(我们系统的)
/// </summary> /// </summary>
public string TrackCode { get; set; } = null!; public string TrackCode { get; set; } = null!;
/// <summary>
/// 操作人
/// </summary>
public string? OperationMan { get; set; }
/// <summary>
/// 系统推送信息
/// </summary>
public SystemPushStruct SystemPushInfo { get; set; }
}
public struct SystemPushStruct
{
/// <summary>
/// 轨迹状态
/// </summary>
public string TrackStatus { get; set; }
/// <summary> /// <summary>
/// 轨迹内容 /// 轨迹内容
/// </summary> /// </summary>
public string TrackContent { get; set; } = null!; public string TrackContent { get; set; }
/// <summary> /// <summary>
/// 轨迹发生地 /// 轨迹发生地
/// </summary> /// </summary>
public string TrackPlace { get; set; } = null!; public string TrackPlace { get; set; }
/// <summary> /// <summary>
/// 轨迹发生时间 /// 轨迹发生时间
@ -51,9 +64,4 @@ public class TrackPushEvent
/// 轨迹发生时区 /// 轨迹发生时区
/// </summary> /// </summary>
public float TrackTimeZone { get; set; } public float TrackTimeZone { get; set; }
/// <summary>
/// 操作人
/// </summary>
public string? OperationMan { get; set; }
} }

View File

@ -18,9 +18,9 @@ public class TrackUpsertEvent
public string? OperationMan { get; set; } public string? OperationMan { get; set; }
/// <summary> /// <summary>
/// true新增,false更新,null表示刷新 /// true新增,false更新
/// </summary> /// </summary>
public bool? IsAdd { get; set; } public bool IsAdd { get; set; }
/// <summary> /// <summary>
/// 轨迹内容代码 /// 轨迹内容代码

View File

@ -19,26 +19,4 @@ public interface ITrackPushCacheService
/// <param name="customId"></param> /// <param name="customId"></param>
/// <returns></returns> /// <returns></returns>
Task<List<TrackPushContentConfigDto>?> SetPushContentConfigsAsync(int subSystemId, int customId); Task<List<TrackPushContentConfigDto>?> SetPushContentConfigsAsync(int subSystemId, int customId);
/// <summary>
/// 获取服务商拉取配置
/// </summary>
/// <param name="subSystemId">子系统id</param>
/// <param name="customId">服务商id</param>
/// <param name="trackConde">轨迹代码</param>
/// <returns></returns>
Task<TrackPushContentConfigDto?> GetPushContentConfigAsync(int subSystemId, int customId, string trackConde);
/// <summary>
/// 根据轨迹代码推断下一个(升序)要推送的内容,如果找不到或者已经是最后一个了
/// 则查询有没有可交换的推送,没有就返回null
/// </summary>
/// <param name="subSystemId"></param>
/// <param name="customId"></param>
/// <param name="latestPushTrackCode"></param>
/// <param name="trackCode"></param>
/// <returns></returns>
Task<TrackPushContentConfigDto?> IsValidPushAsync(int subSystemId, int customId,
string? latestPushTrackCode,
string? trackCode);
} }

View File

@ -32,7 +32,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
var dup = @event.Visited.Intersect(@event.OrderIds).ToArray(); var dup = @event.Visited.Intersect(@event.OrderIds).ToArray();
if (dup.Any()) if (dup.Any())
{ {
LogHelper.Error($"删除轨迹订单时,发现循环依赖:{dup.JoinAsString(",")}"); LogHelper.Error($"删除轨迹时,发现循环依赖:{dup.JoinAsString(",")}");
return; return;
} }

View File

@ -0,0 +1,85 @@
using DotNetCore.CAP;
using Newtonsoft.Json;
using SJZY.InterfaceRelay.Application.Contracts;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Consts;
using SJZY.Track.Domain.Enums;
using Volo.Abp.DependencyInjection;
namespace SJZY.Track.Application.EventHandlers;
public class TrackPushCompletedEventHandler : ITransientDependency, ICapSubscribe
{
private readonly ITrackPushRecordsRepository _trackPushRecordsRepository;
private readonly IOrderRepository _orderRepository;
public TrackPushCompletedEventHandler(ITrackPushRecordsRepository trackPushRecordsRepository,
IOrderRepository orderRepository)
{
_trackPushRecordsRepository = trackPushRecordsRepository;
_orderRepository = orderRepository;
}
[CapSubscribe(GlobalConst.TrackPushCompletedSubscribe, Group = GlobalConst.TrackPushSubscribe)]
public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event)
{
var log = JsonConvert.DeserializeObject<TrackPushRecordIndex>(@event.RequestParams);
if (log == null) throw new BusinessException(message: "轨迹推送返回结果解析异常");
log.IsSuccess = @event.IsSuccess;
log.Message = @event.Message;
log.RequestId = @event.RequestId;
// 往es 写推送日志
await _trackPushRecordsRepository.AddAsync(log);
// if (!log.IsSuccess)
// {
// // 重试过程中不会去更新订单主表
// if (@event.RetryNum < 3)
// {
// @event.RetryNum++;
// await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, @event);
// return;
// }
// }
// 同步去更新订单主表
await TrackPushAfterUpdateOrderAsync(log);
}
private async Task TrackPushAfterUpdateOrderAsync(TrackPushRecordIndex log)
{
var order = new OrderEntity();
order.Id = log.OrderId;
/*
* 异常:最近一条推送是失败
*/
if (!log.IsSuccess)
{
order.QuestionType = (int)TrackProblemType.Error;
order.LatestPushError = log.Message;
}
else
{
order.QuestionType = (int)TrackProblemType.None;
order.LatestPushError = null;
if (log.OptionType == OptionType.新增.ToString())
{
// tips:只有新增会影响推送进度?
order.LatestPushTrackCode = log.TrackCode;
order.LatestPushTime = DateTime.Now;
await _orderRepository.UpdateColumnAsync(order, x => new
{
x.LatestPushTrackCode, x.LatestPushTime, x.QuestionType, x.LatestPushError
});
return;
}
}
await _orderRepository.UpdateColumnAsync(order, x => new
{
x.QuestionType, x.LatestPushError
});
}
}

View File

@ -6,6 +6,7 @@ using SJZY.Track.Application.Contract.Dtos.TrackPush;
using SJZY.Track.Application.Contract.Events; using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Application.Contract.Services; using SJZY.Track.Application.Contract.Services;
using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate; using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Consts;
using SJZY.Track.Domain.Enums; using SJZY.Track.Domain.Enums;
@ -17,212 +18,176 @@ namespace SJZY.Track.Application.EventHandlers;
public class TrackPushEventHandler : ITransientDependency, ICapSubscribe public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
{ {
private readonly IHttpClientProxy<IInterfaceForwardServiceV2> _httpClientProxy; private readonly IHttpClientProxy<IInterfaceForwardServiceV2> _httpClientProxy;
private readonly ITrackPushRecordsRepository _trackPushRecordsRepository;
private readonly IOrderRepository _orderRepository; private readonly IOrderRepository _orderRepository;
private readonly ITrackPushCacheService _trackPushCacheService; private readonly ITrackPushCacheService _trackPushCacheService;
private readonly ICapPublisher _capPublisher; private readonly ITrackDetailsRepository _trackDetailsRepository;
private readonly ITrackPushRecordsRepository _trackPushRecordsRepository;
private List<TrackPushContentConfigDto> _pushConfigs;
private List<OrderEntity> _orders;
public TrackPushEventHandler(IHttpClientProxy<IInterfaceForwardServiceV2> httpClientProxy, public TrackPushEventHandler(IHttpClientProxy<IInterfaceForwardServiceV2> httpClientProxy,
ITrackPushRecordsRepository trackPushRecordsRepository, IOrderRepository orderRepository, ITrackPushCacheService trackPushCacheService,
IOrderRepository orderRepository, ITrackPushCacheService trackPushCacheService, ICapPublisher capPublisher) ITrackDetailsRepository trackDetailsRepository, ITrackPushRecordsRepository trackPushRecordsRepository)
{ {
_httpClientProxy = httpClientProxy; _httpClientProxy = httpClientProxy;
_trackPushRecordsRepository = trackPushRecordsRepository;
_orderRepository = orderRepository; _orderRepository = orderRepository;
_trackPushCacheService = trackPushCacheService; _trackPushCacheService = trackPushCacheService;
_capPublisher = capPublisher; _trackDetailsRepository = trackDetailsRepository;
_trackPushRecordsRepository = trackPushRecordsRepository;
} }
[CapSubscribe(GlobalConst.TrackPushSubscribe, Group = GlobalConst.TrackPushSubscribe)] [CapSubscribe(GlobalConst.TrackPushSubscribe, Group = GlobalConst.TrackPushSubscribe)]
public async Task ConsumerAsync(TrackPushEvent @event) public async Task ConsumerAsync(TrackPushEvent @event)
{ {
var order = await _orderRepository.GetFirstAsync(x => var pushConfigs = await _trackPushCacheService.GetPushContentConfigsAsync(@event.SubSystemId, @event.CustomId);
x.Id == @event.OrderId, x => new if (pushConfigs == null || pushConfigs.Count == 0) return;
_pushConfigs = pushConfigs;
var errorType = (int)TrackProblemType.Error;
var orders = await _orderRepository.GetListAsync(x =>
@event.OrderIds.Contains(x.Id) && x.QuestionType != errorType, x => new OrderEntity
{ {
x.SubSystemId, x.LatestPushTrackCode, x.QuestionType, x.CustomId, x.OrderType Id = x.Id, OrderNo = x.OrderNo, LatestPushTrackCode = x.LatestPushTrackCode,
OrderType = x.OrderType
}); });
if (order == null) return; if (orders.Count == 0) return;
_orders = orders;
var log = new TrackPushRecordIndex
{
IndexName = $"{GlobalConst.TrackPushRecordsIndex}-{DateTime.Now:yyyy.MM.dd}",
OptionType = @event.OptionType.ToString(),
OrderId = @event.OrderId,
TrackStatus = @event.TrackStatus,
TrackCode = @event.TrackCode,
TrackContent = @event.TrackContent,
TrackPlace = @event.TrackPlace,
TrackTime = @event.TrackTime,
TrackTimeZone = @event.TrackTimeZone,
CreateUser = @event.OperationMan ?? GlobalConst.SystemUser,
CreateTime = DateTime.Now
};
TrackPushContentConfigDto? config = null;
switch (@event.OptionType) switch (@event.OptionType)
{ {
case OptionType.无: case OptionType.无:
return; return;
case OptionType.新增: case OptionType.新增:
if (@event.OperationMan == null) await DoPushAsync(@event);
{
if (order.QuestionType != (int)TrackProblemType.Error)
{
// 推送新增,需要根据上一次的推送 推断 本次推送 是否可行
config = await _trackPushCacheService.IsValidPushAsync(order.SubSystemId, order.CustomId,
order.LatestPushTrackCode, @event.TrackCode);
if (config == null) return;
if (!config.IsAutoPush) return;
if (config.OrderType != order.OrderType) return;
}
}
else
{
// 手工推送单条不推断,直接无脑推
config = await _trackPushCacheService.GetPushContentConfigAsync(order.SubSystemId, order.CustomId,
@event.TrackCode);
if (config is { IsAllPush: true })
{
// 推断 本次推送 是否可行
config = await _trackPushCacheService.IsValidPushAsync(order.SubSystemId, order.CustomId,
order.LatestPushTrackCode, @event.TrackCode);
}
}
if (config == null) return;
await DoAddAsync(@event, config, log);
break; break;
case OptionType.删除: case OptionType.删除:
break; break;
case OptionType.修改: case OptionType.修改:
config = await _trackPushCacheService.GetPushContentConfigAsync(order.SubSystemId, order.CustomId, await DoUpdateAsync(@event);
@event.TrackCode);
if (config == null || !config.IsCanUpdate) return;
await DoUpdateAsync(@event, config, log);
break; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
// 往es 写推送日志
await _trackPushRecordsRepository.AddAsync(log);
if (!log.IsSuccess)
{
// 重试过程中不会去更新订单主表
if (@event.RetryNum < 3)
{
@event.RetryNum++;
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, @event);
return;
}
} }
// 同步去更新订单主表 private async Task DoPushAsync(TrackPushEvent @event)
await TrackPushAfterUpdateOrderAsync(new TrackPushAfterUpdateOrderDto
{ {
OptionType = @event.OptionType, var logs = new List<TrackPushRecordIndex>();
OrderId = @event.OrderId, TrackPushContentConfigDto? config;
if (@event.OperationMan == null)
{
foreach (var order in _orders)
{
// 推送新增,需要根据上一次的推送 推断 本次推送 是否可行
config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode);
if (config == null) continue;
if (!config.IsAutoPush) continue;
if (config.OrderType != order.OrderType) continue;
var log = new TrackPushRecordIndex
{
OptionType = @event.OptionType.ToString(),
OrderId = order.Id,
OrderNo = order.OrderNo,
TrackStatus = @event.SystemPushInfo.TrackStatus,
TrackCode = @event.TrackCode, TrackCode = @event.TrackCode,
IsSuccess = log.IsSuccess, TrackContent = @event.SystemPushInfo.TrackContent,
Message = log.Message TrackPlace = @event.SystemPushInfo.TrackPlace,
}); TrackTime = @event.SystemPushInfo.TrackTime,
} TrackTimeZone = @event.SystemPushInfo.TrackTimeZone,
CreateUser = GlobalConst.SystemUser,
private async Task TrackPushAfterUpdateOrderAsync(TrackPushAfterUpdateOrderDto dto)
{
var order = new OrderEntity();
order.Id = dto.OrderId;
/*
* 异常:最近一条推送是失败
*/
if (!dto.IsSuccess)
{
order.QuestionType = (int)TrackProblemType.Error;
order.LatestPushError = dto.Message;
}
else
{
order.QuestionType = (int)TrackProblemType.None;
order.LatestPushError = null;
if (dto.OptionType == OptionType.新增)
{
// tips:只有新增会影响推送进度?
order.LatestPushTrackCode = dto.TrackCode;
order.LatestPushTime = DateTime.Now;
await _orderRepository.UpdateColumnAsync(order, x => new
{
x.LatestPushTrackCode, x.LatestPushTime, x.QuestionType, x.LatestPushError
});
return;
}
}
await _orderRepository.UpdateColumnAsync(order, x => new
{
x.QuestionType, x.LatestPushError
});
}
private async Task DoAddAsync(TrackPushEvent @event,
TrackPushContentConfigDto config, TrackPushRecordIndex log)
{
var track = new TrackItem
{
// 推真实的发生地和发生时间(时间是计算后的)
Location = @event.TrackPlace,
Date = @event.TrackTime.AddHours(
config.TrackTimeZone ?? @event.TrackTimeZone - @event.TrackTimeZone),
TimeZone = config.TrackTimeZone ?? @event.TrackTimeZone,
Description = config.TrackEnContentValue,
DescriptionCn = config.TrackContentValue,
Code = config.TrackContentCodeValue,
Status = config.TrackStatusValue,
Extra = config.ExpandFieldsValue
}; };
await BuiltPushItem(config, log);
var body = new TrackPushInput logs.Add(log);
}
}
else //手工推送
{ {
OrderNo = @event.OrderNo, config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
if (config == null) return;
var tracks = await _trackDetailsRepository.GetListAsync(@event.OrderIds, @event.TrackCode);
tracks = tracks.DistinctBy(x => x.OrderId).ToList(); // 防止重复推送
if (tracks.Count == 0) return; // 一个能推的轨迹都不存在
foreach (var track in tracks)
{
var order = _orders.First(x => x.Id == track.OrderId);
if (config is { IsAllPush: true })
{
// 推断 本次推送 是否可行
config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode);
}
if (config == null) continue;
var log = new TrackPushRecordIndex
{
OptionType = @event.OptionType.ToString(),
OrderId = track.OrderId,
OrderNo = order.OrderNo,
TrackStatus = track.TrackStatus,
TrackCode = @event.TrackCode,
TrackContent = track.TrackContent,
TrackPlace = track.TrackPlace,
TrackTime = track.TrackTime,
TrackTimeZone = track.TrackTimeZone,
CreateUser = @event.OperationMan,
}; };
body.Data.Add(track); await BuiltPushItem(config, log);
logs.Add(log);
}
}
if (config.IsAllPush) await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.PushTrackInterfaceCode,
_pushConfigs.First().ServiceProviderCode, logs, GlobalConst.TrackPushCompletedSubscribe);
}
private async Task DoUpdateAsync(TrackPushEvent @event)
{ {
var history = await _trackPushRecordsRepository.GetLatestTrackPushRecordAsync(@event.OrderId); var config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
if (history != default) if (config == null || !config.IsCanUpdate) return;
var logs = new List<TrackPushRecordIndex>();
foreach (var order in _orders)
{ {
body = JsonConvert.DeserializeObject<TrackPushInput>(history.PushContent); var log = new TrackPushRecordIndex
body!.Data.Add(track); {
} OptionType = @event.OptionType.ToString(),
OrderId = order.Id,
OrderNo = order.OrderNo,
TrackStatus = @event.SystemPushInfo.TrackStatus,
TrackCode = @event.TrackCode,
TrackContent = @event.SystemPushInfo.TrackContent,
TrackPlace = @event.SystemPushInfo.TrackPlace,
TrackTime = @event.SystemPushInfo.TrackTime,
TrackTimeZone = @event.SystemPushInfo.TrackTimeZone,
CreateUser = GlobalConst.SystemUser,
};
BuiltUpdateItem(config, log);
logs.Add(log);
} }
var res = await _httpClientProxy.Service.ForwardWithSubscribeAsync(InterfaceRelayConst.PushTrackInterfaceCode, await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.TrackUpdateInterfaceCode,
config.ServiceProviderCode, body); _pushConfigs.First().ServiceProviderCode, logs, GlobalConst.TrackPushCompletedSubscribe);
log.PushContent = body.ToJson();
log.IsSuccess = res.Code == InterfaceRelayConst.SuccessCode;
log.RequestId = res.RequestId;
log.Message = res.Msg;
} }
private async Task DoUpdateAsync(TrackPushEvent @event, private void BuiltUpdateItem(TrackPushContentConfigDto config, TrackPushRecordIndex log)
TrackPushContentConfigDto config, TrackPushRecordIndex log)
{ {
var data = new var data = new
{ {
orderNo = @event.OrderNo, orderNo = log.OrderNo,
data = new[] data = new[]
{ {
new new
{ {
// 推真实的发生地和发生时间 // 推真实的发生地和发生时间
location = @event.TrackPlace, location = log.TrackPlace,
date = @event.TrackTime.AddHours( date = log.TrackTime.AddHours(
config.TrackTimeZone ?? @event.TrackTimeZone - @event.TrackTimeZone), config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone),
timeZone = config.TrackTimeZone ?? @event.TrackTimeZone, timeZone = config.TrackTimeZone ?? log.TrackTimeZone,
description = config.TrackEnContentValue, description = config.TrackEnContentValue,
description_cn = config.TrackContentValue, description_cn = config.TrackContentValue,
code = config.TrackContentCodeValue, code = config.TrackContentCodeValue,
@ -232,13 +197,66 @@ public class TrackPushEventHandler : ITransientDependency, ICapSubscribe
} }
}; };
var res = await _httpClientProxy.Service.ForwardWithSubscribeAsync(InterfaceRelayConst.TrackUpdateInterfaceCode,
config.ServiceProviderCode, data);
log.PushContent = data.ToJson(); log.PushContent = data.ToJson();
log.IsSuccess = res.Code == InterfaceRelayConst.SuccessCode; }
log.RequestId = res.RequestId;
log.Message = res.Msg; private async Task BuiltPushItem(TrackPushContentConfigDto config, TrackPushRecordIndex log)
{
var track = new TrackItem
{
// 推真实的发生地和发生时间(时间是计算后的)
Location = log.TrackPlace,
Date = log.TrackTime.AddHours(
config.TrackTimeZone ?? log.TrackTimeZone - log.TrackTimeZone),
TimeZone = config.TrackTimeZone ?? log.TrackTimeZone,
Description = config.TrackEnContentValue,
DescriptionCn = config.TrackContentValue,
Code = config.TrackContentCodeValue,
Status = config.TrackStatusValue,
Extra = config.ExpandFieldsValue
};
var body = new TrackPushInput
{
OrderNo = log.OrderNo,
};
body.Data.Add(track);
if (config.IsAllPush)
{
var history = await _trackPushRecordsRepository.GetLatestTrackPushRecordAsync(log.OrderId);
if (history != default)
{
body = JsonConvert.DeserializeObject<TrackPushInput>(history.PushContent);
body!.Data.Add(track);
}
}
log.PushContent = body.ToJson();
}
/// <summary>
/// 根据轨迹代码推断下一个(升序)要推送的内容,如果找不到或者已经是最后一个了
/// 则查询有没有可交换的推送,没有就返回null
/// </summary>
/// <param name="cache"></param>
/// <param name="latestPushTrackCode"></param>
/// <param name="trackCode"></param>
/// <returns></returns>
TrackPushContentConfigDto? GetValidPushConfigAsync(List<TrackPushContentConfigDto> cache,
string? latestPushTrackCode, string? trackCode)
{
var idx = cache.FindIndex(x => x.TrackCode == latestPushTrackCode);
if (idx + 1 >= cache.Count) return default; // 推完了
// find next
var matched = cache[idx + 1].TrackCode == trackCode
? cache[idx + 1]
:
// find swap
cache.FirstOrDefault(x => x.TrackCode == cache[idx + 1].SwapTrackCode);
return matched != null && matched.TrackCode == trackCode ? matched : default;
} }
} }

View File

@ -36,6 +36,7 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
[CapSubscribe(GlobalConst.TrackRefreshSubscribe, Group = GlobalConst.TrackRefreshSubscribe)] [CapSubscribe(GlobalConst.TrackRefreshSubscribe, Group = GlobalConst.TrackRefreshSubscribe)]
public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event) public async Task ConsumerAsync(InterfaceRelayForwardReplayEvent @event)
{ {
if (!@event.IsSuccess) return;
var attach = Base64Helper.DeSerialize<TrackRefreshAttach>(@event.Attach); var attach = Base64Helper.DeSerialize<TrackRefreshAttach>(@event.Attach);
if (attach is null) return; if (attach is null) return;
@ -222,15 +223,16 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
// 新增/更新轨迹 // 新增/更新轨迹
var trackUpsertEvent = new TrackUpsertEvent var trackUpsertEvent = new TrackUpsertEvent
{ {
OrderIdentifiers = new[] OrderIdentifiers =
{ [
new OrderIdentifier new OrderIdentifier
{ {
OrderId = context.OrderId, OrderId = context.OrderId,
OrderNo = context.OrderNo, OrderNo = context.OrderNo,
OrderType = context.OrderType OrderType = context.OrderType,
CustomId = context.CustomId
} }
}, ],
TrackRefreshData = new TrackRefreshStruct TrackRefreshData = new TrackRefreshStruct
{ {
ServiceProviderName = context.ServiceProviderName, ServiceProviderName = context.ServiceProviderName,
@ -247,6 +249,8 @@ public class TrackRefreshEventHandler : ITransientDependency, ICapSubscribe
TrackTimeZone = trackTimeZone ?? matchedContentConfig.TrackTimeZoneValue ?? 8 TrackTimeZone = trackTimeZone ?? matchedContentConfig.TrackTimeZoneValue ?? 8
}; };
trackUpsertEvent.IsAdd =
!await _trackDetailsRepository.AnyByCodeAsync(context.OrderId, matchedContentConfig.TrackContentCode);
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertForRefreshSubscribe, trackUpsertEvent); await _capPublisher.PublishAsync(GlobalConst.TrackUpsertForRefreshSubscribe, trackUpsertEvent);
} }
} }

View File

@ -35,7 +35,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
var dup = @event.Visited.Intersect(orderIds).ToArray(); var dup = @event.Visited.Intersect(orderIds).ToArray();
if (dup.Any()) if (dup.Any())
{ {
LogHelper.Error($"删除轨迹订单时,发现循环依赖:{dup.JoinAsString(",")}"); LogHelper.Error($"{(@event.IsAdd ? "添加" : "修改")}轨迹时,发现循环依赖:{dup.JoinAsString(",")}");
return; return;
} }
@ -48,11 +48,11 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
{ {
// 理论上小包在这不会分组 // 理论上小包在这不会分组
foreach (var group in linkedOrders.Where(x => x.OwnerOrderId == order.OrderId) foreach (var group in linkedOrders.Where(x => x.OwnerOrderId == order.OrderId)
.GroupBy(x => x.SubSystemId)) .GroupBy(x => new { x.SubSystemId, x.CustomId }))
{ {
var nextEvent = @event.DeepCopy(); var nextEvent = @event.DeepCopy();
nextEvent.Visited.AddRange(orderIds); nextEvent.Visited.AddRange(orderIds);
nextEvent.SubSystemId = group.Key; nextEvent.SubSystemId = group.Key.SubSystemId;
nextEvent.TrackRefreshData = new TrackRefreshStruct nextEvent.TrackRefreshData = new TrackRefreshStruct
{ {
ServiceProviderName = @event.TrackRefreshData.ServiceProviderName, ServiceProviderName = @event.TrackRefreshData.ServiceProviderName,
@ -82,7 +82,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
{ {
OrderId = x.OrderId, OrderId = x.OrderId,
OrderNo = x.OrderNo, OrderNo = x.OrderNo,
OrderType = x.OrderType OrderType = x.OrderType,
CustomId = x.CustomId
}).ToList(); }).ToList();
var idx = 0; var idx = 0;
while (idx < identifiers.Count) while (idx < identifiers.Count)
@ -113,11 +114,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
{ {
var track = tracks.FirstOrDefault(x => x.OrderId == order.OrderId); var track = tracks.FirstOrDefault(x => x.OrderId == order.OrderId);
if (@event.IsAdd != null) if (track == null && !@event.IsAdd) continue; // 不存在不让改
{ if (track != null && @event.IsAdd) continue; // 存在不让创建
if (track == null && !@event.IsAdd!.Value) continue; // 不存在不让改
if (track != null && @event.IsAdd!.Value) continue; // 存在不让创建
}
if (track == default) if (track == default)
{ {
@ -167,22 +165,6 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
await _trackDetailsRepository.UpdateAsync(track); await _trackDetailsRepository.UpdateAsync(track);
} }
// step2、触发轨迹推送事件(异步)
var trackPushEvent = new TrackPushEvent
{
OptionType = track.Id.IsNullOrWhiteSpace() ? OptionType.新增 : OptionType.修改,
OrderId = order.OrderId,
OrderNo = order.OrderNo,
TrackStatus = track.TrackStatus,
TrackCode = track.TrackCode,
TrackContent = track.TrackContent,
TrackPlace = track.TrackPlace,
TrackTime = track.TrackTime,
TrackTimeZone = track.TrackTimeZone,
};
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent);
canNextOrderIds.Add(order.OrderId); canNextOrderIds.Add(order.OrderId);
firstTrack ??= track; firstTrack ??= track;
@ -205,5 +187,27 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
TrackTime = @event.TrackTime, TrackTime = @event.TrackTime,
TrackTimeZone = @event.TrackTimeZone TrackTimeZone = @event.TrackTimeZone
}); });
// 触发轨迹推送事件(异步)
foreach (var group in @event.OrderIdentifiers.GroupBy(x => x.CustomId))
{
var trackPushEvent = new TrackPushEvent
{
OptionType = @event.IsAdd ? OptionType.新增 : OptionType.修改,
SubSystemId = @event.SubSystemId,
CustomId = group.Key,
OrderIds = group.Select(x => x.OrderId).ToArray(),
TrackCode = @event.TrackCode,
SystemPushInfo = new SystemPushStruct
{
TrackStatus = firstTrack.TrackStatus,
TrackContent = firstTrack.TrackContent,
TrackPlace = @event.TrackPlace,
TrackTime = @event.TrackTime,
TrackTimeZone = @event.TrackTimeZone
}
};
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent);
}
} }
} }

View File

@ -12,7 +12,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SJZY.InterfaceRelay.Application.Contracts" Version="7.1.9"/> <PackageReference Include="SJZY.InterfaceRelay.Application.Contracts" Version="7.2.0"/>
<PackageReference Include="Volo.Abp.Http.Client" Version="7.0.2" /> <PackageReference Include="Volo.Abp.Http.Client" Version="7.0.2" />
<PackageReference Include="Volo.Abp.FluentValidation" Version="7.0.2" /> <PackageReference Include="Volo.Abp.FluentValidation" Version="7.0.2" />
<PackageReference Include="SJZY.UserCenter.HttpApi" Version="3.0.3-alpha8" /> <PackageReference Include="SJZY.UserCenter.HttpApi" Version="3.0.3-alpha8" />

View File

@ -72,7 +72,7 @@ public partial class OrderService
// 过滤掉不存在的订单 // 过滤掉不存在的订单
var canLinkOrders = await _orderRepository.GetListAsync(x => var canLinkOrders = await _orderRepository.GetListAsync(x =>
x.OrderType == input.LinkOrderType && noLinkOrderNos.Contains(x.OrderNo), x.OrderType == input.LinkOrderType && noLinkOrderNos.Contains(x.OrderNo),
x => new { x.Id, x.OrderNo, x.OrderType, x.SubSystemId }); x => new { x.Id, x.OrderNo, x.OrderType, x.SubSystemId, x.CustomId });
if (canLinkOrders.Count == 0) return; if (canLinkOrders.Count == 0) return;
@ -100,7 +100,8 @@ public partial class OrderService
{ {
OrderId = x.Id, OrderId = x.Id,
OrderNo = x.OrderNo, OrderNo = x.OrderNo,
OrderType = x.OrderType OrderType = x.OrderType,
CustomId = x.CustomId
}).ToArray(), }).ToArray(),
TrackCode = track.TrackCode, TrackCode = track.TrackCode,
TrackPlace = track.TrackPlace, TrackPlace = track.TrackPlace,

View File

@ -65,7 +65,8 @@ public class TrackPullService : ApplicationService
var attach = Base64Helper.SerializeObject(group.Key); var attach = Base64Helper.SerializeObject(group.Key);
// 批量获取轨迹 // 批量获取轨迹
var _ = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync( var _ = await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(
"A012", serviceProviderCode, data, GlobalConst.TrackRefreshSubscribe, attach); InterfaceRelayConst.GetTrackInterfaceCode, serviceProviderCode, data, GlobalConst.TrackRefreshSubscribe,
attach);
} }
return true; return true;

View File

@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Authorization;
using SJZY.Track.Application.Contract.Dtos.ProvideServices; using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Events; using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Domain.Aggregates.OrderAggregate; using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate; using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
using SJZY.Track.Domain.Consts; using SJZY.Track.Domain.Consts;
using SJZY.UserCenter.HttpApi.Services; using SJZY.UserCenter.HttpApi.Services;
@ -17,17 +16,14 @@ namespace SJZY.Track.Application.Services.ProvideServices;
[Route("/ProviderService")] [Route("/ProviderService")]
public class TrackPushService : ApplicationService public class TrackPushService : ApplicationService
{ {
private readonly ITrackDetailsRepository _trackDetailsRepository;
private readonly IOrderRepository _orderRepository; private readonly IOrderRepository _orderRepository;
private readonly ICapPublisher _capPublisher; private readonly ICapPublisher _capPublisher;
private readonly ITrackPushRecordsRepository _trackPushRecordsRepository; private readonly ITrackPushRecordsRepository _trackPushRecordsRepository;
public TrackPushService(ITrackDetailsRepository trackDetailsRepository public TrackPushService(IOrderRepository orderRepository
, IOrderRepository orderRepository
, ICapPublisher capPublisher , ICapPublisher capPublisher
, ITrackPushRecordsRepository trackPushRecordsRepository) , ITrackPushRecordsRepository trackPushRecordsRepository)
{ {
_trackDetailsRepository = trackDetailsRepository;
_orderRepository = orderRepository; _orderRepository = orderRepository;
_capPublisher = capPublisher; _capPublisher = capPublisher;
_trackPushRecordsRepository = trackPushRecordsRepository; _trackPushRecordsRepository = trackPushRecordsRepository;
@ -51,38 +47,17 @@ public class TrackPushService : ApplicationService
throw new BusinessException(message: "一个订单都不存在"); throw new BusinessException(message: "一个订单都不存在");
} }
var tracks = await _trackDetailsRepository.GetListAsync(orderIds, input.TrackCode);
tracks = tracks.DistinctBy(x => x.OrderId).ToList();
if (tracks.Count == 0)
{
throw new BusinessException(message: "一个能推的轨迹都不存在");
}
var res = 0;
foreach (var track in tracks)
{
var trackPushEvent = new TrackPushEvent var trackPushEvent = new TrackPushEvent
{ {
OptionType = OptionType.新增, OptionType = OptionType.新增,
OrderId = track.OrderId, OrderIds = orderIds,
OrderNo = track.OrderNo, TrackCode = input.TrackCode,
TrackStatus = track.TrackStatus,
TrackCode = track.TrackCode,
TrackContent = track.TrackContent,
TrackPlace = track.TrackPlace,
TrackTime = track.TrackTime,
TrackTimeZone = track.TrackTimeZone,
OperationMan = CurrentUserRequest.CurrentUser.Name, OperationMan = CurrentUserRequest.CurrentUser.Name,
}; };
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent); await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent);
res++; return $"即将推送轨迹代码{input.TrackCode}给{orderIds.Length}个订单";
}
return $"即将推送轨迹代码{input.TrackCode}给{res}个订单";
} }

View File

@ -43,7 +43,7 @@ public partial class TrackService : ApplicationService, ITrackService
var order = await _orderRepository.GetFirstAsync(x => var order = await _orderRepository.GetFirstAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => new x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => new
{ {
x.Id, x.SubSystemId, x.OrderNo, x.OrderType x.Id, x.SubSystemId, x.OrderNo, x.OrderType, x.CustomId
}); });
if (order == default) if (order == default)
{ {
@ -53,15 +53,16 @@ public partial class TrackService : ApplicationService, ITrackService
// 新增/更新轨迹 // 新增/更新轨迹
var @event = ObjectMapper.Map<UpsertTrackInput, TrackUpsertEvent>(input); var @event = ObjectMapper.Map<UpsertTrackInput, TrackUpsertEvent>(input);
@event.SubSystemId = order.SubSystemId; @event.SubSystemId = order.SubSystemId;
@event.OrderIdentifiers = new[] @event.OrderIdentifiers =
{ [
new OrderIdentifier new OrderIdentifier
{ {
OrderId = order.Id, OrderId = order.Id,
OrderNo = order.OrderNo, OrderNo = order.OrderNo,
OrderType = order.OrderType OrderType = order.OrderType,
CustomId = order.CustomId
} }
}; ];
@event.OperationMan = CurrentUserRequest.CurrentUser.Name; @event.OperationMan = CurrentUserRequest.CurrentUser.Name;
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event); await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event);
return new UnifyResultDto(true, true); return new UnifyResultDto(true, true);
@ -85,7 +86,7 @@ public partial class TrackService : ApplicationService, ITrackService
var orders = await _orderRepository.GetListAsync(x => var orders = await _orderRepository.GetListAsync(x =>
x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => new x.OrderType == input.OrderType && input.OrderNos.Contains(x.OrderNo), x => new
{ {
x.Id, x.OrderNo, x.SubSystemId x.Id, x.OrderNo, x.SubSystemId, x.CustomId
}); });
foreach (var group in orders.GroupBy(x => x.SubSystemId)) foreach (var group in orders.GroupBy(x => x.SubSystemId))
@ -98,7 +99,8 @@ public partial class TrackService : ApplicationService, ITrackService
{ {
OrderId = order.Id, OrderId = order.Id,
OrderNo = order.OrderNo, OrderNo = order.OrderNo,
OrderType = input.OrderType OrderType = input.OrderType,
CustomId = order.CustomId
}).ToArray(), }).ToArray(),
IsAdd = input.IsAdd, IsAdd = input.IsAdd,
TrackCode = input.TrackCode, TrackCode = input.TrackCode,

View File

@ -43,34 +43,6 @@ public class TrackPushCacheService : ITrackPushCacheService, ITransientDependenc
return data; return data;
} }
public async Task<TrackPushContentConfigDto?> GetPushContentConfigAsync(int subSystemId, int customId,
string trackConde)
{
var configs = await GetPushContentConfigsAsync(subSystemId, customId);
return configs?.FirstOrDefault(x => x.TrackCode == trackConde);
}
public async Task<TrackPushContentConfigDto?> IsValidPushAsync(int subSystemId, int customId,
string? latestPushTrackCode,
string? trackCode)
{
var cache = await GetPushContentConfigsAsync(subSystemId, customId);
if (cache == null || cache.Count < 1) return default;
var idx = cache.FindIndex(x => x.TrackCode == latestPushTrackCode);
if (idx + 1 >= cache.Count) return default; // 推完了
// find next
var matched = cache[idx + 1].TrackCode == trackCode
? cache[idx + 1]
:
// find swap
cache.FirstOrDefault(x => x.TrackCode == cache[idx + 1].SwapTrackCode);
return matched != null && matched.TrackCode == trackCode ? matched : default;
}
private async Task<List<TrackPushContentConfigDto>?> DoGetPushContentConfigsAsync(int subSystemId, int customId) private async Task<List<TrackPushContentConfigDto>?> DoGetPushContentConfigsAsync(int subSystemId, int customId)
{ {
var trackPushConfig = await _trackPushConfigRepository.GetFirstAsync( var trackPushConfig = await _trackPushConfigRepository.GetFirstAsync(

View File

@ -13,6 +13,8 @@ public interface ITrackDetailsRepository
Task<bool> AnyAsync(int orderId, string originTrackData); Task<bool> AnyAsync(int orderId, string originTrackData);
Task<bool> AnyByCodeAsync(int orderId, string trackCode);
Task UpdateAsync(TrackDetailsIndex index); Task UpdateAsync(TrackDetailsIndex index);
Task AddManyAsync(List<TrackDetailsIndex> index); Task AddManyAsync(List<TrackDetailsIndex> index);

View File

@ -9,6 +9,8 @@ public interface ITrackPushRecordsRepository
/// <returns></returns> /// <returns></returns>
Task AddAsync(TrackPushRecordIndex index); Task AddAsync(TrackPushRecordIndex index);
Task AddManyAsync(List<TrackPushRecordIndex> index);
/// <summary> /// <summary>
/// 获取轨迹推送记录 /// 获取轨迹推送记录
/// </summary> /// </summary>

View File

@ -17,6 +17,11 @@ public class TrackPushRecordIndex : IdBaseIndex
/// </summary> /// </summary>
public int OrderId { get; set; } public int OrderId { get; set; }
/// <summary>
/// 订单号
/// </summary>
public string OrderNo { get; set; } = null!;
/// <summary> /// <summary>
/// 接口通请求Id /// 接口通请求Id
/// </summary> /// </summary>

View File

@ -32,6 +32,11 @@ public partial class GlobalConst
/// </summary> /// </summary>
public const string TrackPushSubscribe = "SJZY.Track.TrackPush"; public const string TrackPushSubscribe = "SJZY.Track.TrackPush";
/// <summary>
/// 轨迹推送完成(接口通回调)
/// </summary>
public const string TrackPushCompletedSubscribe = "SJZY.Track.TrackPushCompleted";
/// <summary> /// <summary>
/// 轨迹新增/更新/删除后触发更新订单主表 /// 轨迹新增/更新/删除后触发更新订单主表
/// </summary> /// </summary>

View File

@ -26,4 +26,9 @@ public class LinkedOrderVO
/// 子系统id /// 子系统id
/// </summary> /// </summary>
public int SubSystemId { get; set; } public int SubSystemId { get; set; }
/// <summary>
/// 客户id
/// </summary>
public int CustomId { get; set; }
} }

View File

@ -78,7 +78,8 @@ AND `a`.`IsDeleted` = 0 AND `b`.`IsDeleted` = 0;");
OrderId = b.Id, OrderId = b.Id,
OrderNo = b.OrderNo, OrderNo = b.OrderNo,
OrderType = b.OrderType, OrderType = b.OrderType,
SubSystemId = b.SubSystemId SubSystemId = b.SubSystemId,
CustomId = b.CustomId
}) })
.ToListAsync(); .ToListAsync();
} }

View File

@ -31,7 +31,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
if (!r.IsValid) if (!r.IsValid)
{ {
throw new Exception($"轨迹查询,原因:{r.DebugInformation}。"); throw new Exception($"轨迹查询异常,原因:{r.DebugInformation}。");
} }
return r.ToIdList(); return r.ToIdList();
@ -82,7 +82,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
if (!r.IsValid) if (!r.IsValid)
{ {
throw new Exception($"轨迹查询,原因:{r.DebugInformation}。"); throw new Exception($"轨迹查询异常,原因:{r.DebugInformation}。");
} }
return r.Documents.ToList(); return r.Documents.ToList();
@ -100,7 +100,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
if (!r.IsValid) if (!r.IsValid)
{ {
throw new Exception($"轨迹查询,原因:{r.DebugInformation}。"); throw new Exception($"轨迹查询异常,原因:{r.DebugInformation}。");
} }
return r.Hits.Count > 0; return r.Hits.Count > 0;
@ -118,7 +118,25 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
if (!r.IsValid) if (!r.IsValid)
{ {
throw new Exception($"轨迹查询,原因:{r.DebugInformation}。"); throw new Exception($"轨迹查询异常,原因:{r.DebugInformation}。");
}
return r.Hits.Count > 0;
}
public async Task<bool> AnyByCodeAsync(int orderId, string trackCode)
{
var r = await Context.SearchAsync<TrackDetailsIndex>(x => x
.Source(s => s.Includes(fd => fd.Field(f => f.TrackCode)))
.Query(q =>
q.Term(f => f.OrderId, orderId)
&& q.Term(f => f.TrackCode.Suffix("keyword"), trackCode)
)
);
if (!r.IsValid)
{
throw new Exception($"轨迹查询异常,原因:{r.DebugInformation}。");
} }
return r.Hits.Count > 0; return r.Hits.Count > 0;
@ -130,7 +148,6 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
var r = await Context.UpdateAsync<TrackDetailsIndex>(track.Id, u => u var r = await Context.UpdateAsync<TrackDetailsIndex>(track.Id, u => u
.Index(track.IndexName) .Index(track.IndexName)
.Doc(track) .Doc(track)
//.Refresh(Refresh.True) // 可选:立即刷新索引使更改立即可见
); );
if (!r.IsValid) if (!r.IsValid)
@ -193,7 +210,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
if (!r.IsValid) if (!r.IsValid)
{ {
throw new Exception($"轨迹查询,原因:{r.DebugInformation}。"); throw new Exception($"轨迹查询异常,原因:{r.DebugInformation}。");
} }
return r.Documents.ToList(); return r.Documents.ToList();
@ -210,7 +227,7 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
if (!r.IsValid) if (!r.IsValid)
{ {
throw new Exception($"轨迹查询,原因:{r.DebugInformation}。"); throw new Exception($"轨迹查询异常,原因:{r.DebugInformation}。");
} }
return r.Documents.ToList(); return r.Documents.ToList();
@ -219,12 +236,13 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
public async Task DeleteTrackAsync(int[] orderIds, List<string> trackCodes) public async Task DeleteTrackAsync(int[] orderIds, List<string> trackCodes)
{ {
var r = await Context.DeleteByQueryAsync<TrackDetailsIndex>(x => x var r = await Context.DeleteByQueryAsync<TrackDetailsIndex>(x => x
.Conflicts(Conflicts.Proceed) .Conflicts(Conflicts.Abort)
.Query( .Query(
q => q =>
q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds)) q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds))
&& q.Term(t => t.IsCanDelete, true) && q.Term(t => t.IsCanDelete, true)
&& q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))) && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes)))
.WaitForCompletion()
); );
if (!r.IsValid) if (!r.IsValid)

View File

@ -16,6 +16,8 @@ public class TrackPushRecordsRepository : ElasticSearchContextAbstract<TrackDeta
public async Task AddAsync(TrackPushRecordIndex index) public async Task AddAsync(TrackPushRecordIndex index)
{ {
index.IndexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}";
index.CreateTime = DateTime.Now;
// 按天写入es // 按天写入es
var r = await Context.IndexAsync(index, request => request var r = await Context.IndexAsync(index, request => request
.Index(index.IndexName) .Index(index.IndexName)
@ -28,6 +30,22 @@ public class TrackPushRecordsRepository : ElasticSearchContextAbstract<TrackDeta
} }
} }
public async Task AddManyAsync(List<TrackPushRecordIndex> records)
{
if (!records.Any()) return;
// 按天写入es
var indexName = $"{GlobalConst.TrackIndex}-{DateTime.Now:yyyy.MM.dd}";
records.ForEach(x => x.IndexName = indexName);
var r = await Context.IndexManyAsync(records, indexName);
if (!r.IsValid)
{
throw new Exception($"{records.Count}条轨迹推送记录写入失败,原因:{r.DebugInformation}。");
}
}
public async Task<List<TrackPushRecordIndex>> GetTrackPushRecordsAsync(int orderId) public async Task<List<TrackPushRecordIndex>> GetTrackPushRecordsAsync(int orderId)
{ {
var data = await Context.SearchAsync<TrackPushRecordIndex>(x => x var data = await Context.SearchAsync<TrackPushRecordIndex>(x => x