From 3f4236717c841e7531de9d9c51993a82d961b98f Mon Sep 17 00:00:00 2001 From: shanj <18996038927@163.com> Date: Fri, 10 Mar 2023 15:28:17 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9B=86=E6=88=90=E6=8B=B3=E6=8E=A2SDK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BBWYB.Server.API/BBWYB.Server.API.csproj | 1 + .../Controllers/ProductController.cs | 37 +++++++ BBWYB.Server.API/Program.cs | 2 + .../BBWYB.Server.Business.csproj | 1 + .../Product/ProductBusiness.cs | 28 ++++++ QuanTan.SDK/Client/BaseClient.cs | 57 +++++++++++ .../Client/Buyer/QuanTan_Buyer_OrderClient.cs | 35 +++++++ .../Buyer/QuanTan_Buyer_ProductClient.cs | 17 ++++ .../QuanTan_Supplier_ProductClient.cs | 23 +++++ QuanTan.SDK/Extensions/EncryptionExtension.cs | 85 ++++++++++++++++ .../Order/QuanTan_Buyer_CreateOrderRequest.cs | 16 +++ .../QuanTan_Buyer_GetOrderDetailRequest.cs | 9 ++ .../QuanTan_Buyer_PreviewOrderRequest.cs | 41 ++++++++ .../QuanTan_Buyer_SendGoodsNotifyRequest.cs | 13 +++ .../QuanTan_Buyer_CreateOrderResponse.cs | 13 +++ .../QuanTan_Buyer_OrderDetailResponse.cs | 98 +++++++++++++++++++ .../QuanTan_Buyer_PreviewOrderResponse.cs | 25 +++++ .../Product/QuanTan_Buyer_ProductResponse.cs | 46 +++++++++ .../Response/Vender/QuanTan_Buyer_Supplier.cs | 11 +++ QuanTan.SDK/Models/QuanTanBaseParam.cs | 25 +++++ QuanTan.SDK/Models/QuanTanResponse.cs | 16 +++ .../QuanTan_Supplier_SearchSkuRequest.cs | 19 ++++ .../QuanTan_Supplier_SearchSpuRequest.cs | 13 +++ .../QuanTan_Supplier_ProductListResponse.cs | 24 +++++ ...QuanTan_Supplier_ProductSkuListResponse.cs | 32 ++++++ QuanTan.SDK/QuanTan.SDK.csproj | 13 +++ SDKAdapter/BasePlatformRequest.cs | 17 ++++ .../Client/Base/OP_PlatformClient.cs | 31 ++++++ .../Client/Base/OP_PlatformClientFactory.cs | 26 +++++ .../Client/Impl/OP_JDClient.cs | 14 +++ .../Client/Impl/OP_QuanTanClient.cs | 78 +++++++++++++++ .../Models/Request/OP_SearchProductRequest.cs | 19 ++++ .../Request/OP_SearchProductSkuRequest.cs | 19 ++++ .../Models/Response/OP_ProductResponse.cs | 77 +++++++++++++++ .../PurchasePlatform/Models/AdapterEnums.cs | 15 +++ .../PurchasePlatform/PurchasePlatformSDK.cs | 12 +++ SDKAdapter/SDKAdapter.csproj | 11 +++ bbwyb.sln | 16 ++- 38 files changed, 1033 insertions(+), 2 deletions(-) create mode 100644 BBWYB.Server.API/Controllers/ProductController.cs create mode 100644 BBWYB.Server.Business/Product/ProductBusiness.cs create mode 100644 QuanTan.SDK/Client/BaseClient.cs create mode 100644 QuanTan.SDK/Client/Buyer/QuanTan_Buyer_OrderClient.cs create mode 100644 QuanTan.SDK/Client/Buyer/QuanTan_Buyer_ProductClient.cs create mode 100644 QuanTan.SDK/Client/Supplier/QuanTan_Supplier_ProductClient.cs create mode 100644 QuanTan.SDK/Extensions/EncryptionExtension.cs create mode 100644 QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_CreateOrderRequest.cs create mode 100644 QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_GetOrderDetailRequest.cs create mode 100644 QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_PreviewOrderRequest.cs create mode 100644 QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_SendGoodsNotifyRequest.cs create mode 100644 QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_CreateOrderResponse.cs create mode 100644 QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_OrderDetailResponse.cs create mode 100644 QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_PreviewOrderResponse.cs create mode 100644 QuanTan.SDK/Models/Buyer/Response/Product/QuanTan_Buyer_ProductResponse.cs create mode 100644 QuanTan.SDK/Models/Buyer/Response/Vender/QuanTan_Buyer_Supplier.cs create mode 100644 QuanTan.SDK/Models/QuanTanBaseParam.cs create mode 100644 QuanTan.SDK/Models/QuanTanResponse.cs create mode 100644 QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSkuRequest.cs create mode 100644 QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSpuRequest.cs create mode 100644 QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductListResponse.cs create mode 100644 QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductSkuListResponse.cs create mode 100644 QuanTan.SDK/QuanTan.SDK.csproj create mode 100644 SDKAdapter/BasePlatformRequest.cs create mode 100644 SDKAdapter/OperationPlatform/Client/Base/OP_PlatformClient.cs create mode 100644 SDKAdapter/OperationPlatform/Client/Base/OP_PlatformClientFactory.cs create mode 100644 SDKAdapter/OperationPlatform/Client/Impl/OP_JDClient.cs create mode 100644 SDKAdapter/OperationPlatform/Client/Impl/OP_QuanTanClient.cs create mode 100644 SDKAdapter/OperationPlatform/Models/Request/OP_SearchProductRequest.cs create mode 100644 SDKAdapter/OperationPlatform/Models/Request/OP_SearchProductSkuRequest.cs create mode 100644 SDKAdapter/OperationPlatform/Models/Response/OP_ProductResponse.cs create mode 100644 SDKAdapter/PurchasePlatform/Models/AdapterEnums.cs create mode 100644 SDKAdapter/PurchasePlatform/PurchasePlatformSDK.cs diff --git a/BBWYB.Server.API/BBWYB.Server.API.csproj b/BBWYB.Server.API/BBWYB.Server.API.csproj index e8e4fa5..cede918 100644 --- a/BBWYB.Server.API/BBWYB.Server.API.csproj +++ b/BBWYB.Server.API/BBWYB.Server.API.csproj @@ -20,6 +20,7 @@ + diff --git a/BBWYB.Server.API/Controllers/ProductController.cs b/BBWYB.Server.API/Controllers/ProductController.cs new file mode 100644 index 0000000..e5e2973 --- /dev/null +++ b/BBWYB.Server.API/Controllers/ProductController.cs @@ -0,0 +1,37 @@ +using BBWYB.Server.Business; +using Microsoft.AspNetCore.Mvc; +using SDKAdapter.OperationPlatform.Models; + +namespace BBWYB.Server.API.Controllers +{ + public class ProductController : BaseApiController + { + private ProductBusiness productBusiness; + public ProductController(ProductBusiness productBusiness, IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor) + { + this.productBusiness = productBusiness; + } + + /// + /// spu列表查询 + /// + /// + /// + [HttpPost] + public OP_ProductListResponse GetProductList([FromBody] OP_SearchProductRequest request) + { + return productBusiness.GetProductList(request); + } + + /// + /// sku列表查询 + /// + /// + /// + [HttpPost] + public OP_ProductSkuListResponse GetProductSkuList([FromBody] OP_SearchProductSkuRequest request) + { + return productBusiness.GetProductSkuList(request); + } + } +} diff --git a/BBWYB.Server.API/Program.cs b/BBWYB.Server.API/Program.cs index 3471c8b..65fb3d4 100644 --- a/BBWYB.Server.API/Program.cs +++ b/BBWYB.Server.API/Program.cs @@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Serialization; +using SDKAdapter.OperationPlatform.Client; using System.Reflection; using System.Text; using Yitter.IdGenerator; @@ -44,6 +45,7 @@ services.AddCors(options => services.BatchRegisterServices(new Assembly[] { Assembly.Load("BBWYB.Server.Business") }, typeof(IDenpendency)); +services.AddSingleton(); services.AddMapper(new MappingProfiles()); services.AddControllers(c => diff --git a/BBWYB.Server.Business/BBWYB.Server.Business.csproj b/BBWYB.Server.Business/BBWYB.Server.Business.csproj index fc48f97..2a079df 100644 --- a/BBWYB.Server.Business/BBWYB.Server.Business.csproj +++ b/BBWYB.Server.Business/BBWYB.Server.Business.csproj @@ -17,6 +17,7 @@ + diff --git a/BBWYB.Server.Business/Product/ProductBusiness.cs b/BBWYB.Server.Business/Product/ProductBusiness.cs new file mode 100644 index 0000000..af7fbdc --- /dev/null +++ b/BBWYB.Server.Business/Product/ProductBusiness.cs @@ -0,0 +1,28 @@ +using BBWYB.Common.Log; +using BBWYB.Common.Models; +using SDKAdapter.OperationPlatform.Client; +using SDKAdapter.OperationPlatform.Models; +using Yitter.IdGenerator; + +namespace BBWYB.Server.Business +{ + public class ProductBusiness : BaseBusiness, IDenpendency + { + private OP_PlatformClientFactory opPlatformClientFactory; + + public ProductBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, OP_PlatformClientFactory opPlatformClientFactory) : base(fsql, nLogManager, idGenerator) + { + this.opPlatformClientFactory = opPlatformClientFactory; + } + + public OP_ProductListResponse GetProductList(OP_SearchProductRequest request) + { + return opPlatformClientFactory.GetClient(request.Platform).GetProductList(request); + } + + public OP_ProductSkuListResponse GetProductSkuList(OP_SearchProductSkuRequest request) + { + return opPlatformClientFactory.GetClient(request.Platform).GetProductSkuList(request); + } + } +} diff --git a/QuanTan.SDK/Client/BaseClient.cs b/QuanTan.SDK/Client/BaseClient.cs new file mode 100644 index 0000000..2825440 --- /dev/null +++ b/QuanTan.SDK/Client/BaseClient.cs @@ -0,0 +1,57 @@ +using BBWYB.Common.Http; +using Newtonsoft.Json; +using QuanTan.SDK.Extensions; +using QuanTan.SDK.Model; + +namespace QuanTan.SDK.Client +{ + public class BaseClient + { + protected RestApiService restApiService; + + protected readonly string host = "https://qt.qiyue666.com/"; + + public BaseClient(RestApiService restApiService) + { + this.restApiService = restApiService; + } + + public QuanTanResponse SendRequest(string apiPath, object param, string appId, string appSecret) + { + var callTime = DateTime.Now.ToString("yyyyMMddHHmmss"); + var randomNum = new Random(Guid.NewGuid().GetHashCode()).Next(100000, 999999).ToString(); + if (param == null) + param = new object[] { }; + + var paramStr = JsonConvert.SerializeObject(param); + + var jmStr = JsonConvert.SerializeObject(new QuanTanSignParam() + { + appId = appId, + appSecret = appSecret, + callTime = callTime, + _params = paramStr, + randomNum = randomNum + }); + var md5Str = jmStr.Md5Encrypt(); + var qtToken = $"{appId}-{callTime}-{md5Str}-{randomNum}"; + var requestParam = new QuanTanRequestParam() + { + Params = paramStr, + token = qtToken + }; + + try + { + var restApiResult = restApiService.SendRequest(host, apiPath, requestParam, null, HttpMethod.Post); + if (restApiResult.StatusCode != System.Net.HttpStatusCode.OK) + throw new Exception(restApiResult.Content); + return JsonConvert.DeserializeObject>(restApiResult.Content); + } + catch (Exception ex) + { + return new QuanTanResponse() { Status = 0, Message = ex.Message }; + } + } + } +} diff --git a/QuanTan.SDK/Client/Buyer/QuanTan_Buyer_OrderClient.cs b/QuanTan.SDK/Client/Buyer/QuanTan_Buyer_OrderClient.cs new file mode 100644 index 0000000..33c4f7b --- /dev/null +++ b/QuanTan.SDK/Client/Buyer/QuanTan_Buyer_OrderClient.cs @@ -0,0 +1,35 @@ +using BBWYB.Common.Http; +using QuanTan.SDK.Model; +using QuanTan.SDK.Models.Buyer; + +namespace QuanTan.SDK.Client +{ + public class QuanTan_Buyer_OrderClient : BaseClient + { + public QuanTan_Buyer_OrderClient(RestApiService restApiService) : base(restApiService) + { + } + + /// + /// 预览订单 + /// + /// + /// + /// + /// + public QuanTanResponse PreviewOrder(QuanTan_Buyer_PreviewOrderRequest request, string appId, string appSecret) + { + return SendRequest("api/platform/cart/add", request, appId, appSecret); + } + + public QuanTanResponse CreateOrder(QuanTan_Buyer_CreateOrderRequest request, string appId, string appSecret) + { + return SendRequest("api/platform/order/add", request, appId, appSecret); + } + + public QuanTanResponse GetOrderDetail(QuanTan_Buyer_GetOrderDetailRequest request, string appId, string appSecret) + { + return SendRequest("api/platform/order/detail", request, appId, appSecret); + } + } +} diff --git a/QuanTan.SDK/Client/Buyer/QuanTan_Buyer_ProductClient.cs b/QuanTan.SDK/Client/Buyer/QuanTan_Buyer_ProductClient.cs new file mode 100644 index 0000000..510431b --- /dev/null +++ b/QuanTan.SDK/Client/Buyer/QuanTan_Buyer_ProductClient.cs @@ -0,0 +1,17 @@ +using BBWYB.Common.Http; +using QuanTan.SDK.Model; +using QuanTan.SDK.Models.Buyer; +namespace QuanTan.SDK.Client +{ + public class QuanTan_Buyer_ProductClient : BaseClient + { + public QuanTan_Buyer_ProductClient(RestApiService restApiService) : base(restApiService) + { + } + + public QuanTanResponse GetProductInfo(string productId, string appId, string appSecret) + { + return SendRequest($"api/platform/product/spu/{productId}", null, appId, appSecret); + } + } +} diff --git a/QuanTan.SDK/Client/Supplier/QuanTan_Supplier_ProductClient.cs b/QuanTan.SDK/Client/Supplier/QuanTan_Supplier_ProductClient.cs new file mode 100644 index 0000000..d38770c --- /dev/null +++ b/QuanTan.SDK/Client/Supplier/QuanTan_Supplier_ProductClient.cs @@ -0,0 +1,23 @@ +using BBWYB.Common.Http; +using QuanTan.SDK.Model; +using QuanTan.SDK.Models.Supplier; + +namespace QuanTan.SDK.Client.Supplier +{ + public class QuanTan_Supplier_ProductClient : BaseClient + { + public QuanTan_Supplier_ProductClient(RestApiService restApiService) : base(restApiService) + { + } + + public QuanTanResponse GetProductList(QuanTan_Supplier_SearchSpuRequest request, string appId, string appSecret) + { + return SendRequest("api/platform/supply/product/spu", request, appId, appSecret); + } + + public QuanTanResponse GetProductSkuList(QuanTan_Supplier_SearchSkuRequest request, string appId, string appSecret) + { + return SendRequest("api/platform/supply/product/list", request, appId, appSecret); + } + } +} diff --git a/QuanTan.SDK/Extensions/EncryptionExtension.cs b/QuanTan.SDK/Extensions/EncryptionExtension.cs new file mode 100644 index 0000000..abd451a --- /dev/null +++ b/QuanTan.SDK/Extensions/EncryptionExtension.cs @@ -0,0 +1,85 @@ +using System; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace QuanTan.SDK.Extensions +{ + public static class EncryptionExtension + { + + public static string Md5Encrypt(this string originStr) + { + using (var md5 = MD5.Create()) + { + return string.Join(string.Empty, md5.ComputeHash(Encoding.UTF8.GetBytes(originStr)).Select(x => x.ToString("x2"))); + } + } + + //AES加密 传入,要加密的串和, 解密key + public static string AESEncrypt(this string input) + { + var key = "dataplatform2019"; + var ivStr = "1012132405963708"; + + var encryptKey = Encoding.UTF8.GetBytes(key); + var iv = Encoding.UTF8.GetBytes(ivStr); //偏移量,最小为16 + using (var aesAlg = Aes.Create()) + { + using (var encryptor = aesAlg.CreateEncryptor(encryptKey, iv)) + { + using (var msEncrypt = new MemoryStream()) + { + using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, + CryptoStreamMode.Write)) + + using (var swEncrypt = new StreamWriter(csEncrypt)) + { + swEncrypt.Write(input); + } + var decryptedContent = msEncrypt.ToArray(); + + return Convert.ToBase64String(decryptedContent); + } + } + } + } + + public static string AESDecrypt(this string cipherText) + { + var fullCipher = Convert.FromBase64String(cipherText); + + var ivStr = "1012132405963708"; + var key = "dataplatform2019"; + + var iv = Encoding.UTF8.GetBytes(ivStr); + var decryptKey = Encoding.UTF8.GetBytes(key); + + using (var aesAlg = Aes.Create()) + { + using (var decryptor = aesAlg.CreateDecryptor(decryptKey, iv)) + { + string result; + using (var msDecrypt = new MemoryStream(fullCipher)) + { + using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) + { + using (var srDecrypt = new StreamReader(csDecrypt)) + { + result = srDecrypt.ReadToEnd(); + } + } + } + + return result; + } + } + } + + public static string Base64Encrypt(this string originStr) + { + return Convert.ToBase64String(Encoding.UTF8.GetBytes(originStr)); + } + } +} diff --git a/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_CreateOrderRequest.cs b/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_CreateOrderRequest.cs new file mode 100644 index 0000000..61c023a --- /dev/null +++ b/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_CreateOrderRequest.cs @@ -0,0 +1,16 @@ +namespace QuanTan.SDK.Models.Buyer +{ + public class QuanTan_Buyer_CreateOrderRequest + { + public string clientOrderId { get; set; } + + public string userAccount { get; set; } + + public string cartIds { get; set; } + + public QuanTanCreateOrderReceipt receipt { get; set; } + } + + public class QuanTanCreateOrderReceipt : QuanTan_Buyer_PreviewOrderReceipt + { } +} diff --git a/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_GetOrderDetailRequest.cs b/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_GetOrderDetailRequest.cs new file mode 100644 index 0000000..a945317 --- /dev/null +++ b/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_GetOrderDetailRequest.cs @@ -0,0 +1,9 @@ +namespace QuanTan.SDK.Models.Buyer +{ + public class QuanTan_Buyer_GetOrderDetailRequest + { + public string userAccount { get; set; } + + public string orderId { get; set; } + } +} diff --git a/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_PreviewOrderRequest.cs b/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_PreviewOrderRequest.cs new file mode 100644 index 0000000..b8dcd39 --- /dev/null +++ b/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_PreviewOrderRequest.cs @@ -0,0 +1,41 @@ +namespace QuanTan.SDK.Models.Buyer +{ + public class QuanTan_Buyer_PreviewOrderRequest + { + public string clientOrderId { get; set; } + + public string userAccount { get; set; } + + public IList buyInfo { get; set; } + + public QuanTan_Buyer_PreviewOrderReceipt receipt { get; set; } + } + + public class QuanTan_Buyer_PreviewOrderProduct + { + public string productId { get; set; } + + public string productSku { get; set; } + + public int quantity { get; set; } + } + + public class QuanTan_Buyer_PreviewOrderReceipt + { + public string province { get; set; } + + public string city { get; set; } + + public string area { get; set; } + + public string town { get; set; } + + public string address { get; set; } + + public string realName { get; set; } + + public string phone { get; set; } + } + + +} diff --git a/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_SendGoodsNotifyRequest.cs b/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_SendGoodsNotifyRequest.cs new file mode 100644 index 0000000..149360b --- /dev/null +++ b/QuanTan.SDK/Models/Buyer/Request/Order/QuanTan_Buyer_SendGoodsNotifyRequest.cs @@ -0,0 +1,13 @@ +namespace QuanTan.SDK.Models.Buyer +{ + public class QuanTan_Buyer_SendGoodsNotifyRequest + { + public string OrderId { get; set; } + + public string WayBillNo { get; set; } + + public string ExpressId { get; set; } + + public string ExpressName { get; set; } + } +} diff --git a/QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_CreateOrderResponse.cs b/QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_CreateOrderResponse.cs new file mode 100644 index 0000000..d9015f9 --- /dev/null +++ b/QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_CreateOrderResponse.cs @@ -0,0 +1,13 @@ +namespace QuanTan.SDK.Models.Buyer +{ + public class QuanTan_Buyer_CreateOrderResponse + { + public string OrderId { get; set; } + + public string OrderSn { get; set; } + + public string GroupOrderId { get; set; } + + public string PayStatus { get; set; } + } +} diff --git a/QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_OrderDetailResponse.cs b/QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_OrderDetailResponse.cs new file mode 100644 index 0000000..21598e5 --- /dev/null +++ b/QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_OrderDetailResponse.cs @@ -0,0 +1,98 @@ +namespace QuanTan.SDK.Models.Buyer +{ + public class QuanTan_Buyer_OrderDetailResponse + { + public string OrderId { get; set; } + + public string OrderSn { get; set; } + + public string ClientOrderId { get; set; } + + public string GroupOrderId { get; set; } + + /// + /// 商品金额 + /// + public decimal ProductPrice { get; set; } + + /// + /// 运费 + /// + public decimal TotalPostage { get; set; } + + /// + /// 订单总金额 + /// + public decimal TotalPrice { get; set; } + + /// + /// 订单状态:-1、已退款;0、待发货;1、待收货;2、待评价;3、已完成; + /// + public int Status { get; set; } + + /// + /// 支付状态:0、待支付  1、已支付 + /// + public int Paid { get; set; } + + public DateTime? PayTime { get; set; } + + /// + /// 下单方式:1、普通下单  2、售罄下单 + /// + public int StockType { get; set; } + + public QuanTan_Buyer_OrderDetailReceipt Receipt { get; set; } + + public IList OrderProduct { get; set; } + } + + public class QuanTan_Buyer_OrderDetailReceipt : QuanTan_Buyer_PreviewOrderReceipt + { + + } + + public class QuanTan_Buyer_OrderDetailProduct + { + public string OrderProductId { get; set; } + + public string ProductId { get; set; } + + public string ProductSku { get; set; } + + + public int Quantity { get; set; } + + public decimal Price { get; set; } + + /// + /// 商品总金额 + /// + public decimal ProductPrice { get; set; } + + /// + /// 运费 + /// + public decimal PostagePrice { get; set; } + + /// + /// 总金额 + /// + public decimal TotalPrice { get; set; } + + public QuanTan_Buyer_OrderDetailProductSku SkuInfo { get; set; } + } + + public class QuanTan_Buyer_OrderDetailProductSku + { + public string ProductId { get; set; } + + public string ProductSku { get; set; } + + public string Title { get; set; } + + public string Image { get; set; } + + public decimal Price { get; set; } + } +} diff --git a/QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_PreviewOrderResponse.cs b/QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_PreviewOrderResponse.cs new file mode 100644 index 0000000..d4e0444 --- /dev/null +++ b/QuanTan.SDK/Models/Buyer/Response/Order/QuanTan_Buyer_PreviewOrderResponse.cs @@ -0,0 +1,25 @@ +namespace QuanTan.SDK.Models.Buyer +{ + public class QuanTan_Buyer_PreviewOrderResponse + { + /// + /// 货款 + /// + public decimal ProductPrice { get; set; } + + /// + /// 运费 + /// + public decimal PostagePrice { get; set; } + + /// + /// 总费用 + /// + public decimal TotalPrice { get; set; } + + /// + /// 购物车Id + /// + public string CartIds { get; set; } + } +} diff --git a/QuanTan.SDK/Models/Buyer/Response/Product/QuanTan_Buyer_ProductResponse.cs b/QuanTan.SDK/Models/Buyer/Response/Product/QuanTan_Buyer_ProductResponse.cs new file mode 100644 index 0000000..a828c56 --- /dev/null +++ b/QuanTan.SDK/Models/Buyer/Response/Product/QuanTan_Buyer_ProductResponse.cs @@ -0,0 +1,46 @@ +namespace QuanTan.SDK.Models.Buyer +{ + public class QuanTan_Buyer_ProductResponse + { + public QuanTan_Buyer_Supplier Supplier { get; set; } + + public QuanTan_Buyer_Product Product { get; set; } + + public IList ProductSku { get; set; } + } + + public class QuanTan_Buyer_Product + { + public string ProductId { get; set; } + /// + /// 商品名称(完整标题) + /// + public string ProductName { get; set; } + /// + /// 商品简介 + /// + public string ProductBrief { get; set; } + public decimal Price { get; set; } + public string UnitName { get; set; } + public string Image { get; set; } + //public string Sliderimage { get; set; } + public string VideoLink { get; set; } + public string Stock { get; set; } + public string Context { get; set; } + } + + public class QuanTan_Buyer_ProductSku + { + public string SkuId { get; set; } + public string ProductId { get; set; } + public string Title { get; set; } + public string Logo { get; set; } + public decimal Price { get; set; } + //public decimal RetailPrice { get; set; } + public int Stock { get; set; } + //public decimal Volume { get; set; } + //public string weight { get; set; } + public string BarCode { get; set; } + //public string skuArr { get; set; } + } +} diff --git a/QuanTan.SDK/Models/Buyer/Response/Vender/QuanTan_Buyer_Supplier.cs b/QuanTan.SDK/Models/Buyer/Response/Vender/QuanTan_Buyer_Supplier.cs new file mode 100644 index 0000000..3759ca6 --- /dev/null +++ b/QuanTan.SDK/Models/Buyer/Response/Vender/QuanTan_Buyer_Supplier.cs @@ -0,0 +1,11 @@ +namespace QuanTan.SDK.Models.Buyer +{ + public class QuanTan_Buyer_Supplier + { + public string Location { get; set; } + + public string VenderId { get; set; } + + public string VerdenName { get; set; } + } +} diff --git a/QuanTan.SDK/Models/QuanTanBaseParam.cs b/QuanTan.SDK/Models/QuanTanBaseParam.cs new file mode 100644 index 0000000..4175278 --- /dev/null +++ b/QuanTan.SDK/Models/QuanTanBaseParam.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace QuanTan.SDK.Model +{ + public class QuanTanSignParam + { + public string appId { get; set; } + public string appSecret { get; set; } + + public string callTime { get; set; } + + [JsonProperty(PropertyName = "params")] + public object _params { get; set; } + + public string randomNum { get; set; } + } + + public class QuanTanRequestParam + { + [JsonProperty(PropertyName = "params")] + public object Params { get; set; } + + public string token { get; set; } + } +} diff --git a/QuanTan.SDK/Models/QuanTanResponse.cs b/QuanTan.SDK/Models/QuanTanResponse.cs new file mode 100644 index 0000000..d75b4e4 --- /dev/null +++ b/QuanTan.SDK/Models/QuanTanResponse.cs @@ -0,0 +1,16 @@ +namespace QuanTan.SDK.Model +{ + public class QuanTanResponse + { + public int Status { get; set; } + + public string Message { get; set; } + + public object Data { get; set; } + } + + public class QuanTanResponse : QuanTanResponse + { + public new T Data { get; set; } + } +} diff --git a/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSkuRequest.cs b/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSkuRequest.cs new file mode 100644 index 0000000..186f08d --- /dev/null +++ b/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSkuRequest.cs @@ -0,0 +1,19 @@ +namespace QuanTan.SDK.Models.Supplier +{ + public class QuanTan_Supplier_SearchSkuRequest + { + public string storeId { get; set; } + + public string categroyId { get; set; } + + public string channel { get; set; } + + public string productId { get; set; } + + public string productSku { get; set; } + + public int page { get; set; } = 1; + + public int pageSize { get; set; } = 20; + } +} diff --git a/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSpuRequest.cs b/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSpuRequest.cs new file mode 100644 index 0000000..758f780 --- /dev/null +++ b/QuanTan.SDK/Models/Supplier/Request/Product/QuanTan_Supplier_SearchSpuRequest.cs @@ -0,0 +1,13 @@ +namespace QuanTan.SDK.Models.Supplier +{ + public class QuanTan_Supplier_SearchSpuRequest + { + public string storeId { get; set; } + + public string productId { get; set; } + + public int page { get; set; } = 1; + + public int pageSize { get; set; } = 20; + } +} diff --git a/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductListResponse.cs b/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductListResponse.cs new file mode 100644 index 0000000..500d6f5 --- /dev/null +++ b/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductListResponse.cs @@ -0,0 +1,24 @@ +namespace QuanTan.SDK.Models.Supplier +{ + public class QuanTan_Supplier_Product + { + public string ProductId { get; set; } + + public string ProductName { get; set; } + + public string Image { get; set; } + + public string StoreId { get; set; } + } + + public class QuanTan_Supplier_ProductListResponse + { + public int Count { get; set; } + + public int Page { get; set; } + + public int PageSize { get; set; } + + public IList List { get; set; } + } +} diff --git a/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductSkuListResponse.cs b/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductSkuListResponse.cs new file mode 100644 index 0000000..6d1786e --- /dev/null +++ b/QuanTan.SDK/Models/Supplier/Response/Product/QuanTan_Supplier_ProductSkuListResponse.cs @@ -0,0 +1,32 @@ +namespace QuanTan.SDK.Models.Supplier +{ + public class QuanTan_Supplier_ProductSku + { + public string ProductId { get; set; } + + public string ProductName { get; set; } + + public string ProductSku { get; set; } + + public string SkuName { get; set; } + + public string SkuImage { get; set; } + + public decimal SkuPrice { get; set; } + + public string CategoryId { get; set; } + + public string StoreId { get; set; } + } + + public class QuanTan_Supplier_ProductSkuListResponse + { + public int Count { get; set; } + + public int Page { get; set; } + + public int PageSize { get; set; } + + public IList List { get; set; } + } +} diff --git a/QuanTan.SDK/QuanTan.SDK.csproj b/QuanTan.SDK/QuanTan.SDK.csproj new file mode 100644 index 0000000..5c53a2f --- /dev/null +++ b/QuanTan.SDK/QuanTan.SDK.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/SDKAdapter/BasePlatformRequest.cs b/SDKAdapter/BasePlatformRequest.cs new file mode 100644 index 0000000..e0f9af2 --- /dev/null +++ b/SDKAdapter/BasePlatformRequest.cs @@ -0,0 +1,17 @@ +using SDKAdapter.PurchasePlatform.Models; + +namespace SDKAdapter +{ + public class BasePlatformRequest + { + public AdapterEnums.PlatformType Platform { get; set; } + + public string AppKey { get; set; } + + public string AppSecret { get; set; } + + public string AppToken { get; set; } + + public bool SaveResponseLog { get; set; } + } +} diff --git a/SDKAdapter/OperationPlatform/Client/Base/OP_PlatformClient.cs b/SDKAdapter/OperationPlatform/Client/Base/OP_PlatformClient.cs new file mode 100644 index 0000000..a16c414 --- /dev/null +++ b/SDKAdapter/OperationPlatform/Client/Base/OP_PlatformClient.cs @@ -0,0 +1,31 @@ +using BBWYB.Common.Http; +using SDKAdapter.OperationPlatform.Models; +using SDKAdapter.PurchasePlatform.Models; + +namespace SDKAdapter.OperationPlatform.Client +{ + /// + /// 运营平台通用SDK + /// + public class OP_PlatformClient + { + protected RestApiService restApiService { get; private set; } + + public virtual AdapterEnums.PlatformType Platform { get; } + + public OP_PlatformClient(RestApiService restApiService) + { + this.restApiService = restApiService; + } + + public virtual OP_ProductListResponse GetProductList(OP_SearchProductRequest searchProductRequest) + { + throw new NotImplementedException(); + } + + public virtual OP_ProductSkuListResponse GetProductSkuList(OP_SearchProductSkuRequest searchProductSkuRequest) + { + throw new NotImplementedException(); + } + } +} diff --git a/SDKAdapter/OperationPlatform/Client/Base/OP_PlatformClientFactory.cs b/SDKAdapter/OperationPlatform/Client/Base/OP_PlatformClientFactory.cs new file mode 100644 index 0000000..13489e7 --- /dev/null +++ b/SDKAdapter/OperationPlatform/Client/Base/OP_PlatformClientFactory.cs @@ -0,0 +1,26 @@ +using BBWYB.Common.Http; +using BBWYB.Common.Models; +using SDKAdapter.PurchasePlatform.Models; + +namespace SDKAdapter.OperationPlatform.Client +{ + public class OP_PlatformClientFactory + { + private IList clients; + + public OP_PlatformClientFactory(RestApiService restApiService) + { + clients = new List(); + clients.Add(new OP_JDClient(restApiService)); + clients.Add(new OP_QuanTanClient(restApiService)); + } + + public OP_PlatformClient GetClient(AdapterEnums.PlatformType platform) + { + var client = clients.FirstOrDefault(c => c.Platform == platform); + if (client == null) + throw new Exception("不支持的平台"); + return client; + } + } +} diff --git a/SDKAdapter/OperationPlatform/Client/Impl/OP_JDClient.cs b/SDKAdapter/OperationPlatform/Client/Impl/OP_JDClient.cs new file mode 100644 index 0000000..ce7b515 --- /dev/null +++ b/SDKAdapter/OperationPlatform/Client/Impl/OP_JDClient.cs @@ -0,0 +1,14 @@ +using BBWYB.Common.Http; +using SDKAdapter.PurchasePlatform.Models; + +namespace SDKAdapter.OperationPlatform.Client +{ + public class OP_JDClient : OP_PlatformClient + { + public OP_JDClient(RestApiService restApiService) : base(restApiService) + { + } + + public override AdapterEnums.PlatformType Platform => AdapterEnums.PlatformType.京东; + } +} diff --git a/SDKAdapter/OperationPlatform/Client/Impl/OP_QuanTanClient.cs b/SDKAdapter/OperationPlatform/Client/Impl/OP_QuanTanClient.cs new file mode 100644 index 0000000..1ae90e8 --- /dev/null +++ b/SDKAdapter/OperationPlatform/Client/Impl/OP_QuanTanClient.cs @@ -0,0 +1,78 @@ +using BBWYB.Common.Http; +using QuanTan.SDK.Client.Supplier; +using QuanTan.SDK.Models.Supplier; +using SDKAdapter.OperationPlatform.Models; +using SDKAdapter.PurchasePlatform.Models; + +namespace SDKAdapter.OperationPlatform.Client +{ + public class OP_QuanTanClient : OP_PlatformClient + { + private QuanTan_Supplier_ProductClient supplier_ProductClient; + + public OP_QuanTanClient(RestApiService restApiService) : base(restApiService) + { + this.supplier_ProductClient = new QuanTan_Supplier_ProductClient(restApiService); + } + + public override AdapterEnums.PlatformType Platform => AdapterEnums.PlatformType.拳探; + + public override OP_ProductListResponse GetProductList(OP_SearchProductRequest searchProductRequest) + { + var qtResponse = supplier_ProductClient.GetProductList(new QuanTan_Supplier_SearchSpuRequest() + { + page = searchProductRequest.PageIndex, + pageSize = searchProductRequest.PageSize, + productId = searchProductRequest.Spu, + storeId = searchProductRequest.AppToken + }, searchProductRequest.AppKey, searchProductRequest.AppSecret); + + if (qtResponse.Status != 200) + throw new Exception(qtResponse.Message); + + return new OP_ProductListResponse() + { + Count = qtResponse.Data.Count, + Items = qtResponse.Data.List.Select(qtp => new OP_ProductResponse() + { + Id = qtp.ProductId, + BrandName = string.Empty, + CreateTime = null, + Logo = qtp.Image, + ProductItemNum = string.Empty, + State = 0, + Title = qtp.ProductName + }).ToList() + }; + } + + public override OP_ProductSkuListResponse GetProductSkuList(OP_SearchProductSkuRequest searchProductSkuRequest) + { + var qtResponse = supplier_ProductClient.GetProductSkuList(new QuanTan_Supplier_SearchSkuRequest() + { + page = searchProductSkuRequest.PageIndex, + pageSize = searchProductSkuRequest.PageSize, + storeId = searchProductSkuRequest.AppToken, + productId = searchProductSkuRequest.Spu + }, searchProductSkuRequest.AppKey, searchProductSkuRequest.AppSecret); + + if (qtResponse.Status != 200) + throw new Exception(qtResponse.Message); + + return new OP_ProductSkuListResponse() + { + Count = qtResponse.Data.Count, + Items = qtResponse.Data.List.Select(qtps => new OP_ProductSkuResponse() + { + CreateTime = null, + Id = qtps.ProductSku, + Logo = qtps.SkuImage, + Price = qtps.SkuPrice, + ProductId = qtps.ProductId, + State = 0, + Title = qtps.SkuName + }).ToList() + }; + } + } +} diff --git a/SDKAdapter/OperationPlatform/Models/Request/OP_SearchProductRequest.cs b/SDKAdapter/OperationPlatform/Models/Request/OP_SearchProductRequest.cs new file mode 100644 index 0000000..b141648 --- /dev/null +++ b/SDKAdapter/OperationPlatform/Models/Request/OP_SearchProductRequest.cs @@ -0,0 +1,19 @@ +namespace SDKAdapter.OperationPlatform.Models +{ + public class OP_SearchProductRequest : BasePlatformRequest + { + + public string Spu { get; set; } + + /// + /// 货号 + /// + public string ProductItem { get; set; } + + public string ProductName { get; set; } + + public int PageIndex { get; set; } + + public int PageSize { get; set; } + } +} diff --git a/SDKAdapter/OperationPlatform/Models/Request/OP_SearchProductSkuRequest.cs b/SDKAdapter/OperationPlatform/Models/Request/OP_SearchProductSkuRequest.cs new file mode 100644 index 0000000..922120e --- /dev/null +++ b/SDKAdapter/OperationPlatform/Models/Request/OP_SearchProductSkuRequest.cs @@ -0,0 +1,19 @@ +namespace SDKAdapter.OperationPlatform.Models +{ + public class OP_SearchProductSkuRequest : BasePlatformRequest + { + /// + /// 当Spu有值时会忽略Sku + /// + public string Spu { get; set; } + + /// + /// 多个Sku逗号间隔 + /// + public string Sku { get; set; } + + public int PageIndex { get; set; } + + public int PageSize { get; set; } + } +} diff --git a/SDKAdapter/OperationPlatform/Models/Response/OP_ProductResponse.cs b/SDKAdapter/OperationPlatform/Models/Response/OP_ProductResponse.cs new file mode 100644 index 0000000..77e4a9b --- /dev/null +++ b/SDKAdapter/OperationPlatform/Models/Response/OP_ProductResponse.cs @@ -0,0 +1,77 @@ +namespace SDKAdapter.OperationPlatform.Models +{ + public class OP_ProductResponse + { + /// + /// 商品Id + /// + public string Id { get; set; } + + /// + /// 商品货号 + /// + public string ProductItemNum { get; set; } + + /// + /// 商品标题 + /// + public string Title { get; set; } + + /// + /// 商品状态 + /// 京东【-1:删除 1:从未上架 2:自主下架 4:系统下架 8:上架 513:从未上架待审 514:自主下架待审 516:系统下架待审 520:上架待审核 1028:系统下架审核失败】 + /// + public int State { get; set; } + + public DateTime? CreateTime { get; set; } + + public string Logo { get; set; } + + /// + /// 商品品牌名称 + /// + public string BrandName { get; set; } + } + + public class OP_ProductListResponse + { + public int Count { get; set; } + + public IList Items { get; set; } + } + + public class OP_ProductSkuResponse + { + public string Id { get; set; } + + public string ProductId { get; set; } + + public decimal Price { get; set; } + + /// + /// Sku标题 + /// + public string Title { get; set; } + + public string Logo { get; set; } + + /// + /// Sku状态 + /// + /// 京东【1:上架 2:下架 4:删除】 + /// + /// + public int State { get; set; } + + public DateTime? CreateTime { get; set; } + + //public JToken Source { get; set; } + } + + public class OP_ProductSkuListResponse + { + public int Count { get; set; } + + public IList Items { get; set; } + } +} diff --git a/SDKAdapter/PurchasePlatform/Models/AdapterEnums.cs b/SDKAdapter/PurchasePlatform/Models/AdapterEnums.cs new file mode 100644 index 0000000..34b969b --- /dev/null +++ b/SDKAdapter/PurchasePlatform/Models/AdapterEnums.cs @@ -0,0 +1,15 @@ +namespace SDKAdapter.PurchasePlatform.Models +{ + public class AdapterEnums + { + public enum PlatformType + { + 淘宝 = 0, + 京东 = 1, + 阿里巴巴 = 2, + 拼多多 = 3, + 微信 = 4, + 拳探 = 10 + } + } +} diff --git a/SDKAdapter/PurchasePlatform/PurchasePlatformSDK.cs b/SDKAdapter/PurchasePlatform/PurchasePlatformSDK.cs new file mode 100644 index 0000000..6cdf9d7 --- /dev/null +++ b/SDKAdapter/PurchasePlatform/PurchasePlatformSDK.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SDKAdapter.PurchasePlatform +{ + internal class PurchasePlatformSDK + { + } +} diff --git a/SDKAdapter/SDKAdapter.csproj b/SDKAdapter/SDKAdapter.csproj index 132c02c..bdec773 100644 --- a/SDKAdapter/SDKAdapter.csproj +++ b/SDKAdapter/SDKAdapter.csproj @@ -4,6 +4,17 @@ net6.0 enable enable + True + + + + + + + + + + diff --git a/bbwyb.sln b/bbwyb.sln index d10c859..51bc4af 100644 --- a/bbwyb.sln +++ b/bbwyb.sln @@ -23,7 +23,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SJ.Controls", "SJ.Controls\ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SDK", "SDK", "{B4ED118A-2CFF-4E8F-B395-608E90C6D0C2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDKAdapter", "SDKAdapter\SDKAdapter.csproj", "{442CC858-3A90-48EE-932D-756169EAC2A4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDKAdapter", "SDKAdapter\SDKAdapter.csproj", "{442CC858-3A90-48EE-932D-756169EAC2A4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuanTan.SDK", "QuanTan.SDK\QuanTan.SDK.csproj", "{D5D93778-14D7-45F7-A77C-397FDBA408A1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "C", "C", "{AE01E0D8-FE79-4E30-B68F-862A5907EB3A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "B", "B", "{0142C6AF-5824-4665-8E9E-3A3C547BA109}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -59,18 +65,24 @@ Global {442CC858-3A90-48EE-932D-756169EAC2A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {442CC858-3A90-48EE-932D-756169EAC2A4}.Release|Any CPU.ActiveCfg = Release|Any CPU {442CC858-3A90-48EE-932D-756169EAC2A4}.Release|Any CPU.Build.0 = Release|Any CPU + {D5D93778-14D7-45F7-A77C-397FDBA408A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D5D93778-14D7-45F7-A77C-397FDBA408A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D5D93778-14D7-45F7-A77C-397FDBA408A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D5D93778-14D7-45F7-A77C-397FDBA408A1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {B6039632-07B7-4C74-9F74-F16B6782EF56} = {99D234A0-6830-4C0C-91E8-C626DA939D59} + {1E7D36DB-A817-4208-8FC6-36A66FAB17E5} = {0142C6AF-5824-4665-8E9E-3A3C547BA109} {D52D0167-EF94-4FC8-91BF-FCE5B3ED9C6A} = {1E7D36DB-A817-4208-8FC6-36A66FAB17E5} {52DF7178-3C36-4CA6-A2E9-D9E2BB41C0B8} = {99D234A0-6830-4C0C-91E8-C626DA939D59} {5707BF58-3A98-4283-A6D0-3B78EF7ED2F1} = {99D234A0-6830-4C0C-91E8-C626DA939D59} {DD328472-01CE-4CA8-AF29-C098FC499483} = {1191C1AE-7275-4643-AF24-BEC852717299} - {0415B31B-5A4E-4F7C-9F3B-69CB6284E4F1} = {1E7D36DB-A817-4208-8FC6-36A66FAB17E5} + {0415B31B-5A4E-4F7C-9F3B-69CB6284E4F1} = {1191C1AE-7275-4643-AF24-BEC852717299} {442CC858-3A90-48EE-932D-756169EAC2A4} = {B4ED118A-2CFF-4E8F-B395-608E90C6D0C2} + {D5D93778-14D7-45F7-A77C-397FDBA408A1} = {B4ED118A-2CFF-4E8F-B395-608E90C6D0C2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0D069898-04B7-4D24-A6A4-D7C703B8BFFC}