using Api.Framework; using Api.Framework.Enums; using Api.Framework.Events; using Api.Framework.Model; using Api.Framework.Tools; using CsharpHttpHelper; using CsharpHttpHelper.Enum; using Microsoft.Win32; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using static FLSystem.Forms.point_manage_control; namespace FLSystem { #region 同步Win系统时间 public class Daytime { // Internet Time Server class by Alastair Dallas 01/27/04 // Number of seconds private const int THRESHOLD_SECONDS = 15; // that Windows clock can deviate from NIST and still be okay //Server IP addresses from //http://www.boulder.nist.gov/timefreq/service/time-servers.html private static string[] Servers = { //"129.6.15.28", //"129.6.15.29", //"132.163.4.101", //"132.163.4.102", //"132.163.4.103", //"128.138.140.44", //"192.43.244.18", //"131.107.1.10", //"66.243.43.21", //"216.200.93.8", //"208.184.49.9", //"207.126.98.204", //"205.188.185.33" "time.windows.com"//微软时间同步服务器 }; public static string LastHost = ""; public static DateTime LastSysTime; public static DateTime GetTime() { //Returns UTC/GMT using an NIST server if possible, // degrading to simply returning the system clock //If we are successful in getting NIST time, then // LastHost indicates which server was used and // LastSysTime contains the system time of the call // If LastSysTime is not within 15 seconds of NIST time, // the system clock may need to be reset // If LastHost is "", time is equal to system clock string host = null; DateTime result = default(DateTime); LastHost = ""; foreach (string host_loopVariable in Servers) { host = host_loopVariable; result = GetNISTTime(host); if (result > DateTime.MinValue) { LastHost = host; break; // TODO: might not be correct. Was : Exit For } } if (string.IsNullOrEmpty(LastHost)) { //No server in list was successful so use system time result = DateTime.Now; } return result; } public static int SecondsDifference(DateTime dt1, DateTime dt2) { TimeSpan span = dt1.Subtract(dt2); return span.Seconds + (span.Minutes * 60) + (span.Hours * 360); } public static bool WindowsClockIncorrect() { DateTime nist = GetTime(); if ((Math.Abs(SecondsDifference(nist, LastSysTime)) > THRESHOLD_SECONDS)) { return true; } return false; } private static DateTime GetNISTTime(string host) { //Returns DateTime.MinValue if host unreachable or does not produce time DateTime result = default(DateTime); string timeStr = null; try { StreamReader reader = new StreamReader(new TcpClient(host, 13).GetStream()); LastSysTime = DateTime.UtcNow; timeStr = reader.ReadToEnd(); reader.Close(); } catch (SocketException ex) { //Couldn't connect to server, transmission error Debug.WriteLine("Socket Exception [" + host + "]"); return DateTime.MinValue; } catch (Exception ex) { //Some other error, such as Stream under/overflow return DateTime.MinValue; } //Parse timeStr if ((timeStr.Substring(38, 9) != "UTC(NIST)")) { //This signature should be there return DateTime.MinValue; } if ((timeStr.Substring(30, 1) != "0")) { //Server reports non-optimum status, time off by as much as 5 seconds return DateTime.MinValue; //Try a different server } int jd = int.Parse(timeStr.Substring(1, 5)); int yr = int.Parse(timeStr.Substring(7, 2)); int mo = int.Parse(timeStr.Substring(10, 2)); int dy = int.Parse(timeStr.Substring(13, 2)); int hr = int.Parse(timeStr.Substring(16, 2)); int mm = int.Parse(timeStr.Substring(19, 2)); int sc = int.Parse(timeStr.Substring(22, 2)); if ((jd < 15020)) { //Date is before 1900 return DateTime.MinValue; } if ((jd > 51544)) yr += 2000; else yr += 1900; return new DateTime(yr, mo, dy, hr, mm, sc); } [StructLayout(LayoutKind.Sequential)] public struct SYSTEMTIME { public Int16 wYear; public Int16 wMonth; public Int16 wDayOfWeek; public Int16 wDay; public Int16 wHour; public Int16 wMinute; public Int16 wSecond; public Int16 wMilliseconds; } [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] private static extern Int32 GetSystemTime(ref SYSTEMTIME stru); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] private static extern Int32 SetSystemTime(ref SYSTEMTIME stru); [DllImport("Kernel32.dll")] public static extern void GetLocalTime(ref SYSTEMTIME lpSystemTime); [DllImport("Kernel32.dll")] public static extern bool SetLocalTime(ref SYSTEMTIME lpSystemTime); public static void SetWindowsClock(DateTime dt) { //Sets system time. Note: Use UTC time; Windows will apply time zone SYSTEMTIME timeStru = default(SYSTEMTIME); Int32 result = default(Int32); timeStru.wYear = (Int16)dt.Year; timeStru.wMonth = (Int16)dt.Month; timeStru.wDay = (Int16)dt.Day; timeStru.wDayOfWeek = (Int16)dt.DayOfWeek; timeStru.wHour = (Int16)dt.Hour; timeStru.wMinute = (Int16)dt.Minute; timeStru.wSecond = (Int16)dt.Second; timeStru.wMilliseconds = (Int16)dt.Millisecond; SetLocalTime(ref timeStru); } } #endregion public class Tools { //private static Dictionary Config { get; set; } static Tools() { EventClient.MethodEvent += EventClient_MethodEvent; } private static void EventClient_MethodEvent(object sender, MethodType e) { if (e == MethodType.刷新配置文件) { ApiClient.GetPointManageConfig(true); //Config = Util.ReadConfig("插件-积分管理-配置", true);//刷新积分管理中的配置文件 } } /// /// 获取积分插件配置文件 /// /// /// //public static Dictionary GetPointConfig(bool flush = false) //{ // if (Config == null || flush) // Config = Util.ReadConfig("插件-积分管理-配置", true);//刷新积分管理中的配置文件 // return Config; //} /// /// 判断.Net Framework的Release是否符合需要 /// (.Net Framework 版本在4.0及以上) /// ///需要的版本 version = 4.5 release = 379893 /// public static bool GetDotNetRelease(int release) { const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"; using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey)) { if (ndpKey != null && ndpKey.GetValue("Release") != null) { return (int)ndpKey.GetValue("Release") >= release ? true : false; } return false; } } public static void GetFileFromNetUrl(string url, string file) { try { System.Net.WebRequest req = System.Net.WebRequest.Create(url); req.Method = "GET"; //获得用户名密码的Base64编码 添加Authorization到HTTP头 不需要的账号密码的可以注释下面两行代码 string code = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "userName", "passWord"))); req.Headers.Add("Authorization", "Basic " + code); byte[] fileBytes; using (WebResponse webRes = req.GetResponse()) { int length = (int)webRes.ContentLength; HttpWebResponse response = webRes as HttpWebResponse; Stream stream = response.GetResponseStream(); //读取到内存 MemoryStream stmMemory = new MemoryStream(); byte[] buffer = new byte[length]; int i; //将字节逐个放入到Byte中 while ((i = stream.Read(buffer, 0, buffer.Length)) > 0) { stmMemory.Write(buffer, 0, i); } fileBytes = stmMemory.ToArray();//文件流Byte,需要文件流可直接return,不需要下面的保存代码 stmMemory.Close(); MemoryStream m = new MemoryStream(fileBytes); //string file = Util.MapFile("NDP46-KB3045560-Web.exe", @"Cache\_NetFramework");//可根据文件类型自定义后缀 FileStream fs = new FileStream(file, FileMode.OpenOrCreate); m.WriteTo(fs); m.Close(); fs.Close(); } } catch (System.Exception ex) { throw ex; } } } public class Utils { //private static Timer timer = new Timer(new TimerCallback(ShpaySync), null, 0, 1000 * 60 * 10); //private static bool IsRunSendShPay = false; //private static void ShpaySync(object state) //{ // if (IsRunSendShPay) return; // IsRunSendShPay = true; // try // { // //EventClient.OnEvent("", "执行状态:" + ApiClient.Setting.SystemConfig.send_shpay_switch); // if (!ApiClient.Setting.SystemConfig.send_shpay_switch) return; // var db = ApiClient.GetSession(); // var time = HttpExtend.GetTimeStamp(DateTime.Now.AddDays(-1)); // var shpayList = db.Queryable().Where(f => f.paytype == PayGetType.未领取 && f.sendtime == 0 && f.ctime <= time).ToList(); // //EventClient.OnEvent("", "执行的数量:" + shpayList.Count); // SendShPayMes(shpayList); // } // catch (Exception ex) // { // EventClient.OnEvent("", $"通知24小时商户未领取异常:{ex.Message} - {ex.StackTrace}"); // } // finally // { // IsRunSendShPay = false; // } //} #region 兑换发送消息 public static void SendShPayMes(List shpayList) { try { if (shpayList == null || shpayList.Count == 0) return; var session = ApiClient.GetSession(); var yjPayList = new List();//已经领取的连接 var sendShpayDic = new Dictionary>();//需要发送的商户 var ShPayTmpDic = new Dictionary>();//需要发送并且能发送商户小程序 #region 重新获取商户地址并发送消息 var timedate = shpayList.GroupBy(f => f.ctimedate).Select(f => f.Key).ToList(); //EventClient.OnEvent("", "A " + timedate.Count); foreach (var date in timedate) { var strb = new StringBuilder(); var html = string.Empty; try { strb.Append("手动处理未领取的商户:"); var arr = shpayList.Where(f => f.ctimedate == date).Select(f => "\"" + f.orderid + "\"").ToList(); if (arr.Count() != 0) { string parm = "orders=[" + string.Join(",", arr) + $"]&time={date}"; strb.Append($"手动处理未领取的商户:{parm}"); HttpHelper http = new HttpHelper(); HttpItem item = new HttpItem() { URL = "https://pay.api.52cmg.cn/pay/getNewLinks", Method = "POST", Timeout = 100000, ReadWriteTimeout = 30000, IsToLower = false, Cookie = "", UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0", Accept = "text/html, application/xhtml+xml, */*", ContentType = "application/json", Referer = "", Allowautoredirect = false, AutoRedirectCookie = false, Postdata = parm, ResultType = ResultType.String, }; html = http.GetHtml(item).Html; strb.AppendLine($"最新的数据:{html}"); //{"ok":true,"res":"7d043f8e8e4be0784a596a25cbc078fb|{\"code\":1,\"msg\":\"https://txbgl.kuaizhan.com/?orderid=7d043f8e8e4be0784a596a25cbc078fb\u0026appid=wxb8485eacd6e3b832\",\"appinfo\":null}\r\n144a00f52c271c39513937c252a54ef6|已支付"} //{"ok":true,"res":"1ec1dada9db612ab972bca104c273909|{\"code\":1,\"msg\":\"https://txbgl.kuaizhan.com/?orderid=1ec1dada9db612ab972bca104c273909\u0026appid=wx6e0df44505ec10f5\",\"appinfo\":{\"ShopId\":15000000,\"appId\":\"wxe5d3b3d276b346c3\",\"appSecret\":\"441c959d0491be8a136db63d5cca6497\",\"appName\":\"gh_ec03868ecfeb\",\"target\":\"\\\"pages/index/index.html?orderId=[订单编号]\\\"\"}}"} var shResult = JsonConvert.DeserializeObject(html); if (shResult != null && shResult.ok) { var regs = Regex.Split(shResult.res, @"[\r\n]").Where(f => !string.IsNullOrWhiteSpace(f)).ToList(); if (regs.Count == 0) continue; foreach (var tmp in regs) { var split = tmp.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries); var shpay = shpayList.FirstOrDefault(f => split[0] == f.orderid); if (shpay != null) { shpay.paytype = split[1] == "已支付" ? PayGetType.已领取 : PayGetType.未领取; if (shpay.paytype == PayGetType.已领取) yjPayList.Add(shpay); else { if (!sendShpayDic.ContainsKey(shpay.robotname)) sendShpayDic.Add(shpay.robotname, new List()); var jObj = JObject.Parse(split[1]); if (jObj["msg"] != null) shpay.payurl = jObj["msg"].ToString(); sendShpayDic[shpay.robotname].Add(shpay); if (!ShPayTmpDic.ContainsKey(shpay.robotname)) ShPayTmpDic.Add(shpay.robotname, new List()); if (jObj["appinfo"] != null && jObj["appinfo"].ToString().ToLower() != "null") ShPayTmpDic[shpay.robotname].Add(new ShPayTmp() { id = shpay.id, shpayInfo = jObj["appinfo"].ToObject>() }); } } } } } } catch (Exception ex) { EventClient.OnEvent("", $"商户状态查询异常:{ex.Message} - {ex.StackTrace} , {html}"); } finally { //EventClient.OnEvent("",strb.ToString()); } } //EventClient.OnEvent("", "B " + sendShpayDic.Count); #region 获取到商户数据以后发送消息 var sendShpayList = new List(); if (sendShpayDic.Count != 0) { try { foreach (KeyValuePair> item in sendShpayDic) { //EventClient.OnEvent("", $"C : {item.Key} - {item.Value.Count} - {(Chat.Framework.ChatClient.WXClient.FirstOrDefault(f => f.Key == item.Key).Value == null)}"); var wx = Chat.Framework.ChatClient.WXClient.FirstOrDefault(f => f.Key == item.Key && f.Value.Status == Chat.Framework.WXSdk.WxStatus.在线).Value; if (wx == null) continue; foreach (var tmp in item.Value) { var msg = string.Empty; var flag = false;//是否为xml if (ApiClient.Setting.SystemConfig.send_shpay_minixml && ShPayTmpDic.ContainsKey(item.Key)) { var shpayTmpList = ShPayTmpDic[item.Key]; var payInfo = shpayTmpList.FirstOrDefault(f => f.id == tmp.id); if (payInfo != null) { msg = Util.GetMiNiAppXml(payInfo.shpayInfo, tmp.chattype); if (!string.IsNullOrWhiteSpace(msg)) { wx.SendMessage(tmp.username, msg.Replace("[订单编号]", tmp.orderid)); flag = true; } } } if (!flag) { msg = ApiClient.Setting.SystemConfig.send_shpay_msg.Replace("[账号]", tmp.username).Replace("[昵称]", tmp.usernick).Replace("[领取地址]", tmp.payurl).Replace("[兑换金额]", tmp.point.ToString("0.00")).Replace("[积分名称]", ApiClient.Setting.SystemConfig.PointName); wx.SendMessage(tmp.username, msg); } tmp.sendtime = HttpExtend.GetTimeStamp(DateTime.Now); EventClient.OnEvent("提示用户商户未领取", $"{wx.User.Nick}[{wx.User.Username}]【{wx.User.Uin}】:发送:{tmp.usernick}({tmp.username}),领取地址:{tmp.payurl} ,未领金额:{tmp.point.ToString("0.00")},{(msg == null ? 0 : msg.Length)},xml ? {(flag ? "是" : "否")}"); sendShpayList.Add(tmp); Thread.Sleep(1000); } } if (shpayList.Count != 0) session.Saveable(shpayList).ExecuteCommand(); } catch (Exception ex) { EventClient.OnEvent("", $"商户状态修改异常:{ex.Message} - {ex.StackTrace}"); } } #endregion #region 修改数据库中的状态 var shpayList1 = new List(); if (yjPayList.Count != 0) { try { foreach (var item in yjPayList) { item.paytime = HttpExtend.GetTimeStamp(DateTime.Now); item.paytype = PayGetType.已领取; shpayList1.Add(item); } } catch (Exception ex) { EventClient.OnEvent("", $"商户状态修改异常1:{ex.Message} - {ex.StackTrace}"); } } if (sendShpayList.Count != 0) { try { foreach (var item in sendShpayList) { shpayList1.Add(item); } } catch (Exception ex) { EventClient.OnEvent("", $"商户状态修改异常1:{ex.Message} - {ex.StackTrace}"); } } if (shpayList1.Count != 0) session.Updateable(shpayList1).ExecuteCommand(); #endregion #endregion } catch (Exception ex) { EventClient.OnEvent("", $"{ex.Message} - {ex.StackTrace}"); } } /// /// 商户小程序信息临时类 /// class ShPayTmp { public long id { get; set; } public object shpayInfo { get; set; } } #endregion } }