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.Consts; using SJZY.Track.Domain.Queries; namespace SJZY.Track.Application.Services.ProvideServices; /// /// 订单关联服务 /// public partial class OrderService { private readonly IBasicQuery _orderLinkQuery; private readonly ICapPublisher _capPublisher; /// /// 关联、解除关联订单 /// /// /// /// [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 true; // 单号去重,去空,去自己 input.LinkOrderNos = input.LinkOrderNos .Where(x => !x.IsNullOrWhiteSpace() && x != input.OrderNo) .Distinct().ToList(); // 解绑 if (!input.IsLink) return await UnLinkOrderAsync(input); // 关联订单 var linkedOrderIds = await DoLinkOrderAsync(input, order.Id); // 补轨迹 if (linkedOrderIds.Count > 0) { await _capPublisher.PublishAsync(GlobalConst.OrderLinkAfterFillTrack, new OrderLinkAfterFillTrackEvent { OrderId = order.Id, SubSystemId = order.SubSystemId, LinkedOrderIds = linkedOrderIds, }); } return 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 }); if (canLinkOrders.Count == 0) return new List(); 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()); return canLinkOrders.Select(x => x.Id).ToList(); } 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 true; } }