diff --git a/29WxOrderWpf/29WxOrderWpf.csproj b/29WxOrderWpf/29WxOrderWpf.csproj index 1b34088..ef214a5 100644 --- a/29WxOrderWpf/29WxOrderWpf.csproj +++ b/29WxOrderWpf/29WxOrderWpf.csproj @@ -63,8 +63,10 @@ + + diff --git a/29WxOrderWpf/Converters/ImageUrlToBitmapImageConverter.cs b/29WxOrderWpf/Converters/ImageUrlToBitmapImageConverter.cs index dfbf7e4..2063aaf 100644 --- a/29WxOrderWpf/Converters/ImageUrlToBitmapImageConverter.cs +++ b/29WxOrderWpf/Converters/ImageUrlToBitmapImageConverter.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -14,27 +15,38 @@ namespace _29WxOrderWpf.Converters { public class ImageUrlToBitmapImageConverter : IValueConverter { + /// 缓存上限,防止大量缩略图重复下载导致内存膨胀 + private const int MaxCacheCount = 200; + + private readonly ConcurrentDictionary _imageCache = new ConcurrentDictionary(); + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is string url && Uri.IsWellFormedUriString(url, UriKind.Absolute)) { + if (_imageCache.TryGetValue(url, out BitmapImage cached)) + { + return cached; + } + try { // 直接加载绑定如果遇到有问题的网络图片会直接崩溃。 - //var bitMap = new BitmapImage(new Uri(url)); - BitmapImage bitMap = null; - //bitMap = LoadImageFromUrl(url + "?imageView2/1/w/100/format/webp|imageMogr2/auto-orient="); - bitMap = AllBase.ImageBuild.LoadBitmipImageFromUrl(url); + BitmapImage bitMap = AllBase.ImageBuild.LoadBitmipImageFromUrl(url); + if (bitMap != null) + { + if (_imageCache.Count >= MaxCacheCount) + { + _imageCache.Clear(); + } + _imageCache[url] = bitMap; + } return bitMap; - //string errStr = ""; - //var bitmapImg = GetUrlImg(url, out errStr); - //return bitmapImg; } catch { } - //return Task.Run(() => new BitmapImage(new Uri(url))); // 使用 Task.Run 来异步加载图片。 } return null; } diff --git a/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.Command.cs b/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.Command.cs new file mode 100644 index 0000000..becbbc4 --- /dev/null +++ b/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.Command.cs @@ -0,0 +1,318 @@ +using _29WxOrderWpf.BaseWindows; +using _29WxOrderWpf.Commands; +using _29WxOrderWpf.Common; +using _29WxOrderWpf.Ctrls.PDDInvoice; +using _29WxOrderWpf.Ctrls.Statistics; +using _29WxOrderWpf.Services; +using AllBase.Helper; +using AllBase.Model.DBModel; +using NaiBa.Util.Extension; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using Work._29Tools.BLL; +using static _29WxOrderWpf.Services.ShipGiftService; + +namespace _29WxOrderWpf.Ctrls.OrderCtrls; + +public partial class OrderListCtrl +{ + #region 统计 + private DialogWindow _statisticsDialog; + public ICommand ShowShopRevenueStatisticsDialogViewCommand => new DelegateCommand(ShowShopRevenueStatisticsDialogView); + + private void ShowShopRevenueStatisticsDialogView() + { + if (_statisticsDialog == null) + { + _statisticsDialog = new DialogWindow() + { + Title = "统计", + Content = new ShopRevenueStatisticsView(), + + }; + _statisticsDialog.Closed += (s, e) => _statisticsDialog = null; + } + _statisticsDialog.Show(); + } + #endregion + + #region 礼物 + public ICommand MultipleShipGiftCommand => new AsyncDelegateCommand(MultipleShipGift); + /// + /// 批量发送礼品单 + /// + /// + /// + + private async Task MultipleShipGift() + { + + try + { + var list = GlobalConfig.lstFilterOrder.Where(a => a.IsSelect).ToList(); + int count = list.Count; + if (count == 0) + { + BaseMsgWindow.ShowError("请选取要发货的订单", "Error"); + return; + } + + + GiftType giftType = GiftType._160; + if (cb_gift.SelectedIndex == 0) + { + giftType = GiftType._155; + } + else + { + giftType = GiftType._160; + } + int index = 1; + int sucessCount = 0; + int errorCount = 0; + foreach (oms_wei_order_info item in list) + { + try + { + var rst = await WxApiBLL.WxSearchAndDropshipCancelAsync(item.Shop, item); + if (rst == "success") + { + var ret = await _shipGiftService.Send(item.order_id, giftType); + if (ret) + { + sucessCount++; + item.gift_order_status = 1; + this.FilterOneOrder(item, true); + } + else + { + errorCount++; + } + } + else + { + errorCount++; + } + } + catch (Exception ex) + { + errorCount++; + } + finally + { + item.IsSelect = false; + } + + SetProgress(index, count); + BottomMsg = $"礼品单发送进度:{index}/{count}\t\t{item.orderItems.FirstOrDefault()?.title ?? ""}"; + index++; + } + + BottomMsg = $"礼品单发送完成 成功:{sucessCount} 失败:{errorCount} 总数:{count}"; + } + catch (Exception ex) + { + BaseMsgWindow.ShowError("礼品单发货失败\n" + ex.Message, "Error"); + } + finally + { + + } + } + #endregion + #region 同步订单 + /// + /// 拉取微信订单到任务列表 + /// + public ICommand PullWXOrderCommand => new AsyncDelegateCommand(PullWXOrder); + + private async Task PullWXOrder() + { + try + { + var isAfterSales = GlobalConfig.OrderTabHeaderStr.StartsWith("需处理售后单");//是否售后 + + var selectedShops = GlobalConfig.ShopLoginList.Where(a => a.IsSelect).ToList(); + if (selectedShops.Count == 0) + { + selectedShops = GlobalConfig.ShopLoginList.ToList(); + } + + var selectedOrders = GlobalConfig.lstFilterOrder.Where(a => a.IsSelect).ToList(); + int count = selectedOrders.Count; + if (count > 0 && isAfterSales == false)//非售后订单 + { + if (BaseMsgWindow.ShowConfirm($"已选取:{count}个订单", "同步订单", MainWindow.Instance, MsgWindowLevel.MEDIUM).DialogResult == false) return; + BottomMsg = $"订单同步进度...."; + int index = 1; + int sucessCount = 0; + int errorCount = 0; + foreach (var item in selectedOrders) + { + var ret = await PullWXOrderService.Instance.PullOrderDetailAsync(item.shop_id, item.order_id); ; + if (ret) + { + sucessCount++; + this.GetOrder(item.order_id); + SetProgress(index, count); + item.IsSelect = false; + } + else + { + errorCount++; + } + BottomMsg = $"订单同步进度:{index}/{count}\t\t{item.orderItems.FirstOrDefault()?.title ?? ""}"; + index++; + } + BottomMsg = $"订单同步进度完成 成功:{sucessCount} 失败:{errorCount} 总数:{count}"; + } + else if (count > 0 && isAfterSales == true)//售后订单 + { + if (BaseMsgWindow.ShowConfirm($"已选取:{count}个售后订单", "同步订单", MainWindow.Instance, MsgWindowLevel.MEDIUM).DialogResult == false) return; + //var dictionaryResult = selectedOrders + // .Where(o => o?.refundItems != null) + // .SelectMany(o => o.refundItems + // .Where(item => item != null) + // .Select(item => new { o.shop_id, item.after_sale_order_id })) + // .GroupBy(x => x.shop_id) + // .ToDictionary( + // g => g.Key, + // g => g.Select(x => x.after_sale_order_id).ToArray() + // ); + + + //BottomMsg = $"售后订单同步进度...."; + //foreach (var item in dictionaryResult) + //{ + // var ret = await PullWXOrderService.Instance.PullAfterSaleOrdersAsync(item.Key, item.Value); + //} + //BottomMsg = $"售后同步任务已发送,等待同步完成"; + + + + int index = 1; + int sucessCount = 0; + int errorCount = 0; + BottomMsg = $"售后订单同步进度...."; + foreach (KeyValuePair> item in selectedOrders.GroupBy(a => a.shop_id).ToDictionary(a => a.Key, a => a.ToList())) + { + long shopid = item.Key; + string shopName = item.Value.FirstOrDefault()?.shop_name ?? ""; + string[] afterSaleOrderIds = item.Value.SelectMany(a => a.refundItems).Where(a => a != null).Select(a => a.after_sale_order_id).ToArray(); + var ret = await PullWXOrderService.Instance.PullAfterSaleOrdersAsync(shopid, afterSaleOrderIds); + if (ret) + { + sucessCount++; + SetProgress(index, count); + item.Value.ForEach(a => a.IsSelect = false); + } + else + { + errorCount++; + } + BottomMsg = $"售后订单同步进度:{index}/{count}\t\t{shopName}"; + index++; + + } + BottomMsg = $"售后同步任务已发送,等待同步完成"; + } + else + { + count = selectedShops.Count; + string prefix = $"已选取:{count}个商铺"; + if (count == GlobalConfig.ShopLoginList.Count) + { + prefix = "已选取全部商铺"; + } + + + var startTime = dateStart.SelectedDate.Value; + var endTime = dateEnd.SelectedDate.Value; + + string msg = ""; + if (isAfterSales) + { + msg = $"{prefix}"; + } + else + { + msg = $"{prefix}\n\n时间范围:{startTime.ToString("yyyy-MM-dd")}-{endTime.ToString("yyyy-MM-dd")}"; + } + + if (BaseMsgWindow.ShowConfirm(msg, $"{(isAfterSales ? "售后" : "")}同步订单", MainWindow.Instance, MsgWindowLevel.MEDIUM).DialogResult == false) return; + + if ((endTime - startTime).Days > 7) + { + throw new Exception("时间范围最大7天"); + } + + var ret = false; + if (isAfterSales) + { + ret = await PullWXOrderService.Instance.PullRefundOrderByShopsAsync(selectedShops.Select(a => a.ErpShopId.ParseToLong()).ToArray(), startTime, endTime); + } + else + { + ret = await PullWXOrderService.Instance.PullOrderByShopIdsAndTimeRangeAsync(selectedShops.Select(a => a.ErpShopId.ParseToLong()).ToArray(), startTime, endTime); + } + if (ret) + { + BaseMsgWindow.ShowInfo("同步任务已发送,等待同步完成\n任务详情查看任务列表"); + } + else + { + BaseMsgWindow.ShowError("同步任务失败"); + } + } + + + } + catch (Exception ex) + { + BaseMsgWindow.ShowError("同步订单失败\n" + ex.Message, "Error"); + } + //var service = PullWXOrderService.Instance; + //foreach (var item in list) + //{ + // await service.PullOrderDetailAsync(item.shop_id, item.order_id); + //} + } + #endregion + #region 显示任务列表 + private DialogWindow _taskDialog; + public ICommand ShowTaskDialogViewCommand => new DelegateCommand(ShowTaskDialogView); + + private void ShowTaskDialogView() + { + if (_taskDialog == null) + { + _taskDialog = new DialogWindow() + { + Title = "任务列表", + Content = new OrderTaskDialogView(), + + }; + _taskDialog.Closed += (s, e) => _taskDialog = null; + } + _taskDialog.Show(); + } + #endregion + + #region 拼多多发票 + public ICommand ShowPDDInvoiceDialogCommand => new DelegateCommand(ShowPDDInvoiceDialog); + + private void ShowPDDInvoiceDialog() + { + new DialogWindow + { + Title = "发票助手", + Content = new PDDInvoiceView() + }.Show(); + } + #endregion +} diff --git a/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.xaml b/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.xaml index a280860..e2f9152 100644 --- a/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.xaml +++ b/29WxOrderWpf/Ctrls/OrderCtrls/OrderListCtrl.xaml @@ -271,17 +271,30 @@ IsChecked="true" /> + + - + + _statisticsWindow = null; - } - _statisticsWindow.Show(); - - } + /// /// @@ -2296,263 +2281,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls // set => SetProperty(ref _IsShipGift, value); //} - public ICommand MultipleShipGiftCommand => new AsyncDelegateCommand(MultipleShipGift); - /// - /// 批量发送礼品单 - /// - /// - /// - private async Task MultipleShipGift() - { - - try - { - var list = GlobalConfig.lstFilterOrder.Where(a => a.IsSelect).ToList(); - int count = list.Count; - if (count == 0) - { - BaseMsgWindow.ShowError("请选取要发货的订单", "Error"); - return; - } - - - GiftType giftType = GiftType._160; - if (cb_gift.SelectedIndex == 0) - { - giftType = GiftType._155; - } - else - { - giftType = GiftType._160; - } - int index = 1; - int sucessCount = 0; - int errorCount = 0; - foreach (oms_wei_order_info item in list) - { - try - { - var rst = await WxApiBLL.WxSearchAndDropshipCancelAsync(item.Shop, item); - if (rst == "success") - { - var ret = await _shipGiftService.Send(item.order_id, giftType); - if (ret) - { - sucessCount++; - item.gift_order_status = 1; - this.FilterOneOrder(item, true); - } - else - { - errorCount++; - } - } - else - { - errorCount++; - } - } - catch (Exception ex) - { - errorCount++; - } - finally - { - item.IsSelect = false; - } - - SetProgress(index, count); - BottomMsg = $"礼品单发送进度:{index}/{count}\t\t{item.orderItems.FirstOrDefault()?.title ?? ""}"; - index++; - } - - BottomMsg = $"礼品单发送完成 成功:{sucessCount} 失败:{errorCount} 总数:{count}"; - } - catch (Exception ex) - { - BaseMsgWindow.ShowError("礼品单发货失败\n" + ex.Message, "Error"); - } - finally - { - - } - } - - /// - /// 拉取微信订单到任务列表 - /// - public ICommand PullWXOrderCommand => new AsyncDelegateCommand(PullWXOrder); - - private async Task PullWXOrder() - { - try - { - var isAfterSales = GlobalConfig.OrderTabHeaderStr.StartsWith("需处理售后单");//是否售后 - - var selectedShops = GlobalConfig.ShopLoginList.Where(a => a.IsSelect).ToList(); - if (selectedShops.Count == 0) - { - selectedShops = GlobalConfig.ShopLoginList.ToList(); - } - - var selectedOrders = GlobalConfig.lstFilterOrder.Where(a => a.IsSelect).ToList(); - int count = selectedOrders.Count; - if (count > 0 && isAfterSales == false)//非售后订单 - { - if (BaseMsgWindow.ShowConfirm($"已选取:{count}个订单", "同步订单", MainWindow.Instance, MsgWindowLevel.MEDIUM).DialogResult == false) return; - BottomMsg = $"订单同步进度...."; - int index = 1; - int sucessCount = 0; - int errorCount = 0; - foreach (var item in selectedOrders) - { - var ret = await PullWXOrderService.Instance.PullOrderDetailAsync(item.shop_id, item.order_id); ; - if (ret) - { - sucessCount++; - this.GetOrder(item.order_id); - SetProgress(index, count); - item.IsSelect = false; - } - else - { - errorCount++; - } - BottomMsg = $"订单同步进度:{index}/{count}\t\t{item.orderItems.FirstOrDefault()?.title ?? ""}"; - index++; - } - BottomMsg = $"订单同步进度完成 成功:{sucessCount} 失败:{errorCount} 总数:{count}"; - } - else if (count > 0 && isAfterSales == true)//售后订单 - { - if (BaseMsgWindow.ShowConfirm($"已选取:{count}个售后订单", "同步订单", MainWindow.Instance, MsgWindowLevel.MEDIUM).DialogResult == false) return; - //var dictionaryResult = selectedOrders - // .Where(o => o?.refundItems != null) - // .SelectMany(o => o.refundItems - // .Where(item => item != null) - // .Select(item => new { o.shop_id, item.after_sale_order_id })) - // .GroupBy(x => x.shop_id) - // .ToDictionary( - // g => g.Key, - // g => g.Select(x => x.after_sale_order_id).ToArray() - // ); - - - //BottomMsg = $"售后订单同步进度...."; - //foreach (var item in dictionaryResult) - //{ - // var ret = await PullWXOrderService.Instance.PullAfterSaleOrdersAsync(item.Key, item.Value); - //} - //BottomMsg = $"售后同步任务已发送,等待同步完成"; - - - - int index = 1; - int sucessCount = 0; - int errorCount = 0; - BottomMsg = $"售后订单同步进度...."; - foreach (KeyValuePair> item in selectedOrders.GroupBy(a => a.shop_id).ToDictionary(a => a.Key, a => a.ToList())) - { - long shopid = item.Key; - string shopName = item.Value.FirstOrDefault()?.shop_name ?? ""; - string[] afterSaleOrderIds = item.Value.SelectMany(a => a.refundItems).Where(a => a != null).Select(a => a.after_sale_order_id).ToArray(); - var ret = await PullWXOrderService.Instance.PullAfterSaleOrdersAsync(shopid, afterSaleOrderIds); - if (ret) - { - sucessCount++; - SetProgress(index, count); - item.Value.ForEach(a => a.IsSelect = false); - } - else - { - errorCount++; - } - BottomMsg = $"售后订单同步进度:{index}/{count}\t\t{shopName}"; - index++; - - } - BottomMsg = $"售后同步任务已发送,等待同步完成"; - } - else - { - count = selectedShops.Count; - string prefix = $"已选取:{count}个商铺"; - if (count == GlobalConfig.ShopLoginList.Count) - { - prefix = "已选取全部商铺"; - } - - - var startTime = dateStart.SelectedDate.Value; - var endTime = dateEnd.SelectedDate.Value; - - string msg = ""; - if (isAfterSales) - { - msg = $"{prefix}"; - } - else - { - msg = $"{prefix}\n\n时间范围:{startTime.ToString("yyyy-MM-dd")}-{endTime.ToString("yyyy-MM-dd")}"; - } - - if (BaseMsgWindow.ShowConfirm(msg, $"{(isAfterSales ? "售后" : "")}同步订单", MainWindow.Instance, MsgWindowLevel.MEDIUM).DialogResult == false) return; - - if ((endTime - startTime).Days > 7) - { - throw new Exception("时间范围最大7天"); - } - - var ret = false; - if (isAfterSales) - { - ret = await PullWXOrderService.Instance.PullRefundOrderByShopsAsync(selectedShops.Select(a => a.ErpShopId.ParseToLong()).ToArray(), startTime, endTime); - } - else - { - ret = await PullWXOrderService.Instance.PullOrderByShopIdsAndTimeRangeAsync(selectedShops.Select(a => a.ErpShopId.ParseToLong()).ToArray(), startTime, endTime); - } - if (ret) - { - BaseMsgWindow.ShowInfo("同步任务已发送,等待同步完成\n任务详情查看任务列表"); - } - else - { - BaseMsgWindow.ShowError("同步任务失败"); - } - } - - - } - catch (Exception ex) - { - BaseMsgWindow.ShowError("同步订单失败\n" + ex.Message, "Error"); - } - //var service = PullWXOrderService.Instance; - //foreach (var item in list) - //{ - // await service.PullOrderDetailAsync(item.shop_id, item.order_id); - //} - } - - private DialogWindow _taskDialog; - public ICommand ShowTaskDialogViewCommand => new DelegateCommand(ShowTaskDialogView); - - private void ShowTaskDialogView() - { - if (_taskDialog == null) - { - _taskDialog = new DialogWindow() - { - Title = "任务列表", - Content = new OrderTaskDialogView(), - - }; - _taskDialog.Closed += (s, e) => _taskDialog = null; - } - _taskDialog.Show(); - } } public class OrderFilterConfig diff --git a/29WxOrderWpf/Ctrls/PDDInvoice/PDDInvoiceView.xaml b/29WxOrderWpf/Ctrls/PDDInvoice/PDDInvoiceView.xaml new file mode 100644 index 0000000..a79a1bf --- /dev/null +++ b/29WxOrderWpf/Ctrls/PDDInvoice/PDDInvoiceView.xaml @@ -0,0 +1,868 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +