180 lines
5.0 KiB
C#
180 lines
5.0 KiB
C#
|
|
using Store.Modules.CloudProduct.Entities;
|
|
using Store.Modules.CloudProduct.Enums;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Json.Nodes;
|
|
|
|
namespace Store.Modules.CloudProduct.ImportConverters
|
|
{
|
|
/// <summary>
|
|
/// PDD 前端商品详情数据转换器(数据源格式见 data.txt)
|
|
/// </summary>
|
|
internal class ConverterV1 : GoodsConverterBase
|
|
{
|
|
public override string ConverterName => "ConverterV1";
|
|
|
|
public override PlatformType Platform => PlatformType.PDD;
|
|
|
|
protected override bool IsMatchProvider()
|
|
{
|
|
try
|
|
{
|
|
if (JsonNode.Parse(RawData) is not JsonObject root)
|
|
return false;
|
|
|
|
// data.txt:顶层包含 goods.goods_id
|
|
if (root["goods"] is JsonObject goodsObj && goodsObj["goods_id"] != null)
|
|
return true;
|
|
|
|
// 也兼容顶层直接是商品对象的情况
|
|
if (root["goods_id"] != null && (root["goods_name"] != null || root["title"] != null))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
protected override ProductEntity ConverterProvider()
|
|
{
|
|
if (JsonNode.Parse(RawData) is not JsonObject root)
|
|
throw new Exception("无法解析 PDD 商品数据");
|
|
|
|
var goodsNode = root["goods"] as JsonObject ?? root;
|
|
var priceNode = root["price"] as JsonObject;
|
|
|
|
var goods = new ProductEntity
|
|
{
|
|
Platform = (byte)PlatformType.PDD,
|
|
GoodsId = GetLong(goodsNode, "goods_id"),
|
|
Title = GetString(goodsNode, "goods_name")
|
|
?? GetString(goodsNode, "short_name")
|
|
?? string.Empty,
|
|
Description = GetString(goodsNode, "share_desc") ?? GetString(goodsNode, "short_name"),
|
|
ThumbUrl = GetString(goodsNode, "hd_url") ?? GetString(goodsNode, "thumb_url") ?? GetString(goodsNode, "hd_thumb_url") ?? GetString(goodsNode, "image_url"),
|
|
CatId1 = GetIntOrNull(goodsNode, "cat_id_1"),
|
|
CatId2 = GetIntOrNull(goodsNode, "cat_id_2"),
|
|
CatId3 = GetIntOrNull(goodsNode, "cat_id_3"),
|
|
CatId4 = GetIntOrNull(goodsNode, "cat_id_4"),
|
|
SoldQuantity = GetInt(goodsNode, "sold_quantity"),
|
|
Status = 0,
|
|
};
|
|
|
|
var price = GetPriceRange(priceNode, root);
|
|
goods.MinPrice = price.Min;
|
|
goods.MaxPrice = price.Max;
|
|
|
|
return goods;
|
|
}
|
|
|
|
private static string? GetString(JsonObject? obj, string key)
|
|
{
|
|
if (obj == null || !obj.TryGetPropertyValue(key, out var node) || node == null)
|
|
return null;
|
|
|
|
if (node is JsonValue value && value.TryGetValue<string>(out var str))
|
|
return str;
|
|
|
|
return node.ToJsonString();
|
|
}
|
|
|
|
private static long GetLong(JsonObject? obj, string key)
|
|
{
|
|
if (obj == null || !obj.TryGetPropertyValue(key, out var node) || node == null)
|
|
return 0;
|
|
|
|
if (node is JsonValue value)
|
|
{
|
|
if (value.TryGetValue<long>(out var l)) return l;
|
|
if (value.TryGetValue<decimal>(out var d)) return (long)d;
|
|
if (long.TryParse(value.ToString(), out var l2)) return l2;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private static int GetInt(JsonObject? obj, string key)
|
|
{
|
|
if (obj == null || !obj.TryGetPropertyValue(key, out var node) || node == null)
|
|
return 0;
|
|
|
|
if (node is JsonValue value)
|
|
{
|
|
if (value.TryGetValue<int>(out var i)) return i;
|
|
if (value.TryGetValue<long>(out var l)) return (int)l;
|
|
if (int.TryParse(value.ToString(), out var i2)) return i2;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private static int? GetIntOrNull(JsonObject? obj, string key)
|
|
{
|
|
if (obj == null || !obj.TryGetPropertyValue(key, out var node) || node == null)
|
|
return null;
|
|
|
|
if (node is JsonValue value)
|
|
{
|
|
if (value.TryGetValue<int>(out var i) && i > 0) return i;
|
|
if (value.TryGetValue<long>(out var l) && l > 0) return (int)l;
|
|
if (int.TryParse(value.ToString(), out var i2) && i2 > 0) return i2;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static long? GetLongOrNull(JsonObject? obj, string key)
|
|
{
|
|
if (obj == null || !obj.TryGetPropertyValue(key, out var node) || node == null)
|
|
return null;
|
|
|
|
if (node is JsonValue value)
|
|
{
|
|
if (value.TryGetValue<long>(out var d)) return d;
|
|
if (value.TryGetValue<long>(out var l)) return l;
|
|
if (long.TryParse(value.ToString(), out var d2)) return d2;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算价格区间。优先使用顶层 price 节点,其次遍历 sku。
|
|
/// </summary>
|
|
private static (long? Min, long? Max) GetPriceRange(JsonObject? priceNode, JsonObject root)
|
|
{
|
|
long? min = null;
|
|
long? max = null;
|
|
|
|
if (priceNode != null)
|
|
{
|
|
min = GetLongOrNull(priceNode, "min_group_price");
|
|
max = GetLongOrNull(priceNode, "max_group_price");
|
|
if (min.HasValue || max.HasValue)
|
|
return (min, max);
|
|
}
|
|
|
|
if (root["sku"] is JsonArray skuArray && skuArray.Count > 0)
|
|
{
|
|
foreach (var item in skuArray.OfType<JsonObject>())
|
|
{
|
|
var price = GetLongOrNull(item, "group_price") ?? GetLongOrNull(item, "normal_price");
|
|
if (price == null) continue;
|
|
|
|
min = min.HasValue ? Math.Min(min.Value, price.Value) : price;
|
|
max = max.HasValue ? Math.Max(max.Value, price.Value) : price;
|
|
}
|
|
|
|
if (min.HasValue || max.HasValue)
|
|
return (min, max);
|
|
}
|
|
|
|
return (null, null);
|
|
}
|
|
}
|
|
} |