1415 lines
63 KiB
C#
1415 lines
63 KiB
C#
using AllBase;
|
||
using AllBase.Helper;
|
||
using AllBase.Model.Config;
|
||
using AllBase.Model.Result;
|
||
using CefSharp;
|
||
using CefSharp.DevTools.LayerTree;
|
||
using CefSharp.WinForms;
|
||
using NaiBa.CefHelper;
|
||
using NaiBa.CefHelper.Handler;
|
||
using NaiBa.Util;
|
||
using NaiBa.Util.Extension;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Diagnostics;
|
||
using System.Drawing;
|
||
using System.IO;
|
||
using System.IO.Compression;
|
||
using System.Linq;
|
||
using System.Media;
|
||
using System.Runtime.InteropServices;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using TemuKJD.BaseForms;
|
||
using TemuKJD.BLL;
|
||
using TemuKJD.BLL.Tools;
|
||
using TemuKJD.Extension;
|
||
using TemuKJD.Helper;
|
||
using TemuKJD.ToolForms;
|
||
using TemuKJD.WXForms.ShopForms;
|
||
using TemuKJD.WXForms.TalkForms;
|
||
using TemuKJD.WXForms.TalkForms.TalkHelper;
|
||
using TemuKJD.WXForms.TalkForms.TalkModel;
|
||
|
||
namespace TemuKJD.WXForms.AiTalkForms
|
||
{
|
||
public partial class WxAiTalkForm : BaseTalkForm
|
||
{
|
||
public string AiTalkUrl = "http://14.103.99.254";
|
||
public string AiTalkUserId = "";
|
||
|
||
public static WxAiTalkForm instance { get; set; }
|
||
|
||
/// <summary>
|
||
/// 自动回复话术信息
|
||
/// </summary>
|
||
public static List<KeyValuePair<string, string>> LstTalkTemplatePair { get; set; } = null;
|
||
public Dictionary<string, int> dicTalkAutoReplyCount = new Dictionary<string, int>();
|
||
|
||
/// <summary>
|
||
/// 客服统计信息
|
||
/// </summary>
|
||
public ConcurrentList<WxShopKfStatistics> lstShopKfStatistics = new ConcurrentList<WxShopKfStatistics>();
|
||
/// <summary>
|
||
/// 店铺主页统计信息
|
||
/// </summary>
|
||
public ConcurrentList<WxTalkFormShopMainInfo> lstShopAfterSale = new ConcurrentList<WxTalkFormShopMainInfo>();
|
||
|
||
/// <summary>
|
||
/// 等待自动回复的消息队列
|
||
/// </summary>
|
||
public ConcurrentList<AutoReplayParam> lstAutoReplayParam = new ConcurrentList<AutoReplayParam>();
|
||
|
||
public delegate void SearchResultReceivedHandler(ShopLoginInfo shop);
|
||
/// <summary>
|
||
/// 查询结果事件通知
|
||
/// </summary>
|
||
public event SearchResultReceivedHandler SearchResultReceived;
|
||
|
||
public delegate void InfomationReceivedHandler(string infomation);
|
||
/// <summary>
|
||
/// 消息事件通知,比如:异常等通知
|
||
/// </summary>
|
||
/// <param name="infomation"></param>
|
||
public event InfomationReceivedHandler InfomationReceived;
|
||
|
||
public static ShopLoginInfo currentShop = null;
|
||
ChromiumWebBrowser mainWebBrowser = null;
|
||
ChromiumWebBrowser aiTalkWebBrowser = null;
|
||
ChromiumWebBrowser aiTalkAdminWebBrowser = null;
|
||
|
||
/// <summary>
|
||
/// 弹出框列表
|
||
/// </summary>
|
||
public static Dictionary<DataGridViewRow, Color> dicRowColor = new Dictionary<DataGridViewRow, Color>();
|
||
public List<string> LstTagShop = new List<string>();
|
||
|
||
public PDDBuyerOrderListForm orderListForm = null;
|
||
|
||
DateTime nextRefreshTime = DateTime.Now.AddMinutes(30);
|
||
|
||
public WxAiTalkForm()
|
||
{
|
||
InitializeComponent();
|
||
|
||
instance = this;
|
||
ChatConfig.LoadChatSetting();
|
||
}
|
||
|
||
private void WxTalkForm_FormClosed(object sender, FormClosedEventArgs e)
|
||
{
|
||
Process.GetCurrentProcess().Kill();
|
||
}
|
||
|
||
private void WxTalkForm_Load(object sender, EventArgs e)
|
||
{
|
||
this.splitContainer3.SplitterDistance = 0;
|
||
this.dgvShop.AddSelectorColumn("colSelect");
|
||
|
||
//this.ucTabControl1.SelectedIndex = 2;
|
||
//Task.Run(() =>
|
||
//{
|
||
// Thread.Sleep(2000);
|
||
// Invoke(new Action(() =>
|
||
// {
|
||
// this.ucTabControl1.SelectedIndex = 0;
|
||
// }));
|
||
//});
|
||
|
||
if (BaseClass.LogoImage != null)
|
||
pbLogo.Image = BaseClass.LogoImage;
|
||
if (BaseClass.Ico != null)
|
||
this.Icon = BaseClass.Ico;
|
||
else
|
||
this.Icon = BaseClass.Ico = ImageBuild.ConvertToIcon(Properties.Resources.icon);
|
||
|
||
//#if DEBUG
|
||
//#else
|
||
ucTabControl1.TabPages.Remove(tpBuyerOrder);
|
||
//#endif
|
||
|
||
// 点击变绿的店铺
|
||
LstTagShop = NaiBa.Util.Helper.ConfigHelper.LoadConfig<List<string>>("wx_talk_tag_shop_list");
|
||
if (LstTagShop == null)
|
||
LstTagShop = new List<string>();
|
||
|
||
// 记录自动回复数量
|
||
dicTalkAutoReplyCount = NaiBa.Util.Helper.ConfigHelper.LoadConfig<Dictionary<string,int>>("wx_talk_auto_reply_count");
|
||
if (dicTalkAutoReplyCount == null)
|
||
dicTalkAutoReplyCount = new Dictionary<string, int>();
|
||
|
||
this.chkNotShowMessageWindow.CheckedChanged -= chkNotShowMessageWindow_CheckedChanged;
|
||
|
||
if (this.cmbMessage.Items.Contains(ChatConfig.ChatSettingConfig.MessageSound))
|
||
this.cmbMessage.SelectedItem = ChatConfig.ChatSettingConfig.MessageSound;
|
||
else
|
||
this.cmbMessage.SelectedIndex = 0;
|
||
this.chkNotShowMessageWindow.Checked = ChatConfig.ChatSettingConfig.IsNotShowMessageWindow;
|
||
|
||
this.cmbMessage.SelectedIndexChanged += cmbMessage_SelectedIndexChanged;
|
||
this.chkNotShowMessageWindow.CheckedChanged += chkNotShowMessageWindow_CheckedChanged;
|
||
|
||
SearchResultReceived += Chat_SearchResultReceived;
|
||
InfomationReceived += Collect_InfomationReceived;
|
||
|
||
// 加载店铺后台页面
|
||
if (mainWebBrowser == null)
|
||
{
|
||
mainWebBrowser = CEFBrowser.CreateChromiumWebBrowser("about:blank", false);
|
||
mainWebBrowser.KeyboardHandler = new KeyboardHandler();
|
||
mainWebBrowser.Dock = DockStyle.Fill;
|
||
//var lifeSpanHandler = new LifeSpanHandlerLocal(PopWindowType.NewTitleWindow);
|
||
//lifeSpanHandler.parent = mainWebBrowser;
|
||
//lifeSpanHandler.OnPop += MainLifeHandler_OnPop;
|
||
//mainWebBrowser.LifeSpanHandler = lifeSpanHandler;
|
||
mainWebBrowser.AddressChanged += MainWebBrowser_AddressChanged;
|
||
mainWebBrowser.FrameLoadEnd += MainWebBrowser_FrameLoadEnd;
|
||
mainPanel.Controls.Add(mainWebBrowser);
|
||
}
|
||
|
||
// 加载Ai客服页面
|
||
LoadAiTalk();
|
||
LoadAiTalkAdmin();
|
||
|
||
Task.Run(() =>
|
||
{
|
||
// 等待店铺初始化
|
||
// 直到店铺加载完后再加载客服内容
|
||
while (!StartUp.IsShopInit)
|
||
Thread.Sleep(100);
|
||
|
||
// 店铺加载完成后加载店铺后台页面
|
||
currentShop = GlobalConfig.ValidShopLoginList.FirstOrDefault();
|
||
Invoke(new Action(() =>
|
||
{
|
||
lblCurrentShop.Text = "当前店铺:" + currentShop.ShopAccount;
|
||
}));
|
||
SetMainBrowserUrl(currentShop);
|
||
LoadShop();
|
||
RefreshCookie(true);
|
||
Invoke(new Action(() =>
|
||
{
|
||
foreach (var shopNote in GlobalConfig.ValidShopLoginList.Select(s => s.Notes).Where(s => !s.IsNullOrEmpty()).Distinct())
|
||
{
|
||
this.cmbFiltNotes.Items.Add(shopNote);
|
||
}
|
||
foreach (var group in GlobalConfig.ValidShopLoginList.Select(s => s.GroupName).Where(s => !s.IsNullOrEmpty()).Distinct())
|
||
{
|
||
this.cmbFiltGroups.Items.Add(group);
|
||
}
|
||
|
||
lstShopAfterSale = NaiBa.Util.Helper.ConfigHelper.LoadConfig<NaiBa.Util.ConcurrentList<WxTalkFormShopMainInfo>>("wx_shop_after_sale_list");
|
||
if (lstShopAfterSale == null)
|
||
lstShopAfterSale = new ConcurrentList<WxTalkFormShopMainInfo>();
|
||
}));
|
||
// 加载店铺确认默认店铺后再初始化订单列表读取
|
||
InitOrderForm();
|
||
|
||
// 定时刷新
|
||
while (true)
|
||
{
|
||
Thread.Sleep(1000);
|
||
if (DateTime.Now > nextRefreshTime)
|
||
{
|
||
|
||
Invoke(new Action(() => { pbLoading.Visible = true; }));
|
||
nextRefreshTime = DateTime.Now.AddMinutes(30);
|
||
try
|
||
{
|
||
RefreshCookie(true);
|
||
LoadShop();
|
||
}
|
||
catch (Exception ex) { BaseMsgForm.ShowError("刷新Cookie出错 " + ex.Message); }
|
||
try
|
||
{
|
||
RefreshMsgCount();
|
||
}
|
||
catch (Exception ex) { BaseMsgForm.ShowError("刷新客服统计出错 " + ex.Message); }
|
||
try
|
||
{
|
||
RefreshAfterSale(true);
|
||
}
|
||
catch (Exception ex) { BaseMsgForm.ShowError("刷新售后出错 " + ex.Message); }
|
||
|
||
Invoke(new Action(() => { pbLoading.Visible = false; }));
|
||
}
|
||
var deltaTime = nextRefreshTime - DateTime.Now;
|
||
Invoke(new Action(() =>
|
||
{
|
||
this.btnRefreshShop.Text = "刷 新 店 铺 " + deltaTime.Minutes.ToString("00") + ":" + deltaTime.Seconds.ToString("00");
|
||
}));
|
||
}
|
||
});
|
||
|
||
// 关闭弹窗
|
||
ClosePopWindow();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化买手订单页面
|
||
/// </summary>
|
||
void InitOrderForm()
|
||
{
|
||
Invoke(new Action(() =>
|
||
{
|
||
//orderListForm = new PDDBuyerOrderListForm();
|
||
//orderListForm.TopLevel = false;
|
||
//orderListForm.FormBorderStyle = FormBorderStyle.None;
|
||
//orderListForm.Dock = DockStyle.Fill;
|
||
//orderListForm.lblCurrentShop.Text = currentShop?.ShopAccount;
|
||
//orderListForm.lblCurrentShop.Tag = currentShop;
|
||
//tpBuyerOrder.Controls.Add(orderListForm);
|
||
//orderListForm.Show();
|
||
}));
|
||
}
|
||
|
||
void ClosePopWindow()
|
||
{
|
||
//Task.Run(() =>
|
||
//{
|
||
// for (int i = 0; i < 120; i++)
|
||
// {
|
||
// foreach (var shop in GlobalConfig.ValidShopLoginList)
|
||
// {
|
||
// if (shop.Chat?.IsBrowserInitialized != true)
|
||
// continue;
|
||
|
||
// //关闭弹窗
|
||
// var jsStr1 = @"var btnLst = document.getElementsByTagName('button');
|
||
// for (i=0;i<btnLst.length;i++)
|
||
// {
|
||
// if (btnLst[i].innerHTML.indexOf('暂不启用') !== -1)
|
||
// btnLst[i].click();
|
||
// }";
|
||
// var response1 = shop.Chat.GetBrowser().MainFrame.EvaluateScriptAsync(jsStr1);
|
||
// response1.Wait(2000);
|
||
// }
|
||
// Thread.Sleep(500);
|
||
// }
|
||
//});
|
||
}
|
||
|
||
private void MainWebBrowser_AddressChanged(object sender, AddressChangedEventArgs e)
|
||
{
|
||
if (sender == currentShop?.Chat)
|
||
this.txtAddress.Text = e.Address;
|
||
}
|
||
|
||
private void MainWebBrowser_FrameLoadEnd(object sender, CefSharp.FrameLoadEndEventArgs e)
|
||
{
|
||
}
|
||
|
||
[DllImport("winmm.dll")]
|
||
public static extern uint mciSendString(string lpstrCommand, string lpstrReturnString, uint uReturnLength, uint hWndCallback);
|
||
/// <summary>
|
||
/// 播放提示音
|
||
/// </summary>
|
||
public void playSound()
|
||
{
|
||
string musicname = "默认提示音";
|
||
if (!string.IsNullOrEmpty(ChatConfig.ChatSettingConfig.MessageSound))
|
||
musicname = ChatConfig.ChatSettingConfig.MessageSound;
|
||
if (musicname == "无")
|
||
return;
|
||
if (musicname == "默认提示音")
|
||
musicname = "9527.wav";
|
||
else
|
||
musicname = musicname + ".mp3";
|
||
|
||
if (musicname.Contains("wav"))
|
||
{
|
||
try
|
||
{
|
||
SoundPlayer sound = new SoundPlayer("temp/" + musicname);
|
||
sound.Play();
|
||
}
|
||
catch
|
||
{
|
||
|
||
}
|
||
}
|
||
if (musicname.Contains("mp3"))
|
||
{
|
||
try
|
||
{
|
||
mciSendString(@"close ""temp/" + musicname + @"""", null, 0, 0);
|
||
mciSendString(@"open ""temp/" + musicname + @"""", null, 0, 0);
|
||
mciSendString(@"play ""temp/" + musicname + @"""", null, 0, 0);
|
||
}
|
||
catch
|
||
{ }
|
||
}
|
||
}
|
||
|
||
|
||
public void ShowChat(ShopLoginInfo shop)
|
||
{
|
||
//while (shop.Chat?.IsBrowserInitialized != true)
|
||
//{
|
||
// Thread.Sleep(50);
|
||
//}
|
||
//// 设置cef cookie
|
||
//if (shop.Chat != null && shop.Chat.IsBrowserInitialized)
|
||
//{
|
||
// var cookieManager = shop.Chat.RequestContext.GetCookieManager(null);
|
||
|
||
// var cookieLst = new List<Cookie>();
|
||
// try
|
||
// {
|
||
// cookieLst = JsonHelper.DeserializeJsonToList<CefSharp.Cookie>(shop.Cookies.ParseToString().Replace("empty=true;", "[]"));
|
||
// }
|
||
// catch
|
||
// {
|
||
// }
|
||
|
||
// cookieManager.DeleteCookies("qq.com", null);
|
||
// foreach (var cook in cookieLst)
|
||
// {
|
||
// var t = CEFBrowser.SetCookieAsync(cook.Domain, cook.Name + "=" + cook.Value + ";", cookieManager);
|
||
// t.Wait(5000);
|
||
// }
|
||
|
||
// if (shop.LoginStatus == "登录成功")
|
||
// shop.Chat.Load("https://store.weixin.qq.com/shop/kf");
|
||
//}
|
||
}
|
||
|
||
|
||
public void LoadShop(List<ShopLoginInfo> shopList = null)
|
||
{
|
||
if (shopList == null)
|
||
shopList = new List<ShopLoginInfo>();
|
||
if (shopList.Count == 0)
|
||
shopList.AddRange(GlobalConfig.ValidShopLoginList);
|
||
|
||
for (int i = 0; i < shopList.Count; i++)
|
||
{
|
||
var shop = shopList[i];
|
||
|
||
var r = dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(x => x.Cells["colShopId"].Value.ToString() == shop.ShopId);
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
int iGrid = 0;
|
||
if (r == null)
|
||
{
|
||
iGrid = dgvShop.Rows.Add();
|
||
if (iGrid == 0)
|
||
dgvShop.Rows[iGrid].Cells["colSelect"].Value = true;
|
||
r = dgvShop.Rows[iGrid];
|
||
}
|
||
r.Cells["colSelect"].Value = false;
|
||
r.Cells["colShopId"].Value = shop.ShopId; // 店铺ID
|
||
r.Cells["colShopName"].Value = shop.ShopAccount; // 店铺名称
|
||
r.Cells["colShopName"].Style.BackColor = LstTagShop.Contains(shop.ShopId) ? Color.LightGreen : (r.Tag is Color ? (Color)r.Tag : Color.White);
|
||
r.Cells["colGroup"].Value = shop.GroupName; // 分组
|
||
r.Cells["colShopNotes"].Value = shop.Notes; // 备注
|
||
r.Cells["colAutoReplyCount"].Value = dicTalkAutoReplyCount.FirstOrDefault(t => t.Key == shop.ShopId).Value.ParseToInt();
|
||
r.Cells["colLoginStatus"].Value = shop.LoginStatus == "登录成功" ? "在线" : "掉线"; // 登录状态
|
||
bool canUse = shop.LoginStatus == "登录成功";
|
||
(r.Cells["colLoginStatus"] as DataGridViewLinkCell).Style.ForeColor = canUse ? Color.Blue : Color.Red;
|
||
(r.Cells["colLoginStatus"] as DataGridViewLinkCell).LinkColor = canUse ? Color.Blue : Color.Red;
|
||
(r.Cells["colLoginStatus"] as DataGridViewLinkCell).ActiveLinkColor = canUse ? Color.LightBlue : Color.OrangeRed;
|
||
(r.Cells["colLoginStatus"] as DataGridViewLinkCell).VisitedLinkColor = canUse ? Color.DarkBlue : Color.DarkRed;
|
||
dicRowColor[r] = r.DefaultCellStyle.BackColor;
|
||
}));
|
||
}
|
||
}
|
||
|
||
void LoadAiTalk()
|
||
{
|
||
if (aiTalkWebBrowser == null)
|
||
{
|
||
aiTalkWebBrowser = CEFBrowser.CreateChromiumWebBrowser("about:blank", true);
|
||
CustomResourceRequestHandler resourceRequestHandler = new CustomResourceRequestHandler();
|
||
var handler = resourceRequestHandler;
|
||
handler.ResourceLoadCompleteEvent += AiRequestHandler_ResourceLoadComplete;
|
||
aiTalkWebBrowser.RequestHandler = new CustomRequestHandler(resourceRequestHandler);
|
||
aiTalkWebBrowser.KeyboardHandler = new KeyboardHandler();
|
||
var lifeHandler = new LifeSpanHandlerLocal(PopWindowType.NewWindow);
|
||
lifeHandler.OnPop += LifeHandler_OnPop;
|
||
lifeHandler.parent = aiTalkWebBrowser;
|
||
aiTalkWebBrowser.LifeSpanHandler = lifeHandler;
|
||
//var lifeSapnHandler = new LifeSpanHandlerLocal(PopWindowType.SelfWindow);
|
||
//aiTalkWebBrowser.LifeSpanHandler = lifeSapnHandler;
|
||
|
||
//RequestContextSettings requestContextSettings = new RequestContextSettings();
|
||
//requestContextSettings.PersistSessionCookies = false; // 会话 Cookie(未设置过期时间的 Cookie)仅在内存中存在,关闭浏览器进程后即被删除,下次启动需重新登录。
|
||
//requestContextSettings.PersistUserPreferences = false;
|
||
//aiTalkWebBrowser.RequestContext = new RequestContext(requestContextSettings);
|
||
aiTalkWebBrowser.Dock = DockStyle.Fill;
|
||
aiTalkWebBrowser.Load(AiTalkUrl + "/workbench");
|
||
pnlAiTalk.Controls.Add(aiTalkWebBrowser);
|
||
//while (aiTalkWebBrowser.IsBrowserInitialized != true)
|
||
//{
|
||
// Thread.Sleep(50);
|
||
//}
|
||
}
|
||
}
|
||
void LoadAiTalkAdmin()
|
||
{
|
||
pictureBox1.Visible = true;
|
||
if (aiTalkAdminWebBrowser == null)
|
||
{
|
||
aiTalkAdminWebBrowser = CEFBrowser.CreateChromiumWebBrowser("about:blank", false);
|
||
CustomResourceRequestHandler resourceRequestHandler = new CustomResourceRequestHandler();
|
||
var adminHandler = resourceRequestHandler;
|
||
adminHandler.ResourceLoadCompleteEvent += AdminAiRequestHandler_ResourceLoadComplete;
|
||
aiTalkAdminWebBrowser.RequestHandler = new CustomRequestHandler(resourceRequestHandler);
|
||
aiTalkAdminWebBrowser.KeyboardHandler = new KeyboardHandler();
|
||
//var lifeHandler = new LifeSpanHandlerLocal(PopWindowType.NewTitleWindow);
|
||
//lifeHandler.OnPop += LifeHandler_OnPop;
|
||
//lifeHandler.parent = aiTalkAdminWebBrowser;
|
||
//aiTalkAdminWebBrowser.LifeSpanHandler = lifeHandler;
|
||
aiTalkAdminWebBrowser.Dock = DockStyle.Fill;
|
||
aiTalkAdminWebBrowser.SendToBack();
|
||
}
|
||
aiTalkAdminWebBrowser.Load("http://14.103.99.254");
|
||
pnlShop.Controls.Add(aiTalkAdminWebBrowser);
|
||
|
||
Task.Run(() =>
|
||
{
|
||
while (!aiTalkAdminWebBrowser.Address.Contains("/admin"))
|
||
{
|
||
Thread.Sleep(500);
|
||
string loginJs = @"document.getElementById('username').value = 'admin';
|
||
document.getElementById('password').value = 'liangna123';
|
||
document.getElementsByTagName('button')[0].click();";
|
||
var response = aiTalkAdminWebBrowser.GetBrowser().MainFrame.EvaluateScriptAsync(loginJs);
|
||
response.Wait(2000);
|
||
Thread.Sleep(500);
|
||
}
|
||
|
||
string data = @"{""username"":""" + BaseClass.UserName + @""",""password"":""" + BaseClass.PassWord + @"""}";
|
||
string url = AiTalkUrl + "/login";
|
||
string refer = AiTalkUrl + "/workbench";
|
||
var rst = HttpResponseWxAiTalkBLL.PostResponse(new ShopLoginInfo(), url, data, refer);
|
||
if (!rst.Contains("\"ok\":true"))
|
||
{
|
||
//var cookies = CEFBrowser.GetCookieList("", aiTalkAdminWebBrowser.RequestContext.GetCookieManager(null));
|
||
var cookies = CEFBrowser.GetCookieList("", aiTalkAdminWebBrowser.RequestContext.GetCookieManager(null));
|
||
data = @"{""username"":""" + BaseClass.UserName + @""",""password"":""" + BaseClass.PassWord + @""",""role"":""supervisor"",""status"":""active"",""expiresAt"":"""",""storeIds"":[]}";
|
||
url = AiTalkUrl + "/api/users";
|
||
refer = AiTalkUrl + "workbench";
|
||
rst = HttpResponseWxAiTalkBLL.PostResponse(new ShopLoginInfo() { Cookies = JsonHelper.SerializeObject(cookies) }, url, data, refer);
|
||
if (!rst.Contains("\"username\":\"" + BaseClass.UserName + "\""))
|
||
{
|
||
BaseMsgForm.ShowError("AI客服账户登录失败,请稍候重试!");
|
||
return;
|
||
}
|
||
}
|
||
AiTalkUserId = BaseRegex.GetStringJson(ref rst, "id");
|
||
|
||
aiTalkWebBrowser.Load(AiTalkUrl + "/workbench");
|
||
Thread.Sleep(1000);
|
||
aiTalkWebBrowser.Load(AiTalkUrl + "/workbench");
|
||
Thread.Sleep(500);
|
||
|
||
while (aiTalkWebBrowser.Address.Contains("/login"))
|
||
{
|
||
Thread.Sleep(500);
|
||
string loginJs = @"document.getElementById('username').value='" + BaseClass.UserName + @"';
|
||
document.getElementById('password').value='" + BaseClass.PassWord + @"';
|
||
document.getElementsByTagName('button')[0].click();";
|
||
//var response = aiTalkWebBrowser.GetBrowser().MainFrame.EvaluateScriptAsync(loginJs);
|
||
var client = aiTalkWebBrowser.GetDevToolsClient();
|
||
if (client != null)
|
||
{
|
||
var result = client.Runtime.EvaluateAsync(loginJs, null, true, null, null, true, null, true);
|
||
result.Wait(5000);
|
||
}
|
||
//Invoke(new Action(() => {
|
||
// pnlCover.SendToBack();
|
||
//}));
|
||
Thread.Sleep(500);
|
||
}
|
||
|
||
var shopIds = string.Join(",", GlobalConfig.ShopLoginList.Select(s => s.ShopId));
|
||
url = AiTalkUrl + "/api/stores?page=1&pageSize=5000&keyword=" + shopIds;
|
||
refer = AiTalkUrl + "/api/stores";
|
||
var adminCookies = CEFBrowser.GetCookieList("", aiTalkAdminWebBrowser.RequestContext.GetCookieManager(null));
|
||
rst = HttpResponseWxAiTalkBLL.GetResponse(new ShopLoginInfo() { Cookies = JsonHelper.SerializeObject(adminCookies) }, url, refer);
|
||
|
||
if (rst.Contains("\"stores\":["))
|
||
{
|
||
List<ShopAiTalkInfo> aiTalkInfoLst = JsonHelper.DeserializeJsonToList<ShopAiTalkInfo>(JsonHelper.JObjectParse(rst)["stores"].ParseToString());
|
||
foreach (var shop in GlobalConfig.ShopLoginList)
|
||
{
|
||
shop.shopAiTalkInfo = aiTalkInfoLst.FirstOrDefault(s => s.id == shop.ShopId);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
BaseMsgForm.ShowError("AI客服账户登录失败,请稍候重试!");
|
||
return;
|
||
}
|
||
|
||
Thread.Sleep(1000);
|
||
|
||
foreach (var shop in GlobalConfig.ShopLoginList)
|
||
{
|
||
BindAiTalkStatus(shop);
|
||
}
|
||
|
||
Invoke(new Action(() => {
|
||
pnlCover.Visible = false;
|
||
pnlCover.SendToBack();
|
||
pictureBox1.Visible = false;
|
||
}));
|
||
});
|
||
}
|
||
|
||
private void BindAiTalkStatus(ShopLoginInfo shop)
|
||
{
|
||
var dgvRow = this.dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells["colShopId"].Value.ParseToString() == shop.ShopId);
|
||
if (dgvRow == null)
|
||
return;
|
||
|
||
if (shop.shopAiTalkInfo == null)
|
||
{
|
||
Invoke(new Action(() =>
|
||
{
|
||
dgvRow.Cells["colAiStatus"].Style.ForeColor = Color.Red;
|
||
dgvRow.Cells["colAiStatus"].Value = "点击授权";
|
||
}));
|
||
}
|
||
else if (!shop.shopAiTalkInfo.ownerNames.Contains(BaseClass.UserName))
|
||
{
|
||
Invoke(new Action(() =>
|
||
{
|
||
dgvRow.Cells["colAiStatus"].Style.ForeColor = Color.Purple;
|
||
dgvRow.Cells["colAiStatus"].Value = "未绑定用户";
|
||
}));
|
||
}
|
||
else
|
||
{
|
||
Invoke(new Action(() =>
|
||
{
|
||
dgvRow.Cells["colAiStatus"].Style.ForeColor = Color.Green;
|
||
dgvRow.Cells["colAiStatus"].Value = "已绑定";
|
||
}));
|
||
}
|
||
}
|
||
|
||
private void LoadShopAfterSale(WxTalkFormShopMainInfo shopAfterSale, string msg)
|
||
{
|
||
var r = dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(x => x.Cells["colShopId"].Value.ToString() == shopAfterSale.ShopId);
|
||
if (r != null)
|
||
{
|
||
r.Cells["colMessage"].Value = msg;
|
||
r.Cells["colWaitSend"].Value = shopAfterSale.WaitSendCount;
|
||
r.Cells["colWaitSend"].Style.ForeColor = shopAfterSale.WaitSendCount > 0 ? Color.OrangeRed : Color.Black;
|
||
r.Cells["colWaybillError"].Value = shopAfterSale.WaybillError;
|
||
r.Cells["colWaybillError"].Style.ForeColor = shopAfterSale.WaybillError > 0 ? Color.OrangeRed : Color.Black;
|
||
r.Cells["colAfterSale"].Value = shopAfterSale.AfterSaleCount;
|
||
r.Cells["colAfterSale"].Style.ForeColor = shopAfterSale.AfterSaleCount > 0 ? Color.OrangeRed : Color.Black;
|
||
r.Cells["colPunishCount"].Value = shopAfterSale.PunishCount;
|
||
r.Cells["colPunishCount"].Style.ForeColor = shopAfterSale.PunishCount > 0 ? Color.OrangeRed : Color.Black;
|
||
r.Cells["colScore"].Value = shopAfterSale.ShopScore.IsNullOrEmpty() ? "-" : shopAfterSale.ShopScore.ParseToString();
|
||
}
|
||
}
|
||
|
||
private void AiRequestHandler_ResourceLoadComplete(object sender, string url, string postData, string responseData)
|
||
{
|
||
if (url.Contains(AiTalkUrl) && (responseData.Contains("登录失败") || responseData.Contains("\\u767b\\u5f55\\u5931\\u8d25")))
|
||
{
|
||
Invoke(new Action(() =>
|
||
{
|
||
this.pnlCover.Visible = true;
|
||
this.pnlCover.Dock = DockStyle.Fill;
|
||
this.pnlCover.BringToFront();
|
||
this.btnReLogin.Visible = true;
|
||
}));
|
||
}
|
||
if (url.Contains("/api/me"))
|
||
{
|
||
if (!responseData.Contains("\"" + BaseClass.UserName + "\""))
|
||
{
|
||
Task.Run(() =>
|
||
{
|
||
Invoke(new Action(() =>
|
||
{
|
||
var cookieManager = aiTalkWebBrowser.GetCookieManager(null);
|
||
cookieManager.DeleteCookiesAsync(AiTalkUrl.Replace("https://", "").Replace("http://", ""), null);
|
||
}));
|
||
});
|
||
}
|
||
}
|
||
}
|
||
private void AdminAiRequestHandler_ResourceLoadComplete(object sender, string url, string postData, string responseData)
|
||
{
|
||
}
|
||
|
||
void FlashDgvRow(DataGridViewRow row)
|
||
{
|
||
Task.Run(() =>
|
||
{
|
||
if (row.Tag == null)
|
||
row.Tag = row.DefaultCellStyle.BackColor;
|
||
for (int j = 0; j < 6; j++)
|
||
{
|
||
Invoke(new Action(() => { row.DefaultCellStyle.BackColor = Color.White; }));
|
||
Thread.Sleep(120);
|
||
Invoke(new Action(() => { row.DefaultCellStyle.BackColor = Color.FromArgb(245, 95, 50); }));
|
||
Thread.Sleep(120);
|
||
Invoke(new Action(() => { row.DefaultCellStyle.BackColor = Color.FromArgb(245, 45, 10); }));
|
||
Thread.Sleep(120);
|
||
}
|
||
});
|
||
}
|
||
|
||
private void MainLifeHandler_OnPop(object sender, PopData e)
|
||
{
|
||
var targetUrl = e.Url;
|
||
var lifeHandler = sender as LifeSpanHandlerLocal;
|
||
|
||
Task.Run(() =>
|
||
{
|
||
if (lifeHandler.parent != null)
|
||
{
|
||
var cookies = CEFBrowser.GetCookieList("", lifeHandler.parent.GetCookieManager(null));
|
||
Invoke(new Action(() =>
|
||
{
|
||
CefForm cefForm = new CefForm(targetUrl, cookies);
|
||
cefForm.Show();
|
||
}));
|
||
}
|
||
});
|
||
}
|
||
|
||
private void LifeHandler_OnPop(object sender, PopData e)
|
||
{
|
||
var targetUrl = e.Url;
|
||
var lifeHandler = sender as LifeSpanHandlerLocal;
|
||
|
||
Task.Run(() =>
|
||
{
|
||
if (lifeHandler.parent != null)
|
||
{
|
||
var cookies = CEFBrowser.GetCookieList("", lifeHandler.parent.GetCookieManager(null));
|
||
Invoke(new Action(() =>
|
||
{
|
||
CefForm cefForm = new CefForm(targetUrl, cookies);
|
||
cefForm.Show();
|
||
}));
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 更新店铺后台首页
|
||
/// </summary>
|
||
/// <param name="shop"></param>
|
||
private void SetMainBrowserUrl(ShopLoginInfo shop)
|
||
{
|
||
if (shop == null)
|
||
return;
|
||
|
||
var cookieLst = new List<Cookie>();
|
||
try
|
||
{
|
||
cookieLst = JsonHelper.DeserializeJsonToList<CefSharp.Cookie>(shop.Cookies.ParseToString().Replace("empty=true;", "[]"));
|
||
}
|
||
catch
|
||
{
|
||
}
|
||
|
||
var cookieManager = mainWebBrowser.RequestContext.GetCookieManager(null);
|
||
cookieManager.DeleteCookiesAsync("qq.com", null).Wait();
|
||
foreach (var cook in cookieLst)
|
||
{
|
||
var t = CEFBrowser.SetCookieAsync(cook.Domain, cook.Name + "=" + cook.Value + ";", cookieManager);
|
||
t.Wait(5000);
|
||
}
|
||
|
||
mainWebBrowser.Load("https://store.weixin.qq.com/shop/home");
|
||
}
|
||
|
||
private void cmbMessage_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
ChatConfig.ChatSettingConfig.MessageSound = this.cmbMessage.SelectedItem.ToString();
|
||
ChatConfig.SaveChatSettingParam();
|
||
}
|
||
|
||
private void chkNotShowMessageWindow_CheckedChanged(object sender, EventArgs e)
|
||
{
|
||
ChatConfig.ChatSettingConfig.IsNotShowMessageWindow = chkNotShowMessageWindow.Checked;
|
||
ChatConfig.SaveChatSettingParam();
|
||
|
||
}
|
||
|
||
private void Chat_SearchResultReceived(ShopLoginInfo shop)
|
||
{
|
||
}
|
||
private void Collect_InfomationReceived(string infomation)
|
||
{
|
||
}
|
||
|
||
// 右键点击
|
||
private void dgvShop_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
|
||
{
|
||
if (e.ColumnIndex < 0 || e.RowIndex < 0)
|
||
return;
|
||
|
||
if (e.Button != MouseButtons.Right)
|
||
return;
|
||
|
||
string shopId = dgvShop.Rows[e.RowIndex].Cells["colShopId"].Value?.ToString();
|
||
if (string.IsNullOrEmpty(shopId))
|
||
return;
|
||
var shop = GlobalConfig.ValidShopLoginList.FirstOrDefault(s => s.ShopId == shopId);
|
||
if (shop == null)
|
||
return;
|
||
|
||
if (!LstTagShop.Contains(shop.ShopId))
|
||
{
|
||
LstTagShop.Add(shop.ShopId);
|
||
//dgvShop.Rows[e.RowIndex].Cells["colShopName"].Style.ForeColor = Color.LightGreen;
|
||
dgvShop.Rows[e.RowIndex].Cells["colShopName"].Style.BackColor = Color.LightGreen;
|
||
}
|
||
else
|
||
{
|
||
LstTagShop.Remove(shop.ShopId);
|
||
dgvShop.Rows[e.RowIndex].Cells["colShopName"].Style.ForeColor = DefaultForeColor;
|
||
dgvShop.Rows[e.RowIndex].Cells["colShopName"].Style.BackColor = dgvShop.Rows[e.RowIndex].Tag is Color ? (Color)dgvShop.Rows[e.RowIndex].Tag : Color.White;
|
||
}
|
||
NaiBa.Util.Helper.ConfigHelper.SaveConfig<List<string>>("wx_talk_tag_shop_list", LstTagShop);
|
||
}
|
||
|
||
private void dgvShop_CellContentClick(object sender, DataGridViewCellEventArgs e)
|
||
{
|
||
if (e.ColumnIndex < 0 || e.RowIndex < 0)
|
||
return;
|
||
|
||
var row = dgvShop.Rows[e.RowIndex];
|
||
|
||
string shopId = dgvShop.Rows[e.RowIndex].Cells["colShopId"].Value?.ToString();
|
||
if (string.IsNullOrEmpty(shopId))
|
||
return;
|
||
var shop = GlobalConfig.ValidShopLoginList.FirstOrDefault(s => s.ShopId == shopId);
|
||
if (shop == null)
|
||
return;
|
||
|
||
if (dgvShop.Columns[e.ColumnIndex].HeaderText == "状态"/* && dgvShop.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString() == "掉线"*/)
|
||
{
|
||
Task.Run(() =>
|
||
{
|
||
WXShopListForm.Instance.CheckShopLogin(new ShopLoginInfo[] { shop }, false);
|
||
if (shop.LoginStatus != "登录成功")
|
||
{
|
||
// 如需登录,引导至登录窗口,禁止从聊天窗口登录。
|
||
Invoke(new Action(() =>
|
||
{
|
||
// 登录小店
|
||
WXShopLoginForm lf = new WXShopLoginForm(shop);
|
||
lf.openType = EnumOpenType.login;
|
||
lf.ShowDialog();
|
||
}));
|
||
|
||
//WXShopListForm.Instance.CheckShopLogin(new ShopLoginInfo[] { shop }, false);
|
||
// 掉线店铺重登校验后刷新网页
|
||
LoadShop(new List<ShopLoginInfo>() { shop });
|
||
if (shop.LoginStatus == "登录成功")
|
||
{
|
||
//ShowChat(shop);
|
||
//while (shop.Chat.IsLoading)
|
||
//{
|
||
// Thread.Sleep(50);
|
||
//}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Invoke(new Action(() =>
|
||
{
|
||
// 进入小店
|
||
WXShopLoginForm lf = new WXShopLoginForm(shop);
|
||
lf.openType = EnumOpenType.manage;
|
||
lf.WindowState = FormWindowState.Maximized;
|
||
lf.Show();
|
||
}));
|
||
}
|
||
|
||
});
|
||
}
|
||
else if (dgvShop.Columns[e.ColumnIndex].HeaderText == "客服绑定")
|
||
{
|
||
if (row.Cells[e.ColumnIndex].Value.ParseToString() == "未授权" || row.Cells[e.ColumnIndex].Value.ParseToString() == "点击授权")
|
||
{
|
||
WXShopLoginForm lf = new WXShopLoginForm(shop);
|
||
lf.openType = EnumOpenType.manage;
|
||
lf.InitUrl = "https://store.weixin.qq.com/shop/servicemarket/home";
|
||
lf.TopMost = true;
|
||
lf.lblSecret.Visible = lf.txtSecret.Visible = lf.btnSaveAppSecret.Visible = true;
|
||
lf.SaveCompleteWithDescribe += Lf_SaveComplete;
|
||
lf.Show();
|
||
lf.TopMost = false;
|
||
}
|
||
|
||
//https://store.weixin.qq.com/shop/customerservice/home
|
||
}
|
||
}
|
||
|
||
private void Lf_SaveComplete(object o_shop, object o_appSecret, object o_wxShopLoginForm)
|
||
{
|
||
if (o_shop is ShopLoginInfo shop && o_wxShopLoginForm is WXShopLoginForm shopLoginFrom)
|
||
{
|
||
var appSecret = o_appSecret.ParseToString();
|
||
if (string.IsNullOrEmpty(appSecret))
|
||
{
|
||
shopLoginFrom.lblSecret.Text = "小店密钥输入错误!";
|
||
return;
|
||
}
|
||
var appId = shop.ShopId;
|
||
var aesKey = Randomx.GetWordWithNumber(43);
|
||
var callbackUrl = AiTalkUrl + "/wechat/" + appId + "/callback";
|
||
|
||
string body = @"{""id"":""" + appId + @""",""appId"":""" + appId + @""",""name"":""" + shop.ShopAccount +
|
||
@""",""apiKey"":""" + appSecret + @""",""secret"":""" + appSecret + @""",""token"":""" + appId +
|
||
@""",""encodingAesKey"":""" + aesKey + @""",""callbackUrl"":""" + callbackUrl + @"""}";
|
||
string url = AiTalkUrl + "/api/stores";
|
||
string refer = AiTalkUrl + "/workbanch";
|
||
var cookies = CEFBrowser.GetCookieList("", aiTalkAdminWebBrowser.RequestContext.GetCookieManager(null));
|
||
var rst = HttpResponseWxAiTalkBLL.PostResponse(new ShopLoginInfo() { Cookies = JsonHelper.SerializeObject(cookies) }, url, body, refer);
|
||
if (!rst.Contains("\"id\":\"" + appId + "\""))
|
||
{
|
||
shopLoginFrom.lblSecret.Text = "接入Ai客服错误!请重试!";
|
||
return;
|
||
}
|
||
|
||
// 拿到密钥去微信小店开通消息推送
|
||
url = "https://store.weixin.qq.com/shop-faas/mmecnodeservicemarket/channel/ChannelsEcVerifyCallbackInfo?token=&lang=zh_CN";
|
||
refer = "https://store.weixin.qq.com/shop/servicemarket/home";
|
||
//{"url":"http://14.103.99.254/wechat/wx316b1291351558aa/callback","token":"wx316b1291351558aa","base64Key":"PZPtKsJ165j3IE1YOe0mxJLwiq125lES2Lq2xplg3KU"}
|
||
body = "{\"url\":\"" + callbackUrl + "\",\"token\":\"" + appId + "\",\"base64Key\":\"" + aesKey + "\"}";
|
||
rst = WXHttpResponseBLL.WeiXinPostResponse(shop, url, body, refer);
|
||
//{"ret":0,"success":true,"code":0}
|
||
if (!rst.Contains("\"code\":0"))
|
||
{
|
||
WXShopListForm.Instance.CheckShopLogin(new ShopLoginInfo[] { shop }, false);
|
||
if (shop.LoginStatus != "登录成功")
|
||
{
|
||
shopLoginFrom.lblSecret.Text = "店铺掉线!请登录店铺后重试!";
|
||
return;
|
||
}
|
||
shopLoginFrom.lblSecret.Text = "设置Ai客服推送错误!请重试!";
|
||
return;
|
||
}
|
||
|
||
shopLoginFrom.cefWebBrowser.Load("https://store.weixin.qq.com/shop/customerservice/home");
|
||
shopLoginFrom.lblSecret.Text = "请点击客服设置,接入自研客服,扫码接入(不接入接收不到消息)";
|
||
shopLoginFrom.btnSaveAppSecret.Text = "我已接入,关闭窗口";
|
||
|
||
Task.Run(() =>
|
||
{
|
||
Thread.Sleep(500);
|
||
BatchBindShop(new List<string> { shop.ShopId });
|
||
});
|
||
}
|
||
}
|
||
|
||
private void dgvShop_CellClick(object sender, DataGridViewCellEventArgs e)
|
||
{
|
||
if (e.ColumnIndex < 0 || e.RowIndex < 0)
|
||
return;
|
||
|
||
//foreach (DataGridViewRow r in dgvShop.Rows)
|
||
// r.Cells["colSelect"].Value = false;
|
||
|
||
var row = dgvShop.Rows[e.RowIndex];
|
||
//row.Cells["colSelect"].Value = true;
|
||
if (dgvShop.Columns[e.ColumnIndex].Name == "colSelect")
|
||
row.Cells["colSelect"].Value = !row.Cells["colSelect"].Value.ParseToBool();
|
||
if (row.DefaultCellStyle.BackColor.R == 245 || row.DefaultCellStyle.BackColor == Color.Yellow)
|
||
row.DefaultCellStyle.BackColor = Color.Yellow;
|
||
|
||
string shopId = row.Cells["colShopId"].Value?.ToString();
|
||
if (string.IsNullOrEmpty(shopId))
|
||
return;
|
||
var shop = GlobalConfig.ValidShopLoginList.Where(s => s.ShopId == shopId).FirstOrDefault();
|
||
if (shop == null)
|
||
return;
|
||
|
||
// 之前的当前店铺如果不在聊天界面强制转回聊天界面
|
||
if (currentShop?.Chat != null)
|
||
{
|
||
var script = "document.documentElement.outerHTML;";
|
||
try
|
||
{
|
||
string htmlContent = currentShop.Chat.EvaluateScriptAsync(script).Result.Result.ParseToString();
|
||
if (currentShop.LoginStatus == "登录成功" && !htmlContent.Contains("按Enter发送"))
|
||
currentShop.Chat.Load("https://store.weixin.qq.com/shop/kf");
|
||
}
|
||
catch { }
|
||
}
|
||
|
||
currentShop = shop;
|
||
lblCurrentShop.Text = "当前店铺:" + currentShop.ShopAccount;
|
||
|
||
if (shop?.Chat != null)
|
||
{
|
||
if (orderListForm != null)
|
||
{
|
||
orderListForm.lblCurrentShop.Text = currentShop.ShopAccount;
|
||
orderListForm.lblCurrentShop.Tag = currentShop;
|
||
}
|
||
|
||
shop.Chat.Dock = DockStyle.Fill;
|
||
shop.Chat.BringToFront();
|
||
btnPrev.BringToFront();
|
||
btnNext.BringToFront();
|
||
|
||
txtAddress.Text = currentShop.Chat.Address;
|
||
}
|
||
|
||
Task.Run(() =>
|
||
{
|
||
SetMainBrowserUrl(shop);
|
||
});
|
||
}
|
||
|
||
private void pnlRefresh_Click(object sender, EventArgs e)
|
||
{
|
||
//nextRefreshTime = DateTime.Now.AddMinutes(30);
|
||
pbLoading.Visible = true;
|
||
Task.Run(() =>
|
||
{
|
||
RefreshCookie();
|
||
LoadShop();
|
||
Invoke(new Action(() => { pbLoading.Visible = false; }));
|
||
});
|
||
}
|
||
|
||
void RefreshCookie(bool isAuto = false)
|
||
{
|
||
if (ChatConfig.ChatSettingConfig.IsAutoReply)
|
||
{
|
||
Invoke(new Action(()=> { this.ucTabControl1.SelectedIndex = 0; }));
|
||
}
|
||
|
||
if (!isAuto)
|
||
WXShopListForm.UpdateShop();
|
||
foreach (var shop in GlobalConfig.ValidShopLoginList)
|
||
{
|
||
var r = dgvShop.Rows.Cast<DataGridViewRow>().FirstOrDefault(x => x.Cells["colShopId"].Value.ToString() == shop.ShopId);
|
||
Invoke(new Action(() =>
|
||
{
|
||
if (r != null)
|
||
r.Cells["colMessage"].Value = "正在刷新店铺";
|
||
}));
|
||
WXShopListForm.Instance.CheckShopLogin(new ShopLoginInfo[] { shop }, false);
|
||
Invoke(new Action(() =>
|
||
{
|
||
if (r != null)
|
||
r.Cells["colMessage"].Value = "";
|
||
}));
|
||
}
|
||
}
|
||
|
||
private void btnFilterShop_Click(object sender, EventArgs e)
|
||
{
|
||
string shopName = txtFiltShopName.Text.Trim();
|
||
string notes = cmbFiltNotes.Text.Trim().Trim(';');
|
||
string groups = cmbFiltGroups.Text.Trim().Trim(';');
|
||
if (notes == "全部")
|
||
notes = "";
|
||
if (groups == "全部")
|
||
groups = "";
|
||
List<string> notesLst = notes.Split(new string[] { ";", ";", ",", "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||
List<string> groupsLst = groups.Split(new string[] { ";", ";", ",", "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||
foreach (DataGridViewRow row in dgvShop.Rows)
|
||
{
|
||
if (!row.Cells["colShopName"].Value.ParseToString().Contains(shopName))
|
||
row.Visible = false;
|
||
else if (!string.IsNullOrEmpty(notes) && !notesLst.Contains(row.Cells["colShopNotes"].Value.ParseToString()))
|
||
row.Visible = false;
|
||
else if (!string.IsNullOrEmpty(groups) && !groupsLst.Contains(row.Cells["colGroup"].Value.ParseToString()))
|
||
row.Visible = false;
|
||
else
|
||
row.Visible = true;
|
||
}
|
||
}
|
||
|
||
private void btnEmpty_Click(object sender, EventArgs e)
|
||
{
|
||
cmbFiltGroups.Text = "全部";
|
||
cmbFiltNotes.Text = "全部";
|
||
btnFilterShop_Click(null, null);
|
||
}
|
||
|
||
private void btnPrev_Click(object sender, EventArgs e)
|
||
{
|
||
aiTalkWebBrowser.Back();
|
||
}
|
||
|
||
private void btnNext_Click(object sender, EventArgs e)
|
||
{
|
||
aiTalkWebBrowser.Forward();
|
||
}
|
||
|
||
private void btnRefreshAfterSale_Click(object sender, EventArgs e)
|
||
{
|
||
this.pbLoading.Visible = true;
|
||
Task.Run(() =>
|
||
{
|
||
RefreshAfterSale(true);
|
||
Invoke(new Action(() => { pbLoading.Visible = false; }));
|
||
});
|
||
}
|
||
|
||
void RefreshAfterSale(bool refreshAll = false)
|
||
{
|
||
List<Task> tList = new List<Task>();
|
||
if (refreshAll)
|
||
lstShopAfterSale.Clear();
|
||
foreach (var shop in GlobalConfig.ValidShopLoginList)
|
||
{
|
||
var shopMainInfo = lstShopAfterSale.FirstOrDefault(sa => sa.ShopId == shop.ShopId);
|
||
if (shopMainInfo == null)
|
||
shopMainInfo = new WxTalkFormShopMainInfo() { ShopId = shop.ShopId };
|
||
Invoke(new Action(() => { LoadShopAfterSale(shopMainInfo, ""); }));
|
||
var t = Task.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
if (shop.LoginStatus != "登录成功")
|
||
{
|
||
Invoke(new Action(() => { LoadShopAfterSale(new WxTalkFormShopMainInfo() { ShopId = shop.ShopId }, "店铺掉线"); }));
|
||
return;
|
||
}
|
||
|
||
var afterSaleInfo = lstShopAfterSale.FirstOrDefault(sa => sa.ShopId == shop.ShopId);
|
||
if (refreshAll || afterSaleInfo == null || afterSaleInfo.RefreshTime.Date != DateTime.Now.Date)
|
||
{
|
||
lstShopAfterSale.RemoveAll(sa => sa.ShopId == shop.ShopId);
|
||
var rst = WxShopStatisticsForm.GetShopMainInfoList(shop);
|
||
if (!rst.Contains("\"code\":0"))
|
||
rst = WxShopStatisticsForm.GetShopMainInfoList(shop);
|
||
if (!rst.Contains("\"code\":0"))
|
||
{
|
||
WXShopListForm.Instance.CheckShopLogin(new ShopLoginInfo[] { shop }, false);
|
||
if (shop.LoginStatus != "登录成功")
|
||
{
|
||
Invoke(new Action(() => { LoadShopAfterSale(new WxTalkFormShopMainInfo() { ShopId = shop.ShopId }, "店铺掉线"); }));
|
||
return;
|
||
}
|
||
|
||
string errMsg = BaseRegex.GetStringJson(ref rst, "msg");
|
||
if (string.IsNullOrEmpty(errMsg)) errMsg = BaseRegex.GetStringJson(ref rst, "message");
|
||
if (string.IsNullOrEmpty(errMsg)) errMsg = BaseRegex.GetStringJson(ref rst, "errMsg");
|
||
if (string.IsNullOrEmpty(errMsg)) errMsg = BaseRegex.GetStringJson(ref rst, "errmsg");
|
||
if (string.IsNullOrEmpty(errMsg)) errMsg = rst;
|
||
|
||
shopMainInfo = new WxTalkFormShopMainInfo() { ShopId = shop.ShopId, RefreshTime = DateTime.Now };
|
||
lstShopAfterSale.Add(shopMainInfo);
|
||
Invoke(new Action(() => { LoadShopAfterSale(shopMainInfo, "查询失败 " + errMsg); }));
|
||
return;
|
||
}
|
||
|
||
var afterCount = JsonHelper.JObjectParse(rst)["aftersaleAllRet"]["totalNum"].ParseToInt();
|
||
var waitSendCount = JsonHelper.JObjectParse(rst)["orderNumRet"]["pendingShipNum"].ParseToInt();
|
||
var waybillErrorCount = JsonHelper.JObjectParse(rst)["waybillErrorRet"]["totalNum"].ParseToInt();
|
||
var punishCount = JsonHelper.JObjectParse(rst)["punishRet"]["pendingNum"].ParseToInt();
|
||
shopMainInfo = new WxTalkFormShopMainInfo()
|
||
{
|
||
ShopId = shop.ShopId,
|
||
RefreshTime = DateTime.Now,
|
||
AfterSaleCount = afterCount,
|
||
WaitSendCount = waitSendCount,
|
||
WaybillError = waybillErrorCount,
|
||
PunishCount = punishCount,
|
||
};
|
||
|
||
var shopScoreRst = WxShopStatisticsForm.GetShopScore(shop);
|
||
System.Threading.Thread.Sleep(Randomx.GetId(50, 100));
|
||
if (shopScoreRst.Contains("\"code\":0"))
|
||
{
|
||
shopMainInfo.ShopScore = BaseRegex.GetDecimalJson(ref shopScoreRst, "curValue");
|
||
}
|
||
else
|
||
{
|
||
string errStr = BaseRegex.GetStringJson(ref shopScoreRst, "errorMsg");
|
||
if (string.IsNullOrEmpty(errStr))
|
||
errStr = BaseRegex.GetStringJson(ref shopScoreRst, "error_msg");
|
||
if (string.IsNullOrEmpty(errStr))
|
||
errStr = shopScoreRst;
|
||
WXShopListForm.Instance.CheckShopLogin(new string[] { shop.LoginName }, false);
|
||
shopMainInfo.err_msg = errStr;
|
||
|
||
Invoke(new Action(() => { LoadShopAfterSale(shopMainInfo, "评分查询失败 " + errStr); }));
|
||
return;
|
||
}
|
||
|
||
lstShopAfterSale.Add(shopMainInfo);
|
||
Invoke(new Action(() => { LoadShopAfterSale(shopMainInfo, "已查询"); }));
|
||
return;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
}
|
||
});
|
||
tList.Add(t);
|
||
while (tList.Where(ta => !ta.IsFaulted && !ta.IsCompleted).Count() >= 10) { Thread.Sleep(100); }
|
||
}
|
||
while (tList.Where(ta => !ta.IsFaulted && !ta.IsCompleted).Count() >= 1) { Thread.Sleep(100); }
|
||
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_shop_after_sale_list", lstShopAfterSale);
|
||
}
|
||
|
||
private void btnToKfMainPage_Click(object sender, EventArgs e)
|
||
{
|
||
ucTabControl1.SelectedIndex = 0;
|
||
aiTalkWebBrowser.Load(AiTalkUrl + "/workbench");
|
||
}
|
||
|
||
private void txtAddress_KeyDown(object sender, KeyEventArgs e)
|
||
{
|
||
if (e.KeyCode == Keys.Enter)
|
||
{
|
||
if (aiTalkWebBrowser != null)
|
||
{
|
||
aiTalkWebBrowser.Load(txtAddress.Text);
|
||
}
|
||
}
|
||
}
|
||
|
||
public static string GetKfMsgStatistics(ShopLoginInfo shop, long beginDateTick, long endDateTick)
|
||
{
|
||
string url = "https://store.weixin.qq.com/shop/kf/cgi/data/getRealTimeShopV2?" + "beginDate=" + (beginDateTick / 1000) + "&endDate=" + (endDateTick / 1000m).ToString("0.000");
|
||
string referer = "https://store.weixin.qq.com/shop/kf/data/store";
|
||
var result = WXHttpResponseBLL.WeiXinGetResponse(shop, url, referer);
|
||
return result;
|
||
}
|
||
|
||
private void btnRefreshMsgCount_Click(object sender, EventArgs e)
|
||
{
|
||
pbLoading.Visible = true;
|
||
Task.Run(() =>
|
||
{
|
||
RefreshMsgCount();
|
||
Invoke(new Action(() => { pbLoading.Visible = false; }));
|
||
});
|
||
}
|
||
|
||
void RefreshMsgCount()
|
||
{
|
||
lstShopKfStatistics.Clear();
|
||
foreach (var shop in GlobalConfig.ValidShopLoginList)
|
||
{
|
||
var kfMsg = new WxShopKfStatistics() { ShopId = shop.ShopId };
|
||
var kfMsgRst = GetKfMsgStatistics(shop, BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now.Date), BaseClass.DateTimeToTimestampMilliseconds(DateTime.Now));
|
||
if (!kfMsgRst.Contains("\"ret\":0"))
|
||
continue;
|
||
try
|
||
{
|
||
var jObj = JsonHelper.JObjectParse(kfMsgRst);
|
||
kfMsg.user_cnt = jObj["cardResp"]["objects"]["tableValueLine"][0]["columnValue"][1].ParseToInt();
|
||
kfMsg.sesseion_cnt = jObj["cardResp"]["objects"]["tableValueLine"][0]["columnValue"][2].ParseToInt();
|
||
kfMsg.service_noreply_ratio = jObj["cardResp"]["objects"]["tableValueLine"][0]["columnValue"][5].ParseToDecimal();
|
||
lstShopKfStatistics.Add(kfMsg);
|
||
|
||
Invoke(new Action(() =>
|
||
{
|
||
int count = Math.Max(1, lstShopKfStatistics.Count());
|
||
lblUserCount.Text = lstShopKfStatistics.Sum(s => s.user_cnt).ParseToString();
|
||
lblTalkCount.Text = lstShopKfStatistics.Sum(s => s.sesseion_cnt).ParseToString();
|
||
lblReplyCount.Text = lstShopKfStatistics.Sum(s => s.service_reply_ratio * 100 / count).ParseToDecimal().ToString("0.0") + "%";
|
||
}));
|
||
}
|
||
catch
|
||
{
|
||
}
|
||
}
|
||
Invoke(new Action(() =>
|
||
{
|
||
int count = Math.Max(1, lstShopKfStatistics.Count());
|
||
lblUserCount.Text = lstShopKfStatistics.Sum(s => s.user_cnt).ParseToString();
|
||
lblTalkCount.Text = lstShopKfStatistics.Sum(s => s.sesseion_cnt).ParseToString();
|
||
lblReplyCount.Text = lstShopKfStatistics.Sum(s => s.service_reply_ratio * 100 / count).ParseToDecimal().ToString("0.0") + "%";
|
||
}));
|
||
}
|
||
|
||
public static void UpdateAutoReply(string talkTemplate)
|
||
{
|
||
LstTalkTemplatePair = new List<KeyValuePair<string, string>>();
|
||
var keyValueStrLst = talkTemplate.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||
foreach (var keyValueStr in keyValueStrLst)
|
||
{
|
||
if (keyValueStr.StartsWith("//"))
|
||
continue;
|
||
var keyValueLst = keyValueStr.Split(new string[] { "###" }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||
if (keyValueLst.Count == 1)
|
||
keyValueLst.Insert(0, "");
|
||
LstTalkTemplatePair.Add(new KeyValuePair<string, string>(keyValueLst.FirstOrDefault(), keyValueLst.LastOrDefault()));
|
||
}
|
||
NaiBa.Util.Helper.ConfigHelper.SaveConfig("wx_talk_auto_reply_template", LstTalkTemplatePair);
|
||
}
|
||
|
||
private void btnMultiLogin_Click(object sender, EventArgs e)
|
||
{
|
||
if (currentShop == null)
|
||
return;
|
||
|
||
WXShopListForm.Instance.CheckShopLogin(new string[] { currentShop?.LoginName }, false);
|
||
if (currentShop.LoginStatus != "登录成功")
|
||
{
|
||
BaseMsgForm.ShowError("批量登录需要主店铺处于登录状态!");
|
||
}
|
||
else
|
||
{
|
||
WXShopMultiLoginForm shopMultiLoginForm = new WXShopMultiLoginForm(currentShop);
|
||
shopMultiLoginForm.openType = EnumOpenType.multi_login;
|
||
shopMultiLoginForm.ShowDialog();
|
||
|
||
var switchShopLst = shopMultiLoginForm.lstSwitchShop.ToList();
|
||
var needUpdateShopLst = shopMultiLoginForm.lstNeedUpdateShop.ToList();
|
||
pbLoading.Visible = true;
|
||
Task.Run(() =>
|
||
{
|
||
// 批量登录后刷新网页
|
||
LoadShop(switchShopLst);
|
||
foreach (var shop in needUpdateShopLst)
|
||
{
|
||
ShowChat(shop);
|
||
}
|
||
Invoke(new Action(() => { pbLoading.Visible = false; }));
|
||
});
|
||
}
|
||
}
|
||
|
||
private void btnClose_Click(object sender, EventArgs e)
|
||
{
|
||
if (btnClose.Text == ">>")
|
||
{
|
||
splitContainer1.SplitterDistance = 379;
|
||
btnClose.Text = "<<";
|
||
}
|
||
else
|
||
{
|
||
splitContainer1.SplitterDistance = 0;
|
||
btnClose.Text = ">>";
|
||
}
|
||
}
|
||
|
||
private void lblMsgSound_Click(object sender, EventArgs e)
|
||
{
|
||
}
|
||
|
||
private void label4_Click(object sender, EventArgs e)
|
||
{
|
||
//if (BaseClass.ParentUserName == "15288888888" || BaseClass.UserName == "15288888888")
|
||
{
|
||
#if DEBUG
|
||
if (File.Exists(System.Environment.CurrentDirectory + "\\choice.debug.tools"))
|
||
{
|
||
if (dgvShop.Parent.Controls[0] != dgvShop)
|
||
dgvShop.BringToFront();
|
||
else
|
||
dgvShop.SendToBack();
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
private void btnBatchBindShop_Click(object sender, EventArgs e)
|
||
{
|
||
var shopIds = dgvShop.Rows.Cast<DataGridViewRow>().Where(r => r.Cells["colSelect"].Value.ParseToBool() == true).Select(r => r.Cells["colShopId"].Value.ParseToString()).ToList();
|
||
BatchBindShop(shopIds);
|
||
}
|
||
|
||
void BatchBindShop(List<string> shopIds)
|
||
{
|
||
if (shopIds.Count == 0)
|
||
{
|
||
BaseMsgForm.ShowError("请选择店铺");
|
||
return;
|
||
}
|
||
|
||
var cookies = CEFBrowser.GetCookieList("", aiTalkAdminWebBrowser.RequestContext.GetCookieManager(null));
|
||
string data = @"{""id"":""" + AiTalkUserId + @""",""username"":""" + BaseClass.UserName +
|
||
@""",""role"":""supervisor"",""storeIds"":[""" + string.Join("\",\"", shopIds) + @"""],""status"":""active"",""password"":""""}";
|
||
//data = @"{""id"":""user_1783069143289_df656a"",""username"":""15222220002"",""role"":""supervisor"",""storeIds"":[""shop02"",""wxff3e05179dc3b00d"",""shop01""],""status"":""active"",""expiresAt"":"""",""createdAt"":""2026-07-03T08:59:03.289Z"",""updatedAt"":""2026-07-03T08:59:03.289Z"",""password"":""""}";
|
||
|
||
// string body = @"{""id"":""user_1783069143289_df656a"",""username"":""15222220002"",""role"":""supervisor"",""storeIds"":[""shop02"",""wxff3e05179dc3b00d"",""shop01""],""status"":""active"",""expiresAt"":"""",""createdAt"":""2026-07-03T08:59:03.289Z"",""updatedAt"":""2026-07-03T08:59:03.289Z"",""password"":""""}";
|
||
|
||
var url = AiTalkUrl + "/api/users/" + this.AiTalkUserId + "/stores/bind";
|
||
//url = "http://14.103.99.254/api/users/user_1783069143289_df656a";
|
||
var refer = AiTalkUrl + "/workbench";
|
||
var rst = HttpResponseWxAiTalkBLL.PostResponse(new ShopLoginInfo() { Cookies = JsonHelper.SerializeObject(cookies) }, url, data, refer);
|
||
if (!rst.Contains("\"username\":\"" + BaseClass.UserName + "\""))
|
||
{
|
||
BaseMsgForm.ShowError("AI客服店铺绑定失败,请稍候重试!");
|
||
return;
|
||
}
|
||
|
||
refreshAiStatus(shopIds);
|
||
|
||
this.aiTalkWebBrowser.Reload();
|
||
}
|
||
|
||
private void btnReLogin_Click(object sender, EventArgs e)
|
||
{
|
||
LoadAiTalkAdmin();
|
||
}
|
||
|
||
private void btnRefreshAiStatus_Click(object sender, EventArgs e)
|
||
{
|
||
pbLoading.Visible = true;
|
||
Task.Run(() =>
|
||
{
|
||
refreshAiStatus(GlobalConfig.ShopLoginList.Select(s => s.ShopId).ToList());
|
||
|
||
Thread.Sleep(500);
|
||
Invoke(new Action(() =>
|
||
{
|
||
pbLoading.Visible = false;
|
||
}));
|
||
});
|
||
}
|
||
|
||
void refreshAiStatus(List<string> shopIds)
|
||
{
|
||
var url = AiTalkUrl + "/api/stores?page=1&pageSize=5000&keyword=" + string.Join(",", shopIds);
|
||
var refer = AiTalkUrl + "/api/stores";
|
||
var adminCookies = CEFBrowser.GetCookieList("", aiTalkAdminWebBrowser.RequestContext.GetCookieManager(null));
|
||
var rst = HttpResponseWxAiTalkBLL.GetResponse(new ShopLoginInfo() { Cookies = JsonHelper.SerializeObject(adminCookies) }, url, refer);
|
||
|
||
if (rst.Contains("\"stores\":["))
|
||
{
|
||
List<ShopAiTalkInfo> aiTalkInfoLst = JsonHelper.DeserializeJsonToList<ShopAiTalkInfo>(JsonHelper.JObjectParse(rst)["stores"].ParseToString());
|
||
foreach (var shopId in shopIds)
|
||
{
|
||
var shop = GlobalConfig.ShopLoginList.FirstOrDefault(s => s.ShopId == shopId);
|
||
if (shop != null)
|
||
shop.shopAiTalkInfo = aiTalkInfoLst.FirstOrDefault(ai => ai.id == shop.ShopId);
|
||
}
|
||
}
|
||
|
||
foreach (var shop in GlobalConfig.ShopLoginList)
|
||
{
|
||
BindAiTalkStatus(shop);
|
||
}
|
||
}
|
||
|
||
private void btnReload_Click(object sender, EventArgs e)
|
||
{
|
||
LoadAiTalkAdmin();
|
||
}
|
||
|
||
//https://store.weixin.qq.com/shop-faas/mmchannelstradeorder/list/cgi/orderSearch?token=&lang=zh_CN
|
||
//https://store.weixin.qq.com/shop/order/list
|
||
// 待发货
|
||
//{"isSearch":false,"pageSize":30,"overTime":0,"pengingShipOneDay":0,"pengingShipSixHour":0,"expediteDelivery":0,"stockoutPunishAlert":0,"waybillStatus":0,"pageNum":1,"onAftersaleOrderExist":0,"orderStatus":20}
|
||
// 售后中
|
||
//{"isSearch":false,"pageSize":30,"overTime":0,"pengingShipOneDay":0,"pengingShipSixHour":0,"expediteDelivery":0,"stockoutPunishAlert":0,"waybillStatus":0,"pageNum":1,"onAftersaleOrderExist":1,"orderStatus":0}
|
||
// 已发货
|
||
//{"isSearch":false,"pageSize":30,"overTime":0,"pengingShipOneDay":0,"pengingShipSixHour":0,"expediteDelivery":0,"stockoutPunishAlert":0,"waybillStatus":0,"pageNum":1,"onAftersaleOrderExist":0,"orderStatus":30}
|
||
// 时间段查询全部
|
||
//{"isSearch":true,"pageSize":30,"overTime":0,"pengingShipOneDay":0,"pengingShipSixHour":0,"expediteDelivery":0,"stockoutPunishAlert":0,"waybillStatus":0,"pageNum":1,"onAftersaleOrderExist":0,"orderStatus":0,"orderId":"","orderTime":{"type":0,"time":[1772380800000,1774868515000]},"telNumber":"","title":"","receiverName":"","finderNickName":"","merchantNotes":"","merchantNotesTagColor":0,"waybillId":"","productCode":"","inspectStatus":"","finderWay":0,"searchOrderType":0,"payMethod":0,"orderChannel":0,"bulkbuyActivityId":"","deliveryNegotiationFlag":0,"transactionId":"","page":1,"status":20,"startCreateTime":1772380800000,"endCreateTime":1774868515000}
|
||
}
|
||
}
|