using AllBase; using AllBase.Helper; using AllBase.Model.Param.SalesManage; 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.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using TemuKJD.Extension; using TemuKJD.BaseForms; using TemuKJD.KJDForms.ShopForms; using TemuKJD.BLL; namespace TemuKJD.KJDForms.SalesCenterForms { public partial class MarketingActivityForm : LRBaseForm { public static MarketingActivityForm ActInstance { get; set; } = null; /// /// 单品参加活动时的单品id /// public ShopLoginInfo soloActivityShop { get; set; } = null; public WarehouseProductSubOrderInfo soloActivityProduct { get; set; } = null; private CheckBox chkSelectAll = null; public CancellationTokenSource cancellationTokenSource { get; set; } = null; public List lstActivityThematic { get; set; } = new List(); public List lstShopIdSelect = new List(); public List lstActivityThematicIdSelect = new List(); public List lstDiscount = new List() { 60, 70, 80, 85 }; public Dictionary> dicNoSaleProd = new Dictionary>(); public MarketingActivityForm() { InitializeComponent(); } public MarketingActivityForm(ShopLoginInfo shop, WarehouseProductSubOrderInfo prod) { InitializeComponent(); if(shop != null && prod != null) { this.soloActivityShop = shop; this.soloActivityProduct = prod; ActInstance = this; this.MaximizeBox = true; this.Size = new Size(1400, 850); RefreshSoloActivityCtrl(); } } /// /// 刷新单品活动控件显示 /// public void RefreshSoloActivityCtrl() { if (this.soloActivityProduct == null || this.soloActivityShop == null) return; var prod = soloActivityProduct; chkFullShop.Visible = false; chkNoSaleProd.Visible = false; chkSoloActivityProduct.Visible = true; chkSoloActivityProduct.Location = chkFullShop.Location; chkSoloActivityProduct.Text = "报名单品活动 " + (prod.productName.Length > 60 ? prod.productName.Substring(0, 60) + "……" : prod.productName); this.dgvProduct.Rows.Clear(); } private void MarketingActivityForm_Load(object sender, EventArgs e) { 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; this.dgvActivity.AddSelectorColumn("colCheckActivity"); this.dgvProduct.AddSelectorColumn("colCheckProduct"); this.actDiscount60.chkSignActivity.CheckedChanged += ChkSignActivity_CheckedChanged; this.actDiscount70.chkSignActivity.CheckedChanged += ChkSignActivity_CheckedChanged; this.actDiscount80.chkSignActivity.CheckedChanged += ChkSignActivity_CheckedChanged; this.actDiscount85.chkSignActivity.CheckedChanged += ChkSignActivity_CheckedChanged; } private void ChkSignActivity_CheckedChanged(object sender, EventArgs e) { foreach(DataGridViewRow row in dgvActivity.Rows) { SetRowCheck(row); } } void SetRowCheck(DataGridViewRow row) { try { var activityThematicName = row.Cells["colActivityThematicName"].Value.ToString(); if (activityThematicName == "官方大促") { } if (row.Cells["colDiscountTenth"].Value.ParseToInt() > 0) { int discount = this.GetNearDiscount(row.Cells["colDiscountTenth"].Value.ParseToInt()); var discountCtrl = this.actDiscount60; if (discount == 70) discountCtrl = this.actDiscount70; if (discount == 80) discountCtrl = this.actDiscount80; if (discount == 85) discountCtrl = this.actDiscount85; row.Cells["colCheckActivity"].Value = discountCtrl.chkSignActivity.Checked; } else { row.Cells["colCheckActivity"].Value = false; } } catch (Exception ex) { BaseMsgForm.ShowError("选择活动失败" + ex.Message); } } 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.LoginStatus2 == "国际版在线").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; } } } private void MarketingActivityForm_VisibleChanged(object sender, EventArgs e) { if (this.Visible) FiltShop(); } private void btnRefreshShop_Click(object sender, EventArgs e) { pbShopLoading.Visible = true; Task.Run(() => { ShopListForm.UpdateShop(); Invoke(new Action(() => { FiltShop(); pbShopLoading.Visible = false; })); }); } private void btnSearchShop_Click(object sender, EventArgs e) { FiltShop(); } private void FiltShop() { // 店铺Id var selectIds = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); var shopLst = GlobalConfig.ShopLoginList.ToList(); if (!string.IsNullOrWhiteSpace(txtShopId.Text.Trim())) { shopLst = shopLst.Where(s => ("," + txtShopId.Text.Trim() + ",").Contains("," + s.ShopId + ",") || s.ShopId.Contains(txtShopId.Text.Trim())).ToList(); } if (!string.IsNullOrWhiteSpace(txtShopName.Text.Trim())) { shopLst = shopLst.Where(s => ("," + txtShopName.Text.Trim() + ",").Contains("," + s.ShopAccount + ",") || s.ShopAccount.ToLower().Contains(txtShopName.Text.Trim().ToLower())).ToList(); } if (!string.IsNullOrWhiteSpace(txtNotes.Text.Trim())) { shopLst = shopLst.Where(s => ("," + txtNotes.Text.Trim() + ",").Contains("," + s.Notes + ",") || s.Notes.ToLower().Contains(txtNotes.Text.Trim().ToLower())).ToList(); } // 获取被删除的店铺 List dgvRowList = dgvShop.Rows.Cast().Where(row => !shopLst.Any(s => s.ShopId == row.Cells["colShopId"]?.Value?.ToString())).ToList(); // 更新被删除的店铺列表 foreach (var row in dgvRowList) { dgvShop.Rows.Remove(row); } // 绑定其他店铺(含新导入的店铺) foreach (ShopLoginInfo shopEntity in shopLst) { if (!string.IsNullOrEmpty(shopEntity.ShopId)) BindShop(shopEntity, selectIds); } } private void btnEmpty_Click(object sender, EventArgs e) { txtNotes.Text = txtShopId.Text = txtShopName.Text = ""; FiltShop(); } private void BindShop(ShopLoginInfo shopEntity, List selectShopId = null) { if (shopEntity == null) return; if (selectShopId == null) selectShopId = new List(); bool canUse = shopEntity.LoginStatus2 == "国际版在线"; var row = dgvShop.Rows.Cast().FirstOrDefault(p => p.Cells.GetCellValueFromColumnName("colShopId").ParseToString() == shopEntity.ShopId); if (row == null) { int id = this.dgvShop.Rows.Add( selectShopId.Contains(shopEntity.ShopId) && canUse, shopEntity.LoginName, shopEntity.ShopId, shopEntity.ShopAccount, shopEntity.Notes, canUse ? "在线" : "掉线", canUse, string.Empty ); row = dgvShop.Rows[id]; DisplayLoginStatus(row, canUse); } else { row.Cells["colSelect"].Value = 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["colCanUse"].Value = canUse; DisplayLoginStatus(row, canUse); } if (soloActivityShop != null && row != null) { if (row.Cells["colShopId"].Value.ParseToString() == soloActivityShop.ShopId) { row.Visible = true; row.Cells["colSelect"].Value = row.Cells["colCanUse"].Value; } else { row.Visible = false; row.Cells["colSelect"].Value = false; } } } private void DisplayLoginStatus(DataGridViewRow row, bool canUse) { (row.Cells["colLoginStatus"] as DataGridViewLinkCell).Style.ForeColor = canUse ? Color.Green : Color.Red; (row.Cells["colLoginStatus"] as DataGridViewLinkCell).LinkColor = canUse ? Color.Green : Color.Red; (row.Cells["colLoginStatus"] as DataGridViewLinkCell).ActiveLinkColor = canUse ? Color.LightGreen : Color.OrangeRed; (row.Cells["colLoginStatus"] as DataGridViewLinkCell).VisitedLinkColor = canUse ? Color.DarkGreen : Color.DarkRed; } private void dgvShop_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.ColumnIndex < 0 || e.RowIndex < 0) return; string columnName = dgvShop.Columns[e.ColumnIndex].Name; switch (columnName) { case "colSelect": dgvShop.CellContentClick -= dgvShop_CellContentClick; dgvShop_CellContentClick(sender, e); break; default: dgvShop.CellContentClick -= dgvShop_CellContentClick; dgvShop.CellContentClick += dgvShop_CellContentClick; break; } } 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; long shopId = dgvShop.Rows[e.RowIndex].Cells["colShopId"].Value.ParseToLong(); 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.ParseToBool()) { row.Cells["colSelect"].Value = !row.Cells["colSelect"].Value.ParseToBool(); chkSelectAll.CheckedChanged -= chkSelectAll_CheckedChanged; if (dgvShop.Rows.Cast().All(r => r.Cells["colSelect"].Value.ParseToBool())) chkSelectAll.Checked = true; else chkSelectAll.Checked = false; chkSelectAll.CheckedChanged += chkSelectAll_CheckedChanged; } else { BaseMsgForm.ShowInfo("店铺国际版未登录!"); } break; case "colLoginStatus": { ShopListForm.Instance.CheckShopLogin(new ShopLoginInfo[] { shop }, false); if (shop.LoginStatus2 == "国际版在线") { ShopLoginForm adminLoginForm = new ShopLoginForm(shop); adminLoginForm.openType = EnumOpenType.manage; adminLoginForm.WindowState = FormWindowState.Maximized; adminLoginForm.InitUrl = "https://agentseller.temu.com"; adminLoginForm.Show(); } else { ShopLoginForm shopLoginForm = new ShopLoginForm(shop); shopLoginForm.openType = EnumOpenType.login; shopLoginForm.ShowDialog(); FiltShop(); } } break; } } private void dgvActivity_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (e.ColumnIndex < 0 || e.RowIndex < 0) return; string headerText = dgvActivity.Columns[e.ColumnIndex].HeaderText; string columnName = dgvActivity.Columns[e.ColumnIndex].Name; long activityId = dgvActivity.Rows[e.RowIndex].Cells["colActivityThematicId"].Value.ParseToLong(); var activity = lstActivityThematic.FirstOrDefault(s => s.activityThematicId == activityId); var row = dgvActivity.Rows[e.RowIndex]; switch (columnName) { case "colCheckActivity": row.Cells["colCheckActivity"].Value = !row.Cells["colCheckActivity"].Value.ParseToBool(); //chkSelectAll.CheckedChanged -= chkSelectAll_CheckedChanged; //if (dgvShop.Rows.Cast().All(r => r.Cells["colSelect"].Value.ParseToBool())) // chkSelectAll.Checked = true; //else // chkSelectAll.Checked = false; //chkSelectAll.CheckedChanged += chkSelectAll_CheckedChanged; break; } } private void chkFullShop_CheckedChanged(object sender, EventArgs e) { if (chkFullShop.Checked) chkNoSaleProd.Checked = false; else chkNoSaleProd.Checked = true; } private void chkNoSaleProd_CheckedChanged(object sender, EventArgs e) { if (chkNoSaleProd.Checked) { chkFullShop.Checked = false; panel2.Visible = true; } else { chkFullShop.Checked = true; panel2.Visible = false; } } private void btnSearchActivity_Click(object sender, EventArgs e) { var lstShopId = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); if (lstShopId.Count == 0) { BaseMsgForm.ShowInfo("请选择店铺!"); return; } #region 重置控件 lstActivityThematic.Clear(); dgvActivity.Rows.Clear(); var dgvRows = this.dgvShop.Rows.Cast(); foreach (var row in dgvRows) { row.Cells["colMessage"].Value = ""; } ucGroupBoxEx2.Enabled = false; ucGroupBoxEx3.Enabled = false; cancellationTokenSource = new CancellationTokenSource(); #endregion Task.Run(() => { lstShopIdSelect.Clear(); lstShopIdSelect.AddRange(lstShopId); int i = 0; foreach (var shopId in lstShopIdSelect) { if (lstActivityThematic.Count > 0) break; this.Invoke(new Action(() => { this.statusBar.lblTaskStatus.Text = "正在查询活动..."; this.statusBar.pgbTaskProgress.Maximum = lstShopIdSelect.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 (!CheckLogin(shop)) continue; #endregion Invoke(new Action(() => { var rows = this.dgvShop.Rows.Cast().Where(r => r.Cells["colShopId"].Value.ToString() == shop.ShopId); foreach (var row in rows) { row.Cells["colMessage"].Value = "正在查询"; } })); int page = 1; int totalPage = 1; bool isError = false; string errMsg = ""; while (page <= totalPage) { if (cancellationTokenSource.IsCancellationRequested) break; int tryCount = 0; tryAgain: Thread.Sleep(100 + Randomx.GetId(200)); string jsonRst = GetActivityList(shop); if (jsonRst.Contains("指定的值含有无效的控制字符")) { Invoke(new Action(() => { var rows = this.dgvShop.Rows.Cast().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; DisplayLoginStatus(row, false); } })); errMsg = "店铺可能已掉线,指定的值含有无效的控制字符"; isError = true; break; } if (jsonRst.Contains("当前操作人数太多,请稍后重试") && tryCount < 5) { tryCount++; Thread.Sleep(Randomx.GetId(5000, 7000)); goto tryAgain; } if (!jsonRst.Contains("\"success\":true")) { isError = true; string sErr = BaseRegex.GetStringJson(ref jsonRst, "errorMsg"); if (!string.IsNullOrWhiteSpace(sErr) && !errMsg.Contains(sErr)) errMsg += sErr + " "; page++; continue; } if (jsonRst.Contains("\"success\":true")) { var jArr = new JArray(); try { var jObj = JObject.Parse(jsonRst); jArr = jObj["result"]?["activityList"] as JArray; if (jArr == null) jArr = new JArray(); foreach (var item in jArr) { string sItem = item.ToString(); TemuActivityInfo pActivity = JsonHelper.DeserializeJsonToObject(sItem); // 反序列化得到类 //if (pActivity == null || pActivity.activityName != "大促进阶-限时活动") // continue; if (pActivity.activityType == 51 || pActivity.activityName == "跨店满减") // 51 跨店满减平台补贴活动直接跳过 continue; if (pActivity.benefitLabelName.Contains("平台补贴")) continue; if (pActivity.activityType == 52) { } if (pActivity.thematicList.Count == 0) { pActivity.thematicList.Add(new TemuActivityThematicInfo() { activityType = pActivity.activityType, // 一级活动类型 activityTypeName = pActivity.activityName, // 一级活动名称 activityLabelDesc = pActivity.activityLabelDesc, activityLabelList = new List(), activityLabelTag = pActivity.activityLabelTag, activityThematicContent = pActivity.activityContent, activityThematicId = pActivity.activityType, activityThematicName = pActivity.activityName, benefitLabelName = pActivity.benefitLabelName, canEnrollTotal = null, discount = "", durationDays = 0, endTime = pActivity.sessionEndTime, startTime = pActivity.sessionStartTime, enrollDeadLine = null, enrolledCount = null, enrollSource = null, enrollStartAt = null, salePromotionLabel = null, sites = new List(), }); } foreach (var pActThematic in pActivity.thematicList) { pActThematic.activityType = pActivity.activityType; pActThematic.activityTypeName = pActivity.activityName; lstActivityThematic.Add(pActThematic); string name = pActThematic.activityThematicName; pActThematic.discount = BaseRegex.GetMatchRegexString(ref name, "(\\d{1,3}(\\.?\\d?)折)").ParseToString(); pActThematic.discount = pActThematic.discount.Replace("折", "").Replace(".",""); pActThematic.discount = string.IsNullOrWhiteSpace(pActThematic.discount) ? "" : pActThematic.discount; if (pActThematic.discount.Length == 1) pActThematic.discount += "0"; // 补0 } } } catch (Exception ex) { BaseMsgForm.ShowError(ex.Message); } int total = BaseRegex.GetStringJson(ref jsonRst, "total").ParseToInt(); totalPage = Math.Ceiling(total / 10.0).ParseToInt(); } page++; } Invoke(new Action(() => { var rows = this.dgvShop.Rows.Cast().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; } } })); } foreach (var actInfo in lstActivityThematic) { string sActivityTime = "-"; if (actInfo.startTime.ParseToLong() > 0 && actInfo.endTime.ParseToLong() > 0) { sActivityTime = BaseClass.StampToDateTime((int)(actInfo.startTime.ParseToLong() / 1000)).ToString("yyyy/MM/dd HH:mm:ss") + "~" + BaseClass.StampToDateTime((int)(actInfo.endTime.ParseToLong() / 1000)).ToString("yyyy/MM/dd HH:mm:ss") + "(" + (actInfo.durationDays > 0 ? actInfo.durationDays + "天" : "长期") + ")"; } string sActivityRemaining = "-"; TimeSpan timeRemaining = BaseClass.StampToDateTime((int)(actInfo.enrollDeadLine.ParseToLong() / 1000)) - DateTime.Now; if (timeRemaining.TotalSeconds > 0) { if (timeRemaining.Days >= 1) sActivityRemaining = timeRemaining.Days + "天后截止"; else if (timeRemaining.Hours >= 1) sActivityRemaining = timeRemaining.Hours + "小时后截止"; else if (timeRemaining.Minutes >= 1) sActivityRemaining = timeRemaining.Minutes + "分钟后截止"; else sActivityRemaining = timeRemaining.Seconds + "秒后截止"; } Invoke(new Action(() => { int rowId = this.dgvActivity.Rows.Add( false, actInfo.activityType, actInfo.activityTypeName, actInfo.activityThematicId, actInfo.activityThematicName, sActivityTime, sActivityRemaining, actInfo.discount, string.IsNullOrEmpty(actInfo.discount)? "-" : actInfo.discount.TrimEnd('0') + "折" ); dgvActivity.Rows[rowId].Height = 40; })); } //进详情页查询折扣比例信息,因部分活动可能无符合条件商品,查询可能速度较慢 if(chkGetDiscount.Checked) GetDiscount(); //设置当前快捷选中的活动 ChkSignActivity_CheckedChanged(null, null); Invoke(new Action(() => { ucGroupBoxEx2.Enabled = true; ucGroupBoxEx3.Enabled = true; string sRst = "查询结束!"; if (cancellationTokenSource.IsCancellationRequested) sRst = "已取消查询!"; BaseMsgForm.ShowInfo(sRst); this.statusBar.lblTaskStatus.Text = sRst; })); }, cancellationTokenSource.Token); } // 查询活动折扣 void GetDiscount() { foreach (var shopId in lstShopIdSelect) { if (cancellationTokenSource.IsCancellationRequested) break; var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == shopId); if (shop == null) continue; shop.LastRefreshDate = ""; } int i = 0; // 查询所有活动是否有店铺可以报名,可报名的才显示 foreach (var actInfo in lstActivityThematic) { this.Invoke(new Action(() => { this.statusBar.lblTaskStatus.Text = "正在查询活动折扣" + (i + 1) + "..."; this.statusBar.pgbTaskProgress.Maximum = lstActivityThematic.Count; this.statusBar.UpdateProgressBar(i + 1); i++; })); if (cancellationTokenSource.IsCancellationRequested) break; if (actInfo == null) continue; var actRow = this.dgvActivity.Rows.Cast() .FirstOrDefault(r => r.Cells["colActivityThematicId"].Value.ParseToLong() == actInfo.activityThematicId); if (actRow == null) continue; if (!string.IsNullOrWhiteSpace(actInfo.discount)) { this.Invoke(new Action(() => { actRow.Cells["colActivityMsg"].Value = "折扣查询成功"; })); continue; } this.Invoke(new Action(() => { actRow.Cells["colActivityMsg"].Value = "正在查询折扣..."; })); foreach (var shopId in lstShopIdSelect) { if (cancellationTokenSource.IsCancellationRequested) break; var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == shopId); if (shop == null) continue; var shopRow = this.dgvShop.Rows.Cast() .FirstOrDefault(r => r.Cells["colShopId"].Value.ParseToString() == shop.ShopId); if (shopRow == null) continue; Invoke(new Action(() => { shopRow.Cells["colMessage"].Value = "查询折扣,活动:" + actInfo.activityThematicName; })); #region 检测登录 if (shop.LastRefreshDate == "") { if (!CheckLogin(shop)) continue; } #endregion int tryCount = 0; tryAgain: Thread.Sleep(100 + Randomx.GetId(200)); string jsonRst = GetActivityMatch(shop, actInfo.activityType, actInfo.activityThematicId); if (jsonRst.Contains("指定的值含有无效的控制字符") || jsonRst.Contains("login") || jsonRst.Contains("Login")) { Invoke(new Action(() => { var shopRows = this.dgvShop.Rows.Cast().Where(r => r.Cells["colShopLoginName"].Value.ToString() == shop.LoginName); foreach (var r in shopRows) { r.Cells["colMessage"].Value = "店铺掉线"; r.Cells["colLoginStatus"].Value = "掉线"; r.Cells["colCanUse"].Value = false; DisplayLoginStatus(r, false); } })); continue; } if ((jsonRst.Contains("当前操作人数太多,请稍后重试") || jsonRst.Contains("too quickly")) && tryCount < 5) { tryCount++; Thread.Sleep(Randomx.GetId(5000, 7000)); goto tryAgain; } if (!jsonRst.Contains("\"success\":true")) { //isError = true; //string sErr = BaseRegex.GetStringJson(ref jsonRst, "errorMsg"); //if (!string.IsNullOrWhiteSpace(sErr) && !errMsg.Contains(sErr)) // errMsg += sErr + " "; //page++; string sErr = BaseRegex.GetStringJson(ref jsonRst, "errorMsg"); if (string.IsNullOrEmpty(sErr)) sErr = BaseRegex.GetStringJson(ref jsonRst, "error_msg"); if (string.IsNullOrEmpty(sErr)) sErr = jsonRst; Invoke(new Action(() => { actRow.Cells["colActivityMsg"].Value = sErr; shopRow.Cells["colMessage"].Value = ""; })); continue; } if (jsonRst.Contains("\"success\":true")) { var jArr = new JArray(); try { var jObj = JObject.Parse(jsonRst); jArr = jObj["result"]?["matchList"] as JArray; if (jArr == null) jArr = new JArray(); } catch (Exception ex) { BaseMsgForm.ShowError(ex.Message); } if (jArr.Count() == 0) { Invoke(new Action(() => { shopRow.Cells["colMessage"].Value = ""; })); continue; } try { var skuObj = jArr[0]["skcList"][0]["skuList"][0]; var suggestActivityPrice = skuObj["suggestActivityPrice"].ParseToInt(); var dailyPrice = skuObj["dailyPrice"].ParseToInt(); var discount = suggestActivityPrice * 100.0 / dailyPrice; actInfo.discount = Math.Round(discount) + ""; if (actInfo.discount.Length == 1) actInfo.discount += "0"; // 补0 Invoke(new Action(() => { actRow.Cells["colDiscountTenth"].Value = actInfo.discount; actRow.Cells["colDiscount"].Value = string.IsNullOrEmpty(actInfo.discount) ? "-" : actInfo.discount.TrimEnd('0') + "折"; actRow.Cells["colActivityMsg"].Value = "折扣查询成功"; shopRow.Cells["colMessage"].Value = ""; })); break; } catch (Exception ex) { BaseMsgForm.ShowError(ex.Message); } } } if(string.IsNullOrEmpty(actInfo.discount) && !cancellationTokenSource.IsCancellationRequested) { this.Invoke(new Action(() => { actRow.Cells["colActivityMsg"].Value = "没有活动可用商品,折扣查询失败"; })); } } } int GetNearDiscount(int discount) { if (lstDiscount.Count <= 0) return 100; if (discount < lstDiscount.First()) return lstDiscount.First(); if (discount >= lstDiscount.Last()) return lstDiscount.Last(); for (int i = 0; i < lstDiscount.Count - 1; i++) { if (discount >= lstDiscount[i] && discount < lstDiscount[i + 1]) return lstDiscount[i]; } return lstDiscount.Last(); } private void btnSignActivity_Click(object sender, EventArgs e) { var lstShopId = dgvShop.Rows.Cast().Where(row => row.Cells["colSelect"]?.Value.ParseToBool() == true).Select(r => r.Cells["colShopId"]?.Value.ToString()).ToList(); if (lstShopId.Count == 0) { BaseMsgForm.ShowInfo("请选择店铺!"); return; } var lstActivityId = dgvActivity.Rows.Cast().Where(row => row.Cells["colCheckActivity"]?.Value.ParseToBool() == true) .Select(r => r.Cells["colActivityThematicId"]?.Value.ToString()).ToList(); if (lstActivityId.Count == 0) { BaseMsgForm.ShowInfo("请选择活动!"); return; } #region 重置控件数据 dgvProduct.Rows.Clear(); var shopRows = this.dgvShop.Rows.Cast(); foreach (var r in shopRows) { r.Cells["colMessage"].Value = ""; } ucGroupBoxEx2.Enabled = false; ucGroupBoxEx3.Enabled = false; cancellationTokenSource = new CancellationTokenSource(); lstShopIdSelect.Clear(); lstShopIdSelect.AddRange(lstShopId); lstActivityThematicIdSelect.Clear(); lstActivityThematicIdSelect.AddRange(lstActivityId); #endregion Task.Run(() => { //报名活动 SignActivity(); Invoke(new Action(() => { ucGroupBoxEx2.Enabled = true; ucGroupBoxEx3.Enabled = true; string sRst = "已完成活动报名!"; if (cancellationTokenSource.IsCancellationRequested) sRst = "已取消活动报名!"; BaseMsgForm.ShowInfo(sRst); this.statusBar.lblTaskStatus.Text = sRst; })); },cancellationTokenSource.Token); } /// /// 查询店铺未出单商品,返回商品id列表 /// public List GetNoSaleProd(string shopId) { int onSaleDays = 0; int onSaleDays2 = 9999; int saleCount = 0; string days = "7"; //int i = 0; //foreach (var shopId in lstShopIdSelect) //{ this.Invoke(new Action(() => { days = cmbDays.Text; onSaleDays = numOnSaleDays.Value.ParseToInt(); onSaleDays2 = numOnSaleDays2.Value.ParseToInt(); saleCount = numSaleCount.Value.ParseToInt(); this.statusBar.lblTaskStatus.Text = "正在查询无销量商品..."; this.statusBar.pgbTaskProgress.Maximum = lstShopIdSelect.Count; //this.statusBar.UpdateProgressBar(i + 1); //i++; })); if (cancellationTokenSource.IsCancellationRequested) return new List(); var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == shopId); if (shop == null) return new List(); var shopRow = this.dgvShop.Rows.Cast() .FirstOrDefault(r => r.Cells["colShopId"].Value.ParseToString() == shop.ShopId); if (shopRow == null) return new List(); if (!CheckLogin(shop)) return new List(); Invoke(new Action(() => { shopRow.Cells["colMessage"].Value = "正在查询无销量商品"; })); this.dicNoSaleProd[shop.ShopId] = new List(); int page = 0; int totalPage = 1; while (page < totalPage) { page++; string jsonRst = GetNoSaleProd(shop, days, onSaleDays, onSaleDays2, saleCount, page); if (!jsonRst.Contains("\"success\":true")) { string sErr = BaseRegex.GetStringJson(ref jsonRst, "errorMsg"); if (string.IsNullOrEmpty(sErr)) sErr = BaseRegex.GetStringJson(ref jsonRst, "error_msg"); if (string.IsNullOrEmpty(sErr)) sErr = jsonRst; Invoke(new Action(() => { shopRow.Cells["colMessage"].Value = sErr; })); break; } var jArr = new JArray(); try { var jObj = JObject.Parse(jsonRst); jArr = jObj["result"]["subOrderList"] as JArray; if (jArr == null) jArr = new JArray(); foreach (var item in jArr) { string sItem = item.ToString(); WarehouseProductSubOrderInfo sInfo = JsonHelper.DeserializeJsonToObject(sItem); // 反序列化得到类 if (sInfo != null) { this.dicNoSaleProd[shop.ShopId].Add(sInfo); } } } catch (Exception ex) { BaseMsgForm.ShowError(ex.Message); } int total = BaseRegex.GetStringJson(ref jsonRst, "total").ParseToInt(); totalPage = Math.Ceiling(total / 40.0).ParseToInt(); } //} try { return this.dicNoSaleProd[shop.ShopId].Select(p => p.productId.ParseToString()).ToList(); } catch { return new List(); } } public void SignActivity() { int i = 0; foreach (var shopId in lstShopIdSelect) { List noSaleProdIdLst = new List(); if (chkNoSaleProd.Checked) noSaleProdIdLst.AddRange(GetNoSaleProd(shopId)); this.Invoke(new Action(() => { this.statusBar.lblTaskStatus.Text = "正在报名活动商品..."; this.statusBar.pgbTaskProgress.Maximum = lstShopIdSelect.Count; this.statusBar.UpdateProgressBar(i + 1); i++; })); if (cancellationTokenSource.IsCancellationRequested) break; var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == shopId); if (shop == null) continue; var shopRow = this.dgvShop.Rows.Cast() .FirstOrDefault(r => r.Cells["colShopId"].Value.ParseToString() == shop.ShopId); if (shopRow == null) continue; if (!CheckLogin(shop)) continue; foreach (var activityId in lstActivityThematicIdSelect) { var activity = lstActivityThematic.FirstOrDefault(a => a.activityThematicId.ParseToString() == activityId); if (activity == null) continue; var actRow = this.dgvActivity.Rows.Cast() .FirstOrDefault(r => r.Cells["colActivityThematicId"].Value.ParseToLong() == activity.activityThematicId); if (actRow == null) continue; int tryCount = 0; string searchScrollContext = ""; tryAgain: Thread.Sleep(100 + Randomx.GetId(200)); if (chkNoSaleProd.Checked && noSaleProdIdLst.Count == 0) { noSaleProdIdLst.Add("123"); } if (soloActivityShop != null && soloActivityProduct != null) { noSaleProdIdLst.Clear(); noSaleProdIdLst.Add(soloActivityProduct.productId.ToString()); } var jsonRst = GetActivityMatch(shop, activity.activityType, activity.activityThematicId, searchScrollContext, string.Join(", ", noSaleProdIdLst)); if (jsonRst.Contains("指定的值含有无效的控制字符") || jsonRst.Contains("login") || jsonRst.Contains("Login")) { Invoke(new Action(() => { var shopRows = this.dgvShop.Rows.Cast().Where(r => r.Cells["colShopLoginName"].Value.ToString() == shop.LoginName); foreach (var r in shopRows) { r.Cells["colMessage"].Value = "店铺掉线"; r.Cells["colLoginStatus"].Value = "掉线"; r.Cells["colCanUse"].Value = false; DisplayLoginStatus(r, false); } })); continue; } if ((jsonRst.Contains("当前操作人数太多,请稍后重试") || jsonRst.Contains("too quickly")) && tryCount < 5) { tryCount++; Thread.Sleep(Randomx.GetId(5000, 7000)); goto tryAgain; } if (!jsonRst.Contains("\"success\":true")) { string sErr = BaseRegex.GetStringJson(ref jsonRst, "errorMsg"); if (string.IsNullOrEmpty(sErr)) sErr = BaseRegex.GetStringJson(ref jsonRst, "error_msg"); if (string.IsNullOrEmpty(sErr)) sErr = jsonRst; Invoke(new Action(() => { actRow.Cells["colActivityMsg"].Value = sErr; shopRow.Cells["colMessage"].Value = sErr; })); continue; } var jArr = new JArray(); try { var jObj = JObject.Parse(jsonRst); jArr = jObj["result"]?["matchList"] as JArray; if (jArr == null) jArr = new JArray(); } catch (Exception ex) { BaseMsgForm.ShowError(ex.Message); } int stillCount = BaseRegex.GetIntJson(ref jsonRst, "stillCount"); this.Invoke(new Action(() => { this.statusBar.lblTaskStatus.Text = "正在报名活动商品... 剩余 " + stillCount + " 件"; })); searchScrollContext = BaseRegex.GetStringJson(ref jsonRst, "searchScrollContext"); if (jArr.Count() == 0 && stillCount > 0 && tryCount < 5) { tryCount++; goto tryAgain; } if (jArr.Count() == 0 && stillCount == 0) { if (soloActivityShop != null && soloActivityProduct != null) { Invoke(new Action(() => { int rowId = dgvProduct.Rows.Add( false, shop.ShopId, shop.ShopAccount, activity.activityThematicId, activity.activityThematicName, null,//prod.pictureUrl, "--", //prod.productName, "--", //prod.productId, "--", //prod.skcList.FirstOrDefault()?.skcId, "--", //prod.skcList.FirstOrDefault()?.extCode, activity.discount.Trim('0') + "折", "--", //prod.suggestActivityStock, "--", //prod.targetActivityStock, activity.discount.Trim('0') + "折", "--", //inventory "商品 " + soloActivityProduct.productSkcId + " 不符合报名条件" ); dgvProduct.Rows[rowId].Height = 30; })); } continue; } try { string str = JsonHelper.SerializeObject(jArr); var prodLst = JsonHelper.DeserializeJsonToList(str); var prodSubmitRows = new List(); TemuActivityParam activityParam = new TemuActivityParam(); activityParam.activityType = activity.activityType; // 相同的是主活动,不需要activityThematicId就可以报名。 if (activity.activityThematicId != activity.activityType) activityParam.activityThematicId = activity.activityThematicId; activityParam.productList = new List(); foreach (var prod in prodLst) { int discount = this.GetNearDiscount(activity.discount.ParseToInt()); var discountCtrl = this.actDiscount60; if (discount == 70) discountCtrl = this.actDiscount70; if (discount == 80) discountCtrl = this.actDiscount80; if (discount == 85) discountCtrl = this.actDiscount85; // 如果是默认库存或者库存小于推荐值,使用推荐库存 int inventory = discountCtrl.Inventory; //if (inventory < prod.suggestActivityStock || discountCtrl.IsDefaultInventory) // inventory = prod.suggestActivityStock.ParseToInt(); if (inventory < prod.targetActivityStock || discountCtrl.IsDefaultInventory) inventory = prod.targetActivityStock.ParseToInt(); Invoke(new Action(() => { int rowId = dgvProduct.Rows.Add( true, shop.ShopId, shop.ShopAccount, activity.activityThematicId, activity.activityThematicName, null,//prod.pictureUrl, prod.productName, prod.productId, prod.skcList.FirstOrDefault()?.skcId, prod.skcList.FirstOrDefault()?.extCode, activity.discount.Trim('0') + "折", prod.suggestActivityStock, prod.targetActivityStock, activity.discount.Trim('0') + "折", inventory ); dgvProduct.Rows[rowId].Height = 30; // 过低的报名数量则不参与活动 if (!discountCtrl.IsDefaultInventory && chkIfLowCancel.Checked && discountCtrl.Inventory < prod.targetActivityStock) { } else prodSubmitRows.Add(dgvProduct.Rows[rowId]); })); if (!discountCtrl.IsDefaultInventory && chkIfLowCancel.Checked && discountCtrl.Inventory < prod.targetActivityStock) { continue; } ActProductListItem activityProditem = new ActProductListItem(); activityProditem.productId = prod.productId; activityProditem.activityStock = inventory; activityProditem.skcList = new List(); activityProditem.sessionIds = prod.suggestEnrollSessionIdList; ActSkcListItem actSkcListItem = new ActSkcListItem(); actSkcListItem.skcId = prod.skcList.FirstOrDefault()?.skcId; actSkcListItem.skuList = new List(); foreach (var skuInfo in prod.skcList.FirstOrDefault()?.skuList) { actSkcListItem.skuList.Add(new ActSkuListItem { activityPrice = skuInfo.suggestActivityPrice, skuId = skuInfo.skuId, }); } activityProditem.skcList.Add(actSkcListItem); activityParam.productList.Add(activityProditem); } string data = JsonHelper.SerializeObject(activityParam); string submitRst = ""; Thread.Sleep(Randomx.GetId(3000, 6000)); submitRst = SubmitActivity(shop, activityParam.activityType, activityParam.activityThematicId, data); for (int j = 0; j < 4 && (jsonRst.Contains("当前操作人数太多,请稍后重试") || jsonRst.Contains("too quickly")); j++) { Thread.Sleep(Randomx.GetId(6000, 10000)); submitRst = SubmitActivity(shop, activityParam.activityType, activityParam.activityThematicId, data); } if (!submitRst.Contains("\"success\":true")) { string sSubmitErr = BaseRegex.GetStringJson(ref submitRst, "errorMsg"); if (string.IsNullOrEmpty(sSubmitErr)) sSubmitErr = BaseRegex.GetStringJson(ref submitRst, "error_msg"); if (string.IsNullOrEmpty(sSubmitErr)) sSubmitErr = jsonRst; Invoke(new Action(() => { foreach(var submitRow in prodSubmitRows) { submitRow.Cells["colMsg"].Value = sSubmitErr; } })); continue; } Invoke(new Action(() => { foreach (var submitRow in prodSubmitRows) { submitRow.Cells["colMsg"].Value = "提交活动成功"; } })); // 如果提交成功且还有更多商品可报名,继续重复报名(已报名商品不会出现在搜索结果列表) if (submitRst.Contains("\"success\":true") && jsonRst.Contains("\"hasMore\":true")) { tryCount = 0; goto tryAgain; } } catch (Exception ex) { BaseMsgForm.ShowError(ex.Message); } } } } public bool CheckLogin(ShopLoginInfo shop) { if (shop.LoginStatus2 != "国际版在线") { return false; } if (ShopListForm.Instance == null) ShopListForm.Instance = new ShopListForm(); ShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false); if (shop.LoginStatus2 != "国际版在线") { Invoke(new Action(() => { var rows = this.dgvShop.Rows.Cast().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; DisplayLoginStatus(row, false); } })); return false; } return true; } private void btnStop_Click(object sender, EventArgs e) { if (cancellationTokenSource != null) cancellationTokenSource.Cancel(); } /// /// 获取活动列表 /// /// /// private string GetActivityList(ShopLoginInfo shop) { string url = "https://agentseller.temu.com/api/kiana/gamblers/marketing/enroll/activity/list"; string body; body = @"{""needCanEnrollCnt"":true}"; string refere = "https://agentseller.temu.com/activity/marketing-activity"; return HttpResponseBLL.PostResponse2(shop, url, body, refere); } /// /// 获取符合店铺的活动 /// /// /// /// 多个用逗号隔开 /// private string GetActivityMatch(ShopLoginInfo shop,int? activityType, long? thematicId, string searchScrollContext = "", string spuIds="") { string url = "https://agentseller.temu.com/api/kiana/gamblers/marketing/enroll/scroll/match"; string body; body = "{\"activityType\":" + activityType; if (thematicId != activityType) body += ",\"activityThematicId\":" + thematicId; body += ",\"rowCount\":50"; if (!string.IsNullOrWhiteSpace(searchScrollContext)) body += ",\"searchScrollContext\":\"" + searchScrollContext + "\""; if (!string.IsNullOrWhiteSpace(spuIds)) body += ",\"productIds\":[" + spuIds + "],\"productSkcExtCodes\":[]"; body += "}"; //if (!string.IsNullOrWhiteSpace(spuIds)) //{ // body = "{\"activityType\":" + activityType; // if (thematicId != activityType) // body += ",\"activityThematicId\":" + thematicId; // body += ",\"rowCount\":50,\"productIds\":[" + spuIds + "],\"productSkcExtCodes\":[]}"; //} string refere = "https://agentseller.temu.com/activity/marketing-activity/detail-new?type=" + activityType; if (thematicId != activityType) refere += "&thematicId=" + thematicId; return HttpResponseBLL.PostResponse2(shop, url, body, refere); } /// /// 提交活动报名 /// /// /// /// /// private string SubmitActivity(ShopLoginInfo shop, int? activityType, long? thematicId, string _body) { string url = "https://agentseller.temu.com/api/kiana/gamblers/marketing/enroll/submit"; string body; body = _body; string refere = "https://agentseller.temu.com/activity/marketing-activity/detail-new?type=" + activityType; if (thematicId != activityType) refere += "&thematicId=" + thematicId; return HttpResponseBLL.PostResponse2(shop, url, body, refere); } /// /// /// /// /// 加入站点天数 /// /// private string GetNoSaleProd(ShopLoginInfo shop, string days, int onSalesDays, int onSalesDays2, int saleCount = 0, int page=1) { string url = "https://agentseller.temu.com/mms/venom/api/supplier/sales/management/listWarehouse"; string body; if (days == "7") body = @"{""pageNo"":" + page + @",""pageSize"":40,""isLack"":0,""selectStatusList"":[12],""priceAdjustRecentDays"":7, ""sevenDaysSaleVolumMin"":0, ""sevenDaysSaleVolumMax"":" + saleCount + @",""onSalesDurationOfflineGte"":" + onSalesDays + @",""onSalesDurationOfflineLte"":" + onSalesDays2 + "}"; else body = @"{""pageNo"":" + page + @",""pageSize"":40,""isLack"":0,""selectStatusList"":[12],""priceAdjustRecentDays"":7, ""thirtyDaysSaleVolumMin"":0, ""thirtyDaysSaleVolumMax"":" + saleCount + @",""onSalesDurationOfflineGte"":" + onSalesDays + @",""onSalesDurationOfflineLte"":"+ onSalesDays2 + "}"; string refere = "https://agentseller.temu.com/stock/fully-mgt/sale-manage/main"; return HttpResponseBLL.PostResponse2(shop, url, body, refere); } private void MarketingActivityForm_FormClosing(object sender, FormClosingEventArgs e) { if (this.soloActivityProduct != null && this.soloActivityShop != null) { this.Visible = false; // 隐藏窗口但不从任务栏中移除 this.Hide(); // 阻止窗口关闭 e.Cancel = true; } } } }