diff --git a/BBWYB.Client/APIServices/PurchaseOrderService.cs b/BBWYB.Client/APIServices/PurchaseOrderService.cs new file mode 100644 index 0000000..4a20ac0 --- /dev/null +++ b/BBWYB.Client/APIServices/PurchaseOrderService.cs @@ -0,0 +1,166 @@ +using BBWYB.Client.Models; +using BBWYB.Common.Http; +using BBWYB.Common.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; + +namespace BBWYB.Client.APIServices +{ + public class PurchaseOrderService : BaseApiService, IDenpendency + { + public PurchaseOrderService(RestApiService restApiService, GlobalContext globalContext) : base(restApiService, globalContext) + { + + } + + public ApiResponse AddPurchaseOrder(PurchaseOrder purchaseOrder) + { + return SendRequest(globalContext.BBYWApiHost, + "api/PurchaseOrder/AddPurchaseOrder", + purchaseOrder, + null, + HttpMethod.Post); + } + + public ApiResponse EditPurchaseOrder(PurchaseOrder purchaseOrder) + { + return SendRequest(globalContext.BBYWApiHost, + "api/PurchaseOrder/EditPurchaseOrder", + purchaseOrder, + null, + HttpMethod.Put); + } + + public ApiResponse> GetList(IList skuIdList, StorageType storageType, long shopId) + { + return SendRequest>(globalContext.BBYWApiHost, + "api/PurchaseOrder/GetList", + new { SkuIdList = skuIdList, StorageType = storageType, ShopId = shopId }, + null, + HttpMethod.Post); + } + + public ApiResponse DeletePurchaseOrder(long id) + { + return SendRequest(globalContext.BBYWApiHost, + $"api/purchaseOrder/deletePurchaseOrder/{id}", + null, + null, + HttpMethod.Delete); + } + + /// + /// 预览订单 + /// + /// + /// + /// + public ApiResponse PreviewPurchaseOrder(Consignee consignee, IList purchaseSchemeProductSkuList, Platform purchasePlatform, PurchaseAccount purchaseAccount, PurchaseOrderMode purchaseOrderMode) + { + return SendRequest(globalContext.BBYWApiHost, "api/purchaseOrder/PreviewPurchaseOrder", new + { + purchaseOrderMode, + consignee, + CargoParamList = purchaseSchemeProductSkuList.Select(sku => new + { + ProductId = sku.PurchaseProductId, + SkuId = sku.PurchaseSkuId, + SpecId = sku.PurchaseSkuSpecId, + Quantity = sku.ItemTotal, + BelongSkuId = sku.SkuId + }), + Platform = purchasePlatform, + AppKey = purchaseAccount.AppKey, + AppSecret = purchaseAccount.AppSecret, + AppToken = purchaseAccount.AppToken, + SaveResponseLog = true + }, null, HttpMethod.Post); + } + + /// + /// 创建采购单 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public ApiResponse FastCreateOrder(Consignee consignee, + IList purchaseSchemeProductSkuList, + Platform purchasePlatform, + PurchaseAccount purchaseAccount, + PurchaseOrderMode purchaseOrderMode, + string tradeMode, + string remark, + string orderId, + long shopId, + long purchaseAccountId, + string buyerAccount, + string sellerAccount, + string purchaserId, + decimal platformCommissionRatio, + string extensions) + { + return SendRequest(globalContext.BBYWApiHost, "api/purchaseOrder/NewFastCreateOrder", new + { + purchaseOrderMode, + consignee, + CargoParamList = purchaseSchemeProductSkuList.Select(sku => new + { + ProductId = sku.PurchaseProductId, + SkuId = sku.PurchaseSkuId, + SpecId = sku.PurchaseSkuSpecId, + Quantity = sku.ItemTotal, + BelongSkuId = sku.SkuId + }), + Platform = purchasePlatform, + AppKey = purchaseAccount.AppKey, + AppSecret = purchaseAccount.AppSecret, + AppToken = purchaseAccount.AppToken, + SaveResponseLog = true, + tradeMode, + remark, + orderId, + shopId, + purchaseAccountId, + buyerAccount, + sellerAccount, + purchaserId, + platformCommissionRatio, + extensions + }, null, HttpMethod.Post); + } + + + + /// + /// 查询审核采购单 + /// + /// + /// + /// + /// + public ApiResponse> GetAuditPurchaseOrderList(IList shopIdList, DateTime startDate, DateTime endDate) + { + return SendRequest>(globalContext.BBYWApiHost, "Api/PurchaseOrder/GetAuditPurchaseOrderList", new + { + startDate, + endDate, + shopIdList + }, null, HttpMethod.Post); + } + } +} diff --git a/BBWYB.Client/Converters/PurchaseOrderDelBtnConverter.cs b/BBWYB.Client/Converters/PurchaseOrderDelBtnConverter.cs new file mode 100644 index 0000000..2e19a55 --- /dev/null +++ b/BBWYB.Client/Converters/PurchaseOrderDelBtnConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Windows; +using System.Windows.Data; + +namespace BBWYB.Client.Converters +{ + public class PurchaseOrderDelBtnConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + long.TryParse(values[0]?.ToString(), out long id); + int.TryParse(values[1]?.ToString(), out int purchaseQuantity); + int.TryParse(values[2]?.ToString(), out int remainingQuantity); + return id == 0 || (id != 0 && purchaseQuantity != 0 && purchaseQuantity == remainingQuantity) ? Visibility.Visible : Visibility.Collapsed; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/BBWYB.Client/Converters/PurchaseOrderEditBtnConverter.cs b/BBWYB.Client/Converters/PurchaseOrderEditBtnConverter.cs new file mode 100644 index 0000000..4f1b460 --- /dev/null +++ b/BBWYB.Client/Converters/PurchaseOrderEditBtnConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Windows; +using System.Windows.Data; + +namespace BBWYB.Client.Converters +{ + public class PurchaseOrderEditBtnConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + bool.TryParse(values[0]?.ToString(), out bool isEdit); + int.TryParse(values[1]?.ToString(), out int purchaseQuantity); + int.TryParse(values[2]?.ToString(), out int remainingQuantity); + return !isEdit && + purchaseQuantity != 0 && + purchaseQuantity == remainingQuantity ? Visibility.Visible : Visibility.Collapsed; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/BBWYB.Client/Models/Order/Consignee.cs b/BBWYB.Client/Models/Order/Consignee.cs new file mode 100644 index 0000000..20a9223 --- /dev/null +++ b/BBWYB.Client/Models/Order/Consignee.cs @@ -0,0 +1,39 @@ +using CommunityToolkit.Mvvm.ComponentModel; + +namespace BBWYB.Client.Models +{ + public class Consignee : ObservableObject + { + private string contactName; + private string address; + private string mobile; + private string telePhone; + private bool isDecode; + + + /// + /// 省 + /// + public string Province { get; set; } + + /// + /// 市 + /// + public string City { get; set; } + + /// + /// 县 + /// + public string County { get; set; } + + /// + /// 镇 + /// + public string Town { get; set; } + public string ContactName { get => contactName; set { SetProperty(ref contactName, value); } } + public string Address { get => address; set { SetProperty(ref address, value); } } + public string Mobile { get => mobile; set { SetProperty(ref mobile, value); } } + public string TelePhone { get => telePhone; set { SetProperty(ref telePhone, value); } } + public bool IsDecode { get => isDecode; set { SetProperty(ref isDecode, value); } } + } +} diff --git a/BBWYB.Client/TemplateSelectors/PurchaseOrderDataTemplateSelector.cs b/BBWYB.Client/TemplateSelectors/PurchaseOrderDataTemplateSelector.cs new file mode 100644 index 0000000..f7e0b50 --- /dev/null +++ b/BBWYB.Client/TemplateSelectors/PurchaseOrderDataTemplateSelector.cs @@ -0,0 +1,18 @@ +using BBWYB.Client.Models; +using System.Windows; +using System.Windows.Controls; + +namespace BBWYB.Client.TemplateSelectors +{ + public class PurchaseOrderDataTemplateSelector : DataTemplateSelector + { + public DataTemplate NormalTemplate { get; set; } + public DataTemplate EditTemplate { get; set; } + + public override DataTemplate SelectTemplate(object item, DependencyObject container) + { + PurchaseOrder purchaseOrder = (PurchaseOrder)item; + return purchaseOrder.IsEdit ? EditTemplate : NormalTemplate; + } + } +} diff --git a/BBWYB.Client/ViewModels/MainViewModel.cs b/BBWYB.Client/ViewModels/MainViewModel.cs index 22ba2d7..2a42b99 100644 --- a/BBWYB.Client/ViewModels/MainViewModel.cs +++ b/BBWYB.Client/ViewModels/MainViewModel.cs @@ -206,10 +206,10 @@ namespace BBWYB.Client.ViewModels var vm = App.Current.Resources["Locator"] as ViewModelLocator; //if (vm.IsCreateOrderList) // vm.OrderList.Refresh(); - //if (vm.IsCreateWareManager) - // vm.WareManager.Refresh(); - //if (vm.IsCreateWareStock) - // vm.WareStock.Refresh(); + if (vm.IsCreateWareManager) + vm.WareManager.Refresh(); + if (vm.IsCreateWareStock) + vm.WareStock.Refresh(); } } catch (Exception ex) diff --git a/BBWYB.Client/ViewModels/ViewModelLocator.cs b/BBWYB.Client/ViewModels/ViewModelLocator.cs index 40eb08a..4c77883 100644 --- a/BBWYB.Client/ViewModels/ViewModelLocator.cs +++ b/BBWYB.Client/ViewModels/ViewModelLocator.cs @@ -30,39 +30,39 @@ namespace BBWYB.Client.ViewModels } } - //public WareManagerViewModel WareManager - //{ - // get - // { - // IsCreateWareManager = true; - // using (var s = sp.CreateScope()) - // { - // return s.ServiceProvider.GetRequiredService(); - // } - // } - //} + public WareManagerViewModel WareManager + { + get + { + IsCreateWareManager = true; + using (var s = sp.CreateScope()) + { + return s.ServiceProvider.GetRequiredService(); + } + } + } - //public WareStockViewModel WareStock - //{ - // get - // { - // IsCreateWareStock = true; - // using (var s = sp.CreateScope()) - // { - // return s.ServiceProvider.GetRequiredService(); - // } - // } - //} + public WareStockViewModel WareStock + { + get + { + IsCreateWareStock = true; + using (var s = sp.CreateScope()) + { + return s.ServiceProvider.GetRequiredService(); + } + } + } - //public BindingPurchaseProductViewModel BindingPurchaseProduct - //{ - // get - // { - // using (var s = sp.CreateScope()) - // { - // return s.ServiceProvider.GetRequiredService(); - // } - // } - //} + public BindingPurchaseProductViewModel BindingPurchaseProduct + { + get + { + using (var s = sp.CreateScope()) + { + return s.ServiceProvider.GetRequiredService(); + } + } + } } } diff --git a/BBWYB.Client/ViewModels/Ware/BindingPurchaseProductViewModel.cs b/BBWYB.Client/ViewModels/Ware/BindingPurchaseProductViewModel.cs new file mode 100644 index 0000000..2a8ec79 --- /dev/null +++ b/BBWYB.Client/ViewModels/Ware/BindingPurchaseProductViewModel.cs @@ -0,0 +1,432 @@ +using BBWYB.Client.APIServices; +using BBWYB.Client.Models; +using BBWYB.Client.Views.Ware; +using BBWYB.Common.Models; +using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Messaging; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; + +namespace BBWYB.Client.ViewModels +{ + public class BindingPurchaseProductViewModel : BaseVM, IDenpendency + { + #region Properties + private GlobalContext globalContext; + private PurchaseService purchaseService; + private PurchaseProductAPIService purchaseProductAPIService; + + private string purchaserName; + private bool isLoading; + + private Platform purchasePlatform; + + + private IDictionary urlPatternDictionary; + + + public IList ProductSkuList { get; set; } + + public string PurchaserId { get; set; } + public string PurchaserName { get => purchaserName; set { SetProperty(ref purchaserName, value); } } + public string PurchaserLocation { get; set; } + public bool IsLoading { get => isLoading; set { SetProperty(ref isLoading, value); } } + + public Platform PurchasePlatform { get => purchasePlatform; set { SetProperty(ref purchasePlatform, value); } } + + #endregion + + #region ICommands + public ICommand ClosingCommand { get; set; } + + public ICommand AddPurchaseProductCommand { get; set; } + + public ICommand RemovePurchaseSchemeProductCommand { get; set; } + + public ICommand GetPurchaseProductInfoCommand { get; set; } + + public ICommand ConfirmPurchaseProductCommand { get; set; } + + public ICommand EditPurchaseProductCommand { get; set; } + + public ICommand SavePurchaseSchemeCommand { get; set; } + + public ICommand SearchPurchaseSkuNameCommand { get; set; } + + public ICommand ClearPurchaseSkuNameCommand { get; set; } + #endregion + + #region Methods + public BindingPurchaseProductViewModel(PurchaseProductAPIService purchaseProductAPIService, PurchaseService purchaseService, GlobalContext globalContext) + { + this.globalContext = globalContext; + this.purchaseService = purchaseService; + this.purchaseProductAPIService = purchaseProductAPIService; + ClosingCommand = new RelayCommand(Closing); + AddPurchaseProductCommand = new RelayCommand(AddPurchaseProduct); + RemovePurchaseSchemeProductCommand = new RelayCommand(RemovePurchaseSchemeProduct); + GetPurchaseProductInfoCommand = new RelayCommand(GetPurchaseProductInfo); + ConfirmPurchaseProductCommand = new RelayCommand(ConfirmPurchaseProduct); + EditPurchaseProductCommand = new RelayCommand(EditPurchaseProduct); + SavePurchaseSchemeCommand = new RelayCommand(SavePurchaseScheme); + SearchPurchaseSkuNameCommand = new RelayCommand(SearchPurchaseSkuName); + ClearPurchaseSkuNameCommand = new RelayCommand(ClearPurchaseSkuName); + urlPatternDictionary = new Dictionary() + { + { Platform.阿里巴巴,@"^(https://detail.1688.com/offer/(\d+).html)[^\s]*" }, + //{ Platform.拳探, @"^(https://qt.qiyue666.com/goods_detail/(\d+))(\?\w*)?$" } + }; + } + + public void SetData(IList productSkuList, string purchaserId, string purchaserName, Platform purchasePlatform) + { + this.ProductSkuList = productSkuList; + //this.Product = product; + this.PurchaserId = purchaserId; + this.PurchaserName = purchaserName; + this.PurchasePlatform = purchasePlatform; + } + + protected override void Load() + { + if (!string.IsNullOrEmpty(PurchaserId)) + { + IsLoading = true; + Task.Factory.StartNew(() => purchaseService.GetPurchaseSchemeList(ProductSkuList.Select(s => s.Id).ToList(), PurchaserId, globalContext.User.Shop.ShopId, purchasePlatform: PurchasePlatform)).ContinueWith(r => + { + var apiResponse = r.Result; + if (!apiResponse.Success) + { + App.Current.Dispatcher.BeginInvoke((Action)delegate + { + MessageBox.Show(apiResponse.Msg, "查询采购方案"); + }); + IsLoading = false; + return; + } + + var purchaseSchemeList = apiResponse.Data; + + var waitList = new List(); + foreach (var sku in ProductSkuList) + { + //当前SKU下当前采购商的采购方案 + var apiScheme = purchaseSchemeList.FirstOrDefault(s => s.SkuId == sku.Id && s.PurchaserId == PurchaserId); + + if (apiScheme == null) + continue; + + sku.SelectedPurchaseScheme = PurchaseScheme.Convert(apiScheme); + var ewh = new ManualResetEvent(false); + waitList.Add(ewh); + + Task.Factory.StartNew(() => + { + foreach (var purchaseSchemeProduct in sku.SelectedPurchaseScheme.PurchaseSchemeProductList) + { + purchaseSchemeProduct.IsEditing = false; + LoadPurchaseProduct(sku.SelectedPurchaseScheme.PurchasePlatform, purchaseSchemeProduct, purchaseSchemeProduct.PurchaseProductId, null, out _); + } + ewh.Set(); + ewh.Dispose(); + }); + } + WaitHandle.WaitAll(waitList.ToArray()); + IsLoading = false; + }); + } + } + + public void LoadPurchaseProduct(Platform platform, PurchaseSchemeProduct purchaseSchemeProduct, string purchaseProductId, Func checkPurchaserFunc, out string errorMsg) + { + errorMsg = string.Empty; + App.Current.Dispatcher.Invoke(() => + { + purchaseSchemeProduct.SearchSkuList.Clear(); + purchaseSchemeProduct.SkuList.Clear(); + purchaseSchemeProduct.PurchaseSchemeProductSkuList.Clear(); + }); + //skuList = LoadPurchaseProductCore(purchaseSchemeProduct.PurchaseProductId, out _, out _, out _, out _, null); + var data = purchaseProductAPIService.GetProductInfo(platform, + purchaseSchemeProduct.ProductId, + purchaseSchemeProduct.SkuId, + purchaseProductId, + PurchaseOrderMode.批发, + PurchaseProductAPIMode.Spider); + + if (data != null) + { + if (checkPurchaserFunc != null) + { + errorMsg = checkPurchaserFunc(data.Value.purchaser.Id); + if (!string.IsNullOrEmpty(errorMsg)) + return; + } + + if (data.Value.purchaseSchemeProductSkus.Count == 0) + { + errorMsg = $"商品{purchaseSchemeProduct.PurchaseProductId}缺少sku信息"; + return; + } + + PurchaserId = data.Value.purchaser.Id; + PurchaserName = data.Value.purchaser.Name; + PurchaserLocation = data.Value.purchaser.Location; + + App.Current.Dispatcher.BeginInvoke((Action)delegate + { + foreach (var sku in data.Value.purchaseSchemeProductSkus) + { + purchaseSchemeProduct.SearchSkuList.Add(sku); + purchaseSchemeProduct.SkuList.Add(sku); + if (purchaseSchemeProduct.SelectedSkuIdList.Any(s => s == sku.PurchaseSkuId)) + { + sku.IsSelected = true; + purchaseSchemeProduct.PurchaseSchemeProductSkuList.Add(sku); + } + } + }); + } + } + + private void AddPurchaseProduct(ProductSku productSku) + { + if (productSku.PurchaseSchemeList.Count > 4) + { + MessageBox.Show("该sku的采购方案已达上限(5)"); + return; + } + + if (productSku.SelectedPurchaseScheme == null) + { + productSku.SelectedPurchaseScheme = new PurchaseScheme() + { + ProductId = productSku.ProductId, + SkuId = productSku.Id, + PurchasePlatform = PurchasePlatform + }; + } + else if (productSku.SelectedPurchaseScheme.PurchaseSchemeProductList.Count >= 4) + { + MessageBox.Show("该采购方案的商品数量已达上限(5)"); + return; + } + + productSku.SelectedPurchaseScheme.PurchaseSchemeProductList.Add(new PurchaseSchemeProduct() + { + Id = DateTime.Now.ToFileTime(), + IsEditing = true, + ProductId = productSku.ProductId, + SkuId = productSku.Id + }); + } + + private void RemovePurchaseSchemeProduct(PurchaseSchemeProduct purchaseSchemeProduct) + { + var productSku = ProductSkuList.FirstOrDefault(sku => sku.Id == purchaseSchemeProduct.SkuId); + productSku.SelectedPurchaseScheme.PurchaseSchemeProductList.Remove(purchaseSchemeProduct); + if (!ProductSkuList.Any(s => s.SelectedPurchaseScheme != null && s.SelectedPurchaseScheme.PurchaseSchemeProductList.Count > 0)) + PurchaserId = string.Empty; + } + + /// + /// 查询 + /// + /// + private void GetPurchaseProductInfo(PurchaseSchemeProduct purchaseSchemeProduct) + { + //验证路径是否合法 + if (string.IsNullOrEmpty(purchaseSchemeProduct.PurchaseUrl)) + { + MessageBox.Show("商品url不能为空"); + return; + } + + urlPatternDictionary.TryGetValue(PurchasePlatform, out string pattern); + + var match = Regex.Match(purchaseSchemeProduct.PurchaseUrl, pattern); + if (!match.Success) + { + MessageBox.Show("未能识别的url"); + return; + } + var sku = ProductSkuList.FirstOrDefault(s => s.Id == purchaseSchemeProduct.SkuId); + var purchaseUrl = match.Groups[1].Value; + if (sku.SelectedPurchaseScheme.PurchaseSchemeProductList.Any(p => p.Id != purchaseSchemeProduct.Id && p.PurchaseUrl == purchaseUrl)) + { + MessageBox.Show("商品链接重复"); + return; + } + + var purchaseProductId = match.Groups[2].Value; + + IsLoading = true; + + Task.Factory.StartNew(() => + { + LoadPurchaseProduct(sku.SelectedPurchaseScheme.PurchasePlatform, purchaseSchemeProduct, purchaseProductId, (p) => + { + if (sku.PurchaseSchemeList.Any(s => s.Id != sku.SelectedPurchaseScheme.Id && s.PurchaserId == p)) + return $"sku{sku.Id}的采购方案中已存在相同的采购商"; //同一个sku中的采购方案不能有相同的采购商 + + if (!string.IsNullOrEmpty(PurchaserId) && p != PurchaserId) //同一批操作的sku必须为相同的采购商 + return "采购商必须相同"; + + return string.Empty; + }, out string errorMsg); + IsLoading = false; + + if (!string.IsNullOrEmpty(errorMsg)) + { + App.Current.Dispatcher.Invoke(() => MessageBox.Show(errorMsg, "绑定采购商")); + return; + } + + purchaseSchemeProduct.PurchaseUrl = purchaseUrl; + purchaseSchemeProduct.PurchaseProductId = purchaseProductId; + }); + } + + private void ConfirmPurchaseProduct(PurchaseSchemeProduct purchaseSchemeProduct) + { + if (!purchaseSchemeProduct.SkuList.Any(s => s.IsSelected)) + { + MessageBox.Show("至少选中一个采购Sku"); + return; + } + purchaseSchemeProduct.PurchaseSchemeProductSkuList.Clear(); + purchaseSchemeProduct.SelectedSkuIdList.Clear(); + foreach (var sku in purchaseSchemeProduct.SkuList) + { + if (sku.IsSelected) + { + purchaseSchemeProduct.PurchaseSchemeProductSkuList.Add(sku); + purchaseSchemeProduct.SelectedSkuIdList.Add(sku.PurchaseSkuId); + } + } + purchaseSchemeProduct.IsEditing = false; + + var productSku = ProductSkuList.FirstOrDefault(sku => sku.Id == purchaseSchemeProduct.SkuId); + productSku.SelectedPurchaseScheme.PurchaserId = PurchaserId; + productSku.SelectedPurchaseScheme.PurchaserName = PurchaserName; + productSku.SelectedPurchaseScheme.PurchaserLocation = PurchaserLocation; + productSku.SelectedPurchaseScheme.DefaultCost = productSku.SelectedPurchaseScheme.PurchaseSchemeProductList.Sum(p => p.PurchaseSchemeProductSkuList.Count() == 0 ? 0 : p.PurchaseSchemeProductSkuList.Sum(s => s.Price)); + + } + + private void EditPurchaseProduct(PurchaseSchemeProduct purchaseSchemeProduct) + { + purchaseSchemeProduct.IsEditing = true; + } + + private void SavePurchaseScheme() + { + if (!ProductSkuList.Any(s => s.SelectedPurchaseScheme != null && s.SelectedPurchaseScheme.PurchaseSchemeProductList.Count != 0)) + { + MessageBox.Show("没有需要保存的数据,如需删除该采购商所有数据请返回采购商列表进行删除", "提示"); + return; + } + + var hasNoReady = ProductSkuList.Any(s => s.SelectedPurchaseScheme != null && s.SelectedPurchaseScheme.PurchaseSchemeProductList.Any(p => p.IsEditing)); + if (hasNoReady) + { + MessageBox.Show("存在未保存的数据", "提示"); + return; + } + + var addPurchaseSchemeList = ProductSkuList.Where(s => s.SelectedPurchaseScheme != null && + s.SelectedPurchaseScheme.PurchaseSchemeProductList.Count > 0 && + s.SelectedPurchaseScheme.Id == 0) + .Select(s => s.SelectedPurchaseScheme).ToList(); + var editPurchaseSchemeList = ProductSkuList.Where(s => s.SelectedPurchaseScheme != null && + s.SelectedPurchaseScheme.PurchaseSchemeProductList.Count > 0 && + s.SelectedPurchaseScheme.Id != 0) + .Select(s => s.SelectedPurchaseScheme).ToList(); + SuppPurchaseSkuData(addPurchaseSchemeList); + SuppPurchaseSkuData(editPurchaseSchemeList); + + IsLoading = true; + Task.Factory.StartNew(() => + { + var response = purchaseService.EditPurchaseScheme(addPurchaseSchemeList, editPurchaseSchemeList); + IsLoading = false; + if (response.Success) + { + App.Current.Dispatcher.Invoke(() => + { + MessageBox.Show("绑定成功", "提示"); + }); + //关闭窗口 + //Messenger.Default.Send(true, "BindingPurchaseProduct_Close"); + WeakReferenceMessenger.Default.Send(new Message_BindingPurchaseProductClose(true)); + } + else + { + App.Current.Dispatcher.Invoke(() => + { + MessageBox.Show(response.Msg, "绑定失败"); + }); + } + }); + } + + private void Closing(System.ComponentModel.CancelEventArgs e) + { + PurchaserId = PurchaserName = string.Empty; + //clear data + foreach (var sku in ProductSkuList) + { + sku.SelectedPurchaseScheme = null; + } + //Product = null; + e.Cancel = false; + } + + private void SuppPurchaseSkuData(IList purchaseSchemeList) + { + foreach (var scheme in purchaseSchemeList) + { + scheme.ShopId = globalContext.User.Shop.ShopId; + foreach (var purchaseProduct in scheme.PurchaseSchemeProductList) + { + foreach (var purchaseSku in purchaseProduct.PurchaseSchemeProductSkuList) + { + purchaseSku.ProductId = scheme.ProductId; + purchaseSku.SkuId = scheme.SkuId; + purchaseSku.SkuPurchaseSchemeId = scheme.Id; + } + } + } + } + + private void SearchPurchaseSkuName(PurchaseSchemeProduct purchaseSchemeProduct) + { + purchaseSchemeProduct.SearchSkuList.Clear(); + if (string.IsNullOrEmpty(purchaseSchemeProduct.SearchPurchaseSkuName)) + { + foreach (var sku in purchaseSchemeProduct.SkuList) + purchaseSchemeProduct.SearchSkuList.Add(sku); + } + else + { + var searchList = purchaseSchemeProduct.SkuList.Where(s => s.Title.Contains(purchaseSchemeProduct.SearchPurchaseSkuName)); + foreach (var sku in searchList) + purchaseSchemeProduct.SearchSkuList.Add(sku); + } + } + + private void ClearPurchaseSkuName(PurchaseSchemeProduct purchaseSchemeProduct) + { + purchaseSchemeProduct.SearchPurchaseSkuName = string.Empty; + SearchPurchaseSkuName(purchaseSchemeProduct); + } + #endregion + } +} diff --git a/BBWYB.Client/ViewModels/Ware/WareManagerViewModel.cs b/BBWYB.Client/ViewModels/Ware/WareManagerViewModel.cs new file mode 100644 index 0000000..9c9efab --- /dev/null +++ b/BBWYB.Client/ViewModels/Ware/WareManagerViewModel.cs @@ -0,0 +1,350 @@ +using BBWYB.Client.APIServices; +using BBWYB.Client.Models; +using BBWYB.Client.Views.Ware; +using BBWYB.Common.Models; +using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Messaging; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; + +namespace BBWYB.Client.ViewModels +{ + public class WareManagerViewModel : BaseVM, IDenpendency + { + #region Properties + private PurchaseService purchaseService; + private ProductService productService; + private BindingPurchaseProductViewModel bindingPurchaseProduct; + private GlobalContext globalContext; + private bool isLoading; + private int pageIndex = 1; + private int pageSize; + private int productCount; + private string searchProductName; + private string searchProductItem; + private string searchSpu; + private string searchSku; + + public bool IsLoading { get => isLoading; set { SetProperty(ref isLoading, value); } } + + public IList ProductList { get; set; } + public int PageIndex { get => pageIndex; set { SetProperty(ref pageIndex, value); } } + public int PageSize { get => pageSize; set { SetProperty(ref pageSize, value); } } + public int ProductCount { get => productCount; set { SetProperty(ref productCount, value); } } + + public string SearchProductName { get => searchProductName; set { SetProperty(ref searchProductName, value); } } + public string SearchProductItem { get => searchProductItem; set { SetProperty(ref searchProductItem, value); } } + public string SearchSpu { get => searchSpu; set { SetProperty(ref searchSpu, value); } } + public string SearchSku { get => searchSku; set { SetProperty(ref searchSku, value); } } + #endregion + + #region Commands + public ICommand AddPurchaserCommand { get; set; } + public ICommand EditPurchaserCommand { get; set; } + public ICommand DeletePurchaserCommand { get; set; } + public ICommand SearchCommand { get; set; } + public ICommand ProductPageIndexChangedCommand { get; set; } + + public ICommand SwitchPurchasePlatformCommand { get; set; } + #endregion + + #region Methods + public WareManagerViewModel(GlobalContext globalContext, BindingPurchaseProductViewModel bindingPurchaseProduct, PurchaseService purchaseService, ProductService productService) + { + AddPurchaserCommand = new RelayCommand(AddPurchaser); + EditPurchaserCommand = new RelayCommand(EditPurchaser); + DeletePurchaserCommand = new RelayCommand(DeletePurchaser); + SwitchPurchasePlatformCommand = new RelayCommand(SwitchPurchasePlatform); + SearchCommand = new RelayCommand(() => + { + PageIndex = 1; + Task.Factory.StartNew(() => LoadWare(1)); + }); + ProductPageIndexChangedCommand = new RelayCommand((p) => Task.Factory.StartNew(() => LoadWare(p.PageIndex))); + this.purchaseService = purchaseService; + this.productService = productService; + this.globalContext = globalContext; + this.bindingPurchaseProduct = bindingPurchaseProduct; + ProductList = new ObservableCollection(); + Task.Factory.StartNew(() => LoadWare(1)); + } + + public override void Refresh() + { + this.ProductList.Clear(); + this.ProductCount = 0; + PageIndex = 1; + } + + protected override void Load() + { + Console.WriteLine($"{VMId} {DateTime.Now}"); + } + + private void LoadWare(int pageIndex) + { + if (!string.IsNullOrEmpty(SearchSpu) && !string.IsNullOrEmpty(SearchSku)) + { + App.Current.Dispatcher.Invoke(() => MessageBox.Show("SPU和SKU条件不能共存")); + return; + } + + App.Current.Dispatcher.Invoke(() => ProductList.Clear()); + + IsLoading = true; + + #region 加载JD商品列表 + ApiResponse productApiResponse = null; + if (!string.IsNullOrEmpty(SearchSku)) + { + var skuResponse = productService.GetProductSkuList(string.Empty, SearchSku); + if (skuResponse.Success) + { + if (skuResponse.Data.Count == 0) + { + IsLoading = false; + return; + } + productApiResponse = productService.GetProductList(skuResponse.Data[0].ProductId, string.Empty, string.Empty, pageIndex); + } + else + { + IsLoading = false; + App.Current.Dispatcher.Invoke(() => MessageBox.Show(skuResponse.Msg, "加载sku")); + return; + } + } + else + { + productApiResponse = productService.GetProductList(SearchSpu, SearchProductName, SearchProductItem, pageIndex); + } + + if (!productApiResponse.Success) + { + IsLoading = false; + App.Current.Dispatcher.Invoke(() => MessageBox.Show(productApiResponse.Msg, "加载产品")); + return; + } + var productList = productApiResponse.Data.Items; + ProductCount = productApiResponse.Data.Count; + if (ProductCount == 0) + { + IsLoading = false; + return; + } + #endregion + + #region 加载JDSKU列表 + var waitList = new List(); + foreach (var p in productList) + { + p.CreatePlatformList(); + var ewh = new ManualResetEvent(false); + waitList.Add(ewh); + Task.Factory.StartNew(() => LoadSku(p, ewh)); + } + WaitHandle.WaitAll(waitList.ToArray(), 8000); + #endregion + + #region 加载采购方案 + var skuList = new List(); + foreach (var p in productList) + skuList.AddRange(p.SkuList); + LoadPurchaseScheme(skuList); + #endregion + + App.Current.Dispatcher.BeginInvoke((Action)delegate + { + foreach (var p in productList) + ProductList.Add(p); + ExtractPurchaser(); + //使滚动条保持顶部 + //Messenger.Default.Send(string.Empty, "WareManager_ProductListScrollToTop"); + WeakReferenceMessenger.Default.Send(new Message_WareManager_ProductListScrollToTop(null)); + }); + + IsLoading = false; + } + + private void LoadSku(Product product, EventWaitHandle ewh) + { + try + { + var skuResponse = productService.GetProductSkuList(product.Id, string.Empty); + if (!skuResponse.Success) + { + IsLoading = false; + App.Current.Dispatcher.Invoke(() => MessageBox.Show(skuResponse.Msg, "加载sku")); + return; + } + product.SkuList = skuResponse.Data; + } + catch (Exception ex) + { + + } + finally + { + ewh.Set(); + } + } + + /// + /// 加载采购方案 + /// + /// + private void LoadPurchaseScheme(IList skuList, Platform? purchasePlatform = Platform.阿里巴巴) + { + var response = purchaseService.GetPurchaseSchemeList(skuList.Select(s => s.Id).ToList(), string.Empty, globalContext.User.Shop.ShopId, purchasePlatform: purchasePlatform); + if (!response.Success) + { + App.Current.Dispatcher.BeginInvoke((Action)delegate { MessageBox.Show(response.Msg, "获取采购方案"); }); + return; + } + + var schemeList = response.Data; + + App.Current.Dispatcher.Invoke(() => + { + foreach (var s in skuList) + { + s.PurchaseSchemeList.Clear(); + var currentSchemeList = schemeList.Where(scheme => scheme.SkuId == s.Id); + if (currentSchemeList.Count() > 0) + foreach (var scheme in currentSchemeList) + s.PurchaseSchemeList.Add(PurchaseScheme.Convert(scheme)); + } + }); + } + + /// + /// 提取SKU中的采购商到商品的采购商列表中 + /// + private void ExtractPurchaser(string productId = "") + { + var productList = string.IsNullOrEmpty(productId) ? ProductList : ProductList.Where(p => p.Id == productId); + foreach (var product in productList) + { + product.PurchaserList.Clear(); + foreach (var sku in product.SkuList) + { + if (sku.PurchaseSchemeList.Count() > 0) + { + foreach (var pscheme in sku.PurchaseSchemeList) + { + var purchaser = product.PurchaserList.FirstOrDefault(purchaser => purchaser.Id == pscheme.PurchaserId); + if (purchaser == null) + { + purchaser = new Purchaser() { Id = pscheme.PurchaserId, Name = pscheme.PurchaserName, ProductId = product.Id }; + product.PurchaserList.Add(purchaser); + } + purchaser.SkuUseCount++; + } + } + } + } + } + + private void AddPurchaser(Product product) + { + if (product.PurchaserList.Count >= 5) + { + MessageBox.Show("一个SPU内最多允许5个采购商"); + return; + } + + OpenBindingView(product, string.Empty, string.Empty); + } + + private void EditPurchaser(Purchaser purchaser) + { + var product = ProductList.FirstOrDefault(p => p.Id == purchaser.ProductId); + OpenBindingView(product, purchaser.Id, purchaser.Name); + } + + private void DeletePurchaser(Purchaser purchaser) + { + if (MessageBox.Show("确认删除该采购商吗?", "提示", MessageBoxButton.OKCancel) != MessageBoxResult.OK) + return; + IsLoading = true; + Task.Factory.StartNew(() => + { + var response = purchaseService.DeletePurchaser(purchaser.ProductId, purchaser.Id); + IsLoading = false; + if (response.Success) + { + App.Current.Dispatcher.BeginInvoke((Action)delegate + { + var product = ProductList.FirstOrDefault(p => p.Id == purchaser.ProductId); + if (product != null) + { + foreach (var sku in product.SkuList) + { + var deleteScheme = sku.PurchaseSchemeList.FirstOrDefault(s => s.PurchaserId == purchaser.Id); + if (deleteScheme != null) + sku.PurchaseSchemeList.Remove(deleteScheme); + } + product.PurchaserList.Remove(purchaser); + } + MessageBox.Show("采购商删除成功", "提示"); + }); + } + else + { + App.Current.Dispatcher.BeginInvoke((Action)delegate + { + MessageBox.Show(response.Msg, "采购商删除"); + }); + } + }); + } + + private void OpenBindingView(Product product, string purchaserId, string purchaserName) + { + var skuList = product.SkuList; + bindingPurchaseProduct.SetData(skuList, purchaserId, purchaserName, product.SelectedPurchasePlatformModel); + var bindingView = new BindingPurchaseProduct(); + var r = bindingView.ShowDialog(); + if (r == true) + { + Console.WriteLine("Refresh PurchaseScheme"); + Task.Factory.StartNew(() => + { + IsLoading = true; + LoadPurchaseScheme(skuList, product.SelectedPurchasePlatformModel); + IsLoading = false; + App.Current.Dispatcher.BeginInvoke((Action)delegate + { + ExtractPurchaser(product.Id); + }); + }); + } + } + + private void SwitchPurchasePlatform(object param) + { + var paramList = (object[])param; + var productId = paramList[0].ToString(); + var platform = (Platform)paramList[1]; + + var product = ProductList.FirstOrDefault(p => p.Id == productId); + IsLoading = true; + Task.Factory.StartNew(() => LoadPurchaseScheme(product.SkuList, platform)) + .ContinueWith(t => + { + App.Current.Dispatcher.Invoke(() => ExtractPurchaser(productId)); + IsLoading = false; + }); + } + #endregion + + + + } +} diff --git a/BBWYB.Client/ViewModels/Ware/WareStockViewModel.cs b/BBWYB.Client/ViewModels/Ware/WareStockViewModel.cs new file mode 100644 index 0000000..0c1c829 --- /dev/null +++ b/BBWYB.Client/ViewModels/Ware/WareStockViewModel.cs @@ -0,0 +1,339 @@ +using BBWYB.Client.APIServices; +using BBWYB.Client.Models; +using BBWYB.Client.Views.Ware; +using BBWYB.Common.Extensions; +using BBWYB.Common.Models; +using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Messaging; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; + +namespace BBWYB.Client.ViewModels +{ + public class WareStockViewModel : BaseVM, IDenpendency + { + #region Property + private PurchaseOrderService purchaseOrderService; + private ProductService productService; + private GlobalContext globalContext; + + private bool isLoading; + private int pageIndex = 1; + private int pageSize; + private int productCount; + private string searchProductItem; + private string searchSpu; + private string searchSku; + private string searchPurchaseOrder; + + public bool IsLoading { get => isLoading; set { SetProperty(ref isLoading, value); } } + public int PageIndex { get => pageIndex; set { SetProperty(ref pageIndex, value); } } + public int PageSize { get => pageSize; set { SetProperty(ref pageSize, value); } } + public int ProductCount { get => productCount; set { SetProperty(ref productCount, value); } } + public string SearchProductItem { get => searchProductItem; set { SetProperty(ref searchProductItem, value); } } + public string SearchSpu { get => searchSpu; set { SetProperty(ref searchSpu, value); } } + public string SearchSku { get => searchSku; set { SetProperty(ref searchSku, value); } } + public string SearchPurchaseOrder { get => searchPurchaseOrder; set { SetProperty(ref searchPurchaseOrder, value); } } + + public IList ProductList { get; set; } + #endregion + + #region ICommand + public ICommand SearchCommand { get; set; } + public ICommand ProductPageIndexChangedCommand { get; set; } + public ICommand AddPurchaserOrderCommand { get; set; } + public ICommand EditPurchaseOrderCommand { get; set; } + public ICommand DeletePurchaseOrderCommand { get; set; } + public ICommand SavePurchaseOrderCommand { get; set; } + public ICommand SwitchStorageTypeCommand { get; set; } + #endregion + + #region Method + public WareStockViewModel(GlobalContext globalContext, PurchaseOrderService purchaseOrderService, ProductService productService) + { + this.globalContext = globalContext; + this.purchaseOrderService = purchaseOrderService; + this.productService = productService; + ProductList = new ObservableCollection(); + + SearchCommand = new RelayCommand(() => + { + PageIndex = 1; + Task.Factory.StartNew(() => LoadWare(1)); + }); + ProductPageIndexChangedCommand = new RelayCommand((p) => Task.Factory.StartNew(() => LoadWare(p.PageIndex))); + SwitchStorageTypeCommand = new RelayCommand(SwitchStorageType); + AddPurchaserOrderCommand = new RelayCommand(AddPurchaserOrder); + EditPurchaseOrderCommand = new RelayCommand(po => po.IsEdit = true); + DeletePurchaseOrderCommand = new RelayCommand(DeletePurchaseOrder); + SavePurchaseOrderCommand = new RelayCommand(SavePurchaseOrder); + Task.Factory.StartNew(() => LoadWare(1)); + } + + public override void Refresh() + { + ProductList.Clear(); + ProductCount = 0; + PageSize = 1; + } + private void LoadWare(int pageIndex) + { + if (!string.IsNullOrEmpty(SearchSpu) && !string.IsNullOrEmpty(SearchSku)) + { + App.Current.Dispatcher.Invoke(() => MessageBox.Show("SPU和SKU条件不能共存")); + return; + } + + App.Current.Dispatcher.Invoke(() => ProductList.Clear()); + + IsLoading = true; + + #region 加载JD商品列表 + ApiResponse productApiResponse = null; + if (!string.IsNullOrEmpty(SearchSku)) + { + var skuResponse = productService.GetProductSkuList(string.Empty, SearchSku); + if (skuResponse.Success) + { + if (skuResponse.Data.Count == 0) + { + IsLoading = false; + return; + } + productApiResponse = productService.GetProductList(skuResponse.Data[0].ProductId, string.Empty, string.Empty, pageIndex); + } + else + { + IsLoading = false; + App.Current.Dispatcher.Invoke(() => MessageBox.Show(skuResponse.Msg, "加载sku")); + return; + } + } + else + { + productApiResponse = productService.GetProductList(SearchSpu, string.Empty, SearchProductItem, pageIndex); + } + + if (!productApiResponse.Success) + { + IsLoading = false; + App.Current.Dispatcher.Invoke(() => MessageBox.Show(productApiResponse.Msg, "加载产品")); + return; + } + var productList = productApiResponse.Data.Items; + ProductCount = productApiResponse.Data.Count; + if (ProductCount == 0) + { + IsLoading = false; + return; + } + #endregion + + #region 加载JDSKU列表 + var waitList = new List(); + foreach (var p in productList) + { + var ewh = new ManualResetEvent(false); + waitList.Add(ewh); + Task.Factory.StartNew(() => LoadSku(p, ewh)); + } + WaitHandle.WaitAll(waitList.ToArray(), 8000); + #endregion + + #region 加载采购单 + LoadPurchaseOrder(productList, StorageType.京仓); + #endregion + + App.Current.Dispatcher.BeginInvoke((Action)delegate + { + foreach (var p in productList) + ProductList.Add(p); + //使滚动条保持顶部 + //Messenger.Default.Send(string.Empty, "WareStock_ProductListScrollToTop"); + WeakReferenceMessenger.Default.Send(new Message_WareStock_ProductListScrollToTop(null)); + }); + + IsLoading = false; + } + + private void LoadSku(Product product, EventWaitHandle ewh) + { + try + { + var skuResponse = productService.GetProductSkuList(product.Id, string.Empty); + if (!skuResponse.Success) + { + IsLoading = false; + App.Current.Dispatcher.Invoke(() => MessageBox.Show(skuResponse.Msg, "加载sku")); + return; + } + foreach (var sku in skuResponse.Data) + { + sku.StorageList.Add(new StorageModel() + { + ProductId = product.Id, + SkuId = sku.Id, + StorageType = StorageType.京仓 + }); + sku.StorageList.Add(new StorageModel() + { + ProductId = product.Id, + SkuId = sku.Id, + StorageType = StorageType.云仓 + }); + sku.StorageList.Add(new StorageModel() + { + ProductId = product.Id, + SkuId = sku.Id, + StorageType = StorageType.本地自发 + }); + sku.SelectedStorageModel = sku.StorageList[0]; + } + product.SkuList = skuResponse.Data; + } + catch (Exception ex) + { + + } + finally + { + ewh.Set(); + } + } + + private void LoadPurchaseOrder(IList productList, StorageType storageType) + { + var skuList = new List(); + foreach (var p in productList) + skuList.AddRange(p.SkuList); + LoadPurchaseOrder(skuList, storageType); + } + + private void LoadPurchaseOrder(IList skuList, StorageType storageType) + { + App.Current.Dispatcher.Invoke(() => + { + foreach (var s in skuList) + s.PurchaseOrderList.Clear(); + }); + var response = purchaseOrderService.GetList(skuList.Select(s => s.Id).ToList(), storageType, globalContext.User.Shop.ShopId); + if (response.Success) + { + var purchaseOrderList = response.Data; + App.Current.Dispatcher.Invoke(() => + { + foreach (var s in skuList) + { + var currentSkuPurchaseOrderList = purchaseOrderList.Where(po => po.SkuId == s.Id).Map>(); + foreach (var po in currentSkuPurchaseOrderList) + s.PurchaseOrderList.Add(po); + } + }); + } + } + + private void SwitchStorageType(StorageModel storageModel) + { + var product = ProductList.FirstOrDefault(p => p.Id == storageModel.ProductId); + var sku = product.SkuList.FirstOrDefault(s => s.Id == storageModel.SkuId); + if (sku.SelectedStorageModel == storageModel) + return; + sku.SelectedStorageModel = storageModel; + IsLoading = true; + Task.Factory.StartNew(() => + { + LoadPurchaseOrder(new List() { sku }, storageModel.StorageType); + IsLoading = false; + }); + } + + private void AddPurchaserOrder(Product product) + { + foreach (var sku in product.SkuList) + sku.PurchaseOrderList.Add(new PurchaseOrder + { + IsEdit = true, + SkuId = sku.Id, + ProductId = product.Id, + UserId = globalContext.User.Id, + StorageType = sku.SelectedStorageModel.StorageType, + PurchaseMethod = PurchaseMethod.线下采购, + CreateTime = DateTime.Now, + ShopId = globalContext.User.Shop.ShopId, + PurchasePlatform = Platform.阿里巴巴 + }); + } + + private void DeletePurchaseOrder(PurchaseOrder purchaseOrder) + { + var product = ProductList.FirstOrDefault(p => p.Id == purchaseOrder.ProductId); + var sku = product.SkuList.FirstOrDefault(s => s.Id == purchaseOrder.SkuId); + if (purchaseOrder.Id == 0) + { + sku.PurchaseOrderList.Remove(purchaseOrder); + } + else + { + if (MessageBox.Show("确定要删除采购单吗?", "确认", MessageBoxButton.OKCancel) != MessageBoxResult.OK) + return; + IsLoading = true; + Task.Factory.StartNew(() => + { + var response = purchaseOrderService.DeletePurchaseOrder(purchaseOrder.Id); + IsLoading = false; + App.Current.Dispatcher.BeginInvoke((Action)delegate + { + if (response.Success) + sku.PurchaseOrderList.Remove(purchaseOrder); + else + MessageBox.Show(response.Msg, "删除采购单"); + }); + }); + } + } + + private void SavePurchaseOrder(PurchaseOrder purchaseOrder) + { + if (purchaseOrder.PurchasePlatform == null || + string.IsNullOrEmpty(purchaseOrder.PurchaseOrderId) || + purchaseOrder.PurchaseQuantity == 0) + { + MessageBox.Show("缺少必要信息", "保存采购单"); + return; + } + + if (purchaseOrder.RemainingQuantity > purchaseOrder.PurchaseQuantity) + { + MessageBox.Show("剩余库存不成超过采购数量", "保存采购单"); + return; + } + + purchaseOrder.IsEdit = false; + var product = ProductList.FirstOrDefault(p => p.Id == purchaseOrder.ProductId); + var sku = product.SkuList.FirstOrDefault(s => s.Id == purchaseOrder.SkuId); + IsLoading = true; + Task.Factory.StartNew(() => + { + var response = purchaseOrder.Id == 0 ? purchaseOrderService.AddPurchaseOrder(purchaseOrder) : + purchaseOrderService.EditPurchaseOrder(purchaseOrder); + IsLoading = false; + if (response.Success) + { + if (purchaseOrder.Id == 0) + LoadPurchaseOrder(new List() { sku }, purchaseOrder.StorageType.Value); + } + else + { + App.Current.Dispatcher.Invoke(() => MessageBox.Show(response.Msg, "保存采购单")); + } + }); + } + #endregion + } +} diff --git a/BBWYB.Client/Views/MainWindow.xaml b/BBWYB.Client/Views/MainWindow.xaml index ff9494f..6576e1c 100644 --- a/BBWYB.Client/Views/MainWindow.xaml +++ b/BBWYB.Client/Views/MainWindow.xaml @@ -23,8 +23,6 @@ - @@ -76,40 +74,6 @@ Source="{Binding SelectedMenuModel.Url}" Grid.Column="1"/> - - - - - diff --git a/BBWYB.Client/Views/Ware/BindingPurchaseProduct.xaml b/BBWYB.Client/Views/Ware/BindingPurchaseProduct.xaml new file mode 100644 index 0000000..b1ab4a4 --- /dev/null +++ b/BBWYB.Client/Views/Ware/BindingPurchaseProduct.xaml @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BBWYB.Client/Views/Ware/BindingPurchaseProduct.xaml.cs b/BBWYB.Client/Views/Ware/BindingPurchaseProduct.xaml.cs new file mode 100644 index 0000000..666ed7e --- /dev/null +++ b/BBWYB.Client/Views/Ware/BindingPurchaseProduct.xaml.cs @@ -0,0 +1,50 @@ +using CommunityToolkit.Mvvm.Messaging; +using CommunityToolkit.Mvvm.Messaging.Messages; +using SJ.Controls; +using System.Windows; + +namespace BBWYB.Client.Views.Ware +{ + /// + /// BindingPurchaseProduct.xaml 的交互逻辑 + /// + public partial class BindingPurchaseProduct : BWindow + { + public BindingPurchaseProduct() + { + InitializeComponent(); + //Messenger.Default.Register(this, "BindingPurchaseProduct_Close", (x) => + // { + // this.Dispatcher.Invoke(() => + // { + // this.DialogResult = x; + // this.Close(); + // }); + // }); + + WeakReferenceMessenger.Default.Register(this, (o, x) => + { + this.Dispatcher.Invoke(() => + { + this.DialogResult = x.Value; + this.Close(); + }); + }); + + this.Unloaded += BindingPurchaseProduct_Unloaded; + } + + private void BindingPurchaseProduct_Unloaded(object sender, RoutedEventArgs e) + { + //Messenger.Default.Unregister(this); + WeakReferenceMessenger.Default.UnregisterAll(this); + } + } + + public class Message_BindingPurchaseProductClose : ValueChangedMessage + { + public Message_BindingPurchaseProductClose(bool value) : base(value) + { + } + } +} diff --git a/BBWYB.Client/Views/Ware/WareManager.xaml b/BBWYB.Client/Views/Ware/WareManager.xaml new file mode 100644 index 0000000..505200b --- /dev/null +++ b/BBWYB.Client/Views/Ware/WareManager.xaml @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BBWYB.Client/Views/Ware/WareManager.xaml.cs b/BBWYB.Client/Views/Ware/WareManager.xaml.cs new file mode 100644 index 0000000..be80adb --- /dev/null +++ b/BBWYB.Client/Views/Ware/WareManager.xaml.cs @@ -0,0 +1,50 @@ +using CommunityToolkit.Mvvm.Messaging; +using CommunityToolkit.Mvvm.Messaging.Messages; +using SJ.Controls.Extensions; +using System.Windows; +using System.Windows.Controls; + +namespace BBWYB.Client.Views.Ware +{ + /// + /// WareManager.xaml 的交互逻辑 + /// + public partial class WareManager : Page + { + private ScrollViewer scrollviewer_ProductList; + + public WareManager() + { + InitializeComponent(); + this.Loaded += WareManager_Loaded; + this.Unloaded += WareManager_Unloaded; + //Messenger.Default.Register(this, "WareManager_ProductListScrollToTop", (x) => + //{ + // scrollviewer_ProductList.Dispatcher.Invoke(() => scrollviewer_ProductList.ScrollToTop()); + //}); + + WeakReferenceMessenger.Default.Register(this, (o, x) => + { + scrollviewer_ProductList.Dispatcher.Invoke(() => scrollviewer_ProductList.ScrollToTop()); + }); + } + + private void WareManager_Unloaded(object sender, RoutedEventArgs e) + { + //Messenger.Default.Unregister(this); + WeakReferenceMessenger.Default.UnregisterAll(this); + } + + private void WareManager_Loaded(object sender, RoutedEventArgs e) + { + scrollviewer_ProductList = listbox_productList.FindFirstVisualChild(); + } + } + + public class Message_WareManager_ProductListScrollToTop : ValueChangedMessage + { + public Message_WareManager_ProductListScrollToTop(object value) : base(value) + { + } + } +} diff --git a/BBWYB.Client/Views/Ware/WareStock.xaml b/BBWYB.Client/Views/Ware/WareStock.xaml new file mode 100644 index 0000000..b99668f --- /dev/null +++ b/BBWYB.Client/Views/Ware/WareStock.xaml @@ -0,0 +1,423 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BBWYB.Client/Views/Ware/WareStock.xaml.cs b/BBWYB.Client/Views/Ware/WareStock.xaml.cs new file mode 100644 index 0000000..332a626 --- /dev/null +++ b/BBWYB.Client/Views/Ware/WareStock.xaml.cs @@ -0,0 +1,48 @@ +using CommunityToolkit.Mvvm.Messaging; +using CommunityToolkit.Mvvm.Messaging.Messages; +using SJ.Controls.Extensions; +using System.Windows; +using System.Windows.Controls; + +namespace BBWYB.Client.Views.Ware +{ + /// + /// WareStock.xaml 的交互逻辑 + /// + public partial class WareStock : Page + { + private ScrollViewer scrollviewer_ProductList; + public WareStock() + { + InitializeComponent(); + this.Loaded += WareStock_Loaded; + this.Unloaded += WareStock_Unloaded; + //Messenger.Default.Register(this, "WareStock_ProductListScrollToTop", (x) => + //{ + // scrollviewer_ProductList.Dispatcher.Invoke(() => scrollviewer_ProductList.ScrollToTop()); + //}); + WeakReferenceMessenger.Default.Register(this, (o, x) => + { + scrollviewer_ProductList.Dispatcher.Invoke(() => scrollviewer_ProductList.ScrollToTop()); + }); + } + + private void WareStock_Unloaded(object sender, RoutedEventArgs e) + { + //Messenger.Default.Unregister(this); + WeakReferenceMessenger.Default.UnregisterAll(this); + } + + private void WareStock_Loaded(object sender, RoutedEventArgs e) + { + scrollviewer_ProductList = listbox_productList.FindFirstVisualChild(); + } + } + + public class Message_WareStock_ProductListScrollToTop : ValueChangedMessage + { + public Message_WareStock_ProductListScrollToTop(object value) : base(value) + { + } + } +} diff --git a/SDKAdapter/SDKAdapter.csproj b/SDKAdapter/SDKAdapter.csproj new file mode 100644 index 0000000..132c02c --- /dev/null +++ b/SDKAdapter/SDKAdapter.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/SJ.Controls/Extensions/VisualTreeExtension.cs b/SJ.Controls/Extensions/VisualTreeExtension.cs index 1664ae3..e6adc3e 100644 --- a/SJ.Controls/Extensions/VisualTreeExtension.cs +++ b/SJ.Controls/Extensions/VisualTreeExtension.cs @@ -3,7 +3,7 @@ using System.Windows; using System.Windows.Input; using System.Windows.Media; -namespace BBGWY.Controls.Extensions +namespace SJ.Controls.Extensions { public static class VisualTreeExtension { diff --git a/bbwyb.sln b/bbwyb.sln index 8170464..d10c859 100644 --- a/bbwyb.sln +++ b/bbwyb.sln @@ -19,7 +19,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{1191C1 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BBWYB.Common", "BBWYB.Common\BBWYB.Common.csproj", "{DD328472-01CE-4CA8-AF29-C098FC499483}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SJ.Controls", "SJ.Controls\SJ.Controls.csproj", "{0415B31B-5A4E-4F7C-9F3B-69CB6284E4F1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SJ.Controls", "SJ.Controls\SJ.Controls.csproj", "{0415B31B-5A4E-4F7C-9F3B-69CB6284E4F1}" +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}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -51,6 +55,10 @@ Global {0415B31B-5A4E-4F7C-9F3B-69CB6284E4F1}.Debug|Any CPU.Build.0 = Debug|Any CPU {0415B31B-5A4E-4F7C-9F3B-69CB6284E4F1}.Release|Any CPU.ActiveCfg = Release|Any CPU {0415B31B-5A4E-4F7C-9F3B-69CB6284E4F1}.Release|Any CPU.Build.0 = Release|Any CPU + {442CC858-3A90-48EE-932D-756169EAC2A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -62,6 +70,7 @@ Global {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} + {442CC858-3A90-48EE-932D-756169EAC2A4} = {B4ED118A-2CFF-4E8F-B395-608E90C6D0C2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0D069898-04B7-4D24-A6A4-D7C703B8BFFC}