diff --git a/src/Oms.Application/Dtos/Orders/OrderUpdateInput.cs b/src/Oms.Application/Dtos/Orders/OrderUpdateInput.cs
index d9bc676..58cff86 100644
--- a/src/Oms.Application/Dtos/Orders/OrderUpdateInput.cs
+++ b/src/Oms.Application/Dtos/Orders/OrderUpdateInput.cs
@@ -25,6 +25,12 @@ public class OrderUpdateInput
[StringLength(64)]
public string? TrackNo { get; set; }
+ ///
+ /// 服务商单号。
+ ///
+ [StringLength(64)]
+ public string? DownstreamServiceNo { get; set; }
+
///
/// 渠道编码。
///
diff --git a/src/Oms.Application/Services/Orders/OrderOperationLogSnapshot.cs b/src/Oms.Application/Services/Orders/OrderOperationLogSnapshot.cs
index f37c5d4..e25b977 100644
--- a/src/Oms.Application/Services/Orders/OrderOperationLogSnapshot.cs
+++ b/src/Oms.Application/Services/Orders/OrderOperationLogSnapshot.cs
@@ -37,21 +37,37 @@ public static class OrderOperationLogSnapshot
["isPaid"] = "是否已支付",
["additionalServices"] = "附加服务",
["sender.name"] = "发件人姓名",
+ ["sender.company"] = "发件公司",
["sender.phone"] = "发件人电话",
+ ["sender.telePhone"] = "发件人固话",
+ ["sender.email"] = "发件人邮箱",
["sender.country"] = "发件国家",
["sender.province"] = "发件省/州",
["sender.city"] = "发件城市",
["sender.zipCode"] = "发件邮编",
["sender.address1"] = "发件地址1",
["sender.address2"] = "发件地址2",
+ ["sender.address3"] = "发件地址3",
+ ["sender.houseNumber"] = "发件门牌号",
["receiver.name"] = "收件人姓名",
+ ["receiver.company"] = "收件公司",
["receiver.phone"] = "收件人电话",
+ ["receiver.telePhone"] = "收件人固话",
+ ["receiver.email"] = "收件人邮箱",
["receiver.country"] = "收件国家",
["receiver.province"] = "收件省/州",
["receiver.city"] = "收件城市",
["receiver.zipCode"] = "收件邮编",
+ ["receiver.streetNumber"] = "收件街道号",
["receiver.address1"] = "收件地址1",
["receiver.address2"] = "收件地址2",
+ ["receiver.address3"] = "收件地址3",
+ ["receiver.taxType"] = "收件税号类型",
+ ["receiver.taxNo"] = "收件税号",
+ ["receiver.certificateType"] = "收件证件类型",
+ ["receiver.certificateNo"] = "收件证件号",
+ ["receiver.eori"] = "收件EORI",
+ ["receiver.vat"] = "收件VAT",
["fee.receivableTotal"] = "应收合计",
["fee.payableTotal"] = "应付合计",
};
@@ -94,13 +110,18 @@ public static class OrderOperationLogSnapshot
return new Dictionary(StringComparer.OrdinalIgnoreCase)
{
["sender.name"] = Norm(sender.SenderName),
+ ["sender.company"] = Norm(sender.Company),
["sender.phone"] = Norm(sender.Phone),
+ ["sender.telePhone"] = Norm(sender.TelePhone),
+ ["sender.email"] = Norm(sender.Email),
["sender.country"] = FormatInt(sender.Country),
["sender.province"] = Norm(sender.Province),
["sender.city"] = Norm(sender.City),
["sender.zipCode"] = Norm(sender.ZipCode),
["sender.address1"] = Norm(sender.StreetAddress1),
["sender.address2"] = Norm(sender.StreetAddress2),
+ ["sender.address3"] = Norm(sender.StreetAddress3),
+ ["sender.houseNumber"] = Norm(sender.HouseNumber),
};
}
@@ -114,13 +135,24 @@ public static class OrderOperationLogSnapshot
return new Dictionary(StringComparer.OrdinalIgnoreCase)
{
["receiver.name"] = Norm(recipient.RecipientsName),
+ ["receiver.company"] = Norm(recipient.CompanyName),
["receiver.phone"] = Norm(recipient.Phone),
+ ["receiver.telePhone"] = Norm(recipient.TelePhone),
+ ["receiver.email"] = Norm(recipient.Email),
["receiver.country"] = FormatInt(recipient.Country),
["receiver.province"] = Norm(recipient.Province),
["receiver.city"] = Norm(recipient.City),
["receiver.zipCode"] = Norm(recipient.ZipCode),
+ ["receiver.streetNumber"] = Norm(recipient.StreetNumber),
["receiver.address1"] = Norm(recipient.StreetAddress1),
["receiver.address2"] = Norm(recipient.StreetAddress2),
+ ["receiver.address3"] = Norm(recipient.StreetAddress3),
+ ["receiver.taxType"] = FormatInt(recipient.TaxType),
+ ["receiver.taxNo"] = Norm(recipient.TaxNo),
+ ["receiver.certificateType"] = FormatInt(recipient.CertificateType),
+ ["receiver.certificateNo"] = Norm(recipient.CertificateNo),
+ ["receiver.eori"] = Norm(recipient.Eori),
+ ["receiver.vat"] = Norm(recipient.Vat),
};
}
diff --git a/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs b/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs
index 0a98566..076e3f3 100644
--- a/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs
+++ b/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs
@@ -53,6 +53,13 @@ public partial class OrderService
order.TrackNo = string.IsNullOrWhiteSpace(input.TrackNo) ? null : input.TrackNo.Trim();
}
+ if (input.DownstreamServiceNo != null)
+ {
+ order.DownstreamServiceNo = string.IsNullOrWhiteSpace(input.DownstreamServiceNo)
+ ? null
+ : input.DownstreamServiceNo.Trim();
+ }
+
if (input.ChannelCode != null)
{
order.ChannelCode = string.IsNullOrWhiteSpace(input.ChannelCode) ? null : input.ChannelCode.Trim();
@@ -138,7 +145,9 @@ public partial class OrderService
order = await GetOrderOrThrowAsync(order.Id);
var afterSnap = await CaptureOrderAuditSnapshotAsync(order, includeParties: true);
- var remark = input.Items != null ? "申报信息已更新" : null;
+ // 前端保存基本信息时总会带 items;仅在无字段级 diff 时用备注兜底,避免掩盖真实字段变更
+ var fieldChanges = OrderOperationLogSnapshot.Diff(beforeSnap, afterSnap);
+ var remark = input.Items != null && fieldChanges.Count == 0 ? "申报信息已更新" : null;
await OperationLogWriter.TryWriteAsync(
order,
OrderOperationActionCodes.EditBasic,
diff --git a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs
index fbd528a..15e2e53 100644
--- a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs
+++ b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs
@@ -2382,6 +2382,7 @@ public partial class OrderService
try
{
+ var beforeSnap = await CaptureOrderAuditSnapshotAsync(order, includeWeights: true);
var weights = (await OrderRepository.GetWeightsByOrderIdsAsync([order.Id]))
.OrderBy(x => x.Id)
.ToList();
@@ -2419,6 +2420,16 @@ public partial class OrderService
order.UpdateTime = DateTime.Now;
await OrderRepository.UpdateAsync(order);
+ // 操作日志同步落库(件重尺已写完);计费/排货仍走 MQ,不把审计塞进队列
+ order = await GetOrderOrThrowAsync(order.Id);
+ var afterSnap = await CaptureOrderAuditSnapshotAsync(order, includeWeights: true);
+ await OperationLogWriter.TryWriteAsync(
+ order,
+ OrderOperationActionCodes.Inbound,
+ beforeSnap,
+ afterSnap,
+ FormatMeasuredDimensionsRemark("收货", length!.Value, width!.Value, height!.Value, actualWeight!.Value));
+
await EnqueueLifecycleTrackAppendAsync(order, SmallBagTrackLifecycleEvents.InboundTrackCode);
await EnqueueInboundBillingAsync(order);
}
@@ -3016,6 +3027,7 @@ public partial class OrderService
EnsureBillingProductActive(product);
+ var beforeSnap = await CaptureOrderAuditSnapshotAsync(order, includeWeights: true);
var weights = (await OrderRepository.GetWeightsByOrderIdsAsync([order.Id]))
.OrderBy(x => x.Id)
.ToList();
@@ -3038,9 +3050,28 @@ public partial class OrderService
order.UpdateTime = now;
await OrderRepository.UpdateAsync(order);
+ order = await GetOrderOrThrowAsync(order.Id);
+ var afterSnap = await CaptureOrderAuditSnapshotAsync(order, includeWeights: true);
+ await OperationLogWriter.TryWriteAsync(
+ order,
+ OrderOperationActionCodes.Outbound,
+ beforeSnap,
+ afterSnap,
+ FormatMeasuredDimensionsRemark("发货", length!.Value, width!.Value, height!.Value, actualWeight!.Value));
+
await EnqueueLifecycleTrackAppendAsync(order, SmallBagTrackLifecycleEvents.OutboundTrackCode);
}
+ private static string FormatMeasuredDimensionsRemark(
+ string stage,
+ decimal length,
+ decimal width,
+ decimal height,
+ decimal actualWeight)
+ {
+ return $"{stage} 长×宽×高×重:{length:0.####}×{width:0.####}×{height:0.####}×{actualWeight:0.####}";
+ }
+
private async Task BuildParcelCreateOutputAsync(Order order)
{
// 预报已成功时,映射/面单/本地存储失败不得回滚订单(常见:容器 /app/wwwroot 不可写)。
diff --git a/src/Oms.Domain/OrdersAggregate/Consts/OrderOperationActionCodes.cs b/src/Oms.Domain/OrdersAggregate/Consts/OrderOperationActionCodes.cs
index d6c482b..104d465 100644
--- a/src/Oms.Domain/OrdersAggregate/Consts/OrderOperationActionCodes.cs
+++ b/src/Oms.Domain/OrdersAggregate/Consts/OrderOperationActionCodes.cs
@@ -14,6 +14,8 @@ public static class OrderOperationActionCodes
public const string PreDeclare = "preDeclare";
public const string DownstreamForward = "downstreamForward";
public const string Print = "print";
+ public const string Inbound = "inbound";
+ public const string Outbound = "outbound";
public static string GetActionName(string action) => action switch
{
@@ -29,6 +31,8 @@ public static class OrderOperationActionCodes
PreDeclare => "重新预报",
DownstreamForward => "预报下游",
Print => "打印面单",
+ Inbound => "入库",
+ Outbound => "出库",
_ => action
};
}