From c2dcedd238d00b3670b3cc55a289ede60b3278cc Mon Sep 17 00:00:00 2001 From: Chfei Date: Sat, 12 Sep 2026 15:00:11 +0800 Subject: [PATCH] gx --- Store.Product/Class1.cs | 3 +- Store.Product/Models/Product/ProductBase.cs | 346 ++++++++++------ Store.Product/Publish/PublishContext .cs | 4 +- Store.Product/Publish/PublishPipeline.cs | 7 +- .../Publish/Steps/CheckProductPropertyStep.cs | 2 +- .../Publish/Steps/DetailStep/CheckPrice.cs | 2 +- .../Publish/Steps/WXPublishParameters.cs | 371 +++++++++++++++++- .../Steps/Wx/AddRandomImageBorderStep.cs | 49 +-- .../Publish/Steps/Wx/AddTitlePrefixStep.cs | 7 +- .../Publish/Steps/Wx/BuildSkuInfoStep.cs | 88 ++--- .../Steps/Wx/BuildSkuPropertiesStep.cs | 105 ++--- .../Steps/Wx/CalculateShippingTemplateStep.cs | 38 +- .../Steps/Wx/CommissionPreparationStep.cs | 132 +++---- .../Publish/Steps/Wx/CompatibilityServices.cs | 55 +++ .../Steps/Wx/Convert1688ProductStep.cs | 11 +- .../Steps/Wx/ConvertCloudProductStep.cs | 9 +- .../Steps/Wx/ConvertJstPddProductStep.cs | 11 +- .../Steps/Wx/ConvertWxAppProductStep.cs | 7 +- .../Steps/Wx/ConvertWxRecycleProductStep.cs | 11 +- .../Steps/Wx/ConvertWxShopProductStep.cs | 7 +- .../Publish/Steps/Wx/DetectCategoryStep.cs | 45 +-- .../Publish/Steps/Wx/FillMainImagesStep.cs | 21 +- .../Steps/Wx/FilterDuplicateImagesStep.cs | 33 +- .../Publish/Steps/Wx/FissionTitleStep.cs | 15 +- .../Steps/Wx/GenerateAiProductImageStep.cs | 29 +- .../Steps/Wx/GenerateAiShortTitleStep.cs | 23 +- .../Steps/Wx/GenerateCategoryTemplateStep.cs | 87 ++-- .../Publish/Steps/Wx/GetShopApiTokenStep.cs | 27 +- .../Steps/Wx/GetShopShippingTemplateStep.cs | 22 +- .../Steps/Wx/InitializeProductDataStep.cs | 116 +++--- .../Steps/Wx/InitializeUploadProductStep.cs | 6 +- .../Steps/Wx/MatchProductPropertiesStep.cs | 133 +++---- .../Steps/Wx/PrepareHotlinkImageMapStep.cs | 15 +- .../Steps/Wx/PrepareSourceProductStep.cs | 17 +- .../Wx/RestoreWxShopSourceProductStep.cs | 9 +- .../Steps/Wx/SaveDetailImageHotlinkMapStep.cs | 11 +- .../Steps/Wx/SaveDraftHotlinkMapStep.cs | 11 +- .../Steps/Wx/SaveMainImageHotlinkMapStep.cs | 11 +- .../Publish/Steps/Wx/SaveSkuHotlinkMapStep.cs | 11 +- .../Publish/Steps/Wx/SetAfterSaleInfoStep.cs | 57 +-- .../Publish/Steps/Wx/SetCommissionInfoStep.cs | 15 +- .../Publish/Steps/Wx/SetPreSaleInfoStep.cs | 13 +- .../Publish/Steps/Wx/SetProductExtCodeStep.cs | 19 +- .../Publish/Steps/Wx/SetProductTitleStep.cs | 15 +- .../Wx/SetQualificationsAndTagImagesStep.cs | 128 +++--- .../Steps/Wx/SkipUploadedProductStep.cs | 19 +- .../Steps/Wx/SubmitProductDraftStep.cs | 52 +-- .../Publish/Steps/Wx/SubmitProductStep.cs | 143 +++---- .../Steps/Wx/UploadDetailImagesStep.cs | 67 ++-- .../Publish/Steps/Wx/UploadMainImagesStep.cs | 77 ++-- .../Publish/Steps/Wx/UploadVideoStep.cs | 70 +--- Store.Product/Publish/Steps/Wx/WXUpload.cs | 51 +++ Store.Product/Publish/Steps/Wx/WxApiBLL.cs | 62 +++ .../Steps/Wx/WxProductPublishStepBase.cs | 293 ++++++-------- Store.Product/Store.Product.csproj | 5 +- TEMUKJD/KJD.csproj | 1 + .../WXDBProdUploadForm.Designer.cs | 106 ++--- .../ProductForms/WXDBProdUploadForm.cs | 155 +++++++- .../ProductForms/WXDBProdUploadForm.resx | 72 ++++ 59 files changed, 2053 insertions(+), 1274 deletions(-) create mode 100644 Store.Product/Publish/Steps/Wx/CompatibilityServices.cs create mode 100644 Store.Product/Publish/Steps/Wx/WXUpload.cs create mode 100644 Store.Product/Publish/Steps/Wx/WxApiBLL.cs diff --git a/Store.Product/Class1.cs b/Store.Product/Class1.cs index 1cc5854..94c12c4 100644 --- a/Store.Product/Class1.cs +++ b/Store.Product/Class1.cs @@ -1,4 +1,5 @@ -using Store.Product.Publish.Steps.Wx; +using Store.Product.Models.Product; +using Store.Product.Publish.Steps.Wx; namespace Store.Product; diff --git a/Store.Product/Models/Product/ProductBase.cs b/Store.Product/Models/Product/ProductBase.cs index 5671271..0d8d237 100644 --- a/Store.Product/Models/Product/ProductBase.cs +++ b/Store.Product/Models/Product/ProductBase.cs @@ -7,133 +7,237 @@ using System.Threading.Tasks; namespace Store.Product.Models.Product; - /// - /// 商品属性基类 - /// - public class ProductBase - { - private string _gid = Guid.NewGuid().ToString(); - /// - /// 唯一ID - /// - public string Gid - { - get - { - return _gid; - } - } - /// - /// 商品ID - /// - public long Id { get; set; } - /// - /// 标题 - /// - public string Title { get; set; } +/// +/// 商品属性基类 +/// +public class ProductBase +{ + private string _gid = Guid.NewGuid().ToString(); + /// + /// 唯一ID + /// + public string Gid + { + get + { + return _gid; + } + } + /// + /// 商品ID + /// + public long Id { get; set; } + /// + /// 标题 + /// + public string Title { get; set; } - /// - /// 商铺名称 - /// - public string ShopName { get; set; } - /// - /// 类目ID - /// - public int CategoryId { get; set; } + /// + /// 商铺名称 + /// + public string ShopName { get; set; } + /// + /// 类目ID + /// + public int CategoryId { get; set; } - /// - /// 销售数量 - /// - public int SaleCount { get; set; } - /// - /// 库存数量 - /// - public int StockCount { get; set; } - /// - /// 价格 - /// - public decimal Price { get; set; } - /// - /// 以前价格 | 划线价格 - /// - public decimal BeforePrice { get; set; } - /// - /// 邮费 - /// - public decimal ExpressPrice { get; set; } - /// - /// 折扣 - /// - public decimal Discount { get; set; } - /// - /// 折扣价格 - /// - public decimal DiscountPrice { get; set; } - /// - /// 在线价格 - /// - public decimal OnlinePrice { get; set; } - /// - /// 市场价格 - /// - public decimal MarketPrice { get; set; } - /// - /// 主图 - /// - public string MainImage { get; set; } + /// + /// 销售数量 + /// + public int SaleCount { get; set; } + /// + /// 库存数量 + /// + public int StockCount { get; set; } + /// + /// 价格 + /// + public decimal Price { get; set; } + /// + /// 以前价格 | 划线价格 + /// + public decimal BeforePrice { get; set; } + /// + /// 邮费 + /// + public decimal ExpressPrice { get; set; } + /// + /// 折扣 + /// + public decimal Discount { get; set; } + /// + /// 折扣价格 + /// + public decimal DiscountPrice { get; set; } + /// + /// 在线价格 + /// + public decimal OnlinePrice { get; set; } + /// + /// 市场价格 + /// + public decimal MarketPrice { get; set; } + /// + /// 主图 + /// + public string MainImage { get; set; } - /// - /// 品牌 - /// - public string ShopBrand { get; set; } - /// - /// 是否是促销品 - /// - public bool IsPromotion { get; set; } + /// + /// 品牌 + /// + public string ShopBrand { get; set; } + /// + /// 是否是促销品 + /// + public bool IsPromotion { get; set; } - /// - /// 省 - /// - public string State { get; set; } - /// - /// 市 - /// - public string City { get; set; } - /// - /// 内容 - /// - public ProductContent Content { get; set; } = new ProductContent(""); - /// - /// 来源地址 - /// - public virtual string SourceUrl { get; set; } + /// + /// 省 + /// + public string State { get; set; } + /// + /// 市 + /// + public string City { get; set; } + /// + /// 内容 + /// + public ProductContent Content { get; set; } = new ProductContent(""); + /// + /// 来源地址 + /// + public virtual string SourceUrl { get; set; } + /// + /// 来源平台 + /// + public string SourcePlatform { get; set; } - /// - /// 商品主图视频Id - /// - public long VideoId { get; set; } - /// - /// 重量 - /// - public int Weight { get; set; } + /// + /// 商品主图视频Id + /// + public long VideoId { get; set; } + /// + /// 重量 + /// + public int Weight { get; set; } - /// - /// 商品特性 - /// - public ProductPropertys Propertys { get; set; } = new ProductPropertys(); + /// + /// 商品特性 + /// + public ProductPropertys Propertys { get; set; } = new ProductPropertys(); - /// - /// SKU 属性值 - /// - public SkuPropertys SkuProperty { get; set; } = new SkuPropertys(); + /// + /// SKU 属性值 + /// + public SkuPropertys SkuProperty { get; set; } = new SkuPropertys(); - /// - /// Sku 属性映射 - /// - public SkuMaps SkuMaps { get; set; } = new SkuMaps(); - /// - /// 主图列表 - /// - public MainImageCollection MainImages { get; set; } = new MainImageCollection(); + /// + /// Sku 属性映射 + /// + public SkuMaps SkuMaps { get; set; } = new SkuMaps(); + /// + /// 主图列表 + /// + public MainImageCollection MainImages { get; set; } = new MainImageCollection(); - } + + #region 由 KJDDBProduct 迁移新增的属性 + /// + /// 新增:来源店铺ID。 + /// + public string FromShopId { get; set; } + /// + /// 新增:商品SPU ID。 + /// + public string SpuId { get; set; } + /// + /// 新增:SKC ID;聚水潭为商家coid。 + /// + public string SkcId { get; set; } + /// + /// 新增:聚水潭爆款专区真实商家coid;供应商直采商品为空。 + /// + public string RealCoid { get; set; } + /// + /// 新增:外部商品编号。 + /// + public string ExtCode { get; set; } + /// + /// 新增:加密商品ID,对应聚水潭加密商品编号goodsId。 + /// + public string SecretSpuId { get; set; } + /// + /// 新增:来源商品JSON。 + /// + public string ProductJson { get; set; } + /// + /// 新增:SKU编辑后的JSON。 + /// + public string SkuEditJson { get; set; } + /// + /// 新增:SKU密钥JSON。 + /// + public string SkuSecretJson { get; set; } + /// + /// 新增:微信图片映射JSON。 + /// + public string WxImgMapJson { get; set; } + /// + /// 新增:商品来源类型名称。 + /// + public string ProductGetTypeText { get; set; } + /// + /// 新增:数据库类型。 + /// + public string DbType { get; set; } + /// + /// 新增:特殊商品类型。 + /// + public string SpecialProdType { get; set; } + /// + /// 新增:是否存在微信回采格式数据。 + /// + public string HasWxFormat { get; set; } + /// + /// 新增:微信安全状态。 + /// + public string WxSafeStatus { get; set; } + /// + /// 新增:价格文本。 + /// + public string PriceText { get; set; } + /// + /// 新增:主类目名称。 + /// + public string MainCatName { get; set; } + /// + /// 新增:添加用户名。 + /// + public string AddUserName { get; set; } + /// + /// 新增:微信一级类目ID。 + /// + public long? WxCat1 { get; set; } + /// + /// 新增:微信二级类目ID。 + /// + public long? WxCat2 { get; set; } + /// + /// 新增:微信三级类目ID。 + /// + public long? WxCat3 { get; set; } + /// + /// 新增:微信叶子类目ID。 + /// + public long? WxCatLeaf { get; set; } + /// + /// 新增:是否发送到外部服务。 + /// + public int? SendToOutServer { get; set; } + /// + /// 新增:分销设置。 + /// + public int? DistributionSet { get; set; } + #endregion + +} diff --git a/Store.Product/Publish/PublishContext .cs b/Store.Product/Publish/PublishContext .cs index da9bc3f..11b1d7b 100644 --- a/Store.Product/Publish/PublishContext .cs +++ b/Store.Product/Publish/PublishContext .cs @@ -39,6 +39,6 @@ public class PublishContextBase public WXPublishParameters Parameters { get; set; } = new WXPublishParameters(); - /// 微信小店商品上传的新上下文参数。 - public WxProductUploadParam WxUpload { get; set; } = new WxProductUploadParam(); + /// WxUpload 参数已合并到 Parameters,保留注释用于迁移对照。 + //public WxProductUploadParam WxUpload { get; set; } = new WxProductUploadParam(); } \ No newline at end of file diff --git a/Store.Product/Publish/PublishPipeline.cs b/Store.Product/Publish/PublishPipeline.cs index 7491788..7af6423 100644 --- a/Store.Product/Publish/PublishPipeline.cs +++ b/Store.Product/Publish/PublishPipeline.cs @@ -31,12 +31,17 @@ public class PublishPipeline where TContext : PublishContextBase } // 步骤正常提前结束(提交成功/上传到草稿箱)时会写入 Result 并标记完成,此处跳出后续步骤。 - if (context.WxUpload?.IsCompleted == true) + if (context.Parameters?.IsCompleted == true) { break; } } } + catch (Store.Product.Publish.Steps.Wx.PublishCompletedException ex) + { + context.Parameters.Result = ex.Result; + context.Parameters.IsCompleted = true; + } catch (OperationCanceledException) { throw; diff --git a/Store.Product/Publish/Steps/CheckProductPropertyStep.cs b/Store.Product/Publish/Steps/CheckProductPropertyStep.cs index 022dd23..32571c1 100644 --- a/Store.Product/Publish/Steps/CheckProductPropertyStep.cs +++ b/Store.Product/Publish/Steps/CheckProductPropertyStep.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Store.Product.Publish.Steps; -public class CheckProductPropertyStep : PublishStep +public class CheckProductPropertyStep : PublishStep { public override string Description => "检查商品属性"; diff --git a/Store.Product/Publish/Steps/DetailStep/CheckPrice.cs b/Store.Product/Publish/Steps/DetailStep/CheckPrice.cs index d25cddf..7266be6 100644 --- a/Store.Product/Publish/Steps/DetailStep/CheckPrice.cs +++ b/Store.Product/Publish/Steps/DetailStep/CheckPrice.cs @@ -11,7 +11,7 @@ namespace LittleCow.ProductModule.ExecActions /// /// 检测价格 /// - public class CheckPrice : PublishStep + public class CheckPrice : PublishStep { public override string Description => "检测价格"; diff --git a/Store.Product/Publish/Steps/WXPublishParameters.cs b/Store.Product/Publish/Steps/WXPublishParameters.cs index 2f2719e..754ed50 100644 --- a/Store.Product/Publish/Steps/WXPublishParameters.cs +++ b/Store.Product/Publish/Steps/WXPublishParameters.cs @@ -1,4 +1,11 @@ -using Store.Product.Models.PublishParameters; +using AllBase.Model.DBModel; +using AllBase.Model.Param.WXParam; +using AllBase.Model.Result; +using AllBase.Model.Result.PDDResult; +using AllBase.Model.Result.WXResult; +using Newtonsoft.Json.Linq; +using Store.Product.Models.PublishParameters; +using Store.Product.Models.PublishParameters.Wx; using System; using System.Collections.Generic; using System.Linq; @@ -9,8 +16,366 @@ namespace Store.Product.Publish.Steps; public class WXPublishParameters: PublishParameters { + /// 候补:微信上传初始化参数对象。 + public WXUploadProductInitParam InitParameter { get; set; } = new WXUploadProductInitParam(); + /// 候补:微信上传商品参数对象。 + public WXUploadProductParam ProductParameter { get; set; } = new WXUploadProductParam(); + /// 候补:步骤运行时适配入口。 + public WxProductUploadRuntime Runtime { get; set; } = new WxProductUploadRuntime(); + /// 候补:步骤正常结束后返回的 JSON。 + public string Result { get; set; } + /// 候补:是否已正常结束发布。 + public bool IsCompleted { get; set; } + /// 候补:当前上传店铺。 + public ShopLoginInfo Shop { get; set; } + /// 候补:当前选品商品。 + public TemuDBProductSelect SelectProduct { get; set; } + /// 候补:本次上传开始时间。 + public DateTime StartTime { get; set; } = DateTime.Now; + /// 候补:实际提交的佣金比例。 + public int CommissionRate { get; set; } + /// 候补:允许的最低佣金比例。 + public int MinCommissionRate { get; set; } + /// 候补:允许的最高佣金比例。 + public int MaxCommissionRate { get; set; } + /// 候补:佣金调整值。 + public int CommissionRateChange { get; set; } + /// 候补:商品原佣金比例。 + public int? FromCommissionRate { get; set; } + /// 候补:微信回采商品数据。 + public WXGetEditProductInfoLite WxEditProdInfo { get; set; } + /// 候补:当前商品 JSON。 + public JObject ProdJObject { get; set; } = new JObject(); + /// 候补:盗链图片映射是否变化。 + public bool IsChangeImgDic { get; set; } + /// 候补:盗链图片映射。 + public Dictionary WxImgMapDic { get; set; } = new Dictionary(); + /// 候补:PDD 商品详情。 + public PDDProductInfo ProdInfo { get; set; } + /// 候补:主图数量。 + public int MainImgCount { get; set; } + /// 候补:是否需要增加随机遮块。 + public bool NeedAddRandomBlock { get; set; } + /// 候补:是否希望增加随机遮块。 + public bool WantAddRandomBlock { get; set; } + /// 候补:当前微信 API Token。 + public WXShopTokenInfo Token { get; set; } + /// 候补:裂变后的主图集合。 + public List MainGalleries { get; set; } = new List(); + /// 候补:AI 识别类目 ID 列表。 + public List AiCateIdLst { get; set; } = new List(); + /// 候补:类目查询原始结果。 + public string GetCateRst { get; set; } + /// 候补:类目查询 JSON。 + public JObject JCateRst { get; set; } + /// 候补:叶子类目 ID。 + public long LeafCatId { get; set; } + /// 候补:类目保证金信息。 + public WxCatBoundInfo Bound { get; set; } + /// 候补:最大保证金。 + public int MaxBound { get; set; } + /// 候补:最小保证金。 + public int MinBound { get; set; } + /// 候补:定向品牌 ID。 + public string SpBrandId { get; set; } + /// 候补:运费模板 JSON。 + public string ShippingTemplateJson { get; set; } + /// 候补:计算后的运费。 + public int ShipPrice { get; set; } + /// 候补:运费模板查询原始结果。 + public string ExpressRst { get; set; } + /// 候补:详情图集合。 + public List DetailGalleries { get; set; } = new List(); + /// 候补:AI 推荐商品信息结果。 + public WXUploadProductInfoRecommendParam RecommendParamRst { get; set; } = new WXUploadProductInfoRecommendParam(); + /// 候补:当前类目属性。 + public allAttrParam ProductAttr { get; set; } + /// 候补:最大 SKU 规格数。 + public int MaxSkuSpecCnt { get; set; } + /// 候补:SKU 索引。 + public int SkuIndex { get; set; } + /// 候补:临时主键。 + public int Id { get; set; } + /// 候补:临时类目 ID。 + public long CatId { get; set; } + /// 候补:临时父类目 ID。 + public long FCatId { get; set; } + /// 候补:临时属性类目 ID。 + public long ValueCatId { get; set; } + /// 候补:规格父名称与 ID 映射。 + public Dictionary DicSpecParentNameId { get; set; } = new Dictionary(); + /// 候补:规格父名称与类目 ID 映射。 + public Dictionary DicSpecParentNameCatId { get; set; } = new Dictionary(); + /// 候补:规格名称与父类目 ID 映射。 + public Dictionary DicSpecNameFCatId { get; set; } = new Dictionary(); + /// 候补:规格名称与类目 ID 映射。 + public Dictionary DicSpecNameCatId { get; set; } = new Dictionary(); + /// 候补:草稿提交原始结果。 + public string UploadDraftRst { get; set; } + /// 候补:佣金设置结果文本。 + public string CommissionRstStr { get; set; } + /// 候补:默认成人用品品牌 ID。 + public string DefaultAdultBrandId { get; set; } + /// 候补:微信 Token 列表。 + public List WxShopTokenInfoList { get; set; } = new List(); + /// 候补:资质图片列表。 + public List QualificationImages { get; set; } = new List(); + /// 候补:待上传草稿商品列表。 + public dynamic UploadDraftProductList { get; set; } /// - /// 跳过已存在的商品 + /// 预售天数(页面限制为 3-45 天)。 /// - public bool SkipExisting { get; set; } + public int PreSaleDays { get; set; } = 5; + + /// + /// 需要移除的敏感词,多个词使用逗号分隔。 + /// + public string FilterWords { get; set; } = "顶级,之王,二手,亏本,冲量,白菜价,跳楼价,xx,xxx,最大,最小,低价,降价,成本,赔钱,甩卖,真丝,蚕丝,香云纱,羊绒,羊毛,羊羔绒,羊羔毛,羽绒,皮草"; + /// + /// 是否跳过标题中包含过滤词的商品。 + /// + public bool IsSkipHasFilterWordsProd { get; set; } = false; + + /// + /// 跳过最低售价低于该值的 SKU(单位:元)。 + /// + public int SkuMinPrice { get; set; } = 10; + /// + /// 跳过最高售价高于该值的 SKU(单位:元)。 + /// + public int SkuMaxPrice { get; set; } = 9999; + + /// + /// 商品上传操作后的额外等待秒数(无论上传成功或失败)。 + /// + public int WaitSeconds { get; set; } = 10; + + /// + /// 是否只保留最高价 SKU。 + /// + public bool OnlyHighestPriceSku { get; set; } = false; + /// + /// 是否只保留最低价 SKU。 + /// + public bool OnlyLowestPriceSku { get; set; } = false; + /// + /// 是否启用颜色规格同价(上浮)。 + /// + public bool SameSpecSamePriceUp { get; set; } = false; + /// + /// 是否启用颜色规格同价(下浮)。 + /// + public bool SameSpecSamePriceDown { get; set; } = false; + /// + /// 是否跳过已铺货商品。 + /// + public bool SkipUploaded { get; set; } = true; + /// + /// 跳过已存在商品(兼容原迁移参数命名)。 + /// + public bool SkipExisting + { + get => SkipUploaded; + set => SkipUploaded = value; + } + /// + /// 是否仅上传草稿,不上架商品。 + /// + public bool UpDraft { get; set; } = false; + /// + /// 是否启用预售天数。 + /// + public bool IsPreSale { get; set; } = false; + /// + /// 添加到商品标题最前面的标题前缀词。 + /// + public string TitleHeadWords { get; set; } = ""; + + /// + /// 是否记住待传类目保证金的过滤范围。 + /// + public bool IsSaveBound { get; set; } = false; + /// + /// 待传类目保证金过滤范围下限(单位:元)。 + /// + public int FilterBoundMinSave { get; set; } = 1000; + /// + /// 待传类目保证金过滤范围上限(单位:元)。 + /// + public int FilterBoundMaxSave { get; set; } = 1000; + /// + /// 是否使用 AI 优化商品标题。 + /// + public bool IsAiShortTitle { get; set; } = false; + /// + /// 是否使用回采数据。 + /// + public bool IsUseWXComplateProd { get; set; } + + /// + /// 是否使用拍单退货仓地址。 + /// + public bool IsUseShanghaiReturnOrderAddress { get; set; } = false; + + /// + /// 是否启用裂变标题。 + /// + public bool IsFissionTitle { get; set; } = false; + /// + /// 待裂变标题文本,使用换行分隔。 + /// + public string FissionTitles { get; set; } = ""; + /// + /// 是否删除标题开头的特殊字符。 + /// + public bool IsRemoveSpecialChar { get; set; } = false; + + /// + /// 是否启用佣金上传。 + /// + public bool IsCommissionUpload { get; set; } = false; + /// + /// 佣金调整为增加;false 表示减少。 + /// + public bool IsCommissionIncrease { get; set; } = true; + /// + /// 上传后允许的最低佣金百分比。 + /// + public int CommissionMinPercent { get; set; } = 0; + /// + /// 上传后允许的最高佣金百分比。 + /// + public int CommissionMaxPercent { get; set; } = 0; + /// + /// 佣金调整百分比。 + /// + public int CommissionChangePercent { get; set; } = 0; + + /// + /// 是否使用 AI 推荐商品信息。 + /// + public bool IsUseRecommendation { get; set; } = false; + /// + /// 是否随机生成主图打码块。 + /// + public bool IsImageRandomBlock { get; set; } = false; + /// + /// 是否随机主图顺序。 + /// + public bool IsRandomMainImageOrder { get; set; } = false; + /// + /// 是否随机详情图顺序。 + /// + public bool IsRandomDetailImageOrder { get; set; } = false; + /// + /// 裂变商品是否随机改价。 + /// + public bool IsFissionRandomPriceChange { get; set; } = false; + /// + /// 裂变商品随机改价最大值。 + /// + public decimal FissionRandomPriceChangeValue { get; set; } = 0m; + /// + /// 定向品牌名称。 + /// + public string SpecialBrandName { get; set; } = ""; + + /// + /// 是否使用 AI 生成商品图片。 + /// + public bool IsAiImage { get; set; } = false; + /// + /// AI 生成商品图片数量。 + /// + public int AiImageCount { get; set; } = 1; + /// + /// 是否设置默认保质期。 + /// + public bool IsDefaultBestBefore { get; set; } = false; + /// + /// 默认保质期天数。 + /// + public int DefaultBestBeforeDays { get; set; } = 0; + /// + /// 是否给裂变商品图片添加随机外框。 + /// + public bool IsRandomImageBorder { get; set; } = false; + /// + /// 添加随机外框的主图数量。 + /// + public int MainBorderImageCount { get; set; } = 0; + /// + /// 添加随机外框的详情图数量。 + /// + public int DetailBorderImageCount { get; set; } = 0; + + /// + /// 是否设置运费险。 + /// + public bool IsFreightInsurance { get; set; } = false; + /// + /// 是否仅测试免审上传。 + /// + public bool IsTestNoAuditUpload { get; set; } = false; + /// + /// 提审后是否检查上架结果。 + /// + public bool IsCheckSubmitSuccess { get; set; } = false; + /// + /// 是否使用软件默认地址。 + /// + public bool UseSoftwareDefaultAddress { get; set; } = false; + /// + /// 本次上传是否忽略软件默认地址。 + /// + public bool IgnoreSoftwareDefaultAddressOnce { get; set; } = false; + + /// + /// 默认加价规则。 + /// + public WXAddPriceRule DefaultAddPriceRule { get; set; } = new WXAddPriceRule(); + /// + /// 分段加价规则。 + /// + public List AddPriceRules { get; set; } = new List(); +} + +public class WXAddPriceRule +{ + /// + /// 加价金额区间大于(不包含)。 + /// + public decimal MoreThanPrice { get; set; } + /// + /// 加价金额区间小于(包含)。 + /// + public decimal LessThanPrice { get; set; } + /// + /// 加价倍数。 + /// + public decimal AddPriceTimes { get; set; } = 2m; + /// + /// 额外加价金额。 + /// + public decimal AddMorePrice { get; set; } = 10m; + /// + /// 单买加价金额。 + /// + public decimal SinglePriceAdd { get; set; } = 1m; + /// + /// 是否先加价后乘倍数。 + /// + public bool AddMorePriceFirst { get; set; } = false; + /// + /// 上货库存量。 + /// + public int StockNum { get; set; } = 999; + /// + /// 是否启用分段加价。 + /// + public bool IsStepAddPrice { get; set; } = false; + /// + /// 运费倍率。 + /// + public decimal ShippingPriceTimes { get; set; } = 1.0m; } diff --git a/Store.Product/Publish/Steps/Wx/AddRandomImageBorderStep.cs b/Store.Product/Publish/Steps/Wx/AddRandomImageBorderStep.cs index f4e7fea..3e39943 100644 --- a/Store.Product/Publish/Steps/Wx/AddRandomImageBorderStep.cs +++ b/Store.Product/Publish/Steps/Wx/AddRandomImageBorderStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,24 +34,24 @@ public sealed class AddRandomImageBorderStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (selectProd.is_fission_title && chkRandomImgBorder.Checked) + if (context.Parameters.SelectProduct.is_fission_title && context.Parameters.IsRandomImageBorder) { // selectProd.isFission int mainCount = 9; int detailCount = 1; Invoke(new Action(() => { - mainCount = txtMainBorderImgCount.Text.Trim().ParseToInt(); - detailCount = txtDetailBorderImgCount.Text.Trim().ParseToInt(); + mainCount = context.Parameters.MainBorderImageCount; + detailCount = context.Parameters.DetailBorderImageCount; })); // api上传图片文件 边框主图 if (1 == 1) { - if (chkRandomMainImgOrder.Checked) - upProdParam.product.info.headImg = upProdParam.product.info.headImg.OrderBy(x => Guid.NewGuid()).Take(100).ToList(); - for (int n = 0; n < upProdParam.product.info.headImg.Count && n < mainCount; n++) + if (context.Parameters.IsRandomMainImageOrder) + context.Parameters.ProductParameter.product.info.headImg = context.Parameters.ProductParameter.product.info.headImg.OrderBy(x => Guid.NewGuid()).Take(100).ToList(); + for (int n = 0; n < context.Parameters.ProductParameter.product.info.headImg.Count && n < mainCount; n++) { - var imgUrl = upProdParam.product.info.headImg[n]; + var imgUrl = context.Parameters.ProductParameter.product.info.headImg[n]; try { string errMsg = ""; @@ -64,7 +64,7 @@ public sealed class AddRandomImageBorderStep : WxProductPublishStepBase var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; //upDate += "&is_file=true"; //if (needAddRandomBlock || wantAddRandomBlock) // upDate += "&random_code=true"; @@ -73,24 +73,24 @@ public sealed class AddRandomImageBorderStep : WxProductPublishStepBase var sTime = DateTime.Now; var apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在优化主图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在优化主图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 5 && apiUpImgFileRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref apiUpImgFileRst, "img_url"); if (apiUpImgFileRst.Contains("\"errcode\":0") && !string.IsNullOrEmpty(upImgUrl)) { - upProdParam.product.info.headImg[n] = upImgUrl; + context.Parameters.ProductParameter.product.info.headImg[n] = upImgUrl; } else { @@ -107,11 +107,11 @@ public sealed class AddRandomImageBorderStep : WxProductPublishStepBase // api上传图片文件 边框详情图 if (1 == 1) { - if (chkRandomDetailImgOrder.Checked) - upProdParam.product.info.detail.detailImg = upProdParam.product.info.detail.detailImg.OrderBy(x => Guid.NewGuid()).Take(100).ToList(); - for (int n = 0; n < upProdParam.product.info.detail.detailImg.Count && n < detailCount; n++) + if (context.Parameters.IsRandomDetailImageOrder) + context.Parameters.ProductParameter.product.info.detail.detailImg = context.Parameters.ProductParameter.product.info.detail.detailImg.OrderBy(x => Guid.NewGuid()).Take(100).ToList(); + for (int n = 0; n < context.Parameters.ProductParameter.product.info.detail.detailImg.Count && n < detailCount; n++) { - var imgUrl = upProdParam.product.info.detail.detailImg[n]; + var imgUrl = context.Parameters.ProductParameter.product.info.detail.detailImg[n]; try { string errMsg = ""; @@ -124,7 +124,7 @@ public sealed class AddRandomImageBorderStep : WxProductPublishStepBase var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; //upDate += "&is_file=true"; //if (needAddRandomBlock || wantAddRandomBlock) // upDate += "&random_code=true"; @@ -133,24 +133,24 @@ public sealed class AddRandomImageBorderStep : WxProductPublishStepBase var sTime = DateTime.Now; var apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在优化详情图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在优化详情图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 5 && apiUpImgFileRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref apiUpImgFileRst, "img_url"); if (apiUpImgFileRst.Contains("\"errcode\":0") && !string.IsNullOrEmpty(upImgUrl)) { - upProdParam.product.info.detail.detailImg[n] = upImgUrl; + context.Parameters.ProductParameter.product.info.detail.detailImg[n] = upImgUrl; } else { @@ -165,5 +165,6 @@ public sealed class AddRandomImageBorderStep : WxProductPublishStepBase } } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/AddTitlePrefixStep.cs b/Store.Product/Publish/Steps/Wx/AddTitlePrefixStep.cs index bc471ac..0327ca8 100644 --- a/Store.Product/Publish/Steps/Wx/AddTitlePrefixStep.cs +++ b/Store.Product/Publish/Steps/Wx/AddTitlePrefixStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,7 +34,8 @@ public sealed class AddTitlePrefixStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (!string.IsNullOrWhiteSpace(wxUploadRule.TitleHeadWords)) - upProdParam.product.info.title = wxUploadRule.TitleHeadWords + upProdParam.product.info.title; + if (!string.IsNullOrWhiteSpace(context.Parameters.TitlePrefix)) + context.Parameters.ProductParameter.product.info.title = context.Parameters.TitlePrefix + context.Parameters.ProductParameter.product.info.title; + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/BuildSkuInfoStep.cs b/Store.Product/Publish/Steps/Wx/BuildSkuInfoStep.cs index fb773c0..a328d45 100644 --- a/Store.Product/Publish/Steps/Wx/BuildSkuInfoStep.cs +++ b/Store.Product/Publish/Steps/Wx/BuildSkuInfoStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,9 +21,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; -using Store.Framework.Extensions; namespace Store.Product.Publish.Steps.Wx; /// @@ -35,40 +34,40 @@ public sealed class BuildSkuInfoStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - upProdParam.product.productSkus = new List(); - skuIndex = 0; - id = 3; - catId = 200000000003; - fCatId = 200000000003; - valueCatId = (17 + Randomx.GetNumber(11)).ParseToLong(); - dicSpecParentNameId = new Dictionary(); - dicSpecParentNameCatId = new Dictionary(); - dicSpecNamefCatId = new Dictionary(); - dicSpecNameCatId = new Dictionary(); - foreach (var skuInfo in prodInfo.detail.sku) + context.Parameters.ProductParameter.product.productSkus = new List(); + context.Parameters.SkuIndex = 0; + context.Parameters.Id = 3; + context.Parameters.CatId = 200000000003; + context.Parameters.FCatId = 200000000003; + context.Parameters.ValueCatId = (17 + Randomx.GetNumber(11)).ParseToLong(); + context.Parameters.DicSpecParentNameId = new Dictionary(); + context.Parameters.DicSpecParentNameCatId = new Dictionary(); + context.Parameters.DicSpecNameFCatId = new Dictionary(); + context.Parameters.DicSpecNameCatId = new Dictionary(); + foreach (var skuInfo in context.Parameters.ProdInfo.detail.sku) { foreach (var spec in skuInfo.spec) { - if (!dicSpecParentNameId.Keys.Contains(spec.parent_name)) + if (!context.Parameters.DicSpecParentNameId.Keys.Contains(spec.parent_name)) { - dicSpecParentNameId[spec.parent_name] = id++; - dicSpecParentNameCatId[spec.parent_name] = catId++; + context.Parameters.DicSpecParentNameId[spec.parent_name] = context.Parameters.Id++; + context.Parameters.DicSpecParentNameCatId[spec.parent_name] = context.Parameters.CatId++; } - if (!dicSpecNamefCatId.Keys.Contains(spec.spec_name)) + if (!context.Parameters.DicSpecNameFCatId.Keys.Contains(spec.spec_name)) { - dicSpecNamefCatId[spec.spec_name] = fCatId++; - dicSpecNameCatId[spec.spec_name] = valueCatId++; + context.Parameters.DicSpecNameFCatId[spec.spec_name] = context.Parameters.FCatId++; + context.Parameters.DicSpecNameCatId[spec.spec_name] = context.Parameters.ValueCatId++; } } } - if (dbProd.product_get_type_text == "厂商直采" && !prodInfo.detail.sku.Any(s => s.quantity.ParseToInt() > 0)) + if (context.Product.ProductGetTypeText == "厂商直采" && !context.Parameters.ProdInfo.detail.sku.Any(s => s.quantity.ParseToInt() > 0)) { throw new Exception("源商品库存为0"); } - foreach (var skuInfo in prodInfo.detail.sku) + foreach (var skuInfo in context.Parameters.ProdInfo.detail.sku) { productSkuParam skuParam = new productSkuParam(); - upProdParam.product.productSkus.Add(skuParam); + context.Parameters.ProductParameter.product.productSkus.Add(skuParam); for (int i = skuInfo.spec.Count - 1; i >= 0; i--) { var specInfo = skuInfo.spec[i]; @@ -76,20 +75,20 @@ public sealed class BuildSkuInfoStep : WxProductPublishStepBase skuParam.__skuKey += specInfo.spec_name; } skuParam.__skuKey.TrimEnd('_'); - skuParam.index = skuIndex++; + skuParam.index = context.Parameters.SkuIndex++; skuParam.productSkuInfo = new productSkuInfoParam(); // 加价 - skuParam.productSkuInfo.salePrice = (skuInfo.multi_price * defaultAddPriceRule.AddPriceTimes + defaultAddPriceRule.AddMorePrice * 100).ParseToInt(); - if (defaultAddPriceRule.AddMorePriceFirst) - skuParam.productSkuInfo.salePrice = ((skuInfo.multi_price + defaultAddPriceRule.AddMorePrice * 100) * defaultAddPriceRule.AddPriceTimes).ParseToInt(); + skuParam.productSkuInfo.salePrice = (skuInfo.multi_price * context.Parameters.DefaultAddPriceRule.AddPriceTimes + context.Parameters.DefaultAddPriceRule.AddMorePrice * 100).ParseToInt(); + if (context.Parameters.DefaultAddPriceRule.AddMorePriceFirst) + skuParam.productSkuInfo.salePrice = ((skuInfo.multi_price + context.Parameters.DefaultAddPriceRule.AddMorePrice * 100) * context.Parameters.DefaultAddPriceRule.AddPriceTimes).ParseToInt(); // 阶梯式加价,如果命中则按阶梯式加价进行 - if (defaultAddPriceRule.IsStepAddPrice) + if (context.Parameters.DefaultAddPriceRule.IsStepAddPrice) { - foreach (var addPrice in lstAddPriceRule) + foreach (var addPrice in context.Parameters.AddPriceRules) { if (skuInfo.multi_price > addPrice.MoreThanPrice * 100 && skuInfo.multi_price <= addPrice.LessThanPrice * 100) { - if (defaultAddPriceRule.AddMorePriceFirst) // 先加后乘 + if (context.Parameters.DefaultAddPriceRule.AddMorePriceFirst) // 先加后乘 skuParam.productSkuInfo.salePrice = ((skuInfo.multi_price + addPrice.AddMorePrice * 100) * addPrice.AddPriceTimes).ParseToInt(); else skuParam.productSkuInfo.salePrice = (skuInfo.multi_price * addPrice.AddPriceTimes + addPrice.AddMorePrice * 100).ParseToInt(); @@ -98,19 +97,19 @@ public sealed class BuildSkuInfoStep : WxProductPublishStepBase } } // 聚水潭上微信小店,加运费(其他平台shipPrice默认为0) - skuParam.productSkuInfo.salePrice += (shipPrice * defaultAddPriceRule.ShippingPriceTimes).ParseToInt(); + skuParam.productSkuInfo.salePrice += (context.Parameters.ShipPrice * context.Parameters.DefaultAddPriceRule.ShippingPriceTimes).ParseToInt(); // 商品裂变随机增加价格 - if (selectProd.is_fission_title && chkFissionRandomPriceChange.Checked) + if (context.Parameters.SelectProduct.is_fission_title && context.Parameters.IsFissionRandomPriceChange) { Invoke(new Action(() => { - var fissionRandomPrice = Randomx.GetId((txtFissionRandomPriceChange.Text.ParseToDecimal() * 100).ParseToInt() + 1); + var fissionRandomPrice = Randomx.GetId((context.Parameters.FissionRandomPriceChangeValue * 100).ParseToInt() + 1); skuParam.productSkuInfo.salePrice += fissionRandomPrice; })); } // sku图 - skuParam.productSkuInfo.thumbImg = upProdParam.product.info.productSaleAttrs[0].items.FirstOrDefault(a => a.value == skuInfo.spec[0].spec_name)?.imgUrl; - if (dbProd.special_prod_type == "爆款数据") + skuParam.productSkuInfo.thumbImg = context.Parameters.ProductParameter.product.info.productSaleAttrs[0].items.FirstOrDefault(a => a.value == skuInfo.spec[0].spec_name)?.imgUrl; + if (context.Product.SpecialProdType == "爆款数据") { if (!skuInfo.out_sku_sn.StartsWith("BS")) // Best-seller 爆款 skuInfo.out_sku_sn = "BS" + skuInfo.out_sku_sn; @@ -121,11 +120,11 @@ public sealed class BuildSkuInfoStep : WxProductPublishStepBase //skuParam.productSkuInfo.barCode = skuInfo.out_sku_sn; // 条形码 skuParam.skuKey.outSkuId = skuInfo.out_sku_sn; skuParam.skuKey.productKey = new productKeyParam(); - skuParam.skuKey.productKey.outProductId = upProdParam.product.info.spuCode; + skuParam.skuKey.productKey.outProductId = context.Parameters.ProductParameter.product.info.spuCode; // 库存 - skuParam.productSkuInfo.stockInfo = new stockInfoParam() { stockNum = defaultAddPriceRule.StockNum }; + skuParam.productSkuInfo.stockInfo = new stockInfoParam() { stockNum = context.Parameters.DefaultAddPriceRule.StockNum }; // 厂商直采上家库存为0则按0上架 - if (dbProd.product_get_type_text == "厂商直采" && skuInfo.quantity.IsNullOrZero()) + if (context.Product.ProductGetTypeText == "厂商直采" && skuInfo.quantity.IsNullOrZero()) skuParam.productSkuInfo.stockInfo.stockNum = 0; skuParam.productSkuInfo.saleParam = new List(); foreach (var specInfo in skuInfo.spec) @@ -140,8 +139,8 @@ public sealed class BuildSkuInfoStep : WxProductPublishStepBase skuCateKeyParam.isCustomize = true; skuCateKeyParam.isMainSale = true; skuCateKeyParam.name = specInfo.parent_name; - skuCateKeyParam.id = dicSpecParentNameId[specInfo.parent_name].ParseToInt(); // 3; - skuCateKeyParam.catId = dicSpecParentNameCatId[specInfo.parent_name]; + skuCateKeyParam.id = context.Parameters.DicSpecParentNameId[specInfo.parent_name].ParseToInt(); // 3; + skuCateKeyParam.catId = context.Parameters.DicSpecParentNameCatId[specInfo.parent_name]; skuCateKeyParam.label = "自定义规格"; skuCateKeyParam.catInfo = new skuCatInfoParam() { isCustomize = 1 }; skuCateKeyParam.catType = 8; @@ -149,23 +148,24 @@ public sealed class BuildSkuInfoStep : WxProductPublishStepBase // specValue categoryValueParam skuCateValueParam = new categoryValueParam(); saleParam.categorys.Add(skuCateValueParam); - skuCateValueParam.fCatId = dicSpecNamefCatId[specInfo.spec_name]; - skuCateValueParam.catId = dicSpecNameCatId[specInfo.spec_name]; + skuCateValueParam.fCatId = context.Parameters.DicSpecNameFCatId[specInfo.spec_name]; + skuCateValueParam.catId = context.Parameters.DicSpecNameCatId[specInfo.spec_name]; skuCateValueParam.name = specInfo.spec_name; skuCateValueParam.skuNameValue = specInfo.spec_name; skuCateValueParam.desc = ""; skuCateValueParam.catInfo = new categoryValueCatInfo() { editByUser = 1 }; skuCateValueParam.thumbImg = ""; var specIndex = skuInfo.spec.IndexOf(specInfo); - skuCateValueParam.priority = prodInfo.detail.sku.Select(s => s.spec[specIndex].spec_name).Distinct().ToList().IndexOf(specInfo.spec_name); + skuCateValueParam.priority = context.Parameters.ProdInfo.detail.sku.Select(s => s.spec[specIndex].spec_name).Distinct().ToList().IndexOf(specInfo.spec_name); skuCateValueParam.selected = false; } skuParam.productSkuInfo.skuDeliverInfo = new skuDeliverInfoParam(); - skuParam.productSkuInfo.stockDiff = new stockDiffParam() { diffType = 1, num = defaultAddPriceRule.StockNum }; + skuParam.productSkuInfo.stockDiff = new stockDiffParam() { diffType = 1, num = context.Parameters.DefaultAddPriceRule.StockNum }; // 厂商直采上家库存为0则按0上架 - if (dbProd.product_get_type_text == "厂商直采" && skuInfo.quantity.IsNullOrZero()) + if (context.Product.ProductGetTypeText == "厂商直采" && skuInfo.quantity.IsNullOrZero()) skuParam.productSkuInfo.stockDiff.num = 0; skuParam.status = 5; } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/BuildSkuPropertiesStep.cs b/Store.Product/Publish/Steps/Wx/BuildSkuPropertiesStep.cs index 47d3825..fc2d7c5 100644 --- a/Store.Product/Publish/Steps/Wx/BuildSkuPropertiesStep.cs +++ b/Store.Product/Publish/Steps/Wx/BuildSkuPropertiesStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -21,7 +22,6 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -36,32 +36,32 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成sku"; + context.Progress.Report("正在生成sku"); })); } Thread.Sleep(Randomx.GetId(100, 300)); - upProdParam.product.info.productSaleAttrs = new List(); - if (prodInfo.detail.sku == null) - prodInfo.detail.sku = new List(); - if (prodInfo.detail.sku.Count == 0) - prodInfo.detail.sku.Add(new sku_item() { spec = new List() }); - if (prodInfo.detail.sku.FirstOrDefault().spec == null) - prodInfo.detail.sku.FirstOrDefault().spec = new List(); - if (prodInfo.detail.sku.FirstOrDefault().spec.Count == 0) - prodInfo.detail.sku.FirstOrDefault().spec.Add(new spec_item() { parent_name = "规格", spec_name = "默认" }); - if (prodInfo.detail.sku.FirstOrDefault().thumb_url.IsNullOrEmpty()) - prodInfo.detail.sku.FirstOrDefault().thumb_url = prodInfo.detail.galleries.FirstOrDefault(g => g.type == 1)?.url; + context.Parameters.ProductParameter.product.info.productSaleAttrs = new List(); + if (context.Parameters.ProdInfo.detail.sku == null) + context.Parameters.ProdInfo.detail.sku = new List(); + if (context.Parameters.ProdInfo.detail.sku.Count == 0) + context.Parameters.ProdInfo.detail.sku.Add(new sku_item() { spec = new List() }); + if (context.Parameters.ProdInfo.detail.sku.FirstOrDefault().spec == null) + context.Parameters.ProdInfo.detail.sku.FirstOrDefault().spec = new List(); + if (context.Parameters.ProdInfo.detail.sku.FirstOrDefault().spec.Count == 0) + context.Parameters.ProdInfo.detail.sku.FirstOrDefault().spec.Add(new spec_item() { parent_name = "规格", spec_name = "默认" }); + if (context.Parameters.ProdInfo.detail.sku.FirstOrDefault().thumb_url.IsNullOrEmpty()) + context.Parameters.ProdInfo.detail.sku.FirstOrDefault().thumb_url = context.Parameters.ProdInfo.detail.galleries.FirstOrDefault(g => g.type == 1)?.url; - maxSkuSpecCnt = prodInfo.detail.sku.Max(x => x.spec?.Count).ParseToInt(); - foreach (var skuTmp in prodInfo.detail.sku.ToList()) + context.Parameters.MaxSkuSpecCnt = context.Parameters.ProdInfo.detail.sku.Max(x => x.spec?.Count).ParseToInt(); + foreach (var skuTmp in context.Parameters.ProdInfo.detail.sku.ToList()) { - if (skuTmp.spec?.Count != maxSkuSpecCnt) - prodInfo.detail.sku.Remove(skuTmp); + if (skuTmp.spec?.Count != context.Parameters.MaxSkuSpecCnt) + context.Parameters.ProdInfo.detail.sku.Remove(skuTmp); } // 处理系统指定的规格名称 @@ -87,12 +87,12 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase //// } ////} // 坚果炒货类,系统返回的试规格/净含量但是要求填规格 - if ((upProdParam.product.info?.category?.FirstOrDefault()?.name == "食品饮料" || prodInfo.detail?.cats?.FirstOrDefault() == "食品饮料") && - (upProdParam.product.info?.category?.LastOrDefault()?.name == "坚果炒货" || upProdParam.product.info?.category?.LastOrDefault()?.name == "果干")) + if ((context.Parameters.ProductParameter.product.info?.category?.FirstOrDefault()?.name == "食品饮料" || context.Parameters.ProdInfo.detail?.cats?.FirstOrDefault() == "食品饮料") && + (context.Parameters.ProductParameter.product.info?.category?.LastOrDefault()?.name == "坚果炒货" || context.Parameters.ProductParameter.product.info?.category?.LastOrDefault()?.name == "果干")) { - if (!prodInfo.detail.sku.FirstOrDefault().spec.Any(s => s.parent_name == "规格")) + if (!context.Parameters.ProdInfo.detail.sku.FirstOrDefault().spec.Any(s => s.parent_name == "规格")) { - foreach (var sku in prodInfo.detail.sku) + foreach (var sku in context.Parameters.ProdInfo.detail.sku) { sku.spec.FirstOrDefault().parent_name = "规格"; } @@ -100,7 +100,7 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase } else { - var leafCat = upProdParam.product.info.category.LastOrDefault(); + var leafCat = context.Parameters.ProductParameter.product.info.category.LastOrDefault(); if (leafCat?.catInfo?.saleAttr?.attr != null) { foreach (var att in leafCat.catInfo.saleAttr.attr) @@ -109,9 +109,9 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase if (att.isRequired == true) { // 规格属性名放在第二个规格上 - if (att.normalRelease.ruleType == 2 && prodInfo.detail.sku.FirstOrDefault()?.spec.Count == 2) + if (att.normalRelease.ruleType == 2 && context.Parameters.ProdInfo.detail.sku.FirstOrDefault()?.spec.Count == 2) { - foreach (var sku in prodInfo.detail.sku) + foreach (var sku in context.Parameters.ProdInfo.detail.sku) { // 如果有指定规格属性名称就不再设置 if (!sku.spec.Any(sp => sp.parent_name == att.name)) @@ -150,7 +150,7 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase // 规格属性名放在第一个规格上 else { - foreach (var sku in prodInfo.detail.sku) + foreach (var sku in context.Parameters.ProdInfo.detail.sku) { // 如果有指定规格属性名称就不再设置 if (!sku.spec.Any(sp => sp.parent_name == att.name)) @@ -191,30 +191,30 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase } } - if (prodInfo.detail.sku.FirstOrDefault()?.spec?.Count > 0) + if (context.Parameters.ProdInfo.detail.sku.FirstOrDefault()?.spec?.Count > 0) { productSaleAttrParam attrParam = new productSaleAttrParam() { - key = prodInfo.detail.sku.FirstOrDefault()?.spec[0].parent_name, + key = context.Parameters.ProdInfo.detail.sku.FirstOrDefault()?.spec[0].parent_name, hasImg = true, items = new List() }; - upProdParam.product.info.productSaleAttrs.Add(attrParam); - foreach (var sku in prodInfo.detail.sku) + context.Parameters.ProductParameter.product.info.productSaleAttrs.Add(attrParam); + foreach (var sku in context.Parameters.ProdInfo.detail.sku) { var spec = sku.spec[0]; if (!attrParam.items.Any(it => it.value == spec.spec_name) && !string.IsNullOrEmpty(sku.thumb_url)) { - if (dbProd.product_get_type_text == "微信店采") + if (context.Product.ProductGetTypeText == "微信店采") { attrParam.items.Add(new productSaleAttrItemParam() { value = spec.spec_name, imgUrl = sku.thumb_url, }); continue; } // 获取缓存盗链 sku图 - if (wxImgMapDic.ContainsKey(BaseClass.GetMd5(sku.thumb_url))) + if (context.Parameters.WxImgMapDic.ContainsKey(BaseClass.GetMd5(sku.thumb_url))) { - attrParam.items.Add(new productSaleAttrItemParam() { value = spec.spec_name, imgUrl = wxImgMapDic[BaseClass.GetMd5(sku.thumb_url)], }); + attrParam.items.Add(new productSaleAttrItemParam() { value = spec.spec_name, imgUrl = context.Parameters.WxImgMapDic[BaseClass.GetMd5(sku.thumb_url)], }); continue; } // 使用接口链接传sku图 @@ -222,31 +222,31 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase { var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; upDate += "&post_data=" + GetHtml.UrlEncodeUtf8("{\"img_url\":\"" + sku.thumb_url.Replace("https://", "http://") + "\"}"); var sTime = DateTime.Now; var upDateRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成sku " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在生成sku " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 20 && upDateRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); upDateRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref upDateRst, "img_url"); if (upDateRst.Contains("\"errcode\":0") && !string.IsNullOrEmpty(upImgUrl)) { attrParam.items.Add(new productSaleAttrItemParam() { value = spec.spec_name, imgUrl = upImgUrl, }); - wxImgMapDic[BaseClass.GetMd5(sku.thumb_url)] = upImgUrl; - isChangeImgDic = true; + context.Parameters.WxImgMapDic[BaseClass.GetMd5(sku.thumb_url)] = upImgUrl; + context.Parameters.IsChangeImgDic = true; continue; // 传图成功跳过模拟上传 } else @@ -268,7 +268,7 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; //upDate += "&is_file=true"; //if (needAddRandomBlock || wantAddRandomBlock) // upDate += "&random_code=true"; @@ -277,26 +277,26 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase var sTime = DateTime.Now; var apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在上传商品sku图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在上传商品sku图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 5 && apiUpImgFileRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref apiUpImgFileRst, "img_url"); if (apiUpImgFileRst.Contains("\"errcode\":0") && !string.IsNullOrEmpty(upImgUrl)) { attrParam.items.Add(new productSaleAttrItemParam() { value = spec.spec_name, imgUrl = upImgUrl, }); - wxImgMapDic[BaseClass.GetMd5(sku.thumb_url)] = upImgUrl; - isChangeImgDic = true; + context.Parameters.WxImgMapDic[BaseClass.GetMd5(sku.thumb_url)] = upImgUrl; + context.Parameters.IsChangeImgDic = true; continue; } else @@ -310,7 +310,7 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase } // 上传sku图 - var locationStr = UploadImg(shop, sku.thumb_url, cell); + var locationStr = UploadImg(context.Parameters.Shop, sku.thumb_url); if (!locationStr.Contains("\"success\":true")) throw new Exception(locationStr); var location = BaseRegex.GetStringJson(ref locationStr, "Location"); @@ -322,21 +322,22 @@ public sealed class BuildSkuPropertiesStep : WxProductPublishStepBase } } } - if (prodInfo.detail.sku.FirstOrDefault()?.spec?.Count > 1) + if (context.Parameters.ProdInfo.detail.sku.FirstOrDefault()?.spec?.Count > 1) { productSaleAttrParam attrParam = new productSaleAttrParam() { - key = prodInfo.detail.sku.FirstOrDefault()?.spec[1].parent_name, + key = context.Parameters.ProdInfo.detail.sku.FirstOrDefault()?.spec[1].parent_name, hasImg = false, items = new List() }; - upProdParam.product.info.productSaleAttrs.Add(attrParam); - foreach (var sku in prodInfo.detail.sku) + context.Parameters.ProductParameter.product.info.productSaleAttrs.Add(attrParam); + foreach (var sku in context.Parameters.ProdInfo.detail.sku) { var spec = sku.spec[1]; if (!attrParam.items.Any(it => it.value == spec.spec_name)) attrParam.items.Add(new productSaleAttrItemParam() { value = spec.spec_name }); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/CalculateShippingTemplateStep.cs b/Store.Product/Publish/Steps/Wx/CalculateShippingTemplateStep.cs index f3b5c71..eee37c0 100644 --- a/Store.Product/Publish/Steps/Wx/CalculateShippingTemplateStep.cs +++ b/Store.Product/Publish/Steps/Wx/CalculateShippingTemplateStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -9,7 +10,6 @@ using AllBase.Model.Result.PDDResult; using AllBase.Model.Result.WXResult; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Store.Framework.Extensions; using Store.Product.Models.PublishParameters.Wx; using Store.Product.Publish; using System; @@ -21,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -35,22 +34,22 @@ public sealed class CalculateShippingTemplateStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在选取运费模板"; + context.Progress.Report("正在选取运费模板"); })); } - shippingTemplateJson = ""; - shipPrice = 0; + context.Parameters.ShippingTemplateJson = ""; + context.Parameters.ShipPrice = 0; - if (dbProd.product_get_type_text == "厂商直采") + if (context.Product.ProductGetTypeText == "厂商直采") { var urlShipping = BaseClass.BuildObjString("product/wx_get_shipping_template"); var dataShipping = Work.UserLogin.GetSignaturex() + - "&coid=" + dbProd.skc_id; + "&coid=" + context.Product.SkcId; var htmlShipping = GetHtml.PostUtf8(urlShipping, dataShipping); if (string.IsNullOrEmpty(htmlShipping) || !htmlShipping.Contains("\"code\":200")) htmlShipping = GetHtml.PostUtf8(urlShipping, dataShipping); @@ -66,7 +65,7 @@ public sealed class CalculateShippingTemplateStep : WxProductPublishStepBase { try { - shippingTemplateJson = JsonHelper.SerializeObject(JsonHelper.JObjectParse(htmlShipping)["data"]); + context.Parameters.ShippingTemplateJson = JsonHelper.SerializeObject(JsonHelper.JObjectParse(htmlShipping)["data"]); } catch { @@ -75,11 +74,11 @@ public sealed class CalculateShippingTemplateStep : WxProductPublishStepBase } } - if (string.IsNullOrEmpty(shippingTemplateJson)) + if (string.IsNullOrEmpty(context.Parameters.ShippingTemplateJson)) { // 获取运费模板 var urlShip = BaseClass.BuildObjString("product/e57_get_freight_template"); - var dataShip = Work.UserLogin.GetSignaturex() + "&coid=" + dbProd.skc_id; + var dataShip = Work.UserLogin.GetSignaturex() + "&coid=" + context.Product.SkcId; var shipRst = GetHtml.PostUtf8(urlShip, dataShip); if (string.IsNullOrEmpty(shipRst) || !shipRst.Contains("\"code\":0")) shipRst = GetHtml.PostUtf8(urlShipping, dataShipping); @@ -93,13 +92,13 @@ public sealed class CalculateShippingTemplateStep : WxProductPublishStepBase try { //[{"id":"204","warehouseNum":"15016108","freightType":0,"provinces":"香港特别行政区,台湾省,澳门特别行政区","freightPrice":9999900,"createBy":"vmslin","createTime":"2026-01-30T16:45:03+08:00","updateBy":"vmslin","updateTime":"2026-01-30T16:45:03+08:00"},{"id":"205","warehouseNum":"15016108","freightType":3,"provinces":"海南省,新疆维吾尔自治区,西藏自治区,内蒙古自治区","freightPrice":1530,"createBy":"vmslin","createTime":"2026-01-30T16:45:51+08:00","updateBy":"vmslin","updateTime":"2026-01-30T16:45:51+08:00"},{"id":"206","warehouseNum":"15016108","freightType":1,"provinces":"北京市,上海市","freightPrice":410,"createBy":"vmslin","createTime":"2026-01-30T16:46:04+08:00","updateBy":"vmslin","updateTime":"2026-01-30T16:46:04+08:00"},{"id":"207","warehouseNum":"15016108","freightType":1,"provinces":"安徽省,重庆市,福建省,广东省,甘肃省,广西壮族自治区,贵州省,河北省,湖北省,黑龙江省,河南省,湖南省,吉林省,江苏省,江西省,辽宁省,宁夏回族自治区,青海省,四川省,山东省,山西省,陕西省,天津市,云南省,浙江省","freightPrice":310,"createBy":"vmslin","createTime":"2026-01-30T16:46:17+08:00","updateBy":"vmslin","updateTime":"2026-01-30T16:46:17+08:00"}] - shippingTemplateJson = JsonHelper.SerializeObject(JsonHelper.JObjectParse(shipRst)["data"]); - if (shipRst.Contains("\"code\":0") && !string.IsNullOrEmpty(shippingTemplateJson)) + context.Parameters.ShippingTemplateJson = JsonHelper.SerializeObject(JsonHelper.JObjectParse(shipRst)["data"]); + if (shipRst.Contains("\"code\":0") && !string.IsNullOrEmpty(context.Parameters.ShippingTemplateJson)) { urlShipping = BaseClass.BuildObjString("product/wx_add_mdy_shipping_template"); dataShipping = Work.UserLogin.GetSignaturex() + - "&coid=" + dbProd.skc_id + - "&shipping_template_json=" + shippingTemplateJson; + "&coid=" + context.Product.SkcId + + "&shipping_template_json=" + context.Parameters.ShippingTemplateJson; htmlShipping = GetHtml.PostUtf8(urlShipping, dataShipping); if (string.IsNullOrEmpty(htmlShipping) || !htmlShipping.Contains("\"code\":200")) htmlShipping = GetHtml.PostUtf8(urlShipping, dataShipping); @@ -111,19 +110,19 @@ public sealed class CalculateShippingTemplateStep : WxProductPublishStepBase } } - if (!string.IsNullOrEmpty(shippingTemplateJson)) + if (!string.IsNullOrEmpty(context.Parameters.ShippingTemplateJson)) { try { int count = 0; - var shipObjs = JArray.Parse(shippingTemplateJson); + var shipObjs = JArray.Parse(context.Parameters.ShippingTemplateJson); foreach (var shipObj in shipObjs) { var provincesStr = shipObj["provinces"].ParseToString(); if (provincesStr.Split(',').Length > count) { count = provincesStr.Split(',').Length; - shipPrice = shipObj["freightPrice"].ParseToInt(); + context.Parameters.ShipPrice = shipObj["freightPrice"].ParseToInt(); } } } @@ -132,10 +131,11 @@ public sealed class CalculateShippingTemplateStep : WxProductPublishStepBase throw new Exception("运费模板获取失败 " + ex.Message); } } - if (shipPrice <= 0) + if (context.Parameters.ShipPrice <= 0) { throw new Exception("运费模板获取失败 未获取到"); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/CommissionPreparationStep.cs b/Store.Product/Publish/Steps/Wx/CommissionPreparationStep.cs index c9054d1..6fd5541 100644 --- a/Store.Product/Publish/Steps/Wx/CommissionPreparationStep.cs +++ b/Store.Product/Publish/Steps/Wx/CommissionPreparationStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -9,7 +10,6 @@ using AllBase.Model.Result.PDDResult; using AllBase.Model.Result.WXResult; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Store.Framework.Extensions; using Store.Product.Models.PublishParameters.Wx; using Store.Product.Publish; using System; @@ -21,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -31,81 +30,72 @@ namespace Store.Product.Publish.Steps.Wx; /// public sealed class CommissionPreparationStep : WxProductPublishStepBase { - public override string Description => "处理佣金上传"; + public override string Description => "处理佣金上传"; - protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) - { - if (BaseClass.UserAuthority.Contains("佣金上货") && chkCommission.Checked) + protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) + { + if (BaseClass.UserAuthority.Contains("佣金上货") && context.Parameters.IsCommissionUpload) + { + if (context.Product.SpecialProdType != "爆款数据" && context.Product.ProductGetTypeText != "微信小店") + throw new Exception("拥金上货失败:仅爆款微信小店数据支持佣金上传!"); + + var rst = WXApi.GetAndUpdateWebStatus(context.Shop.Cookie); + if (!rst.Html.Contains("\"isOpenLeague\":true")) { - if (dbProd.special_prod_type != "爆款数据" && dbProd.product_get_type_text != "微信小店") - throw new Exception("拥金上货失败:仅爆款微信小店数据支持佣金上传!"); + throw new Exception("拥金上货失败:需要开通优选联盟!"); + } - var rst = WXApi.GetAndUpdateWebStatus(context.Shop.Cookie); - if (!rst.Html.Contains("\"isOpenLeague\":true")) - { - throw new Exception("拥金上货失败:需要开通优选联盟!"); - } + var url = BaseClass.BuildObjString("product/wx_get_commission_rate"); + var date = UserLogin.GetSignaturex(); + date += "&spu_ids=" + context.Product.SpuId; - var url = BaseClass.BuildObjString("product/wx_get_commission_rate"); - var date = UserLogin.GetSignaturex(); - date += "&spu_ids=" + dbProd.spu_id; - - var prodCommissionRst = GetHtml.PostUtf8(url, date); - if (!prodCommissionRst.Contains("\"code\":200")) - { - var errMsg = BaseRegex.GetStringJsonByRegs(ref prodCommissionRst, prodCommissionRst, "msg"); - throw new Exception("拥金上货失败:" + errMsg); - } - fromCommissionRate = BaseRegex.GetStringJson(ref prodCommissionRst, "commission_rate").ParseToNullableInt(); - if (fromCommissionRate == null) - fromCommissionRate = -1; - if (prodCommissionRst.Contains("\"data\":[]") || BaseRegex.GetStringJson(ref prodCommissionRst, "mdy_time").ParseToString().ParseToDateTime() < DateTime.Now.AddDays(-30)) - { - var assistantShop = new ShopLoginInfo(); - assistantShop.Cookies = JsonHelper.SerializeObject(lstWxSaleAssistantCookie); - var result = WXApi.wxGetAssistant(context.Shop.Cookie, dbProd.spu_id); + var prodCommissionRst = GetHtml.PostUtf8(url, date); + if (!prodCommissionRst.Contains("\"code\":200")) + { + var errMsg = BaseRegex.GetStringJsonByRegs(ref prodCommissionRst, prodCommissionRst, "msg"); + throw new Exception("拥金上货失败:" + errMsg); + } + context.Parameters.FromCommissionRate = BaseRegex.GetStringJson(ref prodCommissionRst, "commission_rate").ParseToNullableInt(); + if (context.Parameters.FromCommissionRate == null) + context.Parameters.FromCommissionRate = -1; + if (prodCommissionRst.Contains("\"data\":[]") || BaseRegex.GetStringJson(ref prodCommissionRst, "mdy_time").ParseToString().ParseToDateTime() < DateTime.Now.AddDays(-30)) + { + var assistantShop = new ShopLoginInfo(); + assistantShop.Cookies = "[]"; + var result = WXApi.wxGetAssistant(context.Parameters.Shop.Cookies, context.Product.SpuId); if (result.Html.Contains("mcn magic invalid")) - { - //throw new Exception("拥金上货失败:请先登录上货助手"); - Invoke(new Action(() => - { - //BaseMsgForm.ShowError - btnLoginAssistant_Click(null, null); - })); - assistantShop.Cookies = JsonHelper.SerializeObject(lstWxSaleAssistantCookie); - result = WXApi.wxGetAssistant(assistantShop, dbProd.spu_id); - if (result.Contains("mcn magic invalid")) - throw new Exception("拥金上货失败:请先登录上货助手"); - } - fromCommissionRate = BaseRegex.GetStringJson(ref result, "commissionRate").ParseToNullableInt(); - var prodName = BaseRegex.GetStringJson(ref result, "name"); - if (fromCommissionRate == null) - fromCommissionRate = -1; - if (prodName.IsNullOrEmpty()) - prodName = dbProd.product_name; - //if (fromCommissionRate != null && !string.IsNullOrEmpty(prodName)) - { - url = BaseClass.BuildObjString("product/wx_add_mdy_commission_rate"); - date = UserLogin.GetSignaturex(); - date += "&spu_id=" + dbProd.spu_id; - date += "&commission_rate=" + fromCommissionRate; - date += "&product_name=" + prodName; - var addCommissionRateRst = GetHtml.PostUtf8(url, date); - } - } - Invoke(new Action(() => + throw new Exception("拥金上货失败:请先登录上货助手"); + var resultHtml = result.Html; + context.Parameters.FromCommissionRate = BaseRegex.GetStringJson(ref resultHtml, "commissionRate").ParseToNullableInt(); + var prodName = BaseRegex.GetStringJson(ref resultHtml, "name"); + if (context.Parameters.FromCommissionRate == null) + context.Parameters.FromCommissionRate = -1; + if (prodName.IsNullOrEmpty()) + prodName = context.Product.Title; + //if (fromCommissionRate != null && !string.IsNullOrEmpty(prodName)) { - minCommissionRate = this.txtMinUpCommission.Text.Trim().ParseToInt() * 10000; - maxCommissionRate = this.txtMaxUpCommission.Text.Trim().ParseToInt() * 10000; - commissionRateChange = this.txtCommissionChangeValue.Text.Trim().ParseToInt() * 10000; - if (cmbCommissionAddOrReduce.Text != "增加") - commissionRateChange = -commissionRateChange; - commissionRate = fromCommissionRate.ParseToInt() + commissionRateChange; - })); - if (fromCommissionRate < minCommissionRate || fromCommissionRate > maxCommissionRate) - { - throw new Exception("拥金上货失败:原商品佣金比例 " + fromCommissionRate * 0.0001 + "% 超过设置的佣金范围!"); + url = BaseClass.BuildObjString("product/wx_add_mdy_commission_rate"); + date = UserLogin.GetSignaturex(); + date += "&spu_id=" + context.Product.SpuId; + date += "&commission_rate=" + context.Parameters.FromCommissionRate; + date += "&product_name=" + prodName; + var addCommissionRateRst = GetHtml.PostUtf8(url, date); } } - } + Invoke(new Action(() => + { + context.Parameters.MinCommissionRate = context.Parameters.CommissionMinPercent * 10000; + context.Parameters.MaxCommissionRate = context.Parameters.CommissionMaxPercent * 10000; + context.Parameters.CommissionRateChange = context.Parameters.CommissionChangePercent * 10000; + if (!context.Parameters.IsCommissionIncrease) + context.Parameters.CommissionRateChange = -context.Parameters.CommissionRateChange; + context.Parameters.CommissionRate = context.Parameters.FromCommissionRate.ParseToInt() + context.Parameters.CommissionRateChange; + })); + if (context.Parameters.FromCommissionRate < context.Parameters.MinCommissionRate || context.Parameters.FromCommissionRate > context.Parameters.MaxCommissionRate) + { + throw new Exception("拥金上货失败:原商品佣金比例 " + context.Parameters.FromCommissionRate * 0.0001 + "% 超过设置的佣金范围!"); + } + } + return Task.CompletedTask; + } } diff --git a/Store.Product/Publish/Steps/Wx/CompatibilityServices.cs b/Store.Product/Publish/Steps/Wx/CompatibilityServices.cs new file mode 100644 index 0000000..b1f1887 --- /dev/null +++ b/Store.Product/Publish/Steps/Wx/CompatibilityServices.cs @@ -0,0 +1,55 @@ +using AllBase.Model.DBModel; +using AllBase.Model.Result; +using AllBase.Model.Result.PDDResult; +using AllBase.Model.Result.WXResult; +using Store.Product.Models.Product; +using System; +using System.Collections.Generic; + +namespace Store.Product.Publish.Steps.Wx; + +internal static class AdminForms +{ + internal static class WXAdminQualificationImageForm + { + public static List AdminGetServerQualificationImageLst(out int pageCount, out decimal seconds, string category, string md5 = null) + { + pageCount = 0; + seconds = 0m; + return new List(); + } + } +} + +internal static class WXProdNoCheckEditHelper +{ + public static Dictionary dicShopAddressId { get; } = new Dictionary(); + + public static string SetShanghaiReturnOrderAddress(ShopLoginInfo shop) + { + throw new NotSupportedException("上海仓退货地址接口尚未迁移到 Store.Product。"); + } +} + +/// +/// 旧商品格式转换器的迁移占位。转换器包含 TEMUKJD 窗体项目依赖,调用时明确抛出异常。 +/// +internal sealed class PDDProdFormConverter +{ + public PDDProductInfo JstPddProdToPddConvert(out string convertRst, ProductBase product) => Throw(out convertRst); + public PDDProductInfo WXProdToPddConvert(out string convertRst, ProductBase product) => Throw(out convertRst); + public PDDProductInfo _1688ClientToPddConvert(out string convertRst, ProductBase product) => Throw(out convertRst); + public PDDProductInfo _1688OutToPddConvert(out string convertRst, ProductBase product) => Throw(out convertRst); + public PDDProductInfo WXClientToPddConvert(out string convertRst, ProductBase product) => Throw(out convertRst); + public string PddFrontToPddBackConvert(string content, bool flag1, object value, bool flag2, bool flag3) => Throw(out _); + public string PddFrontToPddBackConvert2(string content, bool flag1, object value, bool flag2, bool flag3) => Throw(out _); + public string PddFrontToPddBackConvert3(string content, bool flag1, object value, bool flag2, bool flag3) => Throw(out _); + public string PddFrontToPddBackConvertV4(string content, bool flag1, object value, bool flag2, bool flag3) => Throw(out _); + public string PddFrontToPddBackConvertFactory(string content, bool flag1, object value, bool flag2, bool flag3, string factoryContent) => Throw(out _); + + private static T Throw(out string convertRst) + { + convertRst = ""; + throw new NotSupportedException("商品格式转换器尚未迁移到 Store.Product。"); + } +} diff --git a/Store.Product/Publish/Steps/Wx/Convert1688ProductStep.cs b/Store.Product/Publish/Steps/Wx/Convert1688ProductStep.cs index 94201d5..9240128 100644 --- a/Store.Product/Publish/Steps/Wx/Convert1688ProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/Convert1688ProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,19 +34,20 @@ public sealed class Convert1688ProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (dbProd.product_get_type_text == "1688厂家") + if (context.Product.ProductGetTypeText == "1688厂家") { string convertRst = ""; - var pInfo = new PDDProdFormConverter()._1688ClientToPddConvert(out convertRst, dbProd); + var pInfo = new PDDProdFormConverter()._1688ClientToPddConvert(out convertRst, context.Product); if (!string.IsNullOrEmpty(convertRst)) throw new Exception("商品查询错误 " + convertRst); } - if (dbProd.product_get_type_text == "1688外部数据") + if (context.Product.ProductGetTypeText == "1688外部数据") { string convertRst = ""; - var pInfo = new PDDProdFormConverter()._1688OutToPddConvert(out convertRst, dbProd); + var pInfo = new PDDProdFormConverter()._1688OutToPddConvert(out convertRst, context.Product); if (!string.IsNullOrEmpty(convertRst)) throw new Exception("商品查询错误 " + convertRst); } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/ConvertCloudProductStep.cs b/Store.Product/Publish/Steps/Wx/ConvertCloudProductStep.cs index ca6fdca..476b026 100644 --- a/Store.Product/Publish/Steps/Wx/ConvertCloudProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/ConvertCloudProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,11 +34,11 @@ public sealed class ConvertCloudProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (dbProd.db_type == "云端数据" && dbProd.product_get_type_text == "多多") + if (context.Product.DbType == "云端数据" && context.Product.ProductGetTypeText == "多多") { string convertRst = ""; - var content = dbProd.product_json; + var content = context.Product.ProductJson; if (content.Contains("\"spec_keys\"") && content.Contains("\"spec_values\"") && content.Contains("\"is_sku_pre_sale\"")) { convertRst = new PDDProdFormConverter().PddFrontToPddBackConvert(content, true, null, true, false); @@ -73,7 +73,8 @@ public sealed class ConvertCloudProductStep : WxProductPublishStepBase if (convertRst.StartsWith("success")) convertRst = convertRst.Substring("success".Length); - dbProd.product_json = convertRst; + context.Product.ProductJson = convertRst; } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/ConvertJstPddProductStep.cs b/Store.Product/Publish/Steps/Wx/ConvertJstPddProductStep.cs index 76a0987..cff7a28 100644 --- a/Store.Product/Publish/Steps/Wx/ConvertJstPddProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/ConvertJstPddProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,21 +34,22 @@ public sealed class ConvertJstPddProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (dbProd.product_get_type_text == "厂商直采") + if (context.Product.ProductGetTypeText == "厂商直采") { - if (dbProd.sku_secret_json.IsNullOrEmpty() || !dbProd.sku_secret_json.Contains("goodsId")) + if (context.Product.SkuSecretJson.IsNullOrEmpty() || !context.Product.SkuSecretJson.Contains("goodsId")) { throw new Exception("商品查询格式错误"); } - if (dbProd.wx_cat_leaf.IsNullOrZero() || dbProd.send_to_out_server != 1 || dbProd.distribution_set != 1) + if (context.Product.WxCatLeaf.IsNullOrZero() || context.Product.SendToOutServer != 1 || context.Product.DistributionSet != 1) { throw new Exception("商品查询校验错误"); } string convertRst = ""; - var pInfo = new PDDProdFormConverter().JstPddProdToPddConvert(out convertRst, dbProd); + var pInfo = new PDDProdFormConverter().JstPddProdToPddConvert(out convertRst, context.Product); if (!string.IsNullOrEmpty(convertRst)) throw new Exception("商品查询错误 " + convertRst); } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/ConvertWxAppProductStep.cs b/Store.Product/Publish/Steps/Wx/ConvertWxAppProductStep.cs index 088136f..d36409b 100644 --- a/Store.Product/Publish/Steps/Wx/ConvertWxAppProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/ConvertWxAppProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,12 +34,13 @@ public sealed class ConvertWxAppProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (dbProd.product_get_type_text == "微信小店") + if (context.Product.ProductGetTypeText == "微信小店") { string convertRst = ""; - var pInfo = new PDDProdFormConverter().WXClientToPddConvert(out convertRst, dbProd); + var pInfo = new PDDProdFormConverter().WXClientToPddConvert(out convertRst, context.Product); if (!string.IsNullOrEmpty(convertRst)) throw new Exception("商品查询错误 " + convertRst); } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/ConvertWxRecycleProductStep.cs b/Store.Product/Publish/Steps/Wx/ConvertWxRecycleProductStep.cs index fe8d48e..68c52e6 100644 --- a/Store.Product/Publish/Steps/Wx/ConvertWxRecycleProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/ConvertWxRecycleProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,19 +34,20 @@ public sealed class ConvertWxRecycleProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (BaseClass.UserAuthority.ParseToString().Contains("微信回采") && chkUseWXComplateProd.Checked && dbProd.has_wx_format == "1") + if (BaseClass.UserAuthority.ParseToString().Contains("微信回采") && context.Parameters.IsUseWXComplateProd && context.Product.HasWxFormat == "1") { string errMsg = ""; - wxEditProdInfo = GetProductWXComplate(dbProd.secret_spu_id, out errMsg); + context.Parameters.WxEditProdInfo = GetProductWXComplate(context.Product.SecretSpuId, out errMsg); - if (wxEditProdInfo == null) + if (context.Parameters.WxEditProdInfo == null) { Invoke(new Action(() => { - cell.Value = errMsg; + context.Progress.Report(errMsg); })); throw new Exception("" + errMsg); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/ConvertWxShopProductStep.cs b/Store.Product/Publish/Steps/Wx/ConvertWxShopProductStep.cs index dfbf6ff..e5324cd 100644 --- a/Store.Product/Publish/Steps/Wx/ConvertWxShopProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/ConvertWxShopProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,12 +34,13 @@ public sealed class ConvertWxShopProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (dbProd.product_get_type_text == "微信店采") + if (context.Product.ProductGetTypeText == "微信店采") { string convertRst = ""; - var pInfo = new PDDProdFormConverter().WXProdToPddConvert(out convertRst, dbProd); + var pInfo = new PDDProdFormConverter().WXProdToPddConvert(out convertRst, context.Product); if (!string.IsNullOrEmpty(convertRst)) throw new Exception("商品查询错误 " + convertRst); } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/DetectCategoryStep.cs b/Store.Product/Publish/Steps/Wx/DetectCategoryStep.cs index ed8fdd0..8ef7149 100644 --- a/Store.Product/Publish/Steps/Wx/DetectCategoryStep.cs +++ b/Store.Product/Publish/Steps/Wx/DetectCategoryStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,36 +34,36 @@ public sealed class DetectCategoryStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成类目属性"; + context.Progress.Report("正在生成类目属性"); })); } - aiCateIdLst = new List(); + context.Parameters.AiCateIdLst = new List(); // 聚水潭商品已识别类目使用类目缓存 - if (dbProd.product_get_type_text == "厂商直采" && dbProd.wx_cat_leaf == null) + if (context.Product.ProductGetTypeText == "厂商直采" && context.Product.WxCatLeaf == null) { throw new Exception("该商品类目信息不完整"); } // 微信商品使用类目缓存 - if (!dbProd.wx_cat_leaf.IsNullOrZero()) + if (!context.Product.WxCatLeaf.IsNullOrZero()) { - if (dbProd.wx_cat_3 == 7370) - dbProd.wx_cat_3 = 547591; - if (dbProd.wx_cat_leaf == 7370) - dbProd.wx_cat_leaf = 547591; + if (context.Product.WxCat3 == 7370) + context.Product.WxCat3 = 547591; + if (context.Product.WxCatLeaf == 7370) + context.Product.WxCatLeaf = 547591; - if (!dbProd.wx_cat_1.IsNullOrZero()) - aiCateIdLst.Add(dbProd.wx_cat_1.ParseToLong()); - if (!dbProd.wx_cat_2.IsNullOrZero()) - aiCateIdLst.Add(dbProd.wx_cat_2.ParseToLong()); - if (!dbProd.wx_cat_3.IsNullOrZero()) - aiCateIdLst.Add(dbProd.wx_cat_3.ParseToLong()); - if (!dbProd.wx_cat_leaf.IsNullOrZero()) - aiCateIdLst.Add(dbProd.wx_cat_leaf.ParseToLong()); - aiCateIdLst = aiCateIdLst.Distinct().ToList(); + if (!context.Product.WxCat1.IsNullOrZero()) + context.Parameters.AiCateIdLst.Add(context.Product.WxCat1.ParseToLong()); + if (!context.Product.WxCat2.IsNullOrZero()) + context.Parameters.AiCateIdLst.Add(context.Product.WxCat2.ParseToLong()); + if (!context.Product.WxCat3.IsNullOrZero()) + context.Parameters.AiCateIdLst.Add(context.Product.WxCat3.ParseToLong()); + if (!context.Product.WxCatLeaf.IsNullOrZero()) + context.Parameters.AiCateIdLst.Add(context.Product.WxCatLeaf.ParseToLong()); + context.Parameters.AiCateIdLst = context.Parameters.AiCateIdLst.Distinct().ToList(); } else { @@ -74,7 +74,7 @@ public sealed class DetectCategoryStep : WxProductPublishStepBase List tempImgFullPathLst = new List(); //------------------------------------------------------------------------------------------------------------------------------------- // 生成ai识别类目所需图片 - var aiGalleries = prodInfo.detail.galleries.Where(g => g.type == 1).Take(3).ToList(); + var aiGalleries = context.Parameters.ProdInfo.detail.galleries.Where(g => g.type == 1).Take(3).ToList(); foreach (var gallery_item in aiGalleries) // 9张主图 { imgId++; @@ -139,7 +139,7 @@ public sealed class DetectCategoryStep : WxProductPublishStepBase //------------------------------------------------------------------------------------------------------------------------------------- // 根据Ai分类,获取类目信息 //{"code":0,"predInfo":{"firstCatRes":[{"catId":10000111,"catName":"服饰内衣","level":1},{"catId":10000111,"catName":"服饰内衣","level":1},{"catId":10000111,"catName":"服饰内衣","level":1}],"secondCatRes":[{"catId":10000113,"catName":"女装","level":2},{"catId":10000113,"catName":"女装","level":2},{"catId":10000113,"catName":"女装","level":2}],"thirdCatRes":[{"catId":547705,"catName":"牛仔裤","level":3,"modelVersion":""},{"catId":547704,"catName":"加绒裤","level":3,"modelVersion":"商品标题含'加绒加厚、保暖'等关键词,这表示裤子具备加绒保暖功能。主图展示了加绒内衬,也符合【服饰内衣:女装:裤子:加绒裤】类目特征。"},{"catId":547701,"catName":"休闲裤","level":3,"modelVersion":""}],"singleSecondCatRes":[],"singleFirstCatRes":[],"isSupportedCate":1},"aiCategoryList":[{"id":547705,"paths":[{"id":"10000111","name":"服饰内衣","sonIdList":["10000397","10000115","10000112","10000113","10000114"],"fId":"0","level":1,"leaf":false},{"id":"10000113","name":"女装","sonIdList":["546810","546811","530041","547706","6090","6089","6088","6087","6083","6076","6073","6070","6065","6063","6058","10000672","10000671","10000670","10000669","10000668","10000667","10000666","10000665","10000664","10000663","10000662","10000661","10000660","10000659","10000658","10000657","10000656","10000655"],"fId":"10000111","level":2,"leaf":false},{"id":"10000672","name":"裤子","sonIdList":["547699","547700","547701","547702","547703","547704","547705"],"fId":"10000113","level":3,"leaf":false},{"id":"547705","name":"牛仔裤","fId":"10000672","level":4,"leaf":true,"state":0,"hasTrialCategory":false,"isTrialCategory":false,"isLocalLife":false}],"depositAmount":0,"catAuth":true,"limitSubjectTypes":[]},{"id":547704,"paths":[{"id":"10000111","name":"服饰内衣","sonIdList":["10000397","10000115","10000112","10000113","10000114"],"fId":"0","level":1,"leaf":false},{"id":"10000113","name":"女装","sonIdList":["546810","546811","530041","547706","6090","6089","6088","6087","6083","6076","6073","6070","6065","6063","6058","10000672","10000671","10000670","10000669","10000668","10000667","10000666","10000665","10000664","10000663","10000662","10000661","10000660","10000659","10000658","10000657","10000656","10000655"],"fId":"10000111","level":2,"leaf":false},{"id":"10000672","name":"裤子","sonIdList":["547699","547700","547701","547702","547703","547704","547705"],"fId":"10000113","level":3,"leaf":false},{"id":"547704","name":"加绒裤","fId":"10000672","level":4,"leaf":true,"state":0,"hasTrialCategory":false,"isTrialCategory":false,"isLocalLife":false}],"depositAmount":0,"catAuth":true,"limitSubjectTypes":[]},{"id":547701,"paths":[{"id":"10000111","name":"服饰内衣","sonIdList":["10000397","10000115","10000112","10000113","10000114"],"fId":"0","level":1,"leaf":false},{"id":"10000113","name":"女装","sonIdList":["546810","546811","530041","547706","6090","6089","6088","6087","6083","6076","6073","6070","6065","6063","6058","10000672","10000671","10000670","10000669","10000668","10000667","10000666","10000665","10000664","10000663","10000662","10000661","10000660","10000659","10000658","10000657","10000656","10000655"],"fId":"10000111","level":2,"leaf":false},{"id":"10000672","name":"裤子","sonIdList":["547699","547700","547701","547702","547703","547704","547705"],"fId":"10000113","level":3,"leaf":false},{"id":"547701","name":"休闲裤","fId":"10000672","level":4,"leaf":true,"state":0,"hasTrialCategory":false,"isTrialCategory":false,"isLocalLife":false}],"depositAmount":0,"catAuth":true,"limitSubjectTypes":[]}],"version":"ProductClsRAG","noQualificationCatIds":[547705,547704,547701],"depositCatInfos":[{"catId":547705,"amountToPay":0,"error":false},{"catId":547704,"amountToPay":0,"error":false},{"catId":547701,"amountToPay":0,"error":false}],"visionCallMethod":"ProductClsRAG"} - var productClassifyRst = WXUpload.getProductClassify(shop, upProdInitParam.product.info.title, tempImgFullPathLst); + var productClassifyRst = WXUpload.getProductClassify(context.Parameters.Shop, context.Parameters.InitParameter.product.info.title, tempImgFullPathLst); if (!productClassifyRst.Contains("\"code\":0")) { var error = BaseRegex.GetStringJson(ref productClassifyRst, "msg"); @@ -153,7 +153,7 @@ public sealed class DetectCategoryStep : WxProductPublishStepBase cateInfo = JsonHelper.DeserializeJsonToObject(productClassifyRst); foreach (var catePath in cateInfo.aiCategoryList.FirstOrDefault().paths) { - aiCateIdLst.Add(catePath.id.ParseToLong()); + context.Parameters.AiCateIdLst.Add(catePath.id.ParseToLong()); } } catch (Exception ex) @@ -161,5 +161,6 @@ public sealed class DetectCategoryStep : WxProductPublishStepBase throw new Exception("" + "根据图片获取类目失败 " + ex.Message); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/FillMainImagesStep.cs b/Store.Product/Publish/Steps/Wx/FillMainImagesStep.cs index 90bad87..b985d92 100644 --- a/Store.Product/Publish/Steps/Wx/FillMainImagesStep.cs +++ b/Store.Product/Publish/Steps/Wx/FillMainImagesStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,14 +34,14 @@ public sealed class FillMainImagesStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - mainImgCount = (prodInfo?.detail?.galleries?.Where(g => g.type == 1).Count()).ParseToInt(); - if (mainImgCount > 0 && mainImgCount < 3) + context.Parameters.MainImgCount = (context.Parameters.ProdInfo?.detail?.galleries?.Where(g => g.type == 1).Count()).ParseToInt(); + if (context.Parameters.MainImgCount > 0 && context.Parameters.MainImgCount < 3) { - var gallery1 = prodInfo?.detail?.galleries?.Where(g => g.type == 2).FirstOrDefault(); + var gallery1 = context.Parameters.ProdInfo?.detail?.galleries?.Where(g => g.type == 2).FirstOrDefault(); // 先补一张 if (gallery1 != null) { - prodInfo.detail.galleries.Add(new gallery_item() + context.Parameters.ProdInfo.detail.galleries.Add(new gallery_item() { type = 1, url = gallery1.url, @@ -50,12 +50,12 @@ public sealed class FillMainImagesStep : WxProductPublishStepBase }); } // 如果补了只有两张再补一张 - if (mainImgCount == 1 && (prodInfo?.detail?.galleries?.Where(g => g.type == 1).Count()).ParseToInt() > 1) + if (context.Parameters.MainImgCount == 1 && (context.Parameters.ProdInfo?.detail?.galleries?.Where(g => g.type == 1).Count()).ParseToInt() > 1) { - var gallery2 = prodInfo?.detail?.galleries?[1]; + var gallery2 = context.Parameters.ProdInfo?.detail?.galleries?[1]; if (gallery2 != null) { - prodInfo.detail.galleries.Add(new gallery_item() + context.Parameters.ProdInfo.detail.galleries.Add(new gallery_item() { type = 1, url = gallery2.url, @@ -65,13 +65,14 @@ public sealed class FillMainImagesStep : WxProductPublishStepBase } } } - if ((prodInfo?.detail?.galleries?.Where(g => g.type == 1).Count()).ParseToInt() < 3) + if ((context.Parameters.ProdInfo?.detail?.galleries?.Where(g => g.type == 1).Count()).ParseToInt() < 3) { Invoke(new Action(() => { - cell.Value = "主图数量少于三张"; + context.Progress.Report("主图数量少于三张"); })); throw new Exception("主图数量少于三张"); } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/FilterDuplicateImagesStep.cs b/Store.Product/Publish/Steps/Wx/FilterDuplicateImagesStep.cs index e38cb83..69241b5 100644 --- a/Store.Product/Publish/Steps/Wx/FilterDuplicateImagesStep.cs +++ b/Store.Product/Publish/Steps/Wx/FilterDuplicateImagesStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,28 +34,28 @@ public sealed class FilterDuplicateImagesStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - needAddRandomBlock = false; - wantAddRandomBlock = chkImgRandomBlock.Checked && (/*upProdParam.product.info.category.FirstOrDefault()?.name == "图书" ||*/ - prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸" || dbProd.main_cat_name == "图书" || dbProd.main_cat_name == "书籍/杂志/报纸"); + context.Parameters.NeedAddRandomBlock = false; + context.Parameters.WantAddRandomBlock = context.Parameters.IsImageRandomBlock && (/*upProdParam.product.info.category.FirstOrDefault()?.name == "图书" ||*/ + context.Parameters.ProdInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸" || context.Product.MainCatName == "图书" || context.Product.MainCatName == "书籍/杂志/报纸"); { List galls = new List(); - foreach (var gall in prodInfo.detail.galleries.Where(g => g.type == 1).ToList()) + foreach (var gall in context.Parameters.ProdInfo.detail.galleries.Where(g => g.type == 1).ToList()) { if (!galls.Any(g => g.url == gall.url)/* && !prodInfo.detail.sku.Any(s => s.thumb_url == gall.url)*/) galls.Add(gall); } - foreach (var gall in prodInfo.detail.galleries.Where(g => g.type == 2).ToList()) + foreach (var gall in context.Parameters.ProdInfo.detail.galleries.Where(g => g.type == 2).ToList()) { if (!galls.Any(g => g.url == gall.url)/* && !prodInfo.detail.sku.Any(s => s.thumb_url == gall.url)*/) galls.Add(gall); } - prodInfo.detail.galleries.Clear(); - prodInfo.detail.galleries.AddRange(galls); + context.Parameters.ProdInfo.detail.galleries.Clear(); + context.Parameters.ProdInfo.detail.galleries.AddRange(galls); int repeatSn = 0; - while (prodInfo.detail.galleries.Where(g => g.type == 1).Count() > 0 && prodInfo.detail.galleries.Where(g => g.type == 1).Count() < 3) + while (context.Parameters.ProdInfo.detail.galleries.Where(g => g.type == 1).Count() > 0 && context.Parameters.ProdInfo.detail.galleries.Where(g => g.type == 1).Count() < 3) { repeatSn++; - var gallOld = prodInfo.detail.galleries.LastOrDefault(g => g.type == 1); + var gallOld = context.Parameters.ProdInfo.detail.galleries.LastOrDefault(g => g.type == 1); var gallNew = JsonHelper.DeserializeJsonToObject(JsonHelper.SerializeObject(gallOld)); // 如果有 替换掉之前附加的后缀 for (int i = 0; i < 10; i++) @@ -67,21 +67,22 @@ public sealed class FilterDuplicateImagesStep : WxProductPublishStepBase gallNew.url += "&re_sn1=" + repeatSn; else gallNew.url += "?re_sn1=" + repeatSn; - prodInfo.detail.galleries.Add(gallNew); - needAddRandomBlock = true; + context.Parameters.ProdInfo.detail.galleries.Add(gallNew); + context.Parameters.NeedAddRandomBlock = true; } - if (prodInfo.detail.galleries.Where(g => g.type == 1).Count() > 0 && prodInfo.detail.galleries.Where(g => g.type == 2).Count() <= 0) + if (context.Parameters.ProdInfo.detail.galleries.Where(g => g.type == 1).Count() > 0 && context.Parameters.ProdInfo.detail.galleries.Where(g => g.type == 2).Count() <= 0) { - var gallOld = prodInfo.detail.galleries.FirstOrDefault(g => g.type == 1); + var gallOld = context.Parameters.ProdInfo.detail.galleries.FirstOrDefault(g => g.type == 1); var gallNew = JsonHelper.DeserializeJsonToObject(JsonHelper.SerializeObject(gallOld)); if (gallNew.url.Contains("?")) gallNew.url += "&re_sn2=" + 1; else gallNew.url += "?re_sn2=" + 1; gallNew.type = 2; - prodInfo.detail.galleries.Add(gallNew); - needAddRandomBlock = true; + context.Parameters.ProdInfo.detail.galleries.Add(gallNew); + context.Parameters.NeedAddRandomBlock = true; } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/FissionTitleStep.cs b/Store.Product/Publish/Steps/Wx/FissionTitleStep.cs index 6e2f2fe..da18b34 100644 --- a/Store.Product/Publish/Steps/Wx/FissionTitleStep.cs +++ b/Store.Product/Publish/Steps/Wx/FissionTitleStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,21 +34,20 @@ public sealed class FissionTitleStep : WxProductPublishStepBase protected override Task CanExecuteProvider(WXPublishContext context, CancellationToken token) { - return CurrentUser.IsAuthorized("裂变调试") && chkFissionGoodsName.Checked; + return Task.FromResult(CurrentUser.IsAuthorized("裂变调试") && context.Parameters.IsFissionTitle); } protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - var titles = txtFissionTitle.Text.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList(); + var titles = context.Parameters.FissionTitles.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList(); if (titles.Count == 0) { - cancellationTokenSource.Cancel(); throw new Exception("裂变标题数量不足,将暂停上传"); } - selectProd.product_name = titles[0]; - selectProd.is_fission_title = true; + context.Parameters.SelectProduct.product_name = titles[0]; + context.Parameters.SelectProduct.is_fission_title = true; titles.RemoveAt(0); - txtFissionTitle.Text = string.Join("\r\n", titles); - context.Progress.Report("标题裂变成功,更改为:" + selectProd.product_name); + context.Parameters.FissionTitles = string.Join("\r\n", titles); + context.Progress.Report("标题裂变成功,更改为:" + context.Parameters.SelectProduct.product_name); return Task.CompletedTask; } diff --git a/Store.Product/Publish/Steps/Wx/GenerateAiProductImageStep.cs b/Store.Product/Publish/Steps/Wx/GenerateAiProductImageStep.cs index 69d933f..0ac8cd4 100644 --- a/Store.Product/Publish/Steps/Wx/GenerateAiProductImageStep.cs +++ b/Store.Product/Publish/Steps/Wx/GenerateAiProductImageStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,30 +34,30 @@ public sealed class GenerateAiProductImageStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (chkAiImage.Checked) + if (context.Parameters.IsAiImage) { int imgCount = 1; Invoke(new Action(() => { - if (cell != null) - cell.Value = "正在Ai生图"; - imgCount = txtAiImgCount.Text.Trim().ParseToInt(); + if (context.Progress != null) + context.Progress.Report("正在Ai生图"); + imgCount = context.Parameters.AiImageCount; if (imgCount == 0) imgCount = 1; })); List tList = new List(); List errStrLst = new List(); - for (int n = 0; n < upProdParam.product.info.headImg.Count && n < imgCount; n++) + for (int n = 0; n < context.Parameters.ProductParameter.product.info.headImg.Count && n < imgCount; n++) { while (tList.Count >= 10) { Thread.Sleep(500); tList.RemoveAll(t => t.IsCanceled || t.IsFaulted || t.IsCompleted); } - var tt = Task.Run(() => + var tt = Task.Run(async () => { - var imgUrl = GetAiImg(upProdParam.product.info.headImg[n], upProdParam.product.info.shortTitle); + var imgUrl = GetAiImg(context.Parameters.ProductParameter.product.info.headImg[n], context.Parameters.ProductParameter.product.info.shortTitle); if (imgUrl.StartsWith("生成Ai图片错误")) { errStrLst.Add(imgUrl); @@ -82,7 +82,7 @@ public sealed class GenerateAiProductImageStep : WxProductPublishStepBase var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; //upDate += "&is_file=true"; //if (needAddRandomBlock || wantAddRandomBlock) // upDate += "&random_code=true"; @@ -91,24 +91,24 @@ public sealed class GenerateAiProductImageStep : WxProductPublishStepBase var sTime = DateTime.Now; var apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在上传Ai主图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在上传Ai主图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 5 && apiUpImgFileRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref apiUpImgFileRst, "img_url"); if (apiUpImgFileRst.Contains("\"errcode\":0") && !string.IsNullOrEmpty(upImgUrl)) { - upProdParam.product.info.headImg[n] = upImgUrl; + context.Parameters.ProductParameter.product.info.headImg[n] = upImgUrl; //if (n == 0) // upProdParam.product.info.detail.detailImg.Insert(0, upImgUrl); } @@ -141,5 +141,6 @@ public sealed class GenerateAiProductImageStep : WxProductPublishStepBase throw new Exception(string.Join(",", errStrLst)); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/GenerateAiShortTitleStep.cs b/Store.Product/Publish/Steps/Wx/GenerateAiShortTitleStep.cs index b0238f2..10ad713 100644 --- a/Store.Product/Publish/Steps/Wx/GenerateAiShortTitleStep.cs +++ b/Store.Product/Publish/Steps/Wx/GenerateAiShortTitleStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,27 +34,27 @@ public sealed class GenerateAiShortTitleStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (wxUploadRule.IsAiShortTitle || chkAiImage.Checked) + if (context.Parameters.IsAiShortTitle || context.Parameters.IsAiImage) { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成短标题"; + context.Progress.Report("正在生成短标题"); })); } WXGetShortTitleParam titleParam = new WXGetShortTitleParam() { categories = new List(), - headImgUrls = upProdParam.product.info.headImg, - productTitle = upProdParam.product.info.title, + headImgUrls = context.Parameters.ProductParameter.product.info.headImg, + productTitle = context.Parameters.ProductParameter.product.info.title, }; - foreach (var cate in upProdParam.product.info.category) + foreach (var cate in context.Parameters.ProductParameter.product.info.category) { titleParam.categories.Add(new categorieParam() { catId = cate.catId, catName = cate.name }); } - var shortTitleRst = WXUpload.genProductShortTitle(shop, titleParam); + var shortTitleRst = WXUpload.genProductShortTitle(context.Parameters.Shop, titleParam); if (!shortTitleRst.Contains("\"code\":0") && !shortTitleRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref shortTitleRst, "msg"); @@ -62,9 +62,10 @@ public sealed class GenerateAiShortTitleStep : WxProductPublishStepBase error = shortTitleRst; throw new Exception("短标题获取失败 " + error); } - upProdParam.product.info.shortTitle = BaseRegex.GetStringJson(ref shortTitleRst, "shortTitle"); - upProdParam.product.info.aiGenShortTitle = upProdParam.product.info.shortTitle; - upProdParam.product.info.title = upProdParam.product.info.shortTitle + upProdParam.product.info.title; + context.Parameters.ProductParameter.product.info.shortTitle = BaseRegex.GetStringJson(ref shortTitleRst, "shortTitle"); + context.Parameters.ProductParameter.product.info.aiGenShortTitle = context.Parameters.ProductParameter.product.info.shortTitle; + context.Parameters.ProductParameter.product.info.title = context.Parameters.ProductParameter.product.info.shortTitle + context.Parameters.ProductParameter.product.info.title; } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/GenerateCategoryTemplateStep.cs b/Store.Product/Publish/Steps/Wx/GenerateCategoryTemplateStep.cs index 47aa697..199419a 100644 --- a/Store.Product/Publish/Steps/Wx/GenerateCategoryTemplateStep.cs +++ b/Store.Product/Publish/Steps/Wx/GenerateCategoryTemplateStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,33 +34,34 @@ public sealed class GenerateCategoryTemplateStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成类目模板"; + context.Progress.Report("正在生成类目模板"); })); } - if (aiCateIdLst.LastOrDefault() == 7370) + if (context.Parameters.AiCateIdLst.LastOrDefault() == 7370) { - aiCateIdLst.RemoveAt(aiCateIdLst.Count - 1); - aiCateIdLst.Add(547591); + context.Parameters.AiCateIdLst.RemoveAt(context.Parameters.AiCateIdLst.Count - 1); + context.Parameters.AiCateIdLst.Add(547591); } - getCateRst = WXUpload.getCategoryOnShelf(shop, aiCateIdLst); - if (!getCateRst.Contains("\"code\":0")) + context.Parameters.GetCateRst = WXUpload.getCategoryOnShelf(context.Parameters.Shop, context.Parameters.AiCateIdLst); + if (!context.Parameters.GetCateRst.Contains("\"code\":0")) { + var getCateRst = context.Parameters.GetCateRst; var error = BaseRegex.GetStringJson(ref getCateRst, "msg"); if (string.IsNullOrEmpty(error)) - error = getCateRst; + error = context.Parameters.GetCateRst; throw new Exception("获取类目模板失败" + error); } - jCateRst = JObject.Parse(getCateRst); - upProdParam.product.info.category = JsonHelper.DeserializeJsonToList(JsonHelper.SerializeObject(jCateRst["category"])); + context.Parameters.JCateRst = JObject.Parse(context.Parameters.GetCateRst); + context.Parameters.ProductParameter.product.info.category = JsonHelper.DeserializeJsonToList(JsonHelper.SerializeObject(context.Parameters.JCateRst["category"])); // 这里用了ai获取类目,如下填写 - upProdParam.product.info.recommendCategory = new recommendCategoryParam() + context.Parameters.ProductParameter.product.info.recommendCategory = new recommendCategoryParam() { isAccepted = true, categoryNames = new List(), @@ -68,69 +69,66 @@ public sealed class GenerateCategoryTemplateStep : WxProductPublishStepBase interfaceName = "ProductClsRAG", useNewInterface = 1, }; - foreach (var cateParam in upProdParam.product.info.category) + foreach (var cateParam in context.Parameters.ProductParameter.product.info.category) { - upProdParam.product.info.recommendCategory.categoryNames.Add(cateParam.name); + context.Parameters.ProductParameter.product.info.recommendCategory.categoryNames.Add(cateParam.name); } // 获取叶子类目id - leafCatId = (upProdParam.product.info.category.LastOrDefault()?.catId).ParseToLong(); //哲学经典著作 - bound = GlobalConfig.WxCatBoundList.FirstOrDefault(b => b.leaf_id == leafCatId); - if (leafCatId == 547591) - bound = GlobalConfig.WxCatBoundList.FirstOrDefault(b => b.leaf_id == 7370); - if (bound == null) + context.Parameters.LeafCatId = (context.Parameters.ProductParameter.product.info.category.LastOrDefault()?.catId).ParseToLong(); //哲学经典著作 + context.Parameters.Bound = GlobalConfig.WxCatBoundList.FirstOrDefault(b => b.leaf_id == context.Parameters.LeafCatId); + if (context.Parameters.LeafCatId == 547591) + context.Parameters.Bound = GlobalConfig.WxCatBoundList.FirstOrDefault(b => b.leaf_id == 7370); + if (context.Parameters.Bound == null) throw new Exception("获取类目保证金失败"); - maxBount = txtFilterBoundMax.Text.Trim().ParseToInt(); - minBount = txtFilterBoundMin.Text.Trim().ParseToInt(); - if (bound.cat_bound < minBount || bound.cat_bound > maxBount) - throw new Exception("类目保证金(" + bound.cat_bound + ")超过过滤限制(" + minBount + "-" + maxBount + ")"); + context.Parameters.MaxBound = context.Parameters.FilterBoundMaxSave; + context.Parameters.MinBound = context.Parameters.FilterBoundMinSave; + if (context.Parameters.Bound.cat_bound < context.Parameters.MinBound || context.Parameters.Bound.cat_bound > context.Parameters.MaxBound) + throw new Exception("类目保证金(" + context.Parameters.Bound.cat_bound + ")超过过滤限制(" + context.Parameters.MinBound + "-" + context.Parameters.MaxBound + ")"); // 定向类目需指定品牌Id - spBrandId = ""; - spBrandName = ""; - if (leafCatId == 547591) + if (context.Parameters.LeafCatId == 547591) { // 先写死 //spBrandId = 10914219.ToString(); - var rst = WXUpload.getMixBrand(shop, leafCatId.ToString()); - Invoke(new Action(() => { spBrandName = cmbSpBrandName.Text.Trim(); })); + var rst = WXUpload.getMixBrand(context.Parameters.Shop, context.Parameters.LeafCatId.ToString()); - if (!string.IsNullOrEmpty(spBrandName) && rst.Contains("\"code\":0")) + if (!string.IsNullOrEmpty(context.Parameters.SpecialBrandName) && rst.Contains("\"code\":0")) { var jObj = JsonHelper.JObjectParse(rst); if (rst.Contains("mixBrandList")) { foreach (var jItem in jObj["mixBrandList"]) // bizuinBrandList mixBrandList { - if (jItem["chName"].ParseToString() == spBrandName) - spBrandId = jItem["brandId"].ParseToString(); + if (jItem["chName"].ParseToString() == context.Parameters.SpecialBrandName) + context.Parameters.SpBrandId = jItem["brandId"].ParseToString(); } } if (rst.Contains("bizuinBrandList")) { foreach (var jItem in jObj["bizuinBrandList"]) // bizuinBrandList mixBrandList { - if (jItem["chName"].ParseToString() == spBrandName) - spBrandId = jItem["brandId"].ParseToString(); + if (jItem["chName"].ParseToString() == context.Parameters.SpecialBrandName) + context.Parameters.SpBrandId = jItem["brandId"].ParseToString(); } } } - if (spBrandId.IsNullOrEmpty()) + if (context.Parameters.SpBrandId.IsNullOrEmpty()) { throw new Exception("定向类目绑定品牌失败"); } // 国表定向类目 - upProdParam.product.info.brandId = spBrandId.ParseToLong(); + context.Parameters.ProductParameter.product.info.brandId = context.Parameters.SpBrandId.ParseToLong(); } else { // 检测是否有类目上传权限 - var cateUpCheckRst = WXUpload.batchCheckCategoryRelation(shop, leafCatId); + var cateUpCheckRst = WXUpload.batchCheckCategoryRelation(context.Parameters.Shop, context.Parameters.LeafCatId); //"{\"code\":0,\"list\":[{\"category_id\":\"1427\",\"result\":0,\"no_auth_reason_type\":0}]}" //"{\"code\":0,\"list\":[{\"category_id\":\"7486\",\"result\":0,\"no_auth_reason_type\":0}]}" if (!cateUpCheckRst.Contains("\"code\":0") && !cateUpCheckRst.Contains("\"success\":true")) @@ -142,20 +140,20 @@ public sealed class GenerateCategoryTemplateStep : WxProductPublishStepBase } if (!cateUpCheckRst.Contains("\"result\":1")) { - if (aiCateIdLst.FirstOrDefault() == 10000215) + if (context.Parameters.AiCateIdLst.FirstOrDefault() == 10000215) { //@"{""categoryInfo"":{""categories"":[{""id"":10000215},{""id"":10000222},{""id"":7483}],""categoryDeposit"":""1000.00"",""isNewApplyCat"":true,""licenseGroupList"":[{""licenseGroupId"":""1"",""license"":{""licenseId"":""4"",""cosIdList"":[""1771897594802-oM5657FQAaKYlf2uP300NBgx9HYY-0581""],""licenseFieldList"":[{""key"":""audit_license_registration_no"",""value"":""YB23509020049441""},{""key"":""search_url"",""value"":""""}],""isReuse"":true}}],""ruleVersion"":5234,""certificate"":[]},""brandIdList"":[],""leafCategoryId"":7483,""reuse"":0,""applyType"":""normalApply""}"; - var getCatDataRst = WXUpload.getSingleCategoryData(shop, leafCatId, aiCateIdLst); + var getCatDataRst = WXUpload.getSingleCategoryData(context.Parameters.Shop, context.Parameters.LeafCatId, context.Parameters.AiCateIdLst); if (!getCatDataRst.Contains("\"code\":0") && !getCatDataRst.Contains("\"success\":true")) { throw new Exception("类目申请失败 查询类目资质文件失败"); } WXCateAuthParam wxCateAuthParam = new WXCateAuthParam(); - wxCateAuthParam.leafCategoryId = leafCatId; - wxCateAuthParam.categoryInfo.categoryDeposit = bound.cat_bound.ToString("0.00"); + wxCateAuthParam.leafCategoryId = context.Parameters.LeafCatId; + wxCateAuthParam.categoryInfo.categoryDeposit = context.Parameters.Bound.cat_bound.ToString("0.00"); wxCateAuthParam.categoryInfo.ruleVersion = BaseRegex.GetIntJson(ref getCatDataRst, "ruleVersion"); - foreach (var cateId in aiCateIdLst) + foreach (var cateId in context.Parameters.AiCateIdLst) { wxCateAuthParam.categoryInfo.categories.Add(new WXCateId() { id = cateId }); } @@ -177,7 +175,7 @@ public sealed class GenerateCategoryTemplateStep : WxProductPublishStepBase var licenseFieldList = "[" + BaseRegex.GetMatchRegexString(ref getCatDataRst, "\"licenseFieldList\":\\[([\\s\\S]*?)\\]") + "]"; licenseGroup.license.licenseFieldList = JsonHelper.DeserializeJsonToList(licenseFieldList); } - var authCateRst = WXUpload.wxCateAuth(shop, aiCateIdLst, wxCateAuthParam); + var authCateRst = WXUpload.wxCateAuth(context.Parameters.Shop, context.Parameters.AiCateIdLst, wxCateAuthParam); if (!authCateRst.Contains("\"code\":0") && !authCateRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref authCateRst, "msg"); @@ -188,7 +186,7 @@ public sealed class GenerateCategoryTemplateStep : WxProductPublishStepBase throw new Exception("类目申请失败 " + error); } Thread.Sleep(Randomx.GetId(5000, 7000)); - cateUpCheckRst = WXUpload.batchCheckCategoryRelation(shop, leafCatId); + cateUpCheckRst = WXUpload.batchCheckCategoryRelation(context.Parameters.Shop, context.Parameters.LeafCatId); if (!cateUpCheckRst.Contains("\"code\":0") && !cateUpCheckRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref cateUpCheckRst, "msg"); @@ -208,7 +206,7 @@ public sealed class GenerateCategoryTemplateStep : WxProductPublishStepBase else { Thread.Sleep(Randomx.GetId(1000, 2000)); - var cateAuthorRst = WXUpload.addFinderCategoryV2(shop, leafCatId); + var cateAuthorRst = WXUpload.addFinderCategoryV2(context.Parameters.Shop, context.Parameters.LeafCatId); if (!cateAuthorRst.Contains("\"code\":0") && !cateAuthorRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref cateAuthorRst, "msg"); @@ -222,5 +220,6 @@ public sealed class GenerateCategoryTemplateStep : WxProductPublishStepBase } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/GetShopApiTokenStep.cs b/Store.Product/Publish/Steps/Wx/GetShopApiTokenStep.cs index 6249207..64264a2 100644 --- a/Store.Product/Publish/Steps/Wx/GetShopApiTokenStep.cs +++ b/Store.Product/Publish/Steps/Wx/GetShopApiTokenStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -35,26 +35,27 @@ public sealed class GetShopApiTokenStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { // 获取店铺的accessToken - token = lstWXShopTokenInfo.FirstOrDefault(t => t.shopId == shop.ShopId); - if (token == null) - token = new WXShopTokenInfo(); - if (token.isExpire || string.IsNullOrEmpty(token.accessToken)) + context.Parameters.Token = context.Parameters.WxShopTokenInfoList.FirstOrDefault(t => t.shopId == context.Parameters.Shop.ShopId); + if (context.Parameters.Token == null) + context.Parameters.Token = new WXShopTokenInfo(); + if (context.Parameters.Token.isExpire || string.IsNullOrEmpty(context.Parameters.Token.accessToken)) { - AuthInfo auth = GlobalConfig.lstWxShopAuthInfo.FirstOrDefault(sa => sa.ShopId == shop.ShopId); + AuthInfo auth = GlobalConfig.lstWxShopAuthInfo.FirstOrDefault(sa => sa.ShopId == context.Parameters.Shop.ShopId); //if (auth != null && auth.ExpiresTime > DateTime.Now.AddMinutes(5)) { - token = new WxApiBLL().GetShopWxToken(shop); + context.Parameters.Token = new WxApiBLL().GetShopWxToken(context.Parameters.Shop); - if (!string.IsNullOrEmpty(token.accessToken)) + if (!string.IsNullOrEmpty(context.Parameters.Token.accessToken)) { - lstWXShopTokenInfo.RemoveAll(t => t.shopId == shop.ShopId); - lstWXShopTokenInfo.Add(token); - NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_shop_token_list", lstWXShopTokenInfo); + context.Parameters.WxShopTokenInfoList.RemoveAll(t => t.shopId == context.Parameters.Shop.ShopId); + context.Parameters.WxShopTokenInfoList.Add(context.Parameters.Token); + NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_shop_token_list", context.Parameters.WxShopTokenInfoList); } } } // 如果店铺token不可用,随机获取一个上传图片的accessToken - if (token == null || token.isExpire || string.IsNullOrEmpty(token.accessToken)) - token = new WxApiBLL().GetRandomWxToken(); + if (context.Parameters.Token == null || context.Parameters.Token.isExpire || string.IsNullOrEmpty(context.Parameters.Token.accessToken)) + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/GetShopShippingTemplateStep.cs b/Store.Product/Publish/Steps/Wx/GetShopShippingTemplateStep.cs index f713738..7326c65 100644 --- a/Store.Product/Publish/Steps/Wx/GetShopShippingTemplateStep.cs +++ b/Store.Product/Publish/Steps/Wx/GetShopShippingTemplateStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,9 +21,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; -using Store.Framework.Extensions; namespace Store.Product.Publish.Steps.Wx; /// @@ -35,16 +34,18 @@ public sealed class GetShopShippingTemplateStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - expressRst = WXUpload.getFreightTemplate(shop); - if (!expressRst.Contains("\"code\":0") && !expressRst.Contains("\"success\":true")) + context.Parameters.ExpressRst = WXUpload.getFreightTemplate(context.Parameters.Shop); + if (!context.Parameters.ExpressRst.Contains("\"code\":0") && !context.Parameters.ExpressRst.Contains("\"success\":true")) { + var expressRst = context.Parameters.ExpressRst; var error = BaseRegex.GetStringJson(ref expressRst, "msg"); if (string.IsNullOrEmpty(error)) - error = expressRst; + error = context.Parameters.ExpressRst; throw new Exception("运费模板获取失败 " + error); } try { + var expressRst = context.Parameters.ExpressRst; var addressArr = JsonHelper.JObjectParse(expressRst)["freightTemplateList"]; foreach (var addressObj in addressArr) { @@ -52,20 +53,21 @@ public sealed class GetShopShippingTemplateStep : WxProductPublishStepBase if (addressObj["isDefault"].ParseToInt() == 1) { string templateId = addressObj["templateId"].ParseToString(); - upProdParam.product.info.expressInfo = new expressInfoParam(); - upProdParam.product.info.expressInfo.templateId = templateId; // BaseRegex.GetStringJson(ref expressRst, "templateId"); + context.Parameters.ProductParameter.product.info.expressInfo = new expressInfoParam(); + context.Parameters.ProductParameter.product.info.expressInfo.templateId = templateId; // BaseRegex.GetStringJson(ref expressRst, "templateId"); break; } } - if (upProdParam.product.info.expressInfo == null) + if (context.Parameters.ProductParameter.product.info.expressInfo == null) { - upProdParam.product.info.expressInfo = new expressInfoParam(); - upProdParam.product.info.expressInfo.templateId = BaseRegex.GetStringJson(ref expressRst, "templateId"); + context.Parameters.ProductParameter.product.info.expressInfo = new expressInfoParam(); + context.Parameters.ProductParameter.product.info.expressInfo.templateId = BaseRegex.GetStringJson(ref expressRst, "templateId"); } } catch (Exception ex) { throw new Exception("运费模板获取失败 " + ex.Message); } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/InitializeProductDataStep.cs b/Store.Product/Publish/Steps/Wx/InitializeProductDataStep.cs index 1ff7b77..a5dfe1e 100644 --- a/Store.Product/Publish/Steps/Wx/InitializeProductDataStep.cs +++ b/Store.Product/Publish/Steps/Wx/InitializeProductDataStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -21,9 +22,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; -using Store.Framework.Extensions; namespace Store.Product.Publish.Steps.Wx; /// @@ -36,33 +35,33 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - prodJObj = new JObject(); + context.Parameters.ProdJObject = new JObject(); try { - prodJObj = JObject.Parse(dbProd.product_json); + context.Parameters.ProdJObject = JObject.Parse(context.Product.ProductJson); var lstTitleReplaceText = new List(); - if (!txtReplaceText.Text.Trim().IsNullOrEmpty()) - lstTitleReplaceText.AddRange(txtReplaceText.Text.Trim().Split(new string[] { ",", ",", " ", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries)); + if (!context.Parameters.FilterWords.IsNullOrEmpty()) + lstTitleReplaceText.AddRange(context.Parameters.FilterWords.Split(new string[] { ",", ",", " ", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries)); // 过滤标题敏感词 if (lstTitleReplaceText.Count > 0) { - if (chkSkipReplaceText.Checked) + if (context.Parameters.IsSkipHasFilterWordsProd) { - if (lstTitleReplaceText.Any(t => selectProd.product_name.Contains(t))) + if (lstTitleReplaceText.Any(t => context.Parameters.SelectProduct.product_name.Contains(t))) throw new Exception("命中敏感词"); - if (lstTitleReplaceText.Any(t => dbProd.product_name.Contains(t))) + if (lstTitleReplaceText.Any(t => context.Product.Title.Contains(t))) throw new Exception("命中敏感词"); - var goods_name = prodJObj["detail"]["goods_name"].ParseToString(); + var goods_name = context.Parameters.ProdJObject["detail"]["goods_name"].ParseToString(); if (lstTitleReplaceText.Any(t => goods_name.Contains(t))) throw new Exception("命中敏感词"); - var tiny_name = prodJObj["detail"]["tiny_name"].ParseToString(); + var tiny_name = context.Parameters.ProdJObject["detail"]["tiny_name"].ParseToString(); if (lstTitleReplaceText.Any(t => tiny_name.Contains(t))) throw new Exception("命中敏感词"); - var goods_desc = prodJObj["detail"]["goods_desc"].ParseToString(); + var goods_desc = context.Parameters.ProdJObject["detail"]["goods_desc"].ParseToString(); if (lstTitleReplaceText.Any(t => goods_desc.Contains(t))) throw new Exception("命中敏感词"); - var share_desc = prodJObj["detail"]["share_desc"].ParseToString(); + var share_desc = context.Parameters.ProdJObject["detail"]["share_desc"].ParseToString(); if (lstTitleReplaceText.Any(t => share_desc.Contains(t))) throw new Exception("命中敏感词"); } @@ -70,67 +69,67 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase { foreach (var txt in lstTitleReplaceText) { - dbProd.product_name = dbProd.product_name.Replace(txt, ""); - selectProd.product_name = selectProd.product_name.Replace(txt, ""); + context.Product.Title = context.Product.Title.Replace(txt, ""); + context.Parameters.SelectProduct.product_name = context.Parameters.SelectProduct.product_name.Replace(txt, ""); } - var goods_name = prodJObj["detail"]["goods_name"].ParseToString(); + var goods_name = context.Parameters.ProdJObject["detail"]["goods_name"].ParseToString(); foreach (var txt in lstTitleReplaceText) { goods_name = goods_name.Replace(txt, ""); } - prodJObj["detail"]["goods_name"] = goods_name; + context.Parameters.ProdJObject["detail"]["goods_name"] = goods_name; - var tiny_name = prodJObj["detail"]["tiny_name"].ParseToString(); + var tiny_name = context.Parameters.ProdJObject["detail"]["tiny_name"].ParseToString(); foreach (var txt in lstTitleReplaceText) { tiny_name = tiny_name.Replace(txt, ""); } - prodJObj["detail"]["tiny_name"] = tiny_name; + context.Parameters.ProdJObject["detail"]["tiny_name"] = tiny_name; - var goods_desc = prodJObj["detail"]["goods_desc"].ParseToString(); + var goods_desc = context.Parameters.ProdJObject["detail"]["goods_desc"].ParseToString(); foreach (var txt in lstTitleReplaceText) { goods_desc = goods_desc.Replace(txt, ""); } - prodJObj["detail"]["goods_desc"] = goods_desc; + context.Parameters.ProdJObject["detail"]["goods_desc"] = goods_desc; - var share_desc = prodJObj["detail"]["share_desc"].ParseToString(); + var share_desc = context.Parameters.ProdJObject["detail"]["share_desc"].ParseToString(); foreach (var txt in lstTitleReplaceText) { share_desc = share_desc.Replace(txt, ""); } - prodJObj["detail"]["share_desc"] = share_desc; + context.Parameters.ProdJObject["detail"]["share_desc"] = share_desc; } } // 过滤标题特殊字符 - if (chkRemoveSpecialChar.Checked) + if (context.Parameters.IsRemoveSpecialChar) { var chLst = new List { ']', '】', ')', ')', '}', }; foreach (var ch in chLst) { - if (dbProd.product_name.Contains(ch) && dbProd.product_name.IndexOf(ch) < dbProd.product_name.Length / 2 && dbProd.product_name.Length > 10) - dbProd.product_name = dbProd.product_name.Substring(dbProd.product_name.IndexOf(ch)).Trim(ch); + 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); - if (selectProd.product_name.Contains(ch) && selectProd.product_name.IndexOf(ch) < selectProd.product_name.Length / 2 && selectProd.product_name.Length > 10) - selectProd.product_name = selectProd.product_name.Substring(selectProd.product_name.IndexOf(ch)).Trim(ch); + if (context.Parameters.SelectProduct.product_name.Contains(ch) && context.Parameters.SelectProduct.product_name.IndexOf(ch) < context.Parameters.SelectProduct.product_name.Length / 2 && context.Parameters.SelectProduct.product_name.Length > 10) + context.Parameters.SelectProduct.product_name = context.Parameters.SelectProduct.product_name.Substring(context.Parameters.SelectProduct.product_name.IndexOf(ch)).Trim(ch); - var goods_name = prodJObj["detail"]["goods_name"].ParseToString(); + 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) - prodJObj["detail"]["goods_name"] = goods_name.Substring(goods_name.IndexOf(ch)).Trim(ch); + context.Parameters.ProdJObject["detail"]["goods_name"] = goods_name.Substring(goods_name.IndexOf(ch)).Trim(ch); } } // 替换货号 - if (!string.IsNullOrEmpty(dbProd.ext_code)) - prodJObj["detail"]["out_goods_sn"] = dbProd.ext_code; + if (!string.IsNullOrEmpty(context.Product.ExtCode)) + context.Parameters.ProdJObject["detail"]["out_goods_sn"] = context.Product.ExtCode; // 替换编辑过的sku - if (!string.IsNullOrEmpty(dbProd.sku_edit_json)) - prodJObj["detail"]["sku"] = JArray.Parse(JsonHelper.SerializeObject(JsonHelper.DeserializeJsonToList(dbProd.sku_edit_json))); + if (!string.IsNullOrEmpty(context.Product.SkuEditJson)) + context.Parameters.ProdJObject["detail"]["sku"] = JArray.Parse(JsonHelper.SerializeObject(JsonHelper.DeserializeJsonToList(context.Product.SkuEditJson))); // 过滤sku敏感词 if (lstTitleReplaceText.Count > 0) { - var skuJArr = prodJObj["detail"]["sku"] as JArray; + var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray; try { foreach (var skuJObj in skuJArr) @@ -151,14 +150,14 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase } } // 同颜色规格向上浮动同价格 - if (chkSameSpecPriceUp.Checked) + if (context.Parameters.SameSpecSamePriceUp) { - var priceTextLst = dbProd.price_text.Split('-'); + var priceTextLst = context.Product.PriceText.Split('-'); if (priceTextLst.Length != 2 || priceTextLst[0] != priceTextLst[1]) { Dictionary specPriceDic = new Dictionary(); Dictionary specMultiPriceDic = new Dictionary(); - var skuJArr = prodJObj["detail"]["sku"] as JArray; + var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray; try { // 计算主spec的最高价 @@ -189,14 +188,14 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase } } // 同颜色规格向下浮动同价格 - if (chkSameSpecPriceDown.Checked) + if (context.Parameters.SameSpecSamePriceDown) { - var priceTextLst = dbProd.price_text.Split('-'); + var priceTextLst = context.Product.PriceText.Split('-'); if (priceTextLst.Length != 2 || priceTextLst[0] != priceTextLst[1]) { Dictionary specPriceDic = new Dictionary(); Dictionary specMultiPriceDic = new Dictionary(); - var skuJArr = prodJObj["detail"]["sku"] as JArray; + var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray; try { // 计算主spec的最低价 @@ -227,10 +226,10 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase } } // 只保留最高价 - if (chkHighestPriceSku.Checked) + if (context.Parameters.OnlyHighestPriceSku) { int price = 0; - var skuJArr = prodJObj["detail"]["sku"] as JArray; + var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray; try { // 计算主spec的最高价 @@ -240,7 +239,7 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase price = skuJObj["multi_price"].ParseToInt(); } - var product_json_tmp = JsonHelper.SerializeObject(prodJObj); + var product_json_tmp = JsonHelper.SerializeObject(context.Parameters.ProdJObject); // 移除第一组所有sku skuJArr.RemoveAll(); @@ -264,10 +263,10 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase } } // 只保留最低价 - if (chkLowestPriceSku.Checked) + if (context.Parameters.OnlyLowestPriceSku) { int price = 99999999; - var skuJArr = prodJObj["detail"]["sku"] as JArray; + var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray; try { // 计算主spec的最低价 @@ -277,7 +276,7 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase price = skuJObj["multi_price"].ParseToInt(); } - var product_json_tmp = JsonHelper.SerializeObject(prodJObj); + var product_json_tmp = JsonHelper.SerializeObject(context.Parameters.ProdJObject); // 移除第一组所有sku skuJArr.RemoveAll(); @@ -301,12 +300,12 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase } } // 过滤低价sku,如果所有sku都不达标,跳过商品 - if (!string.IsNullOrEmpty(txtMinPrice.Text)) + if (context.Parameters.SkuMinPrice > 0) { - var product_json_tmp = JsonHelper.SerializeObject(prodJObj); + var product_json_tmp = JsonHelper.SerializeObject(context.Parameters.ProdJObject); // 移除第一组所有sku - var skuJArr = prodJObj["detail"]["sku"] as JArray; + var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray; skuJArr.RemoveAll(); // 序列化第二组,从组中挑选符合价格条件的sku往第一组内填写 @@ -314,9 +313,9 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase var skuJArr2 = prodJObj2["detail"]["sku"] as JArray; foreach (var skuJObj2 in skuJArr2) { - var limitMinPrice = this.txtMinPrice.Text.Trim().ParseToDecimal() * 100; + var limitMinPrice = context.Parameters.SkuMinPrice * 100; // 供应商价加价10%(最低1元)赚取差价 先加价后过滤,过滤条件也要相应增加10% - //if (dbProd.product_get_type_text == "厂商直采") + //if (context.Product.ProductGetTypeText == "厂商直采") // limitPrice += Math.Max(100m, limitPrice * 0.1m); if (skuJObj2["multi_price"].ParseToInt() >= limitMinPrice) skuJArr.Add(skuJObj2); @@ -327,12 +326,12 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase } } // 过滤高价sku,如果所有sku都不达标,跳过商品 - if (!string.IsNullOrEmpty(txtMaxPrice.Text)) + if (context.Parameters.SkuMaxPrice < int.MaxValue) { - var product_json_tmp = JsonHelper.SerializeObject(prodJObj); + var product_json_tmp = JsonHelper.SerializeObject(context.Parameters.ProdJObject); // 移除第一组所有sku - var skuJArr = prodJObj["detail"]["sku"] as JArray; + var skuJArr = context.Parameters.ProdJObject["detail"]["sku"] as JArray; skuJArr.RemoveAll(); // 序列化第二组,从组中挑选符合价格条件的sku往第一组内填写 @@ -340,9 +339,9 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase var skuJArr2 = prodJObj2["detail"]["sku"] as JArray; foreach (var skuJObj2 in skuJArr2) { - var limitMaxPrice = this.txtMaxPrice.Text.Trim().ParseToDecimal() * 100; + var limitMaxPrice = context.Parameters.SkuMaxPrice * 100; // 供应商价加价10%(最低1元)赚取差价 先加价后过滤,过滤条件也要相应增加10% - //if (dbProd.product_get_type_text == "厂商直采") + //if (context.Product.ProductGetTypeText == "厂商直采") // limitPrice += Math.Max(100m, limitPrice * 0.1m); if (skuJObj2["multi_price"].ParseToInt() <= limitMaxPrice) skuJArr.Add(skuJObj2); @@ -353,11 +352,12 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase } } - dbProd.product_json = JsonHelper.SerializeObject(prodJObj); + context.Product.ProductJson = JsonHelper.SerializeObject(context.Parameters.ProdJObject); } catch (Exception ex) { throw new Exception("商品数据初始化失败" + ex.Message); } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/InitializeUploadProductStep.cs b/Store.Product/Publish/Steps/Wx/InitializeUploadProductStep.cs index b5bb18c..265c202 100644 --- a/Store.Product/Publish/Steps/Wx/InitializeUploadProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/InitializeUploadProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,11 +34,11 @@ public sealed class InitializeUploadProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (shop == null || string.IsNullOrEmpty(shop.ShopId) || shop.LoginStatus != "登录成功") + if (context.Parameters.Shop == null || string.IsNullOrEmpty(context.Parameters.Shop.ShopId) || context.Parameters.Shop.LoginStatus != "登录成功") { throw new Exception("店铺为空或未登录!"); } - if (cell != null) + if (context.Progress != null) { context.Progress.Report("正在初始化上传"); } diff --git a/Store.Product/Publish/Steps/Wx/MatchProductPropertiesStep.cs b/Store.Product/Publish/Steps/Wx/MatchProductPropertiesStep.cs index c0499e5..85ed853 100644 --- a/Store.Product/Publish/Steps/Wx/MatchProductPropertiesStep.cs +++ b/Store.Product/Publish/Steps/Wx/MatchProductPropertiesStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -35,16 +35,16 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { //真丝、蚕丝、香云纱、羊绒、羊毛、羊羔毛、羽绒、皮草 - upProdParam.product.info.param = new List(); // 商品属性值 - productAttr = upProdParam.product.info.category.LastOrDefault().catInfo.productAttr; + context.Parameters.ProductParameter.product.info.param = new List(); // 商品属性值 + context.Parameters.ProductAttr = context.Parameters.ProductParameter.product.info.category.LastOrDefault().catInfo.productAttr; // 直接转换微信回采 - if (BaseClass.UserAuthority.ParseToString().Contains("微信回采") && chkUseWXComplateProd.Checked && dbProd.has_wx_format == "1" && wxEditProdInfo != null) + if (BaseClass.UserAuthority.ParseToString().Contains("微信回采") && context.Parameters.IsUseWXComplateProd && context.Product.HasWxFormat == "1" && context.Parameters.WxEditProdInfo != null) { - foreach (var wxEditPropParam in wxEditProdInfo.product.info.param) + foreach (var wxEditPropParam in context.Parameters.WxEditProdInfo.product.info.param) { var wxPropParam = new wxPropParam(); - upProdParam.product.info.param.Add(wxPropParam); + context.Parameters.ProductParameter.product.info.param.Add(wxPropParam); foreach (var wxEditCategoryParam in wxEditPropParam.categorys) { var wxCategoryParam = new categoryPropParam() @@ -63,18 +63,18 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase } } // 直接转换微信店采 - else if (dbProd.product_get_type_text == "微信店采") + else if (context.Product.ProductGetTypeText == "微信店采") { - foreach (var wxEditPropParam in wxEditProdInfo.product.info.param) + foreach (var wxEditPropParam in context.Parameters.WxEditProdInfo.product.info.param) { var wxPropParam = new wxPropParam(); - upProdParam.product.info.param.Add(wxPropParam); + context.Parameters.ProductParameter.product.info.param.Add(wxPropParam); foreach (var wxEditCategoryParam in wxEditPropParam.categorys) { // 修改书名 if (wxEditPropParam.categorys.FirstOrDefault().name == "书名" && wxEditCategoryParam == wxEditPropParam.categorys.LastOrDefault()) { - wxEditCategoryParam.name = prodTitle; + wxEditCategoryParam.name = context.Product.Title; } var wxCategoryParam = new categoryPropParam() { @@ -93,7 +93,7 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase } else { - foreach (var propInfo in prodInfo.property.goods_properties) + foreach (var propInfo in context.Parameters.ProdInfo.property.goods_properties) { if (propInfo.name == "容量") { @@ -107,9 +107,9 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase continue; - var attr = productAttr.attr.FirstOrDefault(r => r.name == propInfo.name); + var attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == propInfo.name); if (attr == null) - attr = productAttr.attr.FirstOrDefault(r => r.name.Replace("填充材料", "填充材质") == propInfo.name || + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name.Replace("填充材料", "填充材质") == propInfo.name || r.name.Replace("材质", "材质种类") == propInfo.name); // 材质 产品名称 适用年龄 面料 生产企业名称 CCC证书编号 尺寸(长) 尺寸(宽) 尺寸(高) 物品(含配件)清单 型号 产品名称 if (propInfo.name == "生产日期" && propInfo.values.Count > 0) @@ -121,69 +121,69 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase { if (propInfo.name.Contains("面料俗称")) { - attr = productAttr.attr.FirstOrDefault(r => r.name == "面料材质"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "面料材质"); } if (propInfo.name.Contains("适用年龄")) { - attr = productAttr.attr.FirstOrDefault(r => r.name == "适用年龄" || r.name == "适用年龄段"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "适用年龄" || r.name == "适用年龄段"); } if (propInfo.name.Contains("填充物")) { - attr = productAttr.attr.FirstOrDefault(r => r.name == "填充物种类" || r.name == "填充物"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "填充物种类" || r.name == "填充物"); } // 书籍类目属性匹配 - if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "图书" || context.Parameters.ProdInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { if (propInfo.name == "出版社名称") - attr = productAttr.attr.FirstOrDefault(r => r.name == "出版社名称"); - else if ((propInfo.name == "ISBN编号" || propInfo.name == "书号") && !prodInfo.property.goods_properties.Any(p => p.name == "ISBN版号/CN刊号")) - attr = productAttr.attr.FirstOrDefault(r => r.name == "ISBN版号/CN刊号"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "出版社名称"); + else if ((propInfo.name == "ISBN编号" || propInfo.name == "书号") && !context.Parameters.ProdInfo.property.goods_properties.Any(p => p.name == "ISBN版号/CN刊号")) + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "ISBN版号/CN刊号"); else if (propInfo.name == "书名") - attr = productAttr.attr.FirstOrDefault(r => r.name == "书名"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "书名"); else if (propInfo.name == "定价") - attr = productAttr.attr.FirstOrDefault(r => r.name == "定价"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "定价"); else if (propInfo.name == "作者") - attr = productAttr.attr.FirstOrDefault(r => r.name == "作者"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "作者"); else if (propInfo.name == "出版时间") - attr = productAttr.attr.FirstOrDefault(r => r.name == "出版时间"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "出版时间"); else if (propInfo.name == "版次") - attr = productAttr.attr.FirstOrDefault(r => r.name == "版次"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "版次"); else if (propInfo.name == "装帧类型") - attr = productAttr.attr.FirstOrDefault(r => r.name == "包装"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "包装"); else if (propInfo.name == "包册数") - attr = productAttr.attr.FirstOrDefault(r => r.name == "图书册数"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "图书册数"); } - if (upProdParam.product.info.category.FirstOrDefault()?.name == "食品饮料" || prodInfo.detail.cats.FirstOrDefault() == "食品饮料") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "食品饮料" || context.Parameters.ProdInfo.detail.cats.FirstOrDefault() == "食品饮料") { if (propInfo.name == "厂名") - attr = productAttr.attr.FirstOrDefault(r => r.name == "生产企业名称"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "生产企业名称"); else if (propInfo.name == "食品生产许可证编号") - attr = productAttr.attr.FirstOrDefault(r => r.name == "食品生产许可证编号"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "食品生产许可证编号"); else if (propInfo.name == "产品标准号") - attr = productAttr.attr.FirstOrDefault(r => r.name == "产品标准号"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "产品标准号"); else if (propInfo.name == "保质期") - attr = productAttr.attr.FirstOrDefault(r => r.name == "保质期"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "保质期"); else if (propInfo.name == "生产日期") { - attr = productAttr.attr.FirstOrDefault(r => r.name == "生产日期"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "生产日期"); } else if (propInfo.name == "产品重量") { - attr = productAttr.attr.FirstOrDefault(r => r.name == "单件净含量"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "单件净含量"); if (attr == null) - attr = productAttr.attr.FirstOrDefault(r => r.name == "净含量"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "净含量"); } else if (propInfo.name == "包装方式") - attr = productAttr.attr.FirstOrDefault(r => r.name == "包装方式"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "包装方式"); //else if (propInfo.name == "配料表") // attr = productAttr.attr.FirstOrDefault(r => r.name == "配料表"); //else if (propInfo.name == "联系方式") // attr = productAttr.attr.FirstOrDefault(r => r.name == "联系方式"); else if (propInfo.name == "厂址") - attr = productAttr.attr.FirstOrDefault(r => r.name == "地址"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "地址"); else if (propInfo.name == "储藏方法") - attr = productAttr.attr.FirstOrDefault(r => r.name == "贮存条件"); + attr = context.Parameters.ProductAttr.attr.FirstOrDefault(r => r.name == "贮存条件"); } } if (attr == null) @@ -227,12 +227,12 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase attrValue = propInfo.values.FirstOrDefault()?.value; } //书籍属性处理 - if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "图书" || context.Parameters.ProdInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { // 修改书名 作者 - if (attr.name == "书名" /*&& dbProd.product_get_type_text == "微信小店"*/) + if (attr.name == "书名" /*&& context.Product.ProductGetTypeText == "微信小店"*/) { - attrValue = prodTitle; + attrValue = context.Product.Title; } if (attr.name == "作者" && attrValue == "无") { @@ -275,9 +275,9 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase attrValue = "中国大陆"; else { - var value = values.FirstOrDefault(v => prodTitle.ParseToString().Contains(v)); + var value = values.FirstOrDefault(v => context.Product.Title.ParseToString().Contains(v)); if (value == null) - value = values.FirstOrDefault(v => prodTitle.ParseToString().Contains(string.Join("", v.Take(2)))); + value = values.FirstOrDefault(v => context.Product.Title.ParseToString().Contains(string.Join("", v.Take(2)))); if (value == null) value = values.FirstOrDefault(v => "北京;天津;上海;重庆;河北;山西;内蒙古;辽宁;吉林;黑龙江;江苏;浙江;安徽;福建;江西;山东;河南;湖北;湖南;广东;广西;海南;四川;贵州;云南;西藏;陕西;甘肃;青海;宁夏;新疆".Contains(string.Join("", v.Take(2)))); attrValue = value; @@ -461,7 +461,7 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase } else { - var param = recommendParamRst.productInfo.param.FirstOrDefault(p => p.categorys?.FirstOrDefault()?.name == attr.name); + var param = context.Parameters.RecommendParamRst.productInfo.param.FirstOrDefault(p => p.categorys?.FirstOrDefault()?.name == attr.name); if (param != null && param.categorys.Count == 2) { attrValue = param.categorys[1].name; @@ -499,7 +499,7 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase continue; var wxPropParam = new wxPropParam(); - upProdParam.product.info.param.Add(wxPropParam); + context.Parameters.ProductParameter.product.info.param.Add(wxPropParam); var wxCategoryParam1 = new categoryPropParam() { catType = 7, @@ -516,22 +516,22 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase wxPropParam.categorys.Add(wxCategoryParam2); } } - foreach (var wxPropParam in upProdParam.product.info.param) + foreach (var wxPropParam in context.Parameters.ProductParameter.product.info.param) { if (wxPropParam.categorys.Count > 0 && wxPropParam.categorys.FirstOrDefault().name == "作者" && (wxPropParam.categorys.LastOrDefault().name == "无" || wxPropParam.categorys.LastOrDefault().name == "-" || wxPropParam.categorys.LastOrDefault().name == "/")) { - wxPropParam.categorys.LastOrDefault().name = upProdParam.product.info.param.FirstOrDefault(p => p.categorys.FirstOrDefault()?.name == "出版社名称").categorys.LastOrDefault()?.name; + wxPropParam.categorys.LastOrDefault().name = context.Parameters.ProductParameter.product.info.param.FirstOrDefault(p => p.categorys.FirstOrDefault()?.name == "出版社名称").categorys.LastOrDefault()?.name; } } - foreach (var attr in productAttr.attr) + foreach (var attr in context.Parameters.ProductAttr.attr) { if (attr.isRequired != true) continue; // 已填写内没有但是必填属性 - if (upProdParam.product.info.param.Any(p => p.categorys.FirstOrDefault()?.name == attr.name)) + if (context.Parameters.ProductParameter.product.info.param.Any(p => p.categorys.FirstOrDefault()?.name == attr.name)) continue; var attrValueLst = attr.value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries).ToList(); @@ -571,9 +571,9 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase attrValue = "中国大陆"; else { - var value = values.FirstOrDefault(v => prodTitle.ParseToString().Contains(v)); + var value = values.FirstOrDefault(v => context.Product.Title.ParseToString().Contains(v)); if (value == null) - value = values.FirstOrDefault(v => prodTitle.ParseToString().Contains(string.Join("", v.Take(2)))); + value = values.FirstOrDefault(v => context.Product.Title.ParseToString().Contains(string.Join("", v.Take(2)))); if (value == null) value = values.FirstOrDefault(v => "北京;天津;上海;重庆;河北;山西;内蒙古;辽宁;吉林;黑龙江;江苏;浙江;安徽;福建;江西;山东;河南;湖北;湖南;广东;广西;海南;四川;贵州;云南;西藏;陕西;甘肃;青海;宁夏;新疆".Contains(string.Join("", v.Take(2)))); attrValue = value; @@ -600,12 +600,12 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase attrValue = attrValueLst.Where(v => !"真丝、蚕丝、香云纱、羊绒、羊毛、羊羔绒、羊羔毛、羽绒、皮草".Contains(v)).OrderBy(x => Guid.NewGuid()).FirstOrDefault(); //书籍属性处理 - if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "图书" || context.Parameters.ProdInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { //if (attr.name == "ISBN版号/CN刊号") // attrValue = "9787922575016"; if (attr.name == "书名") - attrValue = prodTitle; + attrValue = context.Product.Title; if (attr.name == "是否为单一书号丛书") attrValue = "是"; if (attr.name == "图书册数") @@ -622,10 +622,10 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase if (attr.name == "出版时间") attrValue = DateTime.Now.AddMonths(0 - Randomx.GetId(3, 7)).ToString("yyyy-MM"); } - if (upProdParam.product.info.category.FirstOrDefault()?.name == "食品饮料" || prodInfo.detail.cats.FirstOrDefault() == "食品饮料") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "食品饮料" || context.Parameters.ProdInfo.detail.cats.FirstOrDefault() == "食品饮料") { if (attr.name == "食品名称") - attrValue = prodTitle; + attrValue = context.Product.Title; if (attr.name == "生产企业名称") attrValue = "见包装"; if (attr.name == "食品生产许可证编号") @@ -659,21 +659,21 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase //if (attr.name == "保质期") //{ - // if (chkDefaultBestBefore.Checked == false) + // if (context.Parameters.IsDefaultBestBefore == false) //throw new Exception("食品属性不含保质期,跳过上传"); - // if (txtDefaultBestBefore.Text.ParseToInt() < 15) + // if (context.Parameters.DefaultBestBeforeDays < 15) //throw new Exception("食品默认保质期设置小于15天,跳过上传"); - // attrValue = txtDefaultBestBefore.Text.ParseToInt() + " 天"; + // attrValue = context.Parameters.DefaultBestBeforeDays + " 天"; //} } if (attr.name == "保质期") { - if (chkDefaultBestBefore.Checked == false) + if (context.Parameters.IsDefaultBestBefore == false) throw new Exception("属性不含保质期,跳过上传"); - if (txtDefaultBestBefore.Text.ParseToInt() < 3) + if (context.Parameters.DefaultBestBeforeDays < 3) throw new Exception("默认保质期设置小于3天,跳过上传"); - attrValue = txtDefaultBestBefore.Text.ParseToInt() + " 天"; + attrValue = context.Parameters.DefaultBestBeforeDays + " 天"; } } if (attrValue.IsNullOrEmpty() && attr.type == "string") @@ -683,7 +683,7 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase if ((attrValue.IsNullOrEmpty() || attrValue == "见包装" || attrValue == "%") && (attr.type == "decimal4_unit" || attr.type == "integer_unit")) { // 走系统推荐 - var param = recommendParamRst.productInfo.param.FirstOrDefault(p => p.categorys?.FirstOrDefault()?.name == attr.name); + var param = context.Parameters.RecommendParamRst.productInfo.param.FirstOrDefault(p => p.categorys?.FirstOrDefault()?.name == attr.name); if (param != null && param.categorys.Count == 2) { attrValue = param.categorys[1].name; @@ -726,7 +726,7 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase } var wxPropParam = new wxPropParam(); - upProdParam.product.info.param.Add(wxPropParam); + context.Parameters.ProductParameter.product.info.param.Add(wxPropParam); var wxCategoryParam1 = new categoryPropParam() { catType = 7, @@ -742,18 +742,19 @@ public sealed class MatchProductPropertiesStep : WxProductPublishStepBase wxPropParam.categorys.Add(wxCategoryParam1); wxPropParam.categorys.Add(wxCategoryParam2); } - if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "图书" || context.Parameters.ProdInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { - foreach (var param in upProdParam.product.info.param.ToList()) + foreach (var param in context.Parameters.ProductParameter.product.info.param.ToList()) { if (param.categorys.FirstOrDefault()?.name == "作者" && param.categorys.LastOrDefault()?.name == "无") { - param.categorys.LastOrDefault().name = upProdParam.product.info.param.FirstOrDefault(p => p.categorys.FirstOrDefault()?.name == "出版社名称")?.categorys?.LastOrDefault()?.name; + param.categorys.LastOrDefault().name = context.Parameters.ProductParameter.product.info.param.FirstOrDefault(p => p.categorys.FirstOrDefault()?.name == "出版社名称")?.categorys?.LastOrDefault()?.name; if (param.categorys.LastOrDefault().name.IsNullOrEmpty()) param.categorys.LastOrDefault().name = "无"; break; } } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/PrepareHotlinkImageMapStep.cs b/Store.Product/Publish/Steps/Wx/PrepareHotlinkImageMapStep.cs index 598ccf9..a14fdd1 100644 --- a/Store.Product/Publish/Steps/Wx/PrepareHotlinkImageMapStep.cs +++ b/Store.Product/Publish/Steps/Wx/PrepareHotlinkImageMapStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,19 +34,20 @@ public sealed class PrepareHotlinkImageMapStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - isChangeImgDic = false; - wxImgMapDic = new Dictionary(); - if (!string.IsNullOrEmpty(dbProd.wx_img_map_json)) + context.Parameters.IsChangeImgDic = false; + context.Parameters.WxImgMapDic = new Dictionary(); + if (!string.IsNullOrEmpty(context.Product.WxImgMapJson)) { try { - wxImgMapDic = JsonHelper.DeserializeJsonToObject>(dbProd.wx_img_map_json); + context.Parameters.WxImgMapDic = JsonHelper.DeserializeJsonToObject>(context.Product.WxImgMapJson); } catch { - isChangeImgDic = true; - wxImgMapDic = new Dictionary(); + context.Parameters.IsChangeImgDic = true; + context.Parameters.WxImgMapDic = new Dictionary(); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/PrepareSourceProductStep.cs b/Store.Product/Publish/Steps/Wx/PrepareSourceProductStep.cs index bc0b7c7..a6efd6b 100644 --- a/Store.Product/Publish/Steps/Wx/PrepareSourceProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/PrepareSourceProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,12 +34,12 @@ public sealed class PrepareSourceProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - prodInfo = JsonHelper.DeserializeJsonToObject(dbProd.product_json); + context.Parameters.ProdInfo = JsonHelper.DeserializeJsonToObject(context.Product.ProductJson); // 如果没有货号或有相同货号无法区分sku,自定义货号 - if (dbProd.db_type == "云端数据") + if (context.Product.DbType == "云端数据") { - foreach (var sku in prodInfo.detail.sku) + foreach (var sku in context.Parameters.ProdInfo.detail.sku) { var skuId = sku.sku_id; if (skuId.IsNullOrZero()) @@ -47,17 +47,18 @@ public sealed class PrepareSourceProductStep : WxProductPublishStepBase sku.out_sku_sn = GetNewExtCode(skuId.ParseToString()); } } - else if (dbProd.product_get_type_text != "厂商直采") + else if (context.Product.ProductGetTypeText != "厂商直采") { - if (prodInfo.detail.sku.Any(s => s.out_sku_sn.IsNullOrEmpty()) || - prodInfo.detail.sku.Select(s => s.out_sku_sn).ToList().Count > prodInfo.detail.sku.Select(s => s.out_sku_sn).Distinct().ToList().Count) + if (context.Parameters.ProdInfo.detail.sku.Any(s => s.out_sku_sn.IsNullOrEmpty()) || + context.Parameters.ProdInfo.detail.sku.Select(s => s.out_sku_sn).ToList().Count > context.Parameters.ProdInfo.detail.sku.Select(s => s.out_sku_sn).Distinct().ToList().Count) { - foreach (var sku in prodInfo.detail.sku) + foreach (var sku in context.Parameters.ProdInfo.detail.sku) { sku.out_sku_sn = string.Join(";", sku.spec.Select(s => s.spec_name)); sku.out_sku_sn = "EC1" + Math.Abs(BaseClass.GetLong(sku.out_sku_sn)) + "A"; } } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/RestoreWxShopSourceProductStep.cs b/Store.Product/Publish/Steps/Wx/RestoreWxShopSourceProductStep.cs index a35b30b..4beaa0f 100644 --- a/Store.Product/Publish/Steps/Wx/RestoreWxShopSourceProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/RestoreWxShopSourceProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,17 +34,18 @@ public sealed class RestoreWxShopSourceProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - wxEditProdInfo = null; - if (dbProd.product_get_type_text == "微信店采") + context.Parameters.WxEditProdInfo = null; + if (context.Product.ProductGetTypeText == "微信店采") { try { - wxEditProdInfo = JsonHelper.DeserializeJsonToObject(dbProd.product_json); + context.Parameters.WxEditProdInfo = JsonHelper.DeserializeJsonToObject(context.Product.ProductJson); } catch (Exception ex) { throw new Exception("微信商品格式获取失败" + ex.Message); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SaveDetailImageHotlinkMapStep.cs b/Store.Product/Publish/Steps/Wx/SaveDetailImageHotlinkMapStep.cs index c208bd4..15f8250 100644 --- a/Store.Product/Publish/Steps/Wx/SaveDetailImageHotlinkMapStep.cs +++ b/Store.Product/Publish/Steps/Wx/SaveDetailImageHotlinkMapStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,22 +34,23 @@ public sealed class SaveDetailImageHotlinkMapStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (isChangeImgDic && dbProd.db_type != "云端数据") + if (context.Parameters.IsChangeImgDic && context.Product.DbType != "云端数据") { var url = BaseClass.BuildObjString("product/mdy_pdd_product"); var data = ""; Invoke(new Action(() => { data = UserLogin.GetSignaturex(); - data += "&spu_id=" + dbProd.spu_id; - data += "&wx_img_map_json=" + JsonHelper.SerializeObject(wxImgMapDic); + data += "&spu_id=" + context.Product.SpuId; + data += "&wx_img_map_json=" + JsonHelper.SerializeObject(context.Parameters.WxImgMapDic); })); var html = GetHtml.PostUtf8(url, data); if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); - isChangeImgDic = false; + context.Parameters.IsChangeImgDic = false; } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SaveDraftHotlinkMapStep.cs b/Store.Product/Publish/Steps/Wx/SaveDraftHotlinkMapStep.cs index ac4b487..efba443 100644 --- a/Store.Product/Publish/Steps/Wx/SaveDraftHotlinkMapStep.cs +++ b/Store.Product/Publish/Steps/Wx/SaveDraftHotlinkMapStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,22 +34,23 @@ public sealed class SaveDraftHotlinkMapStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (isChangeImgDic && dbProd.db_type != "云端数据") + if (context.Parameters.IsChangeImgDic && context.Product.DbType != "云端数据") { var url = BaseClass.BuildObjString("product/mdy_pdd_product"); var data = ""; Invoke(new Action(() => { data = UserLogin.GetSignaturex(); - data += "&spu_id=" + dbProd.spu_id; - data += "&wx_img_map_json=" + JsonHelper.SerializeObject(wxImgMapDic); + data += "&spu_id=" + context.Product.SpuId; + data += "&wx_img_map_json=" + JsonHelper.SerializeObject(context.Parameters.WxImgMapDic); })); var html = GetHtml.PostUtf8(url, data); if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); - isChangeImgDic = false; + context.Parameters.IsChangeImgDic = false; } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SaveMainImageHotlinkMapStep.cs b/Store.Product/Publish/Steps/Wx/SaveMainImageHotlinkMapStep.cs index 0dc739a..9a2cfb0 100644 --- a/Store.Product/Publish/Steps/Wx/SaveMainImageHotlinkMapStep.cs +++ b/Store.Product/Publish/Steps/Wx/SaveMainImageHotlinkMapStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,22 +34,23 @@ public sealed class SaveMainImageHotlinkMapStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (isChangeImgDic && dbProd.db_type != "云端数据") + if (context.Parameters.IsChangeImgDic && context.Product.DbType != "云端数据") { var url = BaseClass.BuildObjString("product/mdy_pdd_product"); var data = ""; Invoke(new Action(() => { data = UserLogin.GetSignaturex(); - data += "&spu_id=" + dbProd.spu_id; - data += "&wx_img_map_json=" + JsonHelper.SerializeObject(wxImgMapDic); + data += "&spu_id=" + context.Product.SpuId; + data += "&wx_img_map_json=" + JsonHelper.SerializeObject(context.Parameters.WxImgMapDic); })); var html = GetHtml.PostUtf8(url, data); if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); - isChangeImgDic = false; + context.Parameters.IsChangeImgDic = false; } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SaveSkuHotlinkMapStep.cs b/Store.Product/Publish/Steps/Wx/SaveSkuHotlinkMapStep.cs index 193401d..5b668fe 100644 --- a/Store.Product/Publish/Steps/Wx/SaveSkuHotlinkMapStep.cs +++ b/Store.Product/Publish/Steps/Wx/SaveSkuHotlinkMapStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,22 +34,23 @@ public sealed class SaveSkuHotlinkMapStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (isChangeImgDic && dbProd.db_type != "云端数据") + if (context.Parameters.IsChangeImgDic && context.Product.DbType != "云端数据") { var url = BaseClass.BuildObjString("product/mdy_pdd_product"); var data = ""; Invoke(new Action(() => { data = UserLogin.GetSignaturex(); - data += "&spu_id=" + dbProd.spu_id; - data += "&wx_img_map_json=" + JsonHelper.SerializeObject(wxImgMapDic); + data += "&spu_id=" + context.Product.SpuId; + data += "&wx_img_map_json=" + JsonHelper.SerializeObject(context.Parameters.WxImgMapDic); })); var html = GetHtml.PostUtf8(url, data); if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); - isChangeImgDic = false; + context.Parameters.IsChangeImgDic = false; } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SetAfterSaleInfoStep.cs b/Store.Product/Publish/Steps/Wx/SetAfterSaleInfoStep.cs index 8ae2935..d78ceb1 100644 --- a/Store.Product/Publish/Steps/Wx/SetAfterSaleInfoStep.cs +++ b/Store.Product/Publish/Steps/Wx/SetAfterSaleInfoStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -35,29 +35,29 @@ public sealed class SetAfterSaleInfoStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在选取售后属性"; + context.Progress.Report("正在选取售后属性"); })); } // 非上海仓退货 - if (!chkUseShanghaiReturnOrderAddress.Checked) + if (!context.Parameters.IsUseShanghaiReturnOrderAddress) { var afterSaleAddress = ""; var afterSaleDetail = ""; // 厂商直采获取售后地址用于处理售后单 - if (dbProd.product_get_type_text == "厂商直采") + if (context.Product.ProductGetTypeText == "厂商直采") { var urlAfterSale = BaseClass.BuildObjString("product/wx_get_after_sale"); var dataAfterSale = Work.UserLogin.GetSignaturex(); - if (!string.IsNullOrEmpty(dbProd.real_coid)) - dataAfterSale += "&coid=" + dbProd.skc_id + "->" + dbProd.real_coid; + if (!string.IsNullOrEmpty(context.Product.RealCoid)) + dataAfterSale += "&coid=" + context.Product.SkcId + "->" + context.Product.RealCoid; else - dataAfterSale += "&coid=" + dbProd.skc_id; + dataAfterSale += "&coid=" + context.Product.SkcId; var htmlAfterSale = GetHtml.PostUtf8(urlAfterSale, dataAfterSale); if (string.IsNullOrEmpty(htmlAfterSale) || !htmlAfterSale.Contains("\"code\":200")) htmlAfterSale = GetHtml.PostUtf8(urlAfterSale, dataAfterSale); @@ -89,7 +89,7 @@ public sealed class SetAfterSaleInfoStep : WxProductPublishStepBase { // 获取推单售后地址 var urlAfter = BaseClass.BuildObjString("product/e57_after_sale"); - var dataAfter = Work.UserLogin.GetSignaturex() + "&coid=" + dbProd.skc_id; + var dataAfter = Work.UserLogin.GetSignaturex() + "&coid=" + context.Product.SkcId; var afterRst = GetHtml.PostUtf8(urlAfter, dataAfter); try { @@ -98,7 +98,7 @@ public sealed class SetAfterSaleInfoStep : WxProductPublishStepBase { urlAfterSale = BaseClass.BuildObjString("product/wx_add_mdy_after_sale"); dataAfterSale = Work.UserLogin.GetSignaturex() + - "&coid=" + dbProd.skc_id + + "&coid=" + context.Product.SkcId + "&after_sale_json=" + afterSaleAddress; htmlAfterSale = GetHtml.PostUtf8(urlAfterSale, dataAfterSale); if (string.IsNullOrEmpty(htmlAfterSale) || !htmlAfterSale.Contains("\"code\":200")) @@ -118,11 +118,11 @@ public sealed class SetAfterSaleInfoStep : WxProductPublishStepBase // 官方库1688厂家数据必须有退货地址才能上传,用户自采数据使用店铺或默认退货地址 26.5.29 // 官方库暂时也放开限制可以随意传 26.5.31 - else if (dbProd.product_get_type_text == "1688厂家" && dbProd.add_user_name == "admin" && 1 == 2) + else if (context.Product.ProductGetTypeText == "1688厂家" && context.Product.AddUserName == "admin" && 1 == 2) { var urlAfterSale = BaseClass.BuildObjString("product/wx_get_after_sale"); var dataAfterSale = Work.UserLogin.GetSignaturex(); - dataAfterSale += "&coid=" + dbProd.from_shop_id; + dataAfterSale += "&coid=" + context.Product.FromShopId; var htmlAfterSale = GetHtml.PostUtf8(urlAfterSale, dataAfterSale); if (string.IsNullOrEmpty(htmlAfterSale) || !htmlAfterSale.Contains("\"code\":200")) htmlAfterSale = GetHtml.PostUtf8(urlAfterSale, dataAfterSale); @@ -154,11 +154,13 @@ public sealed class SetAfterSaleInfoStep : WxProductPublishStepBase } } - else if (GlobalConfig.GlobalSettings.IsWxUseSoftwareDefaultAddress == true && !IsWxNotUseSoftwareDefaultAddressOnce) + else if (GlobalConfig.GlobalSettings.IsWxUseSoftwareDefaultAddress == true && !context.Parameters.IgnoreSoftwareDefaultAddressOnce) { - if (GlobalConfig.WXShopDefaultAddressList.Any(a => a.shop_id == shop.ShopId)) - WXShopDefaultAddressListForm.GetShopDefaultAddress(new List() { shop }); - var address = GlobalConfig.WXShopDefaultAddressList.First(a => a.shop_id == shop.ShopId); + if (GlobalConfig.WXShopDefaultAddressList.Any(a => a.shop_id == context.Parameters.Shop.ShopId)) + { + // 界面操作已移除。 + } + var address = GlobalConfig.WXShopDefaultAddressList.First(a => a.shop_id == context.Parameters.Shop.ShopId); if (!address.isFullAddress) throw new Exception("店铺地址信息获取失败"); afterSaleAddress = JsonHelper.SerializeObject(address); @@ -173,7 +175,7 @@ public sealed class SetAfterSaleInfoStep : WxProductPublishStepBase } } - var addressRst = WXUpload.getAddress(shop, afterSaleDetail); + var addressRst = WXUpload.getAddress(context.Parameters.Shop, afterSaleDetail); if (!addressRst.Contains("\"code\":0") && !addressRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref addressRst, "msg"); @@ -189,11 +191,11 @@ public sealed class SetAfterSaleInfoStep : WxProductPublishStepBase string detailInfo = afterSaleDetail; string userName = BaseRegex.GetStringJson(ref afterSaleAddress, "user_name"); string telNumber = BaseRegex.GetStringJson(ref afterSaleAddress, "tel_number"); - var addAddRst = WXUpload.addAddress(shop, provinceName, cityName, countyName, detailInfo, userName, telNumber); + var addAddRst = WXUpload.addAddress(context.Parameters.Shop, provinceName, cityName, countyName, detailInfo, userName, telNumber); Thread.Sleep(Randomx.GetId(500, 1000)); - addressRst = WXUpload.getAddress(shop, afterSaleDetail); + addressRst = WXUpload.getAddress(context.Parameters.Shop, afterSaleDetail); if (!addressRst.Contains("\"code\":0") && !addressRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref addressRst, "msg"); @@ -208,8 +210,8 @@ public sealed class SetAfterSaleInfoStep : WxProductPublishStepBase throw new Exception("售后地址获取失败"); } - upProdParam.product.info.afterSaleInfo = new afterSaleInfoParam(); - upProdParam.product.info.afterSaleInfo.afterSaleAddressId = BaseRegex.GetStringJson(ref addressRst, "addressId"); + context.Parameters.ProductParameter.product.info.afterSaleInfo = new afterSaleInfoParam(); + context.Parameters.ProductParameter.product.info.afterSaleInfo.afterSaleAddressId = BaseRegex.GetStringJson(ref addressRst, "addressId"); } // 上海仓退货 else @@ -217,28 +219,29 @@ public sealed class SetAfterSaleInfoStep : WxProductPublishStepBase try { string addressId = ""; - string setAddressRst = WXProdNoCheckEditHelper.SetShanghaiReturnOrderAddress(shop); + string setAddressRst = WXProdNoCheckEditHelper.SetShanghaiReturnOrderAddress(context.Parameters.Shop); if (setAddressRst.Contains("\"success\":true")) { - addressId = WXProdNoCheckEditHelper.dicShopAddressId[shop.ShopId]; + addressId = WXProdNoCheckEditHelper.dicShopAddressId[context.Parameters.Shop.ShopId]; } else { var errmsg = BaseRegex.GetStringJson(ref setAddressRst, "msg"); if (string.IsNullOrWhiteSpace(errmsg)) errmsg = setAddressRst; - WXProdNoCheckEditHelper.dicShopAddressId.Remove(shop.ShopId); + WXProdNoCheckEditHelper.dicShopAddressId.Remove(context.Parameters.Shop.ShopId); throw new Exception("退货地址指定失败:" + errmsg); } - upProdParam.product.info.afterSaleInfo = new afterSaleInfoParam(); - upProdParam.product.info.afterSaleInfo.afterSaleAddressId = addressId; + context.Parameters.ProductParameter.product.info.afterSaleInfo = new afterSaleInfoParam(); + context.Parameters.ProductParameter.product.info.afterSaleInfo.afterSaleAddressId = addressId; } catch (Exception ex) { - WXProdNoCheckEditHelper.dicShopAddressId.Remove(shop.ShopId); + WXProdNoCheckEditHelper.dicShopAddressId.Remove(context.Parameters.Shop.ShopId); throw new Exception("退货地址指定失败:" + ex.Message); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SetCommissionInfoStep.cs b/Store.Product/Publish/Steps/Wx/SetCommissionInfoStep.cs index 9a02af9..f484772 100644 --- a/Store.Product/Publish/Steps/Wx/SetCommissionInfoStep.cs +++ b/Store.Product/Publish/Steps/Wx/SetCommissionInfoStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,13 +34,14 @@ public sealed class SetCommissionInfoStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (BaseClass.UserAuthority.Contains("佣金上货") && chkCommission.Checked) + if (BaseClass.UserAuthority.Contains("佣金上货") && context.Parameters.IsCommissionUpload) { - upProdParam.product.info.leagueItemInfo = new leagueItemInfoParam(); - upProdParam.product.info.leagueItemInfo.itemSwitch = 1; - upProdParam.product.info.leagueItemInfo.itemRatio = commissionRate; - upProdParam.product.info.leagueItemInfo.headSupplierPublicItemSwitch = 1; - upProdParam.product.info.leagueItemInfo.headSupplierPublicItemServiceRatio = commissionRate; + context.Parameters.ProductParameter.product.info.leagueItemInfo = new leagueItemInfoParam(); + context.Parameters.ProductParameter.product.info.leagueItemInfo.itemSwitch = 1; + context.Parameters.ProductParameter.product.info.leagueItemInfo.itemRatio = context.Parameters.CommissionRate; + context.Parameters.ProductParameter.product.info.leagueItemInfo.headSupplierPublicItemSwitch = 1; + context.Parameters.ProductParameter.product.info.leagueItemInfo.headSupplierPublicItemServiceRatio = context.Parameters.CommissionRate; } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SetPreSaleInfoStep.cs b/Store.Product/Publish/Steps/Wx/SetPreSaleInfoStep.cs index 3ffed64..91fb18d 100644 --- a/Store.Product/Publish/Steps/Wx/SetPreSaleInfoStep.cs +++ b/Store.Product/Publish/Steps/Wx/SetPreSaleInfoStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,17 +34,18 @@ public sealed class SetPreSaleInfoStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (chkPreSale.Checked) + if (context.Parameters.IsPreSale) { - upProdParam.product.deliverInfo = new productDeliverInfoParam(); - upProdParam.product.deliverInfo.deliverType = 1; - int preSaleDays = Math.Max(3, wxUploadRule.PreSaleDays); + context.Parameters.ProductParameter.product.deliverInfo = new productDeliverInfoParam(); + context.Parameters.ProductParameter.product.deliverInfo.deliverType = 1; + int preSaleDays = Math.Max(3, context.Parameters.PreSaleDays); preSaleDays = Math.Min(45, preSaleDays); - upProdParam.product.deliverInfo.skuDeliverInfo = new skuDeliverInfoParam() + context.Parameters.ProductParameter.product.deliverInfo.skuDeliverInfo = new skuDeliverInfoParam() { stockType = 1, fullPaymentPresaleDeliveryTime = preSaleDays.ParseToString() }; } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SetProductExtCodeStep.cs b/Store.Product/Publish/Steps/Wx/SetProductExtCodeStep.cs index 69d9d46..ab9cf0b 100644 --- a/Store.Product/Publish/Steps/Wx/SetProductExtCodeStep.cs +++ b/Store.Product/Publish/Steps/Wx/SetProductExtCodeStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,15 +34,16 @@ public sealed class SetProductExtCodeStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - extCode = dbProd.ext_code.IsNullOrEmpty() ? prodInfo.detail.out_goods_sn : dbProd.ext_code; - if (extCode.IsNullOrEmpty() || extCode.Length <= 10) + context.Product.ExtCode = context.Product.ExtCode.IsNullOrEmpty() ? context.Parameters.ProdInfo.detail.out_goods_sn : context.Product.ExtCode; + if (context.Product.ExtCode.IsNullOrEmpty() || context.Product.ExtCode.Length <= 10) { - //extCode = "EC" + Randomx.GetId(1000).ToString().PadLeft(3, '0') + dbProd.spu_id + "C"; - extCode = GetEC1ExtCode(dbProd.spu_id); + //extCode = "EC" + Randomx.GetId(1000).ToString().PadLeft(3, '0') + context.Product.SpuId + "C"; + context.Product.ExtCode = GetEC1ExtCode(context.Product.SpuId); } - upProdParam.product.info.spuCode = extCode; - upProdParam.product.info.outProductId = extCode; - upProdParam.product.info.out_product_id = extCode; - upProdParam.product.productKey.outProductId = extCode; + context.Parameters.ProductParameter.product.info.spuCode = context.Product.ExtCode; + context.Parameters.ProductParameter.product.info.outProductId = context.Product.ExtCode; + context.Parameters.ProductParameter.product.info.out_product_id = context.Product.ExtCode; + context.Parameters.ProductParameter.product.productKey.outProductId = context.Product.ExtCode; + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SetProductTitleStep.cs b/Store.Product/Publish/Steps/Wx/SetProductTitleStep.cs index 8d1f879..a303288 100644 --- a/Store.Product/Publish/Steps/Wx/SetProductTitleStep.cs +++ b/Store.Product/Publish/Steps/Wx/SetProductTitleStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,12 +34,13 @@ public sealed class SetProductTitleStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - prodTitle = selectProd.product_name; - if (prodTitle.IsNullOrEmpty()) - prodTitle = dbProd.product_name.IsNullOrEmpty() ? prodInfo.detail.goods_name : dbProd.product_name; + context.Product.Title = context.Parameters.SelectProduct.product_name; + if (context.Product.Title.IsNullOrEmpty()) + context.Product.Title = context.Product.Title.IsNullOrEmpty() ? context.Parameters.ProdInfo.detail.goods_name : context.Product.Title; - upProdInitParam.product.info.title = prodTitle; - upProdParam.product.info.title = prodTitle; - upProdParam.sessionInfo.sessionId = upProdInitParam.product.sessionId; + context.Parameters.InitParameter.product.info.title = context.Product.Title; + context.Parameters.ProductParameter.product.info.title = context.Product.Title; + context.Parameters.ProductParameter.sessionInfo.sessionId = context.Parameters.InitParameter.product.sessionId; + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SetQualificationsAndTagImagesStep.cs b/Store.Product/Publish/Steps/Wx/SetQualificationsAndTagImagesStep.cs index eb704fb..1fed66f 100644 --- a/Store.Product/Publish/Steps/Wx/SetQualificationsAndTagImagesStep.cs +++ b/Store.Product/Publish/Steps/Wx/SetQualificationsAndTagImagesStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,8 +21,8 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; +using Work.BLL.Tools; namespace Store.Product.Publish.Steps.Wx; /// @@ -35,14 +36,14 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { // 微信回采直接复制 - if (BaseClass.UserAuthority.ParseToString().Contains("微信回采") && chkUseWXComplateProd.Checked && dbProd.has_wx_format == "1" && wxEditProdInfo != null) + if (BaseClass.UserAuthority.ParseToString().Contains("微信回采") && context.Parameters.IsUseWXComplateProd && context.Product.HasWxFormat == "1" && context.Parameters.WxEditProdInfo != null) { - upProdParam.product.info.qualificationList.Clear(); - if (wxEditProdInfo.product?.info?.qualificationList?.Count > 0) + context.Parameters.ProductParameter.product.info.qualificationList.Clear(); + if (context.Parameters.WxEditProdInfo.product?.info?.qualificationList?.Count > 0) { - foreach (var editQualification in wxEditProdInfo.product.info.qualificationList) + foreach (var editQualification in context.Parameters.WxEditProdInfo.product.info.qualificationList) { - upProdParam.product.info.qualificationList.Add(new qualificationParam() + context.Parameters.ProductParameter.product.info.qualificationList.Add(new qualificationParam() { qualificationId = editQualification.qualificationId, qualificationUrl = editQualification.qualificationUrl, @@ -50,26 +51,26 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase } } - if (upProdParam.product.info.category.FirstOrDefault()?.name == "成人用品" && upProdParam.product.info.category[1].name != "情趣内衣") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "成人用品" && context.Parameters.ProductParameter.product.info.category[1].name != "情趣内衣") { - if (wxEditProdInfo.product.info.brandId.ParseToLong() > 0) - DefaultAdultBrandId = wxEditProdInfo.product.info.brandId; - if (wxEditProdInfo.product.info.brandId.ParseToLong() > 0) - upProdParam.product.info.brandId = wxEditProdInfo.product.info.brandId.ParseToLong(); + if (context.Parameters.WxEditProdInfo.product.info.brandId.ParseToLong() > 0) + context.Parameters.DefaultAdultBrandId = context.Parameters.WxEditProdInfo.product.info.brandId; + if (context.Parameters.WxEditProdInfo.product.info.brandId.ParseToLong() > 0) + context.Parameters.ProductParameter.product.info.brandId = context.Parameters.WxEditProdInfo.product.info.brandId.ParseToLong(); } } // 微信店采直接复制 - //else if (dbProd.product_get_type_text == "微信店采" && upProdParam.product.info.category.FirstOrDefault()?.name != "图书" && + //else if (context.Product.ProductGetTypeText == "微信店采" && upProdParam.product.info.category.FirstOrDefault()?.name != "图书" && // upProdParam.product.info.category.FirstOrDefault()?.name != "食品饮料") - else if (dbProd.product_get_type_text == "微信店采" && - upProdParam.product.info.category.FirstOrDefault()?.name == "成人用品" && upProdParam.product.info.category[1].name != "情趣内衣") + else if (context.Product.ProductGetTypeText == "微信店采" && + context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "成人用品" && context.Parameters.ProductParameter.product.info.category[1].name != "情趣内衣") { - upProdParam.product.info.qualificationList.Clear(); - if (wxEditProdInfo.product?.info?.qualificationList?.Count > 0) + context.Parameters.ProductParameter.product.info.qualificationList.Clear(); + if (context.Parameters.WxEditProdInfo.product?.info?.qualificationList?.Count > 0) { - foreach (var editQualification in wxEditProdInfo.product.info.qualificationList) + foreach (var editQualification in context.Parameters.WxEditProdInfo.product.info.qualificationList) { - upProdParam.product.info.qualificationList.Add(new qualificationParam() + context.Parameters.ProductParameter.product.info.qualificationList.Add(new qualificationParam() { qualificationId = editQualification.qualificationId, qualificationUrl = editQualification.qualificationUrl, @@ -77,34 +78,34 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase } } - if (upProdParam.product.info.category.FirstOrDefault()?.name == "成人用品" && upProdParam.product.info.category[1].name != "情趣内衣") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "成人用品" && context.Parameters.ProductParameter.product.info.category[1].name != "情趣内衣") { - if (wxEditProdInfo.product.info.brandId.ParseToLong() > 0) - DefaultAdultBrandId = wxEditProdInfo.product.info.brandId; - if (wxEditProdInfo.product.info.brandId.ParseToLong() > 0) - upProdParam.product.info.brandId = wxEditProdInfo.product.info.brandId.ParseToLong(); + if (context.Parameters.WxEditProdInfo.product.info.brandId.ParseToLong() > 0) + context.Parameters.DefaultAdultBrandId = context.Parameters.WxEditProdInfo.product.info.brandId; + if (context.Parameters.WxEditProdInfo.product.info.brandId.ParseToLong() > 0) + context.Parameters.ProductParameter.product.info.brandId = context.Parameters.WxEditProdInfo.product.info.brandId.ParseToLong(); } } else { //qualificationList - if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "图书" || context.Parameters.ProdInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成图书专有信息"; + context.Progress.Report("正在生成图书专有信息"); })); } - if (lstQulificationImage.Count == 0) + if (context.Parameters.QualificationImages.Count == 0) { var pageCount = 1; var seconds = 0m; - lstQulificationImage = AdminForms.WXAdminQualificationImageForm.AdminGetServerQualificationImageLst(out pageCount, out seconds, "图书"); + context.Parameters.QualificationImages = AdminForms.WXAdminQualificationImageForm.AdminGetServerQualificationImageLst(out pageCount, out seconds, "图书"); } - var qulificationImage = lstQulificationImage.OrderBy(x => Guid.NewGuid()).FirstOrDefault(); + var qulificationImage = context.Parameters.QualificationImages.OrderBy(x => Guid.NewGuid()).FirstOrDefault(); if (qulificationImage != null) { if (qulificationImage.img_base64.IsNullOrEmpty()) @@ -231,13 +232,13 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase string isbn = "ISBN/CN刊号:"; //string bookName = "书名:"; string bookName = "图书名称:"; - string bookPrice = "定  价:" + upProdParam.product.productSkus.Max(s => s.productSkuInfo.salePrice) * 0.01; + string bookPrice = "定  价:" + context.Parameters.ProductParameter.product.productSkus.Max(s => s.productSkuInfo.salePrice) * 0.01; string author = "作  者:王老师"; string publishTime = "出版时间:" + DateTime.Now.AddMonths(-3).ToString("yyyy年MM月dd日"); string edition = "版  次:1"; string binding = "装  帧:平装"; - foreach (var propParam in upProdParam.product.info.param) + foreach (var propParam in context.Parameters.ProductParameter.product.info.param) { if (propParam.categorys[0].name.Contains("出版社名称")) publisher = "出版发行:" + propParam.categorys[1].name; @@ -289,7 +290,7 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase int imgW = 800; int imgH = 800; int textImgH = 0; string getImgError; - var img_url = upProdParam.product.info.headImg[0]; + var img_url = context.Parameters.ProductParameter.product.info.headImg[0]; if (!img_url.Contains("wst.wxapp.tc.qq.com") && !img_url.Contains("mmecimage.cn")) img_url = img_url.Replace("https://", "http://"); var imageMain = GetHtml.GetUrlImg(img_url, out getImgError); @@ -311,7 +312,7 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase } - var bookImg = TemuKJD.Properties.Resources.empty_book_900_1200; + var bookImg = new Bitmap(900, 1200); if (!string.IsNullOrEmpty(qulificationImage?.img_base64)) { // 使用服务端随即图 @@ -422,11 +423,11 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase Thread.Sleep(Randomx.GetId(500, 800)); - var locationStr = UploadImg(shop, bookImg, cell); + var locationStr = UploadImg(context.Parameters.Shop, bookImg); if (!locationStr.Contains("\"success\":true")) throw new Exception(locationStr); var location = BaseRegex.GetStringJson(ref locationStr, "Location"); - upProdParam.product.info.qualificationList.Add(new qualificationParam() { qualificationId = "1111485", qualificationUrl = new List() { location }, }); + context.Parameters.ProductParameter.product.info.qualificationList.Add(new qualificationParam() { qualificationId = "1111485", qualificationUrl = new List() { location }, }); using (MemoryStream memoryStream = new MemoryStream()) { @@ -436,7 +437,7 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; //upDate += "&is_file=true"; //if (needAddRandomBlock || wantAddRandomBlock) // upDate += "&random_code=true"; @@ -445,39 +446,39 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase var sTime = DateTime.Now; var apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在上传资质图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在上传资质图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 5 && apiUpImgFileRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref apiUpImgFileRst, "img_url"); - upProdParam.product.info.headImg = upProdParam.product.info.headImg.Take(8).ToList(); - upProdParam.product.info.headImg.Add(upImgUrl); + context.Parameters.ProductParameter.product.info.headImg = context.Parameters.ProductParameter.product.info.headImg.Take(8).ToList(); + context.Parameters.ProductParameter.product.info.headImg.Add(upImgUrl); } } //qualificationList - if (upProdParam.product.info.category.FirstOrDefault()?.name == "食品饮料" || prodInfo.detail.cats.FirstOrDefault() == "食品饮料") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "食品饮料" || context.Parameters.ProdInfo.detail.cats.FirstOrDefault() == "食品饮料") { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成食品饮料专有信息"; + context.Progress.Report("正在生成食品饮料专有信息"); })); } - string foodName = "食品名称:" + prodTitle; + string foodName = "食品名称:" + context.Product.Title; string companyName = "生产商名称:中国地区食品厂"; string SCID = "食品生产许可证编号:SC10241162100670"; string GBID = "产品标准号:GB 2726"; @@ -490,7 +491,7 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase string address = "地址:见包装"; string Storage = "贮存条件:常温"; - foreach (var propParam in upProdParam.product.info.param) + foreach (var propParam in context.Parameters.ProductParameter.product.info.param) { if (propParam.categorys[0].name.Contains("食品名称") && !propParam.categorys[1].name.Contains("见包装") && !propParam.categorys[1].name.Contains("见外包装") && !propParam.categorys[1].name.Contains("1") && propParam.categorys[1].name.Length > 5) @@ -570,33 +571,33 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase } Thread.Sleep(Randomx.GetId(500, 800)); - var locationStr = UploadImg(shop, bookImg, cell); + var locationStr = UploadImg(context.Parameters.Shop, bookImg); if (!locationStr.Contains("\"success\":true")) throw new Exception(locationStr); var location = BaseRegex.GetStringJson(ref locationStr, "Location"); - upProdParam.product.info.qualificationList.Add(new qualificationParam() { qualificationId = "50000057", qualificationUrl = new List() { location }, }); + context.Parameters.ProductParameter.product.info.qualificationList.Add(new qualificationParam() { qualificationId = "50000057", qualificationUrl = new List() { location }, }); } //qualificationList - if (upProdParam.product.info.category.FirstOrDefault()?.name == "成人用品" && upProdParam.product.info.category[1].name != "情趣内衣") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "成人用品" && context.Parameters.ProductParameter.product.info.category[1].name != "情趣内衣") { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成成人用品专有信息"; + context.Progress.Report("正在生成成人用品专有信息"); })); } string prodName = "产品名称:" + - (upProdParam.product.info.category.Count > 2 ? upProdParam.product.info.category[2].name : upProdParam.product.info.category.LastOrDefault()?.name); + (context.Parameters.ProductParameter.product.info.category.Count > 2 ? context.Parameters.ProductParameter.product.info.category[2].name : context.Parameters.ProductParameter.product.info.category.LastOrDefault()?.name); string company = "生产企业:浙江邦臣医药有限公司"; string address = "制造商地址:浙江省金华市婺城区神丽路1399号6号厂房"; string model = "产品型号:见包装"; string material = "材质:其他"; string user = "适用人群:18岁以上成年人"; - foreach (var propParam in upProdParam.product.info.param) + foreach (var propParam in context.Parameters.ProductParameter.product.info.param) { //if (propParam.categorys[0].name.Contains("产品名称")) // prodName = "产品名称:" + propParam.categorys[1].name; @@ -622,26 +623,26 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase } Thread.Sleep(Randomx.GetId(500, 800)); - var locationStr = UploadImg(shop, bookImg, cell); + var locationStr = UploadImg(context.Parameters.Shop, bookImg); if (!locationStr.Contains("\"success\":true")) throw new Exception(locationStr); var location = BaseRegex.GetStringJson(ref locationStr, "Location"); - upProdParam.product.info.qualificationList.Add(new qualificationParam() { qualificationId = "50000089", qualificationUrl = new List() { location }, }); + context.Parameters.ProductParameter.product.info.qualificationList.Add(new qualificationParam() { qualificationId = "50000089", qualificationUrl = new List() { location }, }); } - if (upProdParam.product.info.category.FirstOrDefault()?.name == "成人用品" && upProdParam.product.info.category[1].name != "情趣内衣") + if (context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "成人用品" && context.Parameters.ProductParameter.product.info.category[1].name != "情趣内衣") { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成成人用品专有信息"; + context.Progress.Report("正在生成成人用品专有信息"); })); } - string prodName = (upProdParam.product.info.category.Count > 2 ? upProdParam.product.info.category[2].name : upProdParam.product.info.category.LastOrDefault()?.name); + string prodName = (context.Parameters.ProductParameter.product.info.category.Count > 2 ? context.Parameters.ProductParameter.product.info.category[2].name : context.Parameters.ProductParameter.product.info.category.LastOrDefault()?.name); - var baseImg = TemuKJD.Properties.Resources.qingqu; + var baseImg = new Bitmap(1000, 1000); var newImg = new Bitmap(baseImg.Width, baseImg.Height); using (Graphics g = Graphics.FromImage(newImg)) { @@ -662,12 +663,13 @@ public sealed class SetQualificationsAndTagImagesStep : WxProductPublishStepBase } Thread.Sleep(Randomx.GetId(500, 800)); - var locationStr = UploadImg(shop, newImg, cell); + var locationStr = UploadImg(context.Parameters.Shop, newImg); if (!locationStr.Contains("\"success\":true")) throw new Exception(locationStr); var location = BaseRegex.GetStringJson(ref locationStr, "Location"); - upProdParam.product.info.qualificationList.Add(new qualificationParam() { qualificationId = "50000115", qualificationUrl = new List() { location }, }); + context.Parameters.ProductParameter.product.info.qualificationList.Add(new qualificationParam() { qualificationId = "50000115", qualificationUrl = new List() { location }, }); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SkipUploadedProductStep.cs b/Store.Product/Publish/Steps/Wx/SkipUploadedProductStep.cs index 8608e7b..d502b93 100644 --- a/Store.Product/Publish/Steps/Wx/SkipUploadedProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/SkipUploadedProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -11,7 +12,6 @@ using MAX.Core.DependencyInjection; using MAX.Core.Helpers; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Store.Framework.Extensions; using Store.Management.Framework.Apis; using Store.Product.Models.PublishParameters.Wx; using Store.Product.Publish; @@ -24,7 +24,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -42,12 +41,12 @@ public sealed class SkipUploadedProductStep : WxProductPublishStepBase protected override Task CanExecuteProvider(WXPublishContext context, CancellationToken token) { - return Task.FromResult(context.Parameters.SkipExisting); + return Task.FromResult(context.Parameters.SkipUploaded); } protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { // 裂变按标题名称 - if (selectProd.is_fission_title) + if (context.Parameters.SelectProduct.is_fission_title) { HttpResult result = WXApi.searchProductWithTitle(context.Shop.Cookie, GetHtml.UrlEncodeUtf8(context.Product.Title)); string searchRst = result.Html; @@ -74,19 +73,19 @@ public sealed class SkipUploadedProductStep : WxProductPublishStepBase // 非裂变商品按商品Id else { - var searchExtCode = dbProd.ext_code; - if (dbProd.db_type == "云端数据") + var searchExtCode = context.Product.ExtCode; + if (context.Product.DbType == "云端数据") { - dbProd.ext_code = searchExtCode = GetNewExtCode(dbProd.spu_id); + context.Product.ExtCode = searchExtCode = GetNewExtCode(context.Product.SpuId); } else { if (searchExtCode.ParseToString().Length < 10) - searchExtCode = GetEC1ExtCode(dbProd.spu_id); + searchExtCode = GetEC1ExtCode(context.Product.SpuId); } - if (dbProd.sku_secret_json != null && dbProd.sku_secret_json.Contains("goodsId")) + if (context.Product.SkuSecretJson != null && context.Product.SkuSecretJson.Contains("goodsId")) { - var sku_secret_json = dbProd.sku_secret_json; + var sku_secret_json = context.Product.SkuSecretJson; searchExtCode = BaseRegex.GetStringJson(ref sku_secret_json, "goodsId"); } var result = WXApi.searchProduct(context.Shop.Cookie, searchExtCode); diff --git a/Store.Product/Publish/Steps/Wx/SubmitProductDraftStep.cs b/Store.Product/Publish/Steps/Wx/SubmitProductDraftStep.cs index fcf2ff7..65e13c8 100644 --- a/Store.Product/Publish/Steps/Wx/SubmitProductDraftStep.cs +++ b/Store.Product/Publish/Steps/Wx/SubmitProductDraftStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -35,73 +35,75 @@ public sealed class SubmitProductDraftStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { // 直接使用微信回采情趣商品品牌 - if (BaseClass.UserAuthority.ParseToString().Contains("微信回采") && chkUseWXComplateProd.Checked && - upProdParam.product.info.category.FirstOrDefault()?.name == "成人用品" && upProdParam.product.info.category[1].name != "情趣内衣") + if (BaseClass.UserAuthority.ParseToString().Contains("微信回采") && context.Parameters.IsUseWXComplateProd && + context.Parameters.ProductParameter.product.info.category.FirstOrDefault()?.name == "成人用品" && context.Parameters.ProductParameter.product.info.category[1].name != "情趣内衣") { - if (DefaultAdultBrandId.ParseToLong() > 0) - upProdParam.product.info.brandId = DefaultAdultBrandId.ParseToLong(); + if (context.Parameters.DefaultAdultBrandId.ParseToLong() > 0) + context.Parameters.ProductParameter.product.info.brandId = context.Parameters.DefaultAdultBrandId.ParseToLong(); } // 情趣内衣等类目禁止设置运费险 //if (upProdParam.product.info.category[1].name == "情趣内衣" || // upProdParam.product.info.category[1].name == "水果") - if (chkFreightInsurance.Checked) + if (context.Parameters.IsFreightInsurance) { - upProdParam.product.info.extraService.freightInsurance = 1; + context.Parameters.ProductParameter.product.info.extraService.freightInsurance = 1; } else { - upProdParam.product.info.extraService.freightInsurance = 0; + context.Parameters.ProductParameter.product.info.extraService.freightInsurance = 0; } // 假1赔3 - if (upProdParam.product.info.category[0].name == "珠宝首饰" || upProdParam.product.info.category[1].name == "时尚饰品") + if (context.Parameters.ProductParameter.product.info.category[0].name == "珠宝首饰" || context.Parameters.ProductParameter.product.info.category[1].name == "时尚饰品") { - upProdParam.product.info.extraService.fakeOnePayFour = 1; + context.Parameters.ProductParameter.product.info.extraService.fakeOnePayFour = 1; } // 坏损包退 damageGuarantee - if (upProdParam.product.info.category[0].name == "生鲜" || upProdParam.product.info.category[0].name == "酒类" || - upProdParam.product.info.category[0].name == "食品饮料" || upProdParam.product.info.category[0].name == "保健食品/膳食营养补充食品" || - (upProdParam.product.info.category[0].name == "农资园艺" && upProdParam.product.info.category[1].name == "花卉绿植")) + if (context.Parameters.ProductParameter.product.info.category[0].name == "生鲜" || context.Parameters.ProductParameter.product.info.category[0].name == "酒类" || + context.Parameters.ProductParameter.product.info.category[0].name == "食品饮料" || context.Parameters.ProductParameter.product.info.category[0].name == "保健食品/膳食营养补充食品" || + (context.Parameters.ProductParameter.product.info.category[0].name == "农资园艺" && context.Parameters.ProductParameter.product.info.category[1].name == "花卉绿植")) { - upProdParam.product.info.extraService.damageGuarantee = 1; + context.Parameters.ProductParameter.product.info.extraService.damageGuarantee = 1; } // 生鲜不支持换货,关闭 - if (upProdParam.product.info.category[0].name == "生鲜") + if (context.Parameters.ProductParameter.product.info.category[0].name == "生鲜") { - upProdParam.product.info.extraService.exchangeSupport = 0; + context.Parameters.ProductParameter.product.info.extraService.exchangeSupport = 0; } - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在提交商品"; + context.Progress.Report("正在提交商品"); })); } Thread.Sleep(Randomx.GetId(1000, 2000)); - uploadDraftRst = WXUpload.uploadProductDraft(shop, upProdParam); - if (!uploadDraftRst.Contains("\"code\":0") && !uploadDraftRst.Contains("\"success\":true")) + context.Parameters.UploadDraftRst = WXUpload.uploadProductDraft(context.Parameters.Shop, context.Parameters.ProductParameter); + if (!context.Parameters.UploadDraftRst.Contains("\"code\":0") && !context.Parameters.UploadDraftRst.Contains("\"success\":true")) { + var uploadDraftRst = context.Parameters.UploadDraftRst; var error = BaseRegex.GetStringJson(ref uploadDraftRst, "msg"); if (string.IsNullOrEmpty(error)) { - if (uploadDraftRst.Contains("\"errcode\":9401043")) + if (context.Parameters.UploadDraftRst.Contains("\"errcode\":9401043")) error = "sku价格异常,请检查加价比例"; else - error = uploadDraftRst; + error = context.Parameters.UploadDraftRst; } var draftId = BaseRegex.GetStringJson(ref uploadDraftRst, "productId").ParseToLong(); throw new Exception("草稿保存失败 " + GetHtml.UrlEncodeUtf8(error)); } - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - var timeSpan = DateTime.Now - startTime; + var timeSpan = DateTime.Now - context.Parameters.StartTime; var duration = timeSpan.TotalSeconds; - cell.Value = "商品已保存草稿,正在提交上架" + " " + duration.ParseToInt() + "秒"; + context.Progress.Report("商品已保存草稿,正在提交上架" + " " + duration.ParseToInt() + "秒"); })); } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/SubmitProductStep.cs b/Store.Product/Publish/Steps/Wx/SubmitProductStep.cs index 3764aac..083797b 100644 --- a/Store.Product/Publish/Steps/Wx/SubmitProductStep.cs +++ b/Store.Product/Publish/Steps/Wx/SubmitProductStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,36 +34,37 @@ public sealed class SubmitProductStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - upProdParam.product.productKey.productId = BaseRegex.GetLongJson(ref uploadDraftRst, "productId").ParseToString(); + var uploadDraftRst = context.Parameters.UploadDraftRst; + context.Parameters.ProductParameter.product.productKey.productId = BaseRegex.GetLongJson(ref uploadDraftRst, "productId").ParseToString(); - commissionRstStr = ""; - if (chkUpDraft.Checked && BaseClass.UserAuthority.Contains("佣金上货") && chkCommission.Checked) + context.Parameters.CommissionRstStr = ""; + if (context.Parameters.UpDraft && BaseClass.UserAuthority.Contains("佣金上货") && context.Parameters.IsCommissionUpload) { - var rst = WXUpload.addLeagueItemForUpdatingProduct(shop, 1, commissionRate, 1, commissionRate, upProdParam.product.productKey.productId.ParseToLong()); + var rst = WXUpload.addLeagueItemForUpdatingProduct(context.Parameters.Shop, 1, context.Parameters.CommissionRate, 1, context.Parameters.CommissionRate, context.Parameters.ProductParameter.product.productKey.productId.ParseToLong()); if (!rst.Contains("\"code\":0")) { var error = BaseRegex.GetStringJsonByRegs(ref rst, rst, "msg", "errMsg", "errorMsg", "err_msg", "error_msg"); - commissionRstStr = "设置佣金比例失败 " + rst; + context.Parameters.CommissionRstStr = "设置佣金比例失败 " + rst; } } - if (chkUpDraft.Checked) + if (context.Parameters.UpDraft) { - selectProd.wxDraftProduct = upProdParam; - selectProd.draft_id = upProdParam.product.productKey.productId; - selectProd.status = "草稿箱"; - selectProd.add_time = DateTime.Now; - upload_draft_product_lst.Add(selectProd); - NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_select_upload_draft_products", upload_draft_product_lst); + context.Parameters.SelectProduct.wxDraftProduct = context.Parameters.ProductParameter; + context.Parameters.SelectProduct.draft_id = context.Parameters.ProductParameter.product.productKey.productId; + context.Parameters.SelectProduct.status = "草稿箱"; + context.Parameters.SelectProduct.add_time = DateTime.Now; + context.Parameters.UploadDraftProductList.Add(context.Parameters.SelectProduct); + NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_select_upload_draft_products", context.Parameters.UploadDraftProductList); - StopWithResult("{\"success\":true,\"draftId\":" + upProdParam.product.productKey.productId + ",\"status\":\"草稿箱\",\"errMsg\":\"指定上传到草稿箱" + commissionRstStr + "\"}"); - return; + StopWithResult("{\"success\":true,\"draftId\":" + context.Parameters.ProductParameter.product.productKey.productId + ",\"status\":\"草稿箱\",\"errMsg\":\"指定上传到草稿箱" + context.Parameters.CommissionRstStr + "\"}"); + return Task.CompletedTask; } // 提交商品上架 - if (!chkTestNoAuditUpload.Checked) + if (!context.Parameters.IsTestNoAuditUpload) { - var uploadProdRst = WXUpload.upProductV2(shop, upProdParam); + var uploadProdRst = WXUpload.upProductV2(context.Parameters.Shop, context.Parameters.ProductParameter); //{"success":true,"retcode":209006,"errcode":209006,"productId":10001226244322,"productKey":{"productId":"10001226244322"}} // 提审成功 //{"success":true,"retcode":0,"errcode":0,"productId":10001226095876,"productKey":{"productId":"10001226095876"}} // 未能提审 if (!uploadProdRst.Contains("\"code\":0") && !uploadProdRst.Contains("\"success\":true")) @@ -77,22 +78,22 @@ public sealed class SubmitProductStep : WxProductPublishStepBase error = uploadProdRst; throw new Exception("上架失败 " + error); } - if (upProdParam.product.productKey.productId.IsNullOrEmpty()) - upProdParam.product.productKey.productId = BaseRegex.GetLongJson(ref uploadProdRst, "productId").ParseToString(); + if (context.Parameters.ProductParameter.product.productKey.productId.IsNullOrEmpty()) + context.Parameters.ProductParameter.product.productKey.productId = BaseRegex.GetLongJson(ref uploadProdRst, "productId").ParseToString(); - if (BaseClass.UserAuthority.Contains("佣金上货") && chkCommission.Checked) + if (BaseClass.UserAuthority.Contains("佣金上货") && context.Parameters.IsCommissionUpload) { - var rst = WXUpload.addLeagueItemForUpdatingProduct(shop, 1, commissionRate, 1, commissionRate, upProdParam.product.productKey.productId.ParseToLong(), 1); + var rst = WXUpload.addLeagueItemForUpdatingProduct(context.Parameters.Shop, 1, context.Parameters.CommissionRate, 1, context.Parameters.CommissionRate, context.Parameters.ProductParameter.product.productKey.productId.ParseToLong(), 1); if (!rst.Contains("\"code\":0")) { var error = BaseRegex.GetStringJsonByRegs(ref rst, rst, "msg", "errMsg", "errorMsg", "err_msg", "error_msg"); - commissionRstStr = "设置佣金比例失败 " + rst; + context.Parameters.CommissionRstStr = "设置佣金比例失败 " + rst; } } - if (chkIsSubmitSuccess.Checked) + if (context.Parameters.IsCheckSubmitSuccess) { Thread.Sleep(Randomx.GetId(2000, 3001)); - var uploadCheckRst = WXUpload.SearchProductUpload(shop, upProdParam.product.productKey.productId); + var uploadCheckRst = WXUpload.SearchProductUpload(context.Parameters.Shop, context.Parameters.ProductParameter.product.productKey.productId); if (uploadCheckRst.Contains("\"productList\":[]") || uploadCheckRst.Contains("\"totalNum\":0")) { throw new Exception("上架提审失败 请检查是否在架商品数已达到上限或店铺受到其他限制"); @@ -101,7 +102,7 @@ public sealed class SubmitProductStep : WxProductPublishStepBase } else { - var getEditProd = WXUpload.getEditProductV2(shop, upProdParam.product.productKey.productId); + var getEditProd = WXUpload.getEditProductV2(context.Parameters.Shop, context.Parameters.ProductParameter.product.productKey.productId); //getEditProd = getEditProd.Replace("8388275713", "33333333"); //getEditProd = getEditProd.Replace("33333333", "8387633147"); @@ -110,7 +111,7 @@ public sealed class SubmitProductStep : WxProductPublishStepBase { // 获取免审编辑回传数据 JsonSerializerSettings jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; - var prodStr = JsonConvert.SerializeObject(upProdParam, jsonSetting); + var prodStr = JsonConvert.SerializeObject(context.Parameters.ProductParameter, jsonSetting); JObject jObj = JsonHelper.JObjectParse(prodStr); JObject jObjTmp = JsonHelper.JObjectParse(getEditProd); @@ -137,14 +138,14 @@ public sealed class SubmitProductStep : WxProductPublishStepBase { } - string submitJson = "{\"name\":\"goods/" + upProdParam.product.productKey.productId + "/" + DateTime.Now.ToString("yyyy-MM-dd") + "/" + + string submitJson = "{\"name\":\"goods/" + context.Parameters.ProductParameter.product.productKey.productId + "/" + DateTime.Now.ToString("yyyy-MM-dd") + "/" + BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now) + "/submit.json\"}"; var initFileName = BaseRegex.GetStringJson(ref submitJson, "name"); DateTime tickTime = DateTime.Now.AddSeconds(0 - Randomx.GetId(10, 30)); int time1 = BaseClass.DateTimeToTimestampSeconds(tickTime) - Randomx.GetId(80, 150); int time2 = BaseClass.DateTimeToTimestampSeconds(tickTime); - var uploadPartRst = WXUpload.initUploadPart(shop, submitJson, upProdParam.product.productKey.productId, time1, time2); + var uploadPartRst = WXUpload.initUploadPart(context.Parameters.Shop, submitJson, context.Parameters.ProductParameter.product.productKey.productId, time1, time2); string uploadPartId = BaseRegex.GetStringJson(ref uploadPartRst, "uploadId"); //upProdParam.product.status = 5; @@ -155,7 +156,7 @@ public sealed class SubmitProductStep : WxProductPublishStepBase //upProdParam.product.info.skuList.skuInfo = new List(); //var listingAuditFreeRst = WXUpload.listingAuditFree(shop, upProdParam, upProdParam.product.productKey.productId, time1, time2); // 提交免审修改(实际生效接口) - var listingAuditFreeRst = WXUpload.listingAuditFree(shop, productJson, upProdParam.product.productKey.productId, time1, time2); + var listingAuditFreeRst = WXUpload.listingAuditFree(context.Parameters.Shop, productJson, context.Parameters.ProductParameter.product.productKey.productId, time1, time2); string tempBlobPath = Path.GetTempPath().Trim('\\') + "\\" + Randomx.GetWordWithNumber(8).ToLower(); if (!Directory.Exists(tempBlobPath)) @@ -176,43 +177,43 @@ public sealed class SubmitProductStep : WxProductPublishStepBase } JsonSerializerSettings jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; - foreach (var sku in upProdParam.product.productSkus) + foreach (var sku in context.Parameters.ProductParameter.product.productSkus) { sku.productSkuInfo.stockInfo.stockNum = 1005; } - var prodStr = JsonConvert.SerializeObject(upProdParam, jsonSetting); + var prodStr = JsonConvert.SerializeObject(context.Parameters.ProductParameter, jsonSetting); prodStr = JsonHelper.SerializeObject(jObj["product"]); sw.Write(prodStr); } - uploadPartRst = WXUpload.uploadPartBinary(shop, initFileName, blobFullPath, uploadPartId, upProdParam.product.productKey.productId, time1, time2); + uploadPartRst = WXUpload.uploadPartBinary(context.Parameters.Shop, initFileName, blobFullPath, uploadPartId, context.Parameters.ProductParameter.product.productKey.productId, time1, time2); //{"code":0,"etag":"18e3f73046378472219641ef181d3232"} //C:\Users\Administrator\AppData\Local\Temp\9uaeiplr\blob var eTag = BaseRegex.GetStringJson(ref uploadPartRst, "etag"); string rstParmStr = @"{""name"":""" + initFileName + @""",""uploadId"":""" + uploadPartId + @""",""etagList"":[""" + eTag + @"""],""partSeqList"":[1]}"; - var complateRst = WXUpload.completeUploadPart(shop, rstParmStr, upProdParam.product.productKey.productId, time1, time2); + var complateRst = WXUpload.completeUploadPart(context.Parameters.Shop, rstParmStr, context.Parameters.ProductParameter.product.productKey.productId, time1, time2); } - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - var timeSpan = DateTime.Now - startTime; + var timeSpan = DateTime.Now - context.Parameters.StartTime; var duration = timeSpan.TotalSeconds; - cell.Value = "商品已上传" + " " + duration.ParseToInt() + "秒"; + context.Progress.Report("商品已上传" + " " + duration.ParseToInt() + "秒"); })); } // 已传的商品保存为安全商品 - if (dbProd.wx_safe_status == "未校验") + if (context.Product.WxSafeStatus == "未校验") { var url = BaseClass.BuildObjString("product/mdy_pdd_product"); var data = ""; Invoke(new Action(() => { data = UserLogin.GetSignaturex(); - data += "&spu_id=" + dbProd.spu_id; + data += "&spu_id=" + context.Product.SpuId; data += "&wx_safe_status=安全商品"; })); var html = GetHtml.PostUtf8(url, data); @@ -221,7 +222,7 @@ public sealed class SubmitProductStep : WxProductPublishStepBase if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); } - if (!string.IsNullOrEmpty(dbProd.secret_spu_id)) + if (!string.IsNullOrEmpty(context.Product.SecretSpuId)) { //add_secret_spu_id_shop_id_map //测试id "2017522348787531778" FC4C8B7F3C6E4B029AD2A12D4D323B41 // 老函数已作废 var url = BaseClass.BuildObjString("product/wx_add_secret_id_up_map"); @@ -229,12 +230,12 @@ public sealed class SubmitProductStep : WxProductPublishStepBase Invoke(new Action(() => { data = UserLogin.GetSignaturex(); - data += "&up_secret_spu_id=" + dbProd.secret_spu_id; - data += "&up_spu_id=" + dbProd.spu_id; - data += "&shop_id=" + shop.ShopId; - data += "&index=" + Math.Abs(dbProd.secret_spu_id.GetHashCode()) % 1024; - data += "&price_max=" + upProdParam.product.productSkus.Max(s => s.productSkuInfo.salePrice); - data += "&price_min=" + upProdParam.product.productSkus.Min(s => s.productSkuInfo.salePrice); + data += "&up_secret_spu_id=" + context.Product.SecretSpuId; + data += "&up_spu_id=" + context.Product.SpuId; + data += "&shop_id=" + context.Parameters.Shop.ShopId; + data += "&index=" + Math.Abs(context.Product.SecretSpuId.GetHashCode()) % 1024; + data += "&price_max=" + context.Parameters.ProductParameter.product.productSkus.Max(s => s.productSkuInfo.salePrice); + data += "&price_min=" + context.Parameters.ProductParameter.product.productSkus.Min(s => s.productSkuInfo.salePrice); })); var html = GetHtml.PostUtf8(url, data); if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) @@ -243,31 +244,31 @@ public sealed class SubmitProductStep : WxProductPublishStepBase html = GetHtml.PostUtf8(url, data); } - //colUploadCount - var dgvShopRow = dgvShop.Rows.Cast().FirstOrDefault(row => row.Cells["colShopId"]?.Value.ParseToString() == shop.ShopId); - if (dgvShopRow != null) - { - var day = DateTime.Now.ToString("yyyyMMdd").ParseToInt(); - if (!GlobalConfig.dicWxShopUploadInfo.ContainsKey(shop.ShopId)) - GlobalConfig.dicWxShopUploadInfo[shop.ShopId] = new WxShopUploadInfo(); - if (!GlobalConfig.dicWxShopUploadInfo[shop.ShopId].DicDayUploadCount.ContainsKey(day)) - GlobalConfig.dicWxShopUploadInfo[shop.ShopId].DicDayUploadCount[day] = 0; - GlobalConfig.dicWxShopUploadInfo[shop.ShopId].DicDayUploadCount[day] += 1; - // 删除45天前的记录 - var removeKeys = GlobalConfig.dicWxShopUploadInfo[shop.ShopId].DicDayUploadCount.Keys.Where(s => s < DateTime.Now.AddDays(-45).ToString("yyyyMMdd").ParseToInt()).ToList(); - foreach (var key in removeKeys) - { - GlobalConfig.dicWxShopUploadInfo[shop.ShopId].DicDayUploadCount.Remove(key); - } - NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_shop_upload_info", GlobalConfig.dicWxShopUploadInfo); - - Invoke(new Action(() => - { - dgvShopRow.Cells["colUploadCount"].Value = GlobalConfig.dicWxShopUploadInfo[shop.ShopId].DicDayUploadCount[day]; - })); - } - - StopWithResult("{\"success\":true,\"draftId\":" + upProdParam.product.productKey.productId + ",\"status\":\"已上传\",\"msg\":\"上传成功" + commissionRstStr + "\"}"); - return; +// //colUploadCount +// var dgvShopRow = dgvShop.Rows.Cast().FirstOrDefault(row => row.Cells["colShopId"]?.Value.ParseToString() == context.Parameters.Shop.ShopId); +// if (dgvShopRow != null) +// { +// var day = DateTime.Now.ToString("yyyyMMdd").ParseToInt(); +// if (!GlobalConfig.dicWxShopUploadInfo.ContainsKey(context.Parameters.Shop.ShopId)) +// GlobalConfig.dicWxShopUploadInfo[context.Parameters.Shop.ShopId] = new WxShopUploadInfo(); +// if (!GlobalConfig.dicWxShopUploadInfo[context.Parameters.Shop.ShopId].DicDayUploadCount.ContainsKey(day)) +// GlobalConfig.dicWxShopUploadInfo[context.Parameters.Shop.ShopId].DicDayUploadCount[day] = 0; +// GlobalConfig.dicWxShopUploadInfo[context.Parameters.Shop.ShopId].DicDayUploadCount[day] += 1; +// // 删除45天前的记录 +// var removeKeys = GlobalConfig.dicWxShopUploadInfo[context.Parameters.Shop.ShopId].DicDayUploadCount.Keys.Where(s => s < DateTime.Now.AddDays(-45).ToString("yyyyMMdd").ParseToInt()).ToList(); +// foreach (var key in removeKeys) +// { +// GlobalConfig.dicWxShopUploadInfo[context.Parameters.Shop.ShopId].DicDayUploadCount.Remove(key); +// } +// NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_shop_upload_info", GlobalConfig.dicWxShopUploadInfo); +// +// Invoke(new Action(() => +// { +// dgvShopRow.Cells["colUploadCount"].Value = GlobalConfig.dicWxShopUploadInfo[context.Parameters.Shop.ShopId].DicDayUploadCount[day]; +// })); +// } +// +StopWithResult("{\"success\":true,\"draftId\":" + context.Parameters.ProductParameter.product.productKey.productId + ",\"status\":\"已上传\",\"msg\":\"上传成功" + context.Parameters.CommissionRstStr + "\"}"); + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/UploadDetailImagesStep.cs b/Store.Product/Publish/Steps/Wx/UploadDetailImagesStep.cs index 81936d6..4811607 100644 --- a/Store.Product/Publish/Steps/Wx/UploadDetailImagesStep.cs +++ b/Store.Product/Publish/Steps/Wx/UploadDetailImagesStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,37 +34,37 @@ public sealed class UploadDetailImagesStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成商品详情"; + context.Progress.Report("正在生成商品详情"); })); } Thread.Sleep(Randomx.GetId(100, 300)); - upProdParam.product.info.detail = new productDetailParam(); // 详情图 - detailGalleries = prodInfo.detail.galleries.Where(g => g.type == 2).ToList(); - if (detailGalleries.Count == 0) - detailGalleries.Add(new gallery_item() { type = 2, url = prodInfo.detail.galleries.FirstOrDefault(g => g.type == 1)?.url }); + context.Parameters.ProductParameter.product.info.detail = new productDetailParam(); // 详情图 + context.Parameters.DetailGalleries = context.Parameters.ProdInfo.detail.galleries.Where(g => g.type == 2).ToList(); + if (context.Parameters.DetailGalleries.Count == 0) + context.Parameters.DetailGalleries.Add(new gallery_item() { type = 2, url = context.Parameters.ProdInfo.detail.galleries.FirstOrDefault(g => g.type == 1)?.url }); - foreach (var gallery_item in detailGalleries) + foreach (var gallery_item in context.Parameters.DetailGalleries) { try { - if (dbProd.product_get_type_text == "微信店采") + if (context.Product.ProductGetTypeText == "微信店采") { - upProdParam.product.info.detail.detailImg.Add(gallery_item.url); + context.Parameters.ProductParameter.product.info.detail.detailImg.Add(gallery_item.url); continue; } // 获取缓存盗链 详情图 - if (wxImgMapDic.ContainsKey(BaseClass.GetMd5(gallery_item.url))) + if (context.Parameters.WxImgMapDic.ContainsKey(BaseClass.GetMd5(gallery_item.url))) { - upProdParam.product.info.detail.detailImg.Add(wxImgMapDic[BaseClass.GetMd5(gallery_item.url)]); + context.Parameters.ProductParameter.product.info.detail.detailImg.Add(context.Parameters.WxImgMapDic[BaseClass.GetMd5(gallery_item.url)]); continue; } - if (needAddRandomBlock || wantAddRandomBlock || gallery_item.url.Contains("wst.wxapp.tc.qq.com")) + if (context.Parameters.NeedAddRandomBlock || context.Parameters.WantAddRandomBlock || gallery_item.url.Contains("wst.wxapp.tc.qq.com")) { // 如果想打码或者需要打码,就走差异化详情图,不走api直传 } @@ -73,31 +73,31 @@ public sealed class UploadDetailImagesStep : WxProductPublishStepBase // 使用接口链接传详情图 var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; upDate += "&post_data=" + GetHtml.UrlEncodeUtf8("{\"img_url\":\"" + gallery_item.url.Replace("https://", "http://") + "\"}"); var sTime = DateTime.Now; var upDateRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成商品详情图 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在生成商品详情图 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 20 && upDateRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); upDateRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref upDateRst, "img_url"); if (upDateRst.Contains("\"errcode\":0") && !string.IsNullOrEmpty(upImgUrl)) { - upProdParam.product.info.detail.detailImg.Add(upImgUrl); - wxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = upImgUrl; - isChangeImgDic = true; + context.Parameters.ProductParameter.product.info.detail.detailImg.Add(upImgUrl); + context.Parameters.WxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = upImgUrl; + context.Parameters.IsChangeImgDic = true; continue; } else @@ -115,7 +115,7 @@ public sealed class UploadDetailImagesStep : WxProductPublishStepBase try { string errMsg = ""; - var imgBase64 = GetImgBase64ForApi(out errMsg, gallery_item.url, needAddRandomBlock, wantAddRandomBlock); + var imgBase64 = GetImgBase64ForApi(out errMsg, gallery_item.url, context.Parameters.NeedAddRandomBlock, context.Parameters.WantAddRandomBlock); if (!string.IsNullOrEmpty(errMsg)) { throw new Exception(errMsg); @@ -123,7 +123,7 @@ public sealed class UploadDetailImagesStep : WxProductPublishStepBase var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; //upDate += "&is_file=true"; //if (needAddRandomBlock || wantAddRandomBlock) // upDate += "&random_code=true"; @@ -132,26 +132,26 @@ public sealed class UploadDetailImagesStep : WxProductPublishStepBase var sTime = DateTime.Now; var apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在上传商品详情图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在上传商品详情图文件 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 5 && apiUpImgFileRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref apiUpImgFileRst, "img_url"); if (apiUpImgFileRst.Contains("\"errcode\":0") && !string.IsNullOrEmpty(upImgUrl)) { - upProdParam.product.info.detail.detailImg.Add(upImgUrl); - wxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = upImgUrl; - isChangeImgDic = true; + context.Parameters.ProductParameter.product.info.detail.detailImg.Add(upImgUrl); + context.Parameters.WxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = upImgUrl; + context.Parameters.IsChangeImgDic = true; continue; } else @@ -166,16 +166,17 @@ public sealed class UploadDetailImagesStep : WxProductPublishStepBase // 模拟上传图片 bool randomDrawBlock = false; - if (needAddRandomBlock || wantAddRandomBlock) + if (context.Parameters.NeedAddRandomBlock || context.Parameters.WantAddRandomBlock) randomDrawBlock = true; - var locationStr = UploadImg(shop, gallery_item.url, cell, randomDrawBlock); + var locationStr = UploadImg(context.Parameters.Shop, gallery_item.url, randomDrawBlock); if (!locationStr.Contains("\"success\":true")) throw new Exception(locationStr); var location = BaseRegex.GetStringJson(ref locationStr, "Location"); - upProdParam.product.info.detail.detailImg.Add(location); + context.Parameters.ProductParameter.product.info.detail.detailImg.Add(location); //wxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = location; //isChangeImgDic = true; Thread.Sleep(Randomx.GetId(10, 50)); } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/UploadMainImagesStep.cs b/Store.Product/Publish/Steps/Wx/UploadMainImagesStep.cs index 22fff97..e7f1782 100644 --- a/Store.Product/Publish/Steps/Wx/UploadMainImagesStep.cs +++ b/Store.Product/Publish/Steps/Wx/UploadMainImagesStep.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.Config; using AllBase.Model.DBModel; @@ -20,7 +21,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using Work; namespace Store.Product.Publish.Steps.Wx; @@ -34,35 +34,35 @@ public sealed class UploadMainImagesStep : WxProductPublishStepBase protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成主图并识别商品"; + context.Progress.Report("正在生成主图并识别商品"); })); } Thread.Sleep(Randomx.GetId(100, 300)); - mainGalleries = prodInfo.detail.galleries.Where(g => g.type == 1).Take(9).ToList(); - foreach (var gallery_item in mainGalleries) // 9张主图 + context.Parameters.MainGalleries = context.Parameters.ProdInfo.detail.galleries.Where(g => g.type == 1).Take(9).ToList(); + foreach (var gallery_item in context.Parameters.MainGalleries) // 9张主图 { try { - if (dbProd.product_get_type_text == "微信店采") + if (context.Product.ProductGetTypeText == "微信店采") { - upProdInitParam.product.info.headImg.Add(gallery_item.url); - upProdParam.product.info.headImg.Add(gallery_item.url); + context.Parameters.InitParameter.product.info.headImg.Add(gallery_item.url); + context.Parameters.ProductParameter.product.info.headImg.Add(gallery_item.url); continue; } // 获取缓存盗链 主图 - if (wxImgMapDic.ContainsKey(BaseClass.GetMd5(gallery_item.url))) + if (context.Parameters.WxImgMapDic.ContainsKey(BaseClass.GetMd5(gallery_item.url))) { - upProdInitParam.product.info.headImg.Add(wxImgMapDic[BaseClass.GetMd5(gallery_item.url)]); - upProdParam.product.info.headImg.Add(wxImgMapDic[BaseClass.GetMd5(gallery_item.url)]); + context.Parameters.InitParameter.product.info.headImg.Add(context.Parameters.WxImgMapDic[BaseClass.GetMd5(gallery_item.url)]); + context.Parameters.ProductParameter.product.info.headImg.Add(context.Parameters.WxImgMapDic[BaseClass.GetMd5(gallery_item.url)]); continue; } - if (needAddRandomBlock || wantAddRandomBlock || gallery_item.url.Contains("wst.wxapp.tc.qq.com")) + if (context.Parameters.NeedAddRandomBlock || context.Parameters.WantAddRandomBlock || gallery_item.url.Contains("wst.wxapp.tc.qq.com")) { // 如果想打码或者需要打码,就走差异化详情图,不走api直传 } @@ -71,32 +71,32 @@ public sealed class UploadMainImagesStep : WxProductPublishStepBase // 使用接口链接传主图 var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; upDate += "&post_data=" + GetHtml.UrlEncodeUtf8("{\"img_url\":\"" + gallery_item.url.Replace("https://", "http://") + "\"}"); var sTime = DateTime.Now; var upDateRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在生成主图并识别商品 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在生成主图并识别商品 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 20 && upDateRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); upDateRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref upDateRst, "img_url"); if (upDateRst.Contains("\"errcode\":0") && !string.IsNullOrEmpty(upImgUrl)) { - upProdInitParam.product.info.headImg.Add(upImgUrl); - upProdParam.product.info.headImg.Add(upImgUrl); - wxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = upImgUrl; - isChangeImgDic = true; + context.Parameters.InitParameter.product.info.headImg.Add(upImgUrl); + context.Parameters.ProductParameter.product.info.headImg.Add(upImgUrl); + context.Parameters.WxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = upImgUrl; + context.Parameters.IsChangeImgDic = true; continue; } else @@ -114,7 +114,7 @@ public sealed class UploadMainImagesStep : WxProductPublishStepBase try { string errMsg = ""; - var imgBase64 = GetImgBase64ForApi(out errMsg, gallery_item.url, needAddRandomBlock, wantAddRandomBlock, 800, 800); + var imgBase64 = GetImgBase64ForApi(out errMsg, gallery_item.url, context.Parameters.NeedAddRandomBlock, context.Parameters.WantAddRandomBlock, 800, 800); if (!string.IsNullOrEmpty(errMsg)) { throw new Exception(errMsg); @@ -122,7 +122,7 @@ public sealed class UploadMainImagesStep : WxProductPublishStepBase var urlImg = BaseClass.BuildWXImgObjString("product/wx_api_upload_image"); var upDate = UserLogin.GetSignaturex(); - upDate += "&token=" + token.accessToken; + upDate += "&token=" + context.Parameters.Token.accessToken; //upDate += "&is_file=true"; //if (needAddRandomBlock || wantAddRandomBlock) // upDate += "&random_code=true"; @@ -131,27 +131,27 @@ public sealed class UploadMainImagesStep : WxProductPublishStepBase var sTime = DateTime.Now; var apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); - if (cell != null) + if (context.Progress != null) { Invoke(new Action(() => { - cell.Value = "正在上传主图文件并识别商品 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt(); + context.Progress.Report("正在上传主图文件并识别商品 " + (DateTime.Now - sTime).TotalMilliseconds.ParseToInt()); })); } for (int i = 0; i < 5 && apiUpImgFileRst.Contains("access_token expired"); i++) { - token.mdyTime = DateTime.Now.AddDays(-100); - token = new WxApiBLL().GetRandomWxToken(); + context.Parameters.Token.mdyTime = DateTime.Now.AddDays(-100); + context.Parameters.Token = new WxApiBLL().GetRandomWxToken(); apiUpImgFileRst = GetHtml.PostUtf8(urlImg, upDate); } var upImgUrl = BaseRegex.GetStringJson(ref apiUpImgFileRst, "img_url"); if (apiUpImgFileRst.Contains("\"errcode\":0") && !string.IsNullOrEmpty(upImgUrl)) { - upProdInitParam.product.info.headImg.Add(upImgUrl); - upProdParam.product.info.headImg.Add(upImgUrl); - wxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = upImgUrl; - isChangeImgDic = true; + context.Parameters.InitParameter.product.info.headImg.Add(upImgUrl); + context.Parameters.ProductParameter.product.info.headImg.Add(upImgUrl); + context.Parameters.WxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = upImgUrl; + context.Parameters.IsChangeImgDic = true; continue; } else @@ -167,15 +167,15 @@ public sealed class UploadMainImagesStep : WxProductPublishStepBase // 模拟上传图片 if (1 == 1) { - var upImgAuthRst = WXUpload.getUploadTempImgAuth(shop); + var upImgAuthRst = WXUpload.getUploadTempImgAuth(context.Parameters.Shop); for (int i = 0; i < 10 && upImgAuthRst.Contains("LogicError"); i++) { Invoke(new Action(() => { - cell.Value = "图片提报失败,正在重试。" + (i + 1); + context.Progress.Report("图片提报失败,正在重试。" + (i + 1)); })); Thread.Sleep(Randomx.GetId(3000, 6000)); - upImgAuthRst = WXUpload.getUploadTempImgAuth(shop); + upImgAuthRst = WXUpload.getUploadTempImgAuth(context.Parameters.Shop); } if (!upImgAuthRst.Contains("\"code\":0")) { @@ -203,7 +203,7 @@ public sealed class UploadMainImagesStep : WxProductPublishStepBase using (Graphics g = Graphics.FromImage(imageBg)) { g.DrawImage(image, new Rectangle(0, 0, imageBg.Width, imageBg.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel); - if (needAddRandomBlock || wantAddRandomBlock) + if (context.Parameters.NeedAddRandomBlock || context.Parameters.WantAddRandomBlock) { g.FillRectangle(new SolidBrush(Color.FromArgb(Randomx.GetId(256), Randomx.GetId(256), Randomx.GetId(256))), new Rectangle(Randomx.GetId(imageBg.Width - 30), Randomx.GetId(imageBg.Height - 30), 30, 30)); @@ -223,7 +223,7 @@ public sealed class UploadMainImagesStep : WxProductPublishStepBase //------------------------------------------------------------------------------------------------------------------------------------- //上传主图获取路径 - var upImgRst = WXUpload.adtimageupload(shop, imgBase64, disK, disT, ext).ParseToString(); + var upImgRst = WXUpload.adtimageupload(context.Parameters.Shop, imgBase64, disK, disT, ext).ParseToString(); var location = BaseRegex.GetStringJson(ref upImgRst, "Location"); if (string.IsNullOrEmpty(location)) { @@ -232,12 +232,13 @@ public sealed class UploadMainImagesStep : WxProductPublishStepBase error = upImgAuthRst; throw new Exception("主图上传失败 " + error); } - upProdInitParam.product.info.headImg.Add(location); - upProdParam.product.info.headImg.Add(location); + context.Parameters.InitParameter.product.info.headImg.Add(location); + context.Parameters.ProductParameter.product.info.headImg.Add(location); //wxImgMapDic[BaseClass.GetMd5(gallery_item.url)] = location; //isChangeImgDic = true; Thread.Sleep(Randomx.GetId(10, 50)); } } + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/UploadVideoStep.cs b/Store.Product/Publish/Steps/Wx/UploadVideoStep.cs index 68eb8e3..4663bee 100644 --- a/Store.Product/Publish/Steps/Wx/UploadVideoStep.cs +++ b/Store.Product/Publish/Steps/Wx/UploadVideoStep.cs @@ -1,77 +1,21 @@ -using AllBase; -using AllBase.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 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; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; -using Work; namespace Store.Product.Publish.Steps.Wx; + /// -/// 由 WXDBProdUploadForm.UploadProduct 的“上传商品视频”区段迁移。 -/// TODO(迁移): 原区段中的 TEMUKJD/WXUpload/窗体服务引用需按 Store.Product 运行时适配逐项核对。 +/// 商品视频上传步骤。原实现依赖 TEMUKJD 视频上传服务,迁移到独立 DLL 前明确终止。 /// public sealed class UploadVideoStep : WxProductPublishStepBase { public override string Description => "上传商品视频"; - protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) + protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken) { - if (prodInfo.detail.galleries.Any(a => a.type == 6)) - { - List videos = prodInfo.detail.galleries.Where(a => a.type == 6).ToList(); - //下载视频保存 - foreach (var item in videos) - { - Invoke(new Action(() => - { - cell.Value = "开始下载视频"; - })); - byte[] files; - bool d_ret = GetHtml.DownloadFile(item.url, out files); - if (d_ret == false) - { - Invoke(new Action(() => - { - cell.Value = "视频下载失败"; - })); - throw new Exception("视频下载失败"); - } - Invoke(new Action(() => - { - cell.Value = "开始上传视频"; - })); - var uploader = new WXVideoUploader(); - var video = uploader.Upload(shop, selectProd.id.ToString(), files); - upProdParam.product.info.headVideoInfo.Add(new - { - videoUrl = video.DownloadUrl, - videoHeadImg = video.VideoImgUrl, - videoLen = video.VideoDuration, - videoSize = 0, - videoSource = 0, - videoFormat = 0, - playableVideoUrl = video.DownloadUrl - }); - } - } - //prodInfo.detail.galleries.RemoveAll(g => g.type == 6); // 视频暂时移除,以后再视情况加上 + if (context.Parameters.ProdInfo?.detail?.galleries?.Any(a => a.type == 6) == true) + throw new NotSupportedException("商品视频上传服务尚未迁移到 Store.Product。"); + return Task.CompletedTask; } } diff --git a/Store.Product/Publish/Steps/Wx/WXUpload.cs b/Store.Product/Publish/Steps/Wx/WXUpload.cs new file mode 100644 index 0000000..09da81c --- /dev/null +++ b/Store.Product/Publish/Steps/Wx/WXUpload.cs @@ -0,0 +1,51 @@ +using AllBase.Model.Param.WXParam; +using AllBase.Model.Result; +using MAX.Core.Helpers; +using Newtonsoft.Json; +using Store.Management.Framework.Apis; +using System.Collections.Generic; + +namespace Store.Product.Publish.Steps.Wx; + +/// +/// UploadProduct 旧静态上传调用的无控件兼容层。 +/// +internal static class WXUpload +{ + private static readonly WXApi Api = new WXApi(); + private static string Html(HttpResult result) => result?.Html ?? ""; + private static string Json(object value) => JsonConvert.SerializeObject(value, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + + public static string searchProduct(ShopLoginInfo shop, string extCode, string extCode2 = "") => Html(Api.searchProduct(shop.Cookies, extCode, extCode2)); + public static string searchProductWithSpuId(ShopLoginInfo shop, string spuId) => Html(Api.searchProductWithSpuId(shop.Cookies, spuId)); + public static string searchProductWithTitle(ShopLoginInfo shop, string urlEncodeTitle) => Html(Api.searchProductWithTitle(shop.Cookies, urlEncodeTitle)); + public static string getUploadTempImgAuth(ShopLoginInfo shop, int uploadScene = 3) => Html(Api.getUploadTempImgAuth(shop.Cookies, uploadScene)); + public static string adtimageupload(ShopLoginInfo shop, string imgBase64, string disK, long disT, string ext) => Html(Api.adtimageupload(shop.Cookies, "", imgBase64, disK, disT, ext)); + public static string getProductClassify(ShopLoginInfo shop, string goodsName, List goodImgUrlsLst) => Html(Api.getProductClassify(shop.Cookies, goodsName, goodImgUrlsLst)); + public static string getCategoryOnShelf(ShopLoginInfo shop, List catIdLst, string brandId = "2100000000") => Html(Api.getCategoryOnShelf(shop.Cookies, catIdLst, brandId)); + public static string getMixBrand(ShopLoginInfo shop, string catId = "547591") => Html(Api.getMixBrand(shop.Cookies, catId)); + public static string batchCheckCategoryRelation(ShopLoginInfo shop, long catId) => Html(Api.batchCheckCategoryRelation(shop.Cookies, catId)); + public static string addFinderCategoryV2(ShopLoginInfo shop, long catId) => Html(Api.addFinderCategoryV2(shop.Cookies, catId)); + public static string getSingleCategoryData(ShopLoginInfo shop, long catId, List catIdLst) => Html(Api.getSingleCategoryData(shop.Cookies, catId, catIdLst)); + public static string wxCateAuth(ShopLoginInfo shop, List catIdLst, WXCateAuthParam parameter) => Html(Api.wxCateAuth(shop.Cookies, catIdLst, Json(parameter))); + public static string genProductShortTitle(ShopLoginInfo shop, WXGetShortTitleParam parameter) => Html(Api.genProductShortTitle(shop.Cookies, Json(parameter))); + public static string getFreightTemplate(ShopLoginInfo shop) => Html(Api.getFreightTemplate(shop.Cookies)); + public static string getAddress(ShopLoginInfo shop, string searchText = "") => Html(Api.getAddress(shop.Cookies, searchText)); + public static string getAddressById(ShopLoginInfo shop, string addressId) => Html(Api.getAddressById(shop.Cookies, addressId)); + public static string uploadProductDraft(ShopLoginInfo shop, WXUploadProductParam parameter) => Html(Api.uploadProductDraft(shop.Cookies, Json(parameter))); + public static string upProductV2(ShopLoginInfo shop, WXUploadProductParam parameter) => Html(Api.upProductV2(shop.Cookies, Json(parameter))); + public static string checkProductUpload(ShopLoginInfo shop, string productId) => Html(Api.checkProductUpload(shop.Cookies, productId)); + public static string SearchProductUpload(ShopLoginInfo shop, string productId) => Html(Api.SearchProductUpload(shop.Cookies, productId)); + public static string upProductJObjectV2(ShopLoginInfo shop, string prodStr) => Html(Api.upProductJObjectV2(shop.Cookies, prodStr)); + public static string getEditProductV2(ShopLoginInfo shop, string productId) => Html(Api.getEditProductV2(shop.Cookies, productId)); + public static string initUploadPart(ShopLoginInfo shop, string submitJson, string prodId, int time1, int time2) => Html(Api.initUploadPart(shop.Cookies, submitJson, prodId, time1, time2)); + public static string listingAuditFree(ShopLoginInfo shop, WXUploadProductParam parameter, string prodId, int time1, int time2) => Html(Api.listingAuditFree(shop.Cookies, Json(parameter), prodId, time1, time2)); + public static string listingAuditFree(ShopLoginInfo shop, string prodStr, string prodId, int time1, int time2) => Html(Api.listingAuditFree(shop.Cookies, prodStr, prodId, time1, time2)); + public static string uploadPartBinary(ShopLoginInfo shop, string initFileName, string blobPath, string uploadId, string prodId, int time1, int time2) => Html(Api.uploadPartBinary(shop.Cookies, initFileName, blobPath, uploadId, prodId, time1, time2)); + public static string completeUploadPart(ShopLoginInfo shop, string completeJson, string prodId, int time1, int time2) => Html(Api.completeUploadPart(shop.Cookies, completeJson, prodId, time1, time2)); + public static string addAddress(ShopLoginInfo shop, string provinceName, string cityName, string countyName, string detailInfo, string userName, string telNumber) => Html(Api.addAddress(shop.Cookies, provinceName, cityName, countyName, detailInfo, userName, telNumber)); + public static string GetApiServiceList(ShopLoginInfo shop) => Html(Api.GetApiServiceList(shop.Cookies)); + public static string GetAndUpdateWebStatus(ShopLoginInfo shop) => Html(Api.GetAndUpdateWebStatus(shop.Cookies)); + public static string addLeagueItemForUpdatingProduct(ShopLoginInfo shop, int itemSwitch, int itemRatio, int headSupplierItemSwitch, int headSupplierItemRatio, long prodId, int updType = 2) => Html(Api.addLeagueItemForUpdatingProduct(shop.Cookies, itemSwitch, itemRatio, headSupplierItemSwitch, headSupplierItemRatio, prodId, updType)); + public static string generalProductInfoRecommend(ShopLoginInfo shop, WXUploadProductInfoRecommendParam parameter) => Html(Api.generalProductInfoRecommend(shop.Cookies, parameter.productId, Json(parameter))); +} diff --git a/Store.Product/Publish/Steps/Wx/WxApiBLL.cs b/Store.Product/Publish/Steps/Wx/WxApiBLL.cs new file mode 100644 index 0000000..c93c979 --- /dev/null +++ b/Store.Product/Publish/Steps/Wx/WxApiBLL.cs @@ -0,0 +1,62 @@ +using AllBase; +using AllBase.Extension; +using AllBase.Helper; +using AllBase.Model.Config; +using AllBase.Model.Result; +using AllBase.Model.Result.WXResult; +using NaiBa.Util; +using System; +using System.Linq; +using Work; + +namespace Store.Product.Publish.Steps.Wx; + +/// +/// 微信 API Token 的无控件迁移实现。 +/// +internal sealed class WxApiBLL +{ + public WXShopTokenInfo GetRandomWxToken(bool isShowErrorDlg = true) + { + if (GlobalConfig.WxGlobalTokenList == null) + GlobalConfig.WxGlobalTokenList = new ConcurrentList(); + + if (GlobalConfig.WxGlobalTokenList.Count == 0 || GlobalConfig.WxGlobalTokenList.All(t => t.isExpire)) + { + var url = BaseClass.BuildObjString("shop/e57_get_wx_tokens"); + var data = UserLogin.GetSignaturex(); + var html = GetHtml.PostUtf8(url, data); + if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) + html = GetHtml.PostUtf8(url, data); + if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) + throw new Exception("获取授权失败,请重试!" + BaseRegex.GetStringJson(ref html, "msg")); + + var tokenStr = JsonHelper.SerializeObject(JsonHelper.JObjectParse(html)["tokens"].FirstOrDefault()); + GlobalConfig.WxGlobalTokenList = new ConcurrentList(); + GlobalConfig.WxGlobalTokenList.AddRange(JsonHelper.DeserializeJsonToList(tokenStr)); + foreach (var token in GlobalConfig.WxGlobalTokenList) + token.mdyTime = Convert.ToDateTime(BaseRegex.GetStringJson(ref html, "mdy_time")); + } + + return GlobalConfig.WxGlobalTokenList.Where(t => !t.isExpire).OrderBy(x => Guid.NewGuid()).FirstOrDefault() + ?? new WXShopTokenInfo(); + } + + public WXShopTokenInfo GetShopWxToken(ShopLoginInfo shop) + { + var url = BaseClass.BuildObjString("shop/e57_get_wx_shop_token"); + var data = UserLogin.GetSignaturex() + "&shop_id=" + shop.ShopId; + var html = GetHtml.PostUtf8(url, data); + if (!string.IsNullOrEmpty(html) && html.Contains("\"code\":0")) + { + return new WXShopTokenInfo + { + shopId = shop.ShopId, + accessToken = BaseRegex.GetStringJson(ref html, "accessToken"), + mdyTime = DateTime.Now + }; + } + + return new WXShopTokenInfo { shopId = shop.ShopId, accessToken = "", mdyTime = DateTime.Now }; + } +} diff --git a/Store.Product/Publish/Steps/Wx/WxProductPublishStepBase.cs b/Store.Product/Publish/Steps/Wx/WxProductPublishStepBase.cs index 89643b6..40d0cf8 100644 --- a/Store.Product/Publish/Steps/Wx/WxProductPublishStepBase.cs +++ b/Store.Product/Publish/Steps/Wx/WxProductPublishStepBase.cs @@ -1,5 +1,6 @@ using AllBase; using AllBase.Extension; +using NaiBa.Util.Extension; using AllBase.Helper; using AllBase.Model.DBModel; using AllBase.Model.Param.WXParam; @@ -14,209 +15,145 @@ using Store.Product.Publish; using System; using System.Collections.Generic; using System.Drawing; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; +using Work; namespace Store.Product.Publish.Steps.Wx; /// -/// 微信商品发布步骤基类。 -/// 该基类把原窗体方法的可变状态、控件快照和窗体能力适配集中到一个入口, -/// 让各 Step 尽量保持与原 UploadProduct 区段一致的代码,便于逐段核对。 +/// 微信商品发布步骤基类。所有步骤均不依赖 WinForms 控件。 /// public abstract class WxProductPublishStepBase : PublishStep { protected WXApi WXApi => LazyServiceProvider.Instance.LazyGetService(); + protected static void Invoke(Action action) => action?.Invoke(); - private PublishContextBase _context; - - protected WxProductUploadParam Upload => _context.WxUpload; - protected WxProductPublishState State => Upload.State; - protected WxProductUploadOptions Options => Upload.Options; - protected WxProductUploadFormState Form => Options.Form; - protected dynamic RuntimeHost => Upload.Runtime.Host; - - protected ShopLoginInfo shop => Upload.Source.Shop; - protected KJDDBProduct dbProd => Upload.Source.DbProduct; - protected TemuDBProductSelect selectProd => Upload.Source.SelectProduct; - protected DateTime startTime => Upload.Source.StartTime; - protected WXUploadProductInitParam upProdInitParam => Upload.InitParameter; - protected WXUploadProductParam upProdParam => Upload.ProductParameter; - - // TODO(迁移): cell/cancellationTokenSource 原为 WinForms 对象,这里通过代理回调保持步骤代码形状。 - protected dynamic cell => Upload.Runtime.Cell; - protected dynamic cancellationTokenSource => Upload.Runtime.CancellationTokenSource; - - protected dynamic chkFissionGoodsName => Form.chkFissionGoodsName; - protected dynamic txtFissionTitle => Form.txtFissionTitle; - protected dynamic chkSkipUploaded => Form.chkSkipUploaded; - protected dynamic chkCommission => Form.chkCommission; - protected dynamic cmbCommissionAddOrReduce => Form.cmbCommissionAddOrReduce; - protected dynamic txtCommissionChangeValue => Form.txtCommissionChangeValue; - protected dynamic txtMinUpCommission => Form.txtMinUpCommission; - protected dynamic txtMaxUpCommission => Form.txtMaxUpCommission; - protected dynamic chkImgRandomBlock => Form.chkImgRandomBlock; - protected dynamic chkRandomMainImgOrder => Form.chkRandomMainImgOrder; - protected dynamic chkRandomDetailImgOrder => Form.chkRandomDetailImgOrder; - protected dynamic chkFissionRandomPriceChange => Form.chkFissionRandomPriceChange; - protected dynamic txtFissionRandomPriceChange => Form.txtFissionRandomPriceChange; - protected dynamic chkHighestPriceSku => Form.chkHighestPriceSku; - protected dynamic chkLowestPriceSku => Form.chkLowestPriceSku; - protected dynamic chkSameSpecPriceUp => Form.chkSameSpecPriceUp; - protected dynamic chkSameSpecPriceDown => Form.chkSameSpecPriceDown; - protected dynamic txtMinPrice => Form.txtMinPrice; - protected dynamic txtMaxPrice => Form.txtMaxPrice; - protected dynamic txtReplaceText => Form.txtReplaceText; - protected dynamic chkSkipReplaceText => Form.chkSkipReplaceText; - protected dynamic chkRemoveSpecialChar => Form.chkRemoveSpecialChar; - protected dynamic chkUseWXComplateProd => Form.chkUseWXComplateProd; - protected dynamic chkUseRecommand => Form.chkUseRecommand; - protected dynamic cmbSpBrandName => Form.cmbSpBrandName; - protected dynamic txtFilterBoundMax => Form.txtFilterBoundMax; - protected dynamic txtFilterBoundMin => Form.txtFilterBoundMin; - protected dynamic txtMainBorderImgCount => Form.txtMainBorderImgCount; - protected dynamic txtDetailBorderImgCount => Form.txtDetailBorderImgCount; - protected dynamic chkRandomImgBorder => Form.chkRandomImgBorder; - protected dynamic chkAiImage => Form.chkAiImage; - protected dynamic txtAiImgCount => Form.txtAiImgCount; - protected dynamic chkFreightInsurance => Form.chkFreightInsurance; - protected dynamic chkUseShanghaiReturnOrderAddress => Form.chkUseShanghaiReturnOrderAddress; - protected dynamic chkPreSale => Form.chkPreSale; - protected dynamic chkDefaultBestBefore => Form.chkDefaultBestBefore; - protected dynamic txtDefaultBestBefore => Form.txtDefaultBestBefore; - protected dynamic chkTestNoAuditUpload => Form.chkTestNoAuditUpload; - protected dynamic chkUpDraft => Form.chkUpDraft; - protected dynamic chkIsSubmitSuccess => Form.chkIsSubmitSuccess; - protected dynamic dgvShop => Form.dgvShop; - - protected int commissionRate { get => State.CommissionRate; set => State.CommissionRate = value; } - protected int minCommissionRate { get => State.MinCommissionRate; set => State.MinCommissionRate = value; } - protected int maxCommissionRate { get => State.MaxCommissionRate; set => State.MaxCommissionRate = value; } - protected int commissionRateChange { get => State.CommissionRateChange; set => State.CommissionRateChange = value; } - protected int? fromCommissionRate { get => State.FromCommissionRate; set => State.FromCommissionRate = value; } - protected WXGetEditProductInfoLite wxEditProdInfo { get => State.WxEditProdInfo; set => State.WxEditProdInfo = value; } - protected JObject prodJObj { get => State.ProdJObject; set => State.ProdJObject = value; } - protected bool isChangeImgDic { get => State.IsChangeImgDic; set => State.IsChangeImgDic = value; } - protected Dictionary wxImgMapDic { get => State.WxImgMapDic; set => State.WxImgMapDic = value; } - protected PDDProductInfo prodInfo { get => State.ProdInfo; set => State.ProdInfo = value; } - protected int mainImgCount { get => State.MainImgCount; set => State.MainImgCount = value; } - protected bool needAddRandomBlock { get => State.NeedAddRandomBlock; set => State.NeedAddRandomBlock = value; } - protected bool wantAddRandomBlock { get => State.WantAddRandomBlock; set => State.WantAddRandomBlock = value; } - protected WXShopTokenInfo token { get => State.Token; set => State.Token = value; } - protected string prodTitle { get => State.ProdTitle; set => State.ProdTitle = value; } - protected string extCode { get => State.ExtCode; set => State.ExtCode = value; } - protected List mainGalleries { get => State.MainGalleries; set => State.MainGalleries = value; } - protected List aiCateIdLst { get => State.AiCateIdLst; set => State.AiCateIdLst = value; } - protected string getCateRst { get => State.GetCateRst; set => State.GetCateRst = value; } - protected JObject jCateRst { get => State.JCateRst; set => State.JCateRst = value; } - protected long leafCatId { get => State.LeafCatId; set => State.LeafCatId = value; } - protected WxCatBoundInfo bound { get => State.Bound; set => State.Bound = value; } - protected int maxBount { get => State.MaxBound; set => State.MaxBound = value; } - protected int minBount { get => State.MinBound; set => State.MinBound = value; } - protected string spBrandId { get => State.SpBrandId; set => State.SpBrandId = value; } - protected string spBrandName { get => State.SpBrandName; set => State.SpBrandName = value; } - protected string shippingTemplateJson { get => State.ShippingTemplateJson; set => State.ShippingTemplateJson = value; } - protected int shipPrice { get => State.ShipPrice; set => State.ShipPrice = value; } - protected string expressRst { get => State.ExpressRst; set => State.ExpressRst = value; } - protected List detailGalleries { get => State.DetailGalleries; set => State.DetailGalleries = value; } - protected WXUploadProductInfoRecommendParam recommendParamRst { get => State.RecommendParamRst; set => State.RecommendParamRst = value; } - protected allAttrParam productAttr { get => State.ProductAttr; set => State.ProductAttr = value; } - protected int maxSkuSpecCnt { get => State.MaxSkuSpecCnt; set => State.MaxSkuSpecCnt = value; } - protected int skuIndex { get => State.SkuIndex; set => State.SkuIndex = value; } - protected int id { get => State.Id; set => State.Id = value; } - protected long catId { get => State.CatId; set => State.CatId = value; } - protected long fCatId { get => State.FCatId; set => State.FCatId = value; } - protected long valueCatId { get => State.ValueCatId; set => State.ValueCatId = value; } - protected Dictionary dicSpecParentNameId { get => State.DicSpecParentNameId; set => State.DicSpecParentNameId = value; } - protected Dictionary dicSpecParentNameCatId { get => State.DicSpecParentNameCatId; set => State.DicSpecParentNameCatId = value; } - protected Dictionary dicSpecNamefCatId { get => State.DicSpecNameFCatId; set => State.DicSpecNameFCatId = value; } - protected Dictionary dicSpecNameCatId { get => State.DicSpecNameCatId; set => State.DicSpecNameCatId = value; } - protected string uploadDraftRst { get => State.UploadDraftRst; set => State.UploadDraftRst = value; } - protected string commissionRstStr { get => State.CommissionRstStr; set => State.CommissionRstStr = value; } - protected string DefaultAdultBrandId { get => State.DefaultAdultBrandId; set => State.DefaultAdultBrandId = value; } - protected bool IsWxNotUseSoftwareDefaultAddressOnce { get => State.IsWxNotUseSoftwareDefaultAddressOnce; set => State.IsWxNotUseSoftwareDefaultAddressOnce = value; } - protected List lstWXShopTokenInfo { get => State.WxShopTokenInfoList; set => State.WxShopTokenInfoList = value; } - protected List lstQulificationImage { get => State.QualificationImages; set => State.QualificationImages = value; } - protected List forceFilteKeyWords { get => State.ForceFilterKeywords; set => State.ForceFilterKeywords = value; } - protected dynamic lstAddPriceRule => State.AddPriceRules; - protected dynamic wxUploadRule => State.WxUploadRule; - protected string pdd_product_cates { get => State.PddProductCates; set => State.PddProductCates = value; } - protected dynamic upload_draft_product_lst => State.UploadDraftProductList; - - - - /// - /// 正常结束发布流程(例如提交成功、指定上传到草稿箱)时写入最终结果并停止后续步骤。 - /// 失败场景请直接抛出异常。 - /// - protected void StopWithResult(string result) + protected static string GetEC1ExtCode(string spuId) { - Upload.Result = result; - Upload.IsCompleted = true; - } - - protected void Invoke(Action action) - { - action?.Invoke(); - } - - protected string UploadImg(ShopLoginInfo shopInfo, string imgUrl, object cellState = null, bool randomBlock = false) - { - return Upload.Runtime.UploadImgByUrl?.Invoke(shopInfo, imgUrl, cellState ?? cell, randomBlock) ?? ""; - } - - protected string UploadImg(ShopLoginInfo shopInfo, Bitmap image, object cellState = null) - { - return Upload.Runtime.UploadImgByBitmap?.Invoke(shopInfo, image, cellState ?? cell) ?? ""; - } - - protected string GetImgBase64ForApi(out string errorMsg, string imgUrl, bool needAddRandomBlock, bool wantAddRandomBlock, - int imgWidth = 0, int imgHeight = 0, bool wantAddRandomBorder = false) - { - if (Upload.Runtime.GetImgBase64ForApi == null) - { - errorMsg = "GetImgBase64ForApi 尚未从窗体映射到新上下文"; - return ""; - } - - return Upload.Runtime.GetImgBase64ForApi(out errorMsg, imgUrl, needAddRandomBlock, wantAddRandomBlock, imgWidth, imgHeight, wantAddRandomBorder); - } - - protected string GetAiImg(string imgUrl, string imgWord) - { - return Upload.Runtime.GetAiImg?.Invoke(imgUrl, imgWord) ?? ""; + if (spuId.IsNullOrEmpty()) throw new Exception("货号指定失败,值不能为空!"); + return !spuId.StartsWith("EC1") && !spuId.EndsWith("A") ? "EC1" + spuId + "A" : spuId; } protected static string GetNewExtCode(string spuId) { - if (spuId.IsNullOrEmpty()) - throw new Exception("货号指定失败,值不能为空!"); - if (!spuId.StartsWith("P1-")) - return "P1-" + spuId; - return spuId; + if (spuId.IsNullOrEmpty()) throw new Exception("货号指定失败,值不能为空!"); + return !spuId.StartsWith("P1-") ? "P1-" + spuId : spuId; } - protected static string GetEC1ExtCode(string spuId) + protected static WXGetEditProductInfoLite GetProductWXComplate(string secretSpuId, out string errMsg) { - if (spuId.IsNullOrEmpty()) - throw new Exception("货号指定失败,值不能为空!"); - if (!spuId.StartsWith("EC1") && !spuId.EndsWith("A")) - return "EC1" + spuId + "A"; - return spuId; + errMsg = ""; + if (string.IsNullOrEmpty(secretSpuId)) { errMsg = "产品编码为空"; return null; } + + var url = BaseClass.BuildObjString("product/get_pdd_prod_wx_complate_list"); + var data = UserLogin.GetSignaturex() + "&search_secret_spu_ids=" + secretSpuId; + var html = GetHtml.PostUtf8(url, data); + if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); + if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) html = GetHtml.PostUtf8(url, data); + if (string.IsNullOrEmpty(html) || !html.Contains("\"code\":200")) + { + errMsg = BaseRegex.GetStringJson(ref html, "msg"); + if (errMsg.IsNullOrEmpty()) errMsg = html; + errMsg = "取回采数据失败 " + errMsg; + return null; + } + + var array = JObject.Parse(html)["data"]; + if (array == null || !array.Any()) { errMsg = "产品不存在"; return null; } + var item = array.FirstOrDefault()?["wx_edit_prod_json"]; + if (item == null) return null; + try { return JsonHelper.DeserializeJsonToObject(item.ParseToString()); } + catch (Exception ex) { errMsg = "回采数据转换失败 " + ex.Message; return null; } } - // TODO(迁移): 以下两个窗体私有方法的真实实现仍留在 WXDBProdUploadForm,后续应迁到对应服务。 - protected virtual void btnLoginAssistant_Click(object sender, EventArgs e) + protected string GetAiImg(string imgUrl, string imgWord) { - throw new NotImplementedException("请把 WXDBProdUploadForm.btnLoginAssistant_Click 的实现迁入微信发布运行时适配。"); + try + { + var time = BaseClass.DateTimeToTimestampSeconds(DateTime.Now).ToString(); + var code = BaseClass.GetMd5("sadhjufhe15c4fbvFBvcvds+5sdfds@#%$xsc" + time).ToLower(); + var url = "http://svn.jiaotian.vip:" + Randomx.GetId(20010, 20021) + "/index.php?obj=public/image"; + var data = "time=" + time + "&code=" + code + "&image_url=" + imgUrl + "&word=" + imgWord; + var html = GetHtml.PostUtf8(url, data, "", 120); + return !string.IsNullOrEmpty(html) && !html.Contains("error") ? html : "生成Ai图片错误 " + html; + } + catch (Exception ex) { return "生成Ai图片错误 " + ex.Message; } } - protected virtual WXGetEditProductInfoLite GetProductWXComplate(string secretSpuId, out string errMsg) + protected static string GetImgBase64ForApi(out string errorMsg, string imgUrl, bool needAddRandomBlock, bool wantAddRandomBlock, int imgWidth = 0, int imgHeight = 0, bool wantAddRandomBorder = false) { - errMsg = "GetProductWXComplate 尚未迁移"; - return null; + errorMsg = ""; + try + { + var source = GetHtml.GetUrlImg(imgUrl, out var getImgError); + if (source == null || !string.IsNullOrEmpty(getImgError)) + { + errorMsg = "初始化图片上传失败 " + getImgError; + return ""; + } + var width = imgWidth > 0 ? imgWidth : source.Width; + var height = imgHeight > 0 ? imgHeight : source.Height; + using var target = new Bitmap(width, height); + using (var graphics = Graphics.FromImage(target)) + { + graphics.DrawImage(source, new Rectangle(0, 0, width, height), 0, 0, source.Width, source.Height, GraphicsUnit.Pixel); + if (needAddRandomBlock || wantAddRandomBlock) + { + using var brush = new SolidBrush(Color.FromArgb(Randomx.GetId(256), Randomx.GetId(256), Randomx.GetId(256))); + graphics.FillRectangle(brush, new Rectangle(Randomx.GetId(Math.Max(1, width - 30)), Randomx.GetId(Math.Max(1, height - 30)), 30, 30)); + } + if (wantAddRandomBorder) + { + using var brush = new SolidBrush(Color.FromArgb(Randomx.GetId(256), Randomx.GetId(256), Randomx.GetId(256))); + graphics.FillRectangle(brush, new Rectangle(0, 0, width, 20)); + graphics.FillRectangle(brush, new Rectangle(0, height - 20, width, 20)); + graphics.FillRectangle(brush, new Rectangle(0, 0, 20, height)); + graphics.FillRectangle(brush, new Rectangle(width - 20, 0, 20, height)); + } + } + using var stream = new MemoryStream(); + target.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); + return Convert.ToBase64String(stream.ToArray()); + } + catch (Exception ex) { errorMsg = "修改图片失败 " + ex.Message; return ""; } } -} \ No newline at end of file + + protected string UploadImg(ShopLoginInfo shop, string imgUrl, bool needAddRandomBlock = false) + { + var imgBase64 = GetImgBase64ForApi(out var errMsg, imgUrl, needAddRandomBlock, needAddRandomBlock, 800, 800); + if (!string.IsNullOrEmpty(errMsg)) throw new Exception(errMsg); + return UploadImgBase64(shop, imgBase64); + } + + protected string UploadImg(ShopLoginInfo shop, Bitmap image) + { + using var stream = new MemoryStream(); + image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); + return UploadImgBase64(shop, Convert.ToBase64String(stream.ToArray())); + } + + private static string UploadImgBase64(ShopLoginInfo shop, string imgBase64) + { + var authRst = WXUpload.getUploadTempImgAuth(shop); + if (!authRst.Contains("\"code\":0")) throw new Exception(authRst); + var disK = BaseRegex.GetStringJson(ref authRst, "disK"); + var disT = BaseRegex.GetLongJson(ref authRst, "disT"); + var ext = BaseRegex.GetStringJson(ref authRst, "ext"); + return WXUpload.adtimageupload(shop, imgBase64, disK, disT, ext); + } + + protected static void StopWithResult(string result) + { + throw new PublishCompletedException(result); + } +} + +public sealed class PublishCompletedException : Exception +{ + public string Result { get; } + public PublishCompletedException(string result) : base("发布步骤已正常结束") { Result = result; } +} diff --git a/Store.Product/Store.Product.csproj b/Store.Product/Store.Product.csproj index 0f00cdd..1974d17 100644 --- a/Store.Product/Store.Product.csproj +++ b/Store.Product/Store.Product.csproj @@ -1,11 +1,14 @@  + x64 + + ..\DllReference\NaiBa.Util.dll + - diff --git a/TEMUKJD/KJD.csproj b/TEMUKJD/KJD.csproj index dcd466a..012a862 100644 --- a/TEMUKJD/KJD.csproj +++ b/TEMUKJD/KJD.csproj @@ -65,6 +65,7 @@ + diff --git a/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.Designer.cs b/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.Designer.cs index 6f072d9..e894523 100644 --- a/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.Designer.cs +++ b/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.Designer.cs @@ -42,6 +42,7 @@ namespace TemuKJD.WXForms.ProductForms System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); this.ucGroupBoxEx2 = new TemuKJD.UserComponent.UcGroupBoxEx(this.components); + this.btnClearAll = new DevComponents.DotNetBar.PanelEx(); this.txtWaitSeconds = new System.Windows.Forms.TextBox(); this.label6 = new System.Windows.Forms.Label(); this.chkRemoveSpecialChar = new TemuKJD.UserComponent.UcCheckBox(this.components); @@ -264,7 +265,6 @@ namespace TemuKJD.WXForms.ProductForms this.statusBar = new TemuKJD.UserControls.StatusBarUserControl(); this.btnClear = new DevComponents.DotNetBar.PanelEx(); this.panelEx1 = new DevComponents.DotNetBar.PanelEx(); - this.btnClearAll = new DevComponents.DotNetBar.PanelEx(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); @@ -321,7 +321,7 @@ namespace TemuKJD.WXForms.ProductForms // splitContainer1.Panel2 // this.splitContainer1.Panel2.Controls.Add(this.splitContainer3); - this.splitContainer1.Size = new System.Drawing.Size(1710, 641); + this.splitContainer1.Size = new System.Drawing.Size(1832, 641); this.splitContainer1.SplitterDistance = 190; this.splitContainer1.TabIndex = 11; // @@ -361,15 +361,41 @@ namespace TemuKJD.WXForms.ProductForms this.ucGroupBoxEx2.Controls.Add(this.label15); this.ucGroupBoxEx2.Location = new System.Drawing.Point(608, 2); this.ucGroupBoxEx2.Name = "ucGroupBoxEx2"; - this.ucGroupBoxEx2.Size = new System.Drawing.Size(1100, 189); + this.ucGroupBoxEx2.Size = new System.Drawing.Size(1222, 189); this.ucGroupBoxEx2.TabIndex = 667; this.ucGroupBoxEx2.TabStop = false; this.ucGroupBoxEx2.Text = "商品上传"; // + // btnClearAll + // + this.btnClearAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnClearAll.CanvasColor = System.Drawing.SystemColors.Control; + this.btnClearAll.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; + this.btnClearAll.DisabledBackColor = System.Drawing.Color.Empty; + this.btnClearAll.Location = new System.Drawing.Point(1154, 121); + this.btnClearAll.Margin = new System.Windows.Forms.Padding(4, 2, 2, 2); + this.btnClearAll.Name = "btnClearAll"; + this.btnClearAll.Size = new System.Drawing.Size(60, 23); + this.btnClearAll.Style.Alignment = System.Drawing.StringAlignment.Center; + this.btnClearAll.Style.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(185)))), ((int)(((byte)(215)))), ((int)(((byte)(255))))); + this.btnClearAll.Style.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(185)))), ((int)(((byte)(215)))), ((int)(((byte)(255))))); + this.btnClearAll.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; + this.btnClearAll.Style.BorderColor.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255))))); + this.btnClearAll.Style.ForeColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelText; + this.btnClearAll.Style.GradientAngle = 90; + this.btnClearAll.StyleMouseDown.Alignment = System.Drawing.StringAlignment.Center; + this.btnClearAll.StyleMouseOver.Alignment = System.Drawing.StringAlignment.Center; + this.btnClearAll.StyleMouseOver.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255))))); + this.btnClearAll.StyleMouseOver.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255))))); + this.btnClearAll.StyleMouseOver.ForeColor.Color = System.Drawing.Color.White; + this.btnClearAll.TabIndex = 929; + this.btnClearAll.Text = "清空全部"; + this.btnClearAll.Click += new System.EventHandler(this.btnClearAll_Click); + // // txtWaitSeconds // this.txtWaitSeconds.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.txtWaitSeconds.Location = new System.Drawing.Point(1056, 12); + this.txtWaitSeconds.Location = new System.Drawing.Point(1178, 12); this.txtWaitSeconds.Margin = new System.Windows.Forms.Padding(0, 2, 0, 2); this.txtWaitSeconds.Name = "txtWaitSeconds"; this.txtWaitSeconds.Size = new System.Drawing.Size(22, 23); @@ -381,7 +407,7 @@ namespace TemuKJD.WXForms.ProductForms // this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(1015, 15); + this.label6.Location = new System.Drawing.Point(1137, 15); this.label6.Margin = new System.Windows.Forms.Padding(6, 0, 0, 0); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(44, 17); @@ -394,7 +420,7 @@ namespace TemuKJD.WXForms.ProductForms this.chkRemoveSpecialChar.AutoSize = true; this.chkRemoveSpecialChar.Checked = true; this.chkRemoveSpecialChar.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkRemoveSpecialChar.Location = new System.Drawing.Point(886, 13); + this.chkRemoveSpecialChar.Location = new System.Drawing.Point(1008, 13); this.chkRemoveSpecialChar.Name = "chkRemoveSpecialChar"; this.chkRemoveSpecialChar.Size = new System.Drawing.Size(135, 21); this.chkRemoveSpecialChar.TabIndex = 896; @@ -406,7 +432,7 @@ namespace TemuKJD.WXForms.ProductForms // this.chkIsSubmitSuccess.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.chkIsSubmitSuccess.AutoSize = true; - this.chkIsSubmitSuccess.Location = new System.Drawing.Point(790, 13); + this.chkIsSubmitSuccess.Location = new System.Drawing.Point(912, 13); this.chkIsSubmitSuccess.Name = "chkIsSubmitSuccess"; this.chkIsSubmitSuccess.Size = new System.Drawing.Size(99, 21); this.chkIsSubmitSuccess.TabIndex = 906; @@ -418,7 +444,7 @@ namespace TemuKJD.WXForms.ProductForms // this.chkUseShanghaiReturnOrderAddress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.chkUseShanghaiReturnOrderAddress.AutoSize = true; - this.chkUseShanghaiReturnOrderAddress.Location = new System.Drawing.Point(659, 13); + this.chkUseShanghaiReturnOrderAddress.Location = new System.Drawing.Point(781, 13); this.chkUseShanghaiReturnOrderAddress.Name = "chkUseShanghaiReturnOrderAddress"; this.chkUseShanghaiReturnOrderAddress.Size = new System.Drawing.Size(135, 21); this.chkUseShanghaiReturnOrderAddress.TabIndex = 916; @@ -430,7 +456,7 @@ namespace TemuKJD.WXForms.ProductForms // this.label7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(1077, 15); + this.label7.Location = new System.Drawing.Point(1199, 15); this.label7.Margin = new System.Windows.Forms.Padding(6, 0, 0, 0); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(20, 17); @@ -497,7 +523,7 @@ namespace TemuKJD.WXForms.ProductForms this.btnStop.CanvasColor = System.Drawing.SystemColors.Control; this.btnStop.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; this.btnStop.DisabledBackColor = System.Drawing.Color.Empty; - this.btnStop.Location = new System.Drawing.Point(1032, 65); + this.btnStop.Location = new System.Drawing.Point(1154, 65); this.btnStop.Margin = new System.Windows.Forms.Padding(4, 2, 2, 2); this.btnStop.Name = "btnStop"; this.btnStop.Size = new System.Drawing.Size(60, 23); @@ -523,7 +549,7 @@ namespace TemuKJD.WXForms.ProductForms this.chkRandomCompanyProd.AutoSize = true; this.chkRandomCompanyProd.Checked = true; this.chkRandomCompanyProd.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkRandomCompanyProd.Location = new System.Drawing.Point(1032, 144); + this.chkRandomCompanyProd.Location = new System.Drawing.Point(1154, 144); this.chkRandomCompanyProd.Name = "chkRandomCompanyProd"; this.chkRandomCompanyProd.Size = new System.Drawing.Size(99, 21); this.chkRandomCompanyProd.TabIndex = 889; @@ -549,7 +575,7 @@ namespace TemuKJD.WXForms.ProductForms this.btnClearDgv.CanvasColor = System.Drawing.SystemColors.Control; this.btnClearDgv.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; this.btnClearDgv.DisabledBackColor = System.Drawing.Color.Empty; - this.btnClearDgv.Location = new System.Drawing.Point(1032, 93); + this.btnClearDgv.Location = new System.Drawing.Point(1154, 93); this.btnClearDgv.Margin = new System.Windows.Forms.Padding(4, 2, 2, 2); this.btnClearDgv.Name = "btnClearDgv"; this.btnClearDgv.Size = new System.Drawing.Size(60, 23); @@ -722,7 +748,7 @@ namespace TemuKJD.WXForms.ProductForms this.btnUpload.Cursor = System.Windows.Forms.Cursors.Hand; this.btnUpload.DisabledBackColor = System.Drawing.Color.Empty; this.btnUpload.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); - this.btnUpload.Location = new System.Drawing.Point(1032, 37); + this.btnUpload.Location = new System.Drawing.Point(1154, 37); this.btnUpload.Name = "btnUpload"; this.btnUpload.Size = new System.Drawing.Size(60, 23); this.btnUpload.Style.Alignment = System.Drawing.StringAlignment.Center; @@ -789,7 +815,7 @@ namespace TemuKJD.WXForms.ProductForms this.ucTabControlMetro1.Name = "ucTabControlMetro1"; this.ucTabControlMetro1.SelectedIndex = 0; this.ucTabControlMetro1.ShowCloseButton = false; - this.ucTabControlMetro1.Size = new System.Drawing.Size(620, 176); + this.ucTabControlMetro1.Size = new System.Drawing.Size(742, 176); this.ucTabControlMetro1.TabIndex = 822; this.ucTabControlMetro1.TabSelectColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255))))); this.ucTabControlMetro1.TabSelectTextColor = System.Drawing.Color.Gray; @@ -835,7 +861,7 @@ namespace TemuKJD.WXForms.ProductForms this.上传参数1.Location = new System.Drawing.Point(4, 28); this.上传参数1.Name = "上传参数1"; this.上传参数1.Padding = new System.Windows.Forms.Padding(3); - this.上传参数1.Size = new System.Drawing.Size(612, 144); + this.上传参数1.Size = new System.Drawing.Size(734, 144); this.上传参数1.TabIndex = 1; this.上传参数1.Text = "上传参数"; this.上传参数1.UseVisualStyleBackColor = true; @@ -927,7 +953,7 @@ namespace TemuKJD.WXForms.ProductForms // this.chkUseRecommand.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.chkUseRecommand.AutoSize = true; - this.chkUseRecommand.Location = new System.Drawing.Point(493, 51); + this.chkUseRecommand.Location = new System.Drawing.Point(615, 51); this.chkUseRecommand.Name = "chkUseRecommand"; this.chkUseRecommand.Size = new System.Drawing.Size(123, 21); this.chkUseRecommand.TabIndex = 907; @@ -1014,7 +1040,7 @@ namespace TemuKJD.WXForms.ProductForms // this.chkUpDraft.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.chkUpDraft.AutoSize = true; - this.chkUpDraft.Location = new System.Drawing.Point(493, 72); + this.chkUpDraft.Location = new System.Drawing.Point(615, 72); this.chkUpDraft.Name = "chkUpDraft"; this.chkUpDraft.Size = new System.Drawing.Size(87, 21); this.chkUpDraft.TabIndex = 769; @@ -1077,7 +1103,7 @@ namespace TemuKJD.WXForms.ProductForms this.txtReplaceText.MaxLength = 1000000; this.txtReplaceText.Multiline = true; this.txtReplaceText.Name = "txtReplaceText"; - this.txtReplaceText.Size = new System.Drawing.Size(423, 40); + this.txtReplaceText.Size = new System.Drawing.Size(545, 40); this.txtReplaceText.TabIndex = 740; this.txtReplaceText.Text = "真丝,蚕丝,香云纱,羊绒,羊毛,羊羔绒,羊羔毛,羽绒,皮草"; this.txtReplaceText.TextChanged += new System.EventHandler(this.txtReplaceText_TextChanged); @@ -2723,7 +2749,7 @@ namespace TemuKJD.WXForms.ProductForms // splitContainer3.Panel2 // this.splitContainer3.Panel2.Controls.Add(this.splitContainer4); - this.splitContainer3.Size = new System.Drawing.Size(1710, 447); + this.splitContainer3.Size = new System.Drawing.Size(1832, 447); this.splitContainer3.SplitterDistance = 418; this.splitContainer3.TabIndex = 1; // @@ -2754,7 +2780,7 @@ namespace TemuKJD.WXForms.ProductForms this.splitContainer2.Panel2.Controls.Add(this.chkTestNoAuditUpload); this.splitContainer2.Panel2.Controls.Add(this.dgvSelectProduct); this.splitContainer2.Panel2.Padding = new System.Windows.Forms.Padding(0, 0, 4, 0); - this.splitContainer2.Size = new System.Drawing.Size(1710, 418); + this.splitContainer2.Size = new System.Drawing.Size(1832, 418); this.splitContainer2.SplitterDistance = 410; this.splitContainer2.TabIndex = 0; // @@ -2991,7 +3017,7 @@ namespace TemuKJD.WXForms.ProductForms // this.pbLoading.Anchor = System.Windows.Forms.AnchorStyles.None; this.pbLoading.Image = global::TemuKJD.Properties.Resources.loading_blue; - this.pbLoading.Location = new System.Drawing.Point(623, 187); + this.pbLoading.Location = new System.Drawing.Point(684, 187); this.pbLoading.Name = "pbLoading"; this.pbLoading.Size = new System.Drawing.Size(50, 50); this.pbLoading.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; @@ -3006,7 +3032,7 @@ namespace TemuKJD.WXForms.ProductForms this.并发上传.Cursor = System.Windows.Forms.Cursors.Hand; this.并发上传.DisabledBackColor = System.Drawing.Color.Empty; this.并发上传.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); - this.并发上传.Location = new System.Drawing.Point(1170, 30); + this.并发上传.Location = new System.Drawing.Point(1292, 30); this.并发上传.Name = "并发上传"; this.并发上传.Size = new System.Drawing.Size(118, 23); this.并发上传.Style.Alignment = System.Drawing.StringAlignment.Center; @@ -3118,7 +3144,7 @@ namespace TemuKJD.WXForms.ProductForms this.dgvSelectProduct.Name = "dgvSelectProduct"; this.dgvSelectProduct.ReadOnly = true; this.dgvSelectProduct.RowTemplate.Height = 23; - this.dgvSelectProduct.Size = new System.Drawing.Size(1292, 418); + this.dgvSelectProduct.Size = new System.Drawing.Size(1414, 418); this.dgvSelectProduct.TabIndex = 187; this.dgvSelectProduct.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvSelectProduct_CellContentClick); // @@ -3324,8 +3350,8 @@ namespace TemuKJD.WXForms.ProductForms // this.splitContainer4.Panel2.Controls.Add(this.btnClear); this.splitContainer4.Panel2.Controls.Add(this.panelEx1); - this.splitContainer4.Size = new System.Drawing.Size(1710, 25); - this.splitContainer4.SplitterDistance = 1019; + this.splitContainer4.Size = new System.Drawing.Size(1832, 25); + this.splitContainer4.SplitterDistance = 1141; this.splitContainer4.TabIndex = 3; // // statusBar @@ -3336,7 +3362,7 @@ namespace TemuKJD.WXForms.ProductForms this.statusBar.Location = new System.Drawing.Point(0, 0); this.statusBar.Margin = new System.Windows.Forms.Padding(0); this.statusBar.Name = "statusBar"; - this.statusBar.Size = new System.Drawing.Size(1019, 25); + this.statusBar.Size = new System.Drawing.Size(1141, 25); this.statusBar.TabIndex = 2; // // btnClear @@ -3389,37 +3415,11 @@ namespace TemuKJD.WXForms.ProductForms this.panelEx1.Text = "停止当前操作"; this.panelEx1.Visible = false; // - // btnClearAll - // - this.btnClearAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnClearAll.CanvasColor = System.Drawing.SystemColors.Control; - this.btnClearAll.ColorSchemeStyle = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btnClearAll.DisabledBackColor = System.Drawing.Color.Empty; - this.btnClearAll.Location = new System.Drawing.Point(1032, 121); - this.btnClearAll.Margin = new System.Windows.Forms.Padding(4, 2, 2, 2); - this.btnClearAll.Name = "btnClearAll"; - this.btnClearAll.Size = new System.Drawing.Size(60, 23); - this.btnClearAll.Style.Alignment = System.Drawing.StringAlignment.Center; - this.btnClearAll.Style.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(185)))), ((int)(((byte)(215)))), ((int)(((byte)(255))))); - this.btnClearAll.Style.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(185)))), ((int)(((byte)(215)))), ((int)(((byte)(255))))); - this.btnClearAll.Style.Border = DevComponents.DotNetBar.eBorderType.SingleLine; - this.btnClearAll.Style.BorderColor.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255))))); - this.btnClearAll.Style.ForeColor.ColorSchemePart = DevComponents.DotNetBar.eColorSchemePart.PanelText; - this.btnClearAll.Style.GradientAngle = 90; - this.btnClearAll.StyleMouseDown.Alignment = System.Drawing.StringAlignment.Center; - this.btnClearAll.StyleMouseOver.Alignment = System.Drawing.StringAlignment.Center; - this.btnClearAll.StyleMouseOver.BackColor1.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255))))); - this.btnClearAll.StyleMouseOver.BackColor2.Color = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(126)))), ((int)(((byte)(255))))); - this.btnClearAll.StyleMouseOver.ForeColor.Color = System.Drawing.Color.White; - this.btnClearAll.TabIndex = 929; - this.btnClearAll.Text = "清空全部"; - this.btnClearAll.Click += new System.EventHandler(this.btnClearAll_Click); - // // WXDBProdUploadForm // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.BackColor = System.Drawing.Color.White; - this.ClientSize = new System.Drawing.Size(1710, 641); + this.ClientSize = new System.Drawing.Size(1832, 641); this.Controls.Add(this.splitContainer1); this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.KeyPreview = true; diff --git a/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.cs b/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.cs index bd6664c..c623ae6 100644 --- a/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.cs +++ b/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.cs @@ -35,6 +35,8 @@ using TemuKJD.UserControls; using TemuKJD.WXForms.ShopForms; using Work; using Work.BLL.Tools; +using Store.Product.Models.PublishParameters; +using Store.Product.Publish.Steps; using Work.Services; using static System.Net.Mime.MediaTypeNames; @@ -49,6 +51,8 @@ namespace TemuKJD.WXForms.ProductForms public CancellationTokenSource cancellationTokenSource { get; set; } = null; public bool IsWxNotUseSoftwareDefaultAddressOnce { get; set; } = false; + public WXPublishParameters PublishParameters { get; set; } = new WXPublishParameters(); + ConcurrentList lstAddPriceRule = new ConcurrentList(); bool isInit = false; @@ -1059,6 +1063,98 @@ namespace TemuKJD.WXForms.ProductForms void AddProductArr(List shopIdLst) { + PublishParameters = new WXPublishParameters + { + // 复用基类已有参数。 + TitlePrefix = txtTitleHeadWord.Text.Trim(), + StorageType = chkUpDraft.Checked ? ProductStorage.InStock : ProductStorage.OnSale, + IsFilterPrice = new SwitchParams>( + !string.IsNullOrWhiteSpace(txtMinPrice.Text) || !string.IsNullOrWhiteSpace(txtMaxPrice.Text), + new Tuple( + string.IsNullOrWhiteSpace(txtMinPrice.Text) ? 0 : txtMinPrice.Text.Trim().ParseToInt(), + string.IsNullOrWhiteSpace(txtMaxPrice.Text) ? int.MaxValue : txtMaxPrice.Text.Trim().ParseToInt())), + IsFilterCustomTitleKeywors = chkSkipReplaceText.Checked, + IsRemoveCustomTitleKeywors = !chkSkipReplaceText.Checked && !string.IsNullOrWhiteSpace(txtReplaceText.Text), + + // 原 WXUploadRule 对应参数。 + PreSaleDays = txtPreDays.Text.Trim().ParseToInt(), + FilterWords = txtReplaceText.Text.Trim(), + IsSkipHasFilterWordsProd = chkSkipReplaceText.Checked, + SkuMinPrice = string.IsNullOrWhiteSpace(txtMinPrice.Text) ? 0 : txtMinPrice.Text.Trim().ParseToInt(), + SkuMaxPrice = string.IsNullOrWhiteSpace(txtMaxPrice.Text) ? int.MaxValue : txtMaxPrice.Text.Trim().ParseToInt(), + WaitSeconds = txtWaitSeconds.Text.Trim().ParseToInt(), + OnlyHighestPriceSku = chkHighestPriceSku.Checked, + OnlyLowestPriceSku = chkLowestPriceSku.Checked, + SameSpecSamePriceUp = chkSameSpecPriceUp.Checked, + SameSpecSamePriceDown = chkSameSpecPriceDown.Checked, + SkipUploaded = chkSkipUploaded.Checked, + SkipExisting = chkSkipUploaded.Checked, + UpDraft = chkUpDraft.Checked, + IsPreSale = chkPreSale.Checked, + TitleHeadWords = txtTitleHeadWord.Text.Trim(), + IsSaveBound = chkSaveBound.Checked, + FilterBoundMinSave = txtFilterBoundMin.Text.Trim().ParseToInt(), + FilterBoundMaxSave = txtFilterBoundMax.Text.Trim().ParseToInt(), + IsAiShortTitle = chkAiShortTitle.Checked, + IsUseWXComplateProd = chkUseWXComplateProd.Checked, + IsUseShanghaiReturnOrderAddress = chkUseShanghaiReturnOrderAddress.Checked, + + // UploadProduct 内直接读取的窗体参数。 + IsFissionTitle = chkFissionGoodsName.Checked, + FissionTitles = txtFissionTitle.Text, + IsRemoveSpecialChar = chkRemoveSpecialChar.Checked, + IsCommissionUpload = chkCommission.Checked, + IsCommissionIncrease = cmbCommissionAddOrReduce.Text == "增加", + CommissionMinPercent = txtMinUpCommission.Text.Trim().ParseToInt(), + CommissionMaxPercent = txtMaxUpCommission.Text.Trim().ParseToInt(), + CommissionChangePercent = txtCommissionChangeValue.Text.Trim().ParseToInt(), + IsUseRecommendation = chkUseRecommand.Checked, + IsImageRandomBlock = chkImgRandomBlock.Checked, + IsRandomMainImageOrder = chkRandomMainImgOrder.Checked, + IsRandomDetailImageOrder = chkRandomDetailImgOrder.Checked, + IsFissionRandomPriceChange = chkFissionRandomPriceChange.Checked, + FissionRandomPriceChangeValue = txtFissionRandomPriceChange.Text.Trim().ParseToDecimal(), + SpecialBrandName = cmbSpBrandName.Text.Trim(), + IsAiImage = chkAiImage.Checked, + AiImageCount = txtAiImgCount.Text.Trim().ParseToInt(), + IsDefaultBestBefore = chkDefaultBestBefore.Checked, + DefaultBestBeforeDays = txtDefaultBestBefore.Text.Trim().ParseToInt(), + IsRandomImageBorder = chkRandomImgBorder.Checked, + MainBorderImageCount = txtMainBorderImgCount.Text.Trim().ParseToInt(), + DetailBorderImageCount = txtDetailBorderImgCount.Text.Trim().ParseToInt(), + IsFreightInsurance = chkFreightInsurance.Checked, + IsTestNoAuditUpload = chkTestNoAuditUpload.Checked, + IsCheckSubmitSuccess = chkIsSubmitSuccess.Checked, + UseSoftwareDefaultAddress = GlobalConfig.GlobalSettings.IsWxUseSoftwareDefaultAddress, + IgnoreSoftwareDefaultAddressOnce = IsWxNotUseSoftwareDefaultAddressOnce, + + // 加价规则与商品价格/SKU/图片参数一起迁移。 + DefaultAddPriceRule = new WXAddPriceRule + { + MoreThanPrice = defaultAddPriceRule.MoreThanPrice, + LessThanPrice = defaultAddPriceRule.LessThanPrice, + AddPriceTimes = defaultAddPriceRule.AddPriceTimes, + AddMorePrice = defaultAddPriceRule.AddMorePrice, + SinglePriceAdd = defaultAddPriceRule.SinglePriceAdd, + AddMorePriceFirst = defaultAddPriceRule.AddMorePriceFirst, + StockNum = defaultAddPriceRule.StockNum, + IsStepAddPrice = defaultAddPriceRule.IsStepAddPrice, + ShippingPriceTimes = defaultAddPriceRule.ShippingPriceTimes + }, + AddPriceRules = lstAddPriceRule.Select(rule => new WXAddPriceRule + { + MoreThanPrice = rule.MoreThanPrice, + LessThanPrice = rule.LessThanPrice, + AddPriceTimes = rule.AddPriceTimes, + AddMorePrice = rule.AddMorePrice, + SinglePriceAdd = rule.SinglePriceAdd, + AddMorePriceFirst = rule.AddMorePriceFirst, + StockNum = rule.StockNum, + IsStepAddPrice = rule.IsStepAddPrice, + ShippingPriceTimes = rule.ShippingPriceTimes + }).ToList() + }; + Invoke(new Action(() => { this.pbLoading.Visible = true; @@ -7838,33 +7934,90 @@ Content-Type: application/octet-stream public class WXUploadRule { + /// + /// 预售天数(页面限制为 3-45 天)。 + /// public int PreSaleDays { get; set; } = 5; + /// + /// 需要移除的敏感词,多个词使用逗号分隔。 + /// public string FilterWords { get; set; } = "顶级,之王,二手,亏本,冲量,白菜价,跳楼价,xx,xxx,最大,最小,低价,降价,成本,赔钱,甩卖,真丝,蚕丝,香云纱,羊绒,羊毛,羊羔绒,羊羔毛,羽绒,皮草"; + /// + /// 是否跳过标题中包含过滤词的商品。 + /// public bool IsSkipHasFilterWordsProd { get; set; } = false; + /// + /// 跳过最低售价低于该值的 SKU(单位:元)。 + /// public int SkuMinPrice { get; set; } = 10; + /// + /// 跳过最高售价高于该值的 SKU(单位:元)。 + /// public int SkuMaxPrice { get; set; } = 9999; + /// + /// 商品上传操作后的额外等待秒数(无论上传成功或失败)。 + /// public int WaitSeconds { get; set; } = 10; + /// + /// 是否只保留最高价 SKU。 + /// public bool OnlyHighestPriceSku { get; set; } = false; + /// + /// 是否只保留最低价 SKU。 + /// public bool OnlyLowestPriceSku { get; set; } = false; + /// + /// 是否启用颜色规格同价(上浮)。 + /// public bool SameSpecSamePriceUp { get; set; } = false; + /// + /// 是否启用颜色规格同价(下浮)。 + /// public bool SameSpecSamePriceDown { get; set; } = false; + /// + /// 是否跳过已铺货商品。 + /// public bool SkipUploaded { get; set; } = true; + /// + /// 是否仅上传草稿,不上架商品。 + /// public bool UpDraft { get; set; } = false; + /// + /// 是否启用预售天数。 + /// public bool IsPreSale { get; set; } = false; + /// + /// 添加到商品标题最前面的标题前缀词。 + /// public string TitleHeadWords { get; set; } = ""; + /// + /// 是否记住待传类目保证金的过滤范围。 + /// public bool IsSaveBound { get; set; } = false; + /// + /// 待传类目保证金过滤范围下限(单位:元)。 + /// public int FilterBoundMinSave { get; set; } = 1000; + /// + /// 待传类目保证金过滤范围上限(单位:元)。 + /// public int FilterBoundMaxSave { get; set; } = 1000; + /// + /// 是否使用 AI 优化商品标题。 + /// public bool IsAiShortTitle { get; set; } = false; + /// + /// 是否使用回采数据。 + /// public bool IsUseWXComplateProd { get; set; } /// - /// 上海仓退货 + /// 是否使用拍单退货仓地址。 /// public bool IsUseShanghaiReturnOrderAddress { get; set; } = false; } diff --git a/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.resx b/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.resx index 4a10eec..f1178ae 100644 --- a/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.resx +++ b/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.resx @@ -117,6 +117,69 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 144, 93 + + + 17, 93 + + + 1319, 55 + + + 1179, 55 + + + 1022, 55 + + + 865, 55 + + + 746, 55 + + + 614, 55 + + + 467, 55 + + + 320, 55 + + + 163, 55 + + + 17, 55 + + + 1204, 17 + + + 1056, 17 + + + 936, 17 + + + 804, 17 + + + 664, 17 + + + 532, 17 + + + 384, 17 + + + 238, 17 + True @@ -156,6 +219,9 @@ True + + 135, 17 + True @@ -219,4 +285,10 @@ True + + 245, 93 + + + 349, 93 + \ No newline at end of file