From 0eae9f7706b0c53791bef6f06d7b8ad7f3b01ed5 Mon Sep 17 00:00:00 2001 From: chfei Date: Tue, 1 Sep 2026 14:30:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=BB=E7=AA=97=E5=8F=A3?= =?UTF-8?q?=20header=20=E6=8B=96=E5=8A=A8bug.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 拼多多登录 改为WPF 。PddMobileLoginForm 不再使用 --- 29WxOrderWpf/Common/DialogWindow.xaml | 39 +- .../BuyerCtrls/PDDBuyerOrderReadCtrl.xaml.cs | 16 +- .../BuyerCtrls/PDDBuyerSelectCtrl.xaml.cs | 277 +++++----- .../Ctrls/OrderCtrls/OrderListCtrl.xaml.cs | 4 +- .../OrderCtrls/OrderListRowItemCtrl.xaml.cs | 13 +- 29WxOrderWpf/MainWindow.xaml | 268 ++++++--- 29WxOrderWpf/MainWindow.xaml.cs | 17 +- .../ViewModels/PddMobileLoginViewModel.cs | 511 ++++++++++++++++++ 29WxOrderWpf/Views/PddMobileLoginView.xaml | 112 ++++ 29WxOrderWpf/Views/PddMobileLoginView.xaml.cs | 61 +++ AllBase/Helper/GlobalConfig.cs | 1 + AllBase/Model/DBModel/oms_wei_order_info.cs | 1 + Work/29WxOrderWork.csproj | 5 + .../UserControls/UcSplitPage.designer.cs | 468 ++++++++-------- Work/_29Tools/Forms/PddMobileLoginForm.cs | 2 +- 15 files changed, 1328 insertions(+), 467 deletions(-) create mode 100644 29WxOrderWpf/ViewModels/PddMobileLoginViewModel.cs create mode 100644 29WxOrderWpf/Views/PddMobileLoginView.xaml create mode 100644 29WxOrderWpf/Views/PddMobileLoginView.xaml.cs diff --git a/29WxOrderWpf/Common/DialogWindow.xaml b/29WxOrderWpf/Common/DialogWindow.xaml index 70b13e0..9bb6e07 100644 --- a/29WxOrderWpf/Common/DialogWindow.xaml +++ b/29WxOrderWpf/Common/DialogWindow.xaml @@ -1,24 +1,23 @@ - - + + - - - + diff --git a/29WxOrderWpf/Ctrls/BuyerCtrls/PDDBuyerOrderReadCtrl.xaml.cs b/29WxOrderWpf/Ctrls/BuyerCtrls/PDDBuyerOrderReadCtrl.xaml.cs index 3672621..339432b 100644 --- a/29WxOrderWpf/Ctrls/BuyerCtrls/PDDBuyerOrderReadCtrl.xaml.cs +++ b/29WxOrderWpf/Ctrls/BuyerCtrls/PDDBuyerOrderReadCtrl.xaml.cs @@ -37,7 +37,7 @@ using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Xml.XPath; -using TemuKJD.ToolForms; +using _29WxOrderWpf.ViewModels; using Work; using Work._29Tools.BLL; using Work._29Tools.CefTools; @@ -641,7 +641,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls if (data.Contains("\"error_code\":40001")) { currentReadBuyer = ""; - PddMobileLoginForm.CheckBuyerLogin(new List { buyer }, false); + PddMobileLoginViewModel.CheckBuyerLogin(new List { buyer }, false); return; } @@ -957,7 +957,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls //{"errorCode":72004,"errorMsg":"","error_code":72004,"error_msg":"","result":null} if (data.Contains("\"error_code\":40001") || data.Contains("\"error_code\":50000") || data.Contains("\"error_code\":72004")) { - PddMobileLoginForm.CheckBuyerLogin(new List { buyer }, false); + PddMobileLoginViewModel.CheckBuyerLogin(new List { buyer }, false); if (buyer.status == "掉线") currentReadBuyer = ""; return; @@ -1364,7 +1364,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls if (tokenSource.IsCancellationRequested) break; - PddMobileLoginForm.CheckBuyerLogin(new List() { buyer }); + PddMobileLoginViewModel.CheckBuyerLogin(new List() { buyer }); if (buyer.status != "在线") continue; @@ -1446,7 +1446,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls if (lastCefReadOrderTime < DateTime.Now.AddSeconds(-30)) { - PddMobileLoginForm.CheckBuyerLogin(new List() { buyer }); + PddMobileLoginViewModel.CheckBuyerLogin(new List() { buyer }); if (buyer.status != "在线") { BindBuyer(buyer, "店铺掉线"); @@ -1522,7 +1522,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls if (lastCefReadOrderTime < DateTime.Now.AddSeconds(-30)) { - PddMobileLoginForm.CheckBuyerLogin(new List() { buyer }); + PddMobileLoginViewModel.CheckBuyerLogin(new List() { buyer }); if (buyer.status != "在线") { BindBuyer(buyer, "店铺掉线"); @@ -1534,7 +1534,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls if (times % 100 == 0) { - PddMobileLoginForm.CheckBuyerLogin(new List() { buyer }); + PddMobileLoginViewModel.CheckBuyerLogin(new List() { buyer }); } if (buyer.status != "在线") break; @@ -1604,7 +1604,7 @@ namespace _29WxOrderWpf.Ctrls.BuyerCtrls if (lastCefReadOrderTime < DateTime.Now.AddSeconds(-30)) { - PddMobileLoginForm.CheckBuyerLogin(new List() { buyer }); + PddMobileLoginViewModel.CheckBuyerLogin(new List() { buyer }); if (buyer.status != "在线") { BindBuyer(buyer, "店铺掉线"); diff --git a/29WxOrderWpf/Ctrls/BuyerCtrls/PDDBuyerSelectCtrl.xaml.cs b/29WxOrderWpf/Ctrls/BuyerCtrls/PDDBuyerSelectCtrl.xaml.cs index 4dc06ed..f79f0ca 100644 --- a/29WxOrderWpf/Ctrls/BuyerCtrls/PDDBuyerSelectCtrl.xaml.cs +++ b/29WxOrderWpf/Ctrls/BuyerCtrls/PDDBuyerSelectCtrl.xaml.cs @@ -1,4 +1,7 @@ using _29WxOrderWpf.BaseWindows; +using _29WxOrderWpf.Common; +using _29WxOrderWpf.ViewModels; +using _29WxOrderWpf.Views; using AllBase; using AllBase.Helper; using AllBase.Model.DBModel; @@ -24,146 +27,166 @@ using Work.BaseForms; namespace _29WxOrderWpf.Ctrls.BuyerCtrls { - /// - /// PDDBuyerSelectCtrl.xaml 的交互逻辑 - /// - public partial class PDDBuyerSelectCtrl : UserControl - { - public PDDBuyerSelectCtrl() - { - InitializeComponent(); - } + /// + /// PDDBuyerSelectCtrl.xaml 的交互逻辑 + /// + public partial class PDDBuyerSelectCtrl : UserControl + { + public PDDBuyerSelectCtrl() + { + InitializeComponent(); + } - private void UserControl_Loaded(object sender, RoutedEventArgs e) - { - cmbPddBuyer.ItemsSource = GlobalConfig.PDDBuyerLoginList; - } + private void UserControl_Loaded(object sender, RoutedEventArgs e) + { + cmbPddBuyer.ItemsSource = GlobalConfig.PDDBuyerLoginList; + } - private void btnLoginPdd_Click(object sender, RoutedEventArgs e) - { - BuyerLoginInfo buyer = null; - if (cmbPddBuyer.SelectedItem != null) - { - buyer = cmbPddBuyer.SelectedItem as BuyerLoginInfo; - } + private void btnLoginPdd_Click(object sender, RoutedEventArgs e) + { + BuyerLoginInfo buyer = null; + if (cmbPddBuyer.SelectedItem != null) + { + buyer = cmbPddBuyer.SelectedItem as BuyerLoginInfo; + } - PddMobileLoginForm pddBuyerForm = new PddMobileLoginForm(buyer); - pddBuyerForm.openType = EnumOpenType.login; - pddBuyerForm.InitUrl = "https://mobile.yangkeduo.com/login.html?from=https%3A%2F%2Fmobile.yangkeduo.com%2Fpersonal.html"; - pddBuyerForm.ShowDialog(); - MainWindow.Instance.GetPddBuyer(); - } + PddMobileLoginView pddBuyerForm = new PddMobileLoginView(buyer); + pddBuyerForm.ViewModel.OpenType = EnumOpenType.login; + pddBuyerForm.ViewModel.InitUrl = "https://mobile.yangkeduo.com/login.html?from=https%3A%2F%2Fmobile.yangkeduo.com%2Fpersonal.html"; + //pddBuyerForm.ShowDialog(); + new DialogWindow() + { + Title = "买手登录", + Content = pddBuyerForm, + }.ShowDialog(); - private void cmbPddBuyer_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) - { - if (e.GetPosition(sender as IInputElement).X > cmbPddBuyer.ActualWidth - 18) - return; + MainWindow.Instance.GetPddBuyer(); - BuyerLoginInfo buyer = null; - if (cmbPddBuyer.SelectedItem != null) - { - buyer = cmbPddBuyer.SelectedItem as BuyerLoginInfo; - } - if (buyer == null) - return; - PddMobileLoginForm.CheckBuyerLogin(new List { buyer }, false); - if (buyer.status == "在线") - { - PddMobileLoginForm shopLoginForm = new PddMobileLoginForm(buyer); - shopLoginForm.openType = EnumOpenType.manage; - //shopLoginForm.WindowState = FormWindowState.Maximized; - shopLoginForm.InitUrl = "https://mobile.yangkeduo.com"; - shopLoginForm.Show(); - } - else - { - PddMobileLoginForm shopLoginForm = new PddMobileLoginForm(buyer); - shopLoginForm.openType = EnumOpenType.login; - shopLoginForm.InitUrl = "https://mobile.yangkeduo.com/login.html?from=https%3A%2F%2Fmobile.yangkeduo.com%2Fpersonal.html"; - shopLoginForm.ShowDialog(); - MainWindow.Instance.GetPddBuyer(); - } - } + //PddMobileLoginForm pddBuyerForm = new PddMobileLoginForm(buyer); + //pddBuyerForm.openType = TemuKJD.ToolForms.EnumOpenType.login; + //pddBuyerForm.InitUrl = "https://mobile.yangkeduo.com/login.html?from=https%3A%2F%2Fmobile.yangkeduo.com%2Fpersonal.html"; + //pddBuyerForm.ShowDialog(); + //MainWindow.Instance.GetPddBuyer(); + } - private void cmbPddBuyer_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - BuyerLoginInfo buyer = null; - if (cmbPddBuyer.SelectedItem != null) - { - buyer = cmbPddBuyer.SelectedItem as BuyerLoginInfo; - } - GlobalConfig.CurrentPddBuyer = buyer; - } + private void cmbPddBuyer_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + if (e.GetPosition(sender as IInputElement).X > cmbPddBuyer.ActualWidth - 18) + return; - private void btnDeleteItem_Click(object sender, RoutedEventArgs e) - { - if (BaseMsgWindow.ShowConfirm("确定删除吗?删除后不可恢复!").DialogResult != true) - return; + BuyerLoginInfo buyer = null; + if (cmbPddBuyer.SelectedItem != null) + { + buyer = cmbPddBuyer.SelectedItem as BuyerLoginInfo; + } + if (buyer == null) + return; - if (sender is Button btn) - { - if (btn.DataContext is BuyerLoginInfo buyer) - { - Task.Run(() => - { - var url = BaseClass.Build29PDDObjString("user/del_buyer"); - var data = UserLogin.GetSignaturex() - + "&buyer_id=" + buyer.buyer_id; - var result = GetHtml.PostUtf8(url, data); - if (result.Contains("\"code\":200")) - { - Dispatcher.Invoke(new Action(() => - { - GlobalConfig.PDDBuyerLoginList.Remove(buyer); - this.cmbPddBuyer.SelectedIndex = 0; - })); - } - }); - } - } - //var pddBuyer = + bool islogin = false; + PddMobileLoginViewModel.CheckBuyerLogin(new List { buyer }, false); + PddMobileLoginView shopLoginForm = new PddMobileLoginView(buyer); + if (buyer.status == "在线") + { + shopLoginForm.ViewModel.OpenType = EnumOpenType.manage; + shopLoginForm.ViewModel.InitUrl = "https://mobile.yangkeduo.com"; + //shopLoginForm.Show(); + } + else + { + shopLoginForm.ViewModel.OpenType = EnumOpenType.login; + shopLoginForm.ViewModel.InitUrl = "https://mobile.yangkeduo.com/login.html?from=https%3A%2F%2Fmobile.yangkeduo.com%2Fpersonal.html"; + //shopLoginForm.ShowDialog(); + islogin = true; - //var ids = dgvBuyer.Rows.Cast().Where(r => r.Cells["colSelect"].Value.ParseToBool() == true).Select(s => s.Cells["colBuyerId"].Value.ParseToString()).ToList(); - //var buyers = GlobalConfig.PDDBuyerLoginList.Where(b => ids.Contains(b.buyer_id)).ToList(); - //this.statusBar.pgbTaskProgress.Maximum = buyers.Count; - //pbLoading.Visible = true; + } + new DialogWindow() + { + Title = "买手登录", + Content = shopLoginForm, + }.ShowDialog(); + if (islogin) + MainWindow.Instance.GetPddBuyer(); + } - //Task.Run(() => - //{ - // int i = 0; - // foreach (var buyer in buyers) - // { - // i++; - // this.Invoke(new Action(() => - // { - // this.statusBar.lblTaskStatus.Text = "正在删除..."; - // this.statusBar.pgbTaskProgress.Value = i; - // this.statusBar.pgbTaskProgress.Text = i + "/" + buyers.Count; - // })); + private void cmbPddBuyer_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + BuyerLoginInfo buyer = null; + if (cmbPddBuyer.SelectedItem != null) + { + buyer = cmbPddBuyer.SelectedItem as BuyerLoginInfo; + } + GlobalConfig.CurrentPddBuyer = buyer; + } + + private void btnDeleteItem_Click(object sender, RoutedEventArgs e) + { + if (BaseMsgWindow.ShowConfirm("确定删除吗?删除后不可恢复!").DialogResult != true) + return; + + if (sender is Button btn) + { + if (btn.DataContext is BuyerLoginInfo buyer) + { + Task.Run(() => + { + var url = BaseClass.Build29PDDObjString("user/del_buyer"); + var data = UserLogin.GetSignaturex() + + "&buyer_id=" + buyer.buyer_id; + var result = GetHtml.PostUtf8(url, data); + if (result.Contains("\"code\":200")) + { + Dispatcher.Invoke(new Action(() => + { + GlobalConfig.PDDBuyerLoginList.Remove(buyer); + this.cmbPddBuyer.SelectedIndex = 0; + })); + } + }); + } + } + //var pddBuyer = + + //var ids = dgvBuyer.Rows.Cast().Where(r => r.Cells["colSelect"].Value.ParseToBool() == true).Select(s => s.Cells["colBuyerId"].Value.ParseToString()).ToList(); + //var buyers = GlobalConfig.PDDBuyerLoginList.Where(b => ids.Contains(b.buyer_id)).ToList(); + //this.statusBar.pgbTaskProgress.Maximum = buyers.Count; + //pbLoading.Visible = true; + + //Task.Run(() => + //{ + // int i = 0; + // foreach (var buyer in buyers) + // { + // i++; + // this.Invoke(new Action(() => + // { + // this.statusBar.lblTaskStatus.Text = "正在删除..."; + // this.statusBar.pgbTaskProgress.Value = i; + // this.statusBar.pgbTaskProgress.Text = i + "/" + buyers.Count; + // })); - // Thread.Sleep(100); - // } - // this.Invoke(new Action(() => - // { - // this.statusBar.lblTaskStatus.Text = "删除完成"; - // this.statusBar.pgbTaskProgress.Value = buyers.Count; - // this.statusBar.pgbTaskProgress.Text = buyers.Count + "/" + buyers.Count; - // })); - // GetPddBuyer(); - //}); - } + // Thread.Sleep(100); + // } + // this.Invoke(new Action(() => + // { + // this.statusBar.lblTaskStatus.Text = "删除完成"; + // this.statusBar.pgbTaskProgress.Value = buyers.Count; + // this.statusBar.pgbTaskProgress.Text = buyers.Count + "/" + buyers.Count; + // })); + // GetPddBuyer(); + //}); + } - private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) - { - if (MainWindow.Instance.gridPddBuyerOrderReadCtrl.Visibility != Visibility.Visible) - MainWindow.Instance.gridPddBuyerOrderReadCtrl.Visibility = Visibility.Visible; - if (Panel.GetZIndex(MainWindow.Instance.gridPddBuyerOrderReadCtrl) < 1) - Panel.SetZIndex(MainWindow.Instance.gridPddBuyerOrderReadCtrl, 1); - else - Panel.SetZIndex(MainWindow.Instance.gridPddBuyerOrderReadCtrl, -1); - } - } + private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + if (MainWindow.Instance.gridPddBuyerOrderReadCtrl.Visibility != Visibility.Visible) + MainWindow.Instance.gridPddBuyerOrderReadCtrl.Visibility = Visibility.Visible; + if (Panel.GetZIndex(MainWindow.Instance.gridPddBuyerOrderReadCtrl) < 1) + Panel.SetZIndex(MainWindow.Instance.gridPddBuyerOrderReadCtrl, 1); + else + Panel.SetZIndex(MainWindow.Instance.gridPddBuyerOrderReadCtrl, -1); + } + } } diff --git a/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.xaml.cs b/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.xaml.cs index 8395e0f..e5033be 100644 --- a/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.xaml.cs +++ b/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.xaml.cs @@ -42,7 +42,7 @@ using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Xml; using System.Xml.Linq; -using TemuKJD.ToolForms; +using _29WxOrderWpf.ViewModels; using Work; using Work._29Tools.BLL; using Work.BuyUsers; @@ -2136,7 +2136,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls // 检测一下买手号 if (buyer.status == "在线") { - PddMobileLoginForm.CheckBuyerLogin(buyer); + PddMobileLoginViewModel.CheckBuyerLogin(buyer); } if (buyer.status != "在线") { diff --git a/29WxOrderWpf/Ctrls/OrderCtrls/OrderListRowItemCtrl.xaml.cs b/29WxOrderWpf/Ctrls/OrderCtrls/OrderListRowItemCtrl.xaml.cs index 3d44941..c2cd7cf 100644 --- a/29WxOrderWpf/Ctrls/OrderCtrls/OrderListRowItemCtrl.xaml.cs +++ b/29WxOrderWpf/Ctrls/OrderCtrls/OrderListRowItemCtrl.xaml.cs @@ -30,6 +30,7 @@ using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; +using _29WxOrderWpf.ViewModels; using TemuKJD.ToolForms; using Work; using Work._29Tools.BLL; @@ -381,7 +382,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls // 拍单前检测买手号是否在线 if (GlobalConfig.CurrentPddBuyer.status == "在线") { - PddMobileLoginForm.CheckBuyerLogin(GlobalConfig.CurrentPddBuyer); + PddMobileLoginViewModel.CheckBuyerLogin(GlobalConfig.CurrentPddBuyer); } if (GlobalConfig.CurrentPddBuyer.status != "在线") { @@ -751,7 +752,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls // 拍单的时候检测一下买手号 if (buyer.status == "在线") { - PddMobileLoginForm.CheckBuyerLogin(buyer); + PddMobileLoginViewModel.CheckBuyerLogin(buyer); } if (buyer.status != "在线") { @@ -811,7 +812,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls // 拍单的时候检测一下买手号 if (buyer.status == "在线") { - PddMobileLoginForm.CheckBuyerLogin(buyer); + PddMobileLoginViewModel.CheckBuyerLogin(buyer); } if (buyer.status != "在线") { @@ -946,7 +947,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls { await Task.Run(() => { - PddMobileLoginForm.CheckBuyerLogin(GlobalConfig.CurrentPddBuyer); + PddMobileLoginViewModel.CheckBuyerLogin(GlobalConfig.CurrentPddBuyer); }); } if (GlobalConfig.CurrentPddBuyer.status != "在线") @@ -1265,7 +1266,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls // 检测买手号是否掉线 if (GlobalConfig.CurrentPddBuyer.status == "在线") { - PddMobileLoginForm.CheckBuyerLogin(GlobalConfig.CurrentPddBuyer); + PddMobileLoginViewModel.CheckBuyerLogin(GlobalConfig.CurrentPddBuyer); } if (GlobalConfig.CurrentPddBuyer.status != "在线") { @@ -1478,7 +1479,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls // 检测一下买手号 if (buyer.status == "在线") { - PddMobileLoginForm.CheckBuyerLogin(buyer); + PddMobileLoginViewModel.CheckBuyerLogin(buyer); } if (buyer.status != "在线") { diff --git a/29WxOrderWpf/MainWindow.xaml b/29WxOrderWpf/MainWindow.xaml index ac0d20a..3a26ba2 100644 --- a/29WxOrderWpf/MainWindow.xaml +++ b/29WxOrderWpf/MainWindow.xaml @@ -1,72 +1,204 @@ - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/29WxOrderWpf/MainWindow.xaml.cs b/29WxOrderWpf/MainWindow.xaml.cs index 912d004..e533969 100644 --- a/29WxOrderWpf/MainWindow.xaml.cs +++ b/29WxOrderWpf/MainWindow.xaml.cs @@ -450,5 +450,20 @@ namespace _29WxOrderWpf //else // Panel.SetZIndex(MainWindow.Instance.gridPddBuyerOrderReadCtrl, -1); } - } + + private void gridTitle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + if (e.ClickCount == 2) + { + // 双击切换窗口状态 + this.WindowState = this.WindowState == WindowState.Maximized + ? WindowState.Normal + : WindowState.Maximized; + } + else if (e.LeftButton == MouseButtonState.Pressed) + { + this.DragMove(); + } + } + } } diff --git a/29WxOrderWpf/ViewModels/PddMobileLoginViewModel.cs b/29WxOrderWpf/ViewModels/PddMobileLoginViewModel.cs new file mode 100644 index 0000000..f12b92f --- /dev/null +++ b/29WxOrderWpf/ViewModels/PddMobileLoginViewModel.cs @@ -0,0 +1,511 @@ +using _29WxOrderWpf.CefHelper; +using _29WxOrderWpf.Commands; +using AllBase; +using AllBase.Helper; +using AllBase.Model.DBModel; +using AllBase.Model.MvvmBaseClasses; +using CefSharp; +using CefSharp.Handler; +using CefSharp.Wpf; +using NaiBa.Util.Extension; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using TemuKJD.ToolForms; +using Work; +using Work._29Tools.BLL; +using Work._29Tools.CefTools; + +namespace _29WxOrderWpf.ViewModels +{ + + + /// + /// 拼多多买手移动版登录窗口 视图模型(WPF 版 PddMobileLoginForm) + /// + public class PddMobileLoginViewModel : PropertyNotifyObject + { + // 拼多多买手退货退款售后地址 + // https://mobile.yangkeduo.com/complaint.html?order_sn=260718-101481213440980&after_sales_reason=0&after_sales_type=2&after_sales_code=1002 + + public static PddMobileLoginViewModel PddMobileLoginInstance { get; set; } = null; + + /// 浏览器创建完成后触发(视图在此把浏览器加入可视树) + public event Action BrowserCreated; + + /// 请求关闭窗口 + public event Action RequestClose; + + public int CloseAfterSecond { get; set; } + + private EnumOpenType _openType = EnumOpenType.manage; + public EnumOpenType OpenType + { + get { return _openType; } + set + { + _openType = value; + OnPropertyChanged(nameof(OpenType)); + OnPropertyChanged(nameof(IsLoginMode)); + } + } + + public string InitUrl { get; set; } = ""; + + private string shopCookieHead = "yangkeduo.com"; + private string shopLoginUrl = "https://mobile.yangkeduo.com/login.html?from=https%3A%2F%2Fmobile.yangkeduo.com%2Fpersonal.html"; + private string shopMainUrl = "https://mobile.yangkeduo.com/index.html"; + + public ChromiumWebBrowser CefWebBrowser { get; private set; } + private BuyerLoginInfo buyer = null; + private List lstShopCompany = new List(); + private string currentUrl = ""; + private volatile bool _isWindowLoaded = false; + + #region 界面绑定属性 + + /// 用户名 + public string UserName + { + get { return this.GetValue(x => x.UserName); } + set { this.SetValue(x => x.UserName, value); } + } + + /// 密码 + public string PassWord + { + get { return this.GetValue(x => x.PassWord); } + set { this.SetValue(x => x.PassWord, value); } + } + + /// 地址栏 + public string Address + { + get { return this.GetValue(x => x.Address); } + set { this.SetValue(x => x.Address, value); } + } + + /// 登录成功后关闭窗口 + public bool IsCloseAfterLogin + { + get { return this.GetValue(x => x.IsCloseAfterLogin); } + set { this.SetValue(x => x.IsCloseAfterLogin, value); } + } + + /// 登录模式(显示扫码提示和导入PDDAccessToken面板) + public bool IsLoginMode + { + get { return this.GetValue(x => x.IsLoginMode); } + set { this.SetValue(x => x.IsLoginMode, value); } + } + + /// 导入的PDDAccessToken + public string AccessToken + { + get { return this.GetValue(x => x.AccessToken); } + set { this.SetValue(x => x.AccessToken, value); } + } + + #endregion + + #region 命令 + + public ICommand ReloadCommand { get; } + public ICommand LoginAgainCommand { get; } + public ICommand StopCommand { get; } + public ICommand CopyUserNameCommand { get; } + public ICommand CopyPasswordCommand { get; } + public ICommand SaveCookieCommand { get; } + + #endregion + + public PddMobileLoginViewModel(BuyerLoginInfo buyerInfo) + { + PddMobileLoginInstance = this; + + buyer = buyerInfo; + UserName = buyerInfo?.buyer_name; + PassWord = ""; //DataOpenSSL.DecryptString(buyerInfo.Password); + IsCloseAfterLogin = true; + IsLoginMode = OpenType == EnumOpenType.login; + + ReloadCommand = new DelegateCommand(Reload); + LoginAgainCommand = new DelegateCommand(LoginAgain); + StopCommand = new DelegateCommand(StopButton); + CopyUserNameCommand = new DelegateCommand(CopyUserName); + CopyPasswordCommand = new DelegateCommand(CopyPassword); + SaveCookieCommand = new DelegateCommand(SaveCookie); + } + + /// + /// 窗口加载完成时调用 + /// + public void Start() + { + IsLoginMode = OpenType == EnumOpenType.login; + _isWindowLoaded = true; + + if (CloseAfterSecond > 0) + { + Task.Run(() => + { + Thread.Sleep(1000 * CloseAfterSecond); + if (_isWindowLoaded) + { + Application.Current?.Dispatcher.Invoke(new Action(() => + { + if (_isWindowLoaded) + RequestClose?.Invoke(); + })); + } + }); + } + + AutoLogin(); + } + + /// + /// 窗口关闭时调用,停止后台任务 + /// + public void Stop() + { + _isWindowLoaded = false; + } + + /// + /// 自动登录店铺后台 + /// + private void AutoLogin() + { + if (OpenType != EnumOpenType.login && buyer == null) + return; + + if (CefWebBrowser == null) + { + if (!string.IsNullOrEmpty(InitUrl)) + CefWebBrowser = WPFCEFBrowser.CreateChromiumWebBrowser(InitUrl, false); + else + CefWebBrowser = WPFCEFBrowser.CreateChromiumWebBrowser(shopMainUrl, false); + + LocalResourceRequestHandler resourceRequestHandler = new LocalResourceRequestHandler(); + resourceRequestHandler.ResourceLoadCompleteEvent += RequestHandler_ResourceLoadComplete; + resourceRequestHandler.BeforeResourceLoadEvent += RequestHandler_BeforeResourceLoad; + CefWebBrowser.RequestHandler = new LocalRequestHandler(resourceRequestHandler); + var lifeSapnHandler = new LocalLifeSpanHandler(PopWindowType.SelfWindow); + CefWebBrowser.LifeSpanHandler = lifeSapnHandler; + CefWebBrowser.KeyboardHandler = new KeyboardHandler(); + CefWebBrowser.FrameLoadEnd += CefWebBrowser_FrameLoadEnd; + CefWebBrowser.AddressChanged += CefWebBrowser_AddressChanged; + CefWebBrowser.LoadError += CefWebBrowser_LoadError; + + // 通知视图把浏览器加入可视树(必须在等待浏览器初始化之前完成) + BrowserCreated?.Invoke(CefWebBrowser); + + List cookieLst = new List(); + try + { + if (buyer != null) + { + cookieLst = JsonHelper.DeserializeJsonToList(buyer?.cookie); + if (cookieLst == null) + cookieLst = new List(); + } + } + catch + { + } + + Task.Run(() => + { + // cef138必须init后方可设置或删除cookie + while (!CefWebBrowser.IsBrowserInitialized || !CefWebBrowser.GetBrowser().MainFrame.IsValid) + Thread.Sleep(20); + WPFCEFBrowser.DeleteCookie(CefWebBrowser.GetCookieManager(null)); + + //cef 138 如果没有设置RequestContext 可能为空,直接getCookieManager + var t = WPFCEFBrowser.SetCookieAsync(JsonHelper.SerializeObject(cookieLst), CefWebBrowser.GetCookieManager(null)); + foreach (var cook in cookieLst) + { + //var t = CEFBrowser.SetCookieAsync(cook.Domain.Trim('.'), cook.Name + "=" + cook.Value + ";", CefWebBrowser.GetCookieManager(null)); + //t.Wait(5000); + } + + //根据登录的具体店铺设置local storage + if (!string.IsNullOrEmpty(buyer?.buyer_id)) + { + //var storageJsCode = "window.localStorage.setItem('" + "mall-info-id" + "', '" + shop.ShopId + "');\r\n"; + //storageJsCode += "window.localStorage.setItem('" + "agentseller-mall-info-id" + "', '" + shop.ShopId + "');\r\n"; + //while (!CefWebBrowser.IsBrowserInitialized || !CefWebBrowser.GetBrowser().MainFrame.IsValid) + // Thread.Sleep(20); + //CefWebBrowser.GetBrowser().MainFrame.ExecuteJavaScriptAsync(storageJsCode); + } + + if (!string.IsNullOrEmpty(InitUrl)) + CefWebBrowser.Load(InitUrl); + else + CefWebBrowser.Load(shopMainUrl); + + //不是登录的话就此返回 + if (OpenType != EnumOpenType.login) + { + return; + } + + for (int i = 0; i < 50; i++) + { + if (CefWebBrowser.IsLoading) + Thread.Sleep(100); + } + Thread.Sleep(Randomx.GetId(1500, 2000)); + + if (!_isWindowLoaded) + return; + + while (!CefWebBrowser.Address.StartsWith(shopLoginUrl)) + { + Thread.Sleep(1000); + if (!_isWindowLoaded) + return; + } + }); + } + } + + private void CefWebBrowser_LoadError(object sender, CefSharp.LoadErrorEventArgs e) + { + } + + private void CefWebBrowser_AddressChanged(object sender, DependencyPropertyChangedEventArgs e) + { + if (Application.Current?.Dispatcher != null) + { + Application.Current.Dispatcher.Invoke(new Action(() => + { + currentUrl = e.NewValue.ParseToString(); + Address = e.NewValue.ParseToString(); + })); + } + } + + 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()); + } + + 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.Contains("https://mobile.yangkeduo.com/index.html") && OpenType == EnumOpenType.login) + { + Task.Run(() => { CefWebBrowser.Load("https://mobile.yangkeduo.com/personal.html"); }); + } + + if (url.Contains("https://mobile.yangkeduo.com/personal.html")) + { + if (OpenType == EnumOpenType.login) + { + Task.Run(() => + { + var data = responseData; + if (data.Contains("\"success\":true") || data.Contains("nickname")) + { + var uid = BaseRegex.GetStringJson(ref data, "uid"); + var nickname = BaseRegex.GetStringJson(ref data, "nickname"); + var username = nickname; + + if (!string.IsNullOrEmpty(nickname) && !string.IsNullOrEmpty(uid)) + { + Thread.Sleep(2000); + + List cookieList = WPFCEFBrowser.GetCookieList(shopCookieHead, CefWebBrowser.GetCookieManager(null)); + + var buyerUrl = BaseClass.Build29PDDObjString("user/add_buyer"); + + if (this.buyer == null || this.buyer.buyer_id != uid) + this.buyer = GlobalConfig.PDDBuyerLoginList.FirstOrDefault(b => b.buyer_id == uid); + if (this.buyer != null) + { + this.buyer.user_name = username; + this.buyer.buyer_nick = nickname; + this.buyer.cookie = JsonHelper.SerializeObject(cookieList); + buyerUrl = BaseClass.Build29PDDObjString("user/mdy_buyer"); + } + + var buyerData = UserLogin.GetSignaturex() + + "&buyer_id=" + uid + + "&buyer_name=" + username + + "&buyer_nick=" + nickname; + var result = GetHtml.PostUtf8(buyerUrl, buyerData); + if (string.IsNullOrEmpty(result) || !result.Contains("\"code\":200")) + result = GetHtml.PostUtf8(buyerUrl, buyerData); + + buyerUrl = BaseClass.Build29PDDObjString("user/mdy_buyer_cookie"); + buyerData = UserLogin.GetSignaturex() + + "&buyer_id=" + uid + + "&status=" + "在线" + + "&cookie=" + GetHtml.UrlEncodeUtf8(JsonHelper.SerializeObject(cookieList)); + result = GetHtml.PostUtf8(buyerUrl, buyerData); + if (string.IsNullOrEmpty(result) || !result.Contains("\"code\":200")) + result = GetHtml.PostUtf8(buyerUrl, buyerData); + + Application.Current?.Dispatcher.Invoke(new Action(() => + { + try + { + if (IsCloseAfterLogin) + RequestClose?.Invoke(); + } + catch (Exception ex) + { } + })); + } + } + }); + } + } + } + + private void StopButton() + { + } + + private void CopyUserName() + { + if (!string.IsNullOrEmpty(UserName)) + Clipboard.SetDataObject(UserName); + } + + private void CopyPassword() + { + if (!string.IsNullOrEmpty(PassWord)) + Clipboard.SetDataObject(PassWord); + } + + private void Reload() + { + if (CefWebBrowser != null) + { + if (Address != "about:blank") + CefWebBrowser.Load(Address); + else + CefWebBrowser.Load(shopMainUrl); + } + } + + private void LoginAgain() + { + if (this.currentUrl != shopLoginUrl) + this.CefWebBrowser?.Load(shopLoginUrl); + } + + private void SaveCookie() + { + Cookie cookie = new Cookie(); + cookie.Name = "PDDAccessToken"; + cookie.Domain = "mobile.yangkeduo.com"; + cookie.Expires = DateTime.Now.AddDays(465); + cookie.HttpOnly = true; + cookie.Secure = true; + cookie.Value = AccessToken.Trim(); + + if (this.CefWebBrowser != null) + { + var t = WPFCEFBrowser.SetCookieAsync(JsonHelper.SerializeObject(new List { cookie }), CefWebBrowser.GetCookieManager(null)); + t.Wait(2000); + CefWebBrowser.Load("https://mobile.yangkeduo.com/personal.html"); + } + } + + #region 静态方法(检测/更新买手登录状态) + + public static void CheckBuyerLogin(List checkBuyers, bool isShowProgress = true) + { + for (int i = 0; i < checkBuyers.Count; i++) + { + var buyer = GlobalConfig.PDDBuyerLoginList.FirstOrDefault(v => v.buyer_id == checkBuyers[i].buyer_id); + var buys = GlobalConfig.PDDBuyerLoginList.Where(v => v.buyer_id == checkBuyers[i].buyer_id).ToList(); + if (buyer == null) + continue; + + // 先从服务端取最新cookie + var url = BaseClass.Build29PDDObjString("user/get_buyer"); + var data = UserLogin.GetSignaturex(); + data += "&buyer_ids=" + buyer.buyer_id; + data += "&page_size=1"; + var result = GetHtml.PostUtf8(url, data); + if (string.IsNullOrEmpty(result) || !result.Contains("\"code\":200")) + result = GetHtml.PostUtf8(url, data); + if (!result.Contains("\"code\":200")) + continue; + List loginInfoLst = JsonHelper.DeserializeJsonToList(JsonHelper.JObjectParse(result)["data"].ParseToString()); + + var serverBuyer = loginInfoLst.FirstOrDefault(); + if (buyer != null && serverBuyer != null) + { + buyer.cookie = serverBuyer.cookie; + foreach (var buy in buys) + { + buy.cookie = serverBuyer.cookie; + } + } + + if (buyer != null) + { + var loginResult = CheckBuyerLogin(buyer); + if (!loginResult.Contains("\"success\":true") && !loginResult.Contains("\"login\":true") && !loginResult.Contains("\"nickname\"")) + { + buyer.cookie = "[]"; + foreach (var buy in buys) + { + buy.status = "掉线"; + buy.cookie = "[]"; + } + } + else + { + foreach (var buy in buys) + { + buy.status = "在线"; + } + } + UpdateServerBuyerCookies(buyer); // 店铺cookie和状态写入服务端 + } + } + } + + public static string CheckBuyerLogin(BuyerLoginInfo buyer, string refere = "https://mobile.yangkeduo.com/goods.html") + { + string url = "https://mobile.yangkeduo.com/proxy/api/api/apollo/v3/user/me?pdduid=" + buyer.buyer_id; + return HttpResponseYkdBLL.YangkeduoGetResponse(buyer, url, refere); + } + + public static string UpdateServerBuyerCookies(BuyerLoginInfo buyer, string fromTool = null) + { + var url = BaseClass.Build29PDDObjString("user/mdy_buyer_cookie"); + var data = UserLogin.GetSignaturex() + + "&status=" + buyer.status + + "&cookie=" + GetHtml.UrlEncodeUtf8(buyer.cookie) + + "&buyer_id=" + buyer.buyer_id; + var result = GetHtml.PostUtf8(url, data); + if (!result.Contains("\"code\":200")) + result = GetHtml.PostUtf8(url, data); + return result; + } + + #endregion + } +} \ No newline at end of file diff --git a/29WxOrderWpf/Views/PddMobileLoginView.xaml b/29WxOrderWpf/Views/PddMobileLoginView.xaml new file mode 100644 index 0000000..19ca9bc --- /dev/null +++ b/29WxOrderWpf/Views/PddMobileLoginView.xaml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +