Files
KJD_WebService/TEMUKJD/KJDForms/UploadForms/SpecialDelaySendForm.cs
T
2025-06-29 19:38:31 +08:00

558 lines
26 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 CefSharp.WinForms;
using LittleRabbit.Extension;
using LittleRabbit.LittleRabbitForms.BaseForms;
using NaiBa.CefHelper;
using NaiBa.CefHelper.Handler;
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 Work.DouyinApiClass;
namespace LittleRabbit.LittleRabbitForms.UploadForms
{
public partial class SpecialDelaySendForm : Form
{
private CheckBox chkSelectAll = null;
bool isNotOperateDays = true;
public DateTime notOperateDate = DateTime.Now.Date.AddDays(-7);
CancellationTokenSource cancellationTokenSource = null;
ChromiumWebBrowser webBrowser = null;
int operateCount = 999999;
string keyWords = "";
bool isRun = false;
public SpecialDelaySendForm()
{
InitializeComponent();
}
private void btnRefresh_Click(object sender, EventArgs e)
{
LoadShops();
}
private void SpecialDelaySendForm_VisibleChanged(object sender, EventArgs e)
{
if (Visible)
LoadShops();
}
private void txtNotOperateDays_TextChanged(object sender, EventArgs e)
{
if (txtNotOperateDays.ParseToInt() > 15)
txtNotOperateDays.Text = "15";
}
public void LoadShops()
{
for (int i = 0; i < GlobalConfig.DouShopLoginList.Count; i++)
{
var shop = GlobalConfig.DouShopLoginList[i];
var row = dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value?.ToString() == shop.ShopAccountId);
if (row == null)
dgvShop.Rows.Add(false, shop.ShopAccountId, shop.ShopAccount, shop.LoginStatus == "登录成功" && shop.ApiAuthStatus == "授权成功" ? "可用" : "");
else
{
row.Cells["colLoginStatus"].Value = shop.LoginStatus;
}
}
}
public string GetShopProductListData(DouShopLoginInfo shop, int productStatus = 0, int page = 1, int pageSize = 50)
{
// 读取在售商品数量
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("page", page.ToString());
dictionary.Add("size", pageSize.ToString());
if (productStatus == 0)
dictionary.Add("check_status", "3");
dictionary["status"] = productStatus.ToString();
DouyinApi douApi = new DouyinApi(shop);
douApi.JsonData = dictionary;
var resultOnline = douApi.GetProductList();
return resultOnline;
}
void GetShopProduct(DouShopLoginInfo shop, bool isShowResult = true)
{
DataGridViewRow row = null;
Invoke(new Action(() =>
{
row = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ToString() == shop.ShopAccountId);
if (row != null)
{
if (isShowResult)
row.Cells["colMessage"].Value = "正在获取店铺商品数量";
}
}));
// 读取在售商品数量
var resultOnline = GetShopProductListData(shop, 0, 1, 10);
if (resultOnline.Contains("\"code\":10000"))
{
if (row != null)
{
var text = BaseRegex.GetStringJson(ref resultOnline, "total");
shop.OnlineProductCount = text.ParseToInt();
Invoke(new Action(() =>
{
//row.Cells["colOnSaleCount"].Value = string.IsNullOrEmpty(text) ? "" : text;
}));
}
}
// 读取下架商品数量
var resultOffline = GetShopProductListData(shop, 1, 1, 10);
if (resultOffline.Contains("\"code\":10000"))
{
if (row != null)
{
var text = BaseRegex.GetStringJson(ref resultOffline, "total");
shop.OfflineProductCount = text.ParseToInt();
Invoke(new Action(() =>
{
//row.Cells["colOffSaleCount"].Value = string.IsNullOrEmpty(text) ? "" : text;
}));
}
}
string resultShowText = "";
if (resultOnline.Contains("\"code\":10000") && resultOffline.Contains("\"code\":10000"))
{
resultShowText = "商品数量获取成功";
}
else
{
resultShowText = "商品数量获取失败";
if (!resultOnline.Contains("\"code\":10000"))
{
var html = BaseRegex.GetStringJson(ref resultOnline, "sub_msg");
if (string.IsNullOrEmpty(html))
html = resultOnline;
resultShowText += ",获取在售商品错误:" + html;
}
if (!resultOffline.Contains("\"code\":10000"))
{
var html = BaseRegex.GetStringJson(ref resultOffline, "sub_msg");
if (string.IsNullOrEmpty(html))
html = resultOffline;
resultShowText += ",获取仓库商品错误:" + html;
}
}
Invoke(new Action(() =>
{
if (row != null)
{
if (isShowResult)
row.Cells["colMessage"].Value = resultShowText;
}
}));
}
private void btnStart_Click(object sender, EventArgs e)
{
this.operateCount = this.txtTotalCount.Text.ParseToInt();
var shopIds = this.dgvShop.Rows.Cast<DataGridViewRow>().Where(r => r.Cells["colSelect"].Value.ParseToBool() == true)
.Select(r => r.Cells["colShopId"].Value?.ToString()).ToList();
var shops = GlobalConfig.DouShopLoginList.Where(s => shopIds.Contains(s.ShopAccountId)).ToList();
if (shops.Count == 0)
{
BaseMsgForm.ShowError("请选择要操作的店铺");
return;
}
isRun = true;
isNotOperateDays = chkIsNotOperateDays.Checked;
notOperateDate = DateTime.Now.Date.AddDays(0 - this.txtNotOperateDays.Text.ParseToInt());
btnStart.Enabled = false;
cancellationTokenSource = new CancellationTokenSource();
SetDelaySendCef(shops);
Task.Run(() =>
{
Thread.Sleep(8000);
Invoke(new Action(() => { btnStart.Enabled = true; }));
});
}
void SetDelaySendCef(List<DouShopLoginInfo> shops)
{
Task.Run(() =>
{
InitCef();
while (!webBrowser.IsBrowserInitialized || webBrowser.IsLoading)
continue;
for (int num = 0; num < shops.Count; num++)
{
Thread.Sleep(500);
var shop = shops[num];
if (shop == null)
{
continue;
}
if (!isRun)
{
Invoke(new Action(() =>
{
var row1 = dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value?.ToString() == shop.ShopAccountId);
if (row1 != null)
row1.Cells["colMessage"].Value = "设置中断";
}));
break;
}
Invoke(new Action(() =>
{
this.statusBar.pgbTaskProgress.Maximum = shops.Count;
this.statusBar.lblTaskStatus.Text = "正在获取店铺:" + shop.ShopAccount + "商品";
this.statusBar.pgbTaskProgress.Value = (num + 1);
this.statusBar.pgbTaskProgress.Text = (num + 1) + "/" + shops.Count;
}));
// 获取商品数
GetShopProduct(shop);
int totalNumBase = shop.OnlineProductCount; // 下架开始时的在售商品数
int totalNum = shop.OnlineProductCount; // 在售商品数
int setNum = 0; // 下架商品数量(因关键词存在因此少于或等于商品循环计数)
int currentNum = 0; // 商品循环计数
int page = 0;
int pageSize = 50;
string offSaleMessage = "";
List<DouProductListInfo> productList = new List<DouProductListInfo>();
var onlineProductHtml = "";
while ((currentNum < operateCount && currentNum < totalNumBase) || page == 0)
{
page += 1;
currentNum += pageSize;
if (cancellationTokenSource != null && cancellationTokenSource.IsCancellationRequested)
{
var row = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ToString() == shop.ShopAccountId);
if (row != null) { Invoke(new Action(() => { row.Cells["colMessage"].Value = "下架中断"; })); }
break;
}
// 获取商品列表
onlineProductHtml = GetShopProductListData(shop, 0, page);
Thread.Sleep(Randomx.GetId(500, 1000));
if (onlineProductHtml.Contains("\"code\":10000"))
{
totalNum = BaseRegex.GetIntJson(ref onlineProductHtml, "total");
shop.OfflineProductCount = totalNum;
if (operateCount > totalNumBase)
operateCount = totalNumBase;
if (currentNum > totalNumBase)
currentNum = totalNumBase;
Invoke(new Action(() =>
{
var row = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ToString() == shop.ShopAccountId);
if (row != null)
{
//row.Cells["colOnSaleCount"].Value = totalNumBase;
}
}));
if (totalNum == 0)
{
offSaleMessage = "设置结束,店铺没有在售的商品";
Invoke(new Action(() =>
{
var row = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ToString() == shop.ShopAccountId);
if (row != null) { row.Cells["colMessage"].Value = offSaleMessage; }
}));
break;
}
try
{
JObject jObj = JObject.Parse(onlineProductHtml);
var jObjDataStr = jObj["data"]?["data"]?.ToString();
if (!string.IsNullOrEmpty(jObjDataStr))
{
var addList = JsonHelper.DeserializeJsonToList<DouProductListInfo>(jObjDataStr);
if (addList != null)
productList.AddRange(addList);
}
offSaleMessage = "正在获取商品,第" + currentNum + "件商品,共" + operateCount + "件商品";
Invoke(new Action(() =>
{
var row = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ToString() == shop.ShopAccountId);
if (row != null) { row.Cells["colMessage"].Value = offSaleMessage; }
}));
}
catch (Exception ex)
{
BaseMsgForm.ShowError("获取商品发生错误:" + ex.Message);
}
}
else
{
var failMessage = BaseRegex.GetStringJson(ref onlineProductHtml, "sub_msg");
if (string.IsNullOrEmpty(failMessage))
failMessage = onlineProductHtml;
offSaleMessage = ("设置发货延迟失败," + failMessage).TrimEnd(',');
Invoke(new Action(() =>
{
var row = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ToString() == shop.ShopAccountId);
if (row != null) { row.Cells["colMessage"].Value = offSaleMessage; }
}));
}
}
// 有关键词的过滤符合关键词
if (keyWords.Any())
productList = productList.Where(p => keyWords.Any(key => p.name.Contains(key))).ToList();
// 只操作指定天数之前修改的商品
if (isNotOperateDays)
productList = productList.Where(p => p.update_time < BaseClass.DateTimeToTimestampSeconds(notOperateDate)).ToList();
// 操作数大于满足筛选条件商品数时,操作数改为商品数
if (operateCount > productList.Count)
operateCount = productList.Count;
for (int i = 0; i < productList.Count && i < operateCount; i++)
{
if (cancellationTokenSource != null && cancellationTokenSource.IsCancellationRequested)
{
var row = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ToString() == shop.ShopAccountId);
if (row != null) { Invoke(new Action(() => { row.Cells["colMessage"].Value = "设置发货延迟中断"; })); }
break;
}
Invoke(new Action(() =>
{
offSaleMessage = "正在设置发货延迟,第 " + (i + 1) + " 件商品,共 " + operateCount + " 件商品";
var row = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ToString() == shop.ShopAccountId);
if (row != null) { row.Cells["colMessage"].Value = offSaleMessage; }
this.statusBar.lblTaskStatus.Text = offSaleMessage;
}));
Thread.Sleep(50);
var product = productList[i];
setNum++;
var pid = product.product_id;
var cid = product.category_detail.fourth_cid;
if (cid == 0)
cid = product.category_detail.third_cid;
if (cid == 0)
cid = product.category_detail.second_cid;
if (cid == 0)
cid = product.category_detail.first_cid;
Thread.Sleep(Randomx.GetId(100, 300));
var cookie = shop.Cookies;
CEFBrowser.DeleteCookie(webBrowser.RequestContext.GetCookieManager(null));
var t = CEFBrowser.SetCookieAsync("jinritemai.com", cookie, webBrowser.RequestContext.GetCookieManager(null));
t.Wait(2000);
Thread.Sleep(500);
this.webBrowser.Load("https://fxg.jinritemai.com/ffa/g/create?product_id=" + pid + "&cid=" + cid + "&entrance=edit");
Thread.Sleep(3000);
while (webBrowser.IsLoading)
{
Thread.Sleep(1000);
}
var jsStr = getJsElementStr +
"function getPos(elem) { var box = elem;" +
"if (box == null) return '-|-';" +
"var actualLeft = box.offsetLeft;" +
"var actualTop = box.offsetTop;" +
"var current = box.offsetParent;" +
"while (current !== null) { actualLeft += current.offsetLeft; actualTop += current.offsetTop; current = current.offsetParent; }" +
"return '' + actualLeft + '|' + actualTop;}\r\n" +
"getPos(getElement('特殊日期延迟发货时间'));";
var result = "";
for (int x = 0; x < 100 && string.IsNullOrEmpty(result); x++)
{
var task = webBrowser.GetBrowser().MainFrame.EvaluateScriptAsync(jsStr);
task.Wait();
result = task.Result?.Result?.ToString();
Thread.Sleep(1000);
}
Thread.Sleep(3000);
if (string.IsNullOrEmpty(result) || result == "-|-")
{
continue;
}
jsStr = "document.getElementById('goodsEditScrollContainer').scrollTop = " + result.Split('|').LastOrDefault() + ";";
{
var task = webBrowser.GetBrowser().MainFrame.EvaluateScriptAsync(jsStr);
task.Wait();
result = task.Result?.Result?.ToString();
Thread.Sleep(1500);
}
jsStr = "function clickSwitchButton() { if (document.body.innerHTML.indexOf('最晚发货时间') < 0) document.getElementsByClassName('ant-switch')[0].click(); }\r\n" +
"clickSwitchButton();";
{
var task = webBrowser.GetBrowser().MainFrame.EvaluateScriptAsync(jsStr);
task.Wait();
result = task.Result?.Result?.ToString();
Thread.Sleep(1500 + Randomx.GetId(1000));
}
jsStr = "document.getElementsByClassName('ant-btn sp-tooltip ant-btn-primary')[0].click();";
{
var task = webBrowser.GetBrowser().MainFrame.EvaluateScriptAsync(jsStr);
task.Wait();
result = task.Result?.Result?.ToString();
Thread.Sleep(5000);
}
if (i == operateCount - 1)
{
offSaleMessage = "设置特殊发货时间完成";
Invoke(new Action(() =>
{
var row = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ToString() == shop.ShopAccountId);
if (row != null) { row.Cells["colMessage"].Value = offSaleMessage; }
}));
}
// 操作过程中更新显示仓库商品数
if (i % 50 == 49 || i == operateCount - 1)
GetShopProduct(shop, false);
}
}
Invoke(new Action(() =>
{
this.btnStart.Enabled = true;
if (cancellationTokenSource != null && !cancellationTokenSource.IsCancellationRequested)
{
var text = "设置特殊发货时间完成!";
//if (!string.IsNullOrEmpty(FailedMessages))
//{
// text += "部分商品设置发货延迟失败,请查看详情。";
// btnFailedDetail.Visible = true;
//}
this.statusBar.lblTaskStatus.Text = text;
BaseMsgForm.ShowInfo(text);
}
else
{
var text = "设置特殊发货时间完成!";
//if (!string.IsNullOrEmpty(FailedMessages))
//{
// text += "部分商品设置发货延迟失败,请查看详情。";
// btnFailedDetail.Visible = true;
//}
this.statusBar.lblTaskStatus.Text = text;
BaseMsgForm.ShowInfo(text);
}
}));
}, cancellationTokenSource.Token);
}
void InitCef()
{
if (webBrowser == null)
{
Invoke(new Action(() =>
{
webBrowser = CEFBrowser.CreateChromiumWebBrowser("about:blank", false);
webBrowser.KeyboardHandler = new KeyboardHandler();
webBrowser.Dock = DockStyle.Fill;
webBrowser.SendToBack();
this.panelEx1.Controls.Add(webBrowser);
}));
}
}
private void dgvShop_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0)
return;
string headerText = dgvShop.Columns[e.ColumnIndex].HeaderText;
long shopId = dgvShop.Rows[e.RowIndex].Cells["colShopId"].Value.ParseToLong();
string shopName = dgvShop.Rows[e.RowIndex].Cells["colShopId"].Value.ToString();
var shop = GlobalConfig.DouShopLoginList.FirstOrDefault(s => s.ShopAccountId == shopId.ToString());
switch (headerText)
{
case "操作":
case "全选":
case "选":
if (shop.LoginStatus == "登录成功" && shop.ApiAuthStatus == "授权成功")
{
dgvShop.Rows[e.RowIndex].Cells["colSelect"].Value = !dgvShop.Rows[e.RowIndex].Cells["colSelect"].Value.ParseToBool();
}
else
{
BaseMsgForm.ShowInfo("店铺未授权或未登录");
}
break;
}
}
private void SpecialDelaySendForm_Load(object sender, EventArgs e)
{
chkSelectAll = dgvShop.Columns["colSelect"].AddHeaderCheckBox(HorizontalAlignment.Right, 0, 0, null, null, false);
chkSelectAll.Width = chkSelectAll.Height = 13;
chkSelectAll.CheckedChanged += chkSelectAll_CheckedChanged;
}
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.DouShopLoginList.Where(s => s.ApiAuthStatus == "授权成功" && s.LoginStatus == "登录成功").Select(ss => ss.ShopAccountId);
foreach (DataGridViewRow row in dgvShop.Rows)
{
if (list.Any(l => l == row.Cells["colShopId"]?.Value?.ToString()))
row.Cells["colSelect"].Value = true;
}
}
}
public string getJsElementStr = "function getElement(txt, elem) {\r\n" +
" var child = document.body.firstElementChild;\r\n" +
" if (elem) child = elem\r\n" +
" var element1 = null;\r\n" +
" while (child) {\r\n" +
" if (child.innerHTML.indexOf(txt) >= 0) {\r\n" +
" element1 = child;\r\n" +
" if (child.firstElementChild) {\r\n" +
" child = child.firstElementChild; continue;\r\n" +
" } else break;\r\n" +
" }\r\n" +
" child = child.nextElementSibling;\r\n" +
" }\r\n" +
" if (element1) {\r\n" +
" return element1;\r\n" +
" } else return error;\r\n" +
"}\r\n";
private void btnStop_Click(object sender, EventArgs e)
{
if (cancellationTokenSource != null)
cancellationTokenSource.Cancel();
}
}
}