diff --git a/FLSystem/Forms/main.cs b/FLSystem/Forms/main.cs index f07b7c5..80ed481 100644 --- a/FLSystem/Forms/main.cs +++ b/FLSystem/Forms/main.cs @@ -35,6 +35,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; +using DevExpress.Data.Helpers; using Microsoft.Win32; using UI.Framework.Controls; using UI.Framework.Forms; @@ -100,6 +101,8 @@ namespace FLSystem.Forms { try { + //var ss = ApiClient.ShortURL("https://detail.tmall.com/item.htm?spm=a230r.1.14.16.11f547a36SIAOY&id=526234772827&ns=1&abbucket=1", DwzType.官方短网址).Result; + DevExpress.UserSkins.BonusSkins.Register(); DevExpress.Skins.SkinManager.EnableFormSkins(); @@ -394,7 +397,6 @@ namespace FLSystem.Forms timerLok.Interval = 5 * 60000;//测试1分钟锁屏 timerLok.Start(); - #region 激活抖音xxx //TODO 禁用抖音禁用 //if (StartDy == "1") @@ -573,8 +575,8 @@ namespace FLSystem.Forms System.Timers.Timer timer = new System.Timers.Timer(); timer.Elapsed += Timer_Elapsed; - timer.Interval = 40 * 60 * 1000; - //timer.Interval = 1000; + timer.Interval = 60 * 60 * 1000; + //timer.Interval = 1000 * 10; timer.Start(); //下载黑名单 @@ -961,7 +963,27 @@ namespace FLSystem.Forms bool isinsert = user.id == 0 ? true : false; session.SaveOrUpdate(user); - if (isinsert) EventClient.OnEvent(this, MethodType.刷新机器人); + if (isinsert) + { + try + { + var result = UserRobotUpLoad.CustomerLink_UpLoadRobot(new List() + { + new UserRobotUpLoad.CustomerRobotInput() + { + HeadUrl = string.Empty, + NickName = user.nick, + Remark = user.remark, + RobotType = UserRobotUpLoad.ConvertRobotType(user.type), + UserName = user.name + } + }); + } + catch (Exception e) + { } + + EventClient.OnEvent(this, MethodType.刷新机器人); + } } } catch { } @@ -1098,7 +1120,26 @@ namespace FLSystem.Forms bool isinsert = user.id == 0 ? true : false; session.SaveOrUpdate(user); - if (isinsert) EventClient.OnEvent(this, MethodType.刷新机器人); + if (isinsert) + { + try + { + var result = UserRobotUpLoad.CustomerLink_UpLoadRobot(new List() + { + new UserRobotUpLoad.CustomerRobotInput() + { + HeadUrl = string.Empty, + NickName = user.nick, + Remark = user.remark, + RobotType = UserRobotUpLoad.ConvertRobotType(user.type), + UserName = user.name + } + }); + } + catch (Exception e) + { } + EventClient.OnEvent(this, MethodType.刷新机器人); + } } } catch { } @@ -2372,51 +2413,149 @@ namespace FLSystem.Forms isrun = true; try { - var h = DateTime.Now.Hour; if (!(1 <= h && h < 3)) - return; - try { - var robots = ChatClient.WXClient.Values.Where(f => f.Status == WxStatus.在线).ToList(); - foreach (var robot in robots) + var h = DateTime.Now.Hour; if (!(1 <= h && h < 3)) + return; + Console.WriteLine(); + //没赋值的头像赋值 + try { - try + var robots = ChatClient.WXClient.Values.Where(f => f.Status == WxStatus.在线).ToList(); + foreach (var robot in robots) { - var db = ApiClient.GetSession(); - var members = db.Find("select * from fl_member_info where robot_name = @robotname and headurl = @headurl", new { robotname = robot.WeixinHao, headurl = "" }); - - var friends = robot.Friends; - foreach (var member in members) + try { - if (friends != null && friends.ContainsKey(member.username)) + var db = ApiClient.GetSession(); + var members = db.Find("select * from fl_member_info where robot_name = @robotname and headurl = @headurl", new { robotname = robot.WeixinHao, headurl = "" }); + + var friends = robot.Friends; + foreach (var member in members) { - var headurl = friends[member.username].BigHeadImgUrl; - if (!string.IsNullOrWhiteSpace(headurl)) + if (friends != null && friends.ContainsKey(member.username)) { - member.headurl = friends[member.username].BigHeadImgUrl; - db.SaveOrUpdate(member); - } - } - else - { - var f = robot.GetContact(member.username); - if (f != null) - { - if (!string.IsNullOrWhiteSpace(f.BigHeadImgUrl)) + var headurl = friends[member.username].BigHeadImgUrl; + if (!string.IsNullOrWhiteSpace(headurl)) { - member.headurl = f.BigHeadImgUrl; + member.headurl = friends[member.username].BigHeadImgUrl; db.SaveOrUpdate(member); } } + else + { + var f = robot.GetContact(member.username); + if (f != null) + { + if (!string.IsNullOrWhiteSpace(f.BigHeadImgUrl)) + { + member.headurl = f.BigHeadImgUrl; + db.SaveOrUpdate(member); + } + } + } + + } + } + catch (Exception ex) + { } + } + } + catch (Exception exception) + { } + + //上传用户/机器人信息 + try + { + var db = ApiClient.GetSession(); + + var upload = db.FindSingle("select * from fl_upload_record"); + + if (upload == null) + { + upload = new fl_upload_record(); + var userNumber = db.Queryable().Count(); + upload.usernumber = userNumber; + db.Saveable(upload).ExecuteCommand(); + } + + if (!upload.usersuccess) + { + var pageSize = 100; + while (upload.userindex * pageSize < upload.usernumber) + { + var members = db.Queryable().OrderBy(f => f.id).ToPageList(upload.userindex, pageSize); + List list = new List(); + foreach (var item in members) + { + list.Add(new UserRobotUpLoad.CustomerLinkInput() + { + CreateTime = item.crt_time, + HeadUrl = item.headurl, + NickName = item.usernick, + Remark = item.remark, + RobotName = item.robot_name, + RobotType = UserRobotUpLoad.ConvertRobotType(item.robot_type), + UserName = item.username + }); } + if (list.Count > 0) + { + var result = UserRobotUpLoad.CustomerLink_UpLoadLink(list); + if (result.Ok) + { + db.Saveable(upload).ExecuteCommand(); + } + } + upload.userindex++; + Thread.Sleep(1000); + } + + if (upload.userindex * pageSize >= upload.usernumber) + { + upload.usersuccess = true; + db.Saveable(upload).ExecuteCommand(); } } - catch (Exception ex) - { } + + if (!upload.robotsuccess) + { + try + { + var robots = db.Find("select * from fl_robot_info"); + List list = new List(); + foreach (var item in robots) + { + list.Add(new UserRobotUpLoad.CustomerRobotInput() + { + HeadUrl = string.Empty, + NickName = item.nick, + Remark = item.remark, + RobotType = UserRobotUpLoad.ConvertRobotType(item.type), + UserName = item.name + }); + } + + if (list.Count > 0) + { + var result = UserRobotUpLoad.CustomerLink_UpLoadRobot(list); + if (result.Ok) + { + upload.robotsuccess = true; + } + } + } + catch (Exception ex) + { + upload.robotsuccess = false; + } + db.Saveable(upload).ExecuteCommand(); + } + } + catch (Exception ex) + { + } } - catch (Exception exception) - { } } catch (Exception ex) { } diff --git a/PCRobot/PCRobot.csproj b/PCRobot/PCRobot.csproj index e1a025a..ac98f7e 100644 --- a/PCRobot/PCRobot.csproj +++ b/PCRobot/PCRobot.csproj @@ -211,6 +211,7 @@ + diff --git a/PCRobot/PCRobotForm.cs b/PCRobot/PCRobotForm.cs index 864afed..b3324a6 100644 --- a/PCRobot/PCRobotForm.cs +++ b/PCRobot/PCRobotForm.cs @@ -14,6 +14,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using PCRobot.PCWechat.Enterprise; using PCRobot.PCWechat.Routine; +using WechatHelper; namespace PCRobot { @@ -38,6 +39,14 @@ namespace PCRobot private void PCRobotForm_Load(object sender, EventArgs e) { + + try + { + WeChatActivateHelper.Init(TimeSpan.FromMinutes(20)); + } + catch (Exception exception) + { } + try { //Common.MainExeHandle = this.Handle; @@ -84,7 +93,6 @@ namespace PCRobot IniData(); this.label5.Text = "版本:" + Common.CurVersion; - //MessageBox.Show("版本:" + Common.CurVersion); if (string.IsNullOrWhiteSpace(Config.GetValue("设置", "静态"))) { @@ -148,25 +156,26 @@ namespace PCRobot MessageBox.Show("异常 = " + ex.Message + " --- " + ex.StackTrace); } - try - { - //自动切换聊天对象 - var th = new Thread(OnHandle); - th.IsBackground = true; - th.Start(); - //切换窗口 - var th1 = new Thread(OnActivationHandle); - th1.IsBackground = true; - th1.Start(); + //try + //{ + // //自动切换聊天对象 + // var th = new Thread(OnHandle); + // th.IsBackground = true; + // th.Start(); - //发送消息 - var th2 = new Thread(OnSendHandle); - th2.IsBackground = true; - th2.Start(); - } - catch - { } + // //切换窗口 + // var th1 = new Thread(OnActivationHandle); + // th1.IsBackground = true; + // th1.Start(); + + // //发送消息 + // var th2 = new Thread(OnSendHandle); + // th2.IsBackground = true; + // th2.Start(); + //} + //catch + //{ } } List userNameList = new List() { "gh_3dfda90e39d6"/*, "gh_7aac992b0363"*/ }; diff --git a/PCRobot/Utils/WeChatActivateHelper.cs b/PCRobot/Utils/WeChatActivateHelper.cs new file mode 100644 index 0000000..7757a56 --- /dev/null +++ b/PCRobot/Utils/WeChatActivateHelper.cs @@ -0,0 +1,443 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using PCRobot; + +namespace WechatHelper +{ + /// + /// 微信激活帮助类 + /// + internal class WeChatActivateHelper + { + #region WIN32 API函数 + [DllImport("User32.dll", EntryPoint = "SendMessage")] + private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); + + /// + /// 聚焦 + /// + /// + /// + [DllImport("user32.dll", EntryPoint = "SetFocus")] + private static extern IntPtr SetFocus(IntPtr hWnd); + + /// + /// 判断是否最小化 + /// + /// + /// + [DllImport("user32.dll")] + private static extern bool IsIconic(IntPtr hWnd); + + /// + /// 判断是否可见 + /// + /// + /// + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)] + public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); + + /// + /// 附加线程输入 + /// + /// 当前线程 + /// 目标线程 + /// + /// + [DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "AttachThreadInput", ExactSpelling = true, SetLastError = true)] + private static extern bool AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, bool fAttach); + + //通过句柄获取线程ID + [DllImport("User32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr GetWindowThreadProcessId(IntPtr hwnd, IntPtr id); + + [System.Runtime.InteropServices.DllImport("user32.dll")] + private static extern IntPtr FindWindowExA(IntPtr parentHandle, IntPtr childAfter, string lpClassName, string lpWindowName); + + [System.Runtime.InteropServices.DllImport("USER32.DLL")] + private static extern bool SetForegroundWindow(IntPtr hWnd); + + [System.Runtime.InteropServices.DllImport("user32.dll")] + private static extern bool SetActiveWindow(IntPtr hWnd); + #endregion + + + /// + /// 激活窗口 + /// + private static void ActivateWindow(string lpClassName, string lpWindowName) + { + try + { + //主窗口句柄 + var handle = IntPtr.Zero; + var handleList = new List(); + do + { + //优先休眠,防止continue未休眠 + Thread.Sleep(1000); + + //查找窗口句柄并筛选 + handle = FindWindowExA(IntPtr.Zero, handle, lpClassName, lpWindowName); + if (handle == IntPtr.Zero) + { + break; + } + + if (handleList.Contains(handle)) + { + continue; + } + + handleList.Add(handle); + var isIconic = IsIconic(handle); + + //窗体不可见,视为最小化了 + var isWindowVisible = IsWindowVisible(handle); + if (!isWindowVisible) + { + isIconic = true; + } + + //窗体不可见,或者最小化了 + if (isIconic) + { + ShowWindow(handle, 1); + Thread.Sleep(1000); + } + + var thisHandel = Process.GetCurrentProcess().MainWindowHandle; + //获取自己的线程ID + var thisThreadId = GetWindowThreadProcessId(thisHandel, IntPtr.Zero); + var targetThreadId = GetWindowThreadProcessId(handle, IntPtr.Zero); + //如果这里报错,请添加引用PresentationFramework + var cur = _mSynchronizationContext; + + if (cur == null) + { + Console.WriteLine("当前线程信息获取失败"); + continue; + } + + var handle1 = handle; + cur.Send((e) => + { + try + { + //附加线程 + AttachThreadInput(targetThreadId, thisThreadId, true); + SetFocus(handle1); + var setForegroundWindowResult = SetForegroundWindow(handle1); + var setActiveWindow = SetActiveWindow(handle1); + AttachThreadInput(targetThreadId, thisThreadId, false); + LogHelper.GetSingleObj().Debug("激活", $"this={thisThreadId} target={targetThreadId} fore={setForegroundWindowResult} active={setActiveWindow} "); + + } + catch (Exception exception) + { + Console.WriteLine(exception); + } + + }, null); + + //如果微信最小化了,重新让他最小化 + if (!isIconic) continue; + + Thread.Sleep(1000); + ShowWindow(handle, 2); + } while (true); + } + catch (Exception e) + { + Console.WriteLine($"ActivateWindow Error:{e.Message}\r\nParams:lpClassName={lpClassName} lpWindowName={lpWindowName}"); + } + } + + /// + /// 关闭窗口 + /// + private static void CloseWindow(string className, string windowName) + { + int index = 1; + //主窗口句柄 + var handle = IntPtr.Zero; + var handleList = new List(); + do + { + try + { + Thread.Sleep(1000); + var rstHandlePtr = FindWindowExA(IntPtr.Zero, handle, className, windowName); + if (handle == IntPtr.Zero) break; + if (handleList.Contains(handle)) break; + handleList.Add(handle); + + //找到了,就自动关闭 + SendMessage(rstHandlePtr, 0x0010, 0, 0); + } + catch (Exception e) + { + Console.WriteLine($"关闭窗口失败:{e.Message}"); + break; + } + index++; + } while (index < 10); + } + + /// + /// 激活微信 + /// + private static void ActivateWeChat() + { + CloseWindow("UpdateWnd", "升级"); + ActivateWindow("WeChatMainWndForPC", "微信"); + } + + private static Thread _thread; + private static SynchronizationContext _mSynchronizationContext; + private static MouseHook _mouse; + private static DateTime _lastActiveTime = DateTime.Now; + + /// + /// 初始化激活器 + /// 注:请务必在主线程调用,不要再子线程 + /// + /// 多久激活一次 + /// 强制运行小时 + /// 总激活次数(0表示无限制) + /// + public static bool Init(TimeSpan time, int forcedRunHours = 2, int maxCount = 0) + { + if (_thread != null && _thread.IsAlive) + { + throw new Exception("当前线程尚未结束,请勿重复初始化"); + } + + if (_mouse == null) + { + _mouse = new MouseHook(); + _mouse.OnMouseActivity += _mouse_OnMouseActivity; + _mouse.Start(); + } + + + _mSynchronizationContext = SynchronizationContext.Current; + if (_mSynchronizationContext == null) + { + throw new Exception("获取主线程失败,请不要再子线程执行"); + } + + _thread = new Thread(() => + { + int index = 0; + while (true) + { + try + { + //操作鼠标键盘时间较短 + var curTime = DateTime.Now; + var interval = curTime - _mouseHeartbeatTime; + var isNext = false; + //超过12小时没有激活过,强制激活一次 + if ((curTime - _lastActiveTime).TotalHours > forcedRunHours) + { + isNext = true; + } + //超过了一定时间,没有操作鼠标 + else if (interval > time) + { + isNext = true; + } + + if (!isNext) continue; + index++; + _lastActiveTime = DateTime.Now; + ActivateWeChat(); + if (maxCount != 0 && index >= maxCount) + { + break; + } + } + catch (Exception e) + { + Console.WriteLine($"激活窗口发生异常:{e.Message}"); + } + finally + { + Thread.Sleep(time); + } + } + }) + { + IsBackground = true + }; + _thread.Start(); + return true; + } + + private static DateTime _mouseHeartbeatTime = DateTime.Now; + private static void _mouse_OnMouseActivity(object sender, MouseEventArgs e) + { + _mouseHeartbeatTime = DateTime.Now; + } + } + + internal class MouseHook + { + private const int WM_MOUSEMOVE = 0x200; + private const int WM_LBUTTONDOWN = 0x201; + private const int WM_RBUTTONDOWN = 0x204; + private const int WM_MBUTTONDOWN = 0x207; + private const int WM_LBUTTONUP = 0x202; + private const int WM_RBUTTONUP = 0x205; + private const int WM_MBUTTONUP = 0x208; + private const int WM_LBUTTONDBLCLK = 0x203; + private const int WM_RBUTTONDBLCLK = 0x206; + private const int WM_MBUTTONDBLCLK = 0x209; + + //全局的事件 + public event MouseEventHandler OnMouseActivity; + + static int hMouseHook = 0; //鼠标钩子句柄 + + //鼠标常量 + public const int WH_MOUSE_LL = 14; //mouse hook constant + + HookProc MouseHookProcedure; //声明鼠标钩子事件类型. + + //声明一个Point的封送类型 + [StructLayout(LayoutKind.Sequential)] + public class POINT + { + public int x; + public int y; + } + + //声明鼠标钩子的封送结构类型 + [StructLayout(LayoutKind.Sequential)] + public class MouseHookStruct + { + public POINT pt; + public int hWnd; + public int wHitTestCode; + public int dwExtraInfo; + } + + //装置钩子的函数 + [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); + + //卸下钩子的函数 + [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + public static extern bool UnhookWindowsHookEx(int idHook); + + //下一个钩挂的函数 + [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); + + public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); + + /// + /// 墨认的构造函数构造当前类的实例. + /// + public MouseHook() + { + } + + //析构函数. + ~MouseHook() + { + Stop(); + } + + public void Start() + { + //安装鼠标钩子 + if (hMouseHook == 0) + { + //生成一个HookProc的实例. + MouseHookProcedure = new HookProc(MouseHookProc); + + hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0); + + //如果装置失败停止钩子 + if (hMouseHook == 0) + { + Stop(); + throw new Exception("SetWindowsHookEx failed."); + } + } + } + + public void Stop() + { + bool retMouse = true; + if (hMouseHook != 0) + { + retMouse = UnhookWindowsHookEx(hMouseHook); + hMouseHook = 0; + } + + //如果卸下钩子失败 + if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed."); + } + + private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam) + { + //如果正常运行并且用户要监听鼠标的消息 + if ((nCode >= 0) && (OnMouseActivity != null)) + { + MouseButtons button = MouseButtons.None; + int clickCount = 0; + + switch (wParam) + { + case WM_LBUTTONDOWN: + button = MouseButtons.Left; + clickCount = 1; + break; + case WM_LBUTTONUP: + button = MouseButtons.Left; + clickCount = 1; + break; + case WM_LBUTTONDBLCLK: + button = MouseButtons.Left; + clickCount = 2; + break; + case WM_RBUTTONDOWN: + button = MouseButtons.Right; + clickCount = 1; + break; + case WM_RBUTTONUP: + button = MouseButtons.Right; + clickCount = 1; + break; + case WM_RBUTTONDBLCLK: + button = MouseButtons.Right; + clickCount = 2; + break; + } + + //从回调函数中得到鼠标的信息 + MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); + MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0); + //if(e.X>700)return 1;//如果想要限制鼠标在屏幕中的移动区域可以在此处设置 + OnMouseActivity(this, e); + } + return CallNextHookEx(hMouseHook, nCode, wParam, lParam); + } + } + +} diff --git a/应用/AutoAnswer/Class1.cs b/应用/AutoAnswer/Class1.cs index 72069d8..a68eb39 100644 --- a/应用/AutoAnswer/Class1.cs +++ b/应用/AutoAnswer/Class1.cs @@ -196,7 +196,7 @@ namespace AutoAnswer } #region 呼叫客服 - if (Class1.Config.CellCustomerServiceSwitch == Api.Framework.Enums.SwitchType.开启) + if (Class1.Config.CellCustomerServiceSwitch == Api.Framework.Enums.SwitchType.开启 && !issend) { if (string.IsNullOrEmpty(e.Groupid)) //私聊信息 { diff --git a/类库/Api.Framework/Api.Framework.csproj b/类库/Api.Framework/Api.Framework.csproj index b9000fa..58f156c 100644 --- a/类库/Api.Framework/Api.Framework.csproj +++ b/类库/Api.Framework/Api.Framework.csproj @@ -516,6 +516,7 @@ + @@ -581,6 +582,7 @@ + diff --git a/类库/Api.Framework/ApiClient.cs b/类库/Api.Framework/ApiClient.cs index 4b679af..02f0833 100644 --- a/类库/Api.Framework/ApiClient.cs +++ b/类库/Api.Framework/ApiClient.cs @@ -964,7 +964,25 @@ namespace Api.Framework token = device, remark = "PCWechat HOOK" }; - s.Insertable(robot).ExecuteCommandIdentityIntoEntity(); + robot = s.Insertable(robot).ExecuteReturnEntity(); + + try + { + var result = UserRobotUpLoad.CustomerLink_UpLoadRobot(new List() + { + new UserRobotUpLoad.CustomerRobotInput() + { + HeadUrl = string.Empty, + NickName = robot.nick, + Remark = robot.remark, + RobotType = UserRobotUpLoad.ConvertRobotType(robot.type), + UserName = robot.name + } + }); + } + catch (Exception e) + { } + s.FindRobots(true); } else @@ -2406,6 +2424,12 @@ namespace Api.Framework session.AddIndex("username", "toolpid"); } + if (!session.TableExist()) + { + strb.AppendLine("fl_upload_record"); + session.CreateTable(); + } + if (!session.TableExist()) { strb.AppendLine("fl_bind_cache"); @@ -3606,6 +3630,12 @@ namespace Api.Framework //} case DwzType.快站短网址: { + if (CacheTool.GetSingleObj().Exist("KZShortUrl")) + { + type = DwzType.官方短网址; + goto Next; + } + var urlTmp = KuaiZhanShort.GetShort(url); if (urlTmp == url) { diff --git a/类库/Api.Framework/Model/ModelExtend.cs b/类库/Api.Framework/Model/ModelExtend.cs index 9a2ea05..d38fa2b 100644 --- a/类库/Api.Framework/Model/ModelExtend.cs +++ b/类库/Api.Framework/Model/ModelExtend.cs @@ -433,13 +433,44 @@ namespace Api.Framework.Model var m = session.FindSingle("select * from fl_member_info where robot_type = @robot_type and username = @username", new { username = e.Username, robot_type = e.ChatType }); if (m == null) { - m = new fl_member_info() { crt_time = DateTime.Now, usernick = e.NickName, realnick = e.RealNick, robot_name = e.RobotName, robot_type = e.ChatType, username = e.Username, upd_time = DateTime.Now, alipay_name = string.Empty, alipay_num = string.Empty, remark = string.Empty }; + m = new fl_member_info() + { + crt_time = DateTime.Now, + usernick = e.NickName, + realnick = e.RealNick, + robot_name = e.RobotName, + robot_type = e.ChatType, + username = e.Username, + upd_time = DateTime.Now, + alipay_name = string.Empty, + alipay_num = string.Empty, + remark = string.Empty + }; var groups = session.FindGroups(); if (groups.Count == 0) throw new Exception("会员组未设置,请先设置会员组!"); if (!string.IsNullOrEmpty(e.RealNick)) m.realnick = e.RealNick; if (!string.IsNullOrEmpty(e.Wechatid)) m.wechatid = e.Wechatid; m.group_id = groups[0].id; - session.Insertable(m).ExecuteReturnEntity(); + m = session.Insertable(m).ExecuteReturnEntity(); + + try + { + var result = UserRobotUpLoad.CustomerLink_UpLoadLink(new List() + { + new UserRobotUpLoad.CustomerLinkInput() + { + CreateTime = m.crt_time, + HeadUrl = m.headurl, + NickName = m.usernick, + Remark = m.remark, + RobotName = m.robot_name, + RobotType = UserRobotUpLoad.ConvertRobotType(m.robot_type), + UserName = m.username + } + }); + } + catch (Exception ex) + { } } else { diff --git a/类库/Api.Framework/Model/fl_upload_record.cs b/类库/Api.Framework/Model/fl_upload_record.cs new file mode 100644 index 0000000..b860e44 --- /dev/null +++ b/类库/Api.Framework/Model/fl_upload_record.cs @@ -0,0 +1,31 @@ +using Api.Framework.Tools; + +namespace Api.Framework.Model +{ + /// + /// 数据是否上报成功 + /// + public class fl_upload_record : base_model + { + /// + /// 用户当前的坐标 + /// + public int userindex { get; set; } + + /// + /// 用户数量 + /// + public int usernumber { get; set; } + + /// + /// 用户是否导入完成 + /// + public bool usersuccess { get; set; } = false; + + /// + /// 机器人是否完成 + /// + public bool robotsuccess { get; set; } = false; + + } +} \ No newline at end of file diff --git a/类库/Api.Framework/Tools/KuaiZhanShort.cs b/类库/Api.Framework/Tools/KuaiZhanShort.cs index 37219b5..9d45921 100644 --- a/类库/Api.Framework/Tools/KuaiZhanShort.cs +++ b/类库/Api.Framework/Tools/KuaiZhanShort.cs @@ -63,6 +63,7 @@ namespace Api.Framework.Tools } else if ((int)jobj["code"] == 1001) { + CacheTool.GetSingleObj().Set("KZShortUrl", "", (int)(DateTime.Now.AddDays(1).AddMinutes(5) - DateTime.Now).TotalMinutes); EventClient.OnEvent("短连接", "由于快站短连接接口请求的额度超限制,正在切换其他短连接"); } } diff --git a/类库/Api.Framework/Tools/UserRobotUpLoad.cs b/类库/Api.Framework/Tools/UserRobotUpLoad.cs new file mode 100644 index 0000000..9af3bda --- /dev/null +++ b/类库/Api.Framework/Tools/UserRobotUpLoad.cs @@ -0,0 +1,497 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Net; +using System.Security.Cryptography; +using System.Text; +using Api.Framework.SDK; +using CsharpHttpHelper; + +namespace Api.Framework.Tools +{ + /// + /// 用户/机器人上传 + /// + public class UserRobotUpLoad + { + /// + /// host + /// + public static readonly string host = "http://yzinterface.api.52cmg.cn/api/"; + public static readonly int appkey = 334391396; + public static readonly string appsecret = "b924f8b944694cb8891bcfc7834dedb533436a3776de472cbde99577337902b2"; + public static readonly string appAes = "EDC19B73FEB447929E187243777477913977AB2694394E5B9BC56CD05302C46B"; + public static string UserToken { get; set; } + + /// + /// 上传客户信息 + /// + /// + /// + public static ServiceResult CustomerLink_UpLoadLink(List inputs) + { + if (inputs == null || inputs.Count <= 0) + { + return new ServiceResult() + { + Ok = true + }; + } + return HttpAes("CustomerLink/UpLoadLink", "post", inputs); + } + /// + /// 上传客户机器人信息 + /// + /// + /// + public static ServiceResult CustomerLink_UpLoadRobot(List inputs) + { + if (inputs == null || inputs.Count <= 0) + { + return new ServiceResult() + { + Ok = true + }; + } + return HttpAes("CustomerLink/UpLoadRobot", "post", inputs); + } + + /// + /// AES + /// + /// + /// + /// + /// + /// + private static ServiceResult HttpAes(string api, string method, object postdata = null) + { + try + { + var result = HttpResultAes(api, method, postdata); + if (result.StatusCode == HttpStatusCode.OK) + { + return Newtonsoft.Json.JsonConvert.DeserializeObject>(result.Html); + } + return new ServiceResult(default(T)) + { + Ok = false, + Message = result.Html, + }; + } + catch (Exception e) + { + return new ServiceResult(default(T)) + { + Ok = false, + Message = e.ToString(), + }; + } + } + + /// + /// aes + /// + /// + /// + /// + /// + private static ServiceResult HttpAes(string api, string method, object postdata = null) + { + try + { + var result = HttpResultAes(api, method, postdata); + if (result.StatusCode == HttpStatusCode.OK) + { + return Newtonsoft.Json.JsonConvert.DeserializeObject(result.Html); + } + return new ServiceResult() + { + Ok = false, + Data = result.Html, + }; + } + catch (Exception e) + { + return new ServiceResult() + { + Ok = false, + Data = e.ToString(), + }; + } + } + + /// + /// http aes + /// + /// + /// + /// + /// + private static HttpResult HttpResultAes(string api, string method, object postdata = null) + { + var data = Newtonsoft.Json.JsonConvert.SerializeObject(postdata); + var http = new HttpHelper(); + HttpItem item = new HttpItem() + { + URL = host + api, + Method = method, + Timeout = 100000, + ReadWriteTimeout = 30000, + IsToLower = false, + Cookie = "", + UserAgent = "Server", + Accept = "text/html, application/xhtml+xml, */*", + ContentType = "application/json", + Referer = "", + Allowautoredirect = false, + AutoRedirectCookie = false, + Postdata = data, + PostEncoding = Encoding.UTF8, + //WebProxy = new WebProxy("127.0.0.1:8888") + + }; + var timespan = GetTimespan(DateTime.Now);/*DateTimeHelper.DateTimeToTimeStamp(DateTime.Now)*/; + item.Postdata = SecurityHelper.AesEncrypt(item.Postdata, appAes); + var sign = MD5ToString(Encrypt(item.Postdata + appkey + timespan, appsecret, false)); + item.Header.Add("sign", sign); + item.Header.Add("timestamp", timespan + ""); + item.Header.Add("appkey", appkey + ""); + item.Header.Add("UserToken", UserToken); + var result = http.GetHtml(item); + return result; + } + + /// + /// AES加密 + /// + /// 明文 + /// 密钥 + /// 是否转为base64(否的情况将采用16进制字符串) + /// + public static string Encrypt(string encryptStr, string key, bool isBase64 = true, bool is32 = true) + { + byte[] keyArray = Encoding.UTF8.GetBytes(key.Substring(0, is32 ? 32 : 16)); + byte[] toEncryptArray = Encoding.UTF8.GetBytes(encryptStr); + RijndaelManaged rDel = new RijndaelManaged(); + rDel.Key = keyArray; + rDel.Mode = CipherMode.ECB; + rDel.Padding = PaddingMode.PKCS7; + ICryptoTransform cTransform = rDel.CreateEncryptor(); + byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); + return isBase64 + ? Convert.ToBase64String(resultArray, 0, resultArray.Length) + : ByteArrayToHexString(resultArray); + } + + /// + /// 将一个byte数组转换成16进制字符串 + /// + /// + /// + private static string ByteArrayToHexString(byte[] data) + { + StringBuilder sb = new StringBuilder(data.Length * 3); + foreach (byte b in data) + { + sb.Append(Convert.ToString(b, 16).PadLeft(2, '0')); + } + return sb.ToString().ToUpper(); + } + + public static string MD5ToString(string text) + { + var retVal = new MD5CryptoServiceProvider().ComputeHash(Encoding.Default.GetBytes(text)); + return string.Join("", retVal.Select(s => s.ToString("x2"))); + } + + /// + /// 时间戳(秒) + /// + /// + /// + public static Int64 GetTimespan(DateTime dateTime) + { + TimeSpan ts = dateTime - new DateTime(1970, 1, 1, 0, 0, 0, 0); + return Convert.ToInt64(ts.TotalSeconds); + } + + /// + /// 加密解密帮助类 + /// + public class SecurityHelper + { + #region AES加密解密 + /// + /// 128位处理key + /// + /// 原字节 + /// 处理key + /// + private static byte[] GetAesKey(byte[] keyArray, string key) + { + byte[] newArray = new byte[16]; + if (keyArray.Length < 16) + { + for (int i = 0; i < newArray.Length; i++) + { + if (i >= keyArray.Length) + { + newArray[i] = 0; + } + else + { + newArray[i] = keyArray[i]; + } + } + } + return newArray; + } + /// + /// 使用AES加密字符串,按128位处理key + /// + /// 加密内容 + /// 秘钥,需要128位、256位..... + /// 秘钥,需要128位、256位..... + /// Base64字符串结果 + public static string AesEncrypt(string content, string key, bool autoHandle = true) + { + try + { + byte[] keyArray = Encoding.UTF8.GetBytes(key); + if (autoHandle) + { + keyArray = GetAesKey(keyArray, key); + } + byte[] toEncryptArray = Encoding.UTF8.GetBytes(content); + + SymmetricAlgorithm des = Aes.Create(); + des.Key = keyArray; + des.Mode = CipherMode.ECB; + des.Padding = PaddingMode.PKCS7; + ICryptoTransform cTransform = des.CreateEncryptor(); + byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); + return Convert.ToBase64String(resultArray); + } + catch + { + return ""; + } + + } + /// + /// 使用AES解密字符串,按128位处理key + /// + /// 内容 + /// 秘钥,需要128位、256位..... + /// 秘钥,需要128位、256位..... + /// UTF8解密结果 + public static string AesDecrypt(string content, string key, bool autoHandle = true) + { + try + { + byte[] keyArray = Encoding.UTF8.GetBytes(key); + if (autoHandle) + { + keyArray = GetAesKey(keyArray, key); + } + byte[] toEncryptArray = Convert.FromBase64String(content); + + SymmetricAlgorithm des = Aes.Create(); + des.Key = keyArray; + des.Mode = CipherMode.ECB; + des.Padding = PaddingMode.PKCS7; + + ICryptoTransform cTransform = des.CreateDecryptor(); + byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); + + return Encoding.UTF8.GetString(resultArray); + } + catch + { + return ""; + } + } + /// + /// 使用AES解密字符串,按128位处理key + /// + /// 内容 + /// 秘钥,需要128位、256位..... + /// 秘钥,需要128位、256位..... + /// UTF8解密结果 + public static byte[] AesDecryptByte(string content, string key, bool autoHandle = true) + { + try + { + byte[] keyArray = Encoding.UTF8.GetBytes(key); + if (autoHandle) + { + keyArray = GetAesKey(keyArray, key); + } + byte[] toEncryptArray = Convert.FromBase64String(content); + + SymmetricAlgorithm des = Aes.Create(); + des.Key = keyArray; + des.Mode = CipherMode.ECB; + des.Padding = PaddingMode.PKCS7; + + ICryptoTransform cTransform = des.CreateDecryptor(); + byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); + + return resultArray; + } + catch + { + return null; + } + } + #endregion + } + + /// + /// 上传机器人客户信息 + /// + public class CustomerLinkInput + { + /// + /// 用户名 + /// + [Required] + [DisplayName("用户名")] + public string UserName { get; set; } + /// + /// 机器人类型0个人微信 1企业微信 2QQ + /// + [Required] + [DisplayName("机器人类型0个人微信 1企业微信 2QQ")] + public int RobotType { get; set; } + /// + /// 头像地址 + /// + public string HeadUrl { get; set; } + /// + /// 昵称 + /// + public string NickName { get; set; } + /// + /// 备注 + /// + public string Remark { get; set; } + /// + /// 机器人账号 + /// + [Required] + [DisplayName("机器人账号")] + public string RobotName { get; set; } + /// + /// 添加时间 + /// + [Required] + public DateTime CreateTime { get; set; } + } + + /// + /// 转换机器人类型 + /// + /// + /// + public static int ConvertRobotType(ChatType chatType) + { + /* + 未知来源 = 0, + QQ = 1, + 微信 = 2, + 微信公众号 = 3, + 企业微信 = 4 + */ + + switch (chatType) + { + case ChatType.QQ: + return 2; + case ChatType.企业微信: + return 1; + case ChatType.微信: + return 0; + case ChatType.微信公众号: + return -1; + case ChatType.未知来源: + return -1; + } + return -1; + } + + /// + /// 上传机器人信息 + /// + public class CustomerRobotInput + { + /// + /// 用户名 + /// + [Required] + [DisplayName("用户名")] + public string UserName { get; set; } + /// + /// 机器人类型0个人微信 1企业微信 2QQ + /// + [Required] + [DisplayName("机器人类型0个人微信 1企业微信 2QQ")] + public int RobotType { get; set; } + /// + /// 头像地址 + /// + public string HeadUrl { get; set; } + /// + /// 昵称 + /// + public string NickName { get; set; } + /// + /// 备注 + /// + public string Remark { get; set; } + } + + + /// + /// 统一服务返回结果 + /// + public class ServiceResult + { + /// + /// 请求是否成功 + /// + public bool Ok { get; set; } + /// + /// 数据 + /// + public object Data { get; set; } + /// + /// 错误信息 + /// + public string Message { get; set; } + } + /// + /// 统一返回结果 + /// + /// + public class ServiceResult : ServiceResult + { + /// + /// 初始化 + /// + /// + public ServiceResult(T data) + { + this.Data = data; + } + /// + /// 返回数据 + /// + public new T Data { get; set; } + + } + } +} \ No newline at end of file