416 lines
17 KiB
C#
416 lines
17 KiB
C#
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using Api.Framework.EntityTmp.SuNing;
|
|||
|
using Api.Framework.EntityTmp.SuNing1;
|
|||
|
using Api.Framework.EntityTmp.SuNing2;
|
|||
|
using Api.Framework.EntityTmp.SuNing3;
|
|||
|
using Api.Framework.EntityTmp.SuNing4;
|
|||
|
using Api.Framework.Model;
|
|||
|
using Api.Framework.Utils;
|
|||
|
using CsharpHttpHelper;
|
|||
|
using CsharpHttpHelper.Enum;
|
|||
|
using Newtonsoft.Json;
|
|||
|
using Newtonsoft.Json.Linq;
|
|||
|
|
|||
|
namespace Api.Framework.Cps
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 苏宁操作Api
|
|||
|
/// </summary>
|
|||
|
public class SuNingApi : BaseCpsApi
|
|||
|
{
|
|||
|
private string cookice = string.Empty;
|
|||
|
|
|||
|
internal SuNingApi(fl_cps_member member) : base(member)
|
|||
|
{
|
|||
|
cookice = member.cookies;
|
|||
|
}
|
|||
|
|
|||
|
private const string ChannelID = "15824";
|
|||
|
|
|||
|
#region 获取Appkey
|
|||
|
private static string[] KeyInfo = null;
|
|||
|
private static DateTime UpdateKeyTime = DateTime.MinValue;
|
|||
|
private string[] GetKeySecret()
|
|||
|
{
|
|||
|
if (UpdateKeyTime.AddDays(1) < DateTime.Now)
|
|||
|
KeyInfo = null;
|
|||
|
if (KeyInfo == null)
|
|||
|
{
|
|||
|
for (int i = 0; i < 3; i++)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
var data = this.SendServer("find_wangzhi", "webTool.asmx", new { name = "苏宁APPKEY" }).message.ToString();
|
|||
|
if (!string.IsNullOrWhiteSpace(data))
|
|||
|
{
|
|||
|
//data = a683d87c23dc4e6d01020cd8fa356456_a76798b7230b886627f6e6090d3b4e48
|
|||
|
//data = "75b46e8fb0a3a10a534282a684c92a09_532d037c25612475fd68e09eddb873fa";
|
|||
|
KeyInfo = data.Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries);
|
|||
|
break;
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
catch (Exception)
|
|||
|
{
|
|||
|
KeyInfo = null;
|
|||
|
Thread.Sleep(500);
|
|||
|
}
|
|||
|
}
|
|||
|
UpdateKeyTime = DateTime.Now;
|
|||
|
}
|
|||
|
return KeyInfo;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
|
|||
|
#region 获取所有推广位
|
|||
|
List<SN_TuiGuangWeiInfo> TgwList = null;
|
|||
|
|
|||
|
public List<SN_TuiGuangWeiInfo> GetTuiguagnwei(bool flush = false)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
if (flush || TgwList == null)
|
|||
|
{
|
|||
|
TgwList = RequestTuiguagnwei(1);
|
|||
|
}
|
|||
|
return TgwList;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
throw ex;
|
|||
|
}
|
|||
|
return new List<SN_TuiGuangWeiInfo>();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 请求苏宁获取聊天推广位
|
|||
|
/// </summary>
|
|||
|
/// <param name="pageNumber"></param>
|
|||
|
/// <param name="countNumber"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private List<SN_TuiGuangWeiInfo> RequestTuiguagnwei(int pageNumber, int countNumber = -1)
|
|||
|
{
|
|||
|
var list = new List<SN_TuiGuangWeiInfo>();
|
|||
|
try
|
|||
|
{
|
|||
|
HttpHelper http = new HttpHelper();
|
|||
|
HttpItem item = new HttpItem()
|
|||
|
{
|
|||
|
URL = "http://sums.suning.com/union/member/myPromotion/promotionPosition/list.htm",
|
|||
|
Method = "POST",
|
|||
|
Timeout = 100000,
|
|||
|
ReadWriteTimeout = 30000,
|
|||
|
IsToLower = false,
|
|||
|
Cookie = cookice,
|
|||
|
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 = "http://sums.suning.com/union/member/myPromotion/promotionPosition/list.htm",
|
|||
|
Allowautoredirect = false,
|
|||
|
AutoRedirectCookie = false,
|
|||
|
Postdata = "promotionSubjection=3&siteId_val=&siteId=&pageNumber=" + pageNumber,
|
|||
|
ResultType = ResultType.String
|
|||
|
};
|
|||
|
HttpResult result = http.GetHtml(item);
|
|||
|
string html = result.Html;
|
|||
|
if (!string.IsNullOrWhiteSpace(html))
|
|||
|
{
|
|||
|
html = Regex.Replace(html, @"\s", "", RegexOptions.IgnoreCase);
|
|||
|
|
|||
|
var regs = Regex.Matches(html, @"<tr><tdclass="".+?""width="".+?%""style=""word-wrap:break-word;""><span>(?<推广位名称>.+?)</span></td><td><span>(?<pid>\d+)</span></td><tdwidth="".+?%""style=""word-wrap:break-word;""><span>.+?</span></td><td><span>.+?</span></td><td><span>.+?</span></td><td><span>.+?</span></td><td><span>.+?</span></td><td><pclass=""p-do""><aclass=""pointericon-ctn""onclick=""queryData\('\d+','\d+'\)""><iclass=""sn-iconicon-viewsn-icon-tips""><em><b>查看报表</b></em></i></a><aclass=""pointericon-ctn""onclick=""deleteById\(\d+\)""><iclass=""sn-iconicon-delsn-icon-tips""><em><b>删除</b></em></i></a></p></td></tr>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
|||
|
foreach (Match reg in regs)
|
|||
|
{
|
|||
|
list.Add(new SN_TuiGuangWeiInfo() { adzonename = reg.Groups["推广位名称"].Value, adzonepid = reg.Groups["pid"].ToString() });
|
|||
|
}
|
|||
|
|
|||
|
if (countNumber == -1)
|
|||
|
{
|
|||
|
var reg1 = Regex.Match(html, @"\(inputPageNumber-0\)<=\((?<页数>\d+)\)\)", RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
|||
|
if (reg1.Success)
|
|||
|
{
|
|||
|
countNumber = int.Parse(reg1.Groups["页数"].Value);
|
|||
|
}
|
|||
|
}
|
|||
|
if (countNumber > pageNumber)
|
|||
|
{
|
|||
|
pageNumber++;
|
|||
|
list.AddRange(RequestTuiguagnwei(pageNumber, countNumber));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
return list;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 创建工具商客户关系
|
|||
|
/// </summary>
|
|||
|
/// <param name="phone">苏宁的手机号</param>
|
|||
|
/// <returns></returns>
|
|||
|
public string CreateToolsRelation(string mediaCustNum)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
var result = SendSuNing<ToolsRelation>("suning.netalliance.toolseller.add", new { phone = "", channel = ChannelID, mediaCustNum = mediaCustNum });
|
|||
|
//{"sn_responseContent":{"sn_body":{"addToolseller":{"pid":"0c3cced96b03e0f0a06a","status":"1"}}}}
|
|||
|
if (result == null)
|
|||
|
throw new Exception("请求异常,请稍后重试!");
|
|||
|
var addToolseller = result.sn_responseContent.sn_body.addToolseller;
|
|||
|
if (addToolseller.status != "1")
|
|||
|
throw new Exception(addToolseller.errMsg);
|
|||
|
else
|
|||
|
return addToolseller.pid;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
throw ex;
|
|||
|
}
|
|||
|
return string.Empty;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 查询商品xixni
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public SN_GoodInfo QuerySearchCommodity(string mess)
|
|||
|
{
|
|||
|
var data = new
|
|||
|
{
|
|||
|
keyword = mess
|
|||
|
};
|
|||
|
|
|||
|
return SendSuNing<SN_GoodInfo>("suning.netalliance.searchcommodity.query", data);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 转链 二合一
|
|||
|
/// </summary>
|
|||
|
/// <param name="url">商品链接</param>
|
|||
|
/// <param name="quanUrl">优惠券链接</param>
|
|||
|
/// <returns></returns>
|
|||
|
public SN_QueryCommoditydetail GetExtensionUrl(string pid, string url, string quanUrl)
|
|||
|
{
|
|||
|
var data = new
|
|||
|
{
|
|||
|
productUrl = url,
|
|||
|
quanUrl = quanUrl,
|
|||
|
//promotionId = "",//这个推广只联盟前台申请的推广位,如果没有可以不填 这个不符合我们的需求
|
|||
|
subUser = pid,//这个是自定义字段,传pid以及拼接的绑定信息等
|
|||
|
pid = Member.usernick//这个指定订单归工具商还是客户 - 工具商绑定关系pid
|
|||
|
};
|
|||
|
return SendSuNing<SN_QueryCommoditydetail>("suning.netalliance.extensionlink.get", data);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 查询商品信息
|
|||
|
/// </summary>
|
|||
|
/// <param name="commodityStr">商品编码1-供应商编码1_商品编码2-供应商编码2... 商品编码取有效位,供应商编码左补零至10位 最大查询10个商品</param>
|
|||
|
/// <returns></returns>
|
|||
|
public SN_GoodInfo QueryGoodInfo(string commodityStr)
|
|||
|
{
|
|||
|
var data = new
|
|||
|
{
|
|||
|
commodityStr = commodityStr
|
|||
|
};
|
|||
|
|
|||
|
return SendSuNing<SN_GoodInfo>("suning.netalliance.commoditydetail.query", data);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 商品精选接口
|
|||
|
/// </summary>
|
|||
|
/// <param name="eliteId">默认为1,,营销id。1-小编推荐;2-实时热销榜;3-当日热推榜;4-高佣爆款榜;5-团长招商榜;6-9块9专区</param>
|
|||
|
/// <returns></returns>
|
|||
|
public SN_Recommend_Commodity QueryGuideGoodsInfo(CategoryType categoryType, int pageIndex = 1)
|
|||
|
{
|
|||
|
var data = new
|
|||
|
{
|
|||
|
eliteId = (int)categoryType,
|
|||
|
pageIndex = pageIndex,
|
|||
|
size = 40,
|
|||
|
};
|
|||
|
|
|||
|
return SendSuNing<SN_Recommend_Commodity>("suning.netalliance.selectrecommendcommodity.query", data);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 请求苏宁Api
|
|||
|
/// </summary>
|
|||
|
/// <param name="api">api接口</param>
|
|||
|
/// <param name="data">请求参数</param>
|
|||
|
/// <returns></returns>
|
|||
|
public T SendSuNing<T>(string api, object data)
|
|||
|
{
|
|||
|
var html = SendSuNingServer(api, data);
|
|||
|
|
|||
|
return JsonConvert.DeserializeObject<T>(html);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 请求苏宁Api
|
|||
|
/// </summary>
|
|||
|
/// <param name="api">api接口</param>
|
|||
|
/// <param name="data">请求参数</param>
|
|||
|
/// <returns></returns>
|
|||
|
public JToken SendSuNing(string api, object data)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
var html = SendSuNingServer(api, data);
|
|||
|
var jObj = JObject.Parse(html);
|
|||
|
if (jObj != null && jObj["sn_responseContent"] != null)
|
|||
|
{
|
|||
|
var sn_responseContent = jObj["sn_responseContent"];
|
|||
|
if (sn_responseContent != null && sn_responseContent["sn_body"] != null)
|
|||
|
{
|
|||
|
return sn_responseContent["sn_body"];
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
throw ex;
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
private string SendSuNingServer(string api, object data)
|
|||
|
{
|
|||
|
int number = 0;
|
|||
|
var html = string.Empty;
|
|||
|
Next:
|
|||
|
try
|
|||
|
{
|
|||
|
var appname = string.Empty;
|
|||
|
var apiSplic = api.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
|||
|
if (apiSplic.Length == 4)
|
|||
|
{
|
|||
|
var tmp = apiSplic[2].ToString();
|
|||
|
appname = apiSplic[3] + tmp.Substring(0, 1).ToUpper() + tmp.Substring(1);
|
|||
|
}
|
|||
|
var jsonData = @"{""sn_request"":{""sn_body"":{""" + appname + @""":" + JsonConvert.SerializeObject(data) + "}}}";
|
|||
|
|
|||
|
var keyInfo = GetKeySecret();
|
|||
|
//var jsonData = JsonConvert.SerializeObject(jsonStr);
|
|||
|
var base64Str = HttpExtend.StringToBase64String(jsonData);
|
|||
|
|
|||
|
var timeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|||
|
var versionNo = "v1.2";
|
|||
|
var sign = GetSign(api, timeStr, versionNo, base64Str);
|
|||
|
|
|||
|
var http = new HttpHelper();
|
|||
|
var _item = new HttpItem()
|
|||
|
{
|
|||
|
//URL = $"https://openpre.cnsuning.com/api/http/sopRequest/{api}",
|
|||
|
URL = $"https://open.suning.com/api/http/sopRequest/{api}",
|
|||
|
Method = "post",
|
|||
|
Timeout = 3000,
|
|||
|
ReadWriteTimeout = 3000,
|
|||
|
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",
|
|||
|
PostDataType = CsharpHttpHelper.Enum.PostDataType.Byte,
|
|||
|
PostdataByte = Encoding.UTF8.GetBytes(jsonData),
|
|||
|
Referer = ""
|
|||
|
};
|
|||
|
_item.Header["appMethod"] = api;
|
|||
|
_item.Header["appRequestTime"] = timeStr;
|
|||
|
_item.Header["appKey"] = keyInfo[0];
|
|||
|
_item.Header["versionNo"] = "v1.2";
|
|||
|
_item.Header["format"] = "json";
|
|||
|
_item.Header["signInfo"] = sign;
|
|||
|
|
|||
|
html = http.GetHtml(_item).Html;
|
|||
|
|
|||
|
if (html.Contains("操作超时") || html.Contains("服务端异常") || html.Contains("基础连接已经关闭") || html.Contains("请求被中止"))
|
|||
|
throw new Exception();
|
|||
|
|
|||
|
return html;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Thread.Sleep(200);
|
|||
|
if (number < 2 && html.Contains("操作超时") || html.Contains("服务端异常") || html.Contains("基础连接已经关闭") || html.Contains("请求被中止"))
|
|||
|
goto Next;
|
|||
|
else
|
|||
|
{
|
|||
|
EventClient.OnEvent(this, $"【苏宁易购】 => 请求异常1:{this.Member.usernick}({this.Member.username})");
|
|||
|
LogHelper.GetSingleObj().Error("", $@"【苏宁易购】 => 请求异常1:{this.Member.usernick}({this.Member.username})
|
|||
|
{api}
|
|||
|
{html}
|
|||
|
{ex.Message} - {ex.StackTrace}");
|
|||
|
}
|
|||
|
throw ex;
|
|||
|
}
|
|||
|
return string.Empty;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 下载订单,不带状态(有多页,获取所有)
|
|||
|
/// </summary>
|
|||
|
/// <param name="start_time">开始时间</param>
|
|||
|
/// <param name="_page_index">第几页</param>
|
|||
|
/// <param name="page_size">页大小</param>
|
|||
|
/// <param name="type">阿里妈妈同步的订单类型</param>
|
|||
|
/// <param name="order_scene">场景订单场景类型,1:常规订单,2:渠道订单,3:会员运营订单,默认为1</param>
|
|||
|
/// <returns></returns>
|
|||
|
internal SN_OrderInfo DownOrder(DateTime start_time, DateTime end_time, int page_index, int page_size)
|
|||
|
{
|
|||
|
SN_OrderInfo _rst = null;
|
|||
|
for (int i = 0; i < 2; i++)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
var data = new
|
|||
|
{
|
|||
|
pageNo = page_index,
|
|||
|
pageSize = page_size,
|
|||
|
startTime = start_time.ToString("yyyy-MM-dd HH:mm:ss"),
|
|||
|
endTime = end_time.ToString("yyyy-MM-dd HH:mm:ss"),
|
|||
|
orderLineStatus = 0,
|
|||
|
pid = Member.usernick//这个指定订单归工具商还是客户 - 工具商绑定关系pid
|
|||
|
};
|
|||
|
|
|||
|
_rst = SendSuNing<SN_OrderInfo>("suning.netalliance.order.query", data);
|
|||
|
if (_rst.sn_responseContent != null && _rst.sn_responseContent.sn_body != null && _rst.sn_responseContent.sn_body.queryOrder != null && _rst.sn_responseContent.sn_body.queryOrder.Count != 0)
|
|||
|
return _rst;
|
|||
|
else if (_rst.sn_responseContent != null && _rst.sn_responseContent.sn_error != null && _rst.sn_responseContent.sn_error.error_code.Contains("no-result"))//没有查到数据
|
|||
|
break;
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
throw ex;
|
|||
|
}
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 计算sign
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
private string GetSign(string api, string timeStr, string versionNo, string base64Str)
|
|||
|
{
|
|||
|
//按照顺序依次拼接appSecret的值(appKey对应的密钥)、appMethod的值,appRequestTime的值,appkey的值,versionNo的值和第一步编码后的值
|
|||
|
var data = $"{KeyInfo[1]}{api}{timeStr}{KeyInfo[0]}{versionNo}{base64Str}";
|
|||
|
|
|||
|
//md5 小写
|
|||
|
return HttpHelper.ToMD5(data).ToLower();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|