track/src/SJZY.Track.Repository/Repositories/OrderRepository.cs

397 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using SJZY.Expand.ABP.Core.Logger;
using SJZY.Track.Domain;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Consts;
using SJZY.Track.Domain.Dtos.Order;
using SJZY.Track.Domain.Enums;
using SJZY.Track.Domain.VEntities;
namespace SJZY.Track.Repository.Repositories;
public class OrderRepository : BasicRepository<OrderEntity>, IOrderRepository, ITransientDependency
{
public async Task<UnifyPageResultDto<TrackOrderVO>> GetTrackOrderPagedList(GetPageTrackOrderInputVO input)
{
//查询完去重
var pageList = await Context.Queryable<OrderEntity>()
.Includes(a => a.OrderPlatformNumbers)
.LeftJoin<VExternalSubjectEntity>((a, b) => a.CustomId == b.Id && b.IsDeleted == false)
.LeftJoin<VSystemEntity>((a, b, c) => a.SubSystemId == c.Id && c.IsDeleted == false)
.LeftJoin<OrderPlatformNumberEntity>((a, b, c, d) => a.Id == d.OrderId && d.IsDeleted == false)
.WhereIF(input.SubSystemId > 0, (a, b, c) => a.SubSystemId == input.SubSystemId)
.WhereIF(!input.OrderNos.IsNullOrEmpty(), (a, b, c, d) => input.OrderNos!.Contains(a.OrderNo) || input.OrderNos!.Contains(d.OrderNumber))
.WhereIF(input.CreateTimeStart.HasValue && input.CreateTimeEnd.HasValue,
(a, b, c) => a.CreateTime >= input.CreateTimeStart && a.CreateTime <= input.CreateTimeEnd)
.WhereIF(input.CreateTimeStart.HasValue && (!input.CreateTimeEnd.HasValue),
(a, b, c) => a.CreateTime >= input.CreateTimeStart)
.WhereIF((!input.CreateTimeStart.HasValue) && input.CreateTimeEnd.HasValue,
(a, b, c) => a.CreateTime <= input.CreateTimeEnd)
.WhereIF(input.CustomerId > 0, (a, b, c) => a.CustomId == input.CustomerId)
.WhereIF(input.TrackOrderType > 0, (a, b, c) => a.OrderType == input.TrackOrderType)
.WhereIF(input.TabType > 0, (a, b, c) => a.QuestionType == input.TabType)
.WhereIF(input.TabType == (int) TrackProblemType.Warn, (a, b, c) => !a.IsCompleted)
.OrderByDescending((a, b, c) => a.CreateTime)
.Distinct()
.Select((a, b, c) => new TrackOrderVO
{
Id = a.Id,
OrderNumber = a.OrderNo,
OrderType = a.OrderType,
QuestionType = a.QuestionType,
CustomerShortName = b.Abbreviation,
CustomerCode = b.Code,
CustomerId = a.CustomId,
NewestTrackContent = a.LatestTrackContent,
NewestTrackEnContent = a.LatestTrackEnContent,
NewestTrackPlace = a.LatestTrackPlace,
NewestTrackTime = a.LatestTrackTime,
IsFinish = a.IsCompleted,
CreateTime = a.CreateTime,
SubSystem = c.CnName,
SubSystemId = c.Id,
DestinationTimeZone = a.DestinationTimeZone,
EstimatedDeliveryDate = a.EstimatedDeliveryDate,
ThirdPartyOrderNumber = BuildThirdPartyOrderNumber(a.OrderPlatformNumbers)
})
.ToPagedListAsync(input.PageIndex, input.PageSize);
return pageList;
}
public async Task<(int MainOrderId, int CustomId)> GetTrackOrderByProviderAndOrderNo(string serviceProvidrCode, string orderNo)
{
var orderList = await Context.Queryable<OrderEntity>()
.LeftJoin<OrderPlatformNumberEntity>((a, b) => a.Id == b.OrderId && b.IsDeleted)
.Where((a, b) => a.OrderNo == orderNo
|| (b.Platform == serviceProvidrCode && b.OrderNumber == orderNo))
.Select((a, b) => new
{
a.Id,
a.CustomId,
b.Platform,
b.OrderNumber
})
.ToListAsync();
if (orderList.Count == 0)
{
return default;
}
var order = orderList.First();
//当出现了多条记录匹配,优先使用外部单匹配提升精确度
var matchOrder = orderList.FirstOrDefault(x => x.Platform == serviceProvidrCode && x.OrderNumber == orderNo);
return matchOrder != null
? (matchOrder.Id, matchOrder.CustomId)
: (order.Id, order.CustomId);
}
public async Task<int> CreateOrderAsync(OrderEntity order)
{
using var tran = TransactionHelper.GetReadCommitted();
var orderId = await InsertReturnIdentityAsync(order);
order.OrderFlights.ForEach(x => x.OrderId = orderId);
await Context.Insertable(order.OrderFlights).ExecuteCommandAsync();
order.OrderPullStatus.ForEach(x => x.OrderId = orderId);
await Context.Insertable(order.OrderPullStatus).ExecuteCommandAsync();
order.OrderPlatformNumbers.ForEach(x => x.OrderId = orderId);
await Context.Insertable(order.OrderPlatformNumbers).ExecuteCommandAsync();
tran.Complete();
return orderId;
}
public Task<int> UpdateBatchIdsAsync(List<int> ids, int newValue)
{
var idsString = string.Join(",", ids);
return Context.Ado.ExecuteCommandAsync(
$"UPDATE `t_order` SET `DeficiencyTag` = @newValue ,UpdateTime= current_timestamp WHERE `Id` IN ({idsString})",
new
{
newValue
});
}
public async Task UpdateOrderAsync(OrderEntity order)
{
using var tran = TransactionHelper.GetReadCommitted();
// 更新订单主表
await UpdateAsync(order, x => new
{
x.CustomId,
x.SubSystemId
});
// 更新订单模板
await Context.Deleteable<OrderPullStatusEntity>().Where(x => x.OrderId == order.Id).ExecuteCommandAsync();
order.OrderPullStatus.ForEach(x => x.OrderId = order.Id);
await Context.Insertable(order.OrderPullStatus).ExecuteCommandAsync();
// 更新订单三方关联
await Context.Deleteable<OrderPlatformNumberEntity>().Where(x => x.OrderId == order.Id).ExecuteCommandAsync();
order.OrderPlatformNumbers.ForEach(x => x.OrderId = order.Id);
await Context.Insertable(order.OrderPlatformNumbers).ExecuteCommandAsync();
// 更新订单航班
await Context.Deleteable<OrderFlightEntity>().Where(x => x.OrderId == order.Id).ExecuteCommandAsync();
order.OrderFlights.ForEach(x => x.OrderId = order.Id);
await Context.Insertable(order.OrderFlights).ExecuteCommandAsync();
tran.Complete();
}
public async Task DeleteOrderAsync(int orderId)
{
using var tran = TransactionHelper.GetReadCommitted();
// 软删订单主表
await SoftDeleteAsync(x => x.Id == orderId);
// 软删订单航班
// 软删订单关联关系
// 软删订单拉取状态
tran.Complete();
}
/// <summary>
/// 更新推送预警单
/// </summary>
/// <param name="subSystemId"></param>
/// <param name="pageSize"></param>
/// <param name="pageindex"></param>
/// <returns></returns>
public async Task<int> PushWarnOrdersAsync(int subSystemId, int pageSize, int pageindex)
{
var ordersToUpdate = await Context.Queryable<OrderEntity>()
.Where(b => b.SubSystemId == subSystemId && !b.IsCompleted && b.QuestionType != 1)
.Select(b => new
{
b.LatestPushTime,
b.Id,
b.QuestionType
})
.ToPageListAsync(pageindex, pageSize);
var latestPushTimeIds = new List<int>();
var questionZeroIds = new List<int>();
foreach (var item in ordersToUpdate)
{
var questionType = !item.LatestPushTime.HasValue || item.LatestPushTime < DateTime.Now.AddHours(-12)
? 2
: 0;
if (item.QuestionType == questionType) continue;
if (questionType == 2) latestPushTimeIds.AddLast(item.Id);
else questionZeroIds.AddLast(item.Id);
}
if (latestPushTimeIds.Count > 0) UpdateOrderQuestionType(2, latestPushTimeIds);
if (questionZeroIds.Count > 0) UpdateOrderQuestionType(0, questionZeroIds);
return ordersToUpdate.Count;
}
public async Task<List<(string code, int id)>> GetSubSystemListByCodesAsync(List<string> codes)
{
var res = await Context.Queryable<VSystemEntity>()
.Where(x => codes.Contains(x.Key))
.Select(x => new
{
x.Key,
x.Id
})
.ToListAsync();
return res.Select(x => (x.Key, x.Id)).ToList();
}
public Task<VSystemEntity> GetSystemInfoById(int id)
{
return Context.Queryable<VSystemEntity>().FirstAsync(m => m.IsDeleted == false && m.Id == id);
}
public Task<VUserEntity> GetUserById(int id)
{
return Context.Queryable<VUserEntity>().FirstAsync(m => m.IsDeleted == false && m.Id == id);
}
private int UpdateOrderQuestionType(int questionType, IEnumerable<int> ids)
{
var idsString = string.Join(",", ids);
return Context.Ado.ExecuteCommand(
$"UPDATE `t_order` SET `QuestionType` = @questionType ,UpdateTime= current_timestamp WHERE `Id` IN ({idsString})",
new
{
questionType
});
}
/// <summary>
/// 拼接多个三方单号,默认使用分隔符默认(、)
/// 第三方单号展示: 0000000(服务商)、0000000(服务商)
/// </summary>
/// <param name="orderPlatformNumberEntities"></param>
/// <returns></returns>
private static string BuildThirdPartyOrderNumber(List<OrderPlatformNumberEntity> orderPlatformNumberEntities)
{
const string separator = "、";
var thirdPartyOrderNumbers = orderPlatformNumberEntities
.Where(x => !string.IsNullOrWhiteSpace(x.OrderNumber))
.Select(x => $"{x.OrderNumber}({x.Platform})").ToList();
return string.Join(separator, thirdPartyOrderNumbers);
}
#region 订单关联
public async Task<List<LinkedOrderVO>> GetLinkedOrdersAsync(int[] orderIds)
{
return await Context.Queryable<OrderLinkEntity>()
.LeftJoin<OrderEntity>((a, b) => a.LinkOrderId == b.Id)
.Where(a => orderIds.Contains(a.OrderId))
.Select((a, b) => new LinkedOrderVO
{
OwnerOrderId = a.OrderId,
OrderId = b.Id,
OrderNo = b.OrderNo,
OrderType = b.OrderType,
SubSystemId = b.SubSystemId,
CustomId = b.CustomId
})
.ToListAsync();
}
public async Task<List<string>> GetLinkedOrdersAsync(int orderId, int linkSubSystemId, int linkOrderType)
{
return await Context.Queryable<OrderLinkEntity>()
.LeftJoin<OrderEntity>((a, b) => a.LinkOrderId == b.Id)
.Where((a, b) => orderId == a.OrderId && b.SubSystemId == linkSubSystemId && b.OrderType == linkOrderType)
.Select((a, b) => b.OrderNo)
.ToListAsync();
}
public async Task<List<int>> GetLinkedOrdersAsync(int orderId, int linkSubSystemId, int linkOrderType,
List<string> linkOrderNos)
{
return await Context.Queryable<OrderLinkEntity>()
.LeftJoin<OrderEntity>((a, b) => a.LinkOrderId == b.Id)
.Where((a, b) => orderId == a.OrderId && b.SubSystemId == linkSubSystemId && b.OrderType == linkOrderType
&& linkOrderNos.Contains(b.OrderNo))
.Select((a, b) => a.Id)
.ToListAsync();
}
public async Task LinkOrderAsync(List<OrderLinkEntity> orderLinkEntities)
{
await Context.Insertable(orderLinkEntities).ExecuteCommandAsync();
}
public async Task UnLinkByIdsAsync(List<int> linkIds)
{
await Context.Deleteable<OrderLinkEntity>(linkIds).ExecuteCommandAsync();
}
#endregion
#region 订单拉取
public async Task UpdatePullStatusToSilenceAsync(List<int> orderIds, string trackCode)
{
// var status = await Context.Queryable<OrderPullStatusEntity>()
// .Where(x => orderIds.Contains(x.OrderId) && x.StartTrackCode == trackCode)
// .Where(x => x.PullStatus == TrackPullStatus.Init || x.PullStatus == TrackPullStatus.Pulling)
// .Select(x => new
// {
// x.Id,
// x.PullStatus,
// x.SilenceBeforeStart,
// x.SilenceAfterEnd,
// x.StartTime,
// x.EndTime
// })
// .ToListAsync();
//
// // 初始态-》静默前、拉取中-》静默后
// var changes = status.Select(x => new
// {
// x.Id,
// PullStatus = x.PullStatus == TrackPullStatus.Init
// ? x.SilenceBeforeStart > 0
// ? TrackPullStatus.SilenceBeforeStart
// : TrackPullStatus.Pulling
// : x.SilenceAfterEnd > 0
// ? TrackPullStatus.SilenceAfterEnd
// : TrackPullStatus.Completed,
// StartTime =
// x.PullStatus == TrackPullStatus.Init ? DateTime.Now.AddHours(x.SilenceBeforeStart) : x.StartTime,
// EndTime = x.PullStatus == TrackPullStatus.Pulling ? DateTime.Now.AddHours(x.SilenceAfterEnd) : x.EndTime
// });
// await Context.Updateable<OrderPullStatusEntity>(changes).ExecuteCommandAsync();
// 初始态-》静默前
await Context.Updateable<OrderPullStatusEntity>()
.SetColumns(x => x.PullStatus == TrackPullStatus.SilenceBeforeStart)
.SetColumns(x => x.StartTime == DateTime.Now.AddHours(x.SilenceBeforeStart))
.Where(x => orderIds.Contains(x.OrderId) && x.StartTrackCode == trackCode)
.Where(x => x.PullStatus == TrackPullStatus.Init)
.ExecuteCommandAsync();
// 拉取中-》静默后
await Context.Updateable<OrderPullStatusEntity>()
.SetColumns(x => x.PullStatus == TrackPullStatus.SilenceAfterEnd)
.SetColumns(x => x.EndTime == DateTime.Now.AddHours(x.SilenceAfterEnd)) // >0才有意义
.Where(x => orderIds.Contains(x.OrderId) && x.EndTrackCode == trackCode)
.Where(x => x.PullStatus == TrackPullStatus.Pulling)
.ExecuteCommandAsync();
}
public async Task<int> UpdatePullStatusBySilenceAsync()
{
var cnt1 = await Context.Updateable<OrderPullStatusEntity>()
.SetColumns(x => x.PullStatus == TrackPullStatus.Pulling)
.Where(x => x.PullStatus == TrackPullStatus.SilenceBeforeStart && x.StartTime < DateTime.Now)
.ExecuteCommandAsync();
LogHelper.Info(
$"{cnt1}条订单的拉取状态由{nameof(TrackPullStatus.SilenceBeforeStart)}更新为{nameof(TrackPullStatus.Pulling)}");
var cnt2 = await Context.Updateable<OrderPullStatusEntity>()
.SetColumns(x => x.PullStatus == TrackPullStatus.Completed)
.Where(x => x.PullStatus == TrackPullStatus.SilenceAfterEnd && x.EndTime < DateTime.Now)
.ExecuteCommandAsync();
LogHelper.Info(
$"{cnt2}条订单的拉取状态由{nameof(TrackPullStatus.SilenceAfterEnd)}更新为{nameof(TrackPullStatus.Completed)}");
return cnt1 + cnt2;
}
public async Task<int> ClearPullStatusAsync()
{
var time = DateTime.Now.Subtract(TimeSpan.FromDays(30));
return await Context.Deleteable<OrderPullStatusEntity>().Where(x =>
x.PullStatus == TrackPullStatus.Completed || x.StartTime < time)
.ExecuteCommandAsync();
}
public async Task<int> UpdateOrderPullConfigForServiceProviderAsync(
UpdateOrderPullConfigsInputVo inputVo)
{
// tips:如此更新,影响范围是否可控?状态是否正确?
return await Context.Updateable<OrderPullStatusEntity>()
.SetColumns(x => x.ServiceProviderCode == inputVo.ServiceCode)
.SetColumns(x => x.StartTrackCode == inputVo.StartCode)
.SetColumns(x => x.EndTrackCode == inputVo.EndCode)
.SetColumns(x => x.SilenceBeforeStart == inputVo.SilenceTime)
.SetColumns(x => x.SilenceAfterEnd == inputVo.StopTime)
// 直接将订单拉取状态更新为拉取中,不再考虑性能
.SetColumns(x => x.StartTime == DateTime.Now)
.SetColumns(x => x.EndTime == GlobalConst.MaxDateTime)
.SetColumns(x => x.PullStatus == TrackPullStatus.Pulling)
.Where(x => inputVo.OrderIds.Contains(x.OrderId))
.ExecuteCommandAsync();
}
#endregion
}