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

329 lines
13 KiB
C#
Raw Normal View History

2022-09-20 03:10:29 +00:00
using Api.Framework.Model;
using Api.Framework.Tools;
using Api.Framework.Utils;
using CsharpHttpHelper;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Api.Framework.EntityTmp.WeiPinHui;
namespace Api.Framework.Cps
{
/// <summary>
/// 唯品会操作Api
/// </summary>
public class WeipinhuiApi : BaseCpsApi
{
#region
/// <summary>
/// 构造方法
/// </summary>
/// <param name="member"></param>
internal WeipinhuiApi(fl_cps_member member) : base(member) { }
/// <summary>
/// 刷新授权
/// </summary>
public void RefreshStatus()
{
try
{
var result = SendServer("refresh_token", new { username = Member.username });
if (!result.ok) throw new Exception(result.message.ToString());
Member.online = true;
}
catch (Exception ex)
{
EventClient.OnEvent(this, $"ERROR:{this.GetType()}-{System.Reflection.MethodBase.GetCurrentMethod().Name}->{ex.Message}");
}
}
//private string AppKey = "0c85e6c0";
//private string AppSecret = "F921D8D3EFEAEA5B0387158512AEF909";
#region
/// <summary>
/// 发送唯品会报文
/// </summary>
/// <param name="api">api接口</param>
/// <param name="data">参数</param>
/// <returns></returns>
public T SendWeipinhui<T>(string api, object data)
{
if (!Member.is_valid) return default(T);
var isRefToken = false;
var html = string.Empty;
for (int i = 0; i < 3; i++)
{
try
{
var query = GetRequestData(api, data);
var postData = JsonConvert.SerializeObject(data);
var http = new HttpHelper();
var httpItem = new HttpItem()
{
URL = $"https://vop.vipapis.com/?{query}",
Method = "POST",
Timeout = 5000,
ReadWriteTimeout = 5000,
Accept = "text/html, application/xhtml+xml, */*",
ContentType = "application/json;",
Postdata = postData,
};
var result = http.GetHtml(httpItem);
if (result.StatusCode == HttpStatusCode.OK)
{
html = result.Html;
if (!string.IsNullOrWhiteSpace(html))
{
var jObj = JObject.Parse(html);
var resultCode = jObj["returnCode"]?.ToString();
if (resultCode == "0")
{
T t = JsonConvert.DeserializeObject<T>(html);
return t;
}
else
{
//请求太快了
if (resultCode == "1008")
{
Thread.Sleep(5000);
continue;
}
}
}
}
throw new Exception(html);
}
catch (Exception ex)
{
LogHelper.GetSingleObj().Error("", $@"唯品会请求异常A.,{Member.usernick}({Member.username}),登录时间:{Member.logintime.ToString("yyyy-MM-dd HH:mm:ss")}
{api}
{html}
{ex.Message} - {ex.StackTrace}");
//token失效的错误数据
//{"returnCode":"vipapis.oauth-invalidate-failure","returnMessage":"oauth-error-code[30111]description[access token invalid]"}
if (ex.Message.Contains("invalid") || html.Contains("invalid") || html.Contains("token") || html.ToLower().Contains("does not exist"))
{
//没有刷新过token
if (isRefToken == false)
{
isRefToken = true;
if (RefToken())
continue;
}
EventClient.OnEvent(this, $@"【唯品会】 => 请求异常1{this.Member.usernick}({this.Member.username}),注:请重新登录唯品会!!!");
Member.is_valid = false;
return default(T);
}
Thread.Sleep(500);
}
}
return default(T);
}
#endregion
/// <summary>
/// 唯品会下载订单
/// </summary>
/// <param name="_startTime">开始时间</param>
/// <param name="_endTime">结束时间</param>
/// <param name="page_index">第几页</param>
/// <param name="page_size">每页数量</param>
/// <returns></returns>
internal OrderResponseResult DownOrder(DateTime _startTime, DateTime _endTime, int page_index, int page_size)
{
if (!Member.is_valid)
{
//Api.Framework.Utils.LogHelper.GetSingleObj().Error("唯品会订单下载异常.过期?", $"需要重新登录,{this.Member.usernick}({this.Member.username})");
throw new Exception("vipapis.oauth-invalidate-failure");
}
var startTime = Util.GetTimeSpan(_startTime, true); //每小时同步订单
var endTime = Util.GetTimeSpan(_endTime, true); //每小时同步订单
//time = "2019042216";
//TODO 订单下载接口
var result = this.SendWeipinhui<OrderResponseResult>("com.vip.adp.api.open.service.UnionOrderService-1.0.0#orderListWithOauth", new
{
queryModel = new
{
//status = key,//订单状态:0-不合格1-待定2-已完结,该参数不设置默认代表全部状态
//orderTimeStart = page_index,//订单时间起始 时间戳 单位毫秒
//orderTimeEnd = page_size,//订单时间结束 时间戳 单位毫秒
page = page_index,//页码从1开始
pageSize = page_size,//页面大小默认20
requestId = Util.GetUUID(),//请求id调用方自行定义用于追踪请求单次请求唯一建议使用UUID
updateTimeStart = startTime,//更新时间-起始 时间戳 单位毫秒
updateTimeEnd = endTime,//更新时间-结束 时间戳 单位毫秒
//orderSnList = ,//订单号列表:当传入订单号列表时,订单时间和更新时间区间可不传入
//vendorCode = ,//vendorCode,工具商方式下会传入
//chanTag = ,//渠道标识即推广位PID
}
});
//if (_rst == null || _rst.result == null || _rst.returnCode == null || _rst.returnCode != "0")
// throw new Exception(JsonConvert.SerializeObject(_rst));
return result;
}
#endregion
#region Sign计算
/// <summary>
/// 计算签名,返回请求阿里妈妈服务器的参数
/// </summary>
/// <param name="api">api</param>
/// <param name="data">参数</param>
/// <returns></returns>
private string GetRequestData(string api, object data)
{
//try
//{
var reg = Regex.Match(api, "(?<service>.+?)-(?<version>.+?)#(?<method>.+)");
if (!reg.Success) throw new Exception($"无法识别“{api}”API请求");
var param = new Dictionary<string, string>();
if (Token == null)
{
throw new Exception("invalid ..");
}
param["accessToken"] = Token.access_token;
param["appKey"] = "9f7a9b3d";//Token.appid;
param["format"] = "JSON";
param["language"] = "zh";
param["method"] = reg.Groups["method"].Value;
param["service"] = reg.Groups["service"].Value;
param["version"] = reg.Groups["version"].Value;
param["timestamp"] = Util.GetTimeSpan(DateTime.Now, false).ToString();
//计算签名
string sign = GetSign(param, "074B0E1FFB94334FDEC993913884EC7F"/*Token.appkey*/, data);
param["sign"] = sign;
return HttpExtend.BuildQuery(param);
//}
//catch (Exception ex)
//{
//}
return string.Empty;
}
/// <summary>
/// 计算sign
/// </summary>
/// <param name="parameters">计算的参数</param>
/// <param name="secret">appkey</param>
/// <param name="bizParam">请求的参数</param>
/// <returns></returns>
private string GetSign(Dictionary<string, string> parameters, string secret, object bizParam = null)
{
// 第一步把字典按Key的字母顺序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters, StringComparer.Ordinal);
//// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
foreach (KeyValuePair<string, string> kv in sortedParams)
{
if (!string.IsNullOrEmpty(kv.Key) && !string.IsNullOrEmpty(kv.Value))
query.Append(kv.Key).Append(kv.Value);
}
// 第三步:把请求主体拼接在参数后面
var boby = string.Empty;
if (bizParam != null)
boby = JsonConvert.SerializeObject(bizParam);
if (!string.IsNullOrEmpty(boby))
{
query.Append(boby);
}
var sss = query.ToString();
// 第四步: 使用HMAC加密
HMACMD5 hmac = new HMACMD5(Encoding.UTF8.GetBytes(secret));
var bytes = hmac.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
/// <summary>
/// 获取唯品会推广位
/// </summary>
/// <param name="api">WeipinhuiApi对象</param>
/// <param name="page">第几页</param>
/// <param name="pageSize">每页的数量</param>
/// <returns></returns>
public static QueryPid GetWphTgw(WeipinhuiApi api, int page = 1, int pageSize = 20)
{
var res = api.SendWeipinhui<QueryPids>("com.vip.adp.api.open.service.UnionPidService-1.0.0#queryPidWithOauth", new { pidQueryRequest = new { requestId = Util.GetUUID(), page = page, pageSize = pageSize } });
if (res != null && res.returnCode == "0")
{
return res.result;
}
return null;
}
///// <summary>
///// 获取唯品会推广位
///// </summary>
///// <param name="api">WeipinhuiApi对象</param>
///// <param name="page">第几页</param>
///// <param name="pageSize">每页的数量</param>
///// <returns></returns>
//public static ArrayList GetWphTgw(WeipinhuiApi api, out int total, int page = 1, int pageSize = 20)
//{
// total = 0;
// var res = api.SendWeipinhui("com.vip.adp.api.open.service.UnionPidService-1.0.0#queryPidWithOauth", new { pidQueryRequest = new { requestId = Util.GetUUID(), page = page, pageSize = pageSize } });
// if (res.ContainsKey("returnCode") && res["returnCode"].ToString() == "0")
// {
// res = res["result"] as Dictionary<string, object>;
// total = int.Parse(res["total"].ToString());
// return res["pidInfoList"] as ArrayList;
// }
// return null;
//}
/// <summary>
/// 创建推广位
/// </summary>
/// <param name="api">WeipinhuiApi对象</param>
/// <param name="pidList">要创建的推广位名称</param>
public static void CreateWphTgw(WeipinhuiApi api, List<string> pidList = null)
{
if (pidList == null)
pidList = new List<string>() { "WphDefault" };
api.SendWeipinhui<object>("com.vip.adp.api.open.service.UnionPidService-1.0.0#genPidWithOauth", new { pidGenRequest = new { requestId = Util.GetUUID(), pidNameList = pidList } });
}
}
}