using MAX.Core.DependencyInjection;
using MAX.Core.Helpers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Store.Client.Apis;
using Store.Framework.Apis;
using Store.Framework.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
namespace Store.Client.Services
{
///
/// 商铺管理服务
///
public class ShopManager : ITransientDependency
{
private const int DefaultPageSize = 100;
private const int MaxPageCount = 10000;
private readonly ShopApi _shopApi;
public ShopManager(ShopApi shopApi)
{
_shopApi = shopApi ?? throw new ArgumentNullException(nameof(shopApi));
}
///
/// 获取当前用户的所有商铺。
///
/// 每页数量。
/// 商铺列表。
public List GetShops(int pageSize = DefaultPageSize)
{
return GetShops(false, pageSize);
}
///
/// 获取商铺列表。
///
/// 是否调用管理端接口。
/// 每页数量。
/// 商铺列表。
public List GetShops(bool isAdmin, int pageSize = DefaultPageSize)
{
List shops = new List();
if (pageSize <= 0)
pageSize = DefaultPageSize;
int page = 0;
while (page < MaxPageCount)
{
page++;
string postdata = "page=" + page + "&page_size=" + pageSize;
HttpResult result = isAdmin
? _shopApi.AdminGetShopList(postdata)
: _shopApi.GetShopList(postdata);
ApiResponse> response = DeserializeShopResponse(result);
if (response == null || response.Code != 200 || response.Data == null)
break;
if (response.Data.Count == 0)
break;
shops.AddRange(response.Data);
if (response.Data.Count < pageSize)
break;
}
return shops;
}
///
/// 获取服务端商铺列表,兼容旧调用。
///
public List GetServerShop()
{
return GetShops();
}
///
/// 从服务端刷新商铺 Cookie。
///
/// 待刷新商铺。
/// 服务端原始响应。
public string GetShopCookie(List shops)
{
if (shops == null || shops.Count == 0)
return string.Empty;
string shopJson = JsonConvert.SerializeObject(shops);
string postdata = "shops=" + Uri.EscapeDataString(shopJson);
HttpResult result = _shopApi.GetPddShopCookiesList(postdata);
if (result == null || result.StatusCode != HttpStatusCode.OK || string.IsNullOrEmpty(result.Html))
return string.Empty;
MatchCollection matches = Regex.Matches(
result.Html,
@"[^""]*?)""[^>]*)>(?[\w\W]*?)",
RegexOptions.IgnoreCase);
foreach (Match match in matches)
{
string key = match.Groups["key"].Value;
Shop shop = shops.FirstOrDefault(s => s.Id == key || s.Name == key);
if (shop == null)
continue;
string cookie = ParseCookie(match.Groups["json"].Value);
if (cookie != null)
shop.Cookie = new Cookies(DecodeCookie(cookie));
}
return result.Html;
}
///
/// 检测商铺登录状态。
///
/// 商铺。
public void CheckShopStatus(Shop shop)
{
if (shop == null)
throw new ArgumentNullException(nameof(shop));
if (shop.Cookie == null)
{
shop.Msg = "Cookie为空";
return;
}
HttpItem item = new HttpItem
{
URL = "https://myseller.taobao.com/ajaxProxy.do?_ksTS=1548152154745_13&callback=seller_layout_head&action=FrameworkLayoutAction&event_submit_do_layout_data=true",
Referer = "https://myseller.taobao.com",
Method = MethodType.Post,
Cookie = shop.Cookie.GetCookieString()
};
HttpResult result = HttpHelper.Request(item);
shop.Msg = result != null
&& result.StatusCode == HttpStatusCode.OK
&& !string.IsNullOrEmpty(result.Html)
&& result.Html.Contains("\"shopName\":\"")
? "登录成功"
: "会话已过期";
}
///
/// 删除服务端商铺。
///
/// 店铺登录名。
/// 服务端原始响应。
public string DeleteShop(string loginName)
{
if (string.IsNullOrWhiteSpace(loginName))
throw new ArgumentException("店铺登录名不能为空。", nameof(loginName));
HttpResult result = _shopApi.DelShop("login_name=" + Uri.EscapeDataString(loginName));
return result?.Html ?? string.Empty;
}
///
/// 删除服务端店铺,兼容旧方法命名。
///
public string DelServerDouShop(string shopId)
{
return DeleteShop(shopId);
}
private static ApiResponse> DeserializeShopResponse(HttpResult result)
{
if (result == null || result.StatusCode != HttpStatusCode.OK || string.IsNullOrWhiteSpace(result.Html))
return null;
try
{
return JsonConvert.DeserializeObject>>(result.Html);
}
catch (JsonException)
{
return null;
}
}
private static string ParseCookie(string json)
{
if (string.IsNullOrWhiteSpace(json))
return null;
try
{
JObject root = JObject.Parse(json);
return GetString(root, "Cookies") ?? GetString(root, "cookie") ?? GetString(root, "Cookie");
}
catch (JsonException)
{
return null;
}
}
private static string GetString(JObject source, string propertyName)
{
JToken token = source?[propertyName];
return token == null || token.Type == JTokenType.Null
? null
: token.ToString();
}
private static string DecodeCookie(string cookie)
{
return (cookie ?? string.Empty)
.Replace("&", "&")
.Replace("%", "%")
.Replace("+", "+")
.Replace(""", "\"");
}
}
}