510 lines
20 KiB
C#
510 lines
20 KiB
C#
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<ShopLoginInfo> lstSwitchShop = new ConcurrentList<ShopLoginInfo>();
|
|
public ConcurrentList<ShopSwitchInfo> lstSwitchInfo = new ConcurrentList<ShopSwitchInfo>();
|
|
public ConcurrentList<ShopLoginInfo> lstNeedUpdateShop = new ConcurrentList<ShopLoginInfo>();
|
|
|
|
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<ShopCompany> lstShopCompany = new ConcurrentList<ShopCompany>();
|
|
|
|
|
|
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<ShopSwitchInfo>(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()
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化CEF并登录主店铺
|
|
/// </summary>
|
|
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<Cookie> cookieLst = new List<Cookie>();
|
|
try
|
|
{
|
|
if (mainShop != null)
|
|
{
|
|
cookieLst = JsonHelper.DeserializeJsonToList<CefSharp.Cookie>(mainShop.Cookies.ParseToString());
|
|
if (cookieLst == null)
|
|
cookieLst = new List<Cookie>();
|
|
}
|
|
}
|
|
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<object, string, string, request, bool> 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<ShopLoginInfo>();
|
|
|
|
Task.Run(() =>
|
|
{
|
|
foreach (var shop in lstSwitchShop)
|
|
{
|
|
var switchInfo = lstSwitchInfo.FirstOrDefault(s => s.appid == shop.ShopId);
|
|
var row = dgvShop.Rows.Cast<DataGridViewRow>().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<divLst.length; i++){
|
|
if(divLst[i].innerHTML.indexOf('切换店铺') >= 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<divLst.length; i++){
|
|
//if(divLst[i].innerHTML.indexOf('" + switchInfo.nickname + @"') >= 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<Cookie> 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<DataGridViewRow>().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<string> 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<ShopSwitchJobInfo> 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
|
|
}
|
|
}
|