This commit is contained in:
chfei authored and chfei committed 2026-09-14 09:16:59 +08:00
1 parent c2dcedd238
commit 16cdd3d46e
34 files changed
+837 -481

No files matched your search

+5
View File
@@ -15,5 +15,10 @@ namespace Store.Client.Agent
/// 代理码
/// </summary>
public static string AgentCode { get; set; }
/// <summary>
/// 代理名称
/// </summary>
public static string AgentName { get; set; }
}
}
+4 -4
View File
@@ -21,7 +21,7 @@ namespace Store.Client.Apis
/// </summary>
public DateTime GetServerTime()
{
HttpResult result = ServerRequest(new ServerHttpItem { URL = $"{_config.Host}/time.php" });
HttpResult result = ServerRequest(new HttpItem { URL = $"{_config.Host}/time.php" });
if (result.StatusCode == HttpStatusCode.OK)
{
if (DateTime.TryParse(result.Html, out DateTime dt))
@@ -42,7 +42,7 @@ namespace Store.Client.Apis
/// </summary>
public string GetAuthConfig()
{
ServerHttpItem item = new ServerHttpItem();
HttpItem item = new HttpItem();
item.URL = $"{_config.Host}?obj=api/config&act=auth_config";
HttpResult result = ServerRequest(item);
if (result.StatusCode == HttpStatusCode.OK)
@@ -59,7 +59,7 @@ namespace Store.Client.Apis
public string GetCacheServerRatio()
{
ServerHttpItem item = new ServerHttpItem();
HttpItem item = new HttpItem();
item.URL = _config.Host + "?" + _config.ObjUrl + "config&act=cache_service_mode";
item.Method = MethodType.Post;
//item.SignUser();
@@ -80,7 +80,7 @@ namespace Store.Client.Apis
//public HttpResult GetImageCache(string imgUrl)
//{
// long id = MD5Helper.GetLong(imgUrl);
// ServerHttpItem item = new ServerHttpItem();
// HttpItem item = new HttpItem();
// item.Method = MethodType.Post;
// item.URL = _config.Host + "?" + _config.ObjUrl + "add_img";
// item.Postdata = "act=get&table=" + Math.Abs(id % 1024) + "&id=" + id;
+2 -5
View File
@@ -2,8 +2,6 @@
using MAX.Core.Extensions;
using MAX.Core.Helpers;
using Store.Client.Agent;
using Store.Client.Commons;
using Store.Client.Extensions;
using Store.Client.HttpExtension;
using Store.Framework;
using Store.Framework.Tools;
@@ -26,7 +24,7 @@ namespace Store.Client.Apis
{
_logger.Info("123");
int r2 = RandomHelper.GetRandomNumber(100000000, 899999999); //生成随机码
ServerHttpItem item = new ServerHttpItem();
HttpItem item = new HttpItem();
item.URL = base.BuildServiceUrl("user/user_login");
item.Method = MethodType.Post;
Dictionary<string, string> param = new Dictionary<string, string>
@@ -44,14 +42,13 @@ namespace Store.Client.Apis
//{ "client_addr", _client.Address }
};
item.Postdata = param.ToUrlParams();
item.Sign();
HttpResult result = ServerRequest(item);
if (result.StatusCode == HttpStatusCode.OK)
{
string chCode = Regex.Match(result.Html, "<c>([^<]+)</c>")?.Groups[1]?.Value ?? "";
if (!string.IsNullOrEmpty(chCode))
{
string codex = SignTool.Encryption(r2);
string codex = Encryption(r2);
if (chCode != codex)
{
result.StatusCode = HttpStatusCode.Unauthorized;
-46
View File
@@ -1,46 +0,0 @@
using MAX.Core.Infrastructure;
using Store.Framework.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Store.Framework
{
/// <summary>
/// 客户端信息
/// </summary>
public class ClientInfo : SingleInstance<ClientInfo>
{
public static UserInfo User
{
get
{
return Instance.UserInfo;
}
}
private ClientInfo()
{
}
/// <summary>
/// 客户端IP
/// </summary>
public string Ip { get; }
/// <summary>
/// 客户端地址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 获取当前登录用户
/// </summary>
public UserInfo UserInfo { get; private set; }
}
}
-70
View File
@@ -1,70 +0,0 @@
using MAX.Core.Cryptography;
using MAX.Core.Helpers;
using Store.Client;
using Store.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Store.Client.Commons
{
/// <summary>
/// 签名工具
/// </summary>
public class SignTool
{
/// <summary>
/// 获取签名
/// </summary>
/// <returns></returns>
public static string GetSign()
{
long time = GetReviseUnix();
string s = Encryption(time);
return "time=" + time + "&code=" + s + "&NbCodeVersion=1";
}
/// <summary>
/// 用户签名
/// </summary>
/// <returns></returns>
public static string GetUserSign()
{
return GetUserSign("", "");
}
/// <summary>
/// 获取当前用户签名
/// </summary>
/// <param name="shopId"></param>
/// <param name="shopName"></param>
/// <returns></returns>
public static string GetUserSign(string shopId, string shopName)
{
long time = GetReviseUnix();
string time1 = Encryption(time);
return "time=" + time + "&code=" + time1 + "&NbCodeVersion=1" + "&uid=" + ClientInfo.User.UserId + "&key=" + ClientInfo.User.UserKey +
"&cid=" + ClientInfo.User.CompanyId + "&company=" + UrlHelper.Encode(ClientInfo.User.CompanyName) +
"&sid=" + shopId + "&shop=" + UrlHelper.Encode(shopName);
}
/// <summary>
/// 获取校正后的时间戳
/// </summary>
/// <returns></returns>
public static long GetReviseUnix()
{
return DateHelper.GetCurrentUnixTimestampInSeconds() + ServerConfig.TimeDifferent;
}
/// <summary>
/// 签名算法
/// </summary>
/// <param name="s">随机数</param>
/// <returns>加密签名结果</returns>
public static string Encryption(long s)
{
string value = $"{s}sdhewu*/fhAAue48485ew5+5%@3485esGFFHFD";
return MD5Helper.Md5_32(value);
}
}
}
+5
View File
@@ -13,6 +13,11 @@ public static class Config
{
public const string AppVersion = "1312";
/// <summary>
/// API 项目路径。
/// </summary>
public const string MainPath = "29wx";
public static bool IsRelease
{
get
@@ -1,68 +0,0 @@
using MAX.Core.Helpers;
using Store.Client.Commons;
using Store.Client.HttpExtension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Store.Client.Extensions
{
/// <summary>
/// 请求扩展
/// </summary>
public static class HttpItemExtensions
{
/// <summary>
/// 增加签名
/// </summary>
/// <param name="item"></param>
public static void Sign(this ServerHttpItem item)
{
SetSign(item, SignTool.GetSign());
}
/// <summary>
/// 增加用户签名
/// </summary>
/// <param name="item"></param>
public static void SignUser(this ServerHttpItem item)
{
item.SignUser("", "");
}
/// <summary>
/// 增加用户签名
/// </summary>
/// <param name="item"></param>
/// <param name="shopId"></param>
/// <param name="shopName"></param>
public static void SignUser(this ServerHttpItem item, string shopId, string shopName)
{
SetSign(item, SignTool.GetUserSign(shopId, shopName));
}
private static void SetSign(ServerHttpItem item, string sign)
{
if (item.Method == MethodType.Get)
{
if (item.URL.Contains("?"))
{
item.URL += "&";
}
else
{
item.URL += "?";
}
item.URL += sign;
}
else
{
if (item.Postdata.Length > 0)
{
item.Postdata += "&";
}
item.Postdata += sign;
}
item.IsSign = true;
}
}
}
@@ -1,9 +1,15 @@
using MAX.Core.Autofac;
using MAX.Core.Autofac;
using MAX.Core.Cryptography;
using MAX.Core.DependencyInjection;
using MAX.Core.Helpers;
using MAX.Core.Logger;
using Store.Client.Extensions;
using Store.Client.Agent;
using Store.Framework;
using Store.Framework.Inerterfaces;
using Store.Framework.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
@@ -21,6 +27,7 @@ namespace Store.Client.HttpExtension
[Autowired]
protected ILoggerFacade _logger => LazyServiceProvider.Instance.LazyGetService<ILoggerFacade>();
protected IApiServerConfig _config => LazyServiceProvider.Instance.LazyGetService<IApiServerConfig>();
protected ICurrentUser CurrentUser => LazyServiceProvider.Instance.LazyGetService<ICurrentUser>();
/// <summary>
/// 默认服务请求。
@@ -69,39 +76,36 @@ namespace Store.Client.HttpExtension
{
return Request(BuildServiceUrl(urlpath), postdata);
}
/// <summary>
/// 使用当前 Key 构建服务请求地址。
/// </summary>
protected string BuildServiceUrl(string urlPath)
{
return $"{_config.Host}/wxxd_{urlPath}?obj=29wx/wxxd_{urlPath}";
return $"{_config.Host}/wxxd_{urlPath}?obj={Config.MainPath}/wxxd_{urlPath}";
}
/// <summary>
/// 创建并执行服务端请求,默认使用当前用户签名。
/// </summary>
protected HttpResult Request(string url, string postdata = "", MethodType method = MethodType.Post, bool isUserSign = true)
{
ServerHttpItem item = new ServerHttpItem
HttpItem item = new HttpItem
{
URL = url,
Method = method,
Postdata = postdata ?? string.Empty
};
if (isUserSign)
{
item.SignUser();
}
ApplySign(item, isUserSign);
return ServerRequest(item);
return Send(item);
}
/// <summary>
/// 服务器请求。
/// </summary>
public HttpResult ServerRequest(ServerHttpItem item)
public HttpResult ServerRequest(HttpItem item)
{
if (item == null)
{
@@ -111,26 +115,15 @@ namespace Store.Client.HttpExtension
#if RELEASE
item.WebProxy = null;
#endif
if (!item.IsSign)
{
if (item.Shop != null)
{
item.SignUser(item.Shop.Id, item.Shop.Name);
}
else
{
item.Sign();
}
}
ApplySign(item, false);
return Send(item);
}
/// <summary>
/// 执行底层 HTTP 请求。
/// </summary>
protected HttpResult Send(ServerHttpItem item)
protected HttpResult Send(HttpItem item)
{
if (item == null)
{
@@ -155,5 +148,98 @@ namespace Store.Client.HttpExtension
return result;
}
/// <summary>
/// 为请求添加公共签名或用户签名。
/// </summary>
private void ApplySign(HttpItem item, bool isUserSign)
{
string sign = isUserSign
? GetUserSign("", "")
: GetSign();
SetSign(item, sign);
}
/// <summary>
/// 获取公共签名。
/// </summary>
private static string GetSign()
{
long time = GetReviseUnix();
string code = Encryption(time);
return "time=" + time + "&code=" + code + "&NbCodeVersion=1";
}
/// <summary>
/// 获取当前用户签名。
/// </summary>
private string GetUserSign(string shopId, string shopName)
{
UserInfo user = CurrentUser.User;
if (user == null)
{
throw new InvalidOperationException("当前用户未登录,无法生成用户签名。");
}
long time = GetReviseUnix();
string code = Encryption(time);
var dict = new Dictionary<string, string>
{
{ "time", time.ToString() },
{ "code", code },
{ "code_version", "1" },
{ "version", Config.Version },
{ "user_name", user.UserName },
{ "path", Config.MainPath }
};
if (!string.IsNullOrEmpty(AgentConfig.AgentCode))
{
dict.Add("agent_code", AgentConfig.AgentCode);
dict.Add("agent_name", AgentConfig.AgentName);
}
return string.Join("&", dict.Select(kv => $"{kv.Key}={kv.Value}"));
}
/// <summary>
/// 获取校正后的时间戳。
/// </summary>
protected static long GetReviseUnix()
{
return DateHelper.GetCurrentUnixTimestampInSeconds() + ServerConfig.TimeDifferent;
}
/// <summary>
/// 签名算法。
/// </summary>
/// <param name="s">随机数</param>
/// <returns>加密签名结果</returns>
protected static string Encryption(long s)
{
string value = $"{s}sdhewu*/fhAAue48485ew5+5%@3485esGFFHFD";
return MD5Helper.Md5_32(value);
}
/// <summary>
/// 将签名参数拼接到请求。
/// </summary>
private static void SetSign(HttpItem item, string sign)
{
if (item.Method == MethodType.Get)
{
item.URL += item.URL.Contains("?") ? "&" : "?";
item.URL += sign;
}
else
{
item.Postdata = item.Postdata ?? string.Empty;
if (item.Postdata.Length > 0)
{
item.Postdata += "&";
}
item.Postdata += sign;
}
}
}
}
}
+25 -25
View File
@@ -1,28 +1,28 @@
using MAX.Core.Helpers;
using Store.Framework.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using MAX.Core.Helpers;
//using Store.Framework.Models;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
namespace Store.Client.HttpExtension
{
public class ServerHttpItem : HttpItem
{
public ShopBase Shop { get; private set; }
public ServerHttpItem()
{
//namespace Store.Client.HttpExtension
//{
// public class HttpItem : HttpItem
// {
// public ShopBase Shop { get; private set; }
// public HttpItem()
// {
}
public ServerHttpItem(ShopBase shop)
{
Shop = shop;
}
/// <summary>
/// 是否已签名
/// </summary>
public bool IsSign { get; set; }
}
}
// }
// public HttpItem(ShopBase shop)
// {
// Shop = shop;
// }
// /// <summary>
// /// 是否已签名
// /// </summary>
// public bool IsSign { get; set; }
// }
//}
@@ -76,7 +76,7 @@
// /// <summary>
// /// 执行底层 HTTP 请求。
// /// </summary>
// protected HttpResult Send(ServerHttpItem item)
// protected HttpResult Send(HttpItem item)
// {
// if (item == null)
// {
+156 -29
View File
@@ -1,21 +1,26 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Store.Framework.Models
{
/// <summary>
/// Cookie集合,支持普通 Cookie 字符串和 API 返回的 Cookie JSON。
/// </summary>
[JsonConverter(typeof(CookiesJsonConverter))]
public class Cookies : Dictionary<string, string>
{
private readonly string oldCookie;
public Cookies(string cookie)
{
oldCookie = cookie;
SplitCookie(oldCookie);
Load(cookie);
}
/// <summary>
/// Cookie字符串
/// </summary>
@@ -26,28 +31,6 @@ namespace Store.Framework.Models
return GetCookieString();
}
}
/// <summary>
/// 拆分Cookie
/// </summary>
private void SplitCookie(string cookie)
{
this.Clear();
Regex regCookie = new Regex("(?<key>.+?)=(?<value>.+?)(;|$)");
if (regCookie.IsMatch(cookie))
{
MatchCollection matchs = regCookie.Matches(cookie);
foreach (Match item in matchs)
{
string key = item.Groups["key"].Value.Trim();
string value = item.Groups["value"].Value.Trim();
if (!ContainsKey(key))
{
this.Add(key.Trim(), value.Trim());
}
}
}
}
/// <summary>
/// 获取指定值
@@ -63,6 +46,7 @@ namespace Store.Framework.Models
}
return defvalue;
}
/// <summary>
/// 添加或修改
/// </summary>
@@ -79,6 +63,7 @@ namespace Store.Framework.Models
this[key] = value;
}
}
/// <summary>
/// 获取Cookies字符串
/// </summary>
@@ -89,14 +74,156 @@ namespace Store.Framework.Models
return string.Join(";", list);
}
/// <summary>
/// 转为浏览器 Cookie 字符串。
/// </summary>
public override string ToString()
{
var list = this.Select(a => { return $"{a.Key}={a.Value}"; });
return string.Join("; ", list);
}
/// <summary>
/// 隐式转换
/// </summary>
/// <param name="cookie"></param>
public static implicit operator string (Cookies cookie)
public static implicit operator string(Cookies cookie)
{
return cookie.GetCookieString();
}
internal static Cookies FromToken(JToken token)
{
Cookies cookies = new Cookies(string.Empty);
if (token == null || token.Type == JTokenType.Null)
return cookies;
if (token.Type == JTokenType.String)
return new Cookies(token.ToString());
cookies.AddToken(token);
return cookies;
}
private void Load(string cookie)
{
Clear();
if (string.IsNullOrWhiteSpace(cookie))
return;
try
{
AddToken(JToken.Parse(cookie));
if (Count > 0)
return;
}
catch (JsonException)
{
}
SplitCookie(Decode(cookie));
}
private void AddToken(JToken token)
{
if (token == null || token.Type == JTokenType.Null)
return;
if (token is JArray array)
{
foreach (JToken item in array)
{
AddCookie(item);
}
return;
}
AddCookie(token);
}
private void AddCookie(JToken token)
{
if (token == null || token.Type == JTokenType.Null)
return;
if (token.Type == JTokenType.String)
{
string value = token.ToString();
int index = value.IndexOf('=');
if (index <= 0)
return;
AddOrUpdate(value.Substring(0, index).Trim(), value.Substring(index + 1).Trim());
return;
}
JToken name = token["Name"] ?? token["name"];
JToken valueToken = token["Value"] ?? token["value"];
if (name == null || valueToken == null)
return;
AddOrUpdate(name.ToString(), valueToken.ToString());
}
/// <summary>
/// 拆分普通 Cookie 字符串。
/// </summary>
private void SplitCookie(string cookie)
{
Clear();
if (string.IsNullOrEmpty(cookie))
return;
Regex regCookie = new Regex("(?<key>.+?)=(?<value>.+?)(;|$)");
if (regCookie.IsMatch(cookie))
{
MatchCollection matchs = regCookie.Matches(cookie);
foreach (Match item in matchs)
{
string key = item.Groups["key"].Value.Trim();
string value = item.Groups["value"].Value.Trim();
if (!ContainsKey(key))
{
this.Add(key, value);
}
}
}
}
private static string Decode(string value)
{
return (value ?? string.Empty)
.Replace("&", "&")
.Replace("%", "%")
.Replace("+", "+")
.Replace(""", "\"");
}
}
}
/// <summary>
/// Cookie JSON 转换器。
/// </summary>
public class CookiesJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Cookies).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
if (reader.TokenType == JsonToken.String)
return new Cookies(reader.Value?.ToString());
return Cookies.FromToken(JToken.Load(reader));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Cookies cookies = value as Cookies;
writer.WriteValue(cookies?.GetCookieString());
}
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace Store.Framework.Models
{
/// <summary>
/// 店铺信息。
/// </summary>
public class Shop : ShopBase
{
}
}
+17 -6
View File
@@ -1,4 +1,5 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -9,35 +10,45 @@ namespace Store.Framework.Models
/// <summary>
/// 商铺信息
/// </summary>
public class ShopBase
public abstract class ShopBase
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("shop_account")]
public string Name { get; set; }
[JsonProperty("login_pass")]
public string Password { get; set; }
/// <summary>
/// Cookie信息
public Cookies Cookie { get; set; }
/// </summary>
[JsonProperty("cookie")]
public Cookies Cookie { get; set; }
/// <summary>
/// 分组名称
/// </summary>
[JsonProperty("group_name")]
public string GroupName { get; set; }
/// <summary>
/// 商铺提示信息
/// </summary>
[JsonProperty("login_status")]
public string Msg { get; set; }
}
/// <summary>
/// 商铺信息
/// </summary>
/// <typeparam name="TStatus">状态码</typeparam>
public class ShopBase<TStatus> : ShopBase
public abstract class ShopBase<TStatus> : ShopBase
{
/// <summary>
/// 状态
/// </summary>
public TStatus Status { get; set; }
}
}
}
+10 -6
View File
@@ -10,11 +10,11 @@ using System.Threading.Tasks;
namespace Store.Framework.Services;
public record UserNotification(UserInfo user) : INotification;
//public record UserNotification(UserInfo user) : INotification;
/// <summary>
/// 当前用户
/// </summary>
internal class CurrentUserService : ICurrentUser, ISingletonDependency, INotificationHandler<UserNotification>
internal class CurrentUserService : ICurrentUser, ISingletonDependency//, INotificationHandler<UserNotification>
{
public string UserName => User?.UserName;
@@ -28,10 +28,14 @@ internal class CurrentUserService : ICurrentUser, ISingletonDependency, INotific
{
return User.UserAuthority.Contains(code);
}
Task INotificationHandler<UserNotification>.Handle(UserNotification notification, CancellationToken cancellationToken)
internal void SetUser(UserInfo user)
{
User = notification.user;
return Task.CompletedTask;
User = user;
}
//Task INotificationHandler<UserNotification>.Handle(UserNotification notification, CancellationToken cancellationToken)
//{
// User = notification.user;
// return Task.CompletedTask;
//}
}
+224
View File
@@ -0,0 +1,224 @@
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
{
/// <summary>
/// 商铺管理服务
/// </summary>
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));
}
/// <summary>
/// 获取当前用户的所有商铺。
/// </summary>
/// <param name="pageSize">每页数量。</param>
/// <returns>商铺列表。</returns>
public List<Shop> GetShops(int pageSize = DefaultPageSize)
{
return GetShops(false, pageSize);
}
/// <summary>
/// 获取商铺列表。
/// </summary>
/// <param name="isAdmin">是否调用管理端接口。</param>
/// <param name="pageSize">每页数量。</param>
/// <returns>商铺列表。</returns>
public List<Shop> GetShops(bool isAdmin, int pageSize = DefaultPageSize)
{
List<Shop> shops = new List<Shop>();
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<List<Shop>> 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;
}
/// <summary>
/// 获取服务端商铺列表,兼容旧调用。
/// </summary>
public List<Shop> GetServerShop()
{
return GetShops();
}
/// <summary>
/// 从服务端刷新商铺 Cookie。
/// </summary>
/// <param name="shops">待刷新商铺。</param>
/// <returns>服务端原始响应。</returns>
public string GetShopCookie(List<Shop> 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,
@"<shop\s+(?:(?:id|name)=""(?<key>[^""]*?)""[^>]*)>(?<json>[\w\W]*?)</shop>",
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;
}
/// <summary>
/// 检测商铺登录状态。
/// </summary>
/// <param name="shop">商铺。</param>
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\":\"")
? "登录成功"
: "会话已过期";
}
/// <summary>
/// 删除服务端商铺。
/// </summary>
/// <param name="loginName">店铺登录名。</param>
/// <returns>服务端原始响应。</returns>
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;
}
/// <summary>
/// 删除服务端店铺,兼容旧方法命名。
/// </summary>
public string DelServerDouShop(string shopId)
{
return DeleteShop(shopId);
}
private static ApiResponse<List<Shop>> DeserializeShopResponse(HttpResult result)
{
if (result == null || result.StatusCode != HttpStatusCode.OK || string.IsNullOrWhiteSpace(result.Html))
return null;
try
{
return JsonConvert.DeserializeObject<ApiResponse<List<Shop>>>(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(""", "\"");
}
}
}
-134
View File
@@ -1,134 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
//using FkServices = LittleCow.Framework.Services;
namespace Store.Client.Services
{
///// <summary>
///// 商铺服务
///// </summary>
//internal class ShopService : ITransientDependency
//{
// private readonly ShopApi _shopApi;
// private readonly IEventBus _eventBus;
// public ShopService(ShopApi shopApi, IEventBus eventBus)
// {
// _shopApi = shopApi;
// _eventBus = eventBus;
// }
// /// <summary>
// /// 获取所有商铺信息
// /// </summary>
// /// <typeparam name="T"></typeparam>
// /// <returns></returns>
// public List<T> GetShops<T>() where T : ShopBase
// {
// HttpResult result = _shopApi.GetShops();
// if (result.StatusCode == System.Net.HttpStatusCode.OK)
// {
// StringBuilder sb = new StringBuilder();
// sb.Append("[");
// Regex regShopList = new Regex("<shop([^>]+?)>");
// if (regShopList.IsMatch(result.Html))
// {
// int index = 0;
// MatchCollection matchs = regShopList.Matches(result.Html);
// foreach (Match item in matchs)
// {
// string value = item.Value;
// value = value.Replace("<shop '", "{\"");
// value = value.Replace("'>", "\"}");
// value = value.Replace("':'", "\":\"");
// value = value.Replace("' '", "\",\"");
// if (index > 0)
// {
// sb.Append(",");
// }
// sb.Append(value);
// index++;
// }
// sb.Append("]");
// List<T> list = JsonConvert.DeserializeObject<List<T>>(sb.ToString());
// list.RemoveAll(a => string.IsNullOrEmpty(a.Name));
// return list;
// }
// }
// return new List<T>();
// }
// public string GetShopCookie(List<ShopBase> shops)
// {
// HttpResult result = _shopApi.GetShopsCookie(shops);
// if (result.StatusCode == System.Net.HttpStatusCode.OK)
// {
// MatchCollection matchs = Regex.Matches(result.Html, @"<shop id=""([^""]+?)"">([\w\W]+?)</shop>");
// if (matchs != null)
// {
// foreach (Match item in matchs)
// {
// string shopId = item.Groups[1].Value;
// string json = item.Groups[2].Value;
// var rootToken = JToken.Parse(json);
// string cookie = rootToken["Cookies"]?.ToString() ?? "";
// var shop = shops.FirstOrDefault(a => a.Id == shopId);
// if (shop != null)
// {
// shop.Cookie = new Cookies(cookie);
// }
// }
// }
// }
// return null;
// }
// /// <summary>
// /// 检测商铺登录状态
// /// </summary>
// public void CheckShopStatus(ShopBase shop)
// {
// HttpItem item = new HttpItem();
// item.URL = "https://myseller.taobao.com/ajaxProxy.do?_ksTS=1548152154745_13&callback=seller_layout_head&action=FrameworkLayoutAction&event_submit_do_layout_data=true";
// item.Referer = "https://myseller.taobao.com";
// item.Method = MethodType.Post;
// item.Cookie = shop.Cookie.GetCookieString();
// HttpResult result = HttpHelper.Request(item);
// if (result.StatusCode == System.Net.HttpStatusCode.OK)
// {
// string a = result.Html.Contains("\"shopName\":\"") ? "登录成功" : "会话已过期";
// }
// //string urlx =
// //string refere =
// //string htmlx = GetPostTaobaoHtml.GetUrl(urlx, refere, true, "", Shop.Cookies);
// //Shop.MsgForCookiesLogin = htmlx.Contains("\"shopName\":\"") ? "登录成功" : "会话已过期";
// //GetTaobaoShops.ShopsTemp.Add(Shop);
// }
// /// <summary>
// /// 获取值
// /// </summary>
// /// <param name="html"></param>
// /// <param name="reg"></param>
// /// <returns></returns>
// private string GetUserValue(string html, string reg)
// {
// string temp = Regex.Match(html, @"[""]" + reg + @"[""][\s]*:[\s]*[""]([^""]*?)[""]")?.Value;
// if (string.IsNullOrEmpty(temp))
// temp = Regex.Match(html, @"[']" + reg + @"['][\s]*:[\s]*[']([^']*?)[']")?.Groups[1].Value;
// if (string.IsNullOrEmpty(temp))
// temp = Regex.Match(html, @"['""]" + reg + @"['""][\s]*:[\s]*([\d]+)")?.Value;
// return temp;
// }
//}
}
+7 -1
View File
@@ -5,7 +5,9 @@ using MAX.Core.Helpers;
using Newtonsoft.Json;
using Store.Client.Apis;
using Store.Framework.Apis;
using Store.Framework.Inerterfaces;
using Store.Framework.Models;
using Store.Framework.Services;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -21,10 +23,12 @@ namespace Store.Client.Services
public class UserService : ITransientDependency
{
private readonly UserApi _userApi;
private readonly ICurrentUser _currentUser;
public UserService(UserApi userApi)
public UserService(UserApi userApi, ICurrentUser currentUser)
{
_userApi = userApi;
_currentUser = currentUser;
}
/// <summary>
@@ -75,6 +79,8 @@ namespace Store.Client.Services
ret.Success = true;
ret.Msg = apiResponse.Msg;
ret.Data = result;
(_currentUser as CurrentUserService).SetUser(user);
//_mediator.Publish(new UserNotification(user));
return ret;
}