temp
This commit is contained in:
parent
9bf4150990
commit
5ab91c3d8c
@ -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
|
||||||
|
|||||||
@ -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; }
|
||||||
}
|
}
|
||||||
@ -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; }
|
|
||||||
}
|
}
|
||||||
@ -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>
|
||||||
/// 轨迹内容代码
|
/// 轨迹内容代码
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
}
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 同步去更新订单主表
|
|
||||||
await TrackPushAfterUpdateOrderAsync(new TrackPushAfterUpdateOrderDto
|
|
||||||
{
|
|
||||||
OptionType = @event.OptionType,
|
|
||||||
OrderId = @event.OrderId,
|
|
||||||
TrackCode = @event.TrackCode,
|
|
||||||
IsSuccess = log.IsSuccess,
|
|
||||||
Message = log.Message
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task TrackPushAfterUpdateOrderAsync(TrackPushAfterUpdateOrderDto dto)
|
private async Task DoPushAsync(TrackPushEvent @event)
|
||||||
{
|
{
|
||||||
var order = new OrderEntity();
|
var logs = new List<TrackPushRecordIndex>();
|
||||||
order.Id = dto.OrderId;
|
TrackPushContentConfigDto? config;
|
||||||
/*
|
|
||||||
* 异常:最近一条推送是失败
|
if (@event.OperationMan == null)
|
||||||
*/
|
|
||||||
if (!dto.IsSuccess)
|
|
||||||
{
|
{
|
||||||
order.QuestionType = (int)TrackProblemType.Error;
|
foreach (var order in _orders)
|
||||||
order.LatestPushError = dto.Message;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
order.QuestionType = (int)TrackProblemType.None;
|
|
||||||
order.LatestPushError = null;
|
|
||||||
if (dto.OptionType == OptionType.新增)
|
|
||||||
{
|
{
|
||||||
// tips:只有新增会影响推送进度?
|
// 推送新增,需要根据上一次的推送 推断 本次推送 是否可行
|
||||||
order.LatestPushTrackCode = dto.TrackCode;
|
config = GetValidPushConfigAsync(_pushConfigs, order.LatestPushTrackCode, @event.TrackCode);
|
||||||
order.LatestPushTime = DateTime.Now;
|
if (config == null) continue;
|
||||||
await _orderRepository.UpdateColumnAsync(order, x => new
|
if (!config.IsAutoPush) continue;
|
||||||
|
if (config.OrderType != order.OrderType) continue;
|
||||||
|
|
||||||
|
var log = new TrackPushRecordIndex
|
||||||
{
|
{
|
||||||
x.LatestPushTrackCode, x.LatestPushTime, x.QuestionType, x.LatestPushError
|
OptionType = @event.OptionType.ToString(),
|
||||||
});
|
OrderId = order.Id,
|
||||||
return;
|
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,
|
||||||
|
};
|
||||||
|
await BuiltPushItem(config, log);
|
||||||
|
logs.Add(log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else //手工推送
|
||||||
await _orderRepository.UpdateColumnAsync(order, x => new
|
|
||||||
{
|
{
|
||||||
x.QuestionType, x.LatestPushError
|
config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
|
||||||
});
|
if (config == null) return;
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DoAddAsync(TrackPushEvent @event,
|
var tracks = await _trackDetailsRepository.GetListAsync(@event.OrderIds, @event.TrackCode);
|
||||||
TrackPushContentConfigDto config, TrackPushRecordIndex log)
|
tracks = tracks.DistinctBy(x => x.OrderId).ToList(); // 防止重复推送
|
||||||
{
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
var body = new TrackPushInput
|
if (tracks.Count == 0) return; // 一个能推的轨迹都不存在
|
||||||
{
|
|
||||||
OrderNo = @event.OrderNo,
|
|
||||||
};
|
|
||||||
body.Data.Add(track);
|
|
||||||
|
|
||||||
if (config.IsAllPush)
|
foreach (var track in tracks)
|
||||||
{
|
|
||||||
var history = await _trackPushRecordsRepository.GetLatestTrackPushRecordAsync(@event.OrderId);
|
|
||||||
if (history != default)
|
|
||||||
{
|
{
|
||||||
body = JsonConvert.DeserializeObject<TrackPushInput>(history.PushContent);
|
var order = _orders.First(x => x.Id == track.OrderId);
|
||||||
body!.Data.Add(track);
|
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,
|
||||||
|
};
|
||||||
|
await BuiltPushItem(config, log);
|
||||||
|
logs.Add(log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var res = await _httpClientProxy.Service.ForwardWithSubscribeAsync(InterfaceRelayConst.PushTrackInterfaceCode,
|
await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.PushTrackInterfaceCode,
|
||||||
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 async Task DoUpdateAsync(TrackPushEvent @event)
|
||||||
TrackPushContentConfigDto config, TrackPushRecordIndex log)
|
{
|
||||||
|
var config = _pushConfigs.FirstOrDefault(x => x.TrackCode == @event.TrackCode);
|
||||||
|
if (config == null || !config.IsCanUpdate) return;
|
||||||
|
|
||||||
|
var logs = new List<TrackPushRecordIndex>();
|
||||||
|
foreach (var order in _orders)
|
||||||
|
{
|
||||||
|
var log = new TrackPushRecordIndex
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
await _httpClientProxy.Service.BatchForwardThenPushToQueueAsync(InterfaceRelayConst.TrackUpdateInterfaceCode,
|
||||||
|
_pushConfigs.First().ServiceProviderCode, logs, GlobalConst.TrackPushCompletedSubscribe);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuiltUpdateItem(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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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" />
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
var trackPushEvent = new TrackPushEvent
|
||||||
tracks = tracks.DistinctBy(x => x.OrderId).ToList();
|
|
||||||
|
|
||||||
if (tracks.Count == 0)
|
|
||||||
{
|
{
|
||||||
throw new BusinessException(message: "一个能推的轨迹都不存在");
|
OptionType = OptionType.新增,
|
||||||
}
|
OrderIds = orderIds,
|
||||||
|
TrackCode = input.TrackCode,
|
||||||
|
OperationMan = CurrentUserRequest.CurrentUser.Name,
|
||||||
|
};
|
||||||
|
|
||||||
var res = 0;
|
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent);
|
||||||
|
|
||||||
foreach (var track in tracks)
|
return $"即将推送轨迹代码{input.TrackCode}给{orderIds.Length}个订单";
|
||||||
{
|
|
||||||
var trackPushEvent = new TrackPushEvent
|
|
||||||
{
|
|
||||||
OptionType = OptionType.新增,
|
|
||||||
OrderId = track.OrderId,
|
|
||||||
OrderNo = track.OrderNo,
|
|
||||||
TrackStatus = track.TrackStatus,
|
|
||||||
TrackCode = track.TrackCode,
|
|
||||||
TrackContent = track.TrackContent,
|
|
||||||
TrackPlace = track.TrackPlace,
|
|
||||||
TrackTime = track.TrackTime,
|
|
||||||
TrackTimeZone = track.TrackTimeZone,
|
|
||||||
OperationMan = CurrentUserRequest.CurrentUser.Name,
|
|
||||||
};
|
|
||||||
|
|
||||||
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent);
|
|
||||||
|
|
||||||
res++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $"即将推送轨迹代码{input.TrackCode}给{res}个订单";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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; }
|
||||||
}
|
}
|
||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
@ -128,9 +146,8 @@ internal class TrackDetailsRepository : ElasticSearchContextAbstract<TrackDetail
|
|||||||
public async Task UpdateAsync(TrackDetailsIndex track)
|
public async Task UpdateAsync(TrackDetailsIndex track)
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user