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
};
}
}