using System.Text.Json; using Oms.Domain.OrdersAggregate.Entities; namespace Oms.Application.Integrations.Itfx; /// /// 解析 itfx createOrderOne 成功响应中的 Data 字段,并回写订单。 /// internal static class ItfxCreateOrderOneDataParser { public sealed class CreateOrderOneData { public string? ServiceNo { get; init; } public string? TrackNo { get; init; } public string? ClientNo { get; init; } public string? LabelUrl { get; init; } } public static bool TryParse(string? responseBody, out CreateOrderOneData? data) { data = null; if (string.IsNullOrWhiteSpace(responseBody)) { return false; } try { using var doc = JsonDocument.Parse(responseBody); var root = doc.RootElement; if (root.ValueKind != JsonValueKind.Object) { return false; } if (!TryGetPropertyIgnoreCase(root, out var dataElement, "data", "Data") || dataElement.ValueKind != JsonValueKind.Object) { return false; } data = new CreateOrderOneData { ServiceNo = ReadString(dataElement, "serviceNo", "ServiceNo"), TrackNo = ReadString(dataElement, "trackNo", "TrackNo"), ClientNo = ReadString(dataElement, "clientNo", "ClientNo"), LabelUrl = ReadString(dataElement, "labelUrl", "LabelUrl"), }; return !string.IsNullOrWhiteSpace(data.ServiceNo) || !string.IsNullOrWhiteSpace(data.TrackNo) || !string.IsNullOrWhiteSpace(data.ClientNo) || !string.IsNullOrWhiteSpace(data.LabelUrl); } catch { return false; } } /// /// 将下游返回写入订单:服务商单号 ← Data.serviceNo,跟踪号 ← Data.trackNo。 /// 空值不覆盖已有字段。 /// public static bool ApplyToOrder(Order order, CreateOrderOneData data) { var changed = false; if (!string.IsNullOrWhiteSpace(data.ServiceNo)) { var value = data.ServiceNo.Trim(); if (!string.Equals(order.DownstreamServiceNo, value, StringComparison.Ordinal)) { order.DownstreamServiceNo = value; changed = true; } } if (!string.IsNullOrWhiteSpace(data.TrackNo)) { var value = data.TrackNo.Trim(); if (!string.Equals(order.TrackNo, value, StringComparison.Ordinal)) { order.TrackNo = value; changed = true; } } if (!string.IsNullOrWhiteSpace(data.LabelUrl)) { var value = data.LabelUrl.Trim(); if (!string.Equals(order.LabelUrl, value, StringComparison.Ordinal)) { order.LabelUrl = value; changed = true; } } return changed; } private static bool TryGetPropertyIgnoreCase(JsonElement root, out JsonElement value, params string[] names) { foreach (var name in names) { if (root.TryGetProperty(name, out value)) { return true; } } foreach (var prop in root.EnumerateObject()) { foreach (var name in names) { if (prop.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) { value = prop.Value; return true; } } } value = default; return false; } private static string? ReadString(JsonElement root, params string[] names) { if (!TryGetPropertyIgnoreCase(root, out var prop, names)) { return null; } return prop.ValueKind switch { JsonValueKind.String => prop.GetString()?.Trim(), JsonValueKind.Number => prop.GetRawText(), JsonValueKind.Null => null, _ => null }; } }