admin/src/Oms.Application/Shared/OmsDocHelper.cs
zzh 90f6c25b04 feat(order): 问题件/理赔件标记、通知投递与自动触发
新增 mark-problematic/mark-claimed/handle-status 接口,异常事件审计表与占位符渲染;inApp/email 通知及下单/入库/出库自动触发运行时。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 16:46:52 +08:00

191 lines
6.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using Oms.Application.Dtos.Orders;
using Oms.Domain.OrdersAggregate.Consts;
using Oms.Domain.SystemAggregate.Consts;
namespace Oms.Application.Shared;
/// <summary>
/// OMS 通用文档与展示辅助方法。
/// </summary>
public static class OmsDocHelper
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true
};
private static readonly JsonSerializerOptions SnapshotJsonOptions = new()
{
PropertyNameCaseInsensitive = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
/// <summary>
/// 将页码规范为至少 1。
/// </summary>
public static int NormalizePage(int page) => page <= 0 ? 1 : page;
/// <summary>
/// 将每页条数规范为 1~200。
/// </summary>
public static int NormalizePageSize(int pageSize) => pageSize <= 0 ? 20 : Math.Min(pageSize, 200);
/// <summary>
/// 将默认 DateTime 转为 null。
/// </summary>
public static DateTime? NullIfDefault(DateTime value) => value == default ? null : value;
/// <summary>
/// 将库内 JSON 字符串转为 API 可输出的 CLR 对象(避免 JsonElement 被 Newtonsoft 序列化成 valueKind)。
/// </summary>
public static object? DeserializeJsonObject(string? json)
{
if (string.IsNullOrWhiteSpace(json))
{
return null;
}
using var document = JsonDocument.Parse(json);
return ConvertJsonElement(document.RootElement);
}
/// <summary>
/// 反序列化 JSON 字符串为指定类型。
/// </summary>
public static T? DeserializeJson<T>(string? json)
{
if (string.IsNullOrWhiteSpace(json))
{
return default;
}
return JsonSerializer.Deserialize<T>(json, JsonOptions);
}
/// <summary>
/// 将请求体中的动态 JSON(JsonElement / JToken / Dictionary 等)规范为可落库的 JSON 字符串。
/// </summary>
public static string? SerializeJson<T>(T? value)
{
if (value is null)
{
return null;
}
if (value is JsonElement element)
{
return element.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined
? null
: element.GetRawText();
}
if (value is JsonNode node)
{
return node.ToJsonString();
}
if (value is string text)
{
return string.IsNullOrWhiteSpace(text) ? null : text;
}
var typeName = value.GetType().FullName;
if (typeName is not null && typeName.StartsWith("Newtonsoft.Json.Linq.", StringComparison.Ordinal))
{
return value.ToString();
}
return JsonSerializer.Serialize(value, JsonOptions);
}
/// <summary>
/// 序列化发布快照(忽略 null,避免写出旧兼容字段)。
/// </summary>
public static string? SerializeSnapshotJson<T>(T? value)
{
if (value is null)
{
return null;
}
return JsonSerializer.Serialize(value, SnapshotJsonOptions);
}
public static SalesProductRulesPublishSnapshotDto? DeserializeRulesSnapshot(string? json)
{
var snapshot = DeserializeJson<SalesProductRulesPublishSnapshotDto>(json);
PublishSnapshotNormalizer.NormalizeRulesSnapshot(snapshot);
return snapshot;
}
public static SalesProductPricePublishSnapshotDto? DeserializePriceSnapshot(string? json)
{
var snapshot = DeserializeJson<SalesProductPricePublishSnapshotDto>(json);
PublishSnapshotNormalizer.NormalizePriceSnapshot(snapshot);
return snapshot;
}
private static object? ConvertJsonElement(JsonElement element) => element.ValueKind switch
{
JsonValueKind.Object => element.EnumerateObject()
.ToDictionary(property => property.Name, property => ConvertJsonElement(property.Value)),
JsonValueKind.Array => element.EnumerateArray()
.Select(ConvertJsonElement)
.ToList(),
JsonValueKind.String => element.GetString(),
JsonValueKind.Number => element.TryGetInt64(out var integer)
? integer
: element.GetDecimal(),
JsonValueKind.True => true,
JsonValueKind.False => false,
JsonValueKind.Null or JsonValueKind.Undefined => null,
_ => element.GetRawText()
};
/// <summary>
/// 反序列化 JSON 字符串数组。
/// </summary>
public static List<string> DeserializeStringList(string? json) => JsonStringArrayHelper.Deserialize(json);
/// <summary>
/// 将订单状态码转为中文名称。
/// </summary>
public static string? GetOrderStatusName(string statusCode)
{
return statusCode switch
{
OrderStatusCodes.Draft => "草稿",
OrderStatusCodes.Predeclared => "已预报",
OrderStatusCodes.Received => "已收货",
OrderStatusCodes.PendingPayment => "待支付",
OrderStatusCodes.PendingShip => "待发货",
OrderStatusCodes.PendingOnline => "待上网",
OrderStatusCodes.Shipping => "运输中",
OrderStatusCodes.DeliverySuccess => "派送成功",
OrderStatusCodes.DeliveryFailed => "派送失败",
OrderStatusCodes.Problematic => "问题件",
OrderStatusCodes.Deleted => "已删除",
OrderStatusCodes.Claimed => "理赔件",
_ => statusCode
};
}
/// <summary>
/// 将仓库类型码转为中文名称。
/// </summary>
public static string GetWarehouseTypeName(string warehouseType)
{
return warehouseType switch
{
WarehouseTypeCodes.Main => "主仓",
WarehouseTypeCodes.Transit => "中转仓",
WarehouseTypeCodes.Return => "退货仓",
WarehouseTypeCodes.Other => "其他",
_ => warehouseType
};
}
}