修复 wx 外采 V2 转换器
This commit is contained in:
1 parent
ff3ee89383
commit
184f1984ca
1 file changed
+159
-21
@@ -14,6 +14,9 @@ namespace TemuKJD.BLL.ImportConverters
|
||||
{
|
||||
/// <summary>
|
||||
/// 微信小商店(新版商品详情接口)转拼多多数据源
|
||||
/// 对应示例:title / subTitle / headImg / category / param / brandId /
|
||||
/// skuIdList / skuList.skuInfo / detail.detailImg / expressInfo 等字段
|
||||
/// 与 V1(out_product_id / skus / cats_v2 / head_imgs / attrs / extra_service 等下划线字段)格式不同
|
||||
/// </summary>
|
||||
internal class ConverterWXToPddV2 : GoodsConverterBase
|
||||
{
|
||||
@@ -22,10 +25,7 @@ namespace TemuKJD.BLL.ImportConverters
|
||||
public override string ConverterName => "微信转拼多多数据源V2";
|
||||
|
||||
public override PlatformType Platform => PlatformType.WX;
|
||||
protected override void ReadContent(string filePath)
|
||||
{
|
||||
base.ReadContent(filePath);
|
||||
}
|
||||
|
||||
|
||||
protected override bool IsMatchProvider()
|
||||
{
|
||||
@@ -247,12 +247,12 @@ namespace TemuKJD.BLL.ImportConverters
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从单个SKU节点中提取规格键值对(部分商品SKU不含规格属性,此时返回空列表)
|
||||
/// 兼容多种可能出现的字段名
|
||||
/// 从单个SKU节点中提取规格键值对(兼容极少数直接把属性挂在sku节点上的情况)
|
||||
/// 正常情况下规格信息在顶层的 productSaleAttrs 中,见 BuildSkuIdToAttrsMap
|
||||
/// </summary>
|
||||
private Dictionary<string,string> GetSkuAttrPairs(JToken sku)
|
||||
private List<KeyValuePair<string, string>> GetSkuAttrPairs(JToken sku)
|
||||
{
|
||||
var result = new Dictionary<string, string>();
|
||||
var result = new List<KeyValuePair<string, string>>();
|
||||
|
||||
JArray attrArray = sku["skuAttrs"] as JArray
|
||||
?? sku["attrs"] as JArray
|
||||
@@ -269,14 +269,96 @@ namespace TemuKJD.BLL.ImportConverters
|
||||
var value = attr["attrValue"]?.Value<string>() ?? attr["value"]?.Value<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
|
||||
result.Add(key, value);
|
||||
result.Add(new KeyValuePair<string, string>(key, value));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取SKU(skuList.skuInfo)
|
||||
/// 从顶层 productSaleAttrs 构建 skuId -> [(规格名,规格值)] 的映射
|
||||
/// productSaleAttrs 结构:[{ "key":"型号", "items":[{ "value":"xxx", "imgUrl":"xxx", "skuIds":["xxx"] }] }]
|
||||
/// </summary>
|
||||
private Dictionary<string, List<KeyValuePair<string, string>>> BuildSkuIdToAttrsMap(JObject jsonData)
|
||||
{
|
||||
var map = new Dictionary<string, List<KeyValuePair<string, string>>>();
|
||||
var saleAttrs = jsonData["productSaleAttrs"] as JArray;
|
||||
if (saleAttrs == null)
|
||||
return map;
|
||||
|
||||
foreach (var attr in saleAttrs)
|
||||
{
|
||||
var key = attr["key"]?.Value<string>();
|
||||
var items = attr["items"] as JArray;
|
||||
if (string.IsNullOrEmpty(key) || items == null)
|
||||
continue;
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
var value = item["value"]?.Value<string>();
|
||||
var skuIds = item["skuIds"] as JArray;
|
||||
if (string.IsNullOrEmpty(value) || skuIds == null)
|
||||
continue;
|
||||
|
||||
foreach (var skuIdToken in skuIds)
|
||||
{
|
||||
var skuId = skuIdToken?.Value<string>();
|
||||
if (string.IsNullOrEmpty(skuId))
|
||||
continue;
|
||||
|
||||
if (!map.TryGetValue(skuId, out var list))
|
||||
{
|
||||
list = new List<KeyValuePair<string, string>>();
|
||||
map[skuId] = list;
|
||||
}
|
||||
list.Add(new KeyValuePair<string, string>(key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从顶层 productSaleAttrs 构建 skuId -> 规格图片(imgUrl) 的映射
|
||||
/// </summary>
|
||||
private Dictionary<string, string> BuildSkuIdToSpecImageMap(JObject jsonData)
|
||||
{
|
||||
var map = new Dictionary<string, string>();
|
||||
var saleAttrs = jsonData["productSaleAttrs"] as JArray;
|
||||
if (saleAttrs == null)
|
||||
return map;
|
||||
|
||||
foreach (var attr in saleAttrs)
|
||||
{
|
||||
var items = attr["items"] as JArray;
|
||||
if (items == null)
|
||||
continue;
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
var imgUrl = item["imgUrl"]?.Value<string>();
|
||||
var skuIds = item["skuIds"] as JArray;
|
||||
if (string.IsNullOrEmpty(imgUrl) || skuIds == null)
|
||||
continue;
|
||||
|
||||
foreach (var skuIdToken in skuIds)
|
||||
{
|
||||
var skuId = skuIdToken?.Value<string>();
|
||||
if (string.IsNullOrEmpty(skuId))
|
||||
continue;
|
||||
|
||||
if (!map.ContainsKey(skuId))
|
||||
map[skuId] = imgUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取SKU(skuList.skuInfo),规格信息优先取自顶层 productSaleAttrs
|
||||
/// </summary>
|
||||
private List<SkuItem> GetSkusFromNewFormat(JObject jsonData)
|
||||
{
|
||||
@@ -286,9 +368,20 @@ namespace TemuKJD.BLL.ImportConverters
|
||||
if (skus == null)
|
||||
return result;
|
||||
|
||||
var skuIdToAttrsMap = BuildSkuIdToAttrsMap(jsonData);
|
||||
var skuIdToSpecImageMap = BuildSkuIdToSpecImageMap(jsonData);
|
||||
|
||||
foreach (var sku in skus)
|
||||
{
|
||||
var attrPairs = GetSkuAttrPairs(sku);
|
||||
var skuId = sku["skuId"]?.Value<string>() ?? "";
|
||||
|
||||
// 优先使用 productSaleAttrs 中按 skuId 匹配到的规格,取不到时兼容旧字段
|
||||
List<KeyValuePair<string, string>> attrPairs;
|
||||
if (!string.IsNullOrEmpty(skuId) && skuIdToAttrsMap.TryGetValue(skuId, out var mappedPairs))
|
||||
attrPairs = mappedPairs;
|
||||
else
|
||||
attrPairs = GetSkuAttrPairs(sku);
|
||||
|
||||
var specValues = attrPairs.Select(a => $"{a.Key}:{a.Value}").ToList();
|
||||
|
||||
// price 单位为分,需要转换为元
|
||||
@@ -297,14 +390,21 @@ namespace TemuKJD.BLL.ImportConverters
|
||||
|
||||
var originPriceInCents = sku["originPrice"]?.Value<decimal>() ?? priceInCents;
|
||||
|
||||
string specImage = null;
|
||||
if (!string.IsNullOrEmpty(skuId))
|
||||
skuIdToSpecImageMap.TryGetValue(skuId, out specImage);
|
||||
|
||||
result.Add(new SkuItem
|
||||
{
|
||||
SkuId = sku["skuId"]?.Value<string>() ?? "",
|
||||
SkuId = skuId,
|
||||
Spec = string.Join(";", specValues),
|
||||
Price = priceInYuan,
|
||||
OriginalPrice = originPriceInCents.ToString(), // 保留原始价格(分)
|
||||
Stock = sku["stockNum"]?.Value<int>() ?? 999, // 无库存字段时使用默认值
|
||||
SpecImage = sku["thumbImg"]?.Value<string>() ?? sku["skuImg"]?.Value<string>() ?? ""
|
||||
SpecImage = specImage
|
||||
?? sku["thumbImg"]?.Value<string>()
|
||||
?? sku["skuImg"]?.Value<string>()
|
||||
?? ""
|
||||
});
|
||||
}
|
||||
|
||||
@@ -312,13 +412,49 @@ namespace TemuKJD.BLL.ImportConverters
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取规格(从skuList.skuInfo中的规格属性汇总去重,若商品无规格属性则返回空列表)
|
||||
/// 获取规格:优先从顶层 productSaleAttrs 汇总(key为规格名,items[].value为规格值),
|
||||
/// 若不存在该字段则退回从每个SKU自身属性字段中提取(兼容旧/异形数据)
|
||||
/// </summary>
|
||||
private List<SpecItem> GetSpecsFromNewFormat(JObject jsonData)
|
||||
{
|
||||
var result = new List<SpecItem>();
|
||||
var skus = jsonData.SelectToken("$.skuList.skuInfo") as JArray;
|
||||
var saleAttrs = jsonData["productSaleAttrs"] as JArray;
|
||||
|
||||
if (saleAttrs != null && saleAttrs.Count > 0)
|
||||
{
|
||||
foreach (var attr in saleAttrs)
|
||||
{
|
||||
var key = attr["key"]?.Value<string>();
|
||||
var items = attr["items"] as JArray;
|
||||
if (string.IsNullOrEmpty(key) || items == null)
|
||||
continue;
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
var value = item["value"]?.Value<string>();
|
||||
if (string.IsNullOrEmpty(value))
|
||||
continue;
|
||||
|
||||
// 去重
|
||||
if (result.Any(x => x.SpecKey == key && x.SpecValue == value))
|
||||
continue;
|
||||
|
||||
result.Add(new SpecItem
|
||||
{
|
||||
SpecKey = key,
|
||||
SpecValue = value,
|
||||
SpecKeyId = 0, // 该格式中没有ID
|
||||
SpecValueId = 0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (result.Count > 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
// 兼容处理:没有 productSaleAttrs 时,尝试从每个SKU自身属性字段中提取
|
||||
var skus = jsonData.SelectToken("$.skuList.skuInfo") as JArray;
|
||||
if (skus == null)
|
||||
return result;
|
||||
|
||||
@@ -326,17 +462,19 @@ namespace TemuKJD.BLL.ImportConverters
|
||||
{
|
||||
var attrPairs = GetSkuAttrPairs(sku);
|
||||
|
||||
foreach (var item in attrPairs)
|
||||
foreach (var pair in attrPairs)
|
||||
{
|
||||
// 去重
|
||||
if (result.Any(x => x.SpecKey == item.Key && x.SpecValue == item.Value))
|
||||
var key = pair.Key;
|
||||
var value = pair.Value;
|
||||
|
||||
if (result.Any(x => x.SpecKey == key && x.SpecValue == value))
|
||||
continue;
|
||||
|
||||
result.Add(new SpecItem
|
||||
{
|
||||
SpecKey = item.Key,
|
||||
SpecValue = item.Value,
|
||||
SpecKeyId = 0, // 该格式中没有ID
|
||||
SpecKey = key,
|
||||
SpecValue = value,
|
||||
SpecKeyId = 0,
|
||||
SpecValueId = 0
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user