This commit is contained in:
chfei authored and chfei committed 2026-09-14 09:16:59 +08:00
1 parent c2dcedd238
commit 16cdd3d46e
34 files changed
+837 -481

No files matched your search

@@ -179,10 +179,6 @@ public class ProductBase
/// </summary>
public string SkuSecretJson { get; set; }
/// <summary>
/// 新增:微信图片映射JSON。
/// </summary>
public string WxImgMapJson { get; set; }
/// <summary>
/// 新增:商品来源类型名称。
/// </summary>
public string ProductGetTypeText { get; set; }
@@ -195,14 +191,6 @@ public class ProductBase
/// </summary>
public string SpecialProdType { get; set; }
/// <summary>
/// 新增:是否存在微信回采格式数据。
/// </summary>
public string HasWxFormat { get; set; }
/// <summary>
/// 新增:微信安全状态。
/// </summary>
public string WxSafeStatus { get; set; }
/// <summary>
/// 新增:价格文本。
/// </summary>
public string PriceText { get; set; }
@@ -215,22 +203,6 @@ public class ProductBase
/// </summary>
public string AddUserName { get; set; }
/// <summary>
/// 新增:微信一级类目ID。
/// </summary>
public long? WxCat1 { get; set; }
/// <summary>
/// 新增:微信二级类目ID。
/// </summary>
public long? WxCat2 { get; set; }
/// <summary>
/// 新增:微信三级类目ID。
/// </summary>
public long? WxCat3 { get; set; }
/// <summary>
/// 新增:微信叶子类目ID。
/// </summary>
public long? WxCatLeaf { get; set; }
/// <summary>
/// 新增:是否发送到外部服务。
/// </summary>
public int? SendToOutServer { get; set; }
@@ -0,0 +1,28 @@
namespace Store.Product.Models.Product;
/// <summary>
/// 微信商品上传使用的商品模型。继承通用商品基类,并承载微信平台专属字段。
/// </summary>
public class WxProductUploadProduct : ProductBase
{
/// <summary>微信图片映射 JSON。</summary>
public string WxImgMapJson { get; set; }
/// <summary>是否存在微信回采格式数据。</summary>
public string HasWxFormat { get; set; }
/// <summary>微信安全状态。</summary>
public string WxSafeStatus { get; set; }
/// <summary>微信一级类目 ID。</summary>
public long? WxCat1 { get; set; }
/// <summary>微信二级类目 ID。</summary>
public long? WxCat2 { get; set; }
/// <summary>微信三级类目 ID。</summary>
public long? WxCat3 { get; set; }
/// <summary>微信叶子类目 ID。</summary>
public long? WxCatLeaf { get; set; }
}
@@ -5,6 +5,7 @@ using AllBase.Model.Result.PDDResult;
using AllBase.Model.Result.WXResult;
using Newtonsoft.Json.Linq;
using Store.Framework.Extensions;
using Store.Product.Models.Product;
using System;
using System.Collections.Generic;
using System.Drawing;
@@ -34,11 +35,27 @@ public class WxProductUploadParam
public class WxProductUploadSource
{
public ShopLoginInfo Shop { get; set; }
public KJDDBProduct DbProduct { get; set; }
public TemuDBProductSelect SelectProduct { get; set; }
/// <summary>已完成商品与选品定制组合后的商品数据。</summary>
public WxProductUploadProduct Product { get; set; } = new();
/// <summary>上传任务状态,仅用于结果回写,不作为商品数据源。</summary>
public WxProductPublishTask Task { get; set; } = new();
public DateTime StartTime { get; set; } = DateTime.Now;
}
/// <summary>
/// 上传任务结果。只保存任务状态和最终草稿参数,不保存原始商品数据。
/// </summary>
public class WxProductPublishTask
{
public long id { get; set; }
public string out_product_Id { get; set; }
public string shop_id { get; set; }
public string draft_id { get; set; }
public string status { get; set; }
public DateTime add_time { get; set; }
public WXUploadProductParam wxDraftProduct { get; set; }
}
/// <summary>
/// 原 UploadProduct 方法中跨 #region 使用的可变状态。
/// TODO(迁移): 个别字段当前为 dynamic,需按 Store.Product 最终 DTO 改为明确类型。
@@ -100,7 +117,7 @@ public class WxProductPublishState
public List<dynamic> AddPriceRules { get; set; } = new();
public dynamic WxUploadRule { get; set; }
public string PddProductCates { get; set; }
public dynamic UploadDraftProductList { get; set; }
public List<WxProductPublishTask> UploadDraftProductList { get; set; } = new();
}
/// <summary>
@@ -260,4 +277,4 @@ public class WxControlState
Text = numericUpDown?.Text ?? ""
};
}
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ public class PublishContextBase
/// <summary>
/// 商铺
/// </summary>
public ShopBase Shop { get; set; }
public Shop Shop { get; set; }
/// <summary>
/// 商铺名称
/// </summary>
@@ -28,8 +28,11 @@ public class WXPublishParameters: PublishParameters
public bool IsCompleted { get; set; }
/// <summary>候补:当前上传店铺。</summary>
public ShopLoginInfo Shop { get; set; }
/// <summary>候补:当前选品商品。</summary>
public TemuDBProductSelect SelectProduct { get; set; }
/// <summary>
/// 上传任务对象。仅在上传完成后回写状态、草稿 ID 等任务信息,
/// 不参与商品标题、裂变、SKU、图片等商品内容构造。
/// </summary>
public WxProductPublishTask Task { get; set; } = new WxProductPublishTask();
/// <summary>候补:本次上传开始时间。</summary>
public DateTime StartTime { get; set; } = DateTime.Now;
/// <summary>候补:实际提交的佣金比例。</summary>
@@ -121,7 +124,7 @@ public class WXPublishParameters: PublishParameters
/// <summary>候补:资质图片列表。</summary>
public List<wx_qualification_image_info> QualificationImages { get; set; } = new List<wx_qualification_image_info>();
/// <summary>候补:待上传草稿商品列表。</summary>
public dynamic UploadDraftProductList { get; set; }
public List<WxProductPublishTask> UploadDraftProductList { get; set; } = new List<WxProductPublishTask>();
/// <summary>
/// 预售天数(页面限制为 3-45 天)。
/// </summary>
@@ -34,7 +34,7 @@ public sealed class AddRandomImageBorderStep : WxProductPublishStepBase
protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken)
{
if (context.Parameters.SelectProduct.is_fission_title && context.Parameters.IsRandomImageBorder)
if (context.Parameters.IsFissionTitle && context.Parameters.IsRandomImageBorder)
{
// selectProd.isFission
int mainCount = 9;
@@ -99,7 +99,7 @@ public sealed class BuildSkuInfoStep : WxProductPublishStepBase
// 聚水潭上微信小店,加运费(其他平台shipPrice默认为0)
skuParam.productSkuInfo.salePrice += (context.Parameters.ShipPrice * context.Parameters.DefaultAddPriceRule.ShippingPriceTimes).ParseToInt();
// 商品裂变随机增加价格
if (context.Parameters.SelectProduct.is_fission_title && context.Parameters.IsFissionRandomPriceChange)
if (context.Parameters.IsFissionTitle && context.Parameters.IsFissionRandomPriceChange)
{
Invoke(new Action(() =>
{
@@ -43,11 +43,11 @@ public sealed class FissionTitleStep : WxProductPublishStepBase
{
throw new Exception("裂变标题数量不足,将暂停上传");
}
context.Parameters.SelectProduct.product_name = titles[0];
context.Parameters.SelectProduct.is_fission_title = true;
context.Product.Title = titles[0];
context.Parameters.IsFissionTitle = true;
titles.RemoveAt(0);
context.Parameters.FissionTitles = string.Join("\r\n", titles);
context.Progress.Report("标题裂变成功,更改为:" + context.Parameters.SelectProduct.product_name);
context.Progress.Report("标题裂变成功,更改为:" + context.Product.Title);
return Task.CompletedTask;
}
@@ -48,8 +48,6 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase
{
if (context.Parameters.IsSkipHasFilterWordsProd)
{
if (lstTitleReplaceText.Any(t => context.Parameters.SelectProduct.product_name.Contains(t)))
throw new Exception("命中敏感词");
if (lstTitleReplaceText.Any(t => context.Product.Title.Contains(t)))
throw new Exception("命中敏感词");
var goods_name = context.Parameters.ProdJObject["detail"]["goods_name"].ParseToString();
@@ -70,7 +68,6 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase
foreach (var txt in lstTitleReplaceText)
{
context.Product.Title = context.Product.Title.Replace(txt, "");
context.Parameters.SelectProduct.product_name = context.Parameters.SelectProduct.product_name.Replace(txt, "");
}
var goods_name = context.Parameters.ProdJObject["detail"]["goods_name"].ParseToString();
@@ -111,9 +108,6 @@ public sealed class InitializeProductDataStep : WxProductPublishStepBase
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 (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 = context.Parameters.ProdJObject["detail"]["goods_name"].ParseToString();
if (goods_name.Contains(ch) && goods_name.IndexOf(ch) < goods_name.Length / 2 && goods_name.Length > 10)
context.Parameters.ProdJObject["detail"]["goods_name"] = goods_name.Substring(goods_name.IndexOf(ch)).Trim(ch);
@@ -21,6 +21,13 @@
6. `WxShopTokenInfoList` 当前在入口处做了列表快照;若步骤内需要直接回写窗体静态列表,需要改为共享集合或增加回调。
7. `SubmitProductStep` 中的 `DataGridViewRow` 统计逻辑仍直接依赖表格控件,后续建议迁到运行时回调。
## 新上传参数边界
- 商品内容在进入步骤流水线前完成组合,步骤内统一使用 `WXPublishContext.Product`,其类型为继承 `ProductBase` 的 `WxProductUploadProduct`。
- 最终提交参数只在 `WXPublishParameters.ProductParameter` 上继续修改。
- 裂变状态使用 `WXPublishParameters.IsFissionTitle`,不再从 `TemuDBProductSelect` 读取。
- 上传任务结果使用 `WxProductPublishTask`,只保存状态、草稿 ID 和草稿参数,不参与商品内容判断。
## 步骤顺序
步骤顺序由 `WxProductPublishPipelineFactory.CreateDefault()` 统一维护,和原 `UploadProduct` 从上到下的执行顺序一致。
步骤顺序由 `WxProductPublishPipelineFactory.CreateDefault()` 统一维护,和原 `UploadProduct` 从上到下的执行顺序一致。
@@ -34,9 +34,8 @@ public sealed class SetProductTitleStep : WxProductPublishStepBase
protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken)
{
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;
context.Product.Title = context.Parameters.ProdInfo.detail.goods_name;
context.Parameters.InitParameter.product.info.title = context.Product.Title;
context.Parameters.ProductParameter.product.info.title = context.Product.Title;
@@ -46,7 +46,7 @@ public sealed class SkipUploadedProductStep : WxProductPublishStepBase
protected override Task ExecuteProvider(WXPublishContext context, CancellationToken cancellationToken)
{
// 裂变按标题名称
if (context.Parameters.SelectProduct.is_fission_title)
if (context.Parameters.IsFissionTitle)
{
HttpResult result = WXApi.searchProductWithTitle(context.Shop.Cookie, GetHtml.UrlEncodeUtf8(context.Product.Title));
string searchRst = result.Html;
@@ -50,11 +50,12 @@ public sealed class SubmitProductStep : WxProductPublishStepBase
if (context.Parameters.UpDraft)
{
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);
// Task 仅用于回写上传任务状态,最终商品数据只来自 ProductParameter。
context.Parameters.Task.wxDraftProduct = context.Parameters.ProductParameter;
context.Parameters.Task.draft_id = context.Parameters.ProductParameter.product.productKey.productId;
context.Parameters.Task.status = "草稿箱";
context.Parameters.Task.add_time = DateTime.Now;
context.Parameters.UploadDraftProductList.Add(context.Parameters.Task);
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_select_upload_draft_products", context.Parameters.UploadDraftProductList);
StopWithResult("{\"success\":true,\"draftId\":" + context.Parameters.ProductParameter.product.productKey.productId + ",\"status\":\"草稿箱\",\"errMsg\":\"指定上传到草稿箱" + context.Parameters.CommissionRstStr + "\"}");
@@ -3,10 +3,31 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Store.Product.Models.Product;
namespace Store.Product.Publish.Steps.Wx;
public class WXPublishContext : PublishContextBase
{
private WxProductUploadProduct _product = new WxProductUploadProduct();
/// <summary>
/// 微信商品上传模型
/// </summary>
public new WxProductUploadProduct Product
{
get => _product;
set
{
_product = value ?? new WxProductUploadProduct();
base.Product = _product;
}
}
public WXPublishContext()
{
base.Product = _product;
}
public IProgress<string> Progress { get; set; }
}