using AllBase; using AllBase.Helper; using AllBase.Model.Result; using CefSharp; using CefSharp.WinForms; //using TemuKJD.DashBoardForms; using TemuKJD.Helper; using TemuKJD.BaseForms; using Microsoft.Win32; 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.Web.Hosting; using System.Windows.Forms; using Work; using Work.BLL.Tools; using TemuKJD.BLL; using AllBase.Model.Result.PDDResult; using NaiBa.Util; namespace TemuKJD.WXForms.ShopForms { public partial class WXShopMultiLoginForm : BaseGeneralForm { public static WXShopMultiLoginForm shopMultiLoginFormInstance { get; set; } = null; public bool isAutoLogin = false; public int CloseAfterSecond { get; set; } public EnumOpenType openType = EnumOpenType.manage; public bool isMultiLogin = false; public string MultiLoginCookieName = ""; public string InitUrl = ""; public ChromiumWebBrowser cefWebBrowser = null; public ShopLoginInfo mainShop = null; public ConcurrentList lstSwitchShop = new ConcurrentList(); public ConcurrentList lstSwitchInfo = new ConcurrentList(); public ConcurrentList lstNeedUpdateShop = new ConcurrentList(); const string DefaultUrl = "https://store.weixin.qq.com/shop/home"; const string shopLoginUrl = "https://store.weixin.qq.com/shop?redirect_url=%2Fhome"; private string currentUrl = ""; private string shopCookieHead = "store.weixin.qq.com"; private ConcurrentList lstShopCompany = new ConcurrentList(); public WXShopMultiLoginForm(ShopLoginInfo shopInfo) { InitializeComponent(); shopMultiLoginFormInstance = this; this.mainShop = shopInfo; Task.Run(() => { var shopSwitchRst = WXShopSwitch.getShopSwitchList(mainShop); if (!shopSwitchRst.Contains("\"code\":0")) { BaseMsgForm.ShowError("获取切换列表失败!"); return; } try { string shopSwitchStr = JsonHelper.SerializeObject(JsonHelper.JObjectParse(shopSwitchRst)["list"]); lstSwitchInfo.Clear(); lstSwitchShop.Clear(); lstSwitchInfo.AddRange(JsonHelper.DeserializeJsonToList(shopSwitchStr)); lstSwitchShop.AddRange(GlobalConfig.ShopLoginList.Where(s => lstSwitchInfo.Any(sw => sw.appid == s.ShopId))); foreach(var shop in lstSwitchShop) { bool canUse = shop.LoginStatus == "登录成功"; Invoke(new Action(() => { this.dgvShop.Rows.Add ( true, shop.LoginName, shop.ShopId, shop.ShopAccount, shop.Notes, canUse ? "在线" : "掉线", canUse, "-" ); })); displayAuthStatus(shop); } } catch (Exception ex) { BaseMsgForm.ShowError("切换列表解析失败!"); } if (isAutoLogin) { Thread.Sleep(Randomx.GetId(2500, 3500)); while(this.cefWebBrowser == null || this.cefWebBrowser.IsLoading) { if (!this.Created) return; Thread.Sleep(100); continue; } if (!this.Created) return; Invoke(() => { btnRefreshNum_Click(null, null); }); } }); } private void ShopLoginForm_Load(object sender, EventArgs e) { this.Size = new Size(1680, 900); this.CenterToScreen(); this.splitContainer3.SplitterDistance = this.splitContainer3.Height - 62; if (string.IsNullOrWhiteSpace(InitUrl)) InitUrl = DefaultUrl; if (CloseAfterSecond > 0) { Task.Run(() => { Thread.Sleep(1000 * CloseAfterSecond); if (this.Created) { Invoke(new Action(() => { this.Close(); })); } }); } initSwitchShop(); initCefAndMainShop(); } public void initSwitchShop() { } /// /// 初始化CEF并登录主店铺 /// private void initCefAndMainShop() { if (openType != EnumOpenType.login && mainShop == null) return; if (cefWebBrowser == null) { cefWebBrowser = CEFBrowser.CreateChromiumWebBrowser(InitUrl, false); CustomResourceRequestHandlerLocal resourceRequestHandler = new CustomResourceRequestHandlerLocal(); resourceRequestHandler.ResourceLoadCompleteEvent += RequestHandler_ResourceLoadComplete; resourceRequestHandler.BeforeResourceLoadEvent += RequestHandler_BeforeResourceLoad; cefWebBrowser.RequestHandler = new CustomRequestHandler(resourceRequestHandler); var lifeSapnHandler = new LifeSpanHandlerLocal(PopWindowType.SelfWindow); cefWebBrowser.LifeSpanHandler = lifeSapnHandler; cefWebBrowser.KeyboardHandler = new KeyboardHandler(); cefWebBrowser.FrameLoadEnd += CefWebBrowser_FrameLoadEnd; cefWebBrowser.AddressChanged += CefWebBrowser_AddressChanged; cefWebBrowser.LoadError += CefWebBrowser_LoadError; cefWebBrowser.Dock = DockStyle.Fill; //js绑定C#对象 WXShopBrowserObject shopObj = new WXShopBrowserObject(); shopObj.OnInfoReceived += ShopObj_OnInfoReceived; CefSharpSettings.WcfEnabled = true; cefWebBrowser.JavascriptObjectRepository.Register( name: "shopObj", objectToBind: shopObj, isAsync: false, options: new BindingOptions { Binder = BindingOptions.DefaultBinder.Binder /*CamelCaseJavascriptNames = false*/ /*cef79*/ } ); List cookieLst = new List(); try { if (mainShop != null) { cookieLst = JsonHelper.DeserializeJsonToList(mainShop.Cookies.ParseToString()); if (cookieLst == null) cookieLst = new List(); } } catch { } Task.Run(() => { Invoke(new Action(() => { splitContainer1.Panel1.Controls.Add(cefWebBrowser); })); // cef138必须init后方可设置或删除cookie while (!cefWebBrowser.IsBrowserInitialized || !cefWebBrowser.GetBrowser().MainFrame.IsValid) Thread.Sleep(20); CEFBrowser.DeleteCookie(cefWebBrowser.GetCookieManager(null)); //cef 138 如果没有设置RequestContext 可能为空,直接getCookieManager //异步设置cookie //var t = CEFBrowser.SetCookieAsync(JsonHelper.SerializeObject(cookieLst), cefWebBrowser.GetCookieManager(null)); string address = InitUrl; foreach (var cook in cookieLst) { // 同步设置cookie cefWebBrowser.GetCookieManager(null).SetCookie(address, cook); //var t = CEFBrowser.SetCookieAsync(cook.Domain, cook.Name + "=" + cook.Value + ";", cefWebBrowser.GetCookieManager(null)); //t.Wait(5000); } cefWebBrowser.Load(InitUrl); }); } } private void ShopObj_OnInfoReceived(string information) { //BaseMsgForm.ShowInfo(information); if (!string.IsNullOrEmpty(information)) cefWebBrowser.GetBrowser().MainFrame.EvaluateScriptAsync("alert('" + information + "');"); } private void CefWebBrowser_LoadError(object sender, CefSharp.LoadErrorEventArgs e) { } private void CefWebBrowser_AddressChanged(object sender, CefSharp.AddressChangedEventArgs e) { if (this.Created && !this.Disposing && !this.IsDisposed) { Invoke(new Action(() => { currentUrl = e.Address; txtAddress.Text = e.Address; })); } } private void CefWebBrowser_FrameLoadEnd(object sender, CefSharp.FrameLoadEndEventArgs e) { //js绑定C#对象 html页面内声明绑定的C#对象 StringBuilder sb = new StringBuilder(); sb.Append("(function(){"); sb.Append("CefSharp.BindObjectAsync('shopObj');"); sb.Append("})();"); cefWebBrowser.GetBrowser().MainFrame.EvaluateScriptAsync(sb.ToString()); } //public Func BeforeResourceLoadEvent; // sender, requestUrl, postData, request, true(表示取消执行) private bool RequestHandler_BeforeResourceLoad(object sender, string url, string postData, IRequest request) { return false; } private void RequestHandler_ResourceLoadComplete(object sender, string url, string postData, string responseData, IRequest request) { if (url == "https://store.weixin.qq.com/shop/home" && this.openType == EnumOpenType.login) { Task.Run(() => { var data = responseData; var index = data.IndexOf("window.__INITIAL_PINIA_DATA__=") + "window.__INITIAL_PINIA_DATA__=".Length; var indexEnd = data.IndexOf(";window.__USE_VITE__="); if (index < 1000) { return; } var dataStr = data.Substring(index, indexEnd - index); dataStr = GetHtml.Unicode2String(dataStr); var shopId = BaseRegex.GetStringJson(ref data, "appid"); var nickName = BaseRegex.GetStringJson(ref data, "nickName"); var openId = BaseRegex.GetStringJson(ref data, "openid"); // oGu7k7HxmUyOmc1X6VM7GQwS-9cI if (mainShop != null && mainShop.ShopId != shopId) { BaseMsgForm.ShowError("cookie与店铺不匹配,请核对店铺!"); return; } if (mainShop == null && GlobalConfig.ShopLoginList.Any(s=>s.ShopId == shopId)) { BaseMsgForm.ShowError("录入的新店铺已存在,请核对店铺!"); return; } ShopCompany sc = new ShopCompany() { UserName = BaseClass.UserName, // 登录的用户信息 AccountId = shopId, AccountName = nickName, LoginName = shopId, openid = openId, LoginStatus = "登录成功", }; this.lstShopCompany.RemoveAll(s => s.AccountId == sc.AccountId); this.lstShopCompany.Add(sc); }); } } private void ShopLoginForm_FormClosed(object sender, FormClosedEventArgs e) { ////OnSaveComplete(shop); //Task.Run(() => //{ // Thread.Sleep(500); // MainForm.instance.Invoke(new Action(() => // { // if (!this.Disposing && !this.IsDisposed) // { // this.Dispose(); // } // })); //}); } private void txtAddress_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { if (cefWebBrowser != null) { cefWebBrowser.Load(txtAddress.Text); } } } private void btnPrev_Click(object sender, EventArgs e) { cefWebBrowser.Back(); } private void btnNext_Click(object sender, EventArgs e) { cefWebBrowser.Forward(); } private void btnRefreshNum_Click(object sender, EventArgs e) { pbLoading.Visible = true; btnRefreshNum.Enabled = false; lstNeedUpdateShop = new ConcurrentList(); Task.Run(() => { foreach (var shop in lstSwitchShop) { var switchInfo = lstSwitchInfo.FirstOrDefault(s => s.appid == shop.ShopId); var row = dgvShop.Rows.Cast().FirstOrDefault(r => r.Cells["colShopId"].Value.ParseToString() == shop.ShopId); Invoke(new Action(() => { row.Cells["colMessage"].Value = "-"; })); WXShopListForm.Instance.CheckShopLogin(new ShopLoginInfo[] { shop }, false); if (shop.LoginStatus == "登录成功") { Thread.Sleep(100); Invoke(new Action(() => { row.Cells["colMessage"].Value = "登录成功"; })); continue; } lstNeedUpdateShop.Add(shop); string jsStr1 = @"document.getElementsByClassName('shop-info-popover')[0].style =''; var divLst = document.getElementsByClassName('shop-info-popover')[0].getElementsByTagName('div'); (function() { for (i=0; i= 0){ divLst[i].click(); //return 'success'; } } })();"; var t1 = cefWebBrowser.GetMainFrame().EvaluateScriptAsync(jsStr1); t1.Wait(5000); Thread.Sleep(Randomx.GetId(500, 1000)); jsStr1 = @"(function() { for (i=0; i= 0){ if(divLst[i].innerHTML == '" + switchInfo.nickname + @"'){ divLst[i].click(); return 'success'; } } })();"; t1 = cefWebBrowser.GetMainFrame().EvaluateScriptAsync(jsStr1); t1.Wait(5000); Thread.Sleep(Randomx.GetId(3000, 3500)); List cookieList = CEFBrowser.GetCookieList(shopCookieHead, cefWebBrowser.GetCookieManager(null)); var cookies = cookieList.Where(c => c.Domain == this.shopCookieHead).ToList(); if (!cookies.Any(c => c.Name == "biz_ticket")) { cookies.Add(new CefSharp.Cookie() { Name = "biz_ticket", Value = "", Domain = "store.weixin.qq.com", Expires = null, HttpOnly = true, Path = "/", Priority = CefSharp.Enums.CookiePriority.Medium, SameSite = CefSharp.Enums.CookieSameSite.Unspecified, Secure = true, }); } WXShopUpdateCookieForm.CheckCookieUpdate(shop, cookies); Invoke(new Action(() => { bool canUse = shop.LoginStatus == "登录成功"; row.Cells["colMessage"].Value = canUse ? "登录成功" : "登录失败,请稍后重试"; row.Cells["colLoginStatus"].Value = canUse ? "在线" : "掉线"; row.Cells["colCanUse"].Value = canUse; displayAuthStatus(shop); })); Thread.Sleep(Randomx.GetId(2500, 5000)); } if (!this.Created) return; Invoke(new Action(() => { btnRefreshNum.Enabled = true; pbLoading.Visible = false; if (this.isAutoLogin) this.Close(); else BaseMsgForm.ShowInfo("操作完成!"); })); }); } void displayAuthStatus(ShopLoginInfo shop) { var rows = this.dgvShop.Rows.Cast().Where(r => r.Cells["colShopId"].Value.ParseToString() == shop?.ShopId); foreach (var row in rows) { bool canUse = row.Cells["colLoginStatus"].Value.ParseToString() == "在线"; (row.Cells["colLoginStatus"] as DataGridViewLinkCell).Style.ForeColor = canUse ? Color.Blue : Color.Red; (row.Cells["colLoginStatus"] as DataGridViewLinkCell).LinkColor = canUse ? Color.Blue : Color.Red; (row.Cells["colLoginStatus"] as DataGridViewLinkCell).ActiveLinkColor = canUse ? Color.LightBlue : Color.OrangeRed; (row.Cells["colLoginStatus"] as DataGridViewLinkCell).VisitedLinkColor = canUse ? Color.DarkBlue : Color.DarkRed; } } } public class WXShopSwitch { public static string getShopSwitchList(ShopLoginInfo shop) { string url = "https://store.weixin.qq.com/shop-faas/mmecnodelogin/session/getShopSwitchList?token=&lang=zh_CN"; string refere = "https://store.weixin.qq.com/shop/home"; var result = WXHttpResponseBLL.WeiXinGetResponse(shop, url, refere); return result; } public static async Task getShopSwitchListAsync(ShopLoginInfo shop) { string url = "https://store.weixin.qq.com/shop-faas/mmecnodelogin/session/getShopSwitchList?token=&lang=zh_CN"; string refere = "https://store.weixin.qq.com/shop/home"; var result = await WXHttpResponseBLL.WeiXinGetResponseAsync(shop, url, refere); return result; } } public class ShopSwitchInfo { public string appid { get; set; } // "wxa20bb379d0961414", public string nickname { get; set; } // "夜笙服装店", public string headimgurl { get; set; } // "http://mmbiz.qpic.cn/mmbiz_jpg/ZZIOBibOYfic6CDwhCA8lSSOAZSuEF8HdlBiaJC8RXsTRucB6Xopic49PKgViapwRZDTuGuVxDEtKvhkXNZG63uqUwA/0?wx_fmt=jpeg", public object appuin { get; set; } // null, public List jobInfoList { get; set; } public long? lastLoginTime { get; set; } // 1773216675, public int? ecAcctType { get; set; } // 101, public int? ecAcctStatus { get; set; } // 100, public int? ecSubType { get; set; } // 0, public int? shopType { get; set; } // 6, public string kfMsgNum { get; set; } // "0", public string shopMsgNum { get; set; } // "2002" } public class ShopSwitchJobInfo { public string jobName { get; set; } // "经理人" "资金充值" public long? jobId { get; set; } // 3 99998 } }