using DotNetCore.CAP;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Consts;
using SJZY.Track.Domain.Queries;
namespace SJZY.Track.Application.Services.ProvideServices;
///
/// 订单关联服务
///
public partial class OrderService
{
private readonly IBasicQuery _orderLinkQuery;
private readonly ICapPublisher _capPublisher;
private readonly ITrackDetailsRepository _trackDetailsRepository;
///
/// 关联、解除关联订单
///
///
///
///
[HttpPost("Order/Link")]
public async Task LinkOrderAsync(LinkOrderInput input)
{
var order = await _orderRepository.GetFirstAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo, x => new
{
x.Id,
x.SubSystemId
});
if (order == default)
{
throw new BusinessException(message: $"订单:{input.OrderNo}不存在");
}
//tips:循环关联问题再消费时解决
if (input.OrderType == input.LinkOrderType)
{
throw new BusinessException(message: "不能同级关联");
}
if (input.LinkOrderNos.Count < 1 || input.LinkOrderType == 0) return new UnifyResultDto(true);
// 单号去重,去空,去自己
input.LinkOrderNos = input.LinkOrderNos
.Where(x => !x.IsNullOrWhiteSpace() && x != input.OrderNo)
.Distinct().ToList();
// 解绑
if (!input.IsLink) return await UnLinkOrderAsync(input);
// 关联订单
await DoLinkOrderAsync(input, order.Id);
return new UnifyResultDto(true, true);
}
private async Task DoLinkOrderAsync(LinkOrderInput input, int orderId)
{
// 获取已关联的订单
var linkOrderNos = await _orderLinkQuery.GetListAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo && x.LinkOrderType == input.LinkOrderType,
x => x.LinkOrderNo);
// 计算出未关联的订单
var noLinkOrderNos = input.LinkOrderNos.Except(linkOrderNos);
// 过滤掉不存在的订单
var canLinkOrders = await _orderRepository.GetListAsync(x =>
x.OrderType == input.LinkOrderType && noLinkOrderNos.Contains(x.OrderNo),
x => new { x.Id, x.OrderNo, x.OrderType, x.SubSystemId });
if (canLinkOrders.Count == 0) return;
await _orderRepository.LinkOrderAsync(canLinkOrders.Select(x => new OrderLinkEntity
{
OrderId = orderId,
OrderNo = input.OrderNo,
OrderType = input.OrderType,
LinkOrderId = x.Id,
LinkOrderNo = x.OrderNo,
LinkOrderType = input.LinkOrderType
}).ToList());
var tracks = await _trackDetailsRepository.GetListAsync(orderId);
// 补轨迹
foreach (var group in canLinkOrders.GroupBy(x => x.SubSystemId))
{
foreach (var track in tracks)
{
var fillTrackEvent = new TrackUpsertEvent
{
SubSystemId = group.Key,
OrderIdentifiers = group.Select(x => new OrderIdentifier
{
OrderId = x.Id,
OrderNo = x.OrderNo,
OrderType = x.OrderType
}).ToArray(),
TrackCode = track.TrackCode,
TrackPlace = track.TrackPlace,
TrackTime = track.TrackTime,
TrackTimeZone = track.TrackTimeZone,
IsAdd = true
};
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, fillTrackEvent);
}
}
}
private async Task UnLinkOrderAsync(LinkOrderInput input)
{
var unLinkIds = await _orderLinkQuery.GetListAsync(x =>
x.OrderType == input.OrderType && x.OrderNo == input.OrderNo &&
x.LinkOrderType == input.LinkOrderType && input.LinkOrderNos.Contains(x.LinkOrderNo),
x => x.Id);
// real del
await _orderRepository.UnLinkByIdsAsync(unLinkIds);
return new UnifyResultDto(true, true);
}
}