diff --git a/BBWY.Client/APIServices/BatchPurchaseService.cs b/BBWY.Client/APIServices/BatchPurchaseService.cs index 237f9eb5..3575cd39 100644 --- a/BBWY.Client/APIServices/BatchPurchaseService.cs +++ b/BBWY.Client/APIServices/BatchPurchaseService.cs @@ -1,4 +1,5 @@ using BBWY.Client.Models; +using BBWY.Client.Models.QiKu; using BBWY.Common.Http; using BBWY.Common.Models; using System; @@ -71,7 +72,8 @@ namespace BBWY.Client.APIServices PurchaseOrderMode purchaseOrderMode, IList purchaseAccountList, string extensions, - string remark) + string remark, + IList packSkuConfigList) { var productParamList = new List(); foreach (var productSkuWithScheme in productSkuWithSchemeList) @@ -93,8 +95,7 @@ namespace BBWY.Client.APIServices BelongSkuTitle = productSkuWithScheme.Title, BelongLogo = productSkuWithScheme.Logo, BelongQuantity = productSkuWithScheme.Quantity, - BelongPurchaseSchemeId = productSkuWithScheme.PurchaseSchemeId, - + BelongPurchaseSchemeId = productSkuWithScheme.PurchaseSchemeId }); } } @@ -109,7 +110,8 @@ namespace BBWY.Client.APIServices remark, autoPay, globalContext.User.Shop.ShopId, - globalContext.User.Shop.ShopName + globalContext.User.Shop.ShopName, + packSkuConfigList }, null, HttpMethod.Post); } diff --git a/BBWY.Client/APIServices/LogisticsService.cs b/BBWY.Client/APIServices/LogisticsService.cs index 347484ad..fc6e67ff 100644 --- a/BBWY.Client/APIServices/LogisticsService.cs +++ b/BBWY.Client/APIServices/LogisticsService.cs @@ -20,5 +20,16 @@ namespace BBWY.Client.APIServices globalContext.User.Shop.AppToken }, null, HttpMethod.Post); } + + public ApiResponse> GetStoreList() + { + return SendRequest>(globalContext.BBYWApiHost, "api/vender/GetStoreHouseList", new + { + globalContext.User.Shop.Platform, + globalContext.User.Shop.AppKey, + globalContext.User.Shop.AppSecret, + globalContext.User.Shop.AppToken + }, null, HttpMethod.Post); + } } } diff --git a/BBWY.Client/App.xaml.cs b/BBWY.Client/App.xaml.cs index ed5c0cd0..e749423e 100644 --- a/BBWY.Client/App.xaml.cs +++ b/BBWY.Client/App.xaml.cs @@ -122,6 +122,7 @@ namespace BBWY.Client serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); + serviceCollection.AddTransient(); #region 注册拳探SDK相关类 serviceCollection.AddSingleton(); diff --git a/BBWY.Client/Models/APIModel/Response/Logistics/StoreResponse.cs b/BBWY.Client/Models/APIModel/Response/Logistics/StoreResponse.cs new file mode 100644 index 00000000..8ed924cf --- /dev/null +++ b/BBWY.Client/Models/APIModel/Response/Logistics/StoreResponse.cs @@ -0,0 +1,18 @@ +using System; + +namespace BBWY.Client.Models +{ + public class StoreResponse + { + public DateTime? CreateTime { get; set; } + public string Id { get; set; } + + public string Name { get; set; } + + public Platform Platform { get; set; } + + public StockStatus Status { get; set; } + + public StockType Type { get; set; } + } +} diff --git a/BBWY.Client/Models/Enums.cs b/BBWY.Client/Models/Enums.cs index 61fd6544..42c855db 100644 --- a/BBWY.Client/Models/Enums.cs +++ b/BBWY.Client/Models/Enums.cs @@ -402,6 +402,22 @@ 胶带 = 2, 其他 = 3 } + + /// + /// 京东仓库类型 1商家仓 2京东仓 + /// + public enum StockType + { + 商家仓 = 1, 京仓 = 2 + } + + /// + /// 仓库状态 0暂停,1使用 + /// + public enum StockStatus + { + 暂停 = 0, 使用 = 1 + } public enum PackCerState { 合格证信息 = 0, 无需合格证 = 1 diff --git a/BBWY.Client/Models/QiKu/PackSkuConfig.cs b/BBWY.Client/Models/QiKu/PackSkuConfig.cs new file mode 100644 index 00000000..d02c3370 --- /dev/null +++ b/BBWY.Client/Models/QiKu/PackSkuConfig.cs @@ -0,0 +1,49 @@ +using System.Collections.ObjectModel; + +namespace BBWY.Client.Models.QiKu +{ + public class PackSkuConfig : NotifyObject + { + public PackSkuConfig() + { + PackSkuSplitConfigList = new ObservableCollection(); + } + + private int splitCount; + private string remarkMessage; + + public string SkuId { get; set; } + + public string Logo { get; set; } + + public string Title { get; set; } + + + + /// + /// 采购数量 + /// + public int PurchaseCount { get; set; } + + /// + /// 分箱数量 + /// + public int SplitCount { get => splitCount; set { Set(ref splitCount, value); } } + + public string RemarkMessage { get => remarkMessage; set { Set(ref remarkMessage, value); } } + + public ObservableCollection PackSkuSplitConfigList { get; set; } + } + + public class PackSkuSplitConfig : NotifyObject + { + private int packCount; + private StoreResponse store; + + public int Index { get; set; } + + public int PackCount { get => packCount; set { Set(ref packCount, value); } } + + public StoreResponse Store { get => store; set { Set(ref store, value); } } + } +} diff --git a/BBWY.Client/ViewModels/BatchPurchase/BatchPurchaseCreateNewOrderViewModel.cs b/BBWY.Client/ViewModels/BatchPurchase/BatchPurchaseCreateNewOrderViewModel.cs index 200c9cb5..0b1fd1ac 100644 --- a/BBWY.Client/ViewModels/BatchPurchase/BatchPurchaseCreateNewOrderViewModel.cs +++ b/BBWY.Client/ViewModels/BatchPurchase/BatchPurchaseCreateNewOrderViewModel.cs @@ -1,5 +1,6 @@ using BBWY.Client.APIServices; using BBWY.Client.Models; +using BBWY.Client.Models.QiKu; using BBWY.Client.Views.BatchPurchase; using BBWY.Common.Trigger; using GalaSoft.MvvmLight.Command; @@ -194,6 +195,22 @@ namespace BBWY.Client.ViewModels return; } + IList packSkuConfigList = null; + var isContainsQT = ProductSkuWithSchemeList.Any(ps => ps.PurchasePlatform == Platform.拳探); + if (isContainsQT) + { + var packWindow = new PackSkuConfigWindow(ProductSkuWithSchemeList.Where(ps => ps.PurchasePlatform == Platform.拳探).Select(ps => new PackSkuConfig() + { + Logo = ps.Logo, + SkuId = ps.SkuId, + Title = ps.Title, + PurchaseCount = ps.Quantity + }).ToList()); + + if (packWindow.ShowDialog() != true) + return; + packSkuConfigList = packWindow.GetPackSkuConfigList(); + } IsLoading = true; Task.Factory.StartNew(() => batchPurchaseService.CreateOrder(ProductSkuWithSchemeList, @@ -211,7 +228,8 @@ namespace BBWY.Client.ViewModels this.PurchaseOrderMode, globalContext.User.Shop.PurchaseAccountList, this.extensions, - this.PurchaseRemark)).ContinueWith(t => + this.PurchaseRemark, + packSkuConfigList)).ContinueWith(t => { IsLoading = false; var response = t.Result; @@ -375,5 +393,7 @@ namespace BBWY.Client.ViewModels if (purchaseSchemeProductSku.ItemTotal > 1) purchaseSchemeProductSku.ItemTotal--; } + + } } diff --git a/BBWY.Client/ViewModels/PackTask/PublishTaskViewModel.cs b/BBWY.Client/ViewModels/PackTask/PublishTaskViewModel.cs index 18170d99..8d6325a6 100644 --- a/BBWY.Client/ViewModels/PackTask/PublishTaskViewModel.cs +++ b/BBWY.Client/ViewModels/PackTask/PublishTaskViewModel.cs @@ -185,7 +185,7 @@ namespace BBWY.Client.ViewModels.PackTask { Set(ref isSetBarCode, value); - // IsNeedBarCode = IsSetBarCode ? Need.不需要 : Need.需要; + // IsNeedBarCode = IsSetBarCode ? Need.不需要 : Need.需要; } } @@ -199,7 +199,7 @@ namespace BBWY.Client.ViewModels.PackTask { Set(ref isSetCertificate, value); - //IsNeedCertificateModel = IsSetCertificate ? Need.不需要 : Need.需要; + //IsNeedCertificateModel = IsSetCertificate ? Need.不需要 : Need.需要; } } private string setSpuCerStatus; @@ -330,7 +330,7 @@ namespace BBWY.Client.ViewModels.PackTask { return; } - if (TaskId>0&&string.IsNullOrEmpty(SpuId))//修改界面刷新配置数据 + if (TaskId > 0 && string.IsNullOrEmpty(SpuId))//修改界面刷新配置数据 { SearchSku(SkuId); } @@ -375,7 +375,7 @@ namespace BBWY.Client.ViewModels.PackTask ProductNo = ProductNo, Brand = Brand, SkuId = SkuId, - + } }; @@ -452,7 +452,7 @@ namespace BBWY.Client.ViewModels.PackTask } var productSku = packTaskService.GetProductSku(skuid); - if (productSku == null || !productSku.Success||productSku.Data==null) + if (productSku == null || !productSku.Success || productSku.Data == null) return; BrandName = productSku.Data.BrandName; CertificateModel = productSku.Data.Cers; @@ -461,7 +461,7 @@ namespace BBWY.Client.ViewModels.PackTask CertificateModel = new CertificateModel[] { new CertificateModel{ } }; - + } foreach (var item in CertificateModel) @@ -504,7 +504,7 @@ namespace BBWY.Client.ViewModels.PackTask IsNeedCertificateModel = config.NeedCer ? Need.需要 : Need.不需要; IsSetBarCode = !config.NeedBar; - IsSetCertificate =!config.NeedCer; + IsSetCertificate = !config.NeedCer; bool isSelected = false; foreach (var item in increates) @@ -533,7 +533,7 @@ namespace BBWY.Client.ViewModels.PackTask return; } - //加载配置文件 + //加载配置文件 } public void SearSpuCer() @@ -591,7 +591,7 @@ namespace BBWY.Client.ViewModels.PackTask IsSetBarCode = true; IsSetCertificate = true; BarCodeModel = null; - + CertificateModel = null; SkuTitle = string.Empty; GoodsNumber = 0; @@ -651,7 +651,7 @@ namespace BBWY.Client.ViewModels.PackTask }); }); } - // SearchSku(SkuId); + // SearchSku(SkuId); } private void OpenSkuDetail(object param) @@ -713,14 +713,14 @@ namespace BBWY.Client.ViewModels.PackTask SkuCount = SkuCount, UserId = globalContext.User.Id.ToString(), ShopId = globalContext.User.Shop.ShopId.ToString(), - NeedBar =IsNeedBarCode==Need.需要, - NeedCer =IsNeedCertificateModel==Need.需要 - + NeedBar = IsNeedBarCode == Need.需要, + NeedCer = IsNeedCertificateModel == Need.需要 + //IsWorry = IsWorry }; if (IsNeedBarCode == Need.需要) { - if (BarCodeModel == null ||IsSetBarCode|| BarCodeModel.Id <= 0) + if (BarCodeModel == null || IsSetBarCode || BarCodeModel.Id <= 0) { new TipsWindow("请设置条形码模板").Show(); return; @@ -738,12 +738,12 @@ namespace BBWY.Client.ViewModels.PackTask { createTaskModel.CertificateId = CertificateModel.Where(c => c.Id > 0).FirstOrDefault()?.Id; } - catch + catch { - + } - + createTaskModel.CerId = string.Join(",", CertificateModel.Where(c => c.Id > 0).Select(c => c.Id));// } ApiResponse res = null; diff --git a/BBWY.Client/ViewModels/QiKu/PackSkuSplitConfigViewModel.cs b/BBWY.Client/ViewModels/QiKu/PackSkuSplitConfigViewModel.cs new file mode 100644 index 00000000..324ef251 --- /dev/null +++ b/BBWY.Client/ViewModels/QiKu/PackSkuSplitConfigViewModel.cs @@ -0,0 +1,105 @@ +using BBWY.Client.APIServices; +using BBWY.Client.Models; +using BBWY.Client.Models.QiKu; +using BBWY.Client.Views.BatchPurchase; +using GalaSoft.MvvmLight.Command; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Windows; +using System.Windows.Input; + +namespace BBWY.Client.ViewModels +{ + public class PackSkuSplitConfigViewModel : BaseVM + { + public IList PackSkuConfigList { get; set; } + + private IList storeList; + + public ICommand SetSplitCountCommand { get; set; } + + public ICommand SetPackCountAndStoreCommand { get; set; } + + public ICommand SaveCommand { get; set; } + + private LogisticsService logisticsService; + + public PackSkuSplitConfigViewModel(LogisticsService logisticsService) + { + this.logisticsService = logisticsService; + SetSplitCountCommand = new RelayCommand(SetSplitCount); + SetPackCountAndStoreCommand = new RelayCommand(SetPackCountAndStore); + SaveCommand = new RelayCommand(Save); + PackSkuConfigList = new ObservableCollection(); + } + + public void SetData(IList packSkuConfigList) + { + foreach (var item in packSkuConfigList) + PackSkuConfigList.Add(item); + } + + public IList GetPackSkuConfigList() + { + return PackSkuConfigList; + } + + private void SetSplitCount(PackSkuConfig packSkuConfig) + { + if (packSkuConfig.SplitCount <= 0) + { + MessageBox.Show("份数不正确"); + return; + } + + packSkuConfig.PackSkuSplitConfigList.Clear(); + for (var i = 1; i <= packSkuConfig.SplitCount; i++) + { + packSkuConfig.PackSkuSplitConfigList.Add(new PackSkuSplitConfig() + { + Index = i, + PackCount = 0 + }); + } + } + + private void SetPackCountAndStore(PackSkuSplitConfig packSkuSplitConfig) + { + if (storeList == null) + { + var response = logisticsService.GetStoreList(); + if (!response.Success) + { + MessageBox.Show(response.Msg, "获取仓库"); + return; + } + storeList = response.Data; + } + var w = new PackSkuSplitCountAndStoreWindow(packSkuSplitConfig.PackCount, packSkuSplitConfig.Store, storeList); + if (w.ShowDialog() == true) + { + packSkuSplitConfig.PackCount = w.Quantity; + packSkuSplitConfig.Store = w.Store; + } + } + + private void Save() + { + if (PackSkuConfigList.Any(s => s.PackSkuSplitConfigList.Count() == 0 || + s.PackSkuSplitConfigList.Any(sp => sp.PackCount <= 0))) + { + MessageBox.Show("装箱设置不正确", "提示"); + return; + } + + if (PackSkuConfigList.Any(s => s.PurchaseCount != s.PackSkuSplitConfigList.Sum(sp => sp.PackCount))) + { + MessageBox.Show("打包份数总数与采购数量不相等", "提示"); + return; + } + + GalaSoft.MvvmLight.Messaging.Messenger.Default.Send(true, "PackSkuConfigWindowClose"); + } + } +} diff --git a/BBWY.Client/ViewModels/ViewModelLocator.cs b/BBWY.Client/ViewModels/ViewModelLocator.cs index 7a3489c0..980ebe4c 100644 --- a/BBWY.Client/ViewModels/ViewModelLocator.cs +++ b/BBWY.Client/ViewModels/ViewModelLocator.cs @@ -295,6 +295,15 @@ namespace BBWY.Client.ViewModels } } + public PackSkuSplitConfigViewModel PackSkuConfig + { + get + { + using var s = sp.CreateScope(); + return s.ServiceProvider.GetRequiredService(); + } + } + public QualityViewModel QualityTask { diff --git a/BBWY.Client/Views/BatchPurchase/BatchCreateNewPurchaseOrder.xaml b/BBWY.Client/Views/BatchPurchase/BatchCreateNewPurchaseOrder.xaml index 742f85bb..c98e7518 100644 --- a/BBWY.Client/Views/BatchPurchase/BatchCreateNewPurchaseOrder.xaml +++ b/BBWY.Client/Views/BatchPurchase/BatchCreateNewPurchaseOrder.xaml @@ -137,7 +137,7 @@ - + @@ -237,7 +237,7 @@ Height="18" Command="{Binding DataContext.SubtractQuantityCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" CommandParameter="{Binding }"/> - + diff --git a/BBWY.Client/Views/BatchPurchase/BatchPurchaseOrderList.xaml b/BBWY.Client/Views/BatchPurchase/BatchPurchaseOrderList.xaml index 108f6f48..2ea7916f 100644 --- a/BBWY.Client/Views/BatchPurchase/BatchPurchaseOrderList.xaml +++ b/BBWY.Client/Views/BatchPurchase/BatchPurchaseOrderList.xaml @@ -202,7 +202,7 @@ - + diff --git a/BBWY.Client/Views/BatchPurchase/PackSkuConfigWindow.xaml b/BBWY.Client/Views/BatchPurchase/PackSkuConfigWindow.xaml new file mode 100644 index 00000000..02dc735c --- /dev/null +++ b/BBWY.Client/Views/BatchPurchase/PackSkuConfigWindow.xaml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BBWY.Client/Views/BatchPurchase/PackSkuConfigWindow.xaml.cs b/BBWY.Client/Views/BatchPurchase/PackSkuConfigWindow.xaml.cs new file mode 100644 index 00000000..5a093730 --- /dev/null +++ b/BBWY.Client/Views/BatchPurchase/PackSkuConfigWindow.xaml.cs @@ -0,0 +1,44 @@ +using BBWY.Client.Models.QiKu; +using BBWY.Client.ViewModels; +using BBWY.Controls; +using System.Collections.Generic; + +namespace BBWY.Client.Views.BatchPurchase +{ + /// + /// PackSkuConfigWindow.xaml 的交互逻辑 + /// + public partial class PackSkuConfigWindow : BWindow + { + private PackSkuSplitConfigViewModel vm; + + public PackSkuConfigWindow(IList list) + { + InitializeComponent(); + vm = this.DataContext as PackSkuSplitConfigViewModel; + vm.SetData(list); + + this.Loaded += PackSkuConfigWindow_Loaded; + this.Unloaded += PackSkuConfigWindow_Unloaded; + } + + private void PackSkuConfigWindow_Unloaded(object sender, System.Windows.RoutedEventArgs e) + { + GalaSoft.MvvmLight.Messaging.Messenger.Default.Unregister(this); + } + + private void PackSkuConfigWindow_Loaded(object sender, System.Windows.RoutedEventArgs e) + { + GalaSoft.MvvmLight.Messaging.Messenger.Default.Register(this, "PackSkuConfigWindowClose", (r) => + { + this.DialogResult = r; + this.Close(); + }); + } + + public IList GetPackSkuConfigList() + { + return vm.GetPackSkuConfigList(); + } + } +} diff --git a/BBWY.Client/Views/BatchPurchase/PackSkuSplitCountAndStoreWindow.xaml b/BBWY.Client/Views/BatchPurchase/PackSkuSplitCountAndStoreWindow.xaml new file mode 100644 index 00000000..8ada0b01 --- /dev/null +++ b/BBWY.Client/Views/BatchPurchase/PackSkuSplitCountAndStoreWindow.xaml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BBWY.Client/Views/BatchPurchase/PackSkuSplitCountAndStoreWindow.xaml.cs b/BBWY.Client/Views/BatchPurchase/PackSkuSplitCountAndStoreWindow.xaml.cs new file mode 100644 index 00000000..b00651f8 --- /dev/null +++ b/BBWY.Client/Views/BatchPurchase/PackSkuSplitCountAndStoreWindow.xaml.cs @@ -0,0 +1,64 @@ +using BBWY.Client.Models; +using BBWY.Controls; +using System.Collections.Generic; +using System.Linq; +using System.Windows; + +namespace BBWY.Client.Views.BatchPurchase +{ + /// + /// PackSkuSplitCountAndStoreWindow.xaml 的交互逻辑 + /// + public partial class PackSkuSplitCountAndStoreWindow : BWindow + { + public int Quantity { get; set; } + + public StoreResponse Store { get; set; } + + private IList storeList; + + public PackSkuSplitCountAndStoreWindow(int quantity, StoreResponse store, IList storeList) + { + InitializeComponent(); + this.Quantity = quantity; + this.Store = store; + this.storeList = storeList; + this.Loaded += PackSkuSplitCountAndStoreWindow_Loaded; + } + + private void PackSkuSplitCountAndStoreWindow_Loaded(object sender, System.Windows.RoutedEventArgs e) + { + this.txtQuantity.Text = Quantity.ToString(); + this.cbx_stroeList.ItemsSource = storeList; + if (Store != null) + this.cbx_stroeList.SelectedItem = storeList.FirstOrDefault(s => s.Id == Store.Id); + else + this.cbx_stroeList.SelectedItem = storeList.FirstOrDefault(); + } + + private void btn_save_Click(object sender, System.Windows.RoutedEventArgs e) + { + if (!int.TryParse(txtQuantity.Text, out int q)) + { + MessageBox.Show("件数不正确", "提示"); + return; + } + if (q <= 0) + { + MessageBox.Show("件数不正确", "提示"); + return; + } + if (cbx_stroeList.SelectedItem == null) + { + MessageBox.Show("请选择一个仓库", "提示"); + return; + } + + this.Quantity = q; + this.Store = cbx_stroeList.SelectedItem as StoreResponse; + + this.DialogResult = true; + this.Close(); + } + } +} diff --git a/BBWY.Client/Views/MainWindow.xaml b/BBWY.Client/Views/MainWindow.xaml index ad6b9b1e..7122ab5f 100644 --- a/BBWY.Client/Views/MainWindow.xaml +++ b/BBWY.Client/Views/MainWindow.xaml @@ -26,7 +26,7 @@ - + diff --git a/BBWY.Common/Extensions/CopyExtensions.cs b/BBWY.Common/Extensions/CopyExtensions.cs new file mode 100644 index 00000000..d87833f3 --- /dev/null +++ b/BBWY.Common/Extensions/CopyExtensions.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace BBWY.Common.Extensions +{ + public static class CopyExtensions + { + public static T Copy(this T p) + { + return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(p)); + } + } +} diff --git a/BBWY.Server.API/Controllers/PurchaseOrderController.cs b/BBWY.Server.API/Controllers/PurchaseOrderController.cs index 1684f932..caf9b7c4 100644 --- a/BBWY.Server.API/Controllers/PurchaseOrderController.cs +++ b/BBWY.Server.API/Controllers/PurchaseOrderController.cs @@ -105,9 +105,20 @@ namespace BBWY.Server.API.Controllers /// [HttpPost] [AllowAnonymous] - public void QuanTanEditPriceCallback(QuanTanEditPriceNotifyRequest request) + public void QuanTanEditPriceCallback([FromBody] QuanTanEditPriceNotifyRequest request) { purchaseOrderBusiness.QuanTanEditPriceCallback(request); } + + /// + /// 签收采购单 + /// + /// + [HttpPost] + [AllowAnonymous] + public void SignPurchaseOrder([FromBody] BBWYBSignCallBackRequest request) + { + purchaseOrderBusiness.SignPurchaseOrder(request); + } } } diff --git a/BBWY.Server.API/Controllers/PurchaseSchemeController.cs b/BBWY.Server.API/Controllers/PurchaseSchemeController.cs index 64e35246..80ea4cd7 100644 --- a/BBWY.Server.API/Controllers/PurchaseSchemeController.cs +++ b/BBWY.Server.API/Controllers/PurchaseSchemeController.cs @@ -9,7 +9,7 @@ using System.Collections.Generic; namespace BBWY.Server.API.Controllers { - [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] + //[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] public class PurchaseSchemeController : BaseApiController { private PurchaseSchemeBusiness purchaseSchemeBusiness; @@ -70,5 +70,16 @@ namespace BBWY.Server.API.Controllers { return purchaseSchemeBusiness.GetSharePurchaser(querySchemeRequest); } + + /// + /// 批量修改拳探采购方案归属采购商 + /// + /// + /// + [HttpPost] + public IList BatchUpdateQTPurchaseSchemeBelongPurchaser([FromBody]BatchUpdateQTPurchaseSchemeBelongPurchaserRequest request) + { + return purchaseSchemeBusiness.BatchUpdateQTPurchaseSchemeBelongPurchaser(request); + } } } diff --git a/BBWY.Server.API/Controllers/VenderController.cs b/BBWY.Server.API/Controllers/VenderController.cs index 00b93147..336e77a9 100644 --- a/BBWY.Server.API/Controllers/VenderController.cs +++ b/BBWY.Server.API/Controllers/VenderController.cs @@ -1,5 +1,6 @@ using BBWY.Common.Models; using BBWY.Server.Business; +using BBWY.Server.Model.Db; using BBWY.Server.Model.Dto; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; @@ -109,9 +110,20 @@ namespace BBWY.Server.API.Controllers /// /// [HttpPost] - public IList GetServiceGroupList([FromBody]PlatformRequest request) + public IList GetServiceGroupList([FromBody] PlatformRequest request) { return venderBusiness.GetServiceGroupList(request); } + + /// + /// 获取店铺关联的仓库列表 + /// + /// + /// + [HttpPost] + public IList GetStoreHouseList([FromBody] PlatformRequest request) + { + return venderBusiness.GetStoreHouseList(request); + } } } diff --git a/BBWY.Server.API/Startup.cs b/BBWY.Server.API/Startup.cs index d136e508..97d916ca 100644 --- a/BBWY.Server.API/Startup.cs +++ b/BBWY.Server.API/Startup.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Serialization; +using QuanTan.SDK.Client; using System; using System.IO; using System.Linq; @@ -83,6 +84,10 @@ namespace BBWY.Server.API services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + + #region עȭ̽SDK + services.AddSingleton(); + #endregion //var stores = Configuration.GetSection("Stores").Get>(); services.Configure(Configuration.GetSection("GlobalSetting")); diff --git a/BBWY.Server.Business/PlatformSDK/QuanTanBusiness.cs b/BBWY.Server.Business/PlatformSDK/QuanTanBusiness.cs index a3b14c1c..c52a4bba 100644 --- a/BBWY.Server.Business/PlatformSDK/QuanTanBusiness.cs +++ b/BBWY.Server.Business/PlatformSDK/QuanTanBusiness.cs @@ -23,13 +23,13 @@ namespace BBWY.Server.Business public override PayPurchaseOrderResponse PayPurchaseOrder(PayPurchaseOrderRequest payPurchaseOrderRequest) { - + var qtResponse = quanTanOrderClient.PayOrder(new QuanTanPayOrderRequest { orderId = payPurchaseOrderRequest.OrderId, userAccount = payPurchaseOrderRequest.AppToken }, payPurchaseOrderRequest.AppKey, payPurchaseOrderRequest.AppSecret); - if (qtResponse.Status == 200) return new PayPurchaseOrderResponse { Success = true, PurchaseOrderState= PurchaseOrderState.待发货 }; + if (qtResponse.Status == 200) return new PayPurchaseOrderResponse { Success = true, PurchaseOrderState = PurchaseOrderState.待发货 }; if (qtResponse.Message != null && qtResponse.Message.Contains("已支付")) { @@ -163,7 +163,7 @@ namespace BBWY.Server.Business extended = JsonConvert.SerializeObject(new { BuyerAccount = createOnlinePurchaseOrderRequest.AppToken, - createOnlinePurchaseOrderRequest.SourceSku, + BelongSkus = createOnlinePurchaseOrderRequest.SourceSku, createOnlinePurchaseOrderRequest.SourceShopName }) }; diff --git a/BBWY.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs b/BBWY.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs index 31092f97..c86f3325 100644 --- a/BBWY.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs +++ b/BBWY.Server.Business/PurchaseOrder/PurchaseOrderBusiness.cs @@ -369,7 +369,7 @@ namespace BBWY.Server.Business #region CallBack - #region 1688CallBack + #region 1688 CallBack public void CallbackFrom1688(string jsonStr) { nLogManager.Default().Info(jsonStr); @@ -415,7 +415,7 @@ namespace BBWY.Server.Business } #endregion - #region 拳探回调 + #region QuanTan Callback public void QuanTanSendGoodsCallback(QuanTanSendGoodsNotifyRequest request) { Task.Factory.StartNew(() => DeliveryCallback(request.OrderId, new WayBillNoResponse() @@ -425,12 +425,12 @@ namespace BBWY.Server.Business WayBillNo = request.WayBillNo, }, Enums.Platform.拳探), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.PurchaseOrderCallbackTaskScheduler); - //Task.Factory.StartNew(() => DeliveryCallbackForPurchaseOrder(request.OrderId, new WayBillNoResponse() - //{ - // LogisticsCompanyId = request.ExpressId, - // LogisticsCompanyName = request.ExpressName, - // WayBillNo = request.WayBillNo, - //}, Enums.Platform.拳探), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.PurchaseOrderCallbackTaskScheduler); + Task.Factory.StartNew(() => DeliveryCallbackForPurchaseOrder(request.OrderId, new WayBillNoResponse() + { + LogisticsCompanyId = request.ExpressId, + LogisticsCompanyName = request.ExpressName, + WayBillNo = request.WayBillNo, + }, Enums.Platform.拳探), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.PurchaseOrderCallbackTaskScheduler); } public void QuanTanEditPriceCallback(QuanTanEditPriceNotifyRequest request) @@ -442,6 +442,19 @@ namespace BBWY.Server.Business } #endregion + #region bbwyb Callback + public void SignPurchaseOrder(BBWYBSignCallBackRequest request) + { + var pv2 = fsql.Select(request.OrderId).ToOne(); + if (pv2.OrderState == Enums.PurchaseOrderState.待收货) + { + fsql.Update(request.OrderId).Set(p => p.OrderState, Enums.PurchaseOrderState.待质检) + .Set(p => p.SignTime, DateTime.Now) + .ExecuteAffrows(); + } + } + #endregion + /// /// 采购平台发货回调(一件代发) /// @@ -572,6 +585,14 @@ namespace BBWY.Server.Business if (purchaseOrderV2 == null) throw new Exception("未查询到采购单信息"); + fsql.Update(purchaseOrderId).SetIf(purchaseOrderV2.OrderState == Enums.PurchaseOrderState.待发货 || + purchaseOrderV2.OrderState == Enums.PurchaseOrderState.待付款, + p => p.OrderState, Enums.PurchaseOrderState.待收货) + .Set(p => p.ExpressName, wayBillNoResponse.LogisticsCompanyName) + .Set(p => p.WaybillNo, wayBillNoResponse.WayBillNo) + .ExecuteAffrows(); + + } catch (Exception ex) { diff --git a/BBWY.Server.Business/PurchaseOrderV2/BatchPurchase/BatchPurchaseBusiness.cs b/BBWY.Server.Business/PurchaseOrderV2/BatchPurchase/BatchPurchaseBusiness.cs index 628c6e6b..b5cbc30b 100644 --- a/BBWY.Server.Business/PurchaseOrderV2/BatchPurchase/BatchPurchaseBusiness.cs +++ b/BBWY.Server.Business/PurchaseOrderV2/BatchPurchase/BatchPurchaseBusiness.cs @@ -1,4 +1,5 @@ -using BBWY.Common.Models; +using BBWY.Common.Http; +using BBWY.Common.Models; using BBWY.Server.Model; using BBWY.Server.Model.Db; using BBWY.Server.Model.Db.QK; @@ -9,6 +10,8 @@ using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http; +using System.Net.Mail; using System.Text; using System.Threading.Tasks; using Yitter.IdGenerator; @@ -19,18 +22,19 @@ namespace BBWY.Server.Business { private ProductBusiness productBusiness; private IEnumerable platformSDKBusinessList; - - + //private TaskSchedulerManager taskSchedulerManager; + private RestApiService restApiService; public BatchPurchaseBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, ProductBusiness productBusiness, - IEnumerable platformSDKBusinessList) : base(fsql, nLogManager, idGenerator) + IEnumerable platformSDKBusinessList, + RestApiService restApiService) : base(fsql, nLogManager, idGenerator) { this.productBusiness = productBusiness; this.platformSDKBusinessList = platformSDKBusinessList; - + this.restApiService = restApiService; } /// @@ -218,6 +222,7 @@ namespace BBWY.Server.Business var successSkuIdList = new List(); var failSkuList = new List(); + var qikuPackSkuConfigRequestList = new List(); var extJArray = JsonConvert.DeserializeObject(request.Extensions); var purchaseGroups = request.ProductParamList.GroupBy(p => p.PurchaserId); @@ -242,6 +247,19 @@ namespace BBWY.Server.Business else if (purchasePlatform == Enums.Platform.阿里巴巴) tradeMode = extJson.Value("OrderTradeTypeCode"); + + #region 处理JD SKU和拳探SKU的对应关系 + var belongSkus_mappingList = new List(); + foreach (var belongSkuGroup in belongSkuGroups) + { + var firstProductParam = belongSkuGroup.FirstOrDefault(); + if (!belongSkus_mappingList.Any(j => j.Value("BelongSkuId") == firstProductParam.BelongSkuId)) + { + belongSkus_mappingList.Add(JObject.FromObject(new { firstProductParam.BelongSkuId, SkuId = firstProductParam.PurchaseSkuId })); + } + } + #endregion + var createOrderResponse = platformSDKBusinessList.FirstOrDefault(p => p.Platform == purchasePlatform) .FastCreateOrder(new CreateOnlinePurchaseOrderRequest() { @@ -253,7 +271,7 @@ namespace BBWY.Server.Business PurchaseOrderMode = request.PurchaseOrderMode, Remark = request.Remark, SourceShopName = request.ShopName, - SourceSku = string.Join(",", belongSkuGroups.Select(g => g.Key)), + SourceSku = belongSkus_mappingList, CargoParamList = productParamList.Select(p => new CargoParamRequest() { ProductId = p.PurchaseProductId, @@ -279,6 +297,10 @@ namespace BBWY.Server.Business List updatePurchaseTimeSchemeIdList = productParamList.Select(p => p.BelongPurchaseSchemeId).Distinct().ToList(); List insertPurchaseOrderSkuList = new List(); + List skuPackConfigList = null; + if (purchasePlatform == Enums.Platform.拳探) + skuPackConfigList = new List(); + foreach (var belongSkuGroup in belongSkuGroups) { var firstProductParam = belongSkuGroup.FirstOrDefault(); @@ -308,6 +330,29 @@ namespace BBWY.Server.Business CreateTime = DateTime.Now }; insertPurchaseOrderSkuList.Add(purchaseOrderSku); + + + if (purchasePlatform == Enums.Platform.拳探) + { + var skuPackConfig = request.PackSkuConfigList?.FirstOrDefault(s => s.SkuId == firstProductParam.BelongSkuId); + + if (skuPackConfig != null) + { + + skuPackConfigList.Add(new + { + skuId = firstProductParam.BelongSkuId, + skuCount = skuPackConfig.PurchaseCount, + markMessage = skuPackConfig.RemarkMessage, + wareHourses = skuPackConfig.PackSkuSplitConfigList.Select(x => new + { + wareId = x.Store.Id, + wareName = x.Store.Name, + count = x.PackCount + }) + }); + } + } } var purchaseOrderV2 = new PurchaseOrderV2() @@ -345,6 +390,20 @@ namespace BBWY.Server.Business fsql.Update(updatePurchaseTimeSchemeIdList).Set(p => p.LastPurchaseTime, DateTime.Now).ExecuteAffrows(); }); successSkuIdList.AddRange(belongSkuGroups.Select(g => g.Key)); + + if (purchasePlatform == Enums.Platform.拳探) + { + qikuPackSkuConfigRequestList.Add(new + { + orderId = purchaseOrderV2.Id, + //shopId = request.ShopId.ToString(), + shopId = purchaseGroup.Key, //拳探店铺Id(商家Id) + originShopName = request.ShopName, + userName = purchaseAccount.AccountName, + platform = Enums.Platform.拳探, + purchaseTaskModels = skuPackConfigList + }); + } } catch (Exception ex) { @@ -357,6 +416,30 @@ namespace BBWY.Server.Business } } + if (qikuPackSkuConfigRequestList.Count() > 0) + { + Task.Factory.StartNew(() => + { + foreach (var qikuPackSkuConfigRequest in qikuPackSkuConfigRequestList) + { + try + { + var qikuResponse = restApiService.SendRequest("http://qiku.qiyue666.com/", + "api/PackPurchaseTask/BatchPublicPurchaseTask", + qikuPackSkuConfigRequest, + null, + HttpMethod.Post); + if (qikuResponse.StatusCode != System.Net.HttpStatusCode.OK) + throw new Exception(qikuResponse.Content); + } + catch (Exception ex) + { + nLogManager.GetLogger($"发布打包任务-{request.ShopName}").Error(ex, JsonConvert.SerializeObject(qikuPackSkuConfigRequest)); + } + } + }); + } + return new BatchCreareOrderResponse() { FailSkuList = failSkuList, @@ -466,12 +549,27 @@ namespace BBWY.Server.Business var platformSDKBusiness = platformSDKBusinessList.FirstOrDefault(p => p.Platform == request.Platform); var payOrderResponse = platformSDKBusiness.CancelPurchaseOrder(request); - if (payOrderResponse.Success) + if (payOrderResponse.Success)//取消成功 { //var order = fsql.Select().Where(p => p.Id == request.OrderId).ToOne(); fsql.Update(request.OrderId) .Set(po => po.OrderState, Enums.PurchaseOrderState.已取消) .ExecuteAffrows(); + try + { + var qikuResponse = restApiService.SendRequest("http://qiku.qiyue666.com/", + $"/api/PackPurchaseTask/CancelOrderPackTask?orderId={request.OrderId}", + null, + null, + HttpMethod.Post); + if (qikuResponse.StatusCode != System.Net.HttpStatusCode.OK) + throw new Exception(qikuResponse.Content); + } + catch (Exception ex) + { + nLogManager.GetLogger($"取消打包任务-{request.OrderId}").Error(ex, JsonConvert.SerializeObject(request)); + } + } diff --git a/BBWY.Server.Business/PurchaseScheme/PurchaseProductAPIService.cs b/BBWY.Server.Business/PurchaseScheme/PurchaseProductAPIService.cs new file mode 100644 index 00000000..c7cbf65b --- /dev/null +++ b/BBWY.Server.Business/PurchaseScheme/PurchaseProductAPIService.cs @@ -0,0 +1,301 @@ +using BBWY.Common.Extensions; +using BBWY.Common.Http; +using BBWY.Common.Models; +using BBWY.Server.Model; +using BBWY.Server.Model.Db; +using BBWY.Server.Model.Dto; +using Microsoft.Extensions.Caching.Memory; +using Newtonsoft.Json.Linq; +using QuanTan.SDK.Client; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text.RegularExpressions; + +namespace BBWY.Server.Business +{ + public class PurchaseProductAPIService : IDenpendency + { + private RestApiService restApiService; + private IMemoryCache memoryCache; + private string oneBoundKey = "t5060712539"; + private string oneBoundSecret = "20211103"; + + private string qtAppId = "BBWY2023022001"; + private string qtAppSecret = "908e131365d5448ca651ba20ed7ddefe"; + + private TimeSpan purchaseProductCacheTimeSpan; + //private TimeSpan _1688SessionIdTimeSpan; + + //private ConcurrentDictionary purchaseSchemeProductSkus)> productChaches; + + private IDictionary _1688ProductDetailRequestHeader; + private char[] skuPropertiesSplitChar = new char[] { ';' }; + private QuanTanProductClient quanTanProductClient; + + public PurchaseProductAPIService(RestApiService restApiService, IMemoryCache memoryCache, QuanTanProductClient quanTanProductClient) + { + this.memoryCache = memoryCache; + this.restApiService = restApiService; + _1688ProductDetailRequestHeader = new Dictionary() + { + { "Host","detail.1688.com"}, + { "User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70"}, + { "Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}, + { "Accept-Encoding","gzip, deflate, br"}, + { "Accept-Language","zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"} + }; + purchaseProductCacheTimeSpan = TimeSpan.FromDays(1); + this.quanTanProductClient = quanTanProductClient; + } + + public PurchaseSkuBasicInfoResponse GetProductInfo(PurchaseSkuBasicInfoRequest request) + { + var cacheKey = $"{request.PurchaseProductId}_{request.PriceMode}"; + if (memoryCache.TryGetValue(cacheKey, out var tuple)) + return tuple.Copy(); + + PurchaseSkuBasicInfoResponse response = null; + + if (request.FirstApiMode == Enums.PurchaseProductAPIMode.Spider) + { + response = LoadFromSpider(request); + if (response == null) + response = LoadFromOneBound(request); + } + else if (request.FirstApiMode == Enums.PurchaseProductAPIMode.OneBound) + { + response = LoadFromOneBound(request); + if (response == null) + response = LoadFromSpider(request); + } + + if (response != null) + { + try + { + memoryCache.Set(cacheKey, response, purchaseProductCacheTimeSpan); + } + catch { } + } + + return response?.Copy(); + } + + private PurchaseSkuBasicInfoResponse LoadFromOneBound(PurchaseSkuBasicInfoRequest request) + { + try + { + string platformStr = string.Empty; + if (request.Platform == Enums.Platform.阿里巴巴) + platformStr = "1688"; + + if (string.IsNullOrEmpty(platformStr)) + return null; + + var result = restApiService.SendRequest("https://api-gw.onebound.cn/", $"{platformStr}/item_get", $"key={oneBoundKey}&secret={oneBoundSecret}&num_iid={request.PurchaseProductId}&lang=zh-CN&cache=no&agent={(request.PriceMode == Enums.PurchaseOrderMode.批发 ? 0 : 1)}", null, HttpMethod.Get, paramPosition: ParamPosition.Query, enableRandomTimeStamp: true); + if (result.StatusCode != System.Net.HttpStatusCode.OK) + throw new Exception($"{result.StatusCode} {result.Content}"); + + var jobject = JObject.Parse(result.Content); + var isOK = jobject.Value("error_code") == "0000"; + if (isOK) + { + var skuJArray = (JArray)jobject["item"]["skus"]["sku"]; + if (skuJArray.Count == 0) + { + //errorMsg = $"商品{purchaseSchemeProduct.PurchaseProductId}缺少sku信息"; + return null; + } + + var list = skuJArray.Select(j => new PurchaseSkuItemBasicInfoResponse() + { + PurchaseProductId = request.PurchaseProductId, + Price = j.Value("price"), + PurchaseSkuId = j.Value("sku_id"), + PurchaseSkuSpecId = j.Value("spec_id"), + Title = j.Value("properties_name"), + Logo = GetOneBoundSkuLogo(j, (JArray)jobject["item"]["prop_imgs"]["prop_img"]) + }).ToList(); + + var purchaserId = jobject["item"]["seller_info"].Value("user_num_id"); + var purchaserName = jobject["item"]["seller_info"].Value("title"); + if (string.IsNullOrEmpty(purchaserName)) + purchaserName = jobject["item"]["seller_info"].Value("shop_name"); + var purchaserLocation = jobject["item"].Value("location"); + + return new PurchaseSkuBasicInfoResponse() + { + Purchaser = new Model.Db.Purchaser() + { + Id = purchaserId, + Location = purchaserLocation, + Name = purchaserName, + Platform = request.Platform + }, + ItemList = list, + PurchasePlatform = request.Platform, + PurchaseProductId = request.PurchaseProductId + }; + } + } + catch { } + { + return null; + } + } + + private string GetOneBoundSkuLogo(JToken skuJToken, JArray prop_img) + { + if (!prop_img.HasValues) + return "pack://application:,,,/Resources/Images/defaultItem.png"; + var properties = skuJToken.Value("properties").Split(skuPropertiesSplitChar, StringSplitOptions.RemoveEmptyEntries); + foreach (var p in properties) + { + var imgJToken = prop_img.FirstOrDefault(g => g.Value("properties") == p); + if (imgJToken != null) + return imgJToken.Value("url"); + } + return "pack://application:,,,/Resources/Images/defaultItem.png"; + } + + private PurchaseSkuBasicInfoResponse LoadFromSpider(PurchaseSkuBasicInfoRequest request) + { + switch (request.Platform) + { + case Enums.Platform.阿里巴巴: + return LoadFrom1688Spider(request); + case Enums.Platform.拳探: + return LoadFromQTSpider(request); + } + return null; + } + + private PurchaseSkuBasicInfoResponse LoadFrom1688Spider(PurchaseSkuBasicInfoRequest request) + { + //https://detail.1688.com/offer/672221374773.html?clickid=65f3772cd5d16f190ce4991414607&sessionid=3de47a0c26dcbfde4692064bd55861&sk=order + + //globalData/tempModel/sellerUserId + //globalData/tempModel/companyName + //data/1081181309101/data/location + + + //data/1081181309582/data/pirceModel/[currentPrices]/[0]price + + try + { + var _1688pageResult = restApiService.SendRequest("https://detail.1688.com", + $"offer/{request.PurchaseProductId}.html", + $"clickid={Guid.NewGuid().ToString().Md5Encrypt()}&sessionid={Guid.NewGuid().ToString().Md5Encrypt()}&sk={(request.PriceMode == Enums.PurchaseOrderMode.批发 ? "order" : "consign")}", + _1688ProductDetailRequestHeader, + HttpMethod.Get, + httpClientName: "gzip"); + + if (_1688pageResult.StatusCode != System.Net.HttpStatusCode.OK) + return null; + + var match = Regex.Match(_1688pageResult.Content, @"(window\.__INIT_DATA=)(.*)(\r*\n*\s*)"); + if (!match.Success) + return null; + + var jsonStr = match.Groups[2].Value; + var jobject = JObject.Parse(jsonStr); + + //16347413030323 + var purchaser = new Purchaser() + { + Id = jobject["globalData"]["tempModel"]["sellerUserId"].ToString(), + Name = jobject["globalData"]["tempModel"]["companyName"].ToString(), + Location = jobject["data"]["1081181309101"] != null ? + jobject["data"]["1081181309101"]["data"]["location"].ToString() : + jobject["data"]["16347413030323"]["data"]["location"].ToString(), + Platform = Enums.Platform.阿里巴巴 + }; + + var colorsProperty = jobject["globalData"]["skuModel"]["skuProps"].FirstOrDefault(j => j.Value("fid") == 3216 || + j.Value("fid") == 1627207 || + j.Value("fid") == 1234 || + j.Value("fid") == 3151)["value"] + .Children() + .Select(j => new + { + name = j.Value("name"), + imageUrl = j.Value("imageUrl") + }).ToList(); + + var firstPrice = jobject["data"]["1081181309582"] != null ? + jobject["data"]["1081181309582"]["data"]["priceModel"]["currentPrices"][0].Value("price") : + jobject["data"]["16347413030316"]["data"]["priceModel"]["currentPrices"][0].Value("price"); + + var list = new List(); + + foreach (var jsku in jobject["globalData"]["skuModel"]["skuInfoMap"].Children()) + { + var jskuProperty = jsku as JProperty; + var name = jskuProperty.Name; + var matchName = name.Contains(">") ? name.Substring(0, name.IndexOf(">")) : name; + var value = jskuProperty.Value; + + var skuPrice = value.Value("price"); + + list.Add(new PurchaseSkuItemBasicInfoResponse() + { + PurchaseProductId = request.PurchaseProductId, + Price = skuPrice == 0M ? firstPrice : skuPrice, + Title = name, + PurchaseSkuId = value.Value("skuId"), + PurchaseSkuSpecId = value.Value("specId"), + Logo = colorsProperty.FirstOrDefault(c => c.name == matchName)?.imageUrl ?? "pack://application:,,,/Resources/Images/defaultItem.png" + }); + } + + return new PurchaseSkuBasicInfoResponse() + { + ItemList = list, + Purchaser = purchaser, + PurchaseProductId = request.PurchaseProductId, + PurchasePlatform = Enums.Platform.阿里巴巴 + }; + } + catch + { + + return null; + } + } + + private PurchaseSkuBasicInfoResponse LoadFromQTSpider(PurchaseSkuBasicInfoRequest request) + { + try + { + var response = quanTanProductClient.GetProductInfo(request.PurchaseProductId, qtAppId, qtAppSecret); + if (response.Status != 200) + return null; + return new PurchaseSkuBasicInfoResponse() + { + Purchaser = new Purchaser() + { + Id = response.Data.Supplier.VenderId, + Name = response.Data.Supplier.VerdenName, + Location = response.Data.Supplier.Location + }, + PurchaseProductId = request.PurchaseProductId, + PurchasePlatform = Enums.Platform.拳探, + ItemList = response.Data.ProductSku.Select(s => new PurchaseSkuItemBasicInfoResponse() + { + Logo = s.Logo, + Price = s.Price, + PurchaseProductId = s.ProductId, + PurchaseSkuId = s.SkuId, + Title = s.Title + }).ToList() + }; + } + catch + { + return null; + } + } + } +} diff --git a/BBWY.Server.Business/PurchaseScheme/PurchaseSchemeBusiness.cs b/BBWY.Server.Business/PurchaseScheme/PurchaseSchemeBusiness.cs index 5633fc6b..5e30e3d8 100644 --- a/BBWY.Server.Business/PurchaseScheme/PurchaseSchemeBusiness.cs +++ b/BBWY.Server.Business/PurchaseScheme/PurchaseSchemeBusiness.cs @@ -1,7 +1,9 @@ using BBWY.Common.Extensions; using BBWY.Common.Models; +using BBWY.Server.Model; using BBWY.Server.Model.Db; using BBWY.Server.Model.Dto; +using FreeSql; using System; using System.Collections.Generic; using System.Linq; @@ -11,7 +13,11 @@ namespace BBWY.Server.Business { public class PurchaseSchemeBusiness : BaseBusiness, IDenpendency { - public PurchaseSchemeBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator) : base(fsql, nLogManager, idGenerator) { } + private PurchaseProductAPIService purchaseProductAPIService; + public PurchaseSchemeBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, PurchaseProductAPIService purchaseProductAPIService) : base(fsql, nLogManager, idGenerator) + { + this.purchaseProductAPIService = purchaseProductAPIService; + } private void ExtractNewPurchaser(IList purchaserSchemeList, IList addPurchaserList) where T : InputPurchaseSchemeRequest { @@ -223,13 +229,13 @@ namespace BBWY.Server.Business var purchaserList = fsql.Select().Where(p => sharePurchaserIdList.Contains(p.Id)).ToList(); foreach (var p in purchaserList) { - var scheme = purchaseSchemeList.FirstOrDefault(ps=>ps.PurchaserId == p.Id); + var scheme = purchaseSchemeList.FirstOrDefault(ps => ps.PurchaserId == p.Id); if (scheme != null) { p.DefaultCost = scheme.DefaultCost; p.LastPurchaseTime = scheme.LastPurchaseTime; } - } + } return purchaserList; } @@ -255,5 +261,107 @@ namespace BBWY.Server.Business fsql.Delete().Where(p => p.SkuPurchaseSchemeId == schemeId).ExecuteAffrows(); }); } + + + /// + /// 获取采购Sku的基本信息 + /// + /// + /// + public PurchaseSkuBasicInfoResponse GetPurchaseSkuBasicInfo(PurchaseSkuBasicInfoRequest request) + { + return purchaseProductAPIService.GetProductInfo(request); + } + + public IList BatchGetPurchaseSkuBasicInfo(BatchPurchaseSkuBasicInfoRequest request) + { + var list = new List(); + foreach (var param in request.Params) + { + foreach (var purchaseId in param.PurchaseProductIds) + { + var response = GetPurchaseSkuBasicInfo(new PurchaseSkuBasicInfoRequest() + { + FirstApiMode = request.FirstApiMode, + PriceMode = request.PriceMode, + Platform = param.Platform, + PurchaseProductId = purchaseId + }); + if (response != null) + { + if (param.PurchaseSkuIds != null && param.PurchaseSkuIds.Count() > 0) + { + for (var i = 0; i < response.ItemList.Count(); i++) + { + var skuInfo = response.ItemList[i]; + if (!param.PurchaseSkuIds.Any(s => s == skuInfo.PurchaseSkuId)) + { + response.ItemList.RemoveAt(i); + i--; + } + } + } + list.Add(response); + } + } + } + return list; + } + + /// + /// 批量修改拳探采购方案归属采购商 + /// + /// 修改成功的拳探skuId + /// + public IList BatchUpdateQTPurchaseSchemeBelongPurchaser(BatchUpdateQTPurchaseSchemeBelongPurchaserRequest request) + { + var purchaseSchemeList = GetPurchaseSchemeList(new QuerySchemeRequest() + { + PurchasePlatform = Enums.Platform.拳探, + PurchaserId = request.PurchaserId + }); + var qtPurchaserList = fsql.Select().Where(p => p.Platform == Enums.Platform.拳探).ToList(); + IList updateSkuChangeInfoList = new List(); + IList> updatePurchaseSchemeList = new List>(); + foreach (var purchaseScheme in purchaseSchemeList) + { + var firstProduct = purchaseScheme.PurchaseSchemeProductList.FirstOrDefault(); + var purchaseBasicInfoList = BatchGetPurchaseSkuBasicInfo(new BatchPurchaseSkuBasicInfoRequest() + { + FirstApiMode = Enums.PurchaseProductAPIMode.Spider, + PriceMode = Enums.PurchaseOrderMode.批发, + Params = new List() + { + new BatchPurchaseSkuBasicInfoParamRequest() + { + Platform = Enums.Platform.拳探, + PurchaseProductIds = new string[]{firstProduct.PurchaseProductId} + } + } + }); + + if (purchaseBasicInfoList.Count() == 0) + continue; + var p = purchaseBasicInfoList.FirstOrDefault().Purchaser; + if (p != null && p.Id != purchaseScheme.PurchaserId) + { + var update = fsql.Update(purchaseScheme.Id).Set(ps => ps.PurchaserId, p.Id); + updatePurchaseSchemeList.Add(update); + + var oldPurchasr = qtPurchaserList.FirstOrDefault(op => op.Id == purchaseScheme.PurchaserId); + updateSkuChangeInfoList.Add($"{purchaseScheme.SkuId} -> {oldPurchasr?.Name} -> {p.Name}"); + } + } + + if (updatePurchaseSchemeList.Count() > 0) + { + fsql.Transaction(() => + { + foreach (var update in updatePurchaseSchemeList) + update.ExecuteAffrows(); + }); + } + return updateSkuChangeInfoList; + } } } diff --git a/BBWY.Server.Business/Sync/StoreHouseSyncBusiness.cs b/BBWY.Server.Business/Sync/StoreHouseSyncBusiness.cs index 9420f31f..f8db1684 100644 --- a/BBWY.Server.Business/Sync/StoreHouseSyncBusiness.cs +++ b/BBWY.Server.Business/Sync/StoreHouseSyncBusiness.cs @@ -78,14 +78,20 @@ namespace BBWY.Server.Business.Sync } } - var storeHouseIds = storeHouseList.Select(s => s.Id).ToArray(); - var dbStoreIds = fsql.Select(storeHouseIds).ToList(s => s.Id); - var exceptIds = storeHouseIds.Except(dbStoreIds); - if (exceptIds.Count() > 0) + //var storeHouseIds = storeHouseList.Select(s => s.Id).ToArray(); + //var dbStoreIds = fsql.Select(storeHouseIds).ToList(s => s.Id); + //var exceptIds = storeHouseIds.Except(dbStoreIds); + //if (exceptIds.Count() > 0) + //{ + // var insertList = storeHouseList.Where(s => exceptIds.Contains(s.Id)).ToList(); + // fsql.Insert(insertList).ExecuteAffrows(); + //} + fsql.Transaction(() => { - var insertList = storeHouseList.Where(s => exceptIds.Contains(s.Id)).ToList(); - fsql.Insert(insertList).ExecuteAffrows(); - } + fsql.Delete().Where(s => 1 == 1).ExecuteAffrows(); + fsql.Insert(storeHouseList).ExecuteAffrows(); + }); + } private void ResolveJDStoreHouse(JArray jarray, ShopResponse shop, IList storeHouseList) diff --git a/BBWY.Server.Business/Vender/VenderBusiness.cs b/BBWY.Server.Business/Vender/VenderBusiness.cs index 7c5eb43f..0da2601e 100644 --- a/BBWY.Server.Business/Vender/VenderBusiness.cs +++ b/BBWY.Server.Business/Vender/VenderBusiness.cs @@ -7,6 +7,7 @@ using BBWY.Server.Model.Db.Mds; using BBWY.Server.Model.Dto; using Microsoft.Extensions.Options; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; @@ -323,5 +324,37 @@ namespace BBWY.Server.Business throw new BusinessException(response.Msg) { Code = response.Code }; return response.Data; } + + public IList GetStoreHouseList(PlatformRequest request) + { + var restApiResult = restApiService.SendRequest(GetPlatformRelayAPIHost(request.Platform), "api/PlatformSDK/GetStoreHouseList", new PlatformRequest() + { + AppKey = request.AppKey, + AppSecret = request.AppSecret, + AppToken = request.AppToken, + Platform = request.Platform, + SaveResponseLog = false + }, GetYunDingRequestHeader(), HttpMethod.Post); + if (restApiResult.StatusCode != System.Net.HttpStatusCode.OK) + throw new Exception(restApiResult.Content); + var response = JsonConvert.DeserializeObject>(restApiResult.Content); + if (response.Data == null || response.Data.Count() == 0) + return null; + var storeHouseList = new List(); + foreach (var storeHouseJToken in response.Data) + { + var seq_num = storeHouseJToken.Value("seq_num"); + storeHouseList.Add(new Storehouse() + { + Id = seq_num, + Name = storeHouseJToken.Value("name"), + Platform = request.Platform, + CreateTime = DateTime.Now, + Status = (Enums.StockStatus)storeHouseJToken.Value("use_flag"), + Type = (Enums.StockType)storeHouseJToken.Value("type") + }); + } + return storeHouseList; + } } } diff --git a/BBWY.Server.Model/Dto/Request/PurchaseOrder/Callback/BBWYBDelivertCallBackRequest.cs b/BBWY.Server.Model/Dto/Request/PurchaseOrder/Callback/BBWYBDelivertCallBackRequest.cs new file mode 100644 index 00000000..41008cd8 --- /dev/null +++ b/BBWY.Server.Model/Dto/Request/PurchaseOrder/Callback/BBWYBDelivertCallBackRequest.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BBWY.Server.Model.Dto +{ + public class BBWYBDeliveryCallBackRequest + { + public string OrderId { get; set; } + } + + public class BBWYBSignCallBackRequest : BBWYBDeliveryCallBackRequest + { + + } +} diff --git a/BBWY.Server.Model/Dto/Request/PurchaseOrder/OnlinePurchase/CreateOnlinePurchaseOrderRequest.cs b/BBWY.Server.Model/Dto/Request/PurchaseOrder/OnlinePurchase/CreateOnlinePurchaseOrderRequest.cs index 62f3d1db..a26ba6e7 100644 --- a/BBWY.Server.Model/Dto/Request/PurchaseOrder/OnlinePurchase/CreateOnlinePurchaseOrderRequest.cs +++ b/BBWY.Server.Model/Dto/Request/PurchaseOrder/OnlinePurchase/CreateOnlinePurchaseOrderRequest.cs @@ -48,7 +48,7 @@ public string Extensions { get; set; } - public string SourceSku { get; set; } + public object SourceSku { get; set; } public string SourceShopName { get; set; } diff --git a/BBWY.Server.Model/Dto/Request/PurchaseOrderV2/BatchPurchase/BatchPurchaseCreateOrderRequest.cs b/BBWY.Server.Model/Dto/Request/PurchaseOrderV2/BatchPurchase/BatchPurchaseCreateOrderRequest.cs index c6a8e359..df809592 100644 --- a/BBWY.Server.Model/Dto/Request/PurchaseOrderV2/BatchPurchase/BatchPurchaseCreateOrderRequest.cs +++ b/BBWY.Server.Model/Dto/Request/PurchaseOrderV2/BatchPurchase/BatchPurchaseCreateOrderRequest.cs @@ -1,4 +1,6 @@ -namespace BBWY.Server.Model.Dto +using System.Collections.Generic; + +namespace BBWY.Server.Model.Dto { public class BatchPurchaseCreateOrderRequest : BatchPurchasePreviewOrderRequest { @@ -18,6 +20,9 @@ public string AutoPay { get; set; } - + /// + /// 打包设置 + /// + public IList PackSkuConfigList { get; set; } } } diff --git a/BBWY.Server.Model/Dto/Request/PurchaseScheme/BatchUpdateQTPurchaseSchemeBelongPurchaserRequest.cs b/BBWY.Server.Model/Dto/Request/PurchaseScheme/BatchUpdateQTPurchaseSchemeBelongPurchaserRequest.cs new file mode 100644 index 00000000..2dbf1b5a --- /dev/null +++ b/BBWY.Server.Model/Dto/Request/PurchaseScheme/BatchUpdateQTPurchaseSchemeBelongPurchaserRequest.cs @@ -0,0 +1,10 @@ +namespace BBWY.Server.Model.Dto +{ + public class BatchUpdateQTPurchaseSchemeBelongPurchaserRequest + { + /// + /// 采购商Id 可空 + /// + public string PurchaserId { get; set; } + } +} diff --git a/BBWY.Server.Model/Dto/Request/PurchaseScheme/PurcasheSkuBasicInfoRequest.cs b/BBWY.Server.Model/Dto/Request/PurchaseScheme/PurcasheSkuBasicInfoRequest.cs new file mode 100644 index 00000000..91cb83be --- /dev/null +++ b/BBWY.Server.Model/Dto/Request/PurchaseScheme/PurcasheSkuBasicInfoRequest.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; + +namespace BBWY.Server.Model.Dto +{ + public class PurchaseSkuBasicInfoRequest + { + public Enums.Platform Platform { get; set; } + + /// + /// 采购商品Id + /// + public string PurchaseProductId { get; set; } + + public Enums.PurchaseOrderMode PriceMode { get; set; } + + public Enums.PurchaseProductAPIMode FirstApiMode { get; set; } + } + + public class BatchPurchaseSkuBasicInfoRequest + { + public IList Params { get; set; } + + public Enums.PurchaseOrderMode PriceMode { get; set; } + + public Enums.PurchaseProductAPIMode FirstApiMode { get; set; } + } + + public class BatchPurchaseSkuBasicInfoParamRequest + { + public Enums.Platform Platform { get; set; } + + /// + /// 采购商品Id(采购spu) + /// + public string[] PurchaseProductIds { get; set; } + + /// + /// 需要保留的采购SkuId,如果传递了该数组,将过滤不在该数组的采购sku + /// + public string[] PurchaseSkuIds { get; set; } + } +} diff --git a/BBWY.Server.Model/Dto/Request/QiKu/PackSkuConfigRequest.cs b/BBWY.Server.Model/Dto/Request/QiKu/PackSkuConfigRequest.cs new file mode 100644 index 00000000..44d7f1d2 --- /dev/null +++ b/BBWY.Server.Model/Dto/Request/QiKu/PackSkuConfigRequest.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; + +namespace BBWY.Server.Model.Dto +{ + public class PackSkuConfigRequest + { + public PackSkuConfigRequest() + { + + } + /// + /// 采购备注信息 + /// + public string RemarkMessage { get; set; } + /// + /// 店铺Sku + /// + public string SkuId { get; set; } + + /// + /// 采购数量 + /// + public int PurchaseCount { get; set; } + + + public IList PackSkuSplitConfigList { get; set; } + } + + public class PackSkuSplitConfigRequest + { + public int Index { get; set; } + + public int PackCount { get; set; } + + public StoreRequest Store { get; set; } + } +} diff --git a/BBWY.Server.Model/Dto/Request/Stock/StoreRequest.cs b/BBWY.Server.Model/Dto/Request/Stock/StoreRequest.cs new file mode 100644 index 00000000..91b053b4 --- /dev/null +++ b/BBWY.Server.Model/Dto/Request/Stock/StoreRequest.cs @@ -0,0 +1,9 @@ +namespace BBWY.Server.Model.Dto +{ + public class StoreRequest + { + public string Id { get; set; } + + public string Name { get; set; } + } +} diff --git a/BBWY.Server.Model/Dto/Response/PurchaseScheme/PurchaseProductBasicInfoResponse.cs b/BBWY.Server.Model/Dto/Response/PurchaseScheme/PurchaseProductBasicInfoResponse.cs new file mode 100644 index 00000000..6c3704c8 --- /dev/null +++ b/BBWY.Server.Model/Dto/Response/PurchaseScheme/PurchaseProductBasicInfoResponse.cs @@ -0,0 +1,58 @@ +using BBWY.Server.Model.Db; +using System.Collections.Generic; + +namespace BBWY.Server.Model.Dto +{ + /// + /// 采购Sku基础信息对象 + /// + public class PurchaseSkuBasicInfoResponse + { + public Enums.Platform PurchasePlatform { get; set; } + + public string PurchaseProductId { get; set; } + + /// + /// 采购SKU基础信息列表 + /// + public IList ItemList { get; set; } + + /// + /// 采购商 + /// + public Purchaser Purchaser { get; set; } + } + + /// + /// 采购Sku基础信息对象 + /// + public class PurchaseSkuItemBasicInfoResponse + { + /// + /// 采购SPU + /// + public string PurchaseProductId { get; set; } + + /// + /// 采购SKU + /// + public string PurchaseSkuId { get; set; } + + /// + /// 采购SPEC 1688独有属性 下单需要 + /// + public string PurchaseSkuSpecId { get; set; } + + /// + /// SKU标题 + /// + public string Title { get; set; } + + public string Logo { get; set; } + + /// + /// 单价 + /// + public decimal Price { get; set; } + } +} diff --git a/BBWY.Server.Model/Enums.cs b/BBWY.Server.Model/Enums.cs index cc90dd3a..41e71598 100644 --- a/BBWY.Server.Model/Enums.cs +++ b/BBWY.Server.Model/Enums.cs @@ -33,6 +33,15 @@ 代发 = 1 } + /// + /// 采购商品API模式 Spider = 0,OneBound = 1 + /// + public enum PurchaseProductAPIMode + { + Spider = 0, + OneBound = 1 + } + /// /// 仓储类型 /// diff --git a/BBWY.Test/Program.cs b/BBWY.Test/Program.cs index f111c6f1..ec05aa1d 100644 --- a/BBWY.Test/Program.cs +++ b/BBWY.Test/Program.cs @@ -1,7 +1,11 @@ -using Jd.Api; +using com.alibaba.openapi.client; +using com.alibaba.openapi.client.policy; +using Jd.Api; using Jd.Api.Request; +using Microsoft.Extensions.DependencyInjection; using System; using System.Linq; +using System.Net.Http; using System.Security.Cryptography; using System.Text; @@ -22,6 +26,14 @@ namespace BBWY.Test } } + private static SyncAPIClient GetSyncAPIClient(string appKey, string appSecret) + { + var sercvice = new ServiceCollection(); + sercvice.AddHttpClient(); + var servicePriovder = sercvice.BuildServiceProvider(); + return new SyncAPIClient(appKey, appSecret, new Common.Http.RestApiService(servicePriovder.GetRequiredService())); + } + static void Main(string[] args) { @@ -41,29 +53,70 @@ namespace BBWY.Test //var token = "4a0ddc095e054c7aa90adcaccb14f83cwzgr"; //可比车品 var token = "50a4c0f5c55848b5a8a715709e8d6fe0jntb"; //卿卿玩具专营店 - //var dt1 = DateTime.Now; - //List list = new List(); - //for (var i = 1; i <= 5000000; i++) - //{ - // var str = tomMd5($"Mozilla/5.0 (Linux; Android 12; 21121210C Build/SKQ1.211006.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/13.8 SP-engine/2.46.0 baiduboxapp/13.8.1.10 (Baidu; P1 12) NABar/1.0 Edg/102.0.5005.63_{i}_192.158.241.{i}_28726526517321"); - // Console.WriteLine($"生成第{i}位指纹,长度{str.Length},{str}"); - // list.Add(str); - //} - //var dt2 = DateTime.Now; - //Console.WriteLine($"总数量{list.Count},总耗时{(dt2 - dt1).TotalSeconds}秒"); + var request = new + { + AppKey = "3944754", + AppSecret = "NahdPJS5uzM", + AppToken = "a9a67b4a-1117-4ae6-8422-8188eedd3480", + OrderId = "1885695962273561469" + }; + { + var client = GetSyncAPIClient(request.AppKey, request.AppSecret); + RequestPolicy reqPolicy = new RequestPolicy(); + reqPolicy.HttpMethod = "POST"; + reqPolicy.NeedAuthorization = false; + reqPolicy.RequestSendTimestamp = false; + reqPolicy.UseHttps = false; + reqPolicy.UseSignture = true; + reqPolicy.AccessPrivateApi = false; + Request _request = new Request(); + APIId apiId = new APIId(); + apiId.Name = "alibaba.trade.getLogisticsInfos.buyerView"; + apiId.NamespaceValue = "com.alibaba.logistics"; + apiId.Version = 1; + _request.ApiId = apiId; - var jdClient = GetJdClient(appkey, appSecret); - var req = new AscFreightViewRequest(); + var param = new { orderId = request.OrderId, webSite = "1688", fields = "logisticsCompanyId,logisticsCompanyName,logisticsBillNo" }; + _request.RequestEntity = param; + if (!string.IsNullOrEmpty(request.AppToken)) + _request.AccessToken = request.AppToken; + var result = client.NewRequest(_request, reqPolicy); + } + + { + var client = GetSyncAPIClient(request.AppKey, request.AppSecret); + RequestPolicy reqPolicy = new RequestPolicy(); + reqPolicy.HttpMethod = "POST"; + reqPolicy.NeedAuthorization = false; + reqPolicy.RequestSendTimestamp = false; + reqPolicy.UseHttps = false; + reqPolicy.UseSignture = true; + reqPolicy.AccessPrivateApi = false; + + Request _request = new Request(); + APIId apiId = new APIId + { + Name = "alibaba.trade.get.buyerView", + NamespaceValue = "com.alibaba.trade", + Version = 1 + }; + _request.ApiId = apiId; + + var param = new + { + webSite = "1688", + orderId = request.OrderId, + includeFields = "baseInfo,productItems" + }; + _request.RequestEntity = param; + if (!string.IsNullOrEmpty(request.AppToken)) + _request.AccessToken = request.AppToken; + var result = client.NewRequest(_request, reqPolicy); + } - req.buId = "11926867"; - req.operatePin = "开发测试"; - req.operateNick = "开发测试"; - req.serviceId = 1701316861; - req.orderId = 264691201058; - var res = jdClient.Execute(req,token, DateTime.Now.ToLocalTime()); Console.ReadKey(); }