998 lines
48 KiB
C#
998 lines
48 KiB
C#
using AllBase;
|
|
using AllBase.Helper;
|
|
using AllBase.Model.Result;
|
|
using AllBase.Model.Result.PDDResult;
|
|
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.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using TemuKJD.BaseForms;
|
|
using TemuKJD.BLL;
|
|
using TemuKJD.Extension;
|
|
using TemuKJD.PDDForms.ShopForms;
|
|
using TemuKJD.ToolForms;
|
|
|
|
namespace TemuKJD.PDDForms.ProductForms
|
|
{
|
|
public partial class PDDProductUpDownForm : BaseForm
|
|
{
|
|
public CancellationTokenSource cancellationTokenSource { get; set; } = null;
|
|
|
|
bool isInit = false;
|
|
List<PDDShopListProductInfo> lstPDDShopListProductInfo = new List<PDDShopListProductInfo>();
|
|
Dictionary<ShopLoginInfo, int> dicShopGetCount = new Dictionary<ShopLoginInfo, int>();
|
|
public PDDProductUpDownForm()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
private void PDDProductUpDownForm_Load(object sender, EventArgs e)
|
|
{
|
|
this.dgvShop.AddSelectorColumn("colSelect");
|
|
this.dgvProduct.AddSelectorColumn("colCheck");
|
|
dgvProduct.AddImgColumn("colProductSkcPic", "colImgUrl");
|
|
}
|
|
|
|
private void btnRefreshShop_Click(object sender, EventArgs e)
|
|
{
|
|
RefreshShop();
|
|
}
|
|
|
|
private void PDDProductUpDownForm_VisibleChanged(object sender, EventArgs e)
|
|
{
|
|
if (Visible == true)
|
|
{
|
|
RefreshShop();
|
|
isInit = true;
|
|
}
|
|
}
|
|
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);
|
|
if (row == null)
|
|
{
|
|
this.dgvShop.Rows.Add(
|
|
!isInit || (selectShopId.Contains(shopEntity.ShopId) && canUse),
|
|
shopEntity.LoginName,
|
|
shopEntity.ShopId,
|
|
shopEntity.ShopAccount,
|
|
shopEntity.Notes,
|
|
"选择商品",
|
|
canUse ? "在线" : "掉线",
|
|
canUse,
|
|
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;
|
|
}
|
|
}
|
|
|
|
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":
|
|
row.Cells["colSelect"].Value = !row.Cells["colSelect"].Value.ParseToBool();
|
|
break;
|
|
case "colLoginStatus":
|
|
PDDShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false);
|
|
PDDShopLoginForm shopLoginForm = new PDDShopLoginForm(shop);
|
|
if (shop.LoginStatus != "登录成功")
|
|
{
|
|
shopLoginForm.openType = EnumOpenType.login;
|
|
shopLoginForm.ShowDialog();
|
|
RefreshShop();
|
|
}
|
|
else
|
|
{
|
|
shopLoginForm.openType = EnumOpenType.manage;
|
|
shopLoginForm.WindowState = FormWindowState.Maximized;
|
|
shopLoginForm.Show();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void dgvProduct_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
|
{
|
|
if (e.ColumnIndex < 0 || e.RowIndex < 0)
|
|
return;
|
|
string headerText = dgvProduct.Columns[e.ColumnIndex].HeaderText;
|
|
switch (headerText)
|
|
{
|
|
case "删除":
|
|
//if (BaseMsgForm.ShowConfirm("确定删除商品吗?删除后不可恢复!").DialogResult == DialogResult.Cancel)
|
|
// return;
|
|
//var rst = DeleteProduct(dbId);
|
|
//if (rst)
|
|
//{
|
|
// SearchDbProdSelect(this.ucSplitPage1.CurrentPage);
|
|
//}
|
|
break;
|
|
case "图片":
|
|
{
|
|
ShowImgForm imgFrom = new ShowImgForm(dgvProduct.Rows[e.RowIndex].Cells["colImgUrl"].Value.ParseToString());
|
|
imgFrom.ShowDialog();
|
|
}
|
|
break;
|
|
case "":
|
|
dgvProduct.Rows[e.RowIndex].Cells["colCheck"].Value = !(bool)dgvProduct.Rows[e.RowIndex].Cells["colCheck"].Value;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void btnSearch_Click(object sender, EventArgs e)
|
|
{
|
|
var lstShopId = dgvShop.Rows.Cast<DataGridViewRow>()
|
|
.Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true && row.Cells["colLoginStatus"]?.Value.ParseToString() == "在线")
|
|
.Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList();
|
|
if (lstShopId.Count == 0)
|
|
{
|
|
BaseMsgForm.ShowInfo("请选择登录的店铺!");
|
|
return;
|
|
}
|
|
lstPDDShopListProductInfo.Clear();
|
|
dgvProduct.Rows.Clear();
|
|
|
|
var dgvRows = this.dgvShop.Rows.Cast<DataGridViewRow>();//.Where(r => lstShopId.Contains(r.Cells["colShopId"].Value.ParseToString()));
|
|
foreach (var row in dgvRows)
|
|
{
|
|
row.Cells["colMessage"].Value = "";
|
|
}
|
|
|
|
ucGroupBoxEx2.Enabled = false;
|
|
cancellationTokenSource = new CancellationTokenSource();
|
|
Task.Run(() =>
|
|
{
|
|
var lstShopIdTemp = new List<string>();
|
|
lstShopIdTemp.AddRange(lstShopId);
|
|
int i = 0;
|
|
|
|
foreach (var shopId in lstShopIdTemp)
|
|
{
|
|
this.Invoke(new Action(() =>
|
|
{
|
|
this.statusBar.lblTaskStatus.Text = "正在查询...";
|
|
this.statusBar.pgbTaskProgress.Maximum = lstShopIdTemp.Count;
|
|
this.statusBar.UpdateProgressBar(i + 1);
|
|
i++;
|
|
}));
|
|
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == shopId);
|
|
if (shop == null)
|
|
continue;
|
|
|
|
#region 检测登录
|
|
if (shop.LoginStatus == "登录成功")
|
|
{
|
|
PDDShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false);
|
|
}
|
|
if (shop.LoginStatus != "登录成功")
|
|
{
|
|
Invoke(new Action(() =>
|
|
{
|
|
var rows = this.dgvShop.Rows.Cast<DataGridViewRow>().Where(r => r.Cells["colShopLoginName"].Value.ToString() == shop.LoginName);
|
|
foreach (var row in rows)
|
|
{
|
|
row.Cells["colMessage"].Value = "店铺掉线";
|
|
row.Cells["colLoginStatus"].Value = "掉线";
|
|
row.Cells["colCanUse"].Value = false;
|
|
}
|
|
}));
|
|
continue;
|
|
}
|
|
#endregion
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
var rows = this.dgvShop.Rows.Cast<DataGridViewRow>().Where(r => r.Cells["colShopId"].Value.ToString() == shop.ShopId);
|
|
foreach (var row in rows)
|
|
{
|
|
row.Cells["colMessage"].Value = "正在查询";
|
|
}
|
|
}));
|
|
|
|
int page = 0;
|
|
int pageSize = 100;
|
|
int totalPage = 1;
|
|
bool isError = false;
|
|
string errMsg = "";
|
|
while (page < totalPage)
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
page++;
|
|
|
|
int tryCount = 0;
|
|
tryAgain:
|
|
|
|
GetToken(shop);
|
|
|
|
if (page > 1)
|
|
Thread.Sleep(Randomx.GetId(3000, 7000));
|
|
|
|
int? isOnsale = null;
|
|
Invoke(new Action(() =>
|
|
{
|
|
if (cmbStatus.Text == "在售")
|
|
isOnsale = 1;
|
|
else if (cmbStatus.Text == "下架")
|
|
isOnsale = 0;
|
|
}));
|
|
//,"goods_id_list":["819969337632","819963304053"],"
|
|
List<string> goods_id_list = null;
|
|
if (!string.IsNullOrWhiteSpace(txtSPU.Text))
|
|
goods_id_list = txtSPU.Text.Split(new string[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
|
List<string> out_goods_sn_list = null;
|
|
if (!string.IsNullOrWhiteSpace(txtExtCode.Text))
|
|
out_goods_sn_list = txtExtCode.Text.Split(new string[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
|
List<string> skuSns = null;
|
|
if (!string.IsNullOrWhiteSpace(txtSkuSns.Text))
|
|
skuSns = new List<string>() { txtSkuSns.Text.Trim() };
|
|
long? minPrice = null, maxPrice = null;
|
|
if (!string.IsNullOrWhiteSpace(txtMinPrice.Text))
|
|
minPrice = (txtMinPrice.Text.Trim().ParseToDecimal() * 100).ParseToLong();
|
|
if (!string.IsNullOrWhiteSpace(txtMaxPrice.Text))
|
|
maxPrice = (txtMaxPrice.Text.Trim().ParseToDecimal() * 100).ParseToLong();
|
|
string jsonStr = shop_goods_search(shop, goods_id_list, txtGoodsName.Text.Trim(), out_goods_sn_list, skuSns, isOnsale, minPrice, maxPrice, page, pageSize);
|
|
if (jsonStr.Contains("繁忙") && tryCount < 5)
|
|
{
|
|
tryCount++;
|
|
Thread.Sleep(Randomx.GetId(5000, 10000));
|
|
goto tryAgain;
|
|
}
|
|
if (!jsonStr.Contains("\"success\":true"))
|
|
{
|
|
PDDShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false);
|
|
if (shop.LoginStatus != "登录成功")
|
|
break;
|
|
|
|
isError = true;
|
|
string sErr = BaseRegex.GetStringJson(ref jsonStr, "error_msg");
|
|
if (!string.IsNullOrWhiteSpace(sErr) && !errMsg.Contains(sErr))
|
|
errMsg += sErr + " ";
|
|
page++;
|
|
continue;
|
|
}
|
|
|
|
if (jsonStr.Contains("\"success\":true"))
|
|
{
|
|
var jArr = new JArray();
|
|
try
|
|
{
|
|
var jObj = JObject.Parse(jsonStr);
|
|
jArr = jObj["result"]?["goods_list"] as JArray;
|
|
if (jArr == null)
|
|
jArr = new JArray();
|
|
}
|
|
catch (Exception ex) { BaseMsgForm.ShowError(ex.Message); }
|
|
foreach (var item in jArr)
|
|
{
|
|
string sItem = item.ToString();
|
|
PDDShopListProductInfo pInfo = JsonHelper.DeserializeJsonToObject<PDDShopListProductInfo>(sItem); // 反序列化得到类
|
|
pInfo.shopId = shop.ShopId;
|
|
pInfo.shopName = shop.ShopAccount;
|
|
if (pInfo != null && !lstPDDShopListProductInfo.Any(a => a.id == pInfo.id))
|
|
{
|
|
lstPDDShopListProductInfo.Add(pInfo);
|
|
|
|
string url = pInfo.hd_url;
|
|
if (string.IsNullOrEmpty(url))
|
|
url = pInfo.image_url;
|
|
if (string.IsNullOrEmpty(url))
|
|
url = pInfo.hd_thumb_url;
|
|
if (string.IsNullOrEmpty(url))
|
|
url = pInfo.thumb_url;
|
|
Invoke(new Action(() =>
|
|
{
|
|
int rowId = this.dgvProduct.Rows.Add(
|
|
true,
|
|
shop.ShopId,
|
|
shop.ShopAccount,
|
|
url.Replace("https", "http"),
|
|
null, // 列表图片
|
|
pInfo.id,
|
|
pInfo.out_goods_sn,
|
|
pInfo.goods_name,
|
|
string.Join("~", pInfo.sku_group_price.Select(s => s / 100m)),
|
|
pInfo.quantity,
|
|
"", //收藏
|
|
"", //总销量
|
|
"", //30日销量
|
|
BaseClass.StampToDateTime(pInfo.created_at.ParseToInt()),
|
|
pInfo.is_onsale == true ? "在售" : "下架",
|
|
(pInfo.edit_check == null || pInfo.edit_check.check_status != 3)? "" : "商品修改被驳回",
|
|
"" // 操作结果,状态
|
|
);
|
|
|
|
dgvProduct.Rows[rowId].Height = 60;
|
|
}));
|
|
}
|
|
}
|
|
|
|
int total = BaseRegex.GetStringJson(ref jsonStr, "total").ParseToInt();
|
|
totalPage = Math.Ceiling(1m * total / pageSize).ParseToInt();
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
this.statusBar.lblTaskStatus.Text = "正在查询... 店铺:" + shop.ShopAccount + " 共有 " + cmbStatus.Text + " 商品:" + total;
|
|
}));
|
|
}
|
|
}
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
var rows = this.dgvShop.Rows.Cast<DataGridViewRow>().Where(r => r.Cells["colShopId"].Value.ToString() == shop.ShopId);
|
|
|
|
if (!isError)
|
|
{
|
|
foreach (var row in rows)
|
|
{
|
|
row.Cells["colMessage"].Value = "已查询";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var row in rows)
|
|
{
|
|
row.Cells["colMessage"].Value = "查询失败 " + errMsg;
|
|
}
|
|
}
|
|
}));
|
|
}
|
|
Invoke(new Action(() =>
|
|
{
|
|
ucGroupBoxEx2.Enabled = true;
|
|
string sRst = "查询结束!";
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
sRst = "已取消查询!";
|
|
|
|
BaseMsgForm.ShowInfo(sRst);
|
|
//this.statusBar.lblTaskStatus.Text = sRst;
|
|
this.statusBar.lblTaskStatus.Text = this.statusBar.lblTaskStatus.Text.Replace("正在查询...", sRst);
|
|
}));
|
|
}, cancellationTokenSource.Token);
|
|
}
|
|
|
|
|
|
private string shop_goods_search(ShopLoginInfo shop, List<string> goods_id_list, string goods_name,
|
|
List<string> out_goods_sn_list = null, List<string> out_sku_sns = null, int? isOnsale = null, long? minPrice=null, long? maxPrice=null, int page=1, int pageSize = 100)
|
|
{
|
|
var anti = shop.AntiContents.LastOrDefault().ParseToString();
|
|
if (shop.AntiContents.Count > 0)
|
|
anti = shop.AntiContents[Randomx.GetId(shop.AntiContents.Count)];
|
|
string url = "https://mms.pinduoduo.com/vodka/v2/mms/query/display/mall/goodsList";
|
|
Dictionary<string, object> dicParam = new Dictionary<string, object>();
|
|
dicParam["out_goods_sn_gray_flag"] = true;
|
|
dicParam["pre_sale_type"] = 4;
|
|
dicParam["page"] = page;
|
|
dicParam["shipment_time_type"] = 3;
|
|
if (isOnsale != null)
|
|
dicParam["is_onsale"] = isOnsale;
|
|
if (goods_id_list != null)
|
|
dicParam["goods_id_list"] = goods_id_list;
|
|
if (out_goods_sn_list != null)
|
|
dicParam["out_goods_sn_list"] = out_goods_sn_list;
|
|
if (!string.IsNullOrEmpty(goods_name))
|
|
dicParam["goods_name"] = goods_name;
|
|
if (out_sku_sns != null)
|
|
dicParam["out_sku_sns"] = out_sku_sns;
|
|
dicParam["sold_out"] = 0;
|
|
dicParam["size"] = pageSize;
|
|
if (minPrice != null || maxPrice != null)
|
|
{
|
|
long[] nArr = new long[] { 0, 1000000000 };
|
|
if (minPrice != null)
|
|
nArr[0] = minPrice.Value;
|
|
if (maxPrice != null)
|
|
nArr[1] = maxPrice.Value;
|
|
dicParam["sku_price_range"] = nArr;
|
|
}
|
|
string body = JsonHelper.SerializeObject(dicParam); //"{\"out_goods_sn_gray_flag\":true,\"pre_sale_type\":4,\"page\":1,\"shipment_time_type\":3,\"is_onsale\":1,\"sold_out\":0," + "\"size\":" + pageSize + "}";
|
|
|
|
string refere = "https://mms.pinduoduo.com/goods/goods_list?msfrom=mms_sidenav";
|
|
|
|
var result = HttpResponseBLL.PDDPostResponse(shop, url, body, refere, anti);
|
|
for (int i = 0; i < 5 && (result.Contains("当前请求频繁,请2小时后重试") || result.Contains("网络繁忙,请不要频繁操作") || result.Contains("您的店铺操作过于频繁,请稍后操作")); i++)
|
|
{
|
|
shop.AntiContents.Remove(anti);
|
|
anti = shop.AntiContents.FirstOrDefault().ParseToString();
|
|
if (shop.AntiContents.Count > 0)
|
|
{
|
|
Thread.Sleep(Randomx.GetId(500, 1500));
|
|
anti = shop.AntiContents[Randomx.GetId(shop.AntiContents.Count)];
|
|
result = HttpResponseBLL.PDDPostResponse(shop, url, body, refere, anti);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public string up_goods(ShopLoginInfo shop, string prodIds)
|
|
{
|
|
var anti = shop.AntiContents.LastOrDefault().ParseToString();
|
|
if (shop.AntiContents.Count > 0)
|
|
anti = shop.AntiContents[Randomx.GetId(shop.AntiContents.Count)];
|
|
string url = "https://mms.pinduoduo.com/vodka/v2/mms/batchOnSale";
|
|
string body = @"{""goodsIds"":[" + prodIds + @"],""crawlerInfo"":""" + anti + @"""}";
|
|
|
|
string refere = "https://mms.pinduoduo.com/goods/goods_list?msfrom=mms_sidenav&activeKeyNew=key_4";
|
|
|
|
var result = HttpResponseBLL.PDDPostResponse(shop, url, body, refere, anti);
|
|
for (int i = 0; i < 5 && (result.Contains("网络繁忙,请不要频繁操作") || result.Contains("您的店铺操作过于频繁,请稍后操作")); i++)
|
|
{
|
|
shop.AntiContents.Remove(anti);
|
|
anti = shop.AntiContents.FirstOrDefault().ParseToString();
|
|
if (shop.AntiContents.Count > 0)
|
|
{
|
|
Thread.Sleep(Randomx.GetId(500, 1500));
|
|
anti = shop.AntiContents[Randomx.GetId(shop.AntiContents.Count)];
|
|
body = @"{""goodsIds"":" + prodIds + @",""crawlerInfo"":""" + anti + @"""}";
|
|
result = HttpResponseBLL.PDDPostResponse(shop, url, body.Replace("0asAntiContent", anti), refere, anti);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public string down_goods(ShopLoginInfo shop, string prodIds)
|
|
{
|
|
var anti = shop.AntiContents.LastOrDefault().ParseToString();
|
|
if (shop.AntiContents.Count > 0)
|
|
anti = shop.AntiContents[Randomx.GetId(shop.AntiContents.Count)];
|
|
string url = "https://mms.pinduoduo.com/vodka/v2/mms/batchOffSale";
|
|
string body = @"{""goodsIds"":[" + prodIds + @"],""crawlerInfo"":""" + anti + @"""}";
|
|
|
|
string refere = "https://mms.pinduoduo.com/goods/goods_list?msfrom=mms_sidenav";
|
|
|
|
var result = HttpResponseBLL.PDDPostResponse(shop, url, body, refere, anti);
|
|
for (int i = 0; i < 5 && (result.Contains("网络繁忙,请不要频繁操作") || result.Contains("您的店铺操作过于频繁,请稍后操作")); i++)
|
|
{
|
|
shop.AntiContents.Remove(anti);
|
|
anti = shop.AntiContents.FirstOrDefault().ParseToString();
|
|
if (shop.AntiContents.Count > 0)
|
|
{
|
|
Thread.Sleep(Randomx.GetId(500, 1500));
|
|
anti = shop.AntiContents[Randomx.GetId(shop.AntiContents.Count)];
|
|
body = @"{""goodsIds"":" + prodIds + @",""crawlerInfo"":""" + anti + @"""}";
|
|
result = HttpResponseBLL.PDDPostResponse(shop, url, body.Replace("0asAntiContent", anti), refere, anti);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public string del_goods(ShopLoginInfo shop, string prodIds)
|
|
{
|
|
var anti = shop.AntiContents.LastOrDefault().ParseToString();
|
|
if (shop.AntiContents.Count > 0)
|
|
anti = shop.AntiContents[Randomx.GetId(shop.AntiContents.Count)];
|
|
string url = "https://mms.pinduoduo.com/plutus/api/plutus/bin/goods/delete/batch";
|
|
string body = @"{""goods_ids"":[" + prodIds + @"]}";
|
|
|
|
string refere = "https://mms.pinduoduo.com/goods/goods_list?msfrom=mms_sidenav&activeKeyNew=key_4";
|
|
|
|
var result = HttpResponseBLL.PDDPostResponse(shop, url, body, refere, anti);
|
|
for (int i = 0; i < 5 && (result.Contains("网络繁忙,请不要频繁操作") || result.Contains("您的店铺操作过于频繁,请稍后操作")); i++)
|
|
{
|
|
shop.AntiContents.Remove(anti);
|
|
anti = shop.AntiContents.FirstOrDefault().ParseToString();
|
|
if (shop.AntiContents.Count > 0)
|
|
{
|
|
Thread.Sleep(Randomx.GetId(500, 1500));
|
|
anti = shop.AntiContents[Randomx.GetId(shop.AntiContents.Count)];
|
|
body = @"{""goodsIds"":" + prodIds + @",""crawlerInfo"":""" + anti + @"""}";
|
|
result = HttpResponseBLL.PDDPostResponse(shop, url, body.Replace("0asAntiContent", anti), refere, anti);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
private void btnCancel_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.cancellationTokenSource != null)
|
|
this.cancellationTokenSource.Cancel();
|
|
}
|
|
|
|
private void btnDown_Click(object sender, EventArgs e)
|
|
{
|
|
var selectIds = dgvProduct.Rows.Cast<DataGridViewRow>()
|
|
.Where(row => row.Cells["colCheck"]?.Value.ParseToBool() == true)
|
|
.Select(r => r.Cells["colSpuId"]?.Value.ToString()).ToList();
|
|
var prodLst = lstPDDShopListProductInfo.Where(p => selectIds.Contains(p.id.ParseToString())).ToList();
|
|
var shopIdLst = prodLst.Select(p => p.shopId).Distinct().ToList();
|
|
var shopLst = GlobalConfig.ShopLoginList.Where(s => shopIdLst.Contains(s.ShopId)).ToList();
|
|
|
|
if (prodLst.Count == 0 || shopLst.Count == 0)
|
|
{
|
|
BaseMsgForm.ShowInfo("请选择店铺商品!");
|
|
return;
|
|
}
|
|
|
|
ucGroupBoxEx2.Enabled = false;
|
|
cancellationTokenSource = new CancellationTokenSource();
|
|
Task.Run(() =>
|
|
{
|
|
foreach (var shop in shopLst)
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
var shopProdLst = prodLst.Where(p => p.shopId == shop.ShopId).ToList();
|
|
PDDShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false);
|
|
if (shop.LoginStatus != "登录成功")
|
|
{
|
|
foreach (var prod in shopProdLst)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "店铺掉线";
|
|
}
|
|
continue;
|
|
}
|
|
|
|
while (shopProdLst.Count > 0)
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
GetToken(shop);
|
|
|
|
var shopProdLstTmp = shopProdLst;
|
|
if (shopProdLstTmp.Count > 100)
|
|
shopProdLstTmp = shopProdLst.Take(100).ToList();
|
|
else
|
|
shopProdLstTmp = shopProdLst.Take(shopProdLst.Count).ToList();
|
|
var ids = string.Join(",", shopProdLstTmp.Select(p => p.id));
|
|
|
|
var result = down_goods(shop, ids);
|
|
for (int i = 0; i < 3 && result.Contains("http error:500"); i++)
|
|
{
|
|
Thread.Sleep(Randomx.GetId(6000, 15000));
|
|
result = down_goods(shop, ids);
|
|
}
|
|
if (result.Contains("会话已过期"))
|
|
{
|
|
shop.LoginStatus = "未登录";
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLst)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "店铺掉线";
|
|
}
|
|
}));
|
|
break;
|
|
}
|
|
if (!result.Contains("\"success\":true"))
|
|
{
|
|
var errMsg = BaseRegex.GetStringJson(ref result, "error_msg");
|
|
if (string.IsNullOrEmpty(errMsg))
|
|
errMsg = result;
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = errMsg;
|
|
}
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
prod.is_onsale = false;
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "已提交下架";
|
|
row.Cells["colIsOnSale"].Value = "下架";
|
|
}
|
|
}));
|
|
}
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
shopProdLst.Remove(prod);
|
|
}
|
|
Thread.Sleep(Randomx.GetId(4500, 7500));
|
|
}
|
|
}
|
|
Invoke(new Action(() =>
|
|
{
|
|
ucGroupBoxEx2.Enabled = true;
|
|
string sRst = "下架已结束!";
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
sRst = "已取消下架!";
|
|
|
|
BaseMsgForm.ShowInfo(sRst);
|
|
this.statusBar.lblTaskStatus.Text = sRst;
|
|
}));
|
|
}, cancellationTokenSource.Token);
|
|
}
|
|
|
|
private void btnUp_Click(object sender, EventArgs e)
|
|
{
|
|
var selectIds = dgvProduct.Rows.Cast<DataGridViewRow>()
|
|
.Where(row => row.Cells["colCheck"]?.Value.ParseToBool() == true)
|
|
.Select(r => r.Cells["colSpuId"]?.Value.ToString()).ToList();
|
|
var prodLst = lstPDDShopListProductInfo.Where(p => selectIds.Contains(p.id.ParseToString())).ToList();
|
|
var shopIdLst = prodLst.Select(p => p.shopId).Distinct().ToList();
|
|
var shopLst = GlobalConfig.ShopLoginList.Where(s => shopIdLst.Contains(s.ShopId)).ToList();
|
|
|
|
if (prodLst.Count == 0 || shopLst.Count == 0)
|
|
{
|
|
BaseMsgForm.ShowInfo("请选择店铺商品!");
|
|
return;
|
|
}
|
|
|
|
ucGroupBoxEx2.Enabled = false;
|
|
cancellationTokenSource = new CancellationTokenSource();
|
|
Task.Run(() =>
|
|
{
|
|
foreach (var shop in shopLst)
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
var shopProdLst = prodLst.Where(p => p.shopId == shop.ShopId).ToList();
|
|
PDDShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false);
|
|
if (shop.LoginStatus != "登录成功")
|
|
{
|
|
foreach (var prod in shopProdLst)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "店铺掉线";
|
|
}
|
|
continue;
|
|
}
|
|
|
|
//while (shopProdLst.FirstOrDefault(p=>p.is_onsale == true) != null)
|
|
//{
|
|
// var prod = shopProdLst.FirstOrDefault(p => p.is_onsale == true);
|
|
// var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
// row.Cells["colOpResult"].Value = "已在售无需上架";
|
|
// shopProdLst.Remove(prod);
|
|
//}
|
|
while (shopProdLst.Count > 0)
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
GetToken(shop);
|
|
|
|
var shopProdLstTmp = shopProdLst;
|
|
if (shopProdLstTmp.Count > 100)
|
|
shopProdLstTmp = shopProdLst.Take(100).ToList();
|
|
else
|
|
shopProdLstTmp = shopProdLst.Take(shopProdLst.Count).ToList();
|
|
var ids = string.Join(",", shopProdLstTmp.Select(p => p.id));
|
|
|
|
var result = up_goods(shop, ids);
|
|
for (int i = 0; i < 3 && result.Contains("http error:500"); i++)
|
|
{
|
|
Thread.Sleep(Randomx.GetId(6000, 15000));
|
|
result = up_goods(shop, ids);
|
|
}
|
|
if (result.Contains("会话已过期"))
|
|
{
|
|
shop.LoginStatus = "未登录";
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLst)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "店铺掉线";
|
|
}
|
|
}));
|
|
break;
|
|
}
|
|
if (!result.Contains("\"success\":true"))
|
|
{
|
|
var errMsg = BaseRegex.GetStringJson(ref result, "error_msg");
|
|
if (string.IsNullOrEmpty(errMsg))
|
|
errMsg = result;
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = errMsg;
|
|
}
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
prod.is_onsale = true;
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "已提交上架";
|
|
row.Cells["colIsOnSale"].Value = "在售";
|
|
}
|
|
}));
|
|
}
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
shopProdLst.Remove(prod);
|
|
}
|
|
Thread.Sleep(Randomx.GetId(4500, 7500));
|
|
}
|
|
}
|
|
Invoke(new Action(() =>
|
|
{
|
|
ucGroupBoxEx2.Enabled = true;
|
|
string sRst = "上架已结束!";
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
sRst = "已取消上架!";
|
|
|
|
BaseMsgForm.ShowInfo(sRst);
|
|
this.statusBar.lblTaskStatus.Text = sRst;
|
|
}));
|
|
}, cancellationTokenSource.Token);
|
|
}
|
|
|
|
public void GetToken(ShopLoginInfo shop)
|
|
{
|
|
if (!dicShopGetCount.Keys.Contains(shop))
|
|
dicShopGetCount[shop] = 100;
|
|
else
|
|
dicShopGetCount[shop]++;
|
|
if (dicShopGetCount[shop] > 5)
|
|
{
|
|
dicShopGetCount[shop] = 0;
|
|
|
|
PDDShopLoginForm loginForm = null;
|
|
Invoke(new Action(() =>
|
|
{
|
|
this.panel1.SendToBack();
|
|
loginForm = new PDDShopLoginForm(shop);
|
|
loginForm.TopLevel = false;
|
|
loginForm.openType = EnumOpenType.manage;
|
|
loginForm.WindowState = FormWindowState.Maximized;
|
|
loginForm.InitUrl = "https://mms.pinduoduo.com/goods/goods_list?msfrom=mms_sidenav";
|
|
loginForm.Dock = DockStyle.Fill;
|
|
this.panel1.Controls.Add(loginForm);
|
|
loginForm.Show();
|
|
}));
|
|
Thread.Sleep(Randomx.GetId(3000, 5000));
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
if (loginForm != null)
|
|
loginForm.Close();
|
|
}));
|
|
}
|
|
}
|
|
|
|
private void btnDelSelect_Click(object sender, EventArgs e)
|
|
{
|
|
var selectIds = dgvProduct.Rows.Cast<DataGridViewRow>()
|
|
.Where(row => row.Cells["colCheck"]?.Value.ParseToBool() == true)
|
|
.Select(r => r.Cells["colSpuId"]?.Value.ToString()).ToList();
|
|
var prodLst = lstPDDShopListProductInfo.Where(p => selectIds.Contains(p.id.ParseToString())).ToList();
|
|
var shopIdLst = prodLst.Select(p => p.shopId).Distinct().ToList();
|
|
var shopLst = GlobalConfig.ShopLoginList.Where(s => shopIdLst.Contains(s.ShopId)).ToList();
|
|
|
|
if (prodLst.Count == 0 || shopLst.Count == 0)
|
|
{
|
|
BaseMsgForm.ShowInfo("请选择店铺商品!");
|
|
return;
|
|
}
|
|
|
|
ucGroupBoxEx2.Enabled = false;
|
|
cancellationTokenSource = new CancellationTokenSource();
|
|
Task.Run(() =>
|
|
{
|
|
foreach (var shop in shopLst)
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
var shopProdLst = prodLst.Where(p => p.shopId == shop.ShopId).ToList();
|
|
PDDShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false);
|
|
if (shop.LoginStatus != "登录成功")
|
|
{
|
|
foreach (var prod in shopProdLst)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "店铺掉线";
|
|
}
|
|
continue;
|
|
}
|
|
|
|
while (shopProdLst.Count > 0)
|
|
{
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
break;
|
|
|
|
GetToken(shop);
|
|
|
|
var shopProdLstTmp = shopProdLst;
|
|
if (shopProdLstTmp.Count > 100)
|
|
shopProdLstTmp = shopProdLst.Take(100).ToList();
|
|
else
|
|
shopProdLstTmp = shopProdLst.Take(shopProdLst.Count).ToList();
|
|
var ids = string.Join(",", shopProdLstTmp.Select(p => p.id));
|
|
|
|
string result = "";
|
|
// 先下架
|
|
if (shopProdLstTmp.Any(p => p.is_onsale == true))
|
|
{
|
|
result = down_goods(shop, ids);
|
|
for (int i = 0; i < 3 && (result.Contains("http error:500") || result.Contains("请求method,argument,body错误")); i++)
|
|
{
|
|
Thread.Sleep(Randomx.GetId(6000, 15000));
|
|
result = down_goods(shop, ids);
|
|
}
|
|
if (result.Contains("会话已过期"))
|
|
{
|
|
shop.LoginStatus = "未登录";
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLst)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "店铺掉线";
|
|
}
|
|
}));
|
|
break;
|
|
}
|
|
if (!result.Contains("\"success\":true"))
|
|
{
|
|
var errMsg = BaseRegex.GetStringJson(ref result, "error_msg");
|
|
if (string.IsNullOrEmpty(errMsg) || errMsg.Length <= 2)
|
|
errMsg = result;
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = errMsg;
|
|
}
|
|
}));
|
|
}
|
|
Thread.Sleep(Randomx.GetId(4000, 7000));
|
|
}
|
|
// 删除
|
|
result = del_goods(shop, ids);
|
|
for (int i = 0; i < 3 && result.Contains("http error:500"); i++)
|
|
{
|
|
Thread.Sleep(Randomx.GetId(6000, 15000));
|
|
result = del_goods(shop, ids);
|
|
}
|
|
if (result.Contains("会话已过期"))
|
|
{
|
|
shop.LoginStatus = "未登录";
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLst)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "店铺掉线";
|
|
}
|
|
}));
|
|
break;
|
|
}
|
|
if (!result.Contains("\"success\":true"))
|
|
{
|
|
result = GetHtml.Unicode2String(result);
|
|
var errMsg = BaseRegex.GetStringJson(ref result, "error_msg");
|
|
if (string.IsNullOrEmpty(errMsg) || errMsg.Length <= 2)
|
|
errMsg = result;
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = errMsg;
|
|
}
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
Invoke(new Action(() =>
|
|
{
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
var row = dgvProduct.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => prod.id.ToString() == r.Cells["colSpuId"]?.Value.ToString());
|
|
row.Cells["colOpResult"].Value = "已提交删除";
|
|
row.Cells["colIsOnSale"].Value = "已删除";
|
|
}
|
|
}));
|
|
}
|
|
foreach (var prod in shopProdLstTmp)
|
|
{
|
|
shopProdLst.Remove(prod);
|
|
}
|
|
Thread.Sleep(Randomx.GetId(4500, 7500));
|
|
}
|
|
}
|
|
Invoke(new Action(() =>
|
|
{
|
|
ucGroupBoxEx2.Enabled = true;
|
|
string sRst = "删除已结束!";
|
|
if (cancellationTokenSource.IsCancellationRequested)
|
|
sRst = "已取消删除!";
|
|
|
|
BaseMsgForm.ShowInfo(sRst);
|
|
this.statusBar.lblTaskStatus.Text = sRst;
|
|
}));
|
|
}, cancellationTokenSource.Token);
|
|
}
|
|
|
|
private void btnClearDgv_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void pnlEmpty_Click(object sender, EventArgs e)
|
|
{
|
|
cmbStatus.Text = "在售";
|
|
txtSPU.Text = txtGoodsName.Text = txtExtCode.Text = txtSkuSns.Text = txtMinPrice.Text = txtMaxPrice.Text = "";
|
|
}
|
|
}
|
|
}
|