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(""", "\""); } } }