using AllBase; using AllBase.Helper; using AllBase.Model.Result; using NaiBa.Util.Extension; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using TemuKJD.Extension; using TemuKJD.BaseForms; using TemuKJD.ToolForms; using Work; using TemuKJD.BLL; using System.Text.RegularExpressions; using TemuKJD.PDDForms.ProductSelectForms; using TemuKJD.WXForms.ShopForms; using AllBase.Model.Result.PDDResult; using AllBase.Model.Param.WXParam; using AllBase.Model.Result.WXResult; using Newtonsoft.Json; using NaiBa.Util; using AllBase.Model.Config; namespace TemuKJD.WXForms.ProductForms { public partial class WXDBProdUploadForm : BaseForm { public CancellationTokenSource cancellationTokenSource { get; set; } = null; public bool IsLoadComplate { get; set; } = false; bool isInit = false; CheckBox chkSelectAll = null; Dictionary dicShopGetCount = new Dictionary(); Dictionary> dicNotSupportCate = new Dictionary>(); public NaiBa.Util.ConcurrentList lstTemuDBProductSelect = new NaiBa.Util.ConcurrentList(); NaiBa.Util.ConcurrentList lstAddPriceRule = new NaiBa.Util.ConcurrentList(); AddPriceRule defaultAddPriceRule = null; WXUploadRule wxUploadRule = null; //public Dictionary> dicCheckedShopIdList = new Dictionary>(); public Dictionary dicCheckedShopId = new Dictionary(); public Dictionary dicShopUpload = new Dictionary(); public WXDBProdUploadForm() { InitializeComponent(); } private void UserSelectDbProductForm_Load(object sender, EventArgs e) { cmbSpProdType.SelectedIndex = 0; this.splitContainer1.Dock = DockStyle.Fill; this.panel1.Location = new Point(40, 30); this.panel1.Width = this.Width - 80; this.panel1.Height = this.Height - 60; this.panel1.SendToBack(); cmbWxSafe.SelectedIndex = 0; lstTemuDBProductSelect = NaiBa.Util.Helper.ConfigHelper.LoadConfig>("wx_db_prod_upload_list"); if (lstTemuDBProductSelect == null) lstTemuDBProductSelect = new NaiBa.Util.ConcurrentList(); lstAddPriceRule = NaiBa.Util.Helper.ConfigHelper.LoadConfig>("wx_add_price_rules"); if (lstAddPriceRule == null) { lstAddPriceRule = new NaiBa.Util.ConcurrentList(); lstAddPriceRule.Add(new AddPriceRule() { MoreThanPrice = 0, LessThanPrice = 10, AddPriceTimes = 2, AddMorePrice = 5, SinglePriceAdd = 1 }); lstAddPriceRule.Add(new AddPriceRule() { MoreThanPrice = 10, LessThanPrice = 20, AddPriceTimes = 2, AddMorePrice = 5, SinglePriceAdd = 1 }); lstAddPriceRule.Add(new AddPriceRule() { MoreThanPrice = 20, LessThanPrice = 999, AddPriceTimes = 2, AddMorePrice = 5, SinglePriceAdd = 1 }); } this.fPnlPriceRule.Controls.Clear(); foreach (var priceItem in lstAddPriceRule) { var ucPrice = new UcAddPrice() { PriceEnd = priceItem.LessThanPrice, PriceStart = priceItem.MoreThanPrice, PriceAddTimes = priceItem.AddPriceTimes, PriceAddMore = priceItem.AddMorePrice, SinglePriceAdd = priceItem.SinglePriceAdd, }; ucPrice.lblSinglePriceAdd.Visible = false; ucPrice.txtSinglePriceAdd.Visible = false; if (IsSetFontScaleNone) { Font of = ucPrice.Font; Font nf = new Font(of.FontFamily, (of.Size * 96.0 / FormDpi).ParseToFloat(), of.Style, of.Unit, of.GdiCharSet, of.Bold); ucPrice.Font = nf; } this.fPnlPriceRule.Controls.Add(ucPrice); ucPrice.PriceChange += ucAddPrice_PriceChange; } dicCheckedShopId = NaiBa.Util.Helper.ConfigHelper.LoadConfig>("wx_checked_shop_dic"); if (dicCheckedShopId == null) dicCheckedShopId = new Dictionary(); dicShopUpload = NaiBa.Util.Helper.ConfigHelper.LoadConfig>("wx_shop_upload_info"); if (dicShopUpload == null) dicShopUpload = new Dictionary(); defaultAddPriceRule = NaiBa.Util.Helper.ConfigHelper.LoadConfig("wx_default_add_price_rule"); if (defaultAddPriceRule == null) { defaultAddPriceRule = new AddPriceRule() { AddPriceTimes = 1.3m, AddMorePrice = 1, SinglePriceAdd = 1 }; } txtAddTimes.TextChanged -= txtAddPrice_TextChanged; txtAddMorePrice.TextChanged -= txtAddPrice_TextChanged; txtSinglePriceAdd.TextChanged -= txtAddPrice_TextChanged; txtStockNum.TextChanged -= txtAddPrice_TextChanged; chkAddMorePriceFirst.CheckedChanged -= chkAddMorePriceFirst_CheckedChanged; chkStepAddPrice.CheckedChanged -= chkStepAddPrice_CheckedChanged; this.txtAddTimes.Text = defaultAddPriceRule.AddPriceTimes.ToString(); this.txtAddMorePrice.Text = defaultAddPriceRule.AddMorePrice.ToString(); this.txtSinglePriceAdd.Text = defaultAddPriceRule.SinglePriceAdd.ToString(); this.txtStockNum.Text = defaultAddPriceRule.StockNum.ToString(); this.chkAddMorePriceFirst.Checked = defaultAddPriceRule.AddMorePriceFirst; this.chkStepAddPrice.Checked = defaultAddPriceRule.IsStepAddPrice; txtAddTimes.TextChanged += txtAddPrice_TextChanged; txtAddMorePrice.TextChanged += txtAddPrice_TextChanged; txtSinglePriceAdd.TextChanged += txtAddPrice_TextChanged; txtStockNum.TextChanged += txtAddPrice_TextChanged; chkAddMorePriceFirst.CheckedChanged += chkAddMorePriceFirst_CheckedChanged; chkStepAddPrice.CheckedChanged += chkStepAddPrice_CheckedChanged; wxUploadRule = NaiBa.Util.Helper.ConfigHelper.LoadConfig("wx_upload_rule"); if (wxUploadRule == null) wxUploadRule = new WXUploadRule(); this.txtPreDays.TextChanged -= txtPreDays_TextChanged; this.txtReplaceText.TextChanged -= txtReplaceText_TextChanged; this.txtMinPrice.TextChanged -= txtMinPrice_TextChanged; this.txtWaitSeconds.TextChanged -= txtWaitSeconds_TextChanged; this.chkHighestPriceSku.CheckedChanged -= chkHighestPriceSku_CheckedChanged; this.chkSameSpecPrice.CheckedChanged -= chkSameSpecPrice_CheckedChanged; this.chkSkipUploaded.CheckedChanged -= chkSkipUploaded_CheckedChanged; this.chkUpDraft.CheckedChanged -= chkUpDraft_CheckedChanged; this.chkPreSale.CheckedChanged -= chkPreSale_CheckedChanged; this.txtPreDays.Text = wxUploadRule.PreSaleDays.ParseToString(); this.txtReplaceText.Text = wxUploadRule.FilterWords.ParseToString(); this.txtMinPrice.Text = wxUploadRule.SkuMinPrice.ParseToString(); this.txtWaitSeconds.Text = wxUploadRule.WaitSeconds.ParseToString(); this.chkHighestPriceSku.Checked = wxUploadRule.OnlyHighestPriceSku.ParseToBool(); this.chkSameSpecPrice.Checked = wxUploadRule.SameSpecSamePrice.ParseToBool(); this.chkSkipUploaded.Checked = wxUploadRule.SkipUploaded.ParseToBool(); this.chkUpDraft.Checked = wxUploadRule.UpDraft.ParseToBool(); this.chkPreSale.Checked = wxUploadRule.IsPreSale.ParseToBool(); this.txtPreDays.TextChanged += txtPreDays_TextChanged; this.txtReplaceText.TextChanged += txtReplaceText_TextChanged; this.txtMinPrice.TextChanged += txtMinPrice_TextChanged; this.txtWaitSeconds.TextChanged += txtWaitSeconds_TextChanged; this.chkHighestPriceSku.CheckedChanged += chkHighestPriceSku_CheckedChanged; this.chkSameSpecPrice.CheckedChanged += chkSameSpecPrice_CheckedChanged; this.chkSkipUploaded.CheckedChanged += chkSkipUploaded_CheckedChanged; this.chkUpDraft.CheckedChanged += chkUpDraft_CheckedChanged; this.chkPreSale.CheckedChanged += chkPreSale_CheckedChanged; this.lblWaitToUp.Text = "待上传 " + lstTemuDBProductSelect.Count + " 件"; int prodCount = 0; var list = GetRandomProductList(out prodCount, 1, 1); lblGoodsCount.Text = "产品库 " + prodCount + " 件"; this.panel1.SendToBack(); chkSelectAll = dgvShop.Columns["colSelect"].AddHeaderCheckBox(HorizontalAlignment.Center, 0, 0, null, null, false); dgvShop.Columns["colSelect"].HeaderText = ""; //chkSelectAll.Width = chkSelectAll.Height = 13; chkSelectAll.CheckedChanged += chkSelectAll_CheckedChanged; //chkSelectAll.Checked = true; this.dgvSelectProduct.AddSelectorColumn("colCheck"); dgvSelectProduct.AddImgColumn("colProductSkcPic", "colImgUrl"); dgvSelectProduct.AddImgColumn("colSkuFakeImg", "colSkuFakeImgUrl"); dgvSelectProduct.Columns["colSkuFakeImg"].Visible = false; // if (BaseClass.SaLevel == 1) // { // dgvSelectProduct.Columns["colSkuFakeImg"].Visible = true; // } //#if DEBUG // dgvSelectProduct.Columns["colSkuFakeImg"].Visible = true; //#endif upload_draft_product_lst = NaiBa.Util.Helper.ConfigHelper.LoadConfig>("wx_select_upload_draft_products"); if (upload_draft_product_lst == null) upload_draft_product_lst = new ConcurrentList(); foreach (var selectProd in upload_draft_product_lst) { int rowIndex = 0; this.dgvSelectProduct.Rows.Insert(rowIndex, true, selectProd.id, selectProd.shop_id, selectProd.shop_account, "登录", "进店", selectProd.spu_id, selectProd.skc_id, selectProd.main_img, null, "", null, selectProd.product_name, // 用户端显示商品原名 selectProd.cat_name, selectProd.ext_code, selectProd.status, selectProd.draft_id, selectProd.notes, (selectProd.user_notes + " 编辑").Trim(), "删除", selectProd.add_time.ToString("yy-MM-dd HH:mm:ss"), ""); dgvSelectProduct.Rows[rowIndex].Height = 60; int maxRowCount = 10000; while (dgvSelectProduct.Rows.Count > maxRowCount) { dgvSelectProduct.Rows.RemoveAt(maxRowCount); } } IsLoadComplate = true; } private void chkSelectAll_CheckedChanged(object sender, EventArgs e) { if (!chkSelectAll.Checked) { foreach (DataGridViewRow row in dgvShop.Rows) { row.Cells["colSelect"].Value = false; } } else { //var list = GlobalConfig.ShopLoginList.Where(s => s.LoginStatus == "登录成功").Select(ss => ss.ShopId); foreach (DataGridViewRow row in dgvShop.Rows) { //if (list.Any(l => l == row.Cells["colShopId"]?.Value?.ToString())) row.Cells["colSelect"].Value = true; } } foreach (var r in dgvShop.Rows.Cast()) { dicCheckedShopId[r.Cells["colShopId"].Value.ParseToString()] = r.Cells["colSelect"].Value.ParseToBool(); } NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_checked_shop_dic", dicCheckedShopId); } private void btnRefreshShop_Click(object sender, EventArgs e) { pbLoadingShop.Visible = true; RefreshDbProd(); RefreshShop(); } private void UserSelectDbProductForm_VisibleChanged(object sender, EventArgs e) { if (Visible == true) { RefreshShop(); RefreshDbProd(); if (!isInit) { Task.Run(() => { foreach (var shop in GlobalConfig.ShopLoginList) { //if (shop.LoginStatus == "登录成功") //{ // var rst = WXUpload.scanProductPreview(shop); // if (!rst.Contains("\"code\":0") && !rst.Contains("\"success\":true")) // { // WXShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false); // } //} } }); } isInit = true; } } private void RefreshDbProd() { Task.Run(() => { PDDDBProdListForm.GetPDDProductGroup(cmbGroupFilter); // 同时刷新下商品分组 GetPddProductCate(); Invoke(new Action(() => { pbLoadingShop.Visible = false; })); }); } /// /// 获取商品所有类目 /// void GetPddProductCate() { var url = BaseClass.BuildObjString("product/get_pdd_product_cates"); 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")) { //BaseMsgForm.ShowError("商品分组获取失败,请重试!" + BaseRegex.GetStringJson(ref html, "msg")); } else { Invoke(new Action(() => { cmbCateFilter.Items.Clear(); var groups = BaseRegex.GetStringJson(ref html, "data"); foreach (var item in groups.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { cmbCateFilter.Items.Add(item); } cmbCateFilter.Items.Add(""); })); } } private void RefreshShop() { // 店铺Id var selectIds = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); // 获取被删除的店铺 List dgvRowList = dgvShop.Rows.Cast().Where(row => !GlobalConfig.ShopLoginList.Any(s => s.ShopId == row.Cells["colShopId"]?.Value?.ToString())).ToList(); // 更新被删除的店铺列表 foreach (var row in dgvRowList) { dgvShop.Rows.Remove(row); } // 绑定其他店铺(含新导入的店铺) foreach (ShopLoginInfo shopEntity in GlobalConfig.ShopLoginList) { if (!string.IsNullOrEmpty(shopEntity.ShopId)) BindShop(shopEntity, selectIds); } } private void BindShop(ShopLoginInfo shopEntity, List selectShopId = null) { if (shopEntity == null) return; if (selectShopId == null) selectShopId = new List(); bool canUse = shopEntity.LoginStatus == "登录成功"; //canUse = true; // 内部库不需要校验登录状态 var row = dgvShop.Rows.Cast().FirstOrDefault(p => p.Cells.GetCellValueFromColumnName("colShopId").ParseToString() == shopEntity.ShopId); var day = DateTime.Now.ToString("yyyyMMdd").ParseToInt(); if (row == null) { this.dgvShop.Rows.Add( //!isInit || (selectShopId.Contains(shopEntity.ShopId) && canUse), dicCheckedShopId.Keys.Contains(shopEntity.ShopId) && dicCheckedShopId[shopEntity.ShopId] == true, shopEntity.LoginName, shopEntity.ShopId, shopEntity.ShopAccount, shopEntity.Notes, "选择商品", canUse ? "在线" : "掉线", canUse, dicShopUpload.ContainsKey(shopEntity.ShopId) && dicShopUpload[shopEntity.ShopId].DicDayUploadCount.ContainsKey(day) ? dicShopUpload[shopEntity.ShopId].DicDayUploadCount[day] : 0, dicShopUpload.ContainsKey(shopEntity.ShopId) && dicShopUpload[shopEntity.ShopId].OnSaleRefreshDay == DateTime.Now.ToString("yyyyMMdd").ParseToInt() ? dicShopUpload[shopEntity.ShopId].OnSaleCount : 0, shopEntity.AddProductRemaining, string.Empty ); } else { row.Cells["colSelect"].Value = !isInit || (selectShopId.Contains(shopEntity.ShopId) && canUse); row.Cells["colShopLoginName"].Value = shopEntity.LoginName; row.Cells["colShopName"].Value = shopEntity.ShopAccount; row.Cells["colShopNotes"].Value = shopEntity.Notes; row.Cells["colLoginStatus"].Value = canUse ? "在线" : "掉线"; row.Cells["colLoginStatus"].Style.ForeColor = canUse ? Color.Green : Color.Red; row.Cells["colCanUse"].Value = canUse; row.Cells["colRemaining"].Value = shopEntity.AddProductRemaining; row.Cells["colUploadCount"].Value = dicShopUpload.ContainsKey(shopEntity.ShopId) && dicShopUpload[shopEntity.ShopId].DicDayUploadCount.ContainsKey(day) ? dicShopUpload[shopEntity.ShopId].DicDayUploadCount[day] : 0; row.Cells["colOnSaleNum"].Value = dicShopUpload.ContainsKey(shopEntity.ShopId) && dicShopUpload[shopEntity.ShopId].OnSaleRefreshDay == DateTime.Now.ToString("yyyyMMdd").ParseToInt() ? dicShopUpload[shopEntity.ShopId].OnSaleCount : 0; } } private void dgvShop_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (e.ColumnIndex < 0 || e.RowIndex < 0) return; string headerText = dgvShop.Columns[e.ColumnIndex].HeaderText; string columnName = dgvShop.Columns[e.ColumnIndex].Name; string shopId = dgvShop.Rows[e.RowIndex].Cells["colShopId"].Value.ParseToString(); string shopAccount = dgvShop.Rows[e.RowIndex].Cells["colShopName"].Value.ToString(); var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == shopId.ToString()); var row = dgvShop.Rows[e.RowIndex]; switch (columnName) { case "colSelect": //if (row.Cells["colCanUse"].Value.ParseToBool()) { row.Cells["colSelect"].Value = !row.Cells["colSelect"].Value.ParseToBool(); chkSelectAll.CheckedChanged -= chkSelectAll_CheckedChanged; if (dgvShop.Rows.Cast().All(r => r.Cells["colSelect"].Value.ParseToBool())) chkSelectAll.Checked = true; else chkSelectAll.Checked = false; chkSelectAll.CheckedChanged += chkSelectAll_CheckedChanged; } //else { //BaseMsgForm.ShowInfo("店铺未登录!"); } dicCheckedShopId[row.Cells["colShopId"].Value.ParseToString()] = row.Cells["colSelect"].Value.ParseToBool(); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_checked_shop_dic", dicCheckedShopId); break; case "colLoginStatus": if (WXShopListForm.Instance == null) WXShopListForm.Instance = new WXShopListForm(); WXShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false); WXShopLoginForm shopLoginForm = new WXShopLoginForm(shop); //shopLoginForm.prodUserSelectForm = this; if (shop.LoginStatus != "登录成功") { shopLoginForm.openType = EnumOpenType.login; shopLoginForm.ShowDialog(); RefreshShop(); } else { shopLoginForm.openType = EnumOpenType.manage; shopLoginForm.WindowState = FormWindowState.Maximized; shopLoginForm.Show(); } break; } } private void btnSearch_Click(object sender, EventArgs e) { var lstShopId = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); if (lstShopId.Count == 0) { BaseMsgForm.ShowInfo("请选择店铺!"); return; } } private void dgvSelectProduct_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (e.ColumnIndex < 0 || e.RowIndex < 0) return; string headerText = dgvSelectProduct.Columns[e.ColumnIndex].HeaderText; var dbId = dgvSelectProduct.Rows[e.RowIndex].Cells["colSelectId"].Value.ParseToString(); var dbProduct = lstTemuDBProductSelect.FirstOrDefault(p => p.id.ToString() == dbId); var shopId = dgvSelectProduct.Rows[e.RowIndex].Cells["colSupplierId"].Value.ParseToString(); var draftId = dgvSelectProduct.Rows[e.RowIndex].Cells["colDraftId"].Value.ParseToString(); var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == shopId); switch (headerText) { case "删除": break; case "登录": { WXShopLoginForm shopLoginForm = new WXShopLoginForm(shop); //shopLoginForm.prodUserSelectForm = this; shopLoginForm.openType = EnumOpenType.login; shopLoginForm.ShowDialog(); RefreshShop(); } break; case "进店": { WXShopLoginForm shopLoginForm = new WXShopLoginForm(shop); //shopLoginForm.prodUserSelectForm = this; shopLoginForm.openType = EnumOpenType.manage; shopLoginForm.WindowState = FormWindowState.Maximized; shopLoginForm.InitUrl = "https://store.weixin.qq.com/shop/home"; shopLoginForm.Show(); } break; case "上传商品Id": //if (!string.IsNullOrEmpty(draftId) && shop != null) //{ // ShopLoginForm shopLoginForm = new ShopLoginForm(shop); // shopLoginForm.InitUrl = "https://seller.kuajingmaihuo.com/goods/product-create/product-edit?productDraftId=" + // draftId + "&from=productDraftList"; // shopLoginForm.openType = EnumOpenType.manage; // shopLoginForm.WindowState = FormWindowState.Maximized; // shopLoginForm.ShowDialog(); //} break; case "图片": { ShowImgForm imgFrom = new ShowImgForm(dgvSelectProduct.Rows[e.RowIndex].Cells["colImgUrl"].Value.ParseToString()); imgFrom.ShowDialog(); break; } case "SKU替换图": { ShowImgForm imgFrom = new ShowImgForm(dgvSelectProduct.Rows[e.RowIndex].Cells["colSkuFakeImgUrl"].Value.ParseToString()); imgFrom.ShowDialog(); break; } case "": dgvSelectProduct.Rows[e.RowIndex].Cells["colCheck"].Value = !(bool)dgvSelectProduct.Rows[e.RowIndex].Cells["colCheck"].Value; break; default: break; } } private void btnUpload_Click(object sender, EventArgs e) { var shopIdLst = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); if (shopIdLst.Count <= 0) { BaseMsgForm.ShowError("未勾选上传店铺!"); return; } if (lstTemuDBProductSelect.Count() > 0) { if (WXShopLoginForm.shopLoginInstance != null && WXShopLoginForm.shopLoginInstance.IsDisposed != true) WXShopLoginForm.shopLoginInstance.Dispose(); this.btnUpload.Enabled = false; cancellationTokenSource = new CancellationTokenSource(); Task.Run(() => { AddProductArr(shopIdLst); Invoke(new Action(() => { this.btnUpload.Enabled = true; })); }, cancellationTokenSource.Token); } else { BaseMsgForm.ShowError("请选择要上传的商品!"); } } void AddProductArr(List shopIdLst) { Invoke(new Action(() => { this.pbLoading.Visible = true; this.statusBar.lblTaskStatus.Text = "正在上传" + "...".Substring(0, DateTime.Now.Second % 4); this.statusBar.pgbTaskProgress.Maximum = lstTemuDBProductSelect.Count; this.statusBar.UpdateProgressBar(0); })); NaiBa.Util.ConcurrentList currentShopList = new NaiBa.Util.ConcurrentList(); while (lstTemuDBProductSelect.Count > 0) { if (cancellationTokenSource.IsCancellationRequested) break; Invoke(new Action(() => { shopIdLst = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); })); while (shopIdLst.Count <= 0) { Invoke(new Action(() => { this.statusBar.lblTaskStatus.Text = "请至少勾选一个店铺"; shopIdLst = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); })); Thread.Sleep(1000); if (cancellationTokenSource.IsCancellationRequested) break; } var randomShopLst = new NaiBa.Util.ConcurrentList(); randomShopLst.AddRange(GlobalConfig.ShopLoginList.Where(s => shopIdLst.Contains(s.ShopId) && s.LoginStatus == "登录成功")); while (randomShopLst.Count <= 0) { Thread.Sleep(1000); Invoke(new Action(() => { shopIdLst = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); })); Invoke(new Action(() => { this.statusBar.lblTaskStatus.Text = "所有店铺都已掉线,请登录店铺"; randomShopLst.Clear(); randomShopLst.AddRange(GlobalConfig.ShopLoginList.Where(s => shopIdLst.Contains(s.ShopId) && s.LoginStatus == "登录成功")); })); if (cancellationTokenSource.IsCancellationRequested) break; } if (cancellationTokenSource.IsCancellationRequested) break; while (currentShopList.Count >= 5) // 最多5店同传 { Thread.Sleep(100); } if (cancellationTokenSource.IsCancellationRequested) break; var randomShop = randomShopLst[Randomx.GetId(randomShopLst.Count)]; while (currentShopList.Any(s => s.ShopId == randomShop.ShopId)) { Thread.Sleep(500); var randomShopTmpLst = randomShopLst.Where(s => !currentShopList.Contains(s)).ToList(); if (randomShopTmpLst.Count == 0) continue; randomShop = randomShopTmpLst[Randomx.GetId(randomShopTmpLst.Count)]; } currentShopList.Add(randomShop); if (cancellationTokenSource.IsCancellationRequested) break; // 商品已全部上传,退出 if (lstTemuDBProductSelect.Count <= 0) { currentShopList.Remove(randomShop); break; } var selectProd = lstTemuDBProductSelect[0]; if (randomShop != null) { selectProd.shop_id = randomShop.ShopId; selectProd.shop_account = randomShop.ShopAccount = randomShop.ShopAccount; } else { currentShopList.Remove(randomShop); continue; } if (cancellationTokenSource.IsCancellationRequested) break; lstTemuDBProductSelect.RemoveAt(0); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_db_prod_upload_list", this.lstTemuDBProductSelect); Invoke(new Action(() => { lblWaitToUp.Text = "待上传 " + lstTemuDBProductSelect.Count + " 件"; })); Invoke(new Action(() => { this.statusBar.lblTaskStatus.Text = "正在上传" + "...".Substring(0, DateTime.Now.Second % 4); this.statusBar.pgbTaskProgress.Maximum = lstTemuDBProductSelect.Count + this.statusBar.pgbTaskProgress.Value + 1; this.statusBar.UpdateProgressBar(this.statusBar.pgbTaskProgress.Value + 1); })); if (selectProd == null) { Invoke(new Action(() => { BaseMsgForm.ShowError("商品为空,将为您跳过该商品!"); })); currentShopList.Remove(randomShop); continue; } // 过滤标题 var lstTitleReplaceText = new List(); lstTitleReplaceText.Clear(); if (!txtReplaceText.Text.Trim().IsNullOrEmpty()) lstTitleReplaceText.AddRange(txtReplaceText.Text.Trim().Split(new string[] { ",", ",", " " }, StringSplitOptions.RemoveEmptyEntries)); // 过滤标题内指定词语 if (lstTitleReplaceText.Count > 0) { foreach (var txt in lstTitleReplaceText) { selectProd.product_name = selectProd.product_name.Replace(txt, ""); } } Invoke(new Action(() => { int rowIndex = 0; this.dgvSelectProduct.Rows.Insert(rowIndex, true, selectProd.id, selectProd.shop_id, selectProd.shop_account, "登录", "进店", selectProd.spu_id, selectProd.skc_id, selectProd.main_img, null, "", null, selectProd.product_name, // 用户端显示商品原名 selectProd.cat_name, selectProd.ext_code, selectProd.status, selectProd.draft_id, selectProd.notes, (selectProd.user_notes + " 编辑").Trim(), "删除", "", ""); dgvSelectProduct.Rows[rowIndex].Height = 60; int maxRowCount = 10000; while (dgvSelectProduct.Rows.Count > maxRowCount) { dgvSelectProduct.Rows.RemoveAt(maxRowCount); } })); Invoke(new Action(() => { this.pbLoading.Visible = false; })); Task.Run(() => { DateTime startTime = DateTime.Now; for (int j = 0; j < 1; j++) { var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == selectProd.shop_id); if (shop == null) continue; var row = dgvSelectProduct.Rows.Cast().FirstOrDefault(r => r.Cells["colSelectId"]?.Value.ToString() == selectProd.id.ToString()); double duration = 0; if (row == null) { Invoke(new Action(() => { BaseMsgForm.ShowError("商品已被清除,将为您跳过该商品!"); })); continue; } KJDDBProduct kjdDbProd = selectProd.kjdDbProduct; if (kjdDbProd == null) kjdDbProd = GetProductDetail(selectProd.out_product_Id.ToString()); if (kjdDbProd == null || kjdDbProd.id == 0) { if (kjdDbProd?.id == 0) { selectProd.status = "已清除"; } Invoke(new Action(() => { if (row.Index >= 0) { row.Cells["colOpResult"].Value = "选品数据库商品已被清除"; if (kjdDbProd?.id == 0) row.Cells["colStatus"].Value = "已清除"; } })); continue; } var result = ""; try { WXShopListForm.Instance.CheckShopLogin(new ShopLoginInfo[] { shop }, false); if (shop.LoginStatus != "登录成功") { Invoke(new Action(() => { if (row.Index >= 0) { row.Cells["colOpResult"].Value = "店铺掉线"; } })); continue; } if (cancellationTokenSource.IsCancellationRequested) break; //将商品上传 result = UploadProduct(shop, kjdDbProd, selectProd, row.Cells["colOpResult"], startTime); Invoke(new Action(() => { row.Cells["colSkuFakeImgUrl"].Value = kjdDbProd.sku_img_replace_url; if (row.Displayed) { string getImgError = ""; Image img = GetHtml.GetUrlImg(kjdDbProd.sku_img_replace_url.Replace("https://", "http://"), out getImgError); if (string.IsNullOrEmpty(getImgError)) row.Cells["colSkuFakeImg"].Value = img; } })); if (!result.Contains("success")) { WXShopListForm.Instance.CheckShopLogin(new ShopLoginInfo[] { shop }, false); } } catch (Exception ex) { result = "{\"success\":false,\"status\":\"未上传\",\"errMsg\":\"" + ex.Message + "\"}"; } Thread.Sleep(Randomx.GetId(200, 300)); //额外等待时间(无论失败与否) var waitTime = 0; Invoke(new Action(() => { waitTime = txtWaitSeconds.Text.Trim().ParseToInt(); })); if (waitTime > 0) Thread.Sleep(Randomx.GetId(waitTime * 1000, (waitTime + 10) * 1000)); selectProd.status = BaseRegex.GetStringJson(ref result, "status"); if (string.IsNullOrWhiteSpace(selectProd.status)) selectProd.status = "待上传"; var productDraftId = BaseRegex.GetStringJson(ref result, "draftId"); var timeSpan = DateTime.Now - startTime; duration = timeSpan.TotalSeconds; // 至少15秒才完成一件商品 while (duration < 15) { Thread.Sleep(1000); timeSpan = DateTime.Now - startTime; duration = timeSpan.TotalSeconds; } var error = BaseRegex.GetStringJson(ref result, "errMsg"); // 上传失败 if (!result.Contains("\"success\":true") && !result.Contains("上传成功")) { if (string.IsNullOrWhiteSpace(error)) error = result; Invoke(new Action(() => { if (row.Index >= 0) { row.Cells["colDraftId"].Value = productDraftId; // 草稿箱id row.Cells["colOpResult"].Value = error + " " + duration.ParseToInt() + "秒"; } })); } // 上传成功/上传到草稿箱 else { Invoke(new Action(() => { if (row.Index >= 0) { row.Cells["colDraftId"].Value = productDraftId; // 草稿箱id row.Cells["colAddTime"].Value = DateTime.Now.ToString("yy-MM-dd HH:mm:ss"); row.Cells["colOpResult"].Value = (selectProd.status == "已上传" ? "已成功上传" : "已上传 注意:") + (" " + error).TrimEnd(' ') + " " + duration.ParseToInt() + "秒"; row.Cells["colMsg"].Value = selectProd.status; } })); } } currentShopList.Remove(randomShop); }); } for (int i = 0; i < 300 && currentShopList.Count > 0; i++) { Thread.Sleep(1000); if (cancellationTokenSource.IsCancellationRequested) break; } Invoke(new Action(() => { if (cancellationTokenSource.IsCancellationRequested) BaseMsgForm.ShowInfo("上传停止!"); else BaseMsgForm.ShowInfo("上传完成!"); })); Invoke(new Action(() => { this.pbLoading.Visible = false; if (cancellationTokenSource.IsCancellationRequested) this.statusBar.lblTaskStatus.Text = "上传停止"; else this.statusBar.lblTaskStatus.Text = "上传完成"; //this.statusBar.UpdateProgressBar(lstTemuDBProductSelect.Count); })); } public static KJDDBProduct GetProductDetail(string prodDbId) { if (string.IsNullOrEmpty(prodDbId)) return new KJDDBProduct(); List list = new List(); var url = BaseClass.BuildObjString("product/get_pdd_product_detail_list"); var data = ""; data = UserLogin.GetSignaturex() + "&search_db_ids=" + prodDbId; 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")) { return null; } var jArr = JObject.Parse(html)["data"]; if (jArr.Count() == 0) return null; var sProd = JsonHelper.SerializeObject(jArr); try { list = JsonHelper.DeserializeJsonToList(sProd); var item = list.FirstOrDefault(); if (item == null) item = new KJDDBProduct(); return item; } catch (Exception ex) { return null; } } string UploadProduct(ShopLoginInfo shop, KJDDBProduct dbProd, TemuDBProductSelect selectProd, DataGridViewCell cell, DateTime startTime) { Thread.Sleep(Randomx.GetId(200, 300)); if (shop == null || string.IsNullOrEmpty(shop.ShopId) || shop.LoginStatus != "登录成功") { return "店铺为空或未登录!"; } if (cell != null) { Invoke(new Action(() => { cell.Value = "正在初始化上传"; })); } if (chkSkipUploaded.Checked) { var searchExtCode = "EC1" + dbProd.spu_id + "A"; var searchRst = WXUpload.searchProduct(shop, searchExtCode); if (!searchRst.Contains("\"code\":0") && !searchRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref searchRst, "msg"); if (string.IsNullOrEmpty(error)) error = searchRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"商品查询错误 " + error + "\"}"; } try { var num = JObject.Parse(searchRst)["totalNum"].ParseToInt(); if (num > 0) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"商品已存在,选择跳过\"}"; } } catch (Exception ex) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"商品查询错误 " + ex.Message + "\"}"; } } #region 将产品数据初始化成微信小店支持的参数 JObject prodJObj = new JObject(); try { prodJObj = JObject.Parse(dbProd.product_json); var lstTitleReplaceText = new List(); lstTitleReplaceText.Clear(); if (!txtReplaceText.Text.Trim().IsNullOrEmpty()) lstTitleReplaceText.AddRange(txtReplaceText.Text.Trim().Split(new string[] { ",", ",", " " }, StringSplitOptions.RemoveEmptyEntries)); // 过滤标题内指定词语 if (lstTitleReplaceText.Count > 0) { foreach (var txt in lstTitleReplaceText) { dbProd.product_name = dbProd.product_name.Replace(txt, ""); } var goods_name = prodJObj["detail"]["goods_name"].ParseToString(); foreach (var txt in lstTitleReplaceText) { goods_name = goods_name.Replace(txt, ""); } prodJObj["detail"]["goods_name"] = goods_name; var tiny_name = prodJObj["detail"]["tiny_name"].ParseToString(); foreach (var txt in lstTitleReplaceText) { tiny_name = tiny_name.Replace(txt, ""); } prodJObj["detail"]["tiny_name"] = tiny_name; var goods_desc = prodJObj["detail"]["goods_desc"].ParseToString(); foreach (var txt in lstTitleReplaceText) { goods_desc = goods_desc.Replace(txt, ""); } prodJObj["detail"]["goods_desc"] = goods_desc; var share_desc = prodJObj["detail"]["share_desc"].ParseToString(); foreach (var txt in lstTitleReplaceText) { share_desc = share_desc.Replace(txt, ""); } prodJObj["detail"]["share_desc"] = share_desc; } // 替换货号 if (!string.IsNullOrEmpty(dbProd.ext_code)) prodJObj["detail"]["out_goods_sn"] = dbProd.ext_code; // 替换编辑过的sku if (!string.IsNullOrEmpty(dbProd.sku_edit_json)) prodJObj["detail"]["sku"] = JArray.Parse(JsonHelper.SerializeObject(JsonHelper.DeserializeJsonToList(dbProd.sku_edit_json))); if (chkSameSpecPrice.Checked) { var priceTextLst = dbProd.price_text.Split('-'); if (priceTextLst.Length != 2 || priceTextLst[0] != priceTextLst[1]) { Dictionary specPriceDic = new Dictionary(); Dictionary specMultiPriceDic = new Dictionary(); var skuJArr = prodJObj["detail"]["sku"] as JArray; try { // 计算主spec的最高价 foreach (var skuJObj in skuJArr) { var specJArr = skuJObj["spec"] as JArray; if (!specPriceDic.ContainsKey(specJArr[0]["spec_name"].ParseToString()) || skuJObj["price"].ParseToInt() > specPriceDic[specJArr[0]["spec_name"].ParseToString()]) { specPriceDic[specJArr[0]["spec_name"].ParseToString()] = skuJObj["price"].ParseToInt(); } if (!specMultiPriceDic.ContainsKey(specJArr[0]["spec_name"].ParseToString()) || skuJObj["multi_price"].ParseToInt() > specMultiPriceDic[specJArr[0]["spec_name"].ParseToString()]) { specMultiPriceDic[specJArr[0]["spec_name"].ParseToString()] = skuJObj["multi_price"].ParseToInt(); } } // 统一按最高价设置 foreach (var skuJObj in skuJArr) { var specJArr = skuJObj["spec"] as JArray; skuJObj["price"] = specPriceDic[specJArr[0]["spec_name"].ParseToString()]; skuJObj["multi_price"] = specMultiPriceDic[specJArr[0]["spec_name"].ParseToString()]; } } catch (Exception ex) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"商品数据初始化失败" + ex.Message + "\"}"; } } } if (chkHighestPriceSku.Checked) { int price = 0; var skuJArr = prodJObj["detail"]["sku"] as JArray; try { // 计算主spec的最高价 foreach (var skuJObj in skuJArr) { if (price < skuJObj["multi_price"].ParseToInt()) price = skuJObj["multi_price"].ParseToInt(); } var product_json_tmp = JsonHelper.SerializeObject(prodJObj); // 移除第一组所有sku skuJArr.RemoveAll(); // 序列化第二组,从组中挑选符合价格条件的sku往第一组内填写 var prodJObj2 = JObject.Parse(product_json_tmp); var skuJArr2 = prodJObj2["detail"]["sku"] as JArray; foreach (var skuJObj2 in skuJArr2) { if (skuJObj2["multi_price"].ParseToInt() >= price) skuJArr.Add(skuJObj2); } if (skuJArr.Count == 0) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"商品sku差价不满足上货条件,跳过\"}"; } } catch (Exception ex) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"商品数据初始化失败" + ex.Message + "\"}"; } } // 过滤低价sku,如果所有sku都不达标,跳过商品 if (!string.IsNullOrEmpty(txtMinPrice.Text)) { var product_json_tmp = JsonHelper.SerializeObject(prodJObj); // 移除第一组所有sku var skuJArr = prodJObj["detail"]["sku"] as JArray; skuJArr.RemoveAll(); // 序列化第二组,从组中挑选符合价格条件的sku往第一组内填写 var prodJObj2 = JObject.Parse(product_json_tmp); var skuJArr2 = prodJObj2["detail"]["sku"] as JArray; foreach (var skuJObj2 in skuJArr2) { if (skuJObj2["multi_price"].ParseToInt() >= this.txtMinPrice.Text.Trim().ParseToDecimal() * 100) skuJArr.Add(skuJObj2); } if (skuJArr.Count == 0) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"商品sku价格不满足上货条件,跳过\"}"; } } dbProd.product_json = JsonHelper.SerializeObject(prodJObj); } catch (Exception ex) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"商品数据初始化失败" + ex.Message + "\"}"; } #endregion var prodInfo = JsonHelper.DeserializeJsonToObject(dbProd.product_json); prodInfo.detail.galleries.RemoveAll(g => g.type == 6); // 视频暂时移除,以后再视情况加上 int mainImgCount = (prodInfo?.detail?.galleries?.Where(g => g.type == 1).Count()).ParseToInt(); if (mainImgCount > 0 && mainImgCount < 3) { var gallery1 = prodInfo?.detail?.galleries?.Where(g => g.type == 2).FirstOrDefault(); if (gallery1 != null) { prodInfo.detail.galleries.Add(new gallery_item() { type = 1, url = gallery1.url, width = gallery1.width, height = gallery1.height, }); } if (mainImgCount == 1 && (prodInfo?.detail?.galleries?.Where(g => g.type == 1).Count()).ParseToInt() > 1) { var gallery2 = prodInfo?.detail?.galleries?[1]; if (gallery2 != null) { prodInfo.detail.galleries.Add(new gallery_item() { type = 1, url = gallery2.url, width = gallery2.width, height = gallery2.height, }); } } } if ((prodInfo?.detail?.galleries?.Where(g => g.type == 1).Count()).ParseToInt() < 3) { Invoke(new Action(() => { cell.Value = "主图数量少于三张"; })); return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"主图数量少于三张\"}"; } // 生成初始化上传商品对象 var upProdInitParam = new WXUploadProductInitParam(); // 生成上传商品对象 var upProdParam = new WXUploadProductParam(); // 设置标题 upProdInitParam.product.info.title = dbProd.product_name.IsNullOrEmpty() ? prodInfo.detail.goods_name : dbProd.product_name; upProdParam.product.info.title = dbProd.product_name.IsNullOrEmpty() ? prodInfo.detail.goods_name : dbProd.product_name; upProdParam.sessionInfo.sessionId = upProdInitParam.product.sessionId; // 设置货号 var extCode = dbProd.ext_code.IsNullOrEmpty() ? prodInfo.detail.out_goods_sn : dbProd.ext_code; if (extCode.IsNullOrEmpty()) { //extCode = "EC" + Randomx.GetId(1000).ToString().PadLeft(3, '0') + dbProd.spu_id + "C"; extCode = "EC1" + dbProd.spu_id + "A"; } upProdParam.product.info.spuCode = extCode; if (cell != null) { Invoke(new Action(() => { cell.Value = "正在识别商品"; })); } Thread.Sleep(Randomx.GetId(500, 800)); //------------------------------------------------------------------------------------------------------------------------------------- // ai识别类目暂存主图位置 int imgId = 0; string tempImgPath = Path.GetTempPath() + "\\"; string folderLetters = "abcdefghijklmnopqrstuvwxyz1234567890"; for (int i = 0; i < 8; i++) { tempImgPath += folderLetters[Randomx.GetId(folderLetters.Length)]; } List tempImgFullPathLst = new List(); //------------------------------------------------------------------------------------------------------------------------------------- // 上传主图 foreach (var gallery_item in prodInfo.detail.galleries.Where(g => g.type == 1).Take(9)) // 9张主图 { var upImgAuthRst = WXUpload.getUploadTempImgAuth(shop); for (int i = 0; i < 10 && upImgAuthRst.Contains("LogicError"); i++) { Thread.Sleep(Randomx.GetId(3000, 6000)); upImgAuthRst = WXUpload.getUploadTempImgAuth(shop); Invoke(new Action(() => { cell.Value = "图片提报失败,正在重试。"; })); } if (!upImgAuthRst.Contains("\"code\":0")) { var error = BaseRegex.GetStringJson(ref upImgAuthRst, "msg"); if (string.IsNullOrEmpty(error)) error = upImgAuthRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"申请上传主图失败 " + error + "\"}"; } string disK = BaseRegex.GetStringJson(ref upImgAuthRst, "disK"); long disT = BaseRegex.GetLongJson(ref upImgAuthRst, "disT"); string ext = BaseRegex.GetStringJson(ref upImgAuthRst, "ext"); string imgBase64 = ""; //------------------------------------------------------------------------------------------------------------------------------------- //生成主图base64字符串 string getImgError; var image = GetHtml.GetUrlImg(gallery_item.url.Replace("https://", "http://"), out getImgError); var imageBg = new Bitmap(800, 800); if (!string.IsNullOrEmpty(getImgError) || image == null) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"初始化主图上传失败\"}"; } try { 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 (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { 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)); } } // 取前三张图片保存到系统temp路径,配合商品标题获取商品类目 if (imgId < 3) { imgId++; if (!Directory.Exists(tempImgPath)) Directory.CreateDirectory(tempImgPath); string imgFullPath = tempImgPath + "\\图片" + imgId + ".jpg"; tempImgFullPathLst.Add(imgFullPath); if (imgId == 1) image.Save(imgFullPath, System.Drawing.Imaging.ImageFormat.Jpeg); else { // 只需要传一张真实图像即可 int fileSize = Randomx.GetId(1024, 10240); using (BinaryWriter writer = new BinaryWriter(File.Create(imgFullPath))) { for (int i = 0; i < fileSize; i++) { writer.Write((byte)Randomx.GetId(256)); // 生成0到255之间的随机字节 } } } } using (MemoryStream memoryStream = new MemoryStream()) { imageBg.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg); byte[] imageBytes = memoryStream.ToArray(); imgBase64 = Convert.ToBase64String(imageBytes); } } catch (Exception ex) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"修改主图失败 " + ex.Message + "\"}"; } //------------------------------------------------------------------------------------------------------------------------------------- //上传主图获取路径 var upImgRst = WXUpload.adtimageupload(shop, imgBase64, disK, disT, ext).ParseToString(); var location = BaseRegex.GetStringJson(ref upImgRst, "Location"); if (string.IsNullOrEmpty(location)) { var error = BaseRegex.GetStringJson(ref upImgAuthRst, "msg"); if (string.IsNullOrEmpty(error)) error = upImgAuthRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"主图上传失败 " + error + "\"}"; } upProdInitParam.product.info.headImg.Add(location); upProdParam.product.info.headImg.Add(location); Thread.Sleep(Randomx.GetId(10, 50)); } if (cell != null) { Invoke(new Action(() => { cell.Value = "正在生成类目属性"; })); } Thread.Sleep(Randomx.GetId(500, 800)); //------------------------------------------------------------------------------------------------------------------------------------- // 根据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); if (!productClassifyRst.Contains("\"code\":0")) { var error = BaseRegex.GetStringJson(ref productClassifyRst, "msg"); if (string.IsNullOrEmpty(error)) error = productClassifyRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"获取类目失败 " + error + "\"}"; } WXGetProdCateInfo cateInfo = new WXGetProdCateInfo(); List aiCateIdLst = new List(); try { cateInfo = JsonHelper.DeserializeJsonToObject(productClassifyRst); foreach (var catePath in cateInfo.aiCategoryList.FirstOrDefault().paths) { aiCateIdLst.Add(catePath.id.ParseToLong()); } string getCateRst = WXUpload.getCategoryOnShelf(shop, aiCateIdLst); if (!getCateRst.Contains("\"code\":0")) { var error = BaseRegex.GetStringJson(ref getCateRst, "msg"); if (string.IsNullOrEmpty(error)) error = getCateRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"获取类目模板失败" + error + "\"}"; } JObject jCateRst = JObject.Parse(getCateRst); upProdParam.product.info.category = JsonHelper.DeserializeJsonToList(JsonHelper.SerializeObject(jCateRst["category"])); // 这里用了ai获取类目,如下填写 upProdParam.product.info.recommendCategory = new recommendCategoryParam() { isAccepted = true, categoryNames = new List(), recommendSource = "ai", interfaceName = "ProductClsRAG", useNewInterface = 1, }; foreach (var cateParam in upProdParam.product.info.category) { upProdParam.product.info.recommendCategory.categoryNames.Add(cateParam.name); } } catch (Exception ex) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"" + "根据图片获取类目失败 " + ex.Message + "\"}"; } // 检测是否有类目上传权限 long leafCatId = (upProdParam.product.info.category.LastOrDefault()?.catId).ParseToLong(); //哲学经典著作 var cateUpCheckRst = WXUpload.batchCheckCategoryRelation(shop, leafCatId); if (!cateUpCheckRst.Contains("\"code\":0") && !cateUpCheckRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref cateUpCheckRst, "msg"); if (string.IsNullOrEmpty(error)) error = cateUpCheckRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"类目校验错误 " + error + "\"}"; } if (!cateUpCheckRst.Contains("\"result\":1")) { Thread.Sleep(Randomx.GetId(1000, 2000)); var cateAuthorRst = WXUpload.addFinderCategoryV2(shop, leafCatId); if (!cateAuthorRst.Contains("\"code\":0") && !cateAuthorRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref cateAuthorRst, "msg"); if (string.IsNullOrEmpty(error)) error = cateAuthorRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"类目申请错误 " + error + "\"}"; } } //todo //客服地址https://store.weixin.qq.com/shop/kf // ai获取短标题 #region 短标题 WXGetShortTitleParam titleParam = new WXGetShortTitleParam() { categories = new List(), headImgUrls = upProdParam.product.info.headImg, productTitle = upProdParam.product.info.title, }; foreach (var cate in upProdParam.product.info.category) { titleParam.categories.Add(new categorieParam() { catId = cate.catId, catName = cate.name }); } var shortTitleRst = WXUpload.genProductShortTitle(shop, titleParam); if (!shortTitleRst.Contains("\"code\":0") && !shortTitleRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref shortTitleRst, "msg"); if (string.IsNullOrEmpty(error)) error = shortTitleRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"短标题获取失败 " + error + "\"}"; } upProdParam.product.info.shortTitle = BaseRegex.GetStringJson(ref shortTitleRst, "shortTitle"); upProdParam.product.info.aiGenShortTitle = upProdParam.product.info.shortTitle; #endregion #region 售后信息 var addressRst = WXUpload.getAddress(shop); if (!addressRst.Contains("\"code\":0") && !addressRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref addressRst, "msg"); if (string.IsNullOrEmpty(error)) error = addressRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"售后地址获取失败 " + error + "\"}"; } upProdParam.product.info.afterSaleInfo = new afterSaleInfoParam(); upProdParam.product.info.afterSaleInfo.afterSaleAddressId = BaseRegex.GetStringJson(ref addressRst, "addressId"); #endregion #region 运费模板 var expressRst = WXUpload.getFreightTemplate(shop); if (!expressRst.Contains("\"code\":0") && !expressRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref expressRst, "msg"); if (string.IsNullOrEmpty(error)) error = expressRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"运费模板获取失败 " + error + "\"}"; } upProdParam.product.info.expressInfo = new expressInfoParam(); upProdParam.product.info.expressInfo.templateId = BaseRegex.GetStringJson(ref expressRst, "templateId"); #endregion #region 详情图 if (cell != null) { Invoke(new Action(() => { cell.Value = "正在生成商品详情"; })); } Thread.Sleep(Randomx.GetId(500, 800)); upProdParam.product.info.detail = new productDetailParam(); // 详情图 var 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 }); foreach (var gallery_item in detailGalleries) { bool randomDrawBlock = false; if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") randomDrawBlock = true; var locationStr = UploadImg(shop, gallery_item.url, cell, randomDrawBlock); if (!locationStr.Contains("\"success\":true")) return locationStr; var location = BaseRegex.GetStringJson(ref locationStr, "Location"); upProdParam.product.info.detail.detailImg.Add(location); Thread.Sleep(Randomx.GetId(10, 50)); } #endregion #region 匹配产品属性 //真丝、蚕丝、香云纱、羊绒、羊毛、羊羔毛、羽绒、皮草 upProdParam.product.info.param = new List(); // 商品属性值 var productAttr = upProdParam.product.info.category.LastOrDefault().catInfo.productAttr; foreach (var propInfo in prodInfo.property.goods_properties) { var attr = productAttr.attr.FirstOrDefault(r => r.name == propInfo.name); if (attr == null) { if (propInfo.name.Contains("面料俗称")) { attr = productAttr.attr.FirstOrDefault(r => r.name == "面料材质"); } if (propInfo.name.Contains("适用年龄")) { attr = productAttr.attr.FirstOrDefault(r => r.name == "适用年龄" || r.name == "适用年龄段"); } if (propInfo.name.Contains("填充物")) { attr = productAttr.attr.FirstOrDefault(r => r.name == "填充物种类" || r.name == "填充物"); } // 书籍类目属性匹配 if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { if (propInfo.name == "出版社名称") attr = productAttr.attr.FirstOrDefault(r => r.name == "出版社名称"); else if (propInfo.name == "ISBN编号") attr = productAttr.attr.FirstOrDefault(r => r.name == "ISBN版号/CN刊号"); 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 == "作者"); 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 == "包装"); else if (propInfo.name == "包册数") attr = productAttr.attr.FirstOrDefault(r => r.name == "图书册数"); } } if (attr == null) { continue; } var attrValueLst = attr.value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries).ToList(); var attrValue = attrValueLst.FirstOrDefault(v => v == propInfo.values.FirstOrDefault().value); if (propInfo.name == "风格" && attrValue == null) { attrValue = attrValueLst.FirstOrDefault(v => v == propInfo.values.FirstOrDefault().value + "风"); } if (attr.type == "string") { attrValue = propInfo.values.FirstOrDefault()?.value; } //书籍属性处理 if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { if (attrValue.IsNullOrEmpty() && attr.type == "integer_unit" && (propInfo.values.FirstOrDefault()?.value).IsNumber()) { attrValue = propInfo.values.FirstOrDefault()?.value + " " + attr.value.Split(';').FirstOrDefault(); } if (attrValue.IsNullOrEmpty() && attr.name == "包装") { if (propInfo.values.FirstOrDefault()?.value == "平装-胶订") attrValue = "平装"; } } if (attrValue.IsNullOrEmpty() && attr.isRequired == true) { if (attrValueLst.Contains("其他")) attrValue = "其他"; else if (attrValueLst.Contains("常规")) attrValue = "常规"; else if (attrValueLst.Contains("通用")) attrValue = "通用"; else attrValue = attrValueLst.Where(v => !"真丝、蚕丝、香云纱、羊绒、羊毛、羊羔绒、羊羔毛、羽绒、皮草".Contains(v)).OrderBy(x => Guid.NewGuid()).FirstOrDefault(); } if (attrValue.IsNullOrEmpty()) { if (attrValueLst.Contains("其他")) attrValue = "其他"; else if (attrValueLst.Contains("通用")) attrValue = "通用"; } if (attrValue.IsNullOrEmpty() && attr.type == "string") { attrValue = propInfo.values.FirstOrDefault()?.value; } if (attr.type == "decimal4_unit" || attr.type == "integer_unit") { if (attr.value == "%") attrValue = "10 %"; else if (attr.value == "g;kg") attrValue = "50 g"; else if (attr.value == "g") attrValue = "10 g"; else if (attr.value == "kg") attrValue = "1 kg"; } if (string.IsNullOrEmpty(attrValue)) continue; var wxPropParam = new propParam(); upProdParam.product.info.param.Add(wxPropParam); var wxCategoryParam1 = new categoryPropParam() { catType = 7, name = attr.name, catInfo = new catInfoParam() { inputType = attr.normalRelease.ruleType, isRequired = attr.isRequired == true ? 1 : 0, isCustomize = 0 } }; var wxCategoryParam2 = new categoryPropParam() { catType = 7, name = attrValue, catInfo = new catInfoParam() { inputType = attr.normalRelease.ruleType, isRequired = attr.isRequired == true ? 1 : 0, isCustomize = 0 } }; wxPropParam.categorys.Add(wxCategoryParam1); wxPropParam.categorys.Add(wxCategoryParam2); } foreach (var attr in productAttr.attr) { if (attr.isRequired != true) continue; // 已填写内没有但是必填属性 if (upProdParam.product.info.param.Any(p => p.categorys.FirstOrDefault()?.name == attr.name)) continue; var attrValueLst = attr.value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries).ToList(); string attrValue = ""; if (attrValue.IsNullOrEmpty() && attr.isRequired == true) { if (attrValueLst.Contains("其他")) attrValue = "其他"; else if (attrValueLst.Contains("常规")) attrValue = "常规"; else if (attrValueLst.Contains("通用")) attrValue = "通用"; else if (attr.value.Contains("绒丝;羽毛;白鸭绒;白鹅绒;灰鸭绒;灰鹅绒;鸭毛片;鹅毛片")) { attrValue = "绒丝"; } else if (attrValueLst.Any(v => v.Contains("%"))) { attrValue = attrValueLst.FirstOrDefault(); } else attrValue = attrValueLst.Where(v => !"真丝、蚕丝、香云纱、羊绒、羊毛、羊羔绒、羊羔毛、羽绒、皮草".Contains(v)).OrderBy(x => Guid.NewGuid()).FirstOrDefault(); //书籍属性处理 if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { if (attr.name == "是否为单一书号丛书") attrValue = "是"; if (attr.name == "图书册数") attrValue = "1 册"; if (attr.name == "出版社名称") attrValue = new List() { "技术出版社", "文化出版社", "美术出版社" }[Randomx.GetId(3)]; if (attr.name == "作者") attrValue = new List() { "李老师", "张老师", "王老师" }[Randomx.GetId(3)]; if (attr.name == "包装") attrValue = "平装"; } } if (attrValue.IsNullOrEmpty() && attr.type == "string") { attrValue = "其他"; } if (attr.type == "decimal4_unit" || attr.type == "integer_unit") { if (attr.value == "%") attrValue = "10 %"; else if (attr.value == "g;kg") attrValue = "50 g"; else if (attr.value == "g") attrValue = "10 g"; else if (attr.value == "kg") attrValue = "1 kg"; } var wxPropParam = new propParam(); upProdParam.product.info.param.Add(wxPropParam); var wxCategoryParam1 = new categoryPropParam() { catType = 7, name = attr.name, catInfo = new catInfoParam() { inputType = attr.normalRelease.ruleType, isRequired = attr.isRequired == true ? 1 : 0, isCustomize = 0 } }; var wxCategoryParam2 = new categoryPropParam() { catType = 7, name = attrValue, catInfo = new catInfoParam() { inputType = attr.normalRelease.ruleType, isRequired = attr.isRequired == true ? 1 : 0, isCustomize = 0 } }; wxPropParam.categorys.Add(wxCategoryParam1); wxPropParam.categorys.Add(wxCategoryParam2); } #endregion #region sku规格属性 if (cell != null) { Invoke(new Action(() => { cell.Value = "正在生成sku"; })); } Thread.Sleep(1000); 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; if (prodInfo.detail.sku.FirstOrDefault()?.spec?.Count > 0) { productSaleAttrParam attrParam = new productSaleAttrParam() { key = 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) { var spec = sku.spec[0]; if (!attrParam.items.Any(it => it.value == spec.spec_name)) { // 上传sku图 var locationStr = UploadImg(shop, sku.thumb_url, cell); if (!locationStr.Contains("\"success\":true")) return locationStr; var location = BaseRegex.GetStringJson(ref locationStr, "Location"); Thread.Sleep(Randomx.GetId(10, 50)); attrParam.items.Add(new productSaleAttrItemParam() { value = spec.spec_name, imgUrl = location, }); } } } if (prodInfo.detail.sku.FirstOrDefault()?.spec?.Count > 1) { productSaleAttrParam attrParam = new productSaleAttrParam() { key = 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) { var spec = sku.spec[1]; if (!attrParam.items.Any(it => it.value == spec.spec_name)) attrParam.items.Add(new productSaleAttrItemParam() { value = spec.spec_name }); } } #endregion #region sku信息 upProdParam.product.productSkus = new List(); int skuIndex = 0; int id = 3; long catId = 200000000003; long fCatId = 200000000003; long valueCatId = (17 + Randomx.GetNumber(11)).ParseToLong(); Dictionary dicSpecParentNameId = new Dictionary(); Dictionary dicSpecParentNameCatId = new Dictionary(); Dictionary dicSpecNamefCatId = new Dictionary(); Dictionary dicSpecNameCatId = new Dictionary(); foreach (var skuInfo in prodInfo.detail.sku) { foreach (var spec in skuInfo.spec) { if (!dicSpecParentNameId.Keys.Contains(spec.parent_name)) { dicSpecParentNameId[spec.parent_name] = id++; dicSpecParentNameCatId[spec.parent_name] = catId++; } if (!dicSpecNamefCatId.Keys.Contains(spec.spec_name)) { dicSpecNamefCatId[spec.spec_name] = fCatId++; dicSpecNameCatId[spec.spec_name] = valueCatId++; } } } foreach (var skuInfo in prodInfo.detail.sku) { productSkuParam skuParam = new productSkuParam(); upProdParam.product.productSkus.Add(skuParam); for (int i = skuInfo.spec.Count - 1; i >= 0; i--) { var specInfo = skuInfo.spec[i]; skuParam.__skuKey = specInfo.parent_name + "." + specInfo.spec_name + "_"; skuParam.__skuKey += specInfo.spec_name; } skuParam.__skuKey.TrimEnd('_'); skuParam.index = 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(); // 阶梯式加价,如果命中则按阶梯式加价进行 if (defaultAddPriceRule.IsStepAddPrice) { foreach (var addPrice in lstAddPriceRule) { if (skuInfo.multi_price > addPrice.MoreThanPrice * 100 && skuInfo.multi_price <= addPrice.LessThanPrice * 100) { if (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(); break; } } } // sku图 skuParam.productSkuInfo.thumbImg = upProdParam.product.info.productSaleAttrs[0].items.FirstOrDefault(a => a.value == skuInfo.spec[0].spec_name)?.imgUrl; // 库存 skuParam.productSkuInfo.stockInfo = new stockInfoParam() { stockNum = defaultAddPriceRule.StockNum }; skuParam.productSkuInfo.saleParam = new List(); foreach (var specInfo in skuInfo.spec) { saleParamParam saleParam = new saleParamParam(); skuParam.productSkuInfo.saleParam.Add(saleParam); saleParam.categorys = new List(); // specKey categoryKeyParam skuCateKeyParam = new categoryKeyParam(); saleParam.categorys.Add(skuCateKeyParam); 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.label = "自定义规格"; skuCateKeyParam.catInfo = new skuCatInfoParam() { isCustomize = 1 }; skuCateKeyParam.catType = 8; // specValue categoryValueParam skuCateValueParam = new categoryValueParam(); saleParam.categorys.Add(skuCateValueParam); skuCateValueParam.fCatId = dicSpecNamefCatId[specInfo.spec_name]; skuCateValueParam.catId = 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.selected = false; } skuParam.productSkuInfo.skuDeliverInfo = new skuDeliverInfoParam(); skuParam.productSkuInfo.stockDiff = new stockDiffParam() { diffType = 1, num = defaultAddPriceRule.StockNum }; skuParam.status = 5; } #endregion #region 预售信息 if (chkPreSale.Checked) { upProdParam.product.deliverInfo = new productDeliverInfoParam(); upProdParam.product.deliverInfo.deliverType = 1; int preSaleDays = Math.Max(3, wxUploadRule.PreSaleDays); preSaleDays = Math.Min(45, preSaleDays); upProdParam.product.deliverInfo.skuDeliverInfo = new skuDeliverInfoParam() { stockType = 1, fullPaymentPresaleDeliveryTime = preSaleDays.ParseToString() }; } #endregion #region 书籍类生成书籍图片 //qualificationList if (upProdParam.product.info.category.FirstOrDefault()?.name == "图书" || prodInfo.detail.cats.FirstOrDefault() == "书籍/杂志/报纸") { if (cell != null) { Invoke(new Action(() => { cell.Value = "正在生成图书专有信息"; })); } string publisher = "出版社:" + new List() { "技术出版社", "文化出版社", "美术出版社" }[Randomx.GetId(3)]; string isbn = "ISBN:"; string bookName = "书名:"; string bookPrice = "定价:" + upProdParam.product.productSkus.Max(s => s.productSkuInfo.salePrice) * 0.01; string author = "作者:王老师"; string publishTime = "出版时间:" + DateTime.Now.AddMonths(-3); string edition = "版次:1"; string binding = "装帧:平装"; foreach (var propParam in upProdParam.product.info.param) { if (propParam.categorys[0].name.Contains("出版社名称")) publisher = "出版社:" + propParam.categorys[1].name; else if (propParam.categorys[0].name.Contains("ISBN版号/CN刊号")) isbn = "ISBN:" + propParam.categorys[1].name; else if (propParam.categorys[0].name.Contains("书名")) bookName = "书名:" + propParam.categorys[1].name; else if (propParam.categorys[0].name.Contains("定价")) bookPrice = "定价:" + propParam.categorys[1].name; else if (propParam.categorys[0].name.Contains("作者")) author = "作者:" + propParam.categorys[1].name; else if (propParam.categorys[0].name.Contains("出版时间")) publishTime = "出版时间:" + propParam.categorys[1].name; else if (propParam.categorys[0].name.Contains("版次")) edition = "版次:" + propParam.categorys[1].name; else if (propParam.categorys[0].name.Contains("包装")) binding = "装帧:" + propParam.categorys[1].name; } var bookStr = publisher + "\r\n" + "\r\n" + isbn + "\r\n" + "\r\n" + bookName + "\r\n" + "\r\n" + bookPrice + "\r\n" + "\r\n" + author + "\r\n" + "\r\n" + publishTime + "\r\n" + "\r\n" + edition + "\r\n" + "\r\n" + binding; var bookImg = new Bitmap(800, 800); using (Graphics g = Graphics.FromImage(bookImg)) { g.Clear(Color.White); //Font font = new Font("宋体", 15, FontStyle.Bold); Font font = new Font("微软雅黑", 15, FontStyle.Regular); Brush textBrush = Brushes.Black; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; RectangleF rectF = new RectangleF(80, 80, 800 - 80, 800 - 80); g.DrawString(bookStr, font, textBrush, rectF); } Thread.Sleep(Randomx.GetId(500, 800)); var locationStr = UploadImg(shop, bookImg, cell); if (!locationStr.Contains("\"success\":true")) return locationStr; var location = BaseRegex.GetStringJson(ref locationStr, "Location"); upProdParam.product.info.qualificationList.Add(new qualificationParam() { qualificationId = "1111485", qualificationUrl = new List() { location }, }); } #endregion if (cell != null) { Invoke(new Action(() => { cell.Value = "正在提交商品"; })); } Thread.Sleep(Randomx.GetId(1000, 2000)); var uploadDraftRst = WXUpload.uploadProductDraft(shop, upProdParam); if (!uploadDraftRst.Contains("\"code\":0") && !uploadDraftRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref uploadDraftRst, "msg"); if (string.IsNullOrEmpty(error)) error = uploadDraftRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"草稿保存失败 " + error + "\"}"; } if (cell != null) { Invoke(new Action(() => { var timeSpan = DateTime.Now - startTime; var duration = timeSpan.TotalSeconds; cell.Value = "商品已保存草稿,正在提交上架" + " " + duration.ParseToInt() + "秒"; })); } upProdParam.product.productKey.productId = BaseRegex.GetLongJson(ref uploadDraftRst, "productId").ParseToString(); if (chkUpDraft.Checked) { 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); return "{\"success\":true,\"draftId\":" + upProdParam.product.productKey.productId + ",\"status\":\"草稿箱\",\"errMsg\":\"指定上传到草稿箱\"}"; } // 提交商品上架 if (!chkTestNoAuditUpload.Checked) { var uploadProdRst = WXUpload.upProductV2(shop, upProdParam); if (!uploadProdRst.Contains("\"code\":0") && !uploadProdRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref uploadProdRst, "msg"); if (string.IsNullOrEmpty(error)) error = BaseRegex.GetStringJson(ref uploadProdRst, "errmsg"); if (string.IsNullOrEmpty(error)) error = uploadProdRst; return "{\"success\":false,\"draftId\":" + upProdParam.product.productKey.productId + ",\"status\":\"草稿箱\",\"errMsg\":\"上架失败 " + error + "\"}"; } if (upProdParam.product.productKey.productId.IsNullOrEmpty()) upProdParam.product.productKey.productId = BaseRegex.GetLongJson(ref uploadProdRst, "productId").ParseToString(); } else { #region 尝试免审接口提交 未成功 var getEditProd = WXUpload.getEditProductV2(shop, upProdParam.product.productKey.productId); //getEditProd = getEditProd.Replace("8388275713", "33333333"); //getEditProd = getEditProd.Replace("33333333", "8387633147"); string productJson = ""; try { // 获取免审编辑回传数据 JsonSerializerSettings jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; var prodStr = JsonConvert.SerializeObject(upProdParam, jsonSetting); JObject jObj = JsonHelper.JObjectParse(prodStr); JObject jObjTmp = JsonHelper.JObjectParse(getEditProd); jObj["product"] = jObjTmp["product"]; //productJson = productJson.Replace("999", "1005"); jObj["product"]["status"] = 1; //默认为5 foreach(var sku in jObj["product"]["productSkus"]) { sku["productSkuInfo"]["stockInfo"]["stockNum"] = "1000"; sku["productSkuInfo"]["stockInfo"]["totalNum"] = "1000"; //sku["productSkuInfo"]["realStockInfo"]["stockNum"] = "1000"; //sku["productSkuInfo"]["realStockInfo"]["totalNum"] = "1000"; var realStockInfo = new realStockInfoParam() { stockNum = 999, totalNum = 999 }; sku["productSkuInfo"]["realStockInfo"] = JsonHelper.JObjectParse(JsonHelper.SerializeObject(realStockInfo)); } productJson = JsonHelper.SerializeObject(jObj); // 提交上架 //var uploadProdRst = WXUpload.upProductJObjectV2(shop, productJson); } catch (Exception ex) { } string submitJson = "{\"name\":\"goods/" + upProdParam.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); string uploadPartId = BaseRegex.GetStringJson(ref uploadPartRst, "uploadId"); //upProdParam.product.status = 5; //upProdParam.product.editStatus = 0; //upProdParam.product.auditReason = ""; //upProdParam.product.info.skuIdList = new skuIdListParam(); //upProdParam.product.info.skuList = new skuListParam(); //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); string tempBlobPath = Path.GetTempPath(); for (int i = 0; i < 8; i++) { tempBlobPath += folderLetters[Randomx.GetId(folderLetters.Length)]; } if (!Directory.Exists(tempBlobPath)) Directory.CreateDirectory(tempBlobPath); string blobFullPath = tempBlobPath + "\\blob"; // C:\Users\Administrator\AppData\Local\Temp\3mer3k21\blob using (StreamWriter sw = new StreamWriter(blobFullPath)) { //skuParam.productSkuInfo.realStockInfo = new realStockInfoParam() { stockNum = 1005, totalNum = 1005 }; var jObj = JsonHelper.JObjectParse(productJson); foreach(JObject skuObj in jObj["product"]["productSkus"]) { skuObj["productSkuInfo"]["stockInfo"]["stockNum"] = 1005; var realStockInfo = new realStockInfoParam() { stockNum = 999, totalNum = 999 }; skuObj["productSkuInfo"]["realStockInfo"] = JsonHelper.JObjectParse(JsonHelper.SerializeObject(realStockInfo)); } JsonSerializerSettings jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; foreach (var sku in upProdParam.product.productSkus) { sku.productSkuInfo.stockInfo.stockNum = 1005; } var prodStr = JsonConvert.SerializeObject(upProdParam, jsonSetting); prodStr = JsonHelper.SerializeObject(jObj["product"]); sw.Write(prodStr); } uploadPartRst = WXUpload.uploadPartBinary(shop, initFileName, blobFullPath, uploadPartId, upProdParam.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); #endregion } if (cell != null) { Invoke(new Action(() => { var timeSpan = DateTime.Now - startTime; var duration = timeSpan.TotalSeconds; cell.Value = "商品已上传" + " " + duration.ParseToInt() + "秒"; })); } // 已传的商品保存为安全商品 if (dbProd.wx_safe_status == "未校验") { var url = BaseClass.BuildObjString("product/mdy_pdd_product"); var data = ""; Invoke(new Action(() => { data = UserLogin.GetSignaturex(); data += "&spu_id=" + dbProd.spu_id; data += "&wx_safe_status=安全商品"; })); 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); } //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 (!dicShopUpload.ContainsKey(shop.ShopId)) dicShopUpload[shop.ShopId] = new WxShopUploadInfo(); if (!dicShopUpload[shop.ShopId].DicDayUploadCount.ContainsKey(day)) dicShopUpload[shop.ShopId].DicDayUploadCount[day] = 0; dicShopUpload[shop.ShopId].DicDayUploadCount[day]++; NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_shop_upload_info", dicShopUpload); Invoke(new Action(() => { dgvShopRow.Cells["colUploadCount"].Value = dicShopUpload[shop.ShopId].DicDayUploadCount[day]; })); } return "{\"success\":true,\"draftId\":" + upProdParam.product.productKey.productId + ",\"status\":\"已上传\",\"msg\":\"上传成功\"}"; } public string UploadImg(ShopLoginInfo shop, string img_url, DataGridViewCell cell = null, bool randomBlock = false) { string getImgError; var image = GetHtml.GetUrlImg(img_url.Replace("https://", "http://"), out getImgError); if (image == null) image = new Bitmap(800, 800); var imageBg = new Bitmap(image.Width, image.Height); if (!string.IsNullOrEmpty(getImgError) || image == null) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"初始化图片上传失败\"}"; } try { 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 (randomBlock) 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)); } } catch (Exception ex) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"" + "修改图片失败 " + ex.Message + "\"}"; } return UploadImg(shop, imageBg, cell); } public string UploadImg(ShopLoginInfo shop, Bitmap img, DataGridViewCell cell = null) { var upImgAuthRst = WXUpload.getUploadTempImgAuth(shop); for (int i = 0; i < 10 && upImgAuthRst.Contains("LogicError"); i++) { if (cell != null) { Invoke(new Action(() => { cell.Value = "图片提报失败,正在重试。"; })); } Thread.Sleep(Randomx.GetId(3000, 6000)); upImgAuthRst = WXUpload.getUploadTempImgAuth(shop); } if (!upImgAuthRst.Contains("\"code\":0")) { var error = BaseRegex.GetStringJson(ref upImgAuthRst, "msg"); if (string.IsNullOrEmpty(error)) error = upImgAuthRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"申请上传图片失败 " + error + "\"}"; } string disK = BaseRegex.GetStringJson(ref upImgAuthRst, "disK"); long disT = BaseRegex.GetLongJson(ref upImgAuthRst, "disT"); string ext = BaseRegex.GetStringJson(ref upImgAuthRst, "ext"); string imgBase64 = ""; //------------------------------------------------------------------------------------------------------------------------------------- //生成图片base64字符串 try { using (MemoryStream memoryStream = new MemoryStream()) { img.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg); byte[] imageBytes = memoryStream.ToArray(); imgBase64 = Convert.ToBase64String(imageBytes); } } catch (Exception ex) { return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"" + "修改图片失败 " + ex.Message + "\"}"; } //------------------------------------------------------------------------------------------------------------------------------------- //上传图片,获取图片路径 var upImgRst = WXUpload.adtimageupload(shop, imgBase64, disK, disT, ext).ParseToString(); var location = BaseRegex.GetStringJson(ref upImgRst, "Location"); if (string.IsNullOrEmpty(location)) { var error = BaseRegex.GetStringJson(ref upImgAuthRst, "msg"); if (string.IsNullOrEmpty(error)) error = upImgAuthRst; return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"图片上传失败 " + error + "\"}"; } return "{\"success\":true,\"location\":\"" + location + "\"}"; } private void panel1_Paint(object sender, PaintEventArgs e) { } private void btnStop_Click(object sender, EventArgs e) { if (this.cancellationTokenSource != null) this.cancellationTokenSource.Cancel(); } private void btnRandomAdd_Click(object sender, EventArgs e) { int addCount = txtAddCount.Text.Trim().ParseToInt(); Task.Run(() => { List prodLst = new List(); while (addCount > 0) { int prodCount = 0; // 如果产品数量在0到50之间,说明数据库商品数量不足,无需再重复筛选,直接随机打乱 if (prodLst.Count == 0 || prodLst.Count == Math.Min(50, addCount)) { prodLst = GetRandomProductList(out prodCount, 1, Math.Min(50, addCount)); Thread.Sleep(Randomx.GetId(50, 100)); } else { prodLst = prodLst.OrderBy(x => Guid.NewGuid()).ToList(); Thread.Sleep(Randomx.GetId(10, 30)); } Invoke(new Action(() => { lblGoodsCount.Text = "产品库 " + prodCount + " 件"; })); if (prodLst.Count == 0) // 等于0要么库里没数据要么出错了,跳出 break; foreach (var prod in prodLst) { var selectProd = JsonHelper.DeserializeJsonToObject(JsonHelper.SerializeObject(prod)); selectProd.out_product_Id = prod.id.ToString(); selectProd.id = 1; if(lstTemuDBProductSelect.Count > 0) selectProd.id = lstTemuDBProductSelect.Max(p => p.id) + 1; this.lstTemuDBProductSelect.Add(selectProd); Invoke(new Action(() => { lblWaitToUp.Text = "待上传 " + lstTemuDBProductSelect.Count + " 件"; })); addCount--; if (addCount <= 0) break; } NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_db_prod_upload_list", this.lstTemuDBProductSelect); } }); } public List GetRandomProductList(out int totalCount, int page = 1, int pageSize = 50) { var lstShopId = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); List list = new List(); int pageCount = 1; totalCount = 0; var url = BaseClass.BuildObjString("product/get_pdd_product_list_random"); var data = ""; Invoke(new Action(() => { data = UserLogin.GetSignaturex() + "&page=" + 1 + "&page_size=" + pageSize; data += "&in_ext_codes=" + txtExtCodeFilter.Text; data += "&in_skc_ids=" + txtIdFilter.Text; data += "&in_groups=" + cmbGroupFilter.Text; data += "&in_cates=" + cmbCateFilter.Text; data += "&product_get_type=" + cmbSourceType.Text.Trim(); data += "&wx_safe_status=" + cmbWxSafe.Text.Trim(); data += "&special_prod_type=" + cmbSpProdType.Text.Trim(); data += "&is_supplier_prod_ok=" + cmbSet.Text.Trim(); })); 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")) { Invoke(new Action(() => { BaseMsgForm.ShowError("获取商品失败,请重试!" + BaseRegex.GetStringJson(ref html, "msg")); })); return new List(); } int count = BaseRegex.GetIntJson(ref html, "count"); totalCount = count; pageCount = Math.Ceiling(1.0 * count / pageSize).ParseToInt(); pageCount = Math.Max(pageCount, 1); var jArr = JObject.Parse(html)["data"]; if (jArr.Count() == 0) return list; var sProd = JsonHelper.SerializeObject(jArr); try { list = JsonHelper.DeserializeJsonToList(sProd); return list; } catch (Exception ex) { return new List(); } } private void btnClearUpload_Click(object sender, EventArgs e) { if (BaseMsgForm.ShowConfirm("确定清空待上传商品吗?清空后不可恢复!").DialogResult == DialogResult.Cancel) return; this.lstTemuDBProductSelect.Clear(); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_db_prod_upload_list", this.lstTemuDBProductSelect); lblWaitToUp.Text = "待上传 " + lstTemuDBProductSelect.Count + " 件"; } private void lblNewAddPrice_Click(object sender, EventArgs e) { var ucPrice = new UcAddPrice(); if (IsSetFontScaleNone) { Font of = ucPrice.Font; Font nf = new Font(of.FontFamily, (of.Size * 96.0 / FormDpi).ParseToFloat(), of.Style, of.Unit, of.GdiCharSet, of.Bold); ucPrice.Font = nf; } ucPrice.PriceChange += ucAddPrice_PriceChange; this.fPnlPriceRule.Controls.Add(ucPrice); ucPrice.lblSinglePriceAdd.Visible = false; ucPrice.txtSinglePriceAdd.Visible = false; } private void ucAddPrice_PriceChange(object obj) { List priceRuleLst = new List(); foreach (var ucItem in fPnlPriceRule.Controls) { var ucPrice = ucItem as UcAddPrice; if (ucPrice != null) { priceRuleLst.Add(new AddPriceRule() { AddMorePrice = ucPrice.PriceAddMore, AddPriceTimes = ucPrice.PriceAddTimes, LessThanPrice = ucPrice.PriceEnd, MoreThanPrice = ucPrice.PriceStart, SinglePriceAdd = ucPrice.SinglePriceAdd, }); } } this.lstAddPriceRule.Clear(); this.lstAddPriceRule.AddRange(priceRuleLst); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_add_price_rules", lstAddPriceRule); } private void txtAddPrice_TextChanged(object sender, EventArgs e) { if (IsLoadComplate) { defaultAddPriceRule.AddPriceTimes = txtAddTimes.Text.Trim().ParseToDecimal(); defaultAddPriceRule.AddMorePrice = txtAddMorePrice.Text.Trim().ParseToDecimal(); defaultAddPriceRule.SinglePriceAdd = txtSinglePriceAdd.Text.Trim().ParseToDecimal(); defaultAddPriceRule.StockNum = txtStockNum.Text.Trim().ParseToInt(); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_default_add_price_rule", defaultAddPriceRule); } } private void chkStepAddPrice_CheckedChanged(object sender, EventArgs e) { defaultAddPriceRule.IsStepAddPrice = this.chkStepAddPrice.Checked; NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_default_add_price_rule", defaultAddPriceRule); } private void btnClearDgv_Click(object sender, EventArgs e) { //this.dgvSelectProduct.Rows.Clear(); var rows = this.dgvSelectProduct.Rows.Cast().ToList(); //Cast后Rows做foreach循环时仍会夹花跳过,所以要ToList转一个新的数组。 foreach (var row in rows) { if (row.Cells["colCheck"].Value.ParseToBool() == true) { var draft_id = row.Cells["colDraftId"].Value.ParseToString(); upload_draft_product_lst.RemoveAll(p => p.draft_id == draft_id); this.dgvSelectProduct.Rows.Remove(row); } } NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_select_upload_draft_products", upload_draft_product_lst); } private void chkAddMorePriceFirst_CheckedChanged(object sender, EventArgs e) { if (IsLoadComplate) { defaultAddPriceRule.AddMorePriceFirst = chkAddMorePriceFirst.Checked; NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_default_add_price_rule", defaultAddPriceRule); } } private void lblGoodsCount_Click(object sender, EventArgs e) { //PDDDBProdListForm f = new PDDDBProdListForm(); //f.Width = 1366; //f.Height = 768; //f.ShowMaximizeBox = true; //f.ShowDialog(); } private void lblWaitToUp_Click(object sender, EventArgs e) { PDDDBProdUserSelectCacheForm selectCacheForm = new PDDDBProdUserSelectCacheForm(lstTemuDBProductSelect); selectCacheForm.ShowDialog(); lblWaitToUp.Text = "待上传 " + lstTemuDBProductSelect.Count + " 件"; } private void btnClearFilter_Click(object sender, EventArgs e) { txtIdFilter.Text = ""; txtExtCodeFilter.Text = ""; cmbGroupFilter.Text = ""; cmbCateFilter.Text = ""; cmbWxSafe.SelectedIndex = 0; cmbSpProdType.SelectedIndex = 0; int prodCount; GetRandomProductList(out prodCount, 1, 1); lblGoodsCount.Text = "产品库 " + prodCount + " 件"; } private void 并发上传_Click(object sender, EventArgs e) { var draftIdLst = dgvSelectProduct.Rows.Cast().Where(row => row.Cells["colCheck"]?.Value.ParseToBool() == true).Select(r => r.Cells["colDraftId"]?.Value.ToString()).ToList(); var lst = upload_draft_product_lst.Select(p => p.wxDraftProduct).ToList(); var upLst = lst.Where(l => draftIdLst.Contains(l.product.productKey.productId)).ToList(); DateTime startTime = DateTime.Now; Task.Run(() => { List tLst = new List(); foreach (var prodParam in upLst) { var row = this.dgvSelectProduct.Rows.Cast().FirstOrDefault(r => r.Cells["colDraftId"].Value.ParseToString() == prodParam.product.productKey.productId); if (row == null) continue; var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == row.Cells["colSupplierId"].Value.ParseToString()); if (shop == null) continue; var t =Task.Run(() => { UploadSameTime(shop, prodParam, row.Cells["colOpResult"]); }); tLst.Add(t); } Task.WaitAll(tLst.ToArray()); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_select_upload_draft_products", upload_draft_product_lst); var duration = DateTime.Now - startTime; Invoke(new Action(() => { BaseMsgForm.ShowInfo("并发上传完成,耗时:" + duration.TotalSeconds + " 秒"); })); }); } //public ConcurrentList upload_draft_products = new ConcurrentList(); public ConcurrentList upload_draft_product_lst = new ConcurrentList(); void UploadSameTime(ShopLoginInfo shop, WXUploadProductParam upProdParam, DataGridViewCell cell) { var uploadProdRst = WXUpload.upProductV2(shop, upProdParam); int retryTimes = 0; while (!uploadProdRst.Contains("\"code\":0") && !uploadProdRst.Contains("\"success\":true")) { retryTimes++; uploadProdRst = WXUpload.upProductV2(shop, upProdParam); if (retryTimes >= 5) break; if (uploadProdRst.Contains("今日提审次数已用尽,请明日再试")) break; } if (!uploadProdRst.Contains("\"code\":0") && !uploadProdRst.Contains("\"success\":true")) { var error = BaseRegex.GetStringJson(ref uploadProdRst, "msg"); if (string.IsNullOrEmpty(error)) error = uploadProdRst; if (cell != null) { Invoke(new Action(() => { cell.Value = "商品上传失败 " + error; })); } } else { if (cell != null) { upload_draft_product_lst.RemoveAll(p => p.wxDraftProduct == upProdParam); Invoke(new Action(() => { cell.Value = "商品已上传,重试次数 " + retryTimes; })); } var dgvShopRow = dgvShop.Rows.Cast().FirstOrDefault(row => row.Cells["colShopId"]?.Value.ParseToString() == shop.ShopId); if (dgvShopRow != null) { var day = DateTime.Now.ToString("yyyyMMdd").ParseToInt(); var removeDay = DateTime.Now.Date.AddMonths(-1).ToString("yyyyMMdd").ParseToInt(); if (!dicShopUpload.ContainsKey(shop.ShopId)) dicShopUpload[shop.ShopId] = new WxShopUploadInfo(); if (!dicShopUpload[shop.ShopId].DicDayUploadCount.ContainsKey(day)) dicShopUpload[shop.ShopId].DicDayUploadCount[day] = 0; dicShopUpload[shop.ShopId].DicDayUploadCount[day]++; NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_shop_upload_info", dicShopUpload); Invoke(new Action(() => { dgvShopRow.Cells["colUploadCount"].Value = dicShopUpload[shop.ShopId].DicDayUploadCount[day]; })); } } } private void txtPreDays_TextChanged(object sender, EventArgs e) { wxUploadRule.PreSaleDays = txtPreDays.Text.Trim().ParseToInt(); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_upload_rule", wxUploadRule); } private void txtReplaceText_TextChanged(object sender, EventArgs e) { wxUploadRule.FilterWords = txtReplaceText.Text.Trim(); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_upload_rule", wxUploadRule); } private void txtMinPrice_TextChanged(object sender, EventArgs e) { wxUploadRule.SkuMinPrice = txtMinPrice.Text.Trim().ParseToInt(); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_upload_rule", wxUploadRule); } private void txtWaitSeconds_TextChanged(object sender, EventArgs e) { wxUploadRule.WaitSeconds = txtWaitSeconds.Text.Trim().ParseToInt(); NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_upload_rule", wxUploadRule); } private void chkHighestPriceSku_CheckedChanged(object sender, EventArgs e) { wxUploadRule.OnlyHighestPriceSku = chkHighestPriceSku.Checked; NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_upload_rule", wxUploadRule); } private void chkSameSpecPrice_CheckedChanged(object sender, EventArgs e) { wxUploadRule.SameSpecSamePrice = chkSameSpecPrice.Checked; NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_upload_rule", wxUploadRule); } private void chkSkipUploaded_CheckedChanged(object sender, EventArgs e) { wxUploadRule.SkipUploaded = chkSkipUploaded.Checked; NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_upload_rule", wxUploadRule); } private void chkUpDraft_CheckedChanged(object sender, EventArgs e) { wxUploadRule.UpDraft = chkUpDraft.Checked; NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_upload_rule", wxUploadRule); } private void chkPreSale_CheckedChanged(object sender, EventArgs e) { wxUploadRule.IsPreSale = chkPreSale.Checked; NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_upload_rule", wxUploadRule); } private void btnRefreshNum_Click(object sender, EventArgs e) { } } public class WXUpload { public static string searchProduct(ShopLoginInfo shop, string extCode) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/searchProduct?" + "token=&lang=zh_CN&pageSize=20&productStatus[]=-1&productSource=[1,16,32]&searchSource=1&useNew=true&pageNum=1&status[]=5&spuCode=" + extCode; string refere = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ON"; var result = WXHttpResponseBLL.WeiXinGetResponse(shop, url, refere); return result; } public static string getUploadTempImgAuth(ShopLoginInfo shop, int uploadScene = 3) { string url = "https://store.weixin.qq.com/shop-faas/mmecchannelspicture/cgi/getUploadTempImgAuth?token=&lang=zh_CN&uploadScene=" + uploadScene; string refere = "https://store.weixin.qq.com/shop/goods/entry"; //{"code":0,"disK":"538c14e950da7b678ce9f5a12658c8acddd09e4b","disT":1767870926,"ext":"23aa0ecfb792a","url":"https://westore.video.qq.com/adtimageupload"} var result = WXHttpResponseBLL.WeiXinGetResponse(shop, url, refere); return result; } public static string adtimageupload(ShopLoginInfo shop, string imgBase64, string dis_k, long dis_t, string ext) { string url = "https://westorealpha.video.qq.com/adtimageupload"; string referer = "https://store.weixin.qq.com/"; string body = imgBase64; var result = WXHttpResponseBLL.WeiXinImgPostResponse(shop, url, body, dis_k, dis_t, ext, referer); return result; } public static string getProductClassify(ShopLoginInfo shop, string goodsName, List goodImgUrlsLst) { string boundaryLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; string boundaryStr = "----WebKitFormBoundary"; for (int i = 0; i < 16; i++) { boundaryStr += boundaryLetters[Randomx.GetId(boundaryLetters.Length)]; } string url = "https://store.weixin.qq.com/shop-faas/cgi/common/productClassify?from=B&title=" + GetHtml.UrlEncodeUtf8(goodsName) + "&token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; string body = @"--" + boundaryStr + @" "; foreach (var imgFullPath in goodImgUrlsLst) { string fileName = imgFullPath.Split('\\').LastOrDefault(); body += @"Content-Disposition: form-data; name=""file""; filename=""" + fileName + @""" Content-Type: image/jpeg " + imgFullPath + @" --" + boundaryStr; } body += @"-- "; var result = WXHttpResponseBLL.WeiXinUploadResponse(shop, url, body, boundaryStr, referer); return result; } public static string getCategoryOnShelf(ShopLoginInfo shop, List catIdLst) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/product/getCategoryOnShelfV2?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; string body = @"{""catIdList"":[" + string.Join(",", catIdLst) + @"],""brandId"":2100000000}"; var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } public static string batchCheckCategoryRelation(ShopLoginInfo shop, long catId) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/product/batchCheckCategoryRelation?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; string body = @"{""categoryIdList"":[" + catId + "]}"; var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } public static string addFinderCategoryV2(ShopLoginInfo shop, long catId) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradecategory/cgi/addFinderCategoryV2?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; string body = @"{""categoryInfo"":{""categories"":[{""id"":""" + catId + @"""}]},""brandIdList"":[],""leafCategoryId"":""" + catId + @""",""reuse"":0,""applyType"":1}"; var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); //{"categoryInfo":{"categories":[{"id":10000257},{"id":10000245},{"id":112888}],"categoryDeposit":"10000.00","isNewApplyCat":true,"licenseGroupList":[{"licenseGroupId":"17","license":{"licenseId":"5","cosIdList":["1768635607165-orc0V2WjFHdNvjNnk967_g14awFw-7487"],"licenseFieldList":[{"key":"audit_license_no","value":"新出发皖字第1027号"},{"key":"audit_license_validty_period","value":"2029-04-30"}],"isReuse":true}}],"ruleVersion":5234,"certificate":[]},"brandIdList":[],"leafCategoryId":112888,"reuse":0,"applyType":"normalApply"} //{"code":0,"baseResp":{"errcode":0,"errmsg":"ok"},"auditId":"8362856529"} //string body = @"{""categoryInfo"":{""categories"":[{""id"":10000257},{""id"":10000245},{""id"":112888}],""categoryDeposit"":""10000.00"",""isNewApplyCat"":true,""licenseGroupList"":[{""licenseGroupId"":""17"",""license"":{""licenseId"":""5"",""cosIdList"":[""1768635607165-orc0V2WjFHdNvjNnk967_g14awFw-7487""],""licenseFieldList"":[{""key"":""audit_license_no"",""value"":""新出发皖字第1027号""},{""key"":""audit_license_validty_period"",""value"":""2029-04-30""}],""isReuse"":true}}],""ruleVersion"":5234,""certificate"":[]},""brandIdList"":[],""leafCategoryId"":112888,""reuse"":0,""applyType"":""normalApply""}"; // request.Referer = "https://store.weixin.qq.com/shop/brandAndCat/category/apply?defaultCategoryIds=%5B%2210000257%22%2C%2210000245%22%2C%22112888%22%5D&source=goods&type=apply"; return result; } public static string genProductShortTitle(ShopLoginInfo shop, WXGetShortTitleParam getShortTitleParam) { string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/common/cgi/goods/genProductShortTitle?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; string body = JsonHelper.SerializeObject(getShortTitleParam); //{"productTitle":"妈妈老年中年阔脚裤冬季秋季时尚牛仔裤","headImgUrls":["https://wst.wxapp.tc.qq.com/160/20304/snscosdownload/SH/reserved/6xykWLEnztKEVU0iahAM7HQ28puCia87zPkvSbFT8Fcia99g2ZNWRdy8licxD6qwsqV4bCicoxwQF9e6jh3qwibgzxuA?token=x5Y29zUxcibCe0pFyoSA8zb1aYVKnIBLkQ8ZUXMcwEq3qYHsko3TDzv2rsL2AfJPd&idx=1&expire=1768211170","https://wst.wxapp.tc.qq.com/160/20304/snscosdownload/SH/reserved/6xykWLEnztKEVU0iahAM7Hbwaw1AboTKxjGsLhJgVreuYNxwyQxrk9RtvCv3XsXSnic9WfBFMAIZYpNgYkWd7VDQ?token=x5Y29zUxcibCe0pFyoSA8zb1aYVKnIBLk4qWUsS2WZiaCjXhZLj0D6PYyddX71qNiat&idx=1&expire=1768211170","https://wst.wxapp.tc.qq.com/160/20304/snscosdownload/SH/reserved/6xykWLEnztKEVU0iahAM7HTa1Ej2xJpy6Ej84arVO7A3vxIDD1XP6ZRVw43OficKLXPcXPUvDNmc8A4lMHCgbic3A?token=x5Y29zUxcibCe0pFyoSA8zb1aYVKnIBLkhejArCiaiaLIEKtvOicA5chibIj1tfELV0Mm&idx=1&expire=1768211170"],"categories":[{"catId":"10000111","catName":"服饰内衣"},{"catId":"10000113","catName":"女装"},{"catId":"10000672","catName":"裤子"},{"catId":"547705","catName":"牛仔裤"}]} var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } public static string getFreightTemplate(ShopLoginInfo shop) { string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/express/cgi/goods/getFreightTemplate?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; var result = WXHttpResponseBLL.WeiXinGetResponse(shop, url, referer); return result; } /// /// 取售后地址 /// /// /// public static string getAddress(ShopLoginInfo shop) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/cgi/getAddress?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; var result = WXHttpResponseBLL.WeiXinGetResponse(shop, url, referer); return result; } public static string uploadProductDraft(ShopLoginInfo shop, WXUploadProductParam prodParam) { string url = "https://store.weixin.qq.com/shop-faas/mmecnodeproductupload/common/cgi/goods/uploadProductDraft?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; JsonSerializerSettings jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; var prodStr = JsonConvert.SerializeObject(prodParam, jsonSetting); JObject jObj = new JObject(); jObj.Add("data", prodStr); string body = JsonHelper.SerializeObject(jObj); var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } public static string upProductV2(ShopLoginInfo shop, WXUploadProductParam prodParam) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/upProductV2?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; JsonSerializerSettings jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; var prodStr = JsonConvert.SerializeObject(prodParam, jsonSetting); JObject jObj = new JObject(); jObj.Add("data", prodStr); string body = JsonHelper.SerializeObject(jObj); var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } public static string upProductJObjectV2(ShopLoginInfo shop, string prodStr) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/upProductV2?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry"; //JsonSerializerSettings jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; //var prodStr = JsonConvert.SerializeObject(prodParam, jsonSetting); JObject jObj = new JObject(); jObj.Add("data", prodStr); string body = JsonHelper.SerializeObject(jObj); var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } /// /// 取售后地址 /// /// /// public static string getEditProductV2(ShopLoginInfo shop, string productId) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/getEditProductV2?token=&lang=zh_CN&productKey=%7B%22productId%22:" + productId + "%7D&needRealStock=true&preview=false&release=false"; //url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/getEditProductV2?token=&lang=zh_CN&productKey=%7B%22productId%22:" + // productId + "%7D&needRealStock=true&preview=false&release=true"; string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + productId + "&isUpdateAuditFree=0&source=list_edit&continueEditInfo={%22isEditingContinued%22:false,%22lastEditDraftTime%22:0,%22listingTime%22:0}"; //referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + productId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo={%22isEditingContinued%22:true,%22lastEditDraftTime%22:0,%22listingTime%22:0}"; var result = WXHttpResponseBLL.WeiXinGetResponse(shop, url, referer); return result; } public static string initUploadPart(ShopLoginInfo shop, string submitJson, string prodId, int time1, int time2) { string url = "https://store.weixin.qq.com/shop-faas/mmecnodefiletransfer/filecos/initUploadPart?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}"; string body = submitJson; //@"{""name"":""goods/10000456038253/2026-01-20/1768887306422/submit.json""}"; var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } public static string listingAuditFree(ShopLoginInfo shop, WXUploadProductParam prodParam, string prodId, int time1, int time2) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/listingAuditFree?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}"; JsonSerializerSettings jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; var prodStr = JsonConvert.SerializeObject(prodParam, jsonSetting); JObject jObj = new JObject(); jObj.Add("data", prodStr); string body = JsonHelper.SerializeObject(jObj); var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } public static string listingAuditFree(ShopLoginInfo shop, string prodStr, string prodId, int time1, int time2) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/listingAuditFree?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}"; JsonSerializerSettings jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; JObject jObj = new JObject(); jObj.Add("data", prodStr); string body = JsonHelper.SerializeObject(jObj); var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } public static string uploadPartBinary(ShopLoginInfo shop, string initFileName, string blobPath, string uploadId, string prodId, int time1, int time2) { string boundaryLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; string boundaryStr = "----WebKitFormBoundary"; for (int i = 0; i < 16; i++) { boundaryStr += boundaryLetters[Randomx.GetId(boundaryLetters.Length)]; } string url = "https://store.weixin.qq.com/shop-faas/mmecnodefiletransfer/filecos/uploadPartBinary?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}"; string body = @"--" + boundaryStr + @" Content-Disposition: form-data; name=""name"" " + initFileName + @" --" + boundaryStr + @" Content-Disposition: form-data; name=""uploadId"" " + uploadId + @" --" + boundaryStr + @" Content-Disposition: form-data; name=""partSeq"" 1 --" + boundaryStr + @" Content-Disposition: form-data; name=""file""; filename=""blob"" Content-Type: application/octet-stream " + blobPath + @" --" + boundaryStr + @"-- "; var result = WXHttpResponseBLL.WeiXinUploadResponse(shop, url, body, boundaryStr, referer); return result; } public static string completeUploadPart(ShopLoginInfo shop, string completeJson, string prodId, int time1, int time2) { string url = "https://store.weixin.qq.com/shop-faas/mmecnodefiletransfer/filecos/completeUploadPart?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/entry?productId=" + prodId + "&isUpdateAuditFree=1&source=list_audit_free&continueEditInfo=" + "{%22isEditingContinued%22:true,%22lastEditDraftTime%22:" + time1 + "," + "%22listingTime%22:" + time2 + "}"; string body = completeJson; //{"name":"goods/10000466857488/2026-01-20/1768907711117/submit.json","uploadId":"176890774759894589c6096cab2210e0793688fb68b482b766a0387c8667d3280a36385109","etagList":["ade9671ce546efb4cb209f5aa7e5d597"],"partSeqList":[1]} var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } /// /// 商品列表 /// /// /// /// /// /// public static string scanProductPreview(ShopLoginInfo shop, string status = "5", int pageNum = 1, int pageSize = 20) { string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeproductcore/cgi/goods/scanProductPreview?token=&lang=zh_CN"; string referer = "https://store.weixin.qq.com/shop/goods/list?currentTab=PRODUCT_STATUS_ALL"; string body = @"{""pageSize"":" + pageSize + @",""productStatus"":[-1],""productSource"":""[1,16,32]"",""searchSource"":1,""useNew"":true,""pageNum"":" + pageNum + @",""status"":[" + status + @"]}"; var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer); return result; } } public class AddPriceRule { /// /// 加价金额区间大于 不包含 /// public decimal MoreThanPrice { get; set; } /// /// 加价金额区间小于 包含 /// public decimal LessThanPrice { get; set; } /// /// 加价倍数 /// public decimal AddPriceTimes { get; set; } /// /// 额外加价金额 /// public decimal AddMorePrice { get; set; } /// /// 单买加价 /// public decimal SinglePriceAdd { get; set; } /// /// 先加后乘 /// public bool AddMorePriceFirst { get; set; } = false; /// /// 上货库存量设置 /// public int StockNum { get; set; } = 0; public bool IsStepAddPrice { get; set; } = false; } public class WXUploadRule { public int PreSaleDays { get; set; } = 5; public string FilterWords { get; set; } = "真丝,蚕丝,香云纱,羊绒,羊毛,羊羔绒,羊羔毛,羽绒,皮草"; public int SkuMinPrice { get; set; } = 10; public int WaitSeconds { get; set; } = 10; public bool OnlyHighestPriceSku { get; set; } = true; public bool SameSpecSamePrice { get; set; } = true; public bool SkipUploaded { get; set; } = true; public bool UpDraft { get; set; } = false; public bool IsPreSale { get; set; } = false; } }