Files
KJD/TEMUKJD/WXForms/ProductForms/WXDBProdUploadForm.cs
T

3135 lines
160 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using AllBase;
using AllBase.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<ShopLoginInfo, int> dicShopGetCount = new Dictionary<ShopLoginInfo, int>();
Dictionary<ShopLoginInfo, List<string>> dicNotSupportCate = new Dictionary<ShopLoginInfo, List<string>>();
public NaiBa.Util.ConcurrentList<TemuDBProductSelect> lstTemuDBProductSelect = new NaiBa.Util.ConcurrentList<TemuDBProductSelect>();
NaiBa.Util.ConcurrentList<AddPriceRule> lstAddPriceRule = new NaiBa.Util.ConcurrentList<AddPriceRule>();
AddPriceRule defaultAddPriceRule = null;
WXUploadRule wxUploadRule = null;
//public Dictionary<string, List<string>> dicCheckedShopIdList = new Dictionary<string, List<string>>();
public Dictionary<string, bool> dicCheckedShopId = new Dictionary<string, bool>();
public Dictionary<string, WxShopUploadInfo> dicShopUpload = new Dictionary<string, WxShopUploadInfo>();
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<NaiBa.Util.ConcurrentList<TemuDBProductSelect>>("wx_db_prod_upload_list");
if (lstTemuDBProductSelect == null)
lstTemuDBProductSelect = new NaiBa.Util.ConcurrentList<TemuDBProductSelect>();
lstAddPriceRule = NaiBa.Util.Helper.ConfigHelper.LoadConfig<NaiBa.Util.ConcurrentList<AddPriceRule>>("wx_add_price_rules");
if (lstAddPriceRule == null)
{
lstAddPriceRule = new NaiBa.Util.ConcurrentList<AddPriceRule>();
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<Dictionary<string, bool>>("wx_checked_shop_dic");
if (dicCheckedShopId == null)
dicCheckedShopId = new Dictionary<string, bool>();
dicShopUpload = NaiBa.Util.Helper.ConfigHelper.LoadConfig<Dictionary<string, WxShopUploadInfo>>("wx_shop_upload_info");
if (dicShopUpload == null)
dicShopUpload = new Dictionary<string, WxShopUploadInfo>();
defaultAddPriceRule = NaiBa.Util.Helper.ConfigHelper.LoadConfig<AddPriceRule>("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<WXUploadRule>("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<NaiBa.Util.ConcurrentList<TemuDBProductSelect>>("wx_select_upload_draft_products");
if (upload_draft_product_lst == null)
upload_draft_product_lst = new ConcurrentList<TemuDBProductSelect>();
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<DataGridViewRow>())
{
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;
}));
});
}
/// <summary>
/// 获取商品所有类目
/// </summary>
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<DataGridViewRow>().Where(row
=> row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList();
// 获取被删除的店铺
List<DataGridViewRow> dgvRowList = dgvShop.Rows.Cast<DataGridViewRow>().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<string> selectShopId = null)
{
if (shopEntity == null)
return;
if (selectShopId == null)
selectShopId = new List<string>();
bool canUse = shopEntity.LoginStatus == "登录成功";
//canUse = true; // 内部库不需要校验登录状态
var row = dgvShop.Rows.Cast<DataGridViewRow>().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<DataGridViewRow>().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<DataGridViewRow>().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<DataGridViewRow>().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<string> 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<ShopLoginInfo> currentShopList = new NaiBa.Util.ConcurrentList<ShopLoginInfo>();
while (lstTemuDBProductSelect.Count > 0)
{
if (cancellationTokenSource.IsCancellationRequested)
break;
Invoke(new Action(() =>
{
shopIdLst = dgvShop.Rows.Cast<DataGridViewRow>().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<DataGridViewRow>().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<ShopLoginInfo>();
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<DataGridViewRow>().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<string>();
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<DataGridViewRow>().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<KJDDBProduct> list = new List<KJDDBProduct>();
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<KJDDBProduct>(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";
if (dbProd.sku_secret_json != null && dbProd.sku_secret_json.Contains("goodsId"))
{
var sku_secret_json = dbProd.sku_secret_json;
searchExtCode = BaseRegex.GetStringJson(ref sku_secret_json, "goodsId");
}
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 + "\"}";
}
}
// 加密数据将聚水潭产品数据格式进行转换
if (dbProd.sku_secret_json != null && dbProd.sku_secret_json.Contains("goodsId"))
{
string convertRst = "";
var ob = new PDDProdFormConverter().JstPddProdToPddConvert(out convertRst, dbProd);
if (!string.IsNullOrEmpty(convertRst))
return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"商品查询错误 " + convertRst + "\"}";
}
#region 将产品数据初始化成微信小店支持的参数
JObject prodJObj = new JObject();
try
{
prodJObj = JObject.Parse(dbProd.product_json);
var lstTitleReplaceText = new List<string>();
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<sku_item>(dbProd.sku_edit_json)));
if (chkSameSpecPrice.Checked)
{
var priceTextLst = dbProd.price_text.Split('-');
if (priceTextLst.Length != 2 || priceTextLst[0] != priceTextLst[1])
{
Dictionary<string, int> specPriceDic = new Dictionary<string, int>();
Dictionary<string, int> specMultiPriceDic = new Dictionary<string, int>();
var skuJArr = 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<PDDProductInfo>(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<string> tempImgFullPathLst = new List<string>();
//-------------------------------------------------------------------------------------------------------------------------------------
// 上传主图
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<long> aiCateIdLst = new List<long>();
try
{
cateInfo = JsonHelper.DeserializeJsonToObject<WXGetProdCateInfo>(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<categoryParam>(JsonHelper.SerializeObject(jCateRst["category"]));
// 这里用了ai获取类目,如下填写
upProdParam.product.info.recommendCategory = new recommendCategoryParam()
{
isAccepted = true,
categoryNames = new List<string>(),
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<categorieParam>(),
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 afterSaleAddress = "";
var afterSaleDetail = "";
if (dbProd.wx_cat_leaf != null)
{
var urlAfterSale = BaseClass.BuildObjString("product/wx_get_after_sale");
var dataAfterSale = Work.UserLogin.GetSignaturex() +
"&coid=" + dbProd.skc_id;
var htmlAfterSale = GetHtml.PostUtf8(urlAfterSale, dataAfterSale);
if (string.IsNullOrEmpty(htmlAfterSale) || !htmlAfterSale.Contains("\"code\":200"))
htmlAfterSale = GetHtml.PostUtf8(urlAfterSale, dataAfterSale);
if (string.IsNullOrEmpty(htmlAfterSale) || !htmlAfterSale.Contains("\"code\":200"))
{
}
else
{
if (htmlAfterSale.Contains("\"data\":\"\""))
{
}
else
{
try
{
afterSaleAddress = JsonHelper.SerializeObject(JsonHelper.JObjectParse(htmlAfterSale)["data"]);
}
catch
{
}
}
}
if (string.IsNullOrEmpty(afterSaleAddress))
{
// 获取推单售后地址
//https://po.e57.cn/prod-api/api/sys-api/system/open/api/afterSale/info?warehouseNum=10361546&shopId=46568955
var urlAfter = "https://po.e57.cn/prod-api/api/sys-api/system/open/api/afterSale/info?warehouseNum=" + dbProd.skc_id; //+ "&userName=阿杰账户";
var afterRst = WXHttpResponseBLL.e57GetResponse(urlAfter, "");
try
{
afterSaleAddress = JsonHelper.SerializeObject(JsonHelper.JObjectParse(afterRst)["data"]);
if(afterRst.Contains("\"code\":0") && !string.IsNullOrEmpty(afterSaleAddress))
{
urlAfterSale = BaseClass.BuildObjString("product/wx_add_mdy_after_sale");
dataAfterSale = Work.UserLogin.GetSignaturex() +
"&coid=" + dbProd.skc_id + "&after_sale_json=" + afterSaleAddress;
htmlAfterSale = GetHtml.PostUtf8(urlAfterSale, dataAfterSale);
if (string.IsNullOrEmpty(htmlAfterSale) || !htmlAfterSale.Contains("\"code\":200"))
htmlAfterSale = GetHtml.PostUtf8(urlAfterSale, dataAfterSale);
}
}
catch (Exception ex)
{
}
}
}
if (!string.IsNullOrEmpty (afterSaleAddress))
{
afterSaleDetail = BaseRegex.GetStringJson(ref afterSaleAddress, "detail_info");
}
var addressRst = WXUpload.getAddress(shop, afterSaleDetail);
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 + "\"}";
}
if (addressRst.Contains("\"totalNum\":0") && !string.IsNullOrEmpty(afterSaleDetail))
{
string provinceName = BaseRegex.GetStringJson(ref afterSaleAddress, "province_name");
string cityName = BaseRegex.GetStringJson(ref afterSaleAddress, "city_name");
string countyName = BaseRegex.GetStringJson(ref afterSaleAddress, "county_name");
string detailInfo = afterSaleDetail;
string userName = BaseRegex.GetStringJson(ref afterSaleAddress, "user_name");
string telNumber = BaseRegex.GetStringJson(ref afterSaleAddress, "tel_number");
var addAddRst = WXUpload.addAddress(shop, provinceName, cityName, countyName, detailInfo, userName, telNumber);
Thread.Sleep(Randomx.GetId(500, 1500));
addressRst = WXUpload.getAddress(shop, afterSaleDetail);
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 + "\"}";
}
}
if (addressRst.Contains("\"totalNum\":0"))
{
return "{\"success\":false,\"draftId\":0,\"status\":\"未上传\",\"errMsg\":\"售后地址获取失败\"}";
}
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<propParam>(); // 商品属性值
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 (attrValueLst.Contains("国产"))
attrValue = "国产";
else if (attr.value.Contains("绒丝;羽毛;白鸭绒;白鹅绒;灰鸭绒;灰鹅绒;鸭毛片;鹅毛片"))
{
attrValue = "绒丝";
}
else if (attr.name == "是否进口")
{
attrValue = "非进口";
}
else if (attr.name == "商品产地")
{
attrValue = "中国大陆";
}
else if (attr.name == "产地")
{
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<string>() { "技术出版社", "文化出版社", "美术出版社" }[Randomx.GetId(3)];
if (attr.name == "作者")
attrValue = new List<string>() { "李老师", "张老师", "王老师" }[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<productSaleAttrParam>();
if (prodInfo.detail.sku == null)
prodInfo.detail.sku = new List<sku_item>();
if (prodInfo.detail.sku.Count == 0)
prodInfo.detail.sku.Add(new sku_item() { spec = new List<spec_item>() });
if (prodInfo.detail.sku.FirstOrDefault().spec == null)
prodInfo.detail.sku.FirstOrDefault().spec = new List<spec_item>();
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<productSaleAttrItemParam>()
};
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<productSaleAttrItemParam>()
};
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<productSkuParam>();
int skuIndex = 0;
int id = 3;
long catId = 200000000003;
long fCatId = 200000000003;
long valueCatId = (17 + Randomx.GetNumber(11)).ParseToLong();
Dictionary<string, long> dicSpecParentNameId = new Dictionary<string, long>();
Dictionary<string, long> dicSpecParentNameCatId = new Dictionary<string, long>();
Dictionary<string, long> dicSpecNamefCatId = new Dictionary<string, long>();
Dictionary<string, long> dicSpecNameCatId = new Dictionary<string, long>();
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.skuCode = skuInfo.out_sku_sn;
// 库存
skuParam.productSkuInfo.stockInfo = new stockInfoParam() { stockNum = defaultAddPriceRule.StockNum };
skuParam.productSkuInfo.saleParam = new List<saleParamParam>();
foreach (var specInfo in skuInfo.spec)
{
saleParamParam saleParam = new saleParamParam();
skuParam.productSkuInfo.saleParam.Add(saleParam);
saleParam.categorys = new List<object>();
// 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<string>() { "技术出版社", "文化出版社", "美术出版社" }[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<string>() { 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<skuInfoParam>();
//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<DataGridViewRow>().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<KJDDBProduct> prodLst = new List<KJDDBProduct>();
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<TemuDBProductSelect>(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<KJDDBProduct> GetRandomProductList(out int totalCount, int page = 1, int pageSize = 50)
{
var lstShopId = dgvShop.Rows.Cast<DataGridViewRow>().Where(row
=> row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList();
List<KJDDBProduct> list = new List<KJDDBProduct>();
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_spu_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<KJDDBProduct>();
}
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<KJDDBProduct>(sProd);
return list;
}
catch (Exception ex)
{
return new List<KJDDBProduct>();
}
}
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<AddPriceRule> priceRuleLst = new List<AddPriceRule>();
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<AddPriceRule>("wx_default_add_price_rule", defaultAddPriceRule);
}
}
private void chkStepAddPrice_CheckedChanged(object sender, EventArgs e)
{
defaultAddPriceRule.IsStepAddPrice = this.chkStepAddPrice.Checked;
NaiBa.Util.Helper.ConfigHelper.SaveConfig<AddPriceRule>("wx_default_add_price_rule", defaultAddPriceRule);
}
private void btnClearDgv_Click(object sender, EventArgs e)
{
//this.dgvSelectProduct.Rows.Clear();
var rows = this.dgvSelectProduct.Rows.Cast<DataGridViewRow>().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<DataGridViewRow>().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<Task> tLst = new List<Task>();
foreach (var prodParam in upLst)
{
var row = this.dgvSelectProduct.Rows.Cast<DataGridViewRow>().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<WXUploadProductParam> upload_draft_products = new ConcurrentList<WXUploadProductParam>();
public ConcurrentList<TemuDBProductSelect> upload_draft_product_lst = new ConcurrentList<TemuDBProductSelect>();
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<DataGridViewRow>().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 extCode2 = "")
{
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;
if (!string.IsNullOrEmpty(extCode2))
url += "," + extCode2;
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<string> 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<long> 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;
}
/// <summary>
/// 取售后地址
/// </summary>
/// <param name="shop"></param>
/// <returns></returns>
public static string getAddress(ShopLoginInfo shop, string searchText="")
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/cgi/getAddress?token=&lang=zh_CN";
if (!string.IsNullOrEmpty(searchText))
url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/cgi/getAddress?searchStr=" + GetHtml.UrlEncodeUtf8(searchText) + "&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;
}
/// <summary>
/// 尝试免审 失败
/// </summary>
/// <param name="shop"></param>
/// <param name="productId"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 商品列表
/// </summary>
/// <param name="shop"></param>
/// <param name="status"></param>
/// <param name="pageNum"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 添加售后地址
/// </summary>
public static string addAddress(ShopLoginInfo shop, string provinceName, string cityName, string countyName,
string detailInfo, string userName, string telNumber)
{
string url = "https://store.weixin.qq.com/shop-faas/mmchannelstradeexpress/address/addAddress?token=&lang=zh_CN";
string referer = "https://store.weixin.qq.com/shop/address/expressAddressMgmt";
string address = "{\"addressInfo\":{\"provinceName\":\"" + provinceName +
"\",\"cityName\":\"" + cityName + "\",\"countyName\":\"" + countyName +
"\",\"detailInfo\":\"" + detailInfo + "\",\"userName\":\"" + userName +
"\",\"telNumber\":\"" + telNumber + "\",\"location\":{}},\"defaultSend\":0,\"defaultRecv\":0}";
JObject obj = new JObject();
obj["data"] = address;
string body = JsonHelper.SerializeObject(obj);
var result = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, referer);
return result;
}
}
public class AddPriceRule
{
/// <summary>
/// 加价金额区间大于 不包含
/// </summary>
public decimal MoreThanPrice { get; set; }
/// <summary>
/// 加价金额区间小于 包含
/// </summary>
public decimal LessThanPrice { get; set; }
/// <summary>
/// 加价倍数
/// </summary>
public decimal AddPriceTimes { get; set; }
/// <summary>
/// 额外加价金额
/// </summary>
public decimal AddMorePrice { get; set; }
/// <summary>
/// 单买加价
/// </summary>
public decimal SinglePriceAdd { get; set; }
/// <summary>
/// 先加后乘
/// </summary>
public bool AddMorePriceFirst { get; set; } = false;
/// <summary>
/// 上货库存量设置
/// </summary>
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;
}
}