class MyInit { ALiPayHelper aLiPayHelper = new ALiPayHelper(); HttpClientRequest request = new HttpClientRequest(); public void Init() { Mapper.Initialize(x => x.CreateMap<ALiPay, ALiPaySn>()); Task.Run(() => { while (true) { AnalysisDataTimer_Elapsed(null); Thread.Sleep(Helper.AnalysisHtmlTime); } }); Task.Run(() => { while (true) { SendDataTimer_Elapsed(null); Thread.Sleep(Helper.SendRquestTime); } }); Task.Run(() => { while (true) { DeleteHtmlsTimer_Elapsed(null); Thread.Sleep(12000); } }); ////解析定时器 //var analysisDataTimer = new Timer(new TimerCallback(AnalysisDataTimer_Elapsed), null, 0, Helper.AnalysisHtmlTime); ////发送请求定时器 //var sendDataTimer = new Timer(new TimerCallback(SendDataTimer_Elapsed), null, 0, Helper.SendRquestTime); } void DeleteHtmlsTimer_Elapsed(object sender) { try { using (var db = new ALiPayContext()) { db.Database.ExecuteSqlCommand("delete from alipayhtmls where IsProccessed=1"); } } catch (Exception ex) { Logger.Default.Error($"删除已解析的数据报错{ex.Message}"); } } void AnalysisDataTimer_Elapsed(object sender) { try { Logger.Default.Debug($"开始解析数据"); DateTime nowTime = DateTime.Now; var dbWrite = new ALiPayContext(); aLiPayHelper.AnalysisData(dbWrite, nowTime); Logger.Default.Debug($"完成解析数据"); } catch (Exception ex) { Logger.Default.Error($"解析数据报错{ex.Message}"); } } void SendDataTimer_Elapsed(object sender) { try { Logger.Default.Debug($"开始发送请求"); DateTime nowTime = DateTime.Now; var dbWrite = new ALiPayContext(); aLiPayHelper.SendData(dbWrite, request, nowTime); Logger.Default.Debug($"完成发送请求"); } catch (Exception ex) { Logger.Default.Error($"发送请求报错{ex.Message}"); } } }
class ALiPayHelper { #region 发送请求 public void SendData(ALiPayContext dbWrite, HttpClientRequest request, DateTime nowTime) { var snList = dbWrite.ALiPaySn.Where(w => w.NextRequestTime < nowTime && !w.IsRequestSuccess).Take(200).ToList(); dbWrite.Dispose(); dbWrite = null; if (snList.Count > 0) { var taskList = new List<Task<ResultOut>>(); foreach (var item in snList) { taskList.Add(RequestData(request, Helper.RequestUri, item)); } Task.WhenAll(taskList).ContinueWith(task => { if (task.IsFaulted) { Logger.Default.Error($"1,请求报错:{task.Exception.GetBaseException().Message}"); } else { Logger.Default.Debug($"2,请求结果:{JsonConvert.SerializeObject(task.Result)}"); return ModifyRequestNum(task.Result); } return Task.FromResult(0); }); } } /// <summary> /// 请求完成后将请求的结果信息修改到对应数据中 /// </summary> /// <param name="list"></param> /// <returns></returns> Task<int> ModifyRequestNum(ResultOut[] list) { var paySnList = list.Select(w => w.Model.PaySn).ToList(); if (paySnList.Count > 0) { using (var dbWrite = new ALiPayContext()) { var paySnModelList = dbWrite.ALiPaySn.Where(w => paySnList.Contains(w.PaySn)).ToList(); if (paySnModelList != null) { foreach (var paySnModel in paySnModelList) { var item = list.Where(w => w.Model.PaySn == paySnModel.PaySn).FirstOrDefault(); if (item != null) { paySnModel.IsRequestSuccess = item.IsSuccess; paySnModel.RequestNum = paySnModel.RequestNum + 1; paySnModel.ResponseStr = item.Result; if (!item.IsSuccess) { paySnModel.NextRequestTime = paySnModel.NextRequestTime.AddMinutes(paySnModel.RequestNum * 2); } } } var result = dbWrite.SaveChangesAsync(); return result; } } } return Task.FromResult(0); } /// <summary> /// 发送请求,并返回请求结果信息 /// </summary> /// <param name="request"></param> /// <param name="uri"></param> /// <param name="model"></param> /// <returns></returns> async Task<ResultOut> RequestData(HttpClientRequest request, string uri, ALiPaySn model) { var parameters = new List<KeyValuePair<string, string>>(); parameters.Add(new KeyValuePair<string, string>("Money", model.Money.ToString("f2"))); parameters.Add(new KeyValuePair<string, string>("Name", model.Name)); parameters.Add(new KeyValuePair<string, string>("OtherSide", model.OtherSide)); parameters.Add(new KeyValuePair<string, string>("PaySn", model.PaySn)); parameters.Add(new KeyValuePair<string, string>("PayTime", model.PayTime)); parameters.Add(new KeyValuePair<string, string>("Status", model.Status)); var canshu = $"Money={model.Money.ToString("f2")}&Name={model.Name}&OtherSide={model.OtherSide}&PaySn={model.PaySn}&PayTime={model.PayTime}&Status={model.Status}&key={Helper.RequestMd5Key}"; parameters.Add(new KeyValuePair<string, string>("sign", canshu.To32MD5())); Logger.Default.Debug($"uri:{uri},请求参数:{JsonConvert.SerializeObject(parameters)}"); var postTask = request.PostAsync(uri, parameters); var timeOutTask = Task.Delay(10000); var task = await Task.WhenAny(postTask, timeOutTask);//返回任何一个完成的任务 if (task == timeOutTask)//如果超时任务先完成了 就返回 很可惜 他没有完成! { Logger.Default.Debug($"uri:{uri},请求参数:{JsonConvert.SerializeObject(parameters)},结果:请求超时"); return new ResultOut { IsSuccess = false, Msg = "请求超时", Model = model }; } if (postTask.IsFaulted) { Logger.Default.Debug($"uri:{uri},请求参数:{JsonConvert.SerializeObject(parameters)},结果:请求错误.{task.Exception.GetBaseException().Message}"); return new ResultOut() { IsSuccess = false, Msg = $"请求错误.{task.Exception.GetBaseException().Message}", Model = model }; } //if (postTask.Result.Contains("success")) //{ Logger.Default.Debug($"uri:{uri},请求参数:{JsonConvert.SerializeObject(parameters)},结果:请求成功,{postTask.Result}"); return new ResultOut { IsSuccess = true, Msg = "请求成功", Result = postTask.Result, Model = model }; //} //return new ResultOut { IsSuccess = false, Msg = "请求成功", Result = postTask.Result, Model = model }; } #endregion #region 解析数据并保存 public void AnalysisData(ALiPayContext dbWrite, DateTime nowTime) { var list = dbWrite.AlipayHtmls.Where(w => !w.IsProccessed).OrderByDescending(o => o.CreateTime).Take(200).ToList(); if (list.Count > 0) { var aLiPayList = Send(list); aLiPayList.RemoveAll(w => dbWrite.ALiPaySn.Any(t => t.PaySn == w.PaySn)); if (aLiPayList.Count > 0) { foreach (var item in aLiPayList) { var dto = Mapper.Map<ALiPaySn>(item); dto.Id = Guid.NewGuid(); dto.NextRequestTime = nowTime; dto.CreateTime = nowTime; dto.RequestNum = 0; dbWrite.ALiPaySn.Add(dto); } } foreach (var item in list) { item.IsProccessed = true; } var taskHtml = dbWrite.SaveChangesAsync(); taskHtml.ContinueWith(task => { task.Wait(); dbWrite.Dispose(); dbWrite = null; if (taskHtml.IsFaulted) { StringBuilder exSb = new StringBuilder(); var exList = taskHtml.Exception.InnerExceptions; foreach (var ex in exList) { if (ex is System.Data.Entity.Infrastructure.DbUpdateException) { exSb.Append(ex.InnerException.InnerException.Message); } else if (ex is DbEntityValidationException) { var vex = ex as DbEntityValidationException; foreach (var entityItem in vex.EntityValidationErrors) { foreach (var err in entityItem.ValidationErrors) { exSb.Append(err.ErrorMessage); } } } else { exSb.Append(ex.Message); } } Logger.Default.Error(exSb.ToString()); } else { Logger.Default.Debug($"解析后添加数据,受影响的行数{taskHtml.Result.ToString()}条"); } }); } } #region 解析JSON List<ALiPay> Send(List<AlipayHtmls> list) { var aliPayList = new List<ALiPay>(); Newtonsoft.Json.Linq.JObject json, result; Newtonsoft.Json.Linq.JArray detailArry; string status; foreach (var item in list) { json = (Newtonsoft.Json.Linq.JObject)JsonConvert.DeserializeObject(item.Html); status = json["status"].ToString(); if (status == "succeed") { result = (Newtonsoft.Json.Linq.JObject)json["result"]; detailArry = (Newtonsoft.Json.Linq.JArray)result["detail"]; foreach (var detailItem in detailArry) { var model = new ALiPay { MoneyStr = detailItem["totalAmount"].ToString(), Name = detailItem["goodsTitle"].ToString(), OtherSide = detailItem["consumerLoginId"].ToString(), PaySn = detailItem["tradeNo"].ToString(), PayTime = detailItem["gmtCreate"].ToString(), Status = detailItem["tradeStatus"].ToString() }; if (!aliPayList.Any(w => w.PaySn == model.PaySn)) { aliPayList.Add(model); } } } } return aliPayList; } #endregion #region 解析html //List<ALiPay> Send(List<AlipayHtmls> list) //{ // var doc = new HtmlDocument(); // var aliPayList = new List<ALiPay>(); // foreach (var item in list) // { // doc.LoadHtml(item.Html); // var tradeRecordsIndexTabEle = doc.GetElementbyId("tradeRecordsIndex"); // var trEles = tradeRecordsIndexTabEle.SelectNodes("//tbody/tr"); // foreach (var tr in trEles) // { // var model = new ALiPay(); // var memoEle = tr.SelectSingleNode("td[@class='memo']/a"); // if (memoEle == null) // { // var nameEle = tr.SelectSingleNode("td[@class='name']/p/a"); // if (nameEle == null) // { // nameEle = tr.SelectSingleNode("td[@class='action']/select/option[@class='split']"); // GetOrderOn(nameEle.GetAttributeValue("data-link", string.Empty).RemoveEmpty(), model); // nameEle = tr.SelectSingleNode("td[@class='name']"); // model.Name = nameEle.InnerText.RemoveEmpty(); // } // else // { // GetOrderOn(nameEle.GetAttributeValue("href", string.Empty), model); // model.Name = nameEle.InnerText.RemoveEmpty(); // } // } // else // { // var nameEle = tr.SelectSingleNode("td[@class='name']"); // model.Name = nameEle.InnerText.RemoveEmpty(); // GetOrderOn(memoEle.GetAttributeValue("href", string.Empty), model); // } // if (aliPayList.Any(w => w.PaySn == model.PaySn)) // { // continue; // } // if (model.Name.StartsWith("商品-")) // { // model.Name = model.Name.Substring(3); // } // var otherEle = tr.SelectSingleNode("td[@class='other']"); // model.OtherSide = otherEle == null ? string.Empty : otherEle.InnerText.RemoveEmpty(); // var p0Ele = tr.SelectSingleNode("td[@class='name']/p[@class='consume-title']"); // var payName = p0Ele.InnerText.RemoveEmpty(); // var amountEle = tr.SelectSingleNode("td[@class='amount']"); // model.MoneyStr = amountEle.InnerText.RemoveEmpty(); // var statusEle = tr.SelectSingleNode("td[@class='status']/p"); // model.Status = statusEle.InnerText.RemoveEmpty(); // aliPayList.Add(model); // } // } // return aliPayList; //} //static Regex regEditMemo = new Regex("/record/editMemo.htm?", RegexOptions.IgnoreCase); //static Regex regSimpleDetail = new Regex("/record/detail/simpleDetail.htm?", RegexOptions.IgnoreCase); //static Regex regBizInNo = new Regex(@"bizInNo=(d+)", RegexOptions.IgnoreCase); //static Regex regGmtBizCreate = new Regex(@"gmtBizCreate=(d+)", RegexOptions.IgnoreCase); //static Regex regCreateDate = new Regex(@"createDate=			(d+)", RegexOptions.IgnoreCase); //static Regex regCreateDate1 = new Regex(@"createDate=(d+)", RegexOptions.IgnoreCase); //static void GetOrderOn(string url, ALiPay model) //{ // model.PaySn = regBizInNo.Match(url).Groups[1].Value; // if (regEditMemo.IsMatch(url)) // { // model.PayTime = regCreateDate.Match(url).Groups[1].Value; // if (string.IsNullOrWhiteSpace(model.PayTime)) // { // model.PayTime = regCreateDate1.Match(url).Groups[1].Value; // } // } // else if (regSimpleDetail.IsMatch(url)) // { // model.PayTime = regGmtBizCreate.Match(url).Groups[1].Value; // } //} #endregion #endregion }
/// <summary> /// 移除空字符包括换行,制表符,空格 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string RemoveEmpty(this string str) { if (string.IsNullOrEmpty(str)) { return string.Empty; } return str.Replace(" ", "").Replace(" ", "").Replace(" ", "").Replace(" ", ""); } /// <summary> /// 转换为数字 /// </summary> /// <param name="str"></param> /// <returns></returns> public static int ToMyInt32(this string str, int defaultVal = 0) { if (string.IsNullOrEmpty(str)) { return defaultVal; } int.TryParse(str, out defaultVal); return defaultVal; } static MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); /// <summary> /// 32位MD5加密 /// </summary> /// <param name="val"></param> /// <returns></returns> public static string To32MD5(this string val) { var t2 = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(val))); t2 = t2.Replace("-", ""); return t2; } /// <summary> /// 获取时间戳(取到毫秒得到的时间戳就是13位,只取到秒的话时间戳就是10位) /// </summary> /// <param name="dt"></param> /// <param name="bflag"></param> /// <returns></returns> public static long MyDateToLong(this DateTime dt, bool bflag = false) { TimeSpan ts = dt - new DateTime(1970, 1, 1, 0, 0, 0, 0); if (bflag) { return Convert.ToInt64(ts.TotalSeconds); } return Convert.ToInt64(ts.TotalMilliseconds); } } /// <summary> /// 请求帮助类 /// </summary> public class HttpClientRequest { private readonly HttpClient _httpClient; public HttpClientRequest() { _httpClient = new HttpClient() { BaseAddress = new Uri(Helper.RequestUrl) }; //帮HttpClient热身 _httpClient.SendAsync(new HttpRequestMessage { Method = new HttpMethod("HEAD"), RequestUri = new Uri(Helper.RequestUrl) }).Result.EnsureSuccessStatusCode(); } /// <summary> /// POST请求 /// </summary> /// <param name="uri"></param> /// <param name="parameters"></param> /// <returns></returns> public async Task<string> PostAsync(string uri, List<KeyValuePair<string, string>> parameters) { var response = await _httpClient.PostAsync(uri, new FormUrlEncodedContent(parameters)); return await response.Content.ReadAsStringAsync(); } } public static class ListEx { #region 将datatable数据转化成list /// <summary> /// 将datatable数据转化成list /// </summary> /// <typeparam name="T">泛型T</typeparam> /// <param name="dt">对应的datatable数据表</param> /// <returns>返回结果的数据集</returns> public static List<T> ToLists<T>(this DataTable dt) where T : class, new() { Type t = typeof(T); PropertyInfo[] propertys = t.GetProperties(); List<T> lst = new List<T>(); string typeName = string.Empty; foreach (DataRow dr in dt.Rows) { T entity = new T(); foreach (PropertyInfo pi in propertys) { typeName = pi.Name; if (dt.Columns.Contains(typeName)) { if (!pi.CanWrite) continue; object value = dr[typeName]; if (value == DBNull.Value) continue; if (pi.PropertyType == typeof(string)) { pi.SetValue(entity, value.ToString(), null); } else if (pi.PropertyType == typeof(int) || pi.PropertyType == typeof(int?)) { pi.SetValue(entity, int.Parse(value.ToString()), null); } else if (pi.PropertyType == typeof(DateTime?) || pi.PropertyType == typeof(DateTime)) { pi.SetValue(entity, DateTime.Parse(value.ToString()), null); } else if (pi.PropertyType == typeof(float)) { pi.SetValue(entity, float.Parse(value.ToString()), null); } else if (pi.PropertyType == typeof(double)) { pi.SetValue(entity, double.Parse(value.ToString()), null); } else { pi.SetValue(entity, value, null); } } } lst.Add(entity); } return lst; //调用 //List<People> p = dt.ToList<People>(); } #endregion #region 将list数据转化成datatable public static DataTable ToDataTable(this IList list, params string[] propertyName) { List<string> propertyNameList = new List<string>(); if (propertyName != null) { propertyNameList.AddRange(propertyName); } DataTable result = new DataTable(); if (list.Count > 0) { PropertyInfo[] propertys = list[0].GetType().GetProperties(); foreach (PropertyInfo pi in propertys) { if (propertyNameList.Count == 0) { result.Columns.Add(pi.Name, pi.PropertyType); } else { if (propertyNameList.Contains(pi.Name)) result.Columns.Add(pi.Name, pi.PropertyType); } } for (int i = 0; i < list.Count; i++) { ArrayList tempList = new ArrayList(); foreach (PropertyInfo pi in propertys) { if (propertyNameList.Count == 0) { object obj = pi.GetValue(list[i], null); tempList.Add(obj); } else { if (propertyNameList.Contains(pi.Name)) { object obj = pi.GetValue(list[i], null); tempList.Add(obj); } } } object[] array = tempList.ToArray(); result.LoadDataRow(array, true); } } return result; } #endregion }