2022-09-20 03:10:29 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Security.Cryptography;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Api.Framework.EntityTmp.KuaiShou;
|
|
|
|
|
using Api.Framework.Model;
|
|
|
|
|
using Api.Framework.Utils;
|
|
|
|
|
using CsharpHttpHelper;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
|
|
|
|
|
namespace Api.Framework.Cps
|
|
|
|
|
{
|
|
|
|
|
public class KuaiShouApi : BaseCpsApi
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
internal KuaiShouApi(fl_cps_member member) : base(member) { }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 请求快手Api
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="api">api接口</param>
|
|
|
|
|
/// <param name="data">请求参数</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public T SendData<T>(string api, object data)
|
|
|
|
|
{
|
|
|
|
|
var jObj = SendServer(api, data);
|
|
|
|
|
if (jObj != null)
|
|
|
|
|
return jObj.ToObject<T>();
|
|
|
|
|
return default(T);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 请求快手Api
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="api">api接口</param>
|
|
|
|
|
/// <param name="data">请求参数</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public JToken SendData(string api, object data)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var jObj = SendServer(api, data);
|
|
|
|
|
return jObj;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 请求
|
2022-10-31 16:18:32 +00:00
|
|
|
|
//private string AppKey = "ks679199118973905155";
|
|
|
|
|
////private string Token = "ChFvYXV0aC5hY2Nlc3NUb2tlbhJAq13iHqm2rYA2FPaq_m0RU87-oshvTLzbFJXSnJMC0znK7kwq29tUnRKVow6LFrdSZ8mTRmrQvIWQxVL0FKTqCBoSbRuEMdwtT-6YPlmXD2hUvaWiIiBf7afrOrF3qxUPgNXpAg_nT6OrwDx27hZpMeG8P7OimigFMAE";
|
|
|
|
|
//private string SignSecret = "910631f39a61e70f0b2c85a97ad4477e";
|
|
|
|
|
private string SignSecret = "71cc2e4896d2d035a1b9e556438cf746";
|
2022-09-20 03:10:29 +00:00
|
|
|
|
|
|
|
|
|
private JToken SendServer(string api, object data)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var param = GetRequestData(api, data, out string postParam);
|
|
|
|
|
|
|
|
|
|
var url = $"https://openapi.kwaixiaodian.com/{(api.Replace(".", "/"))}?{param}";
|
|
|
|
|
|
|
|
|
|
HttpHelper http = new HttpHelper();
|
|
|
|
|
HttpItem item = new HttpItem()
|
|
|
|
|
{
|
|
|
|
|
URL = url,//URL 必需项
|
|
|
|
|
Method = "get",//URL 可选项 默认为Get
|
|
|
|
|
Timeout = 10000,//连接超时时间 可选项默认为100000
|
|
|
|
|
ReadWriteTimeout = 5000,//写入Post数据超时时间
|
|
|
|
|
Accept = "text/html, application/xhtml+xml, */*",// 可选项有默认值
|
|
|
|
|
ContentType = "application/x-www-form-urlencoded",//返回类型 可选项有默认值
|
|
|
|
|
};
|
|
|
|
|
var result = http.GetHtml(item);
|
|
|
|
|
//{"tbk_dg_vegas_tlj_create_response":{"result":{"model":{"rights_id":"XvLXNwkX8HBQ8VZ2WS4DlNtN7m9cS4TU","send_url":"https:\/\/uland.taobao.com\/taolijin\/edetail?eh=5L6pfx5vldOZuQF0XRz0iAXoB%2BDaBK5LQS0Flu%2FfbSp4QsdWMikAalrisGmre1Id0BFAqRODu1004PvI5lqUzYTPq7zN5TtBXU4J7X2wljh7PW2ShemY2x1IRRpXndAncj8tXpgtxXzbOKxKSviYxsuv0da8KKt7WubOUkoI2Oa3HR2hP0JFSmjppH3xlrrJg8pBHJnzzOjd2vZvO6fEydXbwx4naJ6dk%2FBu2lJxZtMc7BMk%2FDH7wY2fDQKPuN9qcxwaWpDoQwfi%2B9ZUBfurmaewy3GJqMoK4342DlvX1ZVNOJlvqrE2h6J7%2BkHL3AEW&union_lens=lensId%3A0b14fbf4_0b3d_16f65a622fd_31b4%3Btraffic_flag%3Dlm","vegas_code":"N4HHV6HV"},"success":true},"request_id":"no8k8bbwsct2"}}
|
|
|
|
|
var html = result.Html;
|
|
|
|
|
|
|
|
|
|
LogHelper.GetSingleObj().Debug("", $"快手Api请求:{api} => {JsonConvert.SerializeObject(data)} => 结果:" + html);
|
|
|
|
|
//Console.WriteLine($"快手请求: {html}");
|
|
|
|
|
//Console.WriteLine();
|
|
|
|
|
|
|
|
|
|
//{"result":28,"code":"803000","msg":"鉴权失败","error_msg":"invalid access_token","sub_code":"28","sub_msg":"invalid access_token","request_id":"653573599408509148"}
|
|
|
|
|
//{"result":1017,"code":"802000","msg":"流量限制","error_msg":"[1017] exceed quota limit","sub_code":"802006","sub_msg":"APP已达到当天调用额度限制,请申请额度,[appkey:ks679199118973905155;primaryUserId:2871240599]","request_id":"653817732085832693"}
|
|
|
|
|
var jObj = JObject.Parse(html);
|
|
|
|
|
if (jObj["code"].ToString() == "803000" || jObj["sub_code"].ToString() == "28")
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
base.RefToken();
|
|
|
|
|
LogHelper.GetSingleObj().Error("", $"快手Api请求异常:{api} => {JsonConvert.SerializeObject(data)} => 结果:" + html);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (jObj["code"].ToString() == "802000" || jObj["sub_code"].ToString() == "802006")
|
|
|
|
|
{
|
|
|
|
|
LogHelper.GetSingleObj().Error("", $"快手Api请求异常:{api} => {JsonConvert.SerializeObject(data)} => 结果:" + html);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return jObj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
//if (result != null && result.StatusCode != System.Net.HttpStatusCode.OK)
|
|
|
|
|
// throw new Exception(html);
|
|
|
|
|
|
|
|
|
|
//var jToken = JObject.Parse(html);
|
|
|
|
|
//return jToken;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GetRequestData(string api, object data, out string postParam)
|
|
|
|
|
{
|
|
|
|
|
Dictionary<string, string> param = new Dictionary<string, string>();
|
|
|
|
|
|
2022-10-31 16:18:32 +00:00
|
|
|
|
//param["appkey"] = AppKey;
|
|
|
|
|
param["appkey"] = Token.appid;
|
2022-09-20 03:10:29 +00:00
|
|
|
|
param["version"] = "1";
|
|
|
|
|
param["method"] = api;
|
|
|
|
|
//param["signMethod"] = "HMAC_SHA256";
|
|
|
|
|
param["signMethod"] = "MD5";
|
|
|
|
|
param["access_token"] = base.Token.access_token;
|
|
|
|
|
param["timestamp"] = GetTimeStamp().ToString();
|
|
|
|
|
postParam = param["param"] = JsonConvert.SerializeObject(data);
|
|
|
|
|
|
|
|
|
|
//计算签名
|
|
|
|
|
string sign = SignTopRequest(param);
|
|
|
|
|
param["sign"] = sign;
|
|
|
|
|
|
|
|
|
|
return BuildQuery(param);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 同步订单
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="star"></param>
|
|
|
|
|
/// <param name="end"></param>
|
|
|
|
|
/// <param name="pcursor"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
internal void DownOrder(DateTime beginTime, DateTime endTime, Action<KS_OrderInfo, string, string> action, string pcursor = "")
|
|
|
|
|
{
|
|
|
|
|
var begin = HttpExtend.GetTimeStamp(beginTime, true);
|
|
|
|
|
var end = HttpExtend.GetTimeStamp(endTime, true);
|
|
|
|
|
var jObj = SendData("open.distribution.cps.kwaimoney.order.list", new { cpsOrderStatus = 0, pageSize = 100, sortType = 1, queryType = 2, beginTime = begin, endTime = end, pcursor = pcursor });
|
|
|
|
|
|
|
|
|
|
var data = jObj["data"];
|
|
|
|
|
if (data != null)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var result = data.ToObject<KS_OrderInfo>();
|
|
|
|
|
if (result != null)
|
|
|
|
|
{
|
|
|
|
|
action(result, this.Member.username, this.Member.usernick);
|
|
|
|
|
|
|
|
|
|
if (result.pcursor != "nomore")//继续请求
|
|
|
|
|
{
|
|
|
|
|
DownOrder(beginTime, endTime, action, result.pcursor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
//Console.WriteLine(ex);
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string BuildQuery(IDictionary<string, string> parameters)
|
|
|
|
|
{
|
|
|
|
|
if (parameters == null || parameters.Count == 0)
|
|
|
|
|
return (string)null;
|
|
|
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
|
bool flag = false;
|
|
|
|
|
foreach (KeyValuePair<string, string> parameter in (IEnumerable<KeyValuePair<string, string>>)parameters)
|
|
|
|
|
{
|
|
|
|
|
string key = parameter.Key;
|
|
|
|
|
string str = parameter.Value;
|
|
|
|
|
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(str))
|
|
|
|
|
{
|
|
|
|
|
if (flag)
|
|
|
|
|
stringBuilder.Append("&");
|
|
|
|
|
stringBuilder.Append(key);
|
|
|
|
|
stringBuilder.Append("=");
|
|
|
|
|
stringBuilder.Append(HttpExtend.UrlEncode(str));
|
|
|
|
|
flag = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return stringBuilder.ToString().Replace("%2c", "%2C").Replace("%3a", "%3A");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string SignTopRequest(Dictionary<string, string> parameters)
|
|
|
|
|
{
|
|
|
|
|
// 第一步:把字典按Key的字母顺序排序
|
|
|
|
|
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters, StringComparer.Ordinal);
|
|
|
|
|
|
|
|
|
|
// 第二步:把所有参数名和参数值串在一起
|
|
|
|
|
List<string> list = new List<string>();
|
|
|
|
|
|
|
|
|
|
parameters.Clear();
|
|
|
|
|
|
|
|
|
|
foreach (KeyValuePair<string, string> kv in sortedParams)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(kv.Key) && !string.IsNullOrEmpty(kv.Value))
|
|
|
|
|
{
|
|
|
|
|
list.Add($"{kv.Key}={kv.Value}");
|
|
|
|
|
parameters[kv.Key] = kv.Value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//parameters = sortedParams as Dictionary<string, string>;
|
|
|
|
|
|
|
|
|
|
list.Add($"signSecret={SignSecret}");
|
|
|
|
|
|
|
|
|
|
var query = string.Join("&", list);
|
|
|
|
|
|
|
|
|
|
//// 第三步:使用HMACSHA256加密
|
|
|
|
|
//var h = new HMACSHA256(Encoding.UTF8.GetBytes(SignSecret));
|
|
|
|
|
//var bytes = h.ComputeHash(Encoding.UTF8.GetBytes(query));
|
|
|
|
|
|
|
|
|
|
MD5 md5 = MD5.Create();
|
|
|
|
|
var bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query));
|
|
|
|
|
|
|
|
|
|
// 第五步:把二进制转化为大写的十六进制
|
|
|
|
|
StringBuilder result = new StringBuilder();
|
|
|
|
|
for (int i = 0; i < bytes.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
result.Append(bytes[i].ToString("x2"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private long GetTimeStamp(bool Seconds = false)
|
|
|
|
|
{
|
|
|
|
|
TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
|
|
|
|
if (Seconds) return Convert.ToInt64(ts.TotalSeconds);
|
|
|
|
|
else return Convert.ToInt64(ts.TotalMilliseconds);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 创建推广位
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">推广位名称</param>
|
|
|
|
|
public void CreateMedia(string name)
|
|
|
|
|
{
|
|
|
|
|
SendData("open.distribution.cps.kwaimoney.pid.create", new { promotionBitName = name });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取推广位列表
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="page"></param>
|
|
|
|
|
/// <param name="pageSize"></param>
|
|
|
|
|
/// <param name="total"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public List<KS_TuiGuangWeiInfo> GetMedias(int page, int pageSize, out int total)
|
|
|
|
|
{
|
|
|
|
|
List<KS_TuiGuangWeiInfo> list = null;
|
|
|
|
|
total = 0;
|
|
|
|
|
|
|
|
|
|
var jToken = SendData("open.distribution.cps.kwaimoney.pid.list", new { page = page, pageSize = pageSize });
|
|
|
|
|
|
|
|
|
|
if (jToken != null)
|
|
|
|
|
{
|
|
|
|
|
var cpsPidData = jToken["data"]?["cpsPidData"]?.ToArray();
|
|
|
|
|
if (cpsPidData != null)
|
|
|
|
|
{
|
|
|
|
|
list = new List<KS_TuiGuangWeiInfo>();
|
|
|
|
|
foreach (var item in cpsPidData)
|
|
|
|
|
{
|
|
|
|
|
list.Add(item.ToObject<KS_TuiGuangWeiInfo>());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////{{"result":1,"msg":"success","error_msg":"SUCCESS","code":"1","data":{"cpsPidData":[{"cpsPid":"ks_2871240599_102_DfSm3SDi4fQ","createTime":1653447708399,"promotionBitName":"测试一下","status":1},{"cpsPid":"ks_2871240599_102_ENyeXrpQo0Y","createTime":1653447514432,"promotionBitName":"111","status":1}],"total":2},"requestId":"653449659999263660","sub_msg":"SUCCESS","sub_code":"1"}}
|
|
|
|
|
total = jToken["data"]["total"].Value<int>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 转链
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="linkCarrierId">携带id(达人快手id或商品id)</param>
|
|
|
|
|
/// <param name="pid">快赚客推广位cps pid</param>
|
|
|
|
|
/// <param name="comments">备注(透传字段,拉取订单接口返回)</param>
|
|
|
|
|
/// <param name="customContent">自定义文案</param>
|
|
|
|
|
public KS_TurnUrlInfo TurnUrl(string linkCarrierId, string pid, string comments, string customContent = "")
|
|
|
|
|
{
|
|
|
|
|
var jToken = SendData("open.distribution.cps.kwaimoney.link.create",
|
|
|
|
|
new
|
|
|
|
|
{
|
|
|
|
|
linkType = 101,
|
|
|
|
|
linkCarrierId = linkCarrierId,
|
|
|
|
|
comments = comments,
|
|
|
|
|
cpsPid = pid,
|
|
|
|
|
customContent = customContent
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (jToken["data"] != null)
|
|
|
|
|
{
|
|
|
|
|
var result = jToken["data"]?.ToObject<KS_TurnUrlInfo>();
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加商品到货架
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="itemId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool AddShopWindow(long itemId)
|
|
|
|
|
{
|
|
|
|
|
var jToken = SendData("open.distribution.selection.pick", new { itemIds = new List<long>() { itemId } });
|
|
|
|
|
|
|
|
|
|
if (jToken["data"]?["result"].Value<int>() == 1)
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取商品信息
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="itemId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public KS_ItemInfo GetItemInfo(string itemId)
|
|
|
|
|
{
|
|
|
|
|
var jToken = SendData("open.distribution.cps.kwaimoney.selection.item.detail", new { itemId = new List<long>() { long.Parse(itemId) } });
|
|
|
|
|
|
|
|
|
|
var jArr = jToken?["data"]?.ToArray();
|
|
|
|
|
if (jArr != null && jArr.Length != 0)
|
|
|
|
|
{
|
|
|
|
|
var result = jArr[0].ToObject<KS_ItemInfo>();
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|