diff --git a/src/SJZY.Track.Api/appsettings.json b/src/SJZY.Track.Api/appsettings.json
index 41fc37c6..ac8a5882 100644
--- a/src/SJZY.Track.Api/appsettings.json
+++ b/src/SJZY.Track.Api/appsettings.json
@@ -7,7 +7,7 @@
"Apollo": {
"AppId": "SJZY.Track.Configuration",
"Env": "DEV",
- "Namespace": "test",
+ "Namespace": "dev",
"MetaServer": "http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080",
"ConfigServer": [
"http://apollo-service-test-apollo-configservice.apollo.svc.cluster.local:8080"
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackByEsIdInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackByEsIdInput.cs
new file mode 100644
index 00000000..681b3b75
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchDeleteTrackByEsIdInput.cs
@@ -0,0 +1,13 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
+
+public class BatchDeleteTrackByEsIdInput
+{
+
+ ///
+ /// 轨迹内容es id,必填
+ ///
+ [MaxLength(500)]
+ public List TrackContentEsIds { get; set; } = new();
+}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs
index d8cab392..3992554f 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/BatchUpsertTrackInput.cs
@@ -35,4 +35,82 @@ public class BatchUpsertTrackInput : OrderNosInfo
[Required]
[Range(-12, 12)]
public float TrackTimeZone { get; set; }
+
+ ///
+ /// 客户是否可见
+ ///
+ [Required]
+ public bool IsVisibility { get; set; }
+
+ ///
+ /// 数据来源:1外部服务商创建,2内部系统创建,3人工创建
+ ///
+ [Required]
+ public int Source { get; set; }
+
+ ///
+ /// 轨迹备注
+ ///
+ public string? Remarks { get; set; }
+
+ ///
+ /// 附件集合
+ ///
+ public List? Files { get; set; }
+
+ ///
+ /// 轨迹内容,若为空则取轨迹内容表中该轨迹Code对应的轨迹内容
+ ///
+ public string? Content { get; set; }
+
+ ///
+ /// 轨迹内容英文,若为空则取轨迹内容表中该轨迹Code对应的轨迹英文内容
+ ///
+ public string? EnStatus { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)
+ ///
+ public string? TrackPlaceCity { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)Id
+ ///
+ public int? TrackPlaceCityId { get; set; }
+
+ ///
+ /// 轨迹发生地(省/州)
+ ///
+ public string? TrackPlaceProvince { get; set; }
+
+ ///
+ ///轨迹发生地(省/州)Id
+ ///
+ public int? TrackPlaceProvinceId { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)
+ ///
+ public string? TrackPlaceNation { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)Id
+ ///
+ public int? TrackPlaceNationId { get; set; }
+
+ ///
+ /// 轨迹发生地邮编
+ ///
+ public string? TrackPlacePostcode { get; set; }
+
+ ///
+ /// 预计到达时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 目的地时区
+ ///
+ [Range(-12, 12)]
+ public float? DestinationTimeZone { get; set; }
}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/FileItemDto.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/FileItemDto.cs
new file mode 100644
index 00000000..f483a7ab
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/FileItemDto.cs
@@ -0,0 +1,14 @@
+namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
+
+public class FileItemDto
+{
+ ///
+ /// 文件osskey
+ ///
+ public string OssKey { get; set; }
+
+ ///
+ /// 文件名称
+ ///
+ public string FileName { get; set; }
+}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetDetailTimelineInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetDetailTimelineInput.cs
new file mode 100644
index 00000000..21ec867c
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetDetailTimelineInput.cs
@@ -0,0 +1,19 @@
+namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
+
+public class GetDetailTimelineInput
+{
+ ///
+ /// 订单编号
+ ///
+ public string OrderNumber { get; set; }
+
+ ///
+ /// 订单所属子系统id
+ ///
+ public int SystemId { get; set; }
+
+ ///
+ /// 当前用户登陆子系统id
+ ///
+ public int CurrenUserSystemId { get; set; }
+}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetDetailTimelineOutput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetDetailTimelineOutput.cs
new file mode 100644
index 00000000..4441323c
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetDetailTimelineOutput.cs
@@ -0,0 +1,92 @@
+namespace SJZY.Track.Application.Contract.Dtos.ProvideServices;
+
+public class GetDetailTimelineOutput
+{
+ ///
+ /// 轨迹编码
+ ///
+ public string TrackCode { get; set; }
+
+ ///
+ /// 轨迹内容
+ ///
+ public string Content { get; set; }
+
+ ///
+ /// 轨迹英文内容
+ ///
+ public string EnContent { get; set; }
+
+ ///
+ /// 轨迹发生时间
+ ///
+ public long TrackTime { get; set; }
+
+ ///
+ /// 轨迹时间前缀
+ ///
+ public string TrackTimePrefix { get; set; }
+
+ ///
+ /// 轨迹发生时区
+ ///
+ public string TrackTimeZone { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string Remark { get; set; }
+
+ ///
+ /// 文件 osskey 集合
+ ///
+ public List Files { get; set; }
+
+ ///
+ /// 是否高亮
+ ///
+ public bool IsHighlight { get; set; }
+
+ ///
+ /// 是否显示悬停效果
+ ///
+ public bool IsShowHover { get; set; }
+
+ ///
+ /// 轨迹发生地
+ ///
+ public string TrackPlace { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)
+ ///
+ public string? TrackPlaceCity { get; set; }
+
+ ///
+ /// 轨迹发生地(省/州)
+ ///
+ public string? TrackPlaceProvince { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)
+ ///
+ public string? TrackPlaceNation { get; set; }
+}
+
+public class TrackFileItem
+{
+ ///
+ /// 文件osskey
+ ///
+ public string OssKey { get; set; }
+
+ ///
+ /// 文件名称
+ ///
+ public string FileName { get; set; }
+
+ ///
+ /// 文件url
+ ///
+ public string Url { get; set; }
+}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetOrderDetailsInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetOrderDetailsInput.cs
index 265723e8..23cdaec4 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetOrderDetailsInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetOrderDetailsInput.cs
@@ -86,4 +86,54 @@ public class TrackOrderDetailDto
/// 创建人
///
public string? CreateUser { get; set; }
+
+ ///
+ /// 客户是否可见
+ ///
+ public bool IsVisibility { get; set; }
+
+ ///
+ /// 数据来源:1外部服务商创建,2内部系统创建,3人工创建
+ ///
+ public int Source { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string? Remarks { get; set; }
+
+ ///
+ /// 附件集合
+ ///
+ public List? Files { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)
+ ///
+ public string? TrackPlaceCity { get; set; }
+
+ ///
+ /// 轨迹发生地(省/州)
+ ///
+ public string? TrackPlaceProvince { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)
+ ///
+ public string? TrackPlaceNation { get; set; }
+
+ ///
+ /// 轨迹发生地邮编
+ ///
+ public string? TrackPlacePostcode { get; set; }
+
+ ///
+ /// 预计到达时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 目的地时区
+ ///
+ public float? DestinationTimeZone { get; set; }
}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetPageTrackOrderInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetPageTrackOrderInput.cs
index 61d9fb82..324e9c48 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetPageTrackOrderInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/GetPageTrackOrderInput.cs
@@ -152,4 +152,19 @@ public class TrackOrderDto
///// 问题描述名称
/////
//public string? ProblemDescriptionName { get; set; }
+
+ ///
+ /// 预计到达时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 目的地时区
+ ///
+ public float? DestinationTimeZone { get; set; }
+
+ ///
+ /// 第三方单号,服务商-轨迹0000000、轨迹服务商-0000000
+ ///
+ public string? ThirdPartyOrderNumber { get; set; }
}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpdateOrderInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpdateOrderInput.cs
index 02f025e8..b46ff5be 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpdateOrderInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpdateOrderInput.cs
@@ -57,6 +57,16 @@ public class UpdateOrderInput : OrderNoInfo
///
public string? ProductCode { get; set; }
+ ///
+ /// 预计到达时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 目的地时区
+ ///
+ public float? DestinationTimeZone { get; set; }
+
///
/// 拉取配置信息
///
@@ -76,6 +86,11 @@ public class PullConfigInfo
[Required]
public string ServiceCode { get; set; }
+ ///
+ /// api服务商订单号(第三方单号)
+ ///
+ public string? OrderNo { get; set; }
+
///
/// 开始轨迹code
///
diff --git a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs
index 945a973b..309d652e 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/ProvideServices/UpsertTrackInput.cs
@@ -35,4 +35,82 @@ public class UpsertTrackInput : OrderNoInfo
[Required]
[Range(-12, 12)]
public float? TrackTimeZone { get; set; }
+
+ ///
+ /// 客户是否可见
+ ///
+ [Required]
+ public bool IsVisibility { get; set; }
+
+ ///
+ /// 数据来源:1外部服务商创建,2内部系统创建,3人工创建
+ ///
+ [Required]
+ public int Source { get; set; }
+
+ ///
+ /// 轨迹备注
+ ///
+ public string? Remarks { get; set; }
+
+ ///
+ /// 附件集合
+ ///
+ public List? Files { get; set; }
+
+ ///
+ /// 轨迹内容,若为空则取轨迹内容表中该轨迹Code对应的轨迹内容
+ ///
+ public string? Content { get; set; }
+
+ ///
+ /// 轨迹内容英文,若为空则取轨迹内容表中该轨迹Code对应的轨迹英文内容
+ ///
+ public string? EnStatus { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)
+ ///
+ public string? TrackPlaceCity { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)Id
+ ///
+ public int? TrackPlaceCityId { get; set; }
+
+ ///
+ /// 轨迹发生地(省/州)
+ ///
+ public string? TrackPlaceProvince { get; set; }
+
+ ///
+ /// 轨迹发生地(省/州)Id
+ ///
+ public int? TrackPlaceProvinceId { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)
+ ///
+ public string? TrackPlaceNation { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)Id
+ ///
+ public int? TrackPlaceNationId { get; set; }
+
+ ///
+ /// 轨迹发生地邮编
+ ///
+ public string? TrackPlacePostcode { get; set; }
+
+ ///
+ /// 预计到达时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 目的地时区
+ ///
+ [Range(-12, 12)]
+ public float? DestinationTimeZone { get; set; }
}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackContents/EditTrackContentInput.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/EditTrackContentInput.cs
index 6b7c663f..8b1aca31 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/TrackContents/EditTrackContentInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/EditTrackContentInput.cs
@@ -46,6 +46,21 @@ public class EditTrackContentInput
/// 是否对外
///
public bool IsExternal { get; set; }
+
+ ///
+ /// 是否可重复
+ ///
+ public bool IsRepeatable { get; set; }
+
+ ///
+ /// 是否允许手动修改
+ ///
+ public bool IsAllowManuallyUpdate { get; set; }
+
+ ///
+ /// 是否允许手动创建
+ ///
+ public bool IsAllowManuallyCreate { get; set; }
}
public class GetTrackContentDetailDto
@@ -104,4 +119,19 @@ public class GetTrackContentDetailDto
/// 是否对外
///
public bool IsExternal { get; set; }
+
+ ///
+ /// 是否可重复
+ ///
+ public bool IsRepeatable { get; set; }
+
+ ///
+ /// 是否允许手动修改
+ ///
+ public bool IsAllowManuallyUpdate { get; set; }
+
+ ///
+ /// 是否允许手动创建
+ ///
+ public bool IsAllowManuallyCreate { get; set; }
}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetAvailableContentInput.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetAvailableContentInput.cs
new file mode 100644
index 00000000..fb6aa163
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetAvailableContentInput.cs
@@ -0,0 +1,25 @@
+namespace SJZY.Track.Application.Contract.Dtos.TrackContents;
+
+public class GetAvailableContentInput
+{
+ ///
+ /// 子系统id
+ ///
+ public int SystemId { get; set; }
+
+ ///
+ /// 订单号
+ ///
+ public string? OrderNo { get; set; }
+
+ ///
+ /// 操作类型 1=创建 2=修改
+ ///
+ public TrackOptionType TrackOptionType { get; set; }
+}
+
+public enum TrackOptionType
+{
+ 创建 = 1,
+ 修改 = 2
+}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetAvailableContentOutput.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetAvailableContentOutput.cs
new file mode 100644
index 00000000..69e77773
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetAvailableContentOutput.cs
@@ -0,0 +1,29 @@
+namespace SJZY.Track.Application.Contract.Dtos.TrackContents;
+
+public class GetAvailableContentOutput
+{
+ ///
+ /// Id
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// 轨迹内容代码
+ ///
+ public string Code { get; set; }
+
+ ///
+ /// 轨迹内容
+ ///
+ public string Content { get; set; }
+
+ ///
+ /// 轨迹内容英文
+ ///
+ public string EnContent { get; set; }
+
+ ///
+ /// 是否对外
+ ///
+ public bool IsExternal { get; set; }
+}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetPageTrackContentInput.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetPageTrackContentInput.cs
index 9a5693a3..1d5cceac 100644
--- a/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetPageTrackContentInput.cs
+++ b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetPageTrackContentInput.cs
@@ -89,4 +89,19 @@ public class GetTrackContentListDto
/// 修改人
///
public string UpdateUser { get; set; }
+
+ ///
+ /// 是否可重复
+ ///
+ public bool IsRepeatable { get; set; }
+
+ ///
+ /// 是否允许手动修改
+ ///
+ public bool IsAllowManuallyUpdate { get; set; }
+
+ ///
+ /// 是否允许手动创建
+ ///
+ public bool IsAllowManuallyCreate { get; set; }
}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetTrackContentByCodeInput.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetTrackContentByCodeInput.cs
new file mode 100644
index 00000000..8f7b1c85
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetTrackContentByCodeInput.cs
@@ -0,0 +1,14 @@
+namespace SJZY.Track.Application.Contract.Dtos.TrackContents;
+
+public class GetTrackContentByCodeInput
+{
+ ///
+ /// 子系统id
+ ///
+ public int SystemId { get; set; }
+
+ ///
+ /// 轨迹内容code
+ ///
+ public string Code { get; set; }
+}
diff --git a/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetTrackContentByCodeOutput.cs b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetTrackContentByCodeOutput.cs
new file mode 100644
index 00000000..e584522d
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Dtos/TrackContents/GetTrackContentByCodeOutput.cs
@@ -0,0 +1,19 @@
+namespace SJZY.Track.Application.Contract.Dtos.TrackContents;
+
+public class GetTrackContentByCodeOutput
+{
+ ///
+ /// 中文内容
+ ///
+ public string Content { get; set; }
+
+ ///
+ /// 英文内容
+ ///
+ public string EnContent { get; set; }
+
+ ///
+ /// 是否对外
+ ///
+ public bool IsExternal { get; set; }
+}
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs
index 037c5a8c..90c807d0 100644
--- a/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs
+++ b/src/SJZY.Track.Application.Contract/Events/TrackChangeAfterUpdateOrderEvent.cs
@@ -41,4 +41,14 @@ public class TrackChangeAfterUpdateOrderEvent
/// 时区缺失和发生地缺失标记,1表示时区,2表示发生地,3表示两种
///
public int DeficiencyTagValue { get; set; }
+
+ ///
+ /// 预计到达时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 签收地时区
+ ///
+ public float? DestinationTimeZone { get; set; }
}
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackChangeEto.cs b/src/SJZY.Track.Application.Contract/Events/TrackChangeEto.cs
new file mode 100644
index 00000000..f2eb4fe9
--- /dev/null
+++ b/src/SJZY.Track.Application.Contract/Events/TrackChangeEto.cs
@@ -0,0 +1,131 @@
+using SJZY.Track.Application.Contract.Dtos.ProvideServices;
+
+namespace SJZY.Track.Application.Contract.Events;
+
+public class TrackChangeEto
+{
+ ///
+ /// 操作类型:1新增,2删除,3修改
+ ///
+ public int Option { get; set; }
+
+ ///
+ /// 子系统id
+ ///
+ public int SubSystemId { get; set; }
+
+ ///
+ /// 单号
+ ///
+ public string OrderNo { get; set; }
+
+ ///
+ /// 客户id
+ ///
+ public int CustomId { get; set; }
+
+ ///
+ /// 订单id
+ ///
+ public OrderIdentifier[] OrderIdentifiers { get; set; } = null!;
+
+ ///
+ /// 操作人
+ ///
+ public string? OperationMan { get; set; }
+
+ ///
+ /// 轨迹内容代码
+ ///
+ public string TrackCode { get; set; } = null!;
+
+ ///
+ /// 轨迹内容
+ ///
+ public string? Content { get; set; }
+
+ ///
+ /// 轨迹内容英文
+ ///
+ public string? EnStatus { get; set; }
+
+ ///
+ /// 轨迹状态代码
+ ///
+ public string TrackStatusCode { get; set; }
+
+ ///
+ /// 轨迹发生地
+ ///
+ public string TrackPlace { get; set; } = null!;
+
+ ///
+ /// 轨迹发生时间
+ ///
+ public DateTime TrackTime { get; set; }
+
+ ///
+ /// 轨迹发生地时区
+ ///
+ public float TrackTimeZone { get; set; }
+
+ ///
+ /// 客户是否可见
+ ///
+ public bool IsVisibility { get; set; }
+
+ ///
+ /// 数据来源:1外部服务商创建,2内部系统创建,3人工创建
+ ///
+ public int Source { get; set; }
+
+ ///
+ /// 轨迹备注
+ ///
+ public string? Remarks { get; set; }
+
+ ///
+ /// 附件集合
+ ///
+ public List? Files { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)
+ ///
+ public string? TrackPlaceCity { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)Id
+ ///
+ public int? TrackPlaceCityId { get; set; }
+
+ ///
+ /// 轨迹发生地(省/州)
+ ///
+ public string? TrackPlaceProvince { get; set; }
+
+ ///
+ ///轨迹发生地(省/州)Id
+ ///
+ public int? TrackPlaceProvinceId { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)
+ ///
+ public string? TrackPlaceNation { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)Id
+ ///
+ public int? TrackPlaceNationId { get; set; }
+
+ ///
+ /// 轨迹发生地邮编
+ ///
+ public string? TrackPlacePostcode { get; set; }
+
+ ///
+ /// 预计到达时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+}
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
index f395e972..e8072e27 100644
--- a/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
+++ b/src/SJZY.Track.Application.Contract/Events/TrackDeleteEvent.cs
@@ -7,6 +7,11 @@ public class TrackDeleteEvent
///
public int SubSystemId { get; set; }
+ ///
+ /// es中的id
+ ///
+ public string[] EsIds { get; set; }
+
///
/// 订单ids
///
@@ -22,6 +27,11 @@ public class TrackDeleteEvent
///
public string? OperationMan { get; set; }
+ ///
+ /// 操作人姓名
+ ///
+ public int OperationManId { get; set; }
+
///
/// 已经处理过的订单
///
diff --git a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs
index 1bd4b033..483c929b 100644
--- a/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs
+++ b/src/SJZY.Track.Application.Contract/Events/TrackUpsertEvent.cs
@@ -1,3 +1,5 @@
+using SJZY.Track.Application.Contract.Dtos.ProvideServices;
+
namespace SJZY.Track.Application.Contract.Events;
public class TrackUpsertEvent
@@ -22,6 +24,11 @@ public class TrackUpsertEvent
///
public string? OperationMan { get; set; }
+ ///
+ /// 操作人id
+ ///
+ public int OperationManId { get; set; }
+
///
/// true新增,false更新
///
@@ -54,6 +61,81 @@ public class TrackUpsertEvent
public TrackRefreshStruct TrackRefreshData { get; set; }
+ ///
+ /// 客户是否可见
+ ///
+ public bool IsVisibility { get; set; }
+
+ ///
+ /// 数据来源:1外部服务商创建,2内部系统创建,3人工创建
+ ///
+ public int Source { get; set; }
+
+ ///
+ /// 轨迹备注
+ ///
+ public string? Remarks { get; set; }
+
+ ///
+ /// 附件集合
+ ///
+ public List? Files { get; set; }
+
+ ///
+ /// 轨迹内容,若为空则取轨迹内容表中该轨迹Code对应的轨迹内容
+ ///
+ public string? Content { get; set; }
+
+ ///
+ /// 轨迹内容英文,若为空则取轨迹内容表中该轨迹Code对应的轨迹英文内容
+ ///
+ public string? EnStatus { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)
+ ///
+ public string? TrackPlaceCity { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)Id
+ ///
+ public int? TrackPlaceCityId { get; set; }
+
+ ///
+ /// 轨迹发生地(省/州)
+ ///
+ public string? TrackPlaceProvince { get; set; }
+
+ ///
+ ///轨迹发生地(省/州)Id
+ ///
+ public int? TrackPlaceProvinceId { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)
+ ///
+ public string? TrackPlaceNation { get; set; }
+
+ ///
+ /// 轨迹发生地(国家/地区)Id
+ ///
+ public int? TrackPlaceNationId { get; set; }
+
+ ///
+ /// 轨迹发生地邮编
+ ///
+ public string? TrackPlacePostcode { get; set; }
+
+ ///
+ /// 预计到达时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 目的地时区
+ ///
+ public float? DestinationTimeZone { get; set; }
+
public override string ToString()
{
return
diff --git a/src/SJZY.Track.Application/AutoMapper/OrderAutoMapperProfile.cs b/src/SJZY.Track.Application/AutoMapper/OrderAutoMapperProfile.cs
index 8fc8a9d4..f1a32d4d 100644
--- a/src/SJZY.Track.Application/AutoMapper/OrderAutoMapperProfile.cs
+++ b/src/SJZY.Track.Application/AutoMapper/OrderAutoMapperProfile.cs
@@ -33,6 +33,7 @@ public class OrderAutoMapperProfile : Profile
.ForMember(dest => dest.Content, opt => opt.MapFrom(m => m.TrackContent))
.ForMember(dest => dest.EnContent, opt => opt.MapFrom(m => m.TrackEnContent))
.ForMember(dest => dest.TrackTimeZoneValue, opt => opt.MapFrom(m => m.TrackTimeZone));
+ CreateMap(MemberList.None);
CreateMap(MemberList.None);
}
diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs
index 153e9700..1f32a4e3 100644
--- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs
+++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackChangeAfterUpdateOrderEventHandler.cs
@@ -26,6 +26,8 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
return;
}
+ //指示是否需要更新【预计签收时间】【签收地时区】
+ var isNeedUpdate = false;
var updateOrders = new List();
foreach (var order in orders)
{
@@ -55,20 +57,43 @@ public class TrackChangeAfterUpdateOrderEventHandler : ITransientDependency, ICa
order.LatestTrackPlace = @event.TrackPlace;
order.LatestTrackTime = @event.TrackTime;
order.LatestTrackTimeZone = @event.TrackTimeZone;
+ //当【预计签收时间】【签收地时区】同时存在时则更新主表
+ if (@event.EstimatedDeliveryDate.HasValue && @event.DestinationTimeZone.HasValue)
+ {
+ order.EstimatedDeliveryDate = @event.EstimatedDeliveryDate.Value;
+ order.DestinationTimeZone = @event.DestinationTimeZone.Value;
+ isNeedUpdate = true;
+ }
+
updateOrders.Add(order);
}
await _orderRepository.UpdateRangeAsync(updateOrders,
- x => new
- {
- x.IsCompleted,
- x.LatestTrackContent,
- x.LatestTrackEnContent,
- x.LatestTrackPlace,
- x.LatestTrackTime,
- x.LatestTrackTimeZone,
- x.DeficiencyTag
- });
+ isNeedUpdate
+ ? x => new
+ {
+ x.IsCompleted,
+ x.LatestTrackContent,
+ x.LatestTrackEnContent,
+ x.LatestTrackPlace,
+ x.LatestTrackTime,
+ x.LatestTrackTimeZone,
+ x.DeficiencyTag,
+ //当标识指示需要更新时添加更新列
+ x.EstimatedDeliveryDate,
+ x.DestinationTimeZone
+ }
+ : x => new
+ {
+ x.IsCompleted,
+ x.LatestTrackContent,
+ x.LatestTrackEnContent,
+ x.LatestTrackPlace,
+ x.LatestTrackTime,
+ x.LatestTrackTimeZone,
+ x.DeficiencyTag,
+ }
+ );
}
private async Task> GetOrdersAsync(int[] orderIds)
diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs
index 127305ac..436e55dd 100644
--- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs
+++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackDeleteEventHandler.cs
@@ -1,9 +1,14 @@
+using System.Text;
+using BSI.Stack.Rabbit;
using DotNetCore.CAP;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
+using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
+using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
+using SJZY.Track.Domain.Enums;
using SJZY.Track.Domain.Queries;
using Volo.Abp.DependencyInjection;
@@ -13,17 +18,29 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
{
private readonly ICapPublisher _capPublisher;
private readonly IOrderRepository _orderRepository;
+ private readonly ITrackStatusRepository _trackStatusRepository;
+ private readonly ITrackContentRepository _trackContentRepository;
private readonly IProvideQueries _provideQueries;
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
+ private readonly RabbitClientBus _rabbitClientBus;
+ private readonly IOrderOperationRecordEsRepository _orderOperationRecordEsRepository;
public TrackDeleteEventHandler(IProvideQueries provideQueries,
IOrderRepository orderRepository, ICapPublisher capPublisher,
- ITrackDetailsEsRepository trackDetailsEsRepository)
+ ITrackDetailsEsRepository trackDetailsEsRepository,
+ RabbitClientBus rabbitClientBus,
+ ITrackStatusRepository trackStatusRepository,
+ ITrackContentRepository trackContentRepository,
+ IOrderOperationRecordEsRepository orderOperationRecordEsRepository)
{
_provideQueries = provideQueries;
_orderRepository = orderRepository;
_capPublisher = capPublisher;
_trackDetailsEsRepository = trackDetailsEsRepository;
+ _rabbitClientBus = rabbitClientBus;
+ _trackStatusRepository = trackStatusRepository;
+ _trackContentRepository = trackContentRepository;
+ _orderOperationRecordEsRepository = orderOperationRecordEsRepository;
}
[CapSubscribe(GlobalConst.TrackDeleteSubscribe, Group = GlobalConst.TrackDeleteSubscribe)]
@@ -31,7 +48,10 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
{
if (!CanDelete(@event)) return;
- await DeleteTrackAsync(@event);
+ var trackList = await DeleteTrackAsync(@event);
+
+ //发布事件
+ await PublicTrackTopicAsync(@event, trackList);
// 根据订单关联关系异步向下刷(异步)
await DownByOrderLink(@event);
@@ -84,12 +104,8 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
private bool CanDelete(TrackDeleteEvent @event)
{
- // 系统创建的轨迹不允许删除
- if (@event.Visited.IsNullOrEmpty() && @event.OperationMan == GlobalConst.SystemUser)
- {
- LogHelper.Warn($"系统创建的轨迹不允许被删除:{@event}", true);
- return false;
- }
+ if (@event.OrderIds == null)
+ return true;
// 订单循环关联检测
var dup = @event.Visited.Intersect(@event.OrderIds).ToArray();
@@ -102,14 +118,80 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
return true;
}
- private async Task DeleteTrackAsync(TrackDeleteEvent @event)
+ private async Task PublicTrackTopicAsync(TrackDeleteEvent eto, List trackList)
{
- // 删除轨迹(删的是同子系统下的单,所以code是统一的)
- var tracks = await _trackDetailsEsRepository.GetLatestListAsync(@event.OrderIds, @event.TrackCodes);
+ if (trackList == null)
+ return;
- var orderIds = await _trackDetailsEsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes);
+ var statusList = await _trackStatusRepository.GetListAsync(m => m.SubSystemId == eto.SubSystemId);
+ if (statusList == null)
+ return;
+
+ var contentList = await _trackContentRepository.GetTrackContentBySyetemIdAsync(eto.SubSystemId);
+ if (contentList == null)
+ return;
+
+ foreach (var dataItem in trackList.GroupBy(m => new
+ {
+ m.TrackCode,
+ m.OrderNo
+ }))
+ {
+ var item = dataItem.First();
+ var status = statusList.FirstOrDefault(m => m.Code == item.TrackStatusCode);
+ if (status == null || !status.IsToMq)
+ continue;
+
+ var content = contentList.FirstOrDefault(m => m.TrackContentCode == item.TrackCode);
+
+ var data = new TrackChangeEto()
+ {
+ OrderIdentifiers = dataItem.Select(m => new OrderIdentifier
+ {
+ OrderId = m.OrderId,
+ OrderNo = m.OrderNo,
+ OrderType = m.OrderType
+ }).ToArray(),
+ TrackStatusCode = item.TrackStatusCode,
+ TrackCode = item.TrackCode,
+ OperationMan = eto.OperationMan,
+ SubSystemId = eto.SubSystemId,
+ Option = 2
+ };
+
+ _rabbitClientBus.Publish(GlobalConst.TrackChangeExchange, $"TrackChange.{content.SubSystemCode}", Encoding.UTF8.GetBytes(data.ToJson()));
+ }
+ }
+
+ private async Task> DeleteTrackAsync(TrackDeleteEvent @event)
+ {
+ List orderIds;
+ List tracks;
+ if (@event.EsIds != null && @event.EsIds.Any()) //根据明确的esid进行删除
+ {
+ tracks = await _trackDetailsEsRepository.GetDataByIds(@event.EsIds);
+ orderIds = tracks.Select(m => m.OrderId).Distinct().ToList();
+ @event.OrderIds = orderIds.ToArray();
+
+ // 外部api获取的轨迹不允许删除
+ if (tracks.Any(m => m.Source == TrackSourceEnum.ExternalServiceProvide.GetHashCode()))
+ return tracks;
+
+ // 删除轨迹
+ foreach (var item in tracks)
+ {
+ await _trackDetailsEsRepository.DeleteTrackByIdAsync(item.Id, item.IndexName);
+ }
+ }
+ else //原有逻辑,根据轨迹code和订单进行删除
+ {
+ // 删除轨迹(删的是同子系统下的单,所以code是统一的)
+ tracks = await _trackDetailsEsRepository.GetLatestListAsync(@event.OrderIds, @event.TrackCodes);
+
+ orderIds = await _trackDetailsEsRepository.DeleteTrackAsync(@event.OrderIds, @event.TrackCodes);
+ if (orderIds.Count == 0) return tracks;
+ }
- if (orderIds.Count == 0) return;
var orders = await _orderRepository.GetListAsync(x => orderIds.Contains(x.Id),
x => new OrderEntity
@@ -121,8 +203,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
LatestTrackTime = x.LatestTrackTime,
LatestTrackTimeZone = x.LatestTrackTimeZone,
});
-
- if (orders.Count == 0) return;
+ if (orders.Count == 0) return tracks;
foreach (var order in orders)
{
@@ -146,6 +227,19 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
order.LatestTrackTime = track.TrackTime;
order.LatestTrackTimeZone = track.TrackTimeZone;
}
+
+
+ // 写入操作日志
+ _ = _orderOperationRecordEsRepository.AddAsync(new OrderOperationRecordIndex
+ {
+ OrderId = order.Id,
+ OrderNo = order.OrderNo,
+ OptionType = OrderOperationType.删除轨迹.ToString(),
+ Content = tracks?.Where(m=>m.OrderId == order.Id)?.ToList().ToJson(),
+ CreateUserId = @event.OperationManId,
+ CreateUserName = @event.OperationMan ?? "",
+ CreateTime = DateTime.Now
+ });
}
await _orderRepository.UpdateRangeAsync(orders,
@@ -157,5 +251,7 @@ public class TrackDeleteEventHandler : ITransientDependency, ICapSubscribe
x.LatestTrackTime,
x.LatestTrackTimeZone
});
+
+ return tracks;
}
}
diff --git a/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs
index f30f51fc..c807dab6 100644
--- a/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs
+++ b/src/SJZY.Track.Application/CAP/EventHandlers/TrackUpsertEventHandler.cs
@@ -1,10 +1,14 @@
+using System.Text;
+using BSI.Stack.Rabbit;
using DotNetCore.CAP;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Track.Application.Contract.Events;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
+using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
using SJZY.Track.Domain.Dtos.TrackContents;
+using SJZY.Track.Domain.Enums;
using SJZY.Track.Domain.Queries;
using Volo.Abp.DependencyInjection;
using OrderIdentifier = SJZY.Track.Application.Contract.Events.OrderIdentifier;
@@ -17,14 +21,23 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
private readonly IOrderRepository _orderRepository;
private readonly IProvideQueries _provideQueries;
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
+ private readonly RabbitClientBus _rabbitClientBus;
+ private readonly IOrderOperationRecordEsRepository _orderOperationRecordEsRepository;
- public TrackUpsertEventHandler(IOrderRepository orderRepository, ICapPublisher capPublisher,
- IProvideQueries provideQueries, ITrackDetailsEsRepository trackDetailsEsRepository)
+ public TrackUpsertEventHandler(
+ IOrderRepository orderRepository,
+ ICapPublisher capPublisher,
+ IProvideQueries provideQueries,
+ ITrackDetailsEsRepository trackDetailsEsRepository,
+ RabbitClientBus rabbitClientBus,
+ IOrderOperationRecordEsRepository orderOperationRecordEsRepository)
{
_orderRepository = orderRepository;
_capPublisher = capPublisher;
_provideQueries = provideQueries;
_trackDetailsEsRepository = trackDetailsEsRepository;
+ _rabbitClientBus = rabbitClientBus;
+ _orderOperationRecordEsRepository = orderOperationRecordEsRepository;
}
[CapSubscribe(GlobalConst.TrackUpsertSubscribe, Group = GlobalConst.TrackUpsertSubscribe)]
@@ -34,13 +47,63 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
if (!CanDelete(@event)) return;
var canNextOrderIds = new List();
- await HandleTrackAsync(@event, canNextOrderIds);
+
+ var content = await HandleTrackAsync(@event, canNextOrderIds);
+
+ // 处理广播事件
+ PublicTrackTopic(@event, content);
if (canNextOrderIds.Count == 0) return;
// 根据订单关联关系异步向下刷(异步)
await DownByOrderLink(@event, canNextOrderIds);
}
+ ///
+ /// 发送轨迹广播
+ ///
+ ///
+ ///
+ private void PublicTrackTopic(TrackUpsertEvent eto, TrackContentVO? content)
+ {
+ // var trackStatus = await _trackStatusRepository.GetFirstAsync(m => m.Code == content.TrackStatusCode);
+ if (content == null || !content.IsToMq)
+ return;
+
+ var data = new TrackChangeEto()
+ {
+ EstimatedDeliveryDate = eto.EstimatedDeliveryDate,
+ TrackPlacePostcode = eto.TrackPlacePostcode,
+ TrackPlaceNation = eto.TrackPlaceNation,
+ TrackPlaceNationId = eto.TrackPlaceNationId,
+ TrackPlaceProvince = eto.TrackPlaceProvince,
+ TrackPlaceProvinceId = eto.TrackPlaceProvinceId,
+ TrackPlaceCity = eto.TrackPlaceCity,
+ TrackPlaceCityId = eto.TrackPlaceCityId,
+ Files = eto.Files,
+ Remarks = eto.Remarks,
+ Source = eto.Source,
+ IsVisibility = eto.IsVisibility,
+ TrackTimeZone = eto.TrackTimeZone,
+ TrackTime = eto.TrackTime,
+ TrackPlace = eto.TrackPlace,
+ TrackStatusCode = content.TrackStatusCode,
+ EnStatus = eto.EnStatus,
+ Content = eto.Content,
+ TrackCode = eto.TrackCode,
+ OperationMan = eto.OperationMan,
+ OrderIdentifiers = eto.OrderIdentifiers,
+ CustomId = eto.CustomId,
+ SubSystemId = eto.SubSystemId
+ };
+
+ if (eto.IsAdd)
+ data.Option = 1;
+ else
+ data.Option = 3;
+
+ _rabbitClientBus.Publish(GlobalConst.TrackChangeExchange, $"TrackChange.{content.SubSystemCode}", Encoding.UTF8.GetBytes(data.ToJson()));
+ }
+
private async Task DownByOrderLink(TrackUpsertEvent @event, List canNextOrderIds)
{
// 根据订单关联关系异步向下刷(异步)
@@ -125,7 +188,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
return true;
}
- private async Task HandleTrackAsync(TrackUpsertEvent @event, List canNextOrderIds)
+ private async Task HandleTrackAsync(TrackUpsertEvent @event, List canNextOrderIds)
{
var trackContent = await _provideQueries.GetTrackContentAsync(@event.SubSystemId, @event.TrackCode);
@@ -133,12 +196,20 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
{
// 找不到轨迹内容,直接结束
LogHelper.Warn($"找不到轨迹内容:{@event}", true);
- return;
+ return default;
}
+ //虽然在引发事件之前做了判断,引发之后并不一定立即处理,在此过程中轨迹内容仍然可能被修改,所以要二次进行判断。
+ //通过来源指示是否为手动操作
+ var manualOperation = @event.Source == (int) TrackSourceEnum.Artificial;
+ //轨迹内容标识不允许手动创建的
+ if (manualOperation && @event.IsAdd && trackContent.IsAllowManuallyCreate == false) return trackContent;
+ //轨迹内容标识不允许手动更新的
+ if (manualOperation && !@event.IsAdd && trackContent.IsAllowManuallyUpdate == false) return trackContent;
+
var insertTracks = await UpsertTrackAsync(@event, canNextOrderIds, trackContent);
- if (canNextOrderIds.Count == 0) return;
+ if (canNextOrderIds.Count == 0) return trackContent;
if (insertTracks.Any())
{
@@ -171,6 +242,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
TrackPlace = @event.TrackPlace,
TrackTime = @event.TrackTime,
TrackTimeZone = @event.TrackTimeZone,
+ DestinationTimeZone = @event.DestinationTimeZone,
+ EstimatedDeliveryDate = @event.EstimatedDeliveryDate
});
// 触发轨迹推送事件(异步)
@@ -192,6 +265,8 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
}
};
await _capPublisher.PublishAsync(GlobalConst.TrackPushSubscribe, trackPushEvent);
+
+ return trackContent;
}
private async Task> UpsertTrackAsync(TrackUpsertEvent @event, List canNextOrderIds,
@@ -210,6 +285,7 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
TrackDetailsIndex? track;
if (!@event.IsAdd)
{
+ //同一订单同轨迹code如果有多条轨迹明细则不允许修改
var existTracks = tracks.Where(x => x.OrderId == order.OrderId).ToArray();
if (existTracks.Length > 1)
{
@@ -220,13 +296,44 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
track = existTracks.FirstOrDefault();
if (track == null) continue; // 不存在不让改
+
+ //来源与外部服务商不允许修改
+ if (track.Source == (int) TrackSourceEnum.ExternalServiceProvide) continue;
}
else
{
- track = tracks.FirstOrDefault(x =>
- x.OrderId == order.OrderId && x.TrackTime == @event.TrackTime && x.TrackPlace == @event.TrackPlace);
+ // 【批量新增】所有可能遇到的场景
+ // 标识:允许重复,不允许重复,零条,一条,多条;
+ // 场景A:允许重复,零条 => 新增
+ // 场景B:允许重复,一条 => 新增(约束受限新增,否则跳过新增)
+ // 场景C:允许重复,多条 => 新增(约束受限新增,否则跳过新增)
+ // 场景D:不允许重复,零条 => 新增
+ // 场景E:不允许重复,一条 => 跳过
+ // 场景F:不允许重复,(理想不会出现多条) => 跳过
+ var existTracks = tracks.Where(x => x.OrderId == order.OrderId).ToArray();
+ track = existTracks.FirstOrDefault();
- if (track != null) continue; // 存在不让创建
+ //覆盖场景:B,C
+ if (trackContent.IsRepeatable && existTracks.Length >= 1)
+ {
+ if (existTracks.Any(x => x.TrackPlace == @event.TrackPlace && x.TrackTime == @event.TrackTime))
+ {
+ //允许重复,出现【轨迹发生地】,【轨迹发生时间】的都重复,则不允许新增
+ continue;
+ }
+
+ // 设置null后面执行新增逻辑
+ track = null;
+ }
+
+ //不允许重复,并且记录大于等于一条,跳过
+ //覆盖场景:E,F
+ if (!trackContent.IsRepeatable && existTracks.Length >= 1)
+ {
+ continue;
+ }
+
+ //其余情况:A,D都为新增操作,无需检查数量,track为null执行新增操作
}
if (track == default)
@@ -246,15 +353,47 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
OriginTrackDataHash = @event.TrackRefreshData.OriginTrackDataHash ?? GlobalConst.EmptyString,
CreateUser = @event.OperationMan ?? GlobalConst.SystemUser,
CreateTime = DateTime.Now,
+ //来源轨迹内容,第一次新增的时候使用轨迹内容表提供的
TrackStatus = trackContent.TrackStatus,
+ TrackStatusCode = trackContent.TrackStatusCode,
TrackContent = trackContent.TrackContent,
- TrackEnContent = trackContent.TrackEnContent
+ TrackEnContent = trackContent.TrackEnContent,
+ //S06新增轨迹明细字段
+ IsVisibility = @event.IsVisibility,
+ Source = @event.Source,
+ Remarks = @event.Remarks ?? GlobalConst.EmptyString,
+ Files = @event.Files?.Select(x => new FileItem
+ {
+ OssKey = x.OssKey,
+ FileName = x.FileName
+ }).ToList(),
+ TrackPlaceCity = @event.TrackPlaceCity ?? GlobalConst.EmptyString,
+ TrackPlaceCityId = @event.TrackPlaceCityId ?? GlobalConst.NotExistId,
+ TrackPlaceProvince = @event.TrackPlaceProvince ?? GlobalConst.EmptyString,
+ TrackPlaceProvinceId = @event.TrackPlaceProvinceId ?? GlobalConst.NotExistId,
+ TrackPlaceNation = @event.TrackPlaceNation ?? GlobalConst.EmptyString,
+ TrackPlaceNationId = @event.TrackPlaceNationId ?? GlobalConst.NotExistId,
+ TrackPlacePostcode = @event.TrackPlacePostcode ?? GlobalConst.EmptyString,
+ DestinationTimeZone = @event.DestinationTimeZone,
+ EstimatedDeliveryDate = @event.EstimatedDeliveryDate,
};
track.ZeroTrackTime = Math.Abs(track.TrackTimeZone - GlobalConst.NoneTrackTimeZone) < 1
? track.TrackTime
: track.TrackTime.Subtract(TimeSpan.FromHours(track.TrackTimeZone));
insertTracks.Add(track);
+
+ // 写入操作日志
+ _ = _orderOperationRecordEsRepository.AddAsync(new OrderOperationRecordIndex
+ {
+ OrderId = order.OrderId,
+ OrderNo = order.OrderNo,
+ OptionType = OrderOperationType.创建轨迹.ToString(),
+ Content = track.ToJson(),
+ CreateUserId = @event.OperationManId,
+ CreateUserName = @event.OperationMan ?? "",
+ CreateTime = DateTime.Now
+ });
}
else
{
@@ -267,7 +406,40 @@ public class TrackUpsertEventHandler : ITransientDependency, ICapSubscribe
track.UpdateUser = @event.OperationMan ?? GlobalConst.SystemUser;
track.UpdateTime = DateTime.Now;
+ //允许二次修改,在修改了轨迹内容后进行修改轨迹操作,如果输入的轨迹内容则以输入为准
+ track.TrackContent = @event.Content ?? trackContent.TrackContent;
+ track.TrackEnContent = @event.EnStatus ?? trackContent.TrackEnContent;
+ //S06新增
+ track.IsVisibility = @event.IsVisibility;
+ track.Remarks = @event.Remarks ?? GlobalConst.EmptyString;
+ track.Files = @event.Files?.Select(x => new FileItem
+ {
+ OssKey = x.OssKey,
+ FileName = x.FileName
+ }).ToList();
+ track.TrackPlaceCity = @event.TrackPlaceCity ?? GlobalConst.EmptyString;
+ track.TrackPlaceCityId = @event.TrackPlaceCityId ?? GlobalConst.NotExistId;
+ track.TrackPlaceProvince = @event.TrackPlaceProvince ?? GlobalConst.EmptyString;
+ track.TrackPlaceProvinceId = @event.TrackPlaceProvinceId ?? GlobalConst.NotExistId;
+ track.TrackPlaceNation = @event.TrackPlaceNation ?? GlobalConst.EmptyString;
+ track.TrackPlaceNationId = @event.TrackPlaceNationId ?? GlobalConst.NotExistId;
+ track.TrackPlacePostcode = @event.TrackPlacePostcode ?? GlobalConst.EmptyString;
+ track.DestinationTimeZone = @event.DestinationTimeZone;
+ track.EstimatedDeliveryDate = @event.EstimatedDeliveryDate;
+
updateTracks.Add(track);
+
+ // 写入操作日志
+ _ = _orderOperationRecordEsRepository.AddAsync(new OrderOperationRecordIndex
+ {
+ OrderId = order.OrderId,
+ OrderNo = order.OrderNo,
+ OptionType = OrderOperationType.修改轨迹.ToString(),
+ Content = track.ToJson(),
+ CreateUserId = @event.OperationManId,
+ CreateUserName = @event.OperationMan ?? "",
+ CreateTime = DateTime.Now
+ });
}
canNextOrderIds.Add(order.OrderId);
diff --git a/src/SJZY.Track.Application/SJZY.Track.Application.csproj b/src/SJZY.Track.Application/SJZY.Track.Application.csproj
index 926a7d69..0bcf26d3 100644
--- a/src/SJZY.Track.Application/SJZY.Track.Application.csproj
+++ b/src/SJZY.Track.Application/SJZY.Track.Application.csproj
@@ -10,6 +10,7 @@
+
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
index fd7f723e..dea72486 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/OrderService.cs
@@ -36,6 +36,15 @@ public partial class OrderService : ApplicationService, IOrderService
[HttpPost("Order/Upsert")]
public async Task> UpsertAsync(UpsertOrderInput input)
{
+ // 校验预计到达时间是否不是同时存在或同时不存在
+ if ((input.EstimatedDeliveryDate.HasValue && input.DestinationTimeZone.HasValue == false) ||
+ (input.EstimatedDeliveryDate.HasValue == false && input.DestinationTimeZone.HasValue))
+ {
+ throw new BusinessException(message: "【目的地时区】和【预计到达时间】必须同时输入");
+ }
+
+ var currentUser = CurrentUserRequest.CurrentUser;
+
// 校验订单是否已存在,存在则更新
var order = await _orderRepository.GetFirstAsync(x =>
x.SubSystemId == input.SubSystemId && x.OrderType == input.OrderType && x.OrderNo == input.OrderNo);
@@ -48,8 +57,10 @@ public partial class OrderService : ApplicationService, IOrderService
{
OrderId = order.Id,
OrderNo = input.OrderNo,
- OptionType = OptionType.修改.ToString(),
+ OptionType = OrderOperationType.修改订单.ToString(),
Content = input.ToJson(),
+ CreateUserId = currentUser.UserId,
+ CreateUserName = currentUser.Name,
};
_ = _orderOperationRecordEsRepository.AddAsync(index);
@@ -64,6 +75,7 @@ public partial class OrderService : ApplicationService, IOrderService
order.SubSystemId = input.SubSystemId;
order.OrderFlights = ObjectMapper.Map, List>(input.FlightInfos);
order.OrderPullStatus = BuiltOrderPullStatus(input.PullConfigInfos);
+ order.OrderPlatformNumbers = BuiltOrderPlatformNumbers(input.PullConfigInfos);
var orderId = await _orderRepository.CreateOrderAsync(order);
@@ -72,9 +84,10 @@ public partial class OrderService : ApplicationService, IOrderService
{
OrderId = orderId,
OrderNo = input.OrderNo,
- OptionType = OptionType.新增.ToString(),
+ OptionType = OrderOperationType.创建订单.ToString(),
Content = input.ToJson(),
- CreateUserId = CurrentUserRequest.CurrentUser.UserId,
+ CreateUserId = currentUser.UserId,
+ CreateUserName = currentUser.Name,
CreateTime = DateTime.Now
};
_ = _orderOperationRecordEsRepository.AddAsync(indexForAdd);
@@ -115,6 +128,8 @@ public partial class OrderService : ApplicationService, IOrderService
{
order = ObjectMapper.Map(input, order);
order.OrderFlights = ObjectMapper.Map, List>(input.FlightInfos);
+ order.OrderPullStatus = BuiltOrderPullStatus(input.PullConfigInfos);
+ order.OrderPlatformNumbers = BuiltOrderPlatformNumbers(input.PullConfigInfos);
await _orderRepository.UpdateOrderAsync(order);
}
@@ -128,6 +143,7 @@ public partial class OrderService : ApplicationService, IOrderService
var status = new OrderPullStatusEntity
{
ServiceProviderCode = x.ServiceCode,
+ OrderNo = x.OrderNo,
PullStatus = TrackPullStatus.Init,
StartTrackCode = x.StartCode ?? GlobalConst.EmptyString,
EndTrackCode = x.EndCode ?? GlobalConst.EmptyString,
@@ -147,4 +163,22 @@ public partial class OrderService : ApplicationService, IOrderService
return status;
}).ToList();
}
+
+ private List BuiltOrderPlatformNumbers(List? pullConfigInfos)
+ {
+ if (pullConfigInfos == null) return new List();
+
+ return pullConfigInfos.Select(x =>
+ {
+ var status = new OrderPlatformNumberEntity
+ {
+ //三方单号
+ OrderNumber = x.OrderNo,
+ //三方平台名称,目前认为是服务商code
+ Platform = x.ServiceCode,
+ };
+
+ return status;
+ }).ToList();
+ }
}
diff --git a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
index 63fdd064..c9844221 100644
--- a/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
+++ b/src/SJZY.Track.Application/Services/ProvideServices/TrackService.cs
@@ -5,6 +5,7 @@ using SJZY.Track.Application.Contract.Services.ProvideServices;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
+using SJZY.Track.Domain.Enums;
using SJZY.UserCenter.HttpApi.Services;
using Volo.Abp.Http.Client.DynamicProxying;
@@ -59,6 +60,47 @@ public partial class TrackService : ApplicationService, ITrackService
throw new BusinessException(message: "轨迹时间不合法");
}
+ if ((input.EstimatedDeliveryDate.HasValue == false && input.DestinationTimeZone.HasValue) ||
+ (input.EstimatedDeliveryDate.HasValue && input.DestinationTimeZone.HasValue == false))
+ {
+ throw new BusinessException(message: "【目的地时区】和【预计到达时间】必须同时输入");
+ }
+
+ //当修改时,如果为来源为外部提供商则不允许修改
+ if (!input.IsAdd && input.Source == (int) TrackSourceEnum.ExternalServiceProvide)
+ {
+ throw new BusinessException(message: "来源为外部服务商轨迹不允许修改");
+ }
+
+ var trackContent = await _trackContentRepository.GetByCodeAsync(input.SubSystemId, input.TrackCode);
+ if (trackContent == default)
+ {
+ throw new BusinessException(message: $"轨迹代码:{input.TrackCode}轨迹内容不存在");
+ }
+
+ //指示是否为手动操作
+ var manualOperation = input.Source == (int) TrackSourceEnum.Artificial;
+
+ //不允许手动创建
+ if (manualOperation && input.IsAdd && !trackContent.IsAllowManuallyCreate)
+ {
+ throw new BusinessException(message: $"轨迹代码:{input.TrackCode}不允许手动创建");
+ }
+
+ //不允许手动更新
+ if (manualOperation && !input.IsAdd && !trackContent.IsAllowManuallyUpdate)
+ {
+ throw new BusinessException(message: $"轨迹代码:{input.TrackCode}不允许手动更新");
+ }
+
+ var tracks = await _trackDetailsEsRepository.GetListAsync(new[] { order.Id }, input.TrackCode, true);
+
+ //更新轨迹,但存在多条轨迹记录,理由:不清晰到底要修改哪一条或是全部修改
+ if (!input.IsAdd && tracks.Count > 1)
+ {
+ throw new BusinessException(message: $"订单:{input.OrderNo},轨迹代码:{input.TrackCode}存在多条记录,不允许修改");
+ }
+
var userInfo = await _requestCurrentUserService.Service.GetCurrentUserBasicInfoAsync();
if (userInfo.Code != GlobalConst.SuccessCode || userInfo.Data is null)
{
@@ -112,6 +154,14 @@ public partial class TrackService : ApplicationService, ITrackService
var name = userInfo.Data.UserName;
+ //删除轨迹约束,只要其中有一条来源是外部的就立即返回错误
+ var tracks = await _trackDetailsEsRepository
+ .GetListAsync(new[] { orderId }, input.TrackCodes, TrackSourceEnum.ExternalServiceProvide);
+ if (tracks.Count > 0)
+ {
+ throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除");
+ }
+
// 删除轨迹
var @event = new TrackDeleteEvent
{
@@ -125,6 +175,48 @@ public partial class TrackService : ApplicationService, ITrackService
return new UnifyResultDto(true, true);
}
+ ///
+ /// 根据esid删除轨迹内容
+ ///
+ ///
+ ///
+ [HttpPost("Track/BatchDeleteByEsId")]
+ public async Task BatchDeleteTrackByEsIdAsync(BatchDeleteTrackByEsIdInput input)
+ {
+ var tracks = await _trackDetailsEsRepository.GetDataByIds(input.TrackContentEsIds.ToArray());
+ if (tracks == null || tracks.Count == 0)
+ return new UnifyResultDto(false, "未找到指定id下的轨迹内容");
+
+ if (tracks.Any(m => m.Source == TrackSourceEnum.ExternalServiceProvide.GetHashCode()))
+ return new UnifyResultDto(false, "存在来源于外部服务商的轨迹,不允许删除");
+
+ if (tracks.GroupBy(m => m.SubSystemId).Count() > 1)
+ return new UnifyResultDto(false, "暂不支持跨子系统批量删除");
+
+ // 获取用户name
+ var userInfo = await _requestCurrentUserService.Service.GetCurrentUserBasicInfoAsync();
+ if (userInfo.Code != GlobalConst.SuccessCode || userInfo.Data is null)
+ {
+ throw new BusinessException(message: $"调用用户中心,获取用户信息失败:{userInfo.Msg}");
+ }
+
+ // 删除轨迹
+ var currentUser = CurrentUserRequest.CurrentUser;
+ var userName = userInfo.Data.UserName;
+ if (string.IsNullOrEmpty(userName))
+ userName = (await _orderRepository.GetUserById(currentUser.UserId))?.Name;
+
+ var @event = new TrackDeleteEvent
+ {
+ EsIds = input.TrackContentEsIds.ToArray(),
+ SubSystemId = tracks.First().SubSystemId,
+ OperationMan = userName,
+ OperationManId = currentUser.UserId
+ };
+ await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, @event);
+
+ return new UnifyResultDto(true);
+ }
///
/// 批量删除轨迹
@@ -153,13 +245,21 @@ public partial class TrackService : ApplicationService, ITrackService
throw new BusinessException(message: $"调用用户中心,获取用户信息失败:{userInfo.Msg}");
}
+ //删除轨迹约束,只要其中有一条来源是外部的就立即返回错误
+ var tracks = await _trackDetailsEsRepository
+ .GetListAsync(orderIds.ToArray(), input.TrackCodes, TrackSourceEnum.ExternalServiceProvide);
+ if (tracks.Count > 0)
+ {
+ throw new BusinessException(message: "存在来源于外部服务商的轨迹,不允许删除");
+ }
+
// 删除轨迹
var @event = new TrackDeleteEvent
{
OrderIds = orderIds.ToArray(),
TrackCodes = input.TrackCodes,
SubSystemId = input.SubSystemId,
- OperationMan = userInfo.Data.UserName
+ OperationMan = userInfo.Data.UserName,
};
await _capPublisher.PublishAsync(GlobalConst.TrackDeleteSubscribe, @event);
@@ -191,6 +291,57 @@ public partial class TrackService : ApplicationService, ITrackService
throw new BusinessException(message: "订单一个都不存在");
}
+ //当修改时,如果为来源为外部提供商则不允许修改
+ if (!input.IsAdd && input.Source == (int) TrackSourceEnum.ExternalServiceProvide)
+ {
+ throw new BusinessException(message: "来源为外部服务商轨迹不允许修改");
+ }
+
+ // 校验主体:批量新增只选取第一条订单进行校验
+ //【新增】存在指定轨迹的内容,进行更新覆盖(只处理一条的情况,并且决定权交给用户),不存在直接插入即可
+ //【更新】存在指定轨迹的内容(匹配到多条则不处理)
+ var order = orders.First();
+
+ if (input.TrackTime < DateTime.Now.AddYears(-100) || input.TrackTime > DateTime.Now.AddYears(100))
+ {
+ throw new BusinessException(message: "轨迹时间不合法");
+ }
+
+ if ((input.EstimatedDeliveryDate.HasValue == false && input.DestinationTimeZone.HasValue) ||
+ (input.EstimatedDeliveryDate.HasValue && input.DestinationTimeZone.HasValue == false))
+ {
+ throw new BusinessException(message: "【目的地时区】和【预计到达时间】必须同时输入");
+ }
+
+ var trackContent = await _trackContentRepository.GetByCodeAsync(input.SubSystemId, input.TrackCode);
+ if (trackContent == default)
+ {
+ throw new BusinessException(message: $"轨迹代码:{input.TrackCode}轨迹内容不存在");
+ }
+
+ //指示是否为手动操作
+ var manualOperation = input.Source == (int) TrackSourceEnum.Artificial;
+
+ //不允许手动创建
+ if (manualOperation && input.IsAdd && !trackContent.IsAllowManuallyCreate)
+ {
+ throw new BusinessException(message: $"轨迹代码:{input.TrackCode}不允许手动创建");
+ }
+
+ //不允许手动更新
+ if (manualOperation && !input.IsAdd && !trackContent.IsAllowManuallyUpdate)
+ {
+ throw new BusinessException(message: $"轨迹代码:{input.TrackCode}不允许手动更新");
+ }
+
+ var tracks = await _trackDetailsEsRepository.GetListAsync(new[] { order.Id }, input.TrackCode, true);
+
+ //更新轨迹,存在多条轨迹记录不允许更改,理由:不清晰到底要修改哪一条或是全部修改
+ if (!input.IsAdd && tracks.Count > 1)
+ {
+ throw new BusinessException(message: $"订单:{order.OrderNo},轨迹代码:{input.TrackCode}存在多条记录,不允许修改");
+ }
+
// 获取用户name
var userInfo = await _requestCurrentUserService.Service.GetCurrentUserBasicInfoAsync();
if (userInfo.Code != GlobalConst.SuccessCode || userInfo.Data is null)
@@ -216,7 +367,23 @@ public partial class TrackService : ApplicationService, ITrackService
TrackPlace = input.TrackPlace,
TrackTime = input.TrackTime,
TrackTimeZone = input.TrackTimeZone,
- OperationMan = userInfo.Data.UserName
+ OperationMan = userInfo.Data.UserName,
+ OperationManId = userInfo.Data.UserId,
+ IsVisibility = input.IsVisibility,
+ Source = input.Source,
+ Remarks = input.Remarks,
+ Files = input.Files,
+ Content = input.Content,
+ EnStatus = input.EnStatus,
+ TrackPlaceCity = input.TrackPlaceCity,
+ TrackPlaceCityId = input.TrackPlaceCityId,
+ TrackPlaceProvince = input.TrackPlaceProvince,
+ TrackPlaceProvinceId = input.TrackPlaceProvinceId,
+ TrackPlaceNation = input.TrackPlaceNation,
+ TrackPlaceNationId = input.TrackPlaceNationId,
+ TrackPlacePostcode = input.TrackPlacePostcode,
+ EstimatedDeliveryDate = input.EstimatedDeliveryDate,
+ DestinationTimeZone = input.DestinationTimeZone,
};
await _capPublisher.PublishAsync(GlobalConst.TrackUpsertSubscribe, @event);
}
diff --git a/src/SJZY.Track.Application/Services/TrackContents/TrackContentService.cs b/src/SJZY.Track.Application/Services/TrackContents/TrackContentService.cs
index faf3f428..8cb91e48 100644
--- a/src/SJZY.Track.Application/Services/TrackContents/TrackContentService.cs
+++ b/src/SJZY.Track.Application/Services/TrackContents/TrackContentService.cs
@@ -2,9 +2,12 @@ using System.Linq.Expressions;
using Microsoft.Extensions.Localization;
using SJZY.Expand.ABP.Core.Localization;
using SJZY.Expand.ABP.Core.PublicMethords;
+using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Dtos.TrackContents;
using SJZY.Track.Application.Localization;
+using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
+using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Aggregates.TrackFlagAggregate;
using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
using SJZY.Track.Domain.Dtos.TrackContents;
@@ -23,17 +26,23 @@ public class TrackContentService : ApplicationService
private readonly ITrackContentRepository _trackContentRepository;
private readonly IBasicQuery _trackFlagBasicQuery;
private readonly IBasicQuery _trackStatusBasicQuery;
+ private readonly IOrderRepository _orderRepository;
+ private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
public TrackContentService(
IStringLocalizer stringLocalizer,
ITrackContentRepository trackContentRepository,
IBasicQuery trackStatusBasicQuery,
- IBasicQuery trackFlagBasicQuery)
+ IBasicQuery trackFlagBasicQuery,
+ IOrderRepository orderRepository,
+ ITrackDetailsEsRepository trackDetailsEsRepository)
{
_stringLocalizer = stringLocalizer;
_trackContentRepository = trackContentRepository;
_trackStatusBasicQuery = trackStatusBasicQuery;
_trackFlagBasicQuery = trackFlagBasicQuery;
+ _orderRepository = orderRepository;
+ _trackDetailsEsRepository = trackDetailsEsRepository;
}
///
@@ -96,8 +105,7 @@ public class TrackContentService : ApplicationService
///
///
[HttpPost("GetList")]
- public async Task> GetPageTrackContent(
- GetPageTrackContentInput input)
+ public async Task> GetPageTrackContent(GetPageTrackContentInput input)
{
var vo = ObjectMapper.Map(input);
var resultDto = await _trackContentRepository.GetPageTrackContent(vo);
@@ -181,6 +189,99 @@ public class TrackContentService : ApplicationService
return true;
}
+ ///
+ /// 根据轨迹内容code获取轨迹内容
+ ///
+ ///
+ ///
+ [HttpPost("GetTrackContentByCode")]
+ public async Task> GetTrackContentByCodeAsync([FromBody] GetTrackContentByCodeInput input)
+ {
+ if (input.SystemId <= 0)
+ return new UnifyResultDto(false, "子系统Id必须大于等于0");
+
+ if (string.IsNullOrEmpty(input.Code))
+ return new UnifyResultDto(false, "轨迹内容code不能为空");
+
+ var content = await _trackContentRepository.GetByCodeAsync(input.SystemId, input.Code);
+ if (content == null)
+ return new UnifyResultDto(false, "在当前子系统中未找到指定code的轨迹内容");
+
+ var res = new UnifyResultDto(true)
+ {
+ Data = new GetTrackContentByCodeOutput
+ {
+ Content = content.Content,
+ EnContent = content.EnContent,
+ IsExternal = content.IsExternal
+ }
+ };
+
+ return res;
+ }
+
+ ///
+ /// 创建轨迹时获取可用的轨迹内容
+ ///
+ ///
+ ///
+ [HttpPost("GetAvailableContent")]
+ public async Task>> GetAvailableContent(GetAvailableContentInput input)
+ {
+ if (input.SystemId <= 0)
+ return new UnifyResultDto>(false, "系统id需大于0!");
+
+ if (string.IsNullOrEmpty(input.OrderNo))
+ return new UnifyResultDto>(false, "单号不能为空!");
+
+ //获取当前订单下已有的轨迹内容
+ var orderId = await _orderRepository.GetFirstAsync(x => x.OrderNo == input.OrderNo && x.SubSystemId == input.SystemId, x => x.Id);
+ if (orderId == default)
+ throw new BusinessException(message: "订单不存在!");
+
+ //获取轨迹详情
+ var trackDetails = await _trackDetailsEsRepository.GetListAsync(orderId);
+
+ //获取当前子系统下所有的轨迹内容
+ var contentList = await _trackContentRepository.GetListBySystemIdAsync(input.SystemId);
+ if (contentList == null)
+ throw new BusinessException(message: "当前子系统下未找到任何可用的轨迹内容!");
+
+
+ var res = new UnifyResultDto>(true)
+ {
+ Data = new List()
+ };
+
+ foreach (var item in contentList)
+ {
+ //新增时跳过已存在轨迹内容
+ if (input.TrackOptionType == TrackOptionType.创建 && !item.IsRepeatable && trackDetails?.Any(m => m.TrackCode == item.Code) == true)
+ continue;
+
+ // 修改时跳过不存在轨迹内容
+ if (input.TrackOptionType == TrackOptionType.修改 && trackDetails != null && trackDetails.All(m => m.TrackCode != item.Code))
+ continue;
+
+ if (!item.IsAllowManuallyCreate && input.TrackOptionType == TrackOptionType.创建) //跳过不允许手动创建的轨迹内容
+ continue;
+
+ if (!item.IsAllowManuallyUpdate && input.TrackOptionType == TrackOptionType.修改) //跳过不允许手动创建的轨迹内容
+ continue;
+
+ res.Data.Add(new GetAvailableContentOutput()
+ {
+ IsExternal = item.IsExternal,
+ EnContent = item.EnContent,
+ Content = item.Content,
+ Code = item.Code,
+ Id = item.Id
+ });
+ }
+
+ return res;
+ }
+
#region 私有方法
private async Task AddAsync(EditTrackContentInput input)
diff --git a/src/SJZY.Track.Application/Services/TrackOrders/TrackOrderService.cs b/src/SJZY.Track.Application/Services/TrackOrders/TrackOrderService.cs
index 7c7950dd..af769700 100644
--- a/src/SJZY.Track.Application/Services/TrackOrders/TrackOrderService.cs
+++ b/src/SJZY.Track.Application/Services/TrackOrders/TrackOrderService.cs
@@ -1,9 +1,11 @@
+using SJZY.Expand.AliyunOSS;
using SJZY.Track.Application.Contract.Dtos.ProvideServices;
using SJZY.Track.Application.Contract.Dtos.TrackOrder;
using SJZY.Track.Domain.Aggregates.OrderAggregate;
using SJZY.Track.Domain.Aggregates.TrackContentAggregate;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Aggregates.TrackPushAggregate;
+using SJZY.Track.Domain.Aggregates.TrackStatusAggregate;
using SJZY.Track.Domain.Dtos.Order;
namespace SJZY.Track.Application.Services.TrackOrders;
@@ -18,6 +20,7 @@ public class TrackOrderService : ApplicationService
private readonly IOrderOperationRecordEsRepository _orderOperationRecordEsRepository;
private readonly IOrderRepository _orderRepository;
private readonly ITrackContentRepository _trackContentRepository;
+ private readonly ITrackStatusRepository _trackStatusRepository;
private readonly ITrackDetailsEsRepository _trackDetailsEsRepository;
private readonly ITrackPushRecordEsRepository _trackPushRecordEsRepository;
@@ -26,13 +29,15 @@ public class TrackOrderService : ApplicationService
ITrackDetailsEsRepository trackDetailsEsRepository,
ITrackContentRepository trackContentRepository,
ITrackPushRecordEsRepository trackPushRecordEsRepository,
- IOrderOperationRecordEsRepository orderOperationRecordEsRepository)
+ IOrderOperationRecordEsRepository orderOperationRecordEsRepository,
+ ITrackStatusRepository trackStatusRepository)
{
_orderRepository = orderRepository;
_trackDetailsEsRepository = trackDetailsEsRepository;
_trackContentRepository = trackContentRepository;
_trackPushRecordEsRepository = trackPushRecordEsRepository;
_orderOperationRecordEsRepository = orderOperationRecordEsRepository;
+ _trackStatusRepository = trackStatusRepository;
}
#region 轨迹订单列表
@@ -93,7 +98,7 @@ public class TrackOrderService : ApplicationService
int hours = (int) x.TrackTimeZone; // 提取整数部分作为小时
int minutes = (int) ((x.TrackTimeZone - hours) * 60); // 将小数部分乘以 60 转换为分钟
x.TrackGTMTimeZone =
- $"GTM {(x.TrackTimeZone >= 0 ? "+" : "-")}{new TimeSpan(hours, minutes, 0).ToString().RemovePostFix(":00")}";
+ $"GMT {(x.TrackTimeZone >= 0 ? "+" : "-")}{new TimeSpan(hours, minutes, 0).ToString().RemovePostFix(":00")}";
});
return res;
@@ -144,7 +149,7 @@ public class TrackOrderService : ApplicationService
{
if (a.TrackTimeZoneValue == 0f)
{
- a.TrackTimeZone = "GTM +00:00";
+ a.TrackTimeZone = "GMT +00:00";
}
else if (Math.Abs(a.TrackTimeZoneValue - GlobalConst.NoneTrackTimeZone) < 1)
{
@@ -158,12 +163,121 @@ public class TrackOrderService : ApplicationService
var offset = new TimeSpan(hours, minutes, 0);
var timeZoneStr = offset.ToString();
var flag = a.TrackTimeZoneValue > 0f ? "+" : "";
- a.TrackTimeZone = $"GTM {flag}{timeZoneStr.RemovePostFix(":00")}";
+ a.TrackTimeZone = $"GMT {flag}{timeZoneStr.RemovePostFix(":00")}";
}
});
return list;
}
+
+ ///
+ /// 按时间轴获取轨迹内容
+ ///
+ ///
+ ///
+ [HttpPost("GetDetailTimeline")]
+ public async Task>> GetDetailTimeline(GetDetailTimelineInput input)
+ {
+ var res = new UnifyResultDto>(true);
+
+ var order = await _orderRepository.GetFirstAsync(m => m.OrderNo == input.OrderNumber);
+ if (order == null)
+ return new UnifyResultDto>(false, "订单不存在");
+
+ if (input.SystemId <= 0)
+ return new UnifyResultDto>(false, "子系统id不合法");
+
+ if (input.CurrenUserSystemId <= 0)
+ return new UnifyResultDto>(false, "当前登陆用户子系统id不合法");
+
+ var system = await _orderRepository.GetSystemInfoById(input.CurrenUserSystemId);
+ if (system == null)
+ return new UnifyResultDto>(false, "未找到指定id的子系统");
+
+ var trackStatus = await _trackStatusRepository.GetListAsync(m => m.SubSystemId == input.SystemId);
+ if (trackStatus == null)
+ return new UnifyResultDto>(false, "未找到子系统下的任何轨迹状态");
+
+ var trackContent = await _trackContentRepository.GetListAsync(m => m.SubSystemId == input.SystemId);
+ if (trackContent == null)
+ return new UnifyResultDto>(false, "未找到子系统下的任何轨迹内容");
+
+ var trackDetails = await _trackDetailsEsRepository.GetListAsync(order.Id);
+ res.Data = new List();
+ var isCompleted = false;
+ foreach (var item in trackDetails)
+ {
+ var currentTrackStatus = trackStatus.FirstOrDefault(m => m.Code == item.TrackStatusCode);
+ var currentTrackContet = trackContent.FirstOrDefault(m => m.Code == item.TrackCode);
+
+ //是否完结
+ if (!isCompleted)
+ isCompleted = currentTrackStatus is { IsCompleted: true };
+
+ //如果是外部系统,且轨迹内容不对外则跳过这条轨迹内容
+ if (system.SystemProperty == 2 && currentTrackContet != null && !currentTrackContet.IsExternal)
+ continue;
+
+ res.Data.Add(new GetDetailTimelineOutput()
+ {
+ IsHighlight = true,
+ IsShowHover = true,
+ Remark = item.Remarks == null || item.Remarks == "--" ? "" : item.Remarks,
+ TrackTimeZone = $"GMT{(item.TrackTimeZone >= 0 ? "+" : "-")}{GetTimeZoneStr(item.TrackTimeZone)}",
+ TrackTime = ToUnixTimestamp(item.TrackTime),
+ TrackPlace = item.TrackPlace,
+ EnContent = item.TrackEnContent,
+ Files = item.Files == null
+ ? new List()
+ : item.Files!.Select(m => new TrackFileItem()
+ {
+ OssKey = m.OssKey,
+ FileName = m.FileName,
+ Url = m.OssKey.GetUrlByKey(),
+ }).ToList(),
+ Content = item.TrackContent,
+ TrackCode = item.TrackCode,
+ TrackPlaceNation = item.TrackPlaceNation,
+ TrackPlaceProvince = item.TrackPlaceProvince,
+ TrackPlaceCity = item.TrackPlaceCity,
+ });
+ }
+
+ //如果轨迹状态没完结则追加最后一个默认节点
+ if (!isCompleted)
+ {
+ res.Data.Add(new GetDetailTimelineOutput()
+ {
+ Content = "签收",
+ IsHighlight = false,
+ TrackTimeZone = order.EstimatedDeliveryDate.HasValue ? $"GMT{(order.DestinationTimeZone >= 0 ? "+" : "-")}{order.DestinationTimeZone}" : "",
+ TrackTime = order.EstimatedDeliveryDate.HasValue ? ToUnixTimestamp(DateTime.Parse(order.EstimatedDeliveryDate.ToString()!)) : 0,
+ TrackTimePrefix = order.EstimatedDeliveryDate.HasValue ? "预计签收时间:" : "",
+ });
+ }
+
+ return res;
+ }
+
+ public static long ToUnixTimestamp(DateTime time)
+ {
+ var sTime = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1), TimeZoneInfo.Utc, TimeZoneInfo.Local);
+ return (long) (time - sTime).TotalMilliseconds;
+ }
+
+ private string GetTimeZoneStr(float timeZone)
+ {
+ var time = timeZone.ToString().Split('.');
+ if (time.Length > 1 && time[1] != "0") //如果时区有小数点
+ {
+ return time[0] + ":30";
+ }
+ else
+ {
+ return time[0] + ":00";
+ }
+ }
+
///
/// 根据轨迹id删除单条轨迹
///
diff --git a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
index 9a8cc79b..e36b86ce 100644
--- a/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
+++ b/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
@@ -3,9 +3,11 @@ using DotNetCore.CAP;
using DotNetCore.CAP.Internal;
using Microsoft.Extensions.Configuration;
using RabbitMQ.Client;
+using Savorboard.CAP.InMemoryMessageQueue;
using SJZY.Expand.ABP.Core.Localization;
using SJZY.Expand.ABP.Core.Logger;
using SJZY.Expand.ABP.Core.PublicMethords;
+using SJZY.Expand.AliyunOSS;
using SJZY.InterfaceRelay.Application.Contracts;
using SJZY.Track.Application.CAP;
using SJZY.Track.Application.Contract;
@@ -49,10 +51,7 @@ public class SjzyTrackApplicationModule : AbpModule
});
//添加虚拟文件系统
- Configure(options =>
- {
- options.FileSets.AddEmbedded("SJZY.Track.Application");
- });
+ Configure(options => { options.FileSets.AddEmbedded("SJZY.Track.Application"); });
//添加多语言
var languageConfig = configuration.GetSection("Language");
@@ -81,45 +80,59 @@ public class SjzyTrackApplicationModule : AbpModule
//CAP
context.Services.AddSingleton();
context.Services.AddCapTableNameService();
- context.Services.AddCap(options =>
+ if (!System.Diagnostics.Debugger.IsAttached)
{
- options.UseMySql(configuration["ConnectionStrings:DefaultConnection"]!);
- options.UseRabbitMQ(configure =>
+ context.Services.AddCap(options =>
{
- configure.HostName = configuration["RabbitMQ:HostName"]!;
- configure.UserName = configuration["RabbitMQ:UserName"]!;
- configure.Password = configuration["RabbitMQ:Password"]!;
- configure.Port = configuration.GetValue("RabbitMQ:Port");
- configure.BasicQosOptions =
- new RabbitMQOptions.BasicQos(configuration.GetValue("CAP:PrefetchCount"));
- });
- options.FailedRetryInterval = configuration.GetValue("CAP:FailedRetryInterval");
- options.FailedRetryCount = configuration.GetValue("CAP:FailedRetryCount");
- options.SucceedMessageExpiredAfter = configuration.GetValue("CAP:SucceedMessageExpiredAfter");
- options.FallbackWindowLookbackSeconds =
- configuration.GetValue("CAP:FallbackWindowLookbackSeconds");
-
- options.UseDashboard(dashboardOptions =>
- {
- dashboardOptions.PathBase = System.Diagnostics.Debugger.IsAttached
- ? ""
- : configuration["Swagger:JsonUrlPrefix"]!;
- });
- options.FailedThresholdCallback = faileCalback =>
- {
- try
+ options.UseMySql(configuration["ConnectionStrings:DefaultConnection"]!);
+ options.UseRabbitMQ(configure =>
{
- LogHelper.Error($@"
+ configure.HostName = configuration["RabbitMQ:HostName"]!;
+ configure.UserName = configuration["RabbitMQ:UserName"]!;
+ configure.Password = configuration["RabbitMQ:Password"]!;
+ configure.Port = configuration.GetValue("RabbitMQ:Port");
+ configure.BasicQosOptions =
+ new RabbitMQOptions.BasicQos(configuration.GetValue("CAP:PrefetchCount"));
+ });
+ options.FailedRetryInterval = configuration.GetValue("CAP:FailedRetryInterval");
+ options.FailedRetryCount = configuration.GetValue("CAP:FailedRetryCount");
+ options.SucceedMessageExpiredAfter = configuration.GetValue("CAP:SucceedMessageExpiredAfter");
+ options.FallbackWindowLookbackSeconds =
+ configuration.GetValue("CAP:FallbackWindowLookbackSeconds");
+
+ options.UseDashboard(dashboardOptions =>
+ {
+ dashboardOptions.PathBase = System.Diagnostics.Debugger.IsAttached
+ ? ""
+ : configuration["Swagger:JsonUrlPrefix"]!;
+ });
+ options.FailedThresholdCallback = faileCalback =>
+ {
+ try
+ {
+ LogHelper.Error($@"
|-CAP失败回调事件:
|-处理类型:{(faileCalback.MessageType == DotNetCore.CAP.Messages.MessageType.Subscribe ? "消费消息达到最大重试次数,需要开发人员介入" : "生产消息推送失败")}
|-头部信息:{faileCalback.Message.Headers.ToJson()}");
- }
- catch (Exception ex)
- {
- LogHelper.Error("【严重】CAP失败回调事件发生未处理异常" + ex);
- }
- };
- }).AddSubscribeFilter();
+ }
+ catch (Exception ex)
+ {
+ LogHelper.Error("【严重】CAP失败回调事件发生未处理异常" + ex);
+ }
+ };
+ }).AddSubscribeFilter();
+ }
+ else
+ {
+ //是本地调试环境,用内存存储和内存队列
+ context.Services.AddCap(capOptions =>
+ {
+ capOptions.UseInMemoryStorage();
+ capOptions.UseInMemoryMessageQueue();
+ capOptions.UseDashboard();
+ }).AddSubscribeFilter();
+ Console.WriteLine("-- 当前为VS本地环境,用内存存储和内存队列");
+ }
context.Services.AddRabbitBoot(options =>
@@ -141,6 +154,17 @@ public class SjzyTrackApplicationModule : AbpModule
o.QueueBind(GlobalConst.TrackRefreshSubscribe, GlobalConst.InterfaceRelayExchange,
GlobalConst.TrackRefreshSubscribe);
}
+ },
+ new()
+ {
+ //广播轨迹
+ Queue = GlobalConst.TrackRefreshSubscribe,
+ FetchCount = configuration.GetValue("TrackApp:TrackRefreshFetchCount"),
+ FailedRequeue = false,
+ Declaration = o =>
+ {
+ o.ExchangeDeclare(GlobalConst.TrackChangeExchange, ExchangeType.Topic, true);
+ }
}
};
}, typeof(SjzyTrackApplicationModule).Assembly);
@@ -148,6 +172,16 @@ public class SjzyTrackApplicationModule : AbpModule
context.Services.Configure(configuration.GetSection("TrackApp"));
context.Services.Configure(
configuration.GetSection("InterfaceRelayParamsConfig"));
+
+ //注册阿里云OSS服务
+ context.Services.AddAliOSS(option =>
+ {
+ option.AccessKeyId = configuration["OSS:AccessKeyId"];
+ option.AccessKeySecret = configuration["OSS:AccessKeySecret"];
+ option.Endpoint = configuration["OSS:Endpoint"];
+ option.BucketName = configuration["OSS:BucketName"];
+ option.ReturnHttpsUrl = true;
+ });
}
public override void PreConfigureServices(ServiceConfigurationContext context)
diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs
index be928230..ae172fc0 100644
--- a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/IOrderRepository.cs
@@ -1,4 +1,5 @@
using SJZY.Track.Domain.Dtos.Order;
+using SJZY.Track.Domain.VEntities;
namespace SJZY.Track.Domain.Aggregates.OrderAggregate;
@@ -131,4 +132,18 @@ public interface IOrderRepository : IBasicRepository
Task UpdateOrderPullConfigForServiceProviderAsync(UpdateOrderPullConfigsInputVo inputVo);
#endregion
+
+ ///
+ /// 根据id获取子系统信息
+ ///
+ ///
+ ///
+ Task GetSystemInfoById(int id);
+
+ ///
+ /// 根据id获取员工姓名
+ ///
+ ///
+ ///
+ Task GetUserById(int id);
}
diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderEntity.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderEntity.cs
index 9a24699e..b2e3a5ba 100644
--- a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderEntity.cs
+++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderEntity.cs
@@ -168,10 +168,25 @@ public class OrderEntity : IFullAuditedBasicEntitys, IAggregateRoot
[SugarColumn(ColumnName = "ArrivalProvince")]
public string? ArrivalProvince { get; set; }
+ ///
+ /// 预计到达时间
+ ///
+ [SugarColumn(ColumnName = "EstimatedDeliveryDate")]
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 目的地时区
+ ///
+ [SugarColumn(ColumnName = "DestinationTimeZone")]
+ public float? DestinationTimeZone { get; set; }
+
[SugarColumn(IsIgnore = true)] public List OrderFlights { get; set; }
[SugarColumn(IsIgnore = true)] public List OrderPullStatus { get; set; }
+ [Navigate(NavigateType.OneToMany, nameof(OrderPlatformNumberEntity.OrderId))]
+ [SugarColumn(IsIgnore = true)] public List OrderPlatformNumbers { get; set; }
+
public void ResetTrackInfo()
{
IsCompleted = false;
diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderOperationRecordIndex.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderOperationRecordIndex.cs
index cedba47d..c53ed8c5 100644
--- a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderOperationRecordIndex.cs
+++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderOperationRecordIndex.cs
@@ -40,8 +40,22 @@ public class OrderOperationRecordIndex : IdBaseIndex
///
public int CreateUserId { get; set; }
+ ///
+ /// 创建人姓名
+ ///
+ public string CreateUserName { get; set; }
+
///
/// 创建时间
///
public DateTime CreateTime { get; set; }
}
+
+public enum OrderOperationType
+{
+ 创建订单 = 1,
+ 修改订单 = 2,
+ 创建轨迹 = 3,
+ 修改轨迹 = 4,
+ 删除轨迹 = 5
+}
diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderPlatformNumberEntity.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderPlatformNumberEntity.cs
new file mode 100644
index 00000000..b4ae68bf
--- /dev/null
+++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderPlatformNumberEntity.cs
@@ -0,0 +1,32 @@
+namespace SJZY.Track.Domain.Aggregates.OrderAggregate;
+
+///
+/// 外部单号关联表
+///
+[SugarTable("t_order_platform_number")]
+public class OrderPlatformNumberEntity : IFullAuditedBasicEntitys, IEntity
+{
+ ///
+ /// 自增主键
+ ///
+ [SugarColumn(ColumnName = "Id", IsPrimaryKey = true, IsIdentity = true)]
+ public int Id { get; set; }
+
+ ///
+ /// 订单id
+ ///
+ [SugarColumn(ColumnName = "OrderId")]
+ public int OrderId { get; set; }
+
+ ///
+ /// 外部单号
+ ///
+ [SugarColumn(ColumnName = "OrderNumber")]
+ public string? OrderNumber { get; set; }
+
+ ///
+ /// 平台名称
+ ///
+ [SugarColumn(ColumnName = "Platform")]
+ public string? Platform { get; set; }
+}
diff --git a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderTrackPullStatusEntity.cs b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderTrackPullStatusEntity.cs
index 29215b28..b4db417c 100644
--- a/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderTrackPullStatusEntity.cs
+++ b/src/SJZY.Track.Domain/Aggregates/OrderAggregate/OrderTrackPullStatusEntity.cs
@@ -18,6 +18,12 @@ public class OrderPullStatusEntity : ICreateBaicEntity, IUpdateBasicEntity, IEnt
[SugarColumn(ColumnName = "OrderId")]
public int OrderId { get; set; }
+ ///
+ /// api服务商订单号(第三方单号)
+ ///
+ [SugarColumn(ColumnName = "OrderNo")]
+ public string? OrderNo { get; set; }
+
///
/// 服务商code
///
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs
index 000dbe3b..fe3a81d7 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/ITrackContentRepository.cs
@@ -26,4 +26,7 @@ public interface ITrackContentRepository : IBasicRepository
Expression> whereExpression);
Task GetTemplateIsExist(int trackContentId);
+ Task GetByCodeAsync(int systemId, string code);
+ Task> GetListBySystemIdAsync(int systemId);
+ Task> GetTrackContentBySyetemIdAsync(int subSystemId);
}
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/TrackContentEntity.cs b/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/TrackContentEntity.cs
index ee797ce1..b6809891 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/TrackContentEntity.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackContentAggregate/TrackContentEntity.cs
@@ -36,6 +36,12 @@ public class TrackContentEntity : IFullAuditedBasicEntitys, IAggregateRoot
[SugarColumn(ColumnName = "SubSystemId")]
public int SubSystemId { get; set; }
+ ///
+ /// 子系统名称
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public string SubSystem { get; set; }
+
///
/// 轨迹标记id,多个逗号分隔
///
@@ -53,4 +59,22 @@ public class TrackContentEntity : IFullAuditedBasicEntitys, IAggregateRoot
///
[SugarColumn(ColumnName = "IsExternal")]
public bool IsExternal { get; set; }
+
+ ///
+ /// 是否可重复
+ ///
+ [SugarColumn(ColumnName = "IsRepeatable")]
+ public bool IsRepeatable { get; set; }
+
+ ///
+ /// 是否允许手动修改
+ ///
+ [SugarColumn(ColumnName = "IsAllowManuallyUpdate")]
+ public bool IsAllowManuallyUpdate { get; set; }
+
+ ///
+ /// 是否允许手动创建
+ ///
+ [SugarColumn(ColumnName = "IsAllowManuallyCreate")]
+ public bool IsAllowManuallyCreate { get; set; }
}
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/FileItem.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/FileItem.cs
new file mode 100644
index 00000000..2d2dc4a3
--- /dev/null
+++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/FileItem.cs
@@ -0,0 +1,14 @@
+namespace SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
+
+public class FileItem
+{
+ ///
+ /// 文件osskey
+ ///
+ public string OssKey { get; set; }
+
+ ///
+ /// 文件名称
+ ///
+ public string FileName { get; set; }
+}
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs
index b52f5f20..a8da5185 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/ITrackDetailsEsRepository.cs
@@ -1,4 +1,5 @@
using SJZY.Expand.ElasticSearch.Services;
+using SJZY.Track.Domain.Enums;
namespace SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
@@ -22,7 +23,10 @@ public interface ITrackDetailsEsRepository : IElasticsearchClientService> GetListAsync(int orderId);
+ Task> GetListAsync(int[] orderIds, List trackCodes, TrackSourceEnum source);
+
Task> DeleteTrackAsync(int[] orderIds, List trackCodes);
Task DeleteTrackByIdAsync(string id, string indexName);
+ Task> GetDataByIds(string[] ids);
}
diff --git a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs
index a89fb67e..c842786b 100644
--- a/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs
+++ b/src/SJZY.Track.Domain/Aggregates/TrackDetailsAggregate/TrackDetailsIndex.cs
@@ -37,6 +37,11 @@ public class TrackDetailsIndex : IdBaseIndex
///
public string TrackStatus { get; set; } = GlobalConst.EmptyString;
+ ///
+ /// 轨迹状态code
+ ///
+ public string TrackStatusCode { get; set; } = GlobalConst.EmptyString;
+
///
/// 轨迹内容代码
///
@@ -106,4 +111,69 @@ public class TrackDetailsIndex : IdBaseIndex
/// 修改时间
///
public DateTime? UpdateTime { get; set; }
+
+ ///
+ /// 客户是否可见
+ ///
+ public bool IsVisibility { get; set; }
+
+ ///
+ /// 数据来源:1外部服务商创建,2内部系统创建,3人工创建
+ ///
+ public int Source { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string? Remarks { get; set; } = GlobalConst.EmptyString;
+
+ ///
+ /// 附件集合
+ ///
+ public List? Files { get; set; }
+
+ ///
+ /// 轨迹发生地(城市)
+ ///
+ public string? TrackPlaceCity { get; set; } = GlobalConst.EmptyString;
+
+ ///
+ /// 轨迹发生地(城市)Id
+ ///
+ public int? TrackPlaceCityId { get; set; } = GlobalConst.NotExistId;
+
+ ///
+ /// 轨迹发生地(省/州)
+ ///
+ public string? TrackPlaceProvince { get; set; } = GlobalConst.EmptyString;
+
+ ///
+ ///轨迹发生地(省/州)Id
+ ///
+ public int? TrackPlaceProvinceId { get; set; } = GlobalConst.NotExistId;
+
+ ///
+ /// 轨迹发生地(国家/地区)
+ ///
+ public string? TrackPlaceNation { get; set; } = GlobalConst.EmptyString;
+
+ ///
+ /// 轨迹发生地(国家/地区)Id
+ ///
+ public int? TrackPlaceNationId { get; set; } = GlobalConst.NotExistId;
+
+ ///
+ /// 轨迹发生地邮编
+ ///
+ public string? TrackPlacePostcode { get; set; } = GlobalConst.EmptyString;
+
+ ///
+ /// 预计签收时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 签收地时区
+ ///
+ public float? DestinationTimeZone { get; set; }
}
diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs
index d517bfc8..e7901efa 100644
--- a/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs
+++ b/src/SJZY.Track.Domain/Consts/GlobalConst.MQ.cs
@@ -51,4 +51,11 @@ public partial class GlobalConst
/// 预警计算任务
///
public const string TrackWarningCalcSubscribe = "SJZY.Track.TrackWarningCalc";
+
+ ///
+ /// 轨迹变更通知交换机
+ ///
+ public const string TrackChangeExchange = "sjzy.track.on_track_change_ex";
+
+
}
diff --git a/src/SJZY.Track.Domain/Consts/GlobalConst.cs b/src/SJZY.Track.Domain/Consts/GlobalConst.cs
index 183d921e..d8064f12 100644
--- a/src/SJZY.Track.Domain/Consts/GlobalConst.cs
+++ b/src/SJZY.Track.Domain/Consts/GlobalConst.cs
@@ -7,6 +7,7 @@ public partial class GlobalConst
public const int ChunkSize = 100;
public const int SafelyLimit = 10000;
public const int NormalLimit = 10000;
+ public const int NotExistId = -9999;
public const float NoneTrackTimeZone = 99999;
diff --git a/src/SJZY.Track.Domain/Dtos/Order/GetPageTrackOrderInputVO.cs b/src/SJZY.Track.Domain/Dtos/Order/GetPageTrackOrderInputVO.cs
index 7d473d1f..b57037a0 100644
--- a/src/SJZY.Track.Domain/Dtos/Order/GetPageTrackOrderInputVO.cs
+++ b/src/SJZY.Track.Domain/Dtos/Order/GetPageTrackOrderInputVO.cs
@@ -68,6 +68,7 @@ public class TrackOrderVO
///
public string? OrderNumber { get; set; }
+
///
/// 客户简称
///
@@ -137,4 +138,19 @@ public class TrackOrderVO
/// 问题类型名称
///
public string? QuestionTypeName { get; set; }
+
+ ///
+ /// 预计到达时间
+ ///
+ public DateTime? EstimatedDeliveryDate { get; set; }
+
+ ///
+ /// 目的地时区
+ ///
+ public float? DestinationTimeZone { get; set; }
+
+ ///
+ /// 第三方单号,服务商-轨迹0000000、轨迹服务商-0000000
+ ///
+ public string? ThirdPartyOrderNumber { get; set; }
}
diff --git a/src/SJZY.Track.Domain/Dtos/TrackContents/GetPageTrackContentVO.cs b/src/SJZY.Track.Domain/Dtos/TrackContents/GetPageTrackContentVO.cs
index 5dc044c7..2c9ef883 100644
--- a/src/SJZY.Track.Domain/Dtos/TrackContents/GetPageTrackContentVO.cs
+++ b/src/SJZY.Track.Domain/Dtos/TrackContents/GetPageTrackContentVO.cs
@@ -89,4 +89,19 @@ public class GetTrackContentListVO
/// 修改人
///
public string UpdateUser { get; set; }
+
+ ///
+ /// 是否可重复
+ ///
+ public bool IsRepeatable { get; set; }
+
+ ///
+ /// 是否允许手动修改
+ ///
+ public bool IsAllowManuallyUpdate { get; set; }
+
+ ///
+ /// 是否允许手动创建
+ ///
+ public bool IsAllowManuallyCreate { get; set; }
}
diff --git a/src/SJZY.Track.Domain/Dtos/TrackContents/GetTrackContentDetailVO.cs b/src/SJZY.Track.Domain/Dtos/TrackContents/GetTrackContentDetailVO.cs
index 2d1d8426..fe5b29d2 100644
--- a/src/SJZY.Track.Domain/Dtos/TrackContents/GetTrackContentDetailVO.cs
+++ b/src/SJZY.Track.Domain/Dtos/TrackContents/GetTrackContentDetailVO.cs
@@ -56,4 +56,18 @@ public class GetTrackContentDetailVO
/// 是否对外
///
public bool IsExternal { get; set; }
+ ///
+ /// 是否可重复
+ ///
+ public bool IsRepeatable { get; set; }
+
+ ///
+ /// 是否允许手动修改
+ ///
+ public bool IsAllowManuallyUpdate { get; set; }
+
+ ///
+ /// 是否允许手动创建
+ ///
+ public bool IsAllowManuallyCreate { get; set; }
}
diff --git a/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs b/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs
index 374fa387..8b7cdf3f 100644
--- a/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs
+++ b/src/SJZY.Track.Domain/Dtos/TrackContents/TrackContentVO.cs
@@ -31,4 +31,34 @@ public class TrackContentVO
/// 是否完成态
///
public bool IsCompleted { get; set; }
+
+ ///
+ /// 轨迹状态代码
+ ///
+ public string TrackStatusCode { get; set; }
+
+ ///
+ /// 是否可重复
+ ///
+ public bool IsRepeatable { get; set; }
+
+ ///
+ /// 是否允许手动修改
+ ///
+ public bool IsAllowManuallyUpdate { get; set; }
+
+ ///
+ /// 是否允许手动创建
+ ///
+ public bool IsAllowManuallyCreate { get; set; }
+
+ ///
+ /// 是否广播
+ ///
+ public bool IsToMq { get; set; }
+
+ ///
+ /// 轨迹内容code
+ ///
+ public string TrackContentCode { get; set; }
}
diff --git a/src/SJZY.Track.Domain/Enums/TrackSourceEnum.cs b/src/SJZY.Track.Domain/Enums/TrackSourceEnum.cs
new file mode 100644
index 00000000..021616af
--- /dev/null
+++ b/src/SJZY.Track.Domain/Enums/TrackSourceEnum.cs
@@ -0,0 +1,24 @@
+using System.ComponentModel;
+
+namespace SJZY.Track.Domain.Enums;
+
+///
+/// 轨迹来源
+///
+public enum TrackSourceEnum
+{
+ ///
+ /// 外部服务商创建
+ ///
+ [Description("外部服务商创建")] ExternalServiceProvide = 1,
+
+ ///
+ /// 内部系统创建
+ ///
+ [Description("内部系统创建")] InternalService = 2,
+
+ ///
+ /// 人工创建
+ ///
+ [Description("人工创建")] Artificial = 3,
+}
diff --git a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs
index 91550425..31855027 100644
--- a/src/SJZY.Track.Repository/Queries/ProvideQueries.cs
+++ b/src/SJZY.Track.Repository/Queries/ProvideQueries.cs
@@ -45,7 +45,8 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen
&& b.StartTime <= DateTime.Now && b.EndTime >= DateTime.Now)
.Select((a, b, c) => new OrderWithServiceProviderVO
{
- OrderNo = a.OrderNo,
+ //优先使用第三方的订单号,为空时才使用主单号
+ OrderNo = b.OrderNo ?? a.OrderNo,
OrderType = a.OrderType,
SubSystemId = a.SubSystemId,
ServiceProviderCode = b.ServiceProviderCode,
@@ -65,7 +66,8 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen
b.EndTime >= DateTime.Now)
.Select((a, b) => new OrderWithServiceProviderVO
{
- OrderNo = a.OrderNo,
+ //优先使用第三方的订单号,为空时才使用主单号
+ OrderNo = b.OrderNo ?? a.OrderNo,
OrderType = a.OrderType,
SubSystemId = a.SubSystemId,
ServiceProviderCode = b.ServiceProviderCode
@@ -87,9 +89,14 @@ public class ProvideQueries : ISugarRepository, IProvideQueries, ITransientDepen
SubSystemCode = z.Key,
TrackStatusId = x.TrackStatusId,
TrackStatus = y.Status,
+ TrackStatusCode = y.Code,
TrackContent = x.Content,
TrackEnContent = x.EnContent,
IsCompleted = y.IsCompleted,
+ IsRepeatable = x.IsRepeatable,
+ IsAllowManuallyUpdate = x.IsAllowManuallyUpdate,
+ IsAllowManuallyCreate = x.IsAllowManuallyCreate,
+ IsToMq = y.IsToMq,
})
.FirstAsync();
}
diff --git a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs
index eb62e350..727f17d6 100644
--- a/src/SJZY.Track.Repository/Repositories/OrderRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/OrderRepository.cs
@@ -12,11 +12,14 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
{
public async Task> GetTrackOrderPagedList(GetPageTrackOrderInputVO input)
{
+ //查询完去重
var pageList = await Context.Queryable()
+ .Includes(a => a.OrderPlatformNumbers)
.LeftJoin((a, b) => a.CustomId == b.Id && b.IsDeleted == false)
.LeftJoin((a, b, c) => a.SubSystemId == c.Id && c.IsDeleted == false)
+ .LeftJoin((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) => input.OrderNos!.Contains(a.OrderNo))
+ .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),
@@ -28,6 +31,7 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
.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,
@@ -44,7 +48,10 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
IsFinish = a.IsCompleted,
CreateTime = a.CreateTime,
SubSystem = c.CnName,
- SubSystemId = c.Id
+ SubSystemId = c.Id,
+ DestinationTimeZone = a.DestinationTimeZone,
+ EstimatedDeliveryDate = a.EstimatedDeliveryDate,
+ ThirdPartyOrderNumber = BuildThirdPartyOrderNumber(a.OrderPlatformNumbers)
})
.ToPagedListAsync(input.PageIndex, input.PageSize);
@@ -60,6 +67,8 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
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();
@@ -90,6 +99,13 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
// 更新订单模板
await Context.Deleteable().Where(x => x.OrderId == order.Id).ExecuteCommandAsync();
+ order.OrderPullStatus.ForEach(x => x.OrderId = order.Id);
+ await Context.Insertable(order.OrderPullStatus).ExecuteCommandAsync();
+
+ // 更新订单三方关联
+ await Context.Deleteable().Where(x => x.OrderId == order.Id).ExecuteCommandAsync();
+ order.OrderPlatformNumbers.ForEach(x => x.OrderId = order.Id);
+ await Context.Insertable(order.OrderPlatformNumbers).ExecuteCommandAsync();
// 更新订单航班
await Context.Deleteable().Where(x => x.OrderId == order.Id).ExecuteCommandAsync();
@@ -163,6 +179,16 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
return res.Select(x => (x.Key, x.Id)).ToList();
}
+ public Task GetSystemInfoById(int id)
+ {
+ return Context.Queryable().FirstAsync(m => m.IsDeleted == false && m.Id == id);
+ }
+
+ public Task GetUserById(int id)
+ {
+ return Context.Queryable().FirstAsync(m => m.IsDeleted == false && m.Id == id);
+ }
+
private int UpdateOrderQuestionType(int questionType, IEnumerable ids)
{
var idsString = string.Join(",", ids);
@@ -174,6 +200,20 @@ public class OrderRepository : BasicRepository, IOrderRepository, I
});
}
+ ///
+ /// 拼接多个三方单号,默认使用分隔符默认(、)
+ /// 第三方单号,服务商-轨迹0000000、轨迹服务商-0000000
+ ///
+ ///
+ ///
+ private static string BuildThirdPartyOrderNumber(List orderPlatformNumberEntities)
+ {
+ const string separator = "、";
+ var thirdPartyOrderNumbers = orderPlatformNumberEntities
+ .Select(x => $"{x.Platform}-{x.OrderNumber}").ToList();
+ return string.Join(separator, thirdPartyOrderNumbers);
+ }
+
#region 订单关联
public async Task> GetLinkedOrdersAsync(int[] orderIds)
diff --git a/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs
index c1399c6a..d619613b 100644
--- a/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/TrackContentRepository.cs
@@ -33,6 +33,9 @@ public class TrackContentRepository : BasicRepository, ITrac
EnContent = a.EnContent,
TrackFlagId = a.TrackFlagId,
IsExternal = a.IsExternal,
+ IsRepeatable = a.IsRepeatable,
+ IsAllowManuallyUpdate = a.IsAllowManuallyUpdate,
+ IsAllowManuallyCreate = a.IsAllowManuallyCreate
})
.Mapper(x => { x.TrackFlagIds = x.TrackFlagId?.Split(',').Select(int.Parse).ToList(); })
.FirstAsync();
@@ -80,6 +83,9 @@ public class TrackContentRepository : BasicRepository, ITrac
CreateUser = e.Name,
UpdateTime = a.UpdateTime,
UpdateUser = f.Name,
+ IsRepeatable = a.IsRepeatable,
+ IsAllowManuallyUpdate = a.IsAllowManuallyUpdate,
+ IsAllowManuallyCreate = a.IsAllowManuallyCreate
})
.ToPagedListAsync(input.PageIndex, input.PageSize);
@@ -113,7 +119,6 @@ public class TrackContentRepository : BasicRepository, ITrac
return false;
}
-
public async Task> GetMapPageAsync(
GetTrackContentMapPageInputVO input)
{
@@ -220,4 +225,50 @@ public class TrackContentRepository : BasicRepository, ITrac
return await Context.Updateable().SetColumns(columns).Where(whereExpression)
.ExecuteCommandAsync() > 0;
}
+
+ public Task GetByCodeAsync(int systemId, string code)
+ {
+ return Context.Queryable().FirstAsync(m => m.SubSystemId == systemId && m.Code == code);
+ }
+
+ public Task> GetListBySystemIdAsync(int systemId)
+ {
+ return Context.Queryable()
+ .Where(content => content.SubSystemId == systemId && !content.IsDeleted)
+ .Select((content) => new TrackContentEntity
+ {
+ Id = content.Id,
+ Code = content.Code,
+ IsExternal = content.IsExternal,
+ EnContent = content.EnContent,
+ Content = content.Content,
+ IsRepeatable = content.IsRepeatable,
+ IsAllowManuallyCreate = content.IsAllowManuallyCreate,
+ IsAllowManuallyUpdate = content.IsAllowManuallyUpdate,
+ })
+ .ToListAsync();
+ }
+
+ public Task> GetTrackContentBySyetemIdAsync(int subSystemId)
+ {
+ return Context.Queryable()
+ .LeftJoin((x, y) => x.TrackStatusId == y.Id)
+ .LeftJoin((x, y, z) => x.SubSystemId == z.Id)
+ .Where(x => x.SubSystemId == subSystemId)
+ .Select((x, y, z) => new TrackContentVO
+ {
+ SubSystemCode = z.Key,
+ TrackStatusId = x.TrackStatusId,
+ TrackStatus = y.Status,
+ TrackStatusCode = y.Code,
+ TrackContent = x.Content,
+ TrackContentCode = x.Code,
+ TrackEnContent = x.EnContent,
+ IsCompleted = y.IsCompleted,
+ IsRepeatable = x.IsRepeatable,
+ IsAllowManuallyUpdate = x.IsAllowManuallyUpdate,
+ IsAllowManuallyCreate = x.IsAllowManuallyCreate,
+ IsToMq = y.IsToMq,
+ }).ToListAsync();
+ }
}
diff --git a/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs b/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs
index 44715ae6..0fee4fc6 100644
--- a/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs
+++ b/src/SJZY.Track.Repository/Repositories/TrackDetailsEsRepository.cs
@@ -3,6 +3,7 @@ using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.Expand.ElasticSearch.Services;
using SJZY.Track.Domain.Aggregates.TrackDetailsAggregate;
using SJZY.Track.Domain.Consts;
+using SJZY.Track.Domain.Enums;
namespace SJZY.Track.Repository.Repositories;
@@ -145,6 +146,20 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract p
.Add("trackPlace", track.TrackPlace)
@@ -181,6 +211,21 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract> GetListAsync(int[] orderIds, List trackCodes, TrackSourceEnum source)
+ {
+ var r = await Context.SearchAsync(x => x
+ .Index(GlobalConst.TrackDetailsIndex)
+ .Query(q =>
+ q.Terms(t => t.Field(f => f.OrderId).Terms(orderIds))
+ && q.Terms(t => t.Field(f => f.TrackCode.Suffix("keyword")).Terms(trackCodes))
+ && q.Term(t => t.Source, (int) source)
+ )
+ .Size(SafelyLimit)
+ .Sort(s => s.Field(f => f.ZeroTrackTime, SortOrder.Descending)));
+
+ if (!r.IsValid)
+ {
+ throw new InvalidOperationException($"轨迹查询失败,orderIds:[{string.Join(',', orderIds)}],原因:{r.DebugInformation}。");
+ }
+
+ return r.ToIdList();
+ }
+
public async Task> DeleteTrackAsync(int[] orderIds, List trackCodes)
{
// var deleteResponse = await Context.DeleteByQueryAsync(d => d
@@ -334,6 +399,7 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract new
{
doc.OrderId,
@@ -351,6 +417,7 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract x.OrderId).ToList();
}
+
public async Task DeleteTrackByIdAsync(string id, string indexName)
{
var r = await Context.DeleteAsync(id, u => u
@@ -362,4 +429,15 @@ public class TrackDetailsEsRepository : ElasticSearchContextAbstract> GetDataByIds(string[] ids)
+ {
+ var res = await Context.SearchAsync(m => m
+ .Index(GlobalConst.TrackDetailsIndex)
+ .Query(
+ q => q.Ids(i => i.Values(ids))
+ ));
+
+ return res.ToIdList();
+ }
}