old_flsystem/类库/Api.Framework/Cps/PinduoduoApi.cs

214 lines
8.9 KiB
C#
Raw Normal View History

2022-09-20 03:10:29 +00:00
using Api.Framework.Model;
using CsharpHttpHelper;
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
namespace Api.Framework.Cps
{
/// <summary>
/// 拼多多操作Api
/// </summary>
public class PinduoduoApi : BaseCpsApi
{
#region
/// <summary>
/// 拼多多接口请求地址
/// </summary>
private const string app_host = "http://gw-api.pinduoduo.com/api/router";
/// <summary>
/// 计算sign
/// </summary>
/// <param name="parameters">参数</param>
/// <param name="appkey">appkey</param>
/// <returns></returns>
private string SignTopRequest(Dictionary<string, string> parameters, string appkey)
{
// 第一步把字典按Key的字母顺序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters, StringComparer.Ordinal);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
query.Append(appkey);
foreach (KeyValuePair<string, string> kv in sortedParams)
{
if (!string.IsNullOrEmpty(kv.Key) && !string.IsNullOrEmpty(kv.Value))
{
query.Append(kv.Key).Append(kv.Value);
}
}
// 第四步
byte[] bytes;
query.Append(appkey);
MD5 md5 = MD5.Create();
bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));
// 第五步:把二进制转化为大写的十六进制
StringBuilder result = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
result.Append(bytes[i].ToString("X2"));
}
return result.ToString();
}
#endregion
#region
/// <summary>
/// 构造方法
/// </summary>
/// <param name="member"></param>
internal PinduoduoApi(fl_cps_member member) : base(member) { }
/// <summary>
/// 刷新授权
/// </summary>
internal void RefreshStatus()
{
for (int i = 0; i < 3; i++)
{
try
{
//if (Member.cpstype == Enums.CpsType.多多进宝)
// Console.WriteLine();
//UpdateCookies();
var result = SendServer("refresh_token", new { username = Member.username });
if (!result.ok) throw new Exception(result.message.ToString());
Member.online = true;
RefToken();
break;
}
catch (Exception ex)
{
if (i < 2)
{
Thread.Sleep(10000);
continue;
}
else
EventClient.OnEvent(this, $"ERROR:{this.GetType()}@{System.Reflection.MethodBase.GetCurrentMethod().Name}->{ex.Message}");
}
}
}
/// <summary>
/// 发送拼多多报文
/// </summary>
/// <param name="api">请求的api</param>
/// <param name="data">参数</param>
/// <returns></returns>
public Dictionary<string, object> SendPinduoduo(string api, object data)
{
int number = 0;
string html = string.Empty;
Next:
try
{
number++;
//throw new Exception("{\"error_msg\":\"公共参数错误: access_token\",\"sub_msg\":\"公共参数错误: access_token\",\"sub_code\":\"10019\",\"error_code\":10019,\"request_id\":\"16249438515389810\"}");
Dictionary<string, string> param = new Dictionary<string, string>();
var type = data.GetType().GetProperties();
foreach (var item in type)
{
var _value = item.GetValue(data).ToString();
param[item.Name] = _value;
}
//if (api != "pdd.ddk.oauth.order.list.increment.get" && api != "pdd.ddk.oauth.goods.search")
if (api.Contains("oauth"))
param["access_token"] = Token.access_token;
param["type"] = api;
param["client_id"] = Token.appid;
//param["timestamp"] = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000).ToString();//HttpExtend.GetTimeStamp(DateTime.Now).ToString();
param["timestamp"] = HttpExtend.GetTimeStamp();
param["data_type"] = "JSON";
var sign = SignTopRequest(param, Token.appkey);
param["sign"] = sign;
HttpHelper http = new HttpHelper();
HttpItem _item = new HttpItem()
{
URL = app_host,
Method = "Post",//URL 可选项 默认为Get
Timeout = 10000,//连接超时时间 可选项默认为100000
ReadWriteTimeout = 10000,//写入Post数据超时时间 可选项默认为30000
IsToLower = false,//得到的HTML代码是否转成小写 可选项默认转小写
Cookie = "",//字符串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/x-www-form-urlencoded",//返回类型 可选项有默认值
Referer = "",//来源URL 可选项
Postdata = HttpExtend.BuildQuery(param),//Post数据 可选项GET时不需要写
};
html = http.GetHtml(_item).Html;
//if (html.Contains("access_token已过期")) Member.online = false;
//else if (api == "pdd.ddk.oauth.order.list.increment.get") Member.online = true;
var dic = HttpExtend.JsonToDictionary(html);
if (dic.ContainsKey("error_response"))
{
//EventClient.OnEvent(this, $"拼多多接口异常:{this.Member.username}({this.Member.usernick})->{api}->{html}");
throw new Exception(HttpHelper.ObjectToJson(dic["error_response"]));
}
return dic;
}
catch (Exception ex)
{
if (ex.Message.Contains("access_token") && ((ex.Message.Contains("10019") || ex.Message.Contains("20033") || ex.Message.Contains("20032"))))
{
Thread.Sleep(1000);
if (this.Member != null && RefToken() && this.Member.is_valid && number < 3) goto Next;
else
{
//Member.online = false;
//ApiClient.GetSession().SaveOrUpdate(Member);
Member.is_valid = false;
2022-10-26 15:01:01 +00:00
ApiClient.GetSession().SaveOrUpdate(Member);
2022-09-20 03:10:29 +00:00
EventClient.OnEvent(this, $@"拼多多异常:{this.Member.username}({this.Member.usernick}),{ex.Message} - {ex.StackTrace}
,:,{api}");
throw new Exception($"{this.Member.username}({this.Member.usernick}),{ex.Message},注:请重新登录拼多多");
}
}
else if (html.Contains("超时"))
{
goto Next;
}
throw ex;
}
}
/// <summary>
/// 拼多多下载订单
/// </summary>
/// <param name="start_time">开始时间</param>
/// <param name="end_time">结束时间</param>
/// <param name="page_index">每页数量默认50安全</param>
/// <param name="page_size">第几页</param>
/// <returns></returns>
internal Dictionary<string, object> DownOrder(DateTime start_time, DateTime end_time, int page_index, int page_size)
{
if (!Member.is_valid)
throw new Exception("需要重新登录");
var _rst = this.SendPinduoduo("pdd.ddk.oauth.order.list.increment.get", new
{
start_update_time = HttpExtend.GetTimeStamp(start_time),
end_update_time = HttpExtend.GetTimeStamp(end_time),
page_size = page_size,
page = page_index
});
if (_rst.ContainsKey("order_list_get_response"))
{
return _rst["order_list_get_response"] as Dictionary<string, object>;
}
return null;
}
#endregion
}
}