t
This commit is contained in:
parent
3add96f52f
commit
7b3f083b9b
@ -14,25 +14,25 @@ public class EditTrackPullPriorityInput
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 轨迹拉取配置id
|
/// 轨迹拉取配置id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? TrackPullConfigId { get; set; }
|
public int TrackPullConfigId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 客户
|
/// 客户
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Customer { get; set; }
|
public string Customer { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 订单类型
|
/// 订单类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TrackOrderType? OrderType { get; set; }
|
public TrackOrderType OrderType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 优先级
|
/// 优先级
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 服务商拉取频率(分钟)
|
/// 服务商拉取频率(分钟)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? PullInterval { get; set; }
|
public int PullInterval { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using InterfaceForward.Domain.Shared.Helpers;
|
using InterfaceForward.Domain.Shared.Helpers;
|
||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
using TrackCenter.Domain.Aggregates.OrderAggregate;
|
||||||
using TrackCenter.Domain.Aggregates.TrackPullAggregate;
|
using TrackCenter.Domain.Aggregates.TrackPullAggregate;
|
||||||
using TrackCenter.Repository.Aggregates.OrderAggregate;
|
using TrackCenter.Repository.Aggregates.OrderAggregate;
|
||||||
@ -71,6 +72,65 @@ public class OrderServiceV2(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增、更新大包(存在就更新)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("OrderV2/UpsertBigBag")]
|
||||||
|
public async Task<IdBaseDto> UpsertAsync(UpsertBigBagInput input)
|
||||||
|
{
|
||||||
|
// 校验订单是否已存在,存在则更新
|
||||||
|
var order = await orderRepository.GetFirstAsync(x =>
|
||||||
|
x.AppKey == input.ApiCode && x.OrderType == TrackOrderType.大包 && x.OrderNo == input.BagNo);
|
||||||
|
// 订单已存在则视为更新
|
||||||
|
if (order != null)
|
||||||
|
{
|
||||||
|
order = await BuiltOrder(input);
|
||||||
|
|
||||||
|
await orderRepository.UpdateOrderAsync(order);
|
||||||
|
|
||||||
|
var index = new OrderOperationRecordIndex
|
||||||
|
{
|
||||||
|
OrderId = order.Id,
|
||||||
|
OrderNo = input.BagNo,
|
||||||
|
OptionType = OrderOperationType.修改订单.ToString(),
|
||||||
|
Content = input.ToJson(),
|
||||||
|
CreateUserId = CurrentUserId,
|
||||||
|
CreateUserName = CurrentUser.UserName ?? string.Empty,
|
||||||
|
};
|
||||||
|
|
||||||
|
_ = orderOperationRecordEsRepository.AddAsync(index);
|
||||||
|
|
||||||
|
return new IdBaseDto
|
||||||
|
{
|
||||||
|
Id = order.Id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
order = await BuiltOrder(input);
|
||||||
|
var orderId = await orderRepository.CreateOrderAsync(order);
|
||||||
|
|
||||||
|
// 写入操作日志
|
||||||
|
var indexForAdd = new OrderOperationRecordIndex
|
||||||
|
{
|
||||||
|
OrderId = orderId,
|
||||||
|
OrderNo = input.BagNo,
|
||||||
|
OptionType = nameof(OrderOperationType.创建订单),
|
||||||
|
Content = input.ToJson(),
|
||||||
|
CreateUserId = CurrentUserId,
|
||||||
|
CreateUserName = CurrentUser.UserName ?? string.Empty,
|
||||||
|
CreateTime = DateTime.Now
|
||||||
|
};
|
||||||
|
_ = orderOperationRecordEsRepository.AddAsync(indexForAdd);
|
||||||
|
|
||||||
|
|
||||||
|
return new IdBaseDto
|
||||||
|
{
|
||||||
|
Id = orderId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<OrderEntity> BuiltOrder(UpsertSmallBagInput input)
|
private async Task<OrderEntity> BuiltOrder(UpsertSmallBagInput input)
|
||||||
{
|
{
|
||||||
var order = new OrderEntity
|
var order = new OrderEntity
|
||||||
@ -92,86 +152,42 @@ public class OrderServiceV2(
|
|||||||
};
|
};
|
||||||
|
|
||||||
var config = await trackPullConfigRepository
|
var config = await trackPullConfigRepository
|
||||||
.GetListAsync(x => x.AppKey == input.ApiCode
|
.FirstOrDefaultAsync(x => x.AppKey == input.ApiCode
|
||||||
&& x.ServiceProviderCode == input.ApiCode && x.OrderType == TrackOrderType.小包);
|
&& x.ServiceProviderCode == input.ApiCode);
|
||||||
|
|
||||||
order.OrderPullStatus = BuiltOrderPullStatus(config, order);
|
if (config == null) throw new BusinessException(message: "没有一个拉取配置可以适用,请配置,否则无法拉取轨迹");
|
||||||
|
|
||||||
|
order.OrderPullStatus = [CreateOrderPullStatus(config, order)];
|
||||||
|
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<OrderPullStatusEntity> BuiltOrderPullStatus(
|
private Task<OrderEntity> BuiltOrder(UpsertBigBagInput input)
|
||||||
List<TrackPullConfigEntity> configs,
|
|
||||||
OrderEntity order)
|
|
||||||
{
|
{
|
||||||
if (configs.IsNullOrEmpty()) return [];
|
var order = new OrderEntity
|
||||||
|
|
||||||
TrackPullConfigEntity? selected = null;
|
|
||||||
var bestScore = -1;
|
|
||||||
|
|
||||||
foreach (var config in configs)
|
|
||||||
{
|
{
|
||||||
if (!IsConfigApplicable(config, order))
|
AppKey = input.ApiCode,
|
||||||
{
|
ServiceProviderCode = input.ApiCode,
|
||||||
continue;
|
OrderType = TrackOrderType.大包,
|
||||||
}
|
OrderNo = input.BagNo,
|
||||||
|
ThirdPartyOrderNumber = input.OtherNo,
|
||||||
|
Customer = input.Client,
|
||||||
|
Channel = input.Channel,
|
||||||
|
ProductCode = input.Product,
|
||||||
|
ArrivalCountry = input.Country
|
||||||
|
};
|
||||||
|
|
||||||
var score = CalculateMatchScore(config, order);
|
// tips: 2025-11-29 zzh 大包没有轨迹拉取能力
|
||||||
if (score > bestScore)
|
|
||||||
{
|
|
||||||
bestScore = score;
|
|
||||||
selected = config;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selected == null) throw new BusinessException(message: "没有一个拉取配置可以适用,请配置,否则无法拉取轨迹");
|
// var config = await trackPullConfigRepository
|
||||||
|
// .FirstOrDefaultAsync(x => x.AppKey == input.ApiCode
|
||||||
|
// && x.ServiceProviderCode == input.ApiCode);
|
||||||
|
//
|
||||||
|
// if (config == null) throw new BusinessException(message: "没有一个拉取配置可以适用,请配置,否则无法拉取轨迹");
|
||||||
|
//
|
||||||
|
// order.OrderPullStatus = [CreateOrderPullStatus(config, order)];
|
||||||
|
|
||||||
return [CreateOrderPullStatus(selected, order)];
|
return Task.FromResult(order);
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsConfigApplicable(TrackPullConfigEntity config, OrderEntity order)
|
|
||||||
{
|
|
||||||
return IsFieldApplicable(order.Customer, config.Customer) &&
|
|
||||||
IsFieldApplicable(order.Channel, config.Channel) &&
|
|
||||||
IsFieldApplicable(order.ProductCode, config.Product);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsFieldApplicable(string? orderValue, string? configValue)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(configValue))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Equals(configValue, orderValue, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int CalculateMatchScore(TrackPullConfigEntity config, OrderEntity order)
|
|
||||||
{
|
|
||||||
var score = 0;
|
|
||||||
|
|
||||||
if (IsPreciseMatch(order.Customer, config.Customer))
|
|
||||||
{
|
|
||||||
score++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsPreciseMatch(order.Channel, config.Channel))
|
|
||||||
{
|
|
||||||
score++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsPreciseMatch(order.ProductCode, config.Product))
|
|
||||||
{
|
|
||||||
score++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return score;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsPreciseMatch(string? orderValue, string? configValue)
|
|
||||||
{
|
|
||||||
return !string.IsNullOrWhiteSpace(configValue) &&
|
|
||||||
string.Equals(configValue, orderValue, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OrderPullStatusEntity CreateOrderPullStatus(TrackPullConfigEntity config, OrderEntity order)
|
private static OrderPullStatusEntity CreateOrderPullStatus(TrackPullConfigEntity config, OrderEntity order)
|
||||||
@ -195,6 +211,11 @@ public class OrderServiceV2(
|
|||||||
status.StartTime = DateTime.Now.AddHours(config.SilenceBeforeStart);
|
status.StartTime = DateTime.Now.AddHours(config.SilenceBeforeStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(config.EndTrackCode))
|
||||||
|
{
|
||||||
|
status.EndTime = DateTime.Now.AddHours(config.SilenceBeforeStart).AddDays(7);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,3 +294,49 @@ public class Consignee
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class UpsertBigBagInput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 客户名称,或者code,必填
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public string Client { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 客户单号,必填
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public string BagNo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 其他单号
|
||||||
|
/// </summary>
|
||||||
|
public string OtherNo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 渠道名称,或者code
|
||||||
|
/// </summary>
|
||||||
|
public string Channel { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 产品名称,或者code
|
||||||
|
/// </summary>
|
||||||
|
public string Product { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 产品名称,或者code
|
||||||
|
/// </summary>
|
||||||
|
public string Country { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 服务商code
|
||||||
|
/// </summary>
|
||||||
|
public string ApiCode { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UpsertMsterOrderInput
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -88,8 +88,7 @@ public class TrackPullService(
|
|||||||
{
|
{
|
||||||
Expression<Func<TrackPullConfigEntity, bool>> isAnyExp = x =>
|
Expression<Func<TrackPullConfigEntity, bool>> isAnyExp = x =>
|
||||||
x.AppKey == input.AppKey &&
|
x.AppKey == input.AppKey &&
|
||||||
x.ServiceProviderCode == input.ServiceProviderCode &&
|
x.ServiceProviderCode == input.ServiceProviderCode;
|
||||||
x.OrderType == input.OrderType;
|
|
||||||
if (input.Options == OptionTypeNoNull.修改) isAnyExp = isAnyExp.And(x => x.Id != input.Id);
|
if (input.Options == OptionTypeNoNull.修改) isAnyExp = isAnyExp.And(x => x.Id != input.Id);
|
||||||
|
|
||||||
if (await trackPullConfigRepository.IsAnyAsync(isAnyExp))
|
if (await trackPullConfigRepository.IsAnyAsync(isAnyExp))
|
||||||
@ -317,6 +316,8 @@ public class TrackPullService(
|
|||||||
|
|
||||||
if (await trackPullConfigRepository.IsPriorityAnyAsync(isPriorityAnyExp))
|
if (await trackPullConfigRepository.IsPriorityAnyAsync(isPriorityAnyExp))
|
||||||
throw new BusinessException("配置已存在");
|
throw new BusinessException("配置已存在");
|
||||||
|
|
||||||
|
if (input.PullInterval < 60) input.PullInterval = 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (input.Options)
|
switch (input.Options)
|
||||||
@ -345,8 +346,7 @@ public class TrackPullService(
|
|||||||
|
|
||||||
case OptionTypeNoNull.删除:
|
case OptionTypeNoNull.删除:
|
||||||
{
|
{
|
||||||
var oldTrackPullPriorityEntity =
|
_ = await trackPullConfigRepository.GetPriorityByIdAsync(input.Id!.Value) ??
|
||||||
await trackPullConfigRepository.GetPriorityByIdAsync(input.Id!.Value) ??
|
|
||||||
throw new BusinessException(message: "找不到数据");
|
throw new BusinessException(message: "找不到数据");
|
||||||
|
|
||||||
await trackPullConfigRepository.SoftDeletePriorityAsync(x => x.Id == input.Id);
|
await trackPullConfigRepository.SoftDeletePriorityAsync(x => x.Id == input.Id);
|
||||||
|
|||||||
@ -221,6 +221,7 @@ public class OrderEntity : FullAuditedAggregateRoot<int, int>
|
|||||||
|
|
||||||
[SugarColumn(IsIgnore = true)] public List<OrderFlightEntity> OrderFlights { get; set; } = [];
|
[SugarColumn(IsIgnore = true)] public List<OrderFlightEntity> OrderFlights { get; set; } = [];
|
||||||
|
|
||||||
|
// tips:2025-11-29:sp挪到订单主表了,1v1拉取
|
||||||
[SugarColumn(IsIgnore = true)] public List<OrderPullStatusEntity> OrderPullStatus { get; set; } = [];
|
[SugarColumn(IsIgnore = true)] public List<OrderPullStatusEntity> OrderPullStatus { get; set; } = [];
|
||||||
|
|
||||||
public void ResetTrackInfo()
|
public void ResetTrackInfo()
|
||||||
|
|||||||
@ -8,12 +8,6 @@ namespace TrackCenter.Domain.Aggregates.TrackPullAggregate;
|
|||||||
[SugarTable("t_track_pull_config")]
|
[SugarTable("t_track_pull_config")]
|
||||||
public class TrackPullConfigEntity : FullAuditedAggregateRoot<int, int>
|
public class TrackPullConfigEntity : FullAuditedAggregateRoot<int, int>
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 自增主键
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
|
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用
|
/// 应用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -24,7 +18,7 @@ public class TrackPullConfigEntity : FullAuditedAggregateRoot<int, int>
|
|||||||
/// 服务商代码
|
/// 服务商代码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(ColumnName = "ServiceProviderCode")]
|
[SugarColumn(ColumnName = "ServiceProviderCode")]
|
||||||
public string? ServiceProviderCode { get; set; }
|
public string ServiceProviderCode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 解析方式,1取接口通返参映射后的,2取服务商原返参
|
/// 解析方式,1取接口通返参映射后的,2取服务商原返参
|
||||||
@ -92,12 +86,6 @@ public class TrackPullConfigEntity : FullAuditedAggregateRoot<int, int>
|
|||||||
[SugarColumn(ColumnName = "TrackTimeZoneName")]
|
[SugarColumn(ColumnName = "TrackTimeZoneName")]
|
||||||
public string? TrackTimeZoneName { get; set; }
|
public string? TrackTimeZoneName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 订单类型
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnName = "OrderType")]
|
|
||||||
public TrackOrderType OrderType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开始轨迹code
|
/// 开始轨迹code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -30,7 +30,7 @@ public class TrackPullPriorityEntity: FullAuditedEntity<int, int>
|
|||||||
/// 优先级
|
/// 优先级
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(ColumnName = "优先级")]
|
[SugarColumn(ColumnName = "优先级")]
|
||||||
public string Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 服务商拉取频率(分钟)
|
/// 服务商拉取频率(分钟)
|
||||||
|
|||||||
@ -81,11 +81,6 @@ public class GetTrackPullConfigDetailOutputVO
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string TrackDetailsPath { get; set; }
|
public string TrackDetailsPath { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 订单类型
|
|
||||||
/// </summary>
|
|
||||||
public TrackOrderType OrderType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开始轨迹code
|
/// 开始轨迹code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -24,7 +24,7 @@ public class GetTrackPullPriorityDetailOutputVO
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 优先级
|
/// 优先级
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 服务商拉取频率(分钟)
|
/// 服务商拉取频率(分钟)
|
||||||
|
|||||||
@ -19,7 +19,7 @@ public class GetTrackPullPriorityPageOutputVO
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 优先级
|
/// 优先级
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 服务商拉取频率(分钟)
|
/// 服务商拉取频率(分钟)
|
||||||
|
|||||||
@ -102,7 +102,6 @@ public class TrackPullConfigRepository : BasicRepository<TrackPullConfigEntity>,
|
|||||||
TrackStatusName = trackPull.TrackStatusName,
|
TrackStatusName = trackPull.TrackStatusName,
|
||||||
OrderPath = trackPull.OrderPath,
|
OrderPath = trackPull.OrderPath,
|
||||||
TrackDetailsPath = trackPull.TrackDetailsPath,
|
TrackDetailsPath = trackPull.TrackDetailsPath,
|
||||||
OrderType = trackPull.OrderType,
|
|
||||||
StartTrackCode = trackPull.StartTrackCode,
|
StartTrackCode = trackPull.StartTrackCode,
|
||||||
EndTrackCode = trackPull.EndTrackCode,
|
EndTrackCode = trackPull.EndTrackCode,
|
||||||
SilenceBeforeStart = trackPull.SilenceBeforeStart,
|
SilenceBeforeStart = trackPull.SilenceBeforeStart,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user