diff --git a/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackCurlBuilder.cs b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackCurlBuilder.cs new file mode 100644 index 0000000..cdf27c4 --- /dev/null +++ b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackCurlBuilder.cs @@ -0,0 +1,37 @@ +using System.Text; +using System.Text.Json; + +namespace Oms.Application.Integrations.SmallBagTrack; + +internal static class SmallBagTrackCurlBuilder +{ + public static string Build( + string url, + string appKey, + long timestamp, + string sign, + string? authorization, + object body, + JsonSerializerOptions jsonOptions) + { + var bodyJson = JsonSerializer.Serialize(body, jsonOptions); + var sb = new StringBuilder(); + sb.AppendLine($"curl --location --request POST '{url}' \\"); + sb.AppendLine($"--header 'appKey: {appKey}' \\"); + sb.AppendLine($"--header 'timestamp: {timestamp}' \\"); + sb.AppendLine($"--header 'sign: {sign}' \\"); + if (!string.IsNullOrWhiteSpace(authorization)) + { + sb.AppendLine($"--header 'Authorization: {authorization.Trim()}' \\"); + } + + sb.AppendLine("--header 'Content-Type: application/json' \\"); + sb.Append("--data-raw '"); + sb.Append(EscapeForSingleQuotedShell(bodyJson)); + sb.Append('\''); + return sb.ToString(); + } + + private static string EscapeForSingleQuotedShell(string value) => + value.Replace("'", "'\\''", StringComparison.Ordinal); +} diff --git a/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderClient.cs b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderClient.cs index 0522cf0..5149e26 100644 --- a/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderClient.cs +++ b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackOrderClient.cs @@ -72,20 +72,8 @@ internal sealed class SmallBagTrackOrderClient( var body = SmallBagTrackUpsertApiRequest.FromBusinessRequest(request); var url = SmallBagTrackUpsertApiRequest.BuildEndpointUrl(settings.BaseUrl); var authorization = ResolveAuthorization(request); - var requestJson = JsonSerializer.Serialize( - new - { - auth = new - { - appKey, - timestamp, - sign, - transport = "header", - authorizationForwarded = !string.IsNullOrWhiteSpace(authorization) - }, - body - }, - JsonOptions); + var curlCommand = SmallBagTrackCurlBuilder.Build(url, appKey, timestamp, sign, authorization, body, JsonOptions); + var requestJson = JsonSerializer.Serialize(body, JsonOptions); using var httpRequest = new HttpRequestMessage(HttpMethod.Post, url); httpRequest.Headers.TryAddWithoutValidation("appKey", appKey); @@ -105,6 +93,7 @@ internal sealed class SmallBagTrackOrderClient( Success = response.IsSuccessStatusCode, Url = url, RequestJson = requestJson, + CurlCommand = curlCommand, StatusCode = (int)response.StatusCode, ResponseBody = responseBody }; diff --git a/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackUpsertResult.cs b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackUpsertResult.cs index f200d8a..e4e3883 100644 --- a/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackUpsertResult.cs +++ b/src/Oms.Application/Integrations/SmallBagTrack/SmallBagTrackUpsertResult.cs @@ -15,6 +15,11 @@ public class SmallBagTrackUpsertResult public string RequestJson { get; set; } = string.Empty; + /// + /// 可复现的 curl 命令(含 appKey/timestamp/sign/Authorization 与业务 body)。 + /// + public string CurlCommand { get; set; } = string.Empty; + public int? StatusCode { get; set; } public string ResponseBody { get; set; } = string.Empty;