315 lines
7.8 KiB
C#
315 lines
7.8 KiB
C#
using AllBase.Model.Result;
|
|
using AllBase.Model.Result.PDDResult;
|
|
using NaiBa.Util.Extension;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace TemuKJD.BLL.ImportConverters
|
|
{
|
|
internal class ConverterWXToPddV1 : GoodsConverterBase
|
|
{
|
|
private JObject jsonRoot;
|
|
|
|
public override string ConverterName => "微信转拼多多数据源";
|
|
|
|
public override PlatformType Platform => PlatformType.WX;
|
|
|
|
|
|
protected override bool IsMatchProvider()
|
|
{
|
|
try
|
|
{
|
|
jsonRoot = JsonConvert.DeserializeObject<JObject>(RawData);
|
|
if (jsonRoot == null) return false;
|
|
|
|
// 1. 检查 extra_service 是否存在且为对象类型
|
|
var extraService = jsonRoot.SelectToken("$.extra_service");
|
|
if (extraService == null || extraService.Type != JTokenType.Object) return false;
|
|
|
|
// 2. 检查 out_product_id 是否存在且为字符串类型(非空)
|
|
var outProductId = jsonRoot.SelectToken("$.out_product_id")?.ToString();
|
|
if (string.IsNullOrEmpty(outProductId)) return false;
|
|
|
|
// 3. 检查 skus 是否存在且为数组,且第一个元素包含 out_sku_id
|
|
var skus = jsonRoot.SelectToken("$.skus");
|
|
if (skus == null) return true;
|
|
if (skus.Type != JTokenType.Array) return false;
|
|
var skusArray = skus as JArray;
|
|
if (skusArray.Count == 0) return true;
|
|
|
|
var outSkuId = skusArray[0]?.SelectToken("$.out_sku_id")?.ToString();
|
|
if (string.IsNullOrEmpty(outSkuId)) return false;
|
|
|
|
// 三个条件全部通过
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
protected override PDDFrontProductInfo5 ConverterProvider()
|
|
{
|
|
var product = new PDDFrontProductInfo5();
|
|
|
|
product.Platform = Platform;
|
|
// 解析JSON数据
|
|
var jsonData = JsonConvert.DeserializeObject<JObject>(RawData);
|
|
product.GoodsId = Path.GetFileNameWithoutExtension(FilePath).ParseToLong();
|
|
// 商品基本信息
|
|
product.Title = jsonData["title"]?.Value<string>() ?? "";
|
|
product.Description = jsonData["short_title"]?.Value<string>() ?? "";
|
|
|
|
// 品牌ID - 转换为long
|
|
product.BrandId = jsonData["brand_id"]?.Value<long>() ?? 0;
|
|
|
|
// 类目信息
|
|
product.CategoryId = GetCategoryIdFromCats(jsonData);
|
|
product.CategoryPath = GetCategoryPathFromCats(jsonData);
|
|
|
|
// 主图
|
|
product.MainImages = GetMainImagesFromNewFormat(jsonData);
|
|
|
|
// 详情图
|
|
product.DetailImages = GetDetailImagesFromNewFormat(jsonData);
|
|
|
|
// 商品属性
|
|
product.Propertys = GetPropertiesFromNewFormat(jsonData);
|
|
|
|
// SKU和规格信息
|
|
product.Skus = GetSkusFromNewFormat(jsonData);
|
|
product.Specs = GetSpecsFromNewFormat(jsonData);
|
|
|
|
// 其他默认值
|
|
product.ThumbUrl = jsonData["head_imgs"]?[0]?.Value<string>() ?? "";
|
|
product.MallId = 0; // 新格式中没有mallID
|
|
product.Price = GetMinPrice(jsonData); // 从SKU中获取最低价
|
|
product.Videos = new List<string>(); // 新格式中没有视频信息
|
|
|
|
return product;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 从cats_v2中获取类目ID
|
|
/// </summary>
|
|
private int GetCategoryIdFromCats(JObject jsonData)
|
|
{
|
|
var cats = jsonData["cats_v2"] as JArray;
|
|
if (cats == null || cats.Count == 0)
|
|
return 0;
|
|
|
|
// 获取最后一个类目(最细分类目)
|
|
var lastCat = cats.Last;
|
|
return lastCat?["cat_id"]?.Value<int>() ?? 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 从cats_v2中获取类目路径
|
|
/// </summary>
|
|
private List<int> GetCategoryPathFromCats(JObject jsonData)
|
|
{
|
|
var result = new List<int>();
|
|
var cats = jsonData["cats_v2"] as JArray;
|
|
|
|
if (cats == null)
|
|
return result;
|
|
|
|
foreach (var cat in cats)
|
|
{
|
|
var catId = cat["cat_id"]?.Value<int>();
|
|
if (catId.HasValue && catId.Value > 0)
|
|
result.Add(catId.Value);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取主图(新格式)
|
|
/// </summary>
|
|
private List<string> GetMainImagesFromNewFormat(JObject jsonData)
|
|
{
|
|
var result = new List<string>();
|
|
var headImgs = jsonData["head_imgs"] as JArray;
|
|
|
|
if (headImgs == null)
|
|
return result;
|
|
|
|
foreach (var img in headImgs)
|
|
{
|
|
var url = img?.Value<string>();
|
|
if (!string.IsNullOrEmpty(url))
|
|
result.Add(url);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取详情图(新格式)
|
|
/// </summary>
|
|
private List<string> GetDetailImagesFromNewFormat(JObject jsonData)
|
|
{
|
|
var result = new List<string>();
|
|
var descInfo = jsonData["desc_info"];
|
|
|
|
if (descInfo == null)
|
|
return result;
|
|
|
|
var imgs = descInfo["imgs"] as JArray;
|
|
if (imgs == null)
|
|
return result;
|
|
|
|
foreach (var img in imgs)
|
|
{
|
|
var url = img?.Value<string>();
|
|
if (!string.IsNullOrEmpty(url))
|
|
result.Add(url);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取商品属性(新格式)
|
|
/// </summary>
|
|
private List<Property> GetPropertiesFromNewFormat(JObject jsonData)
|
|
{
|
|
var result = new List<Property>();
|
|
var attrs = jsonData["attrs"] as JArray;
|
|
|
|
if (attrs == null)
|
|
return result;
|
|
|
|
foreach (var attr in attrs)
|
|
{
|
|
var key = attr["attr_key"]?.Value<string>();
|
|
var value = attr["attr_value"]?.Value<string>();
|
|
|
|
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
|
|
{
|
|
result.Add(new Property
|
|
{
|
|
Key = key,
|
|
Value = value
|
|
});
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取SKU(新格式)
|
|
/// </summary>
|
|
private List<SkuItem> GetSkusFromNewFormat(JObject jsonData)
|
|
{
|
|
var result = new List<SkuItem>();
|
|
var skus = jsonData["skus"] as JArray;
|
|
|
|
if (skus == null)
|
|
return result;
|
|
|
|
foreach (var sku in skus)
|
|
{
|
|
var skuAttrs = sku["sku_attrs"] as JArray;
|
|
var specValues = new List<string>();
|
|
|
|
if (skuAttrs != null)
|
|
{
|
|
foreach (var attr in skuAttrs)
|
|
{
|
|
var key = attr["attr_key"]?.Value<string>();
|
|
var value = attr["attr_value"]?.Value<string>();
|
|
|
|
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
|
|
specValues.Add($"{key}:{value}");
|
|
}
|
|
}
|
|
|
|
// sale_price 是分,需要转换为元
|
|
var salePriceInCents = sku["sale_price"]?.Value<decimal>() ?? 0;
|
|
var salePriceInYuan = salePriceInCents / 100;
|
|
|
|
result.Add(new SkuItem
|
|
{
|
|
SkuId = sku["out_sku_id"]?.Value<string>() ?? "",
|
|
Spec = string.Join(";", specValues),
|
|
Price = salePriceInYuan,
|
|
OriginalPrice = salePriceInCents.ToString(), // 保留原始价格(分)
|
|
Stock = 999, // 新格式中没有库存,设置默认值
|
|
SpecImage = sku["thumb_img"]?.Value<string>() ?? ""
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取规格(新格式)
|
|
/// </summary>
|
|
private List<SpecItem> GetSpecsFromNewFormat(JObject jsonData)
|
|
{
|
|
var result = new List<SpecItem>();
|
|
var skus = jsonData["skus"] as JArray;
|
|
|
|
if (skus == null)
|
|
return result;
|
|
|
|
foreach (var sku in skus)
|
|
{
|
|
var skuAttrs = sku["sku_attrs"] as JArray;
|
|
if (skuAttrs == null)
|
|
continue;
|
|
|
|
foreach (var attr in skuAttrs)
|
|
{
|
|
var specKey = attr["attr_key"]?.Value<string>() ?? "";
|
|
var specValue = attr["attr_value"]?.Value<string>() ?? "";
|
|
|
|
// 去重
|
|
if (result.Any(x => x.SpecKey == specKey && x.SpecValue == specValue))
|
|
continue;
|
|
|
|
result.Add(new SpecItem
|
|
{
|
|
SpecKey = specKey,
|
|
SpecValue = specValue,
|
|
SpecKeyId = 0, // 新格式中没有ID
|
|
SpecValueId = 0
|
|
});
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取最低价格
|
|
/// </summary>
|
|
private decimal GetMinPrice(JObject jsonData)
|
|
{
|
|
var skus = jsonData["skus"] as JArray;
|
|
if (skus == null || skus.Count == 0)
|
|
return 0;
|
|
|
|
var minPrice = decimal.MaxValue;
|
|
foreach (var sku in skus)
|
|
{
|
|
var price = sku["sale_price"]?.Value<decimal>() ?? 0;
|
|
if (price > 0 && price < minPrice)
|
|
minPrice = price;
|
|
}
|
|
|
|
return minPrice > 0 ? minPrice / 100 : 0; // 转换为元
|
|
}
|
|
}
|
|
}
|