Files
KJD/Store.Product/Publish/Steps/Wx/InitializeProductDataStep.cs
T
2026-09-14 09:16:59 +08:00

358 lines
13 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 AllBase;
using AllBase.Extension;
using NaiBa.Util.Extension;
using AllBase.Helper;
using AllBase.Model.Config;
using AllBase.Model.DBModel;
using AllBase.Model.Param.WXParam;
using AllBase.Model.Result;
using AllBase.Model.Result.PDDResult;
using AllBase.Model.Result.WXResult;
using MAX.Core.Helpers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Store.Product.Models.PublishParameters.Wx;
using Store.Product.Publish;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Work;
namespace Store.Product.Publish.Steps.Wx;
/// <summary>
/// 由 WXDBProdUploadForm.UploadProduct 的“初始化微信小店商品参数”区段迁移。
/// TODO(迁移): 原区段中的 TEMUKJD/WXUpload/窗体服务引用需按 Store.Product 运行时适配逐项核对。
/// </summary>
public sealed class InitializeProductDataStep : WxProductPublishStepBase
{
public override string Description => "初始化微信小店商品参数";
protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken)
{
context.Parameters.ProdJObject = new JObject();
try
{
context.Parameters.ProdJObject = JObject.Parse(context.Product.ProductJson);
var lstTitleReplaceText = new List<string>();
if (!context.Parameters.FilterWords.IsNullOrEmpty())
lstTitleReplaceText.AddRange(context.Parameters.FilterWords.Split(new string[] { ",", ",", " ", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries));
// 过滤标题敏感词
if (lstTitleReplaceText.Count > 0)
{
if (context.Parameters.IsSkipHasFilterWordsProd)
{
if (lstTitleReplaceText.Any(t => context.Product.Title.Contains(t)))
throw new Exception("命中敏感词");
var goods_name = context.Parameters.ProdJObject["detail"]["goods_name"].ParseToString();
if (lstTitleReplaceText.Any(t => goods_name.Contains(t)))
throw new Exception("命中敏感词");
var tiny_name = context.Parameters.ProdJObject["detail"]["tiny_name"].ParseToString();
if (lstTitleReplaceText.Any(t => tiny_name.Contains(t)))
throw new Exception("命中敏感词");
var goods_desc = context.Parameters.ProdJObject["detail"]["goods_desc"].ParseToString();
if (lstTitleReplaceText.Any(t => goods_desc.Contains(t)))
throw new Exception("命中敏感词");
var share_desc = context.Parameters.ProdJObject["detail"]["share_desc"].ParseToString();
if (lstTitleReplaceText.Any(t => share_desc.Contains(t)))
throw new Exception("命中敏感词");
}
else
{
foreach (var txt in lstTitleReplaceText)
{
context.Product.Title = context.Product.Title.Replace(txt, "");
}
var goods_name = context.Parameters.ProdJObject["detail"]["goods_name"].ParseToString();
foreach (var txt in lstTitleReplaceText)
{
goods_name = goods_name.Replace(txt, "");
}
context.Parameters.ProdJObject["detail"]["goods_name"] = goods_name;
var tiny_name = context.Parameters.ProdJObject["detail"]["tiny_name"].ParseToString();
foreach (var txt in lstTitleReplaceText)
{
tiny_name = tiny_name.Replace(txt, "");
}
context.Parameters.ProdJObject["detail"]["tiny_name"] = tiny_name;
var goods_desc = context.Parameters.ProdJObject["detail"]["goods_desc"].ParseToString();
foreach (var txt in lstTitleReplaceText)
{
goods_desc = goods_desc.Replace(txt, "");
}
context.Parameters.ProdJObject["detail"]["goods_desc"] = goods_desc;
var share_desc = context.Parameters.ProdJObject["detail"]["share_desc"].ParseToString();
foreach (var txt in lstTitleReplaceText)
{
share_desc = share_desc.Replace(txt, "");
}
context.Parameters.ProdJObject["detail"]["share_desc"] = share_desc;
}
}
// 过滤标题特殊字符
if (context.Parameters.IsRemoveSpecialChar)
{
var chLst = new List<char> { ']', '】', ')', ')', '}', };
foreach (var ch in chLst)
{
if (context.Product.Title.Contains(ch) && context.Product.Title.IndexOf(ch) < context.Product.Title.Length / 2 && context.Product.Title.Length > 10)
context.Product.Title = context.Product.Title.Substring(context.Product.Title.IndexOf(ch)).Trim(ch);
var goods_name = context.Parameters.ProdJObject["detail"]["goods_name"].ParseToString();
if (goods_name.Contains(ch) && goods_name.IndexOf(ch) < goods_name.Length / 2 && goods_name.Length > 10)
context.Parameters.ProdJObject["detail"]["goods_name"] = goods_name.Substring(goods_name.IndexOf(ch)).Trim(ch);
}
}
// 替换货号
if (!string.IsNullOrEmpty(context.Product.ExtCode))
context.Parameters.ProdJObject["detail"]["out_goods_sn"] = context.Product.ExtCode;
// 替换编辑过的sku
if (!string.IsNullOrEmpty(context.Product.SkuEditJson))
context.Parameters.ProdJObject["detail"]["sku"] = JArray.Parse(JsonHelper.SerializeObject(JsonHelper.DeserializeJsonToList<sku_item>(context.Product.SkuEditJson)));
// 过滤sku敏感词
if (lstTitleReplaceText.Count > 0)
{
var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray;
try
{
foreach (var skuJObj in skuJArr)
{
var specJArr = skuJObj["spec"] as JArray;
for (int i = 0; i < specJArr.Count; i++)
{
foreach (var txt in lstTitleReplaceText)
{
specJArr[i]["spec_name"] = specJArr[i]["spec_name"].ParseToString().Replace(txt, "");
}
}
}
}
catch (Exception ex)
{
throw new Exception("商品数据初始化失败" + ex.Message);
}
}
// 同颜色规格向上浮动同价格
if (context.Parameters.SameSpecSamePriceUp)
{
var priceTextLst = context.Product.PriceText.Split('-');
if (priceTextLst.Length != 2 || priceTextLst[0] != priceTextLst[1])
{
Dictionary<string, int> specPriceDic = new Dictionary<string, int>();
Dictionary<string, int> specMultiPriceDic = new Dictionary<string, int>();
var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray;
try
{
// 计算主spec的最高价
foreach (var skuJObj in skuJArr)
{
var specJArr = skuJObj["spec"] as JArray;
if (!specPriceDic.ContainsKey(specJArr[0]["spec_name"].ParseToString()) || skuJObj["price"].ParseToInt() > specPriceDic[specJArr[0]["spec_name"].ParseToString()])
{
specPriceDic[specJArr[0]["spec_name"].ParseToString()] = skuJObj["price"].ParseToInt();
}
if (!specMultiPriceDic.ContainsKey(specJArr[0]["spec_name"].ParseToString()) || skuJObj["multi_price"].ParseToInt() > specMultiPriceDic[specJArr[0]["spec_name"].ParseToString()])
{
specMultiPriceDic[specJArr[0]["spec_name"].ParseToString()] = skuJObj["multi_price"].ParseToInt();
}
}
// 统一按最高价设置
foreach (var skuJObj in skuJArr)
{
var specJArr = skuJObj["spec"] as JArray;
skuJObj["price"] = specPriceDic[specJArr[0]["spec_name"].ParseToString()];
skuJObj["multi_price"] = specMultiPriceDic[specJArr[0]["spec_name"].ParseToString()];
}
}
catch (Exception ex)
{
throw new Exception("商品数据初始化失败" + ex.Message);
}
}
}
// 同颜色规格向下浮动同价格
if (context.Parameters.SameSpecSamePriceDown)
{
var priceTextLst = context.Product.PriceText.Split('-');
if (priceTextLst.Length != 2 || priceTextLst[0] != priceTextLst[1])
{
Dictionary<string, int> specPriceDic = new Dictionary<string, int>();
Dictionary<string, int> specMultiPriceDic = new Dictionary<string, int>();
var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray;
try
{
// 计算主spec的最低价
foreach (var skuJObj in skuJArr)
{
var specJArr = skuJObj["spec"] as JArray;
if (!specPriceDic.ContainsKey(specJArr[0]["spec_name"].ParseToString()) || skuJObj["price"].ParseToInt() < specPriceDic[specJArr[0]["spec_name"].ParseToString()])
{
specPriceDic[specJArr[0]["spec_name"].ParseToString()] = skuJObj["price"].ParseToInt();
}
if (!specMultiPriceDic.ContainsKey(specJArr[0]["spec_name"].ParseToString()) || skuJObj["multi_price"].ParseToInt() < specMultiPriceDic[specJArr[0]["spec_name"].ParseToString()])
{
specMultiPriceDic[specJArr[0]["spec_name"].ParseToString()] = skuJObj["multi_price"].ParseToInt();
}
}
// 统一按最低价设置
foreach (var skuJObj in skuJArr)
{
var specJArr = skuJObj["spec"] as JArray;
skuJObj["price"] = specPriceDic[specJArr[0]["spec_name"].ParseToString()];
skuJObj["multi_price"] = specMultiPriceDic[specJArr[0]["spec_name"].ParseToString()];
}
}
catch (Exception ex)
{
throw new Exception("商品数据初始化失败" + ex.Message);
}
}
}
// 只保留最高价
if (context.Parameters.OnlyHighestPriceSku)
{
int price = 0;
var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray;
try
{
// 计算主spec的最高价
foreach (var skuJObj in skuJArr)
{
if (price < skuJObj["multi_price"].ParseToInt())
price = skuJObj["multi_price"].ParseToInt();
}
var product_json_tmp = JsonHelper.SerializeObject(context.Parameters.ProdJObject);
// 移除第一组所有sku
skuJArr.RemoveAll();
// 序列化第二组,从组中挑选符合价格条件的sku往第一组内填写
var prodJObj2 = JObject.Parse(product_json_tmp);
var skuJArr2 = prodJObj2["detail"]["sku"] as JArray;
foreach (var skuJObj2 in skuJArr2)
{
if (skuJObj2["multi_price"].ParseToInt() >= price)
skuJArr.Add(skuJObj2);
}
if (skuJArr.Count == 0)
{
throw new Exception("商品sku差价不满足上货条件,跳过");
}
}
catch (Exception ex)
{
throw new Exception("商品数据初始化失败" + ex.Message);
}
}
// 只保留最低价
if (context.Parameters.OnlyLowestPriceSku)
{
int price = 99999999;
var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray;
try
{
// 计算主spec的最低价
foreach (var skuJObj in skuJArr)
{
if (price > skuJObj["multi_price"].ParseToInt())
price = skuJObj["multi_price"].ParseToInt();
}
var product_json_tmp = JsonHelper.SerializeObject(context.Parameters.ProdJObject);
// 移除第一组所有sku
skuJArr.RemoveAll();
// 序列化第二组,从组中挑选符合价格条件的sku往第一组内填写
var prodJObj2 = JObject.Parse(product_json_tmp);
var skuJArr2 = prodJObj2["detail"]["sku"] as JArray;
foreach (var skuJObj2 in skuJArr2)
{
if (skuJObj2["multi_price"].ParseToInt() <= price)
skuJArr.Add(skuJObj2);
}
if (skuJArr.Count == 0)
{
throw new Exception("商品sku差价不满足上货条件,跳过");
}
}
catch (Exception ex)
{
throw new Exception("商品数据初始化失败" + ex.Message);
}
}
// 过滤低价sku,如果所有sku都不达标,跳过商品
if (context.Parameters.SkuMinPrice > 0)
{
var product_json_tmp = JsonHelper.SerializeObject(context.Parameters.ProdJObject);
// 移除第一组所有sku
var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray;
skuJArr.RemoveAll();
// 序列化第二组,从组中挑选符合价格条件的sku往第一组内填写
var prodJObj2 = JObject.Parse(product_json_tmp);
var skuJArr2 = prodJObj2["detail"]["sku"] as JArray;
foreach (var skuJObj2 in skuJArr2)
{
var limitMinPrice = context.Parameters.SkuMinPrice * 100;
// 供应商价加价10%(最低1元)赚取差价 先加价后过滤,过滤条件也要相应增加10%
//if (context.Product.ProductGetTypeText == "厂商直采")
// limitPrice += Math.Max(100m, limitPrice * 0.1m);
if (skuJObj2["multi_price"].ParseToInt() >= limitMinPrice)
skuJArr.Add(skuJObj2);
}
if (skuJArr.Count == 0)
{
throw new Exception("商品sku价格不满足上货条件,跳过");
}
}
// 过滤高价sku,如果所有sku都不达标,跳过商品
if (context.Parameters.SkuMaxPrice < int.MaxValue)
{
var product_json_tmp = JsonHelper.SerializeObject(context.Parameters.ProdJObject);
// 移除第一组所有sku
var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray;
skuJArr.RemoveAll();
// 序列化第二组,从组中挑选符合价格条件的sku往第一组内填写
var prodJObj2 = JObject.Parse(product_json_tmp);
var skuJArr2 = prodJObj2["detail"]["sku"] as JArray;
foreach (var skuJObj2 in skuJArr2)
{
var limitMaxPrice = context.Parameters.SkuMaxPrice * 100;
// 供应商价加价10%(最低1元)赚取差价 先加价后过滤,过滤条件也要相应增加10%
//if (context.Product.ProductGetTypeText == "厂商直采")
// limitPrice += Math.Max(100m, limitPrice * 0.1m);
if (skuJObj2["multi_price"].ParseToInt() <= limitMaxPrice)
skuJArr.Add(skuJObj2);
}
if (skuJArr.Count == 0)
{
throw new Exception("商品sku价格不满足上货条件,跳过");
}
}
context.Product.ProductJson = JsonHelper.SerializeObject(context.Parameters.ProdJObject);
}
catch (Exception ex)
{
throw new Exception("商品数据初始化失败" + ex.Message);
}
return Task.CompletedTask;
}
}