发票助手
This commit is contained in:
1 parent
acd07e6854
commit
f2d31c4a42
10 files changed
+1850
-304
No files matched your search
@@ -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
|
||||
{
|
||||
/// <summary> 缓存上限,防止大量缩略图重复下载导致内存膨胀 </summary>
|
||||
private const int MaxCacheCount = 200;
|
||||
|
||||
private readonly ConcurrentDictionary<string, BitmapImage> _imageCache = new ConcurrentDictionary<string, BitmapImage>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
/// <summary>
|
||||
/// 批量发送礼品单
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
|
||||
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 同步订单
|
||||
/// <summary>
|
||||
/// 拉取微信订单到任务列表
|
||||
/// </summary>
|
||||
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<long, List<oms_wei_order_info>> 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()
|
||||
}.ShowDialog();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -25,7 +25,8 @@
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="18" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid x:Name="gridSearch" Margin="8,0,8,-2">
|
||||
|
||||
<Grid x:Name="gridSearch" Margin="8,0,290,-2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="1.2*" />
|
||||
@@ -40,11 +41,8 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="1.4*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
|
||||
@@ -205,7 +203,8 @@
|
||||
Padding="4"
|
||||
Click="btnFilter_Click"
|
||||
Content="过滤"
|
||||
Style="{StaticResource BasePageButtonStyle}" />
|
||||
Style="{StaticResource BasePageButtonStyle}"
|
||||
ToolTip="过滤" />
|
||||
<Button
|
||||
x:Name="btnSearch"
|
||||
Grid.Column="10"
|
||||
@@ -274,16 +273,29 @@
|
||||
IsChecked="true" />
|
||||
</WrapPanel>
|
||||
|
||||
<wpf:SpacingStackPanel Grid.Column="13" HorizontalSpacing="5">
|
||||
<Button
|
||||
Width="30"
|
||||
Height="28"
|
||||
Padding="4"
|
||||
HorizontalAlignment="Center"
|
||||
Command="{Binding ShowShopRevenueStatisticsDialogViewCommand}"
|
||||
Style="{StaticResource BasePageButtonStyle}"
|
||||
ToolTip="利润统计">
|
||||
<TextBlock Style="{StaticResource TextBlockIcon}" Text="{StaticResource txt-data_pie}" />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
Grid.Column="13"
|
||||
Width="60"
|
||||
Height="28"
|
||||
Padding="4"
|
||||
HorizontalAlignment="Center"
|
||||
Click="btn_ShowShopRevenueStatisticsView"
|
||||
Content="利润统计"
|
||||
Style="{StaticResource BasePageButtonStyle}" />
|
||||
<Button
|
||||
Width="30"
|
||||
Height="28"
|
||||
Padding="4"
|
||||
HorizontalAlignment="Center"
|
||||
Command="{Binding ShowPDDInvoiceDialogCommand}"
|
||||
Style="{StaticResource BasePageButtonStyle}"
|
||||
ToolTip="发票助手">
|
||||
<TextBlock Style="{StaticResource TextBlockIcon}" Text="{StaticResource txt-fapiao}" />
|
||||
</Button>
|
||||
</wpf:SpacingStackPanel>
|
||||
</Grid>
|
||||
|
||||
<Border
|
||||
|
||||
@@ -1947,22 +1947,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls
|
||||
FilterOrders();
|
||||
}
|
||||
|
||||
private DialogWindow _statisticsWindow;
|
||||
private void btn_ShowShopRevenueStatisticsView(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_statisticsWindow == null)
|
||||
{
|
||||
_statisticsWindow = new DialogWindow()
|
||||
{
|
||||
Title = "统计",
|
||||
Content = new ShopRevenueStatisticsView(),
|
||||
|
||||
};
|
||||
_statisticsWindow.Closed += (s, e) => _statisticsWindow = null;
|
||||
}
|
||||
_statisticsWindow.Show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -2066,263 +2051,7 @@ namespace _29WxOrderWpf.Ctrls.OrderCtrls
|
||||
// set => SetProperty(ref _IsShipGift, value);
|
||||
//}
|
||||
|
||||
public ICommand MultipleShipGiftCommand => new AsyncDelegateCommand(MultipleShipGift);
|
||||
/// <summary>
|
||||
/// 批量发送礼品单
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拉取微信订单到任务列表
|
||||
/// </summary>
|
||||
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<long, List<oms_wei_order_info>> 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
|
||||
|
||||
@@ -0,0 +1,800 @@
|
||||
<UserControl
|
||||
x:Class="_29WxOrderWpf.Ctrls.PDDInvoice.PDDInvoiceView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:comm="clr-namespace:_29WxOrderWpf.Common"
|
||||
xmlns:common="clr-namespace:_29WxOrderWpf.Common"
|
||||
xmlns:converters="clr-namespace:_29WxOrderWpf.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:_29WxOrderWpf.Ctrls.PDDInvoice.ViewModels"
|
||||
xmlns:wpf="clr-namespace:WPFCommon.Controls;assembly=WPFCommon"
|
||||
comm:DialogWindowProperty.ResizeMode="CanResizeWithGrip"
|
||||
comm:DialogWindowProperty.ShowMinButton="False"
|
||||
common:DialogWindowProperty.Height="720"
|
||||
common:DialogWindowProperty.Width="1160"
|
||||
d:DataContext="{d:DesignInstance Type=vm:PDDInvoiceViewModel,
|
||||
IsDesignTimeCreatable=True}"
|
||||
d:DesignHeight="720"
|
||||
d:DesignWidth="1160"
|
||||
Background="White"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibility" />
|
||||
<converters:ImageUrlToBitmapImageConverter x:Key="ImageUrlToBitmapImage" />
|
||||
<converters:InverseVisibleToVisibilityConverter x:Key="InverseBooleanToVisibility" />
|
||||
|
||||
<!-- 原型配色 -->
|
||||
<SolidColorBrush x:Key="PageBgBrush" Color="#F5F6F8" />
|
||||
<SolidColorBrush x:Key="CardBgBrush" Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="RowBgBrush" Color="#FAFAFA" />
|
||||
<SolidColorBrush x:Key="SplitLineBrush" Color="#EBEEF5" />
|
||||
<SolidColorBrush x:Key="InputBorderBrush" Color="#DCDFE6" />
|
||||
<SolidColorBrush x:Key="PrimaryBrush" Color="#409EFF" />
|
||||
<SolidColorBrush x:Key="PrimaryHoverBrush" Color="#66B1FF" />
|
||||
<SolidColorBrush x:Key="TextPrimaryBrush" Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextNormalBrush" Color="#666666" />
|
||||
<SolidColorBrush x:Key="TextSecondaryBrush" Color="#909399" />
|
||||
<SolidColorBrush x:Key="TextPlaceholderBrush" Color="#C0C4CC" />
|
||||
<SolidColorBrush x:Key="AmountBrush" Color="#F56C6C" />
|
||||
<SolidColorBrush x:Key="SuccessBrush" Color="#67C23A" />
|
||||
<SolidColorBrush x:Key="WarningBrush" Color="#E6A23C" />
|
||||
|
||||
<!-- 表头单元格 -->
|
||||
<Style x:Key="HeaderCellTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="Foreground" Value="{StaticResource TextNormalBrush}" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<!-- 搜索 / 表单输入框 -->
|
||||
<Style x:Key="SearchTextBoxStyle" TargetType="TextBox">
|
||||
<Setter Property="Height" Value="36" />
|
||||
<Setter Property="Padding" Value="12,0" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}" />
|
||||
<Setter Property="Background" Value="White" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource InputBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="TextBox">
|
||||
<Border
|
||||
x:Name="border"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="4">
|
||||
<ScrollViewer x:Name="PART_ContentHost" Margin="{TemplateBinding Padding}" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsKeyboardFocused" Value="True">
|
||||
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource PrimaryBrush}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="border" Property="Opacity" Value="0.6" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- 主按钮 -->
|
||||
<Style x:Key="PrimaryButtonStyle" TargetType="Button">
|
||||
<Setter Property="Height" Value="36" />
|
||||
<Setter Property="Padding" Value="18,0" />
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
<Setter Property="Background" Value="{StaticResource PrimaryBrush}" />
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="Cursor" Value="Hand" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border
|
||||
x:Name="border"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="4">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="border" Property="Background" Value="{StaticResource PrimaryHoverBrush}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="border" Property="Opacity" Value="0.8" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="border" Property="Opacity" Value="0.5" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- 默认按钮 -->
|
||||
<Style x:Key="DefaultButtonStyle" TargetType="Button">
|
||||
<Setter Property="Height" Value="36" />
|
||||
<Setter Property="Padding" Value="18,0" />
|
||||
<Setter Property="Foreground" Value="{StaticResource TextNormalBrush}" />
|
||||
<Setter Property="Background" Value="White" />
|
||||
<Setter Property="BorderBrush" Value="{StaticResource InputBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="Cursor" Value="Hand" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border
|
||||
x:Name="border"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="4">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="border" Property="Background" Value="#F5F7FA" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="border" Property="Opacity" Value="0.8" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- 文字链接按钮 -->
|
||||
<Style x:Key="LinkButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Foreground" Value="{StaticResource PrimaryBrush}" />
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="Cursor" Value="Hand" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Foreground" Value="{StaticResource PrimaryHoverBrush}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- 弹窗遮罩 -->
|
||||
<Style x:Key="ModalMaskStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#80000000" />
|
||||
<Setter Property="Panel.ZIndex" Value="100" />
|
||||
</Style>
|
||||
|
||||
<!-- 发票详情 标签 / 值 -->
|
||||
<Style x:Key="DetailLabelStyle" TargetType="TextBlock">
|
||||
<Setter Property="Width" Value="100" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="Foreground" Value="{StaticResource TextSecondaryBrush}" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
<Style x:Key="DetailValueStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="Foreground" Value="{StaticResource TextPrimaryBrush}" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Border Padding="10,10,10,0">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="20" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 功能区域 -->
|
||||
<Border Grid.Row="0">
|
||||
|
||||
<wpf:SpacingStackPanel Background="{StaticResource CardBgBrush}" HorizontalSpacing="10">
|
||||
<Grid Width="300">
|
||||
<TextBox
|
||||
x:Name="txtSearch"
|
||||
Height="30"
|
||||
Padding="5,0,0,0"
|
||||
KeyDown="txtSearch_KeyDown"
|
||||
Style="{StaticResource SearchTextBoxStyle}"
|
||||
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<TextBlock
|
||||
Padding="12,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="13"
|
||||
Foreground="{StaticResource TextPlaceholderBrush}"
|
||||
IsHitTestVisible="False"
|
||||
Text="请输入订单号 / 商品名称"
|
||||
Visibility="{Binding Text, ElementName=txtSearch, Converter={StaticResource NotHasTextVisibility}}" />
|
||||
</Grid>
|
||||
<Button
|
||||
Width="50"
|
||||
Height="30"
|
||||
Command="{Binding SearchCommand}"
|
||||
Content="搜索"
|
||||
Style="{StaticResource BasePageButtonStyle}" />
|
||||
<Button
|
||||
Height="30"
|
||||
Command="{Binding ResetCommand}"
|
||||
Content="重置"
|
||||
Style="{StaticResource DefaultButtonStyle}" />
|
||||
|
||||
<wpf:TitleContent
|
||||
Title="买手号:"
|
||||
Placement="Left"
|
||||
TitleVerticalAlignment="Center">
|
||||
<ComboBox
|
||||
Width="150"
|
||||
Height="28"
|
||||
DisplayMemberPath="buyer_nick"
|
||||
ItemsSource="{Binding BuyerLoginList}"
|
||||
SelectedItem="{Binding SelectedBuyer}"
|
||||
Style="{StaticResource RoundedComboBox}" />
|
||||
</wpf:TitleContent>
|
||||
<Button
|
||||
Height="30"
|
||||
Padding="5,0"
|
||||
Command="{Binding ReadOrderCommand}"
|
||||
Content="读取订单"
|
||||
Style="{StaticResource BasePageButtonStyle}" />
|
||||
</wpf:SpacingStackPanel>
|
||||
</Border>
|
||||
<!-- 订单列表(已移除分页与订单分组) -->
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Height="Auto"
|
||||
Margin="0,10,0,0"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="{StaticResource CardBgBrush}"
|
||||
CornerRadius="6">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
|
||||
<!-- 表头 -->
|
||||
<Border
|
||||
Grid.Row="0"
|
||||
Padding="20,14"
|
||||
Background="{StaticResource RowBgBrush}"
|
||||
BorderBrush="{StaticResource SplitLineBrush}"
|
||||
BorderThickness="0,0,0,1">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
<ColumnDefinition Width="80" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="1.2*" />
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Style="{StaticResource HeaderCellTextStyle}"
|
||||
Text="商品信息" />
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource HeaderCellTextStyle}"
|
||||
Text="数量" />
|
||||
<TextBlock
|
||||
Grid.Column="3"
|
||||
Style="{StaticResource HeaderCellTextStyle}"
|
||||
Text="实付金额" />
|
||||
<TextBlock
|
||||
Grid.Column="4"
|
||||
Style="{StaticResource HeaderCellTextStyle}"
|
||||
Text="发票" />
|
||||
<TextBlock
|
||||
Grid.Column="5"
|
||||
Style="{StaticResource HeaderCellTextStyle}"
|
||||
Text="操作" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<Grid Grid.Row="1">
|
||||
<Border Background="White">
|
||||
<!-- 列表(虚拟化滚动加载) -->
|
||||
<ItemsControl
|
||||
Margin="0,2,0,-2"
|
||||
Padding="0"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
ItemsSource="{Binding Orders}">
|
||||
<ItemsControl.Template>
|
||||
<ControlTemplate TargetType="ItemsControl">
|
||||
<ScrollViewer
|
||||
CanContentScroll="True"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<ItemsPresenter />
|
||||
</ScrollViewer>
|
||||
</ControlTemplate>
|
||||
</ItemsControl.Template>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel
|
||||
CacheLength="1,1"
|
||||
CacheLengthUnit="Page"
|
||||
IsVirtualizing="True"
|
||||
ScrollUnit="Pixel"
|
||||
VirtualizationMode="Recycling" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderBrush="{StaticResource SplitLineBrush}" BorderThickness="0,0,0,1">
|
||||
<StackPanel>
|
||||
<!-- 订单信息栏 -->
|
||||
<Border Padding="20,12" Background="{StaticResource RowBgBrush}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
FontSize="12"
|
||||
Foreground="{StaticResource TextNormalBrush}"
|
||||
Text="{Binding order_sn, StringFormat=订单号:{0}}" />
|
||||
<TextBlock
|
||||
Margin="28,0,0,0"
|
||||
FontSize="12"
|
||||
Foreground="{StaticResource TextNormalBrush}"
|
||||
Text="{Binding OrderTime, StringFormat=下单时间:{0:yyyy-MM-dd}}" />
|
||||
<TextBlock
|
||||
Margin="28,0,0,0"
|
||||
FontSize="12"
|
||||
Foreground="{StaticResource TextNormalBrush}"
|
||||
Text="{Binding order_status_prompt}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 订单内容 -->
|
||||
<Border Padding="20">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
<ColumnDefinition Width="80" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="1.2*" />
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 商品 -->
|
||||
<Grid Grid.Column="0" VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="72" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border
|
||||
Width="72"
|
||||
Height="72"
|
||||
Background="#EEEEEE"
|
||||
CornerRadius="5">
|
||||
<Image Source="{Binding ThumbUrl, Converter={StaticResource ImageUrlToBitmapImage}, IsAsync=True}" Stretch="UniformToFill" />
|
||||
</Border>
|
||||
<StackPanel
|
||||
Grid.Column="1"
|
||||
Margin="14,0,0,0"
|
||||
VerticalAlignment="Center">
|
||||
<TextBlock
|
||||
MaxHeight="44"
|
||||
FontSize="14"
|
||||
Foreground="{StaticResource TextPrimaryBrush}"
|
||||
LineHeight="22"
|
||||
Text="{Binding GoodsName}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
|
||||
<!-- 数量 -->
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="13"
|
||||
Foreground="{StaticResource TextPrimaryBrush}"
|
||||
Text="{Binding Quantity, StringFormat=×{0}}" />
|
||||
|
||||
<!-- 实付金额 -->
|
||||
<TextBlock
|
||||
Grid.Column="3"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{StaticResource AmountBrush}"
|
||||
Text="{Binding DisplayAmount}" />
|
||||
|
||||
<!-- 发票 -->
|
||||
<StackPanel Grid.Column="4" VerticalAlignment="Center">
|
||||
<TextBlock FontSize="13" Text="{Binding InvoiceStatusText}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{StaticResource WarningBrush}" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsInvoiced}" Value="True">
|
||||
<Setter Property="Foreground" Value="{StaticResource SuccessBrush}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 操作 -->
|
||||
<StackPanel Grid.Column="5" VerticalAlignment="Center">
|
||||
<Button
|
||||
d:Visibility="Visible"
|
||||
Command="{Binding DataContext.ShowInvoiceCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
Content="查看发票"
|
||||
Style="{StaticResource LinkButtonStyle}"
|
||||
Visibility="{Binding IsInvoiced, Converter={StaticResource BooleanToVisibility}}" />
|
||||
<Button
|
||||
Margin="0,5"
|
||||
Command="{Binding DataContext.OpenInvoiceCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
Content="申请开票"
|
||||
Style="{StaticResource LinkButtonStyle}"
|
||||
Visibility="{Binding IsInvoiced, Converter={StaticResource InverseBooleanToVisibility}}" />
|
||||
<Button
|
||||
Command="{Binding DataContext.ViewOrderCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
Content="查看订单"
|
||||
Style="{StaticResource LinkButtonStyle}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Border>
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Panel.ZIndex="{Binding BrowserZIndex}"
|
||||
d:Panel.ZIndex="-10"
|
||||
Style="{StaticResource ModalMaskStyle}">
|
||||
<Grid>
|
||||
<ContentControl
|
||||
Grid.Row="0"
|
||||
Width="400"
|
||||
Height="600"
|
||||
Background="White"
|
||||
Content="{Binding Browser}" />
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Orientation="Horizontal">
|
||||
|
||||
<Button
|
||||
Command="{Binding CloseOrderBrowserCommand}"
|
||||
Content="隐藏"
|
||||
Style="{StaticResource DefaultButtonStyle}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Panel.ZIndex="{Binding BrowserDetailZIndex}"
|
||||
d:Panel.ZIndex="-10"
|
||||
Style="{StaticResource ModalMaskStyle}">
|
||||
<Grid>
|
||||
<!--<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>-->
|
||||
<ContentControl
|
||||
Grid.Row="0"
|
||||
Width="400"
|
||||
Height="600"
|
||||
Background="White"
|
||||
Content="{Binding BrowserDetail}" />
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
Command="{Binding CloseInvoiceDetailCommand}"
|
||||
Content="关闭"
|
||||
Style="{StaticResource DefaultButtonStyle}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Grid
|
||||
Grid.Row="2"
|
||||
Margin="-10,0"
|
||||
Background="{StaticResource pageColorBrush}">
|
||||
<ProgressBar
|
||||
VerticalAlignment="Stretch"
|
||||
d:IsIndeterminate="False"
|
||||
d:Maximum="100"
|
||||
d:Value="10"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Foreground="#FFA680"
|
||||
Maximum="{Binding ProgressMaximum}"
|
||||
Value="{Binding ProgressValue}" />
|
||||
<Grid Margin="10,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="100*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBox
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="4,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
d:Text="共计:{}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Foreground="White"
|
||||
IsReadOnly="True"
|
||||
Text="{Binding BottomMsg}" />
|
||||
</Grid>
|
||||
<Button
|
||||
HorizontalAlignment="Right"
|
||||
Background="Transparent"
|
||||
Command="{Binding ShowTaskDialogViewCommand}"
|
||||
Foreground="White"
|
||||
ToolTip="任务列表">
|
||||
<Button.Content>
|
||||
<TextBlock Style="{StaticResource TextBlockIcon}" Text="{StaticResource txt-task_list_square_ltr}" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</Grid>
|
||||
<!-- 开票弹窗 -->
|
||||
<!--<Border
|
||||
Grid.RowSpan="3"
|
||||
Style="{StaticResource ModalMaskStyle}"
|
||||
Visibility="{Binding IsInvoiceDialogOpen, Converter={StaticResource BooleanToVisibility}}">
|
||||
<Border
|
||||
Width="520"
|
||||
Padding="24"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Background="White"
|
||||
CornerRadius="8">
|
||||
<StackPanel>
|
||||
<TextBlock
|
||||
Margin="0,0,0,24"
|
||||
FontSize="18"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{StaticResource TextPrimaryBrush}"
|
||||
Text="开具发票" />
|
||||
|
||||
<Grid Margin="0,0,0,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="90" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
FontSize="13"
|
||||
Foreground="{StaticResource TextNormalBrush}"
|
||||
Text="订单号" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="13"
|
||||
Foreground="{StaticResource TextPrimaryBrush}"
|
||||
Text="{Binding SelectedOrder.order_sn}" />
|
||||
</Grid>
|
||||
|
||||
<Grid Margin="0,0,0,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="90" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
FontSize="13"
|
||||
Foreground="{StaticResource TextNormalBrush}"
|
||||
Text="发票类型" />
|
||||
<ComboBox
|
||||
Grid.Column="1"
|
||||
Height="36"
|
||||
Padding="10,0"
|
||||
VerticalContentAlignment="Center"
|
||||
FontSize="13"
|
||||
SelectedValue="{Binding InvoiceType}"
|
||||
SelectedValuePath="Content">
|
||||
<ComboBoxItem Content="电子普通发票" />
|
||||
<ComboBoxItem Content="增值税专用发票" />
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
|
||||
<Grid Margin="0,0,0,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="90" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
FontSize="13"
|
||||
Foreground="{StaticResource TextNormalBrush}"
|
||||
Text="发票抬头" />
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource SearchTextBoxStyle}"
|
||||
Text="{Binding InvoiceTitle}" />
|
||||
</Grid>
|
||||
|
||||
<Grid Margin="0,0,0,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="90" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
FontSize="13"
|
||||
Foreground="{StaticResource TextNormalBrush}"
|
||||
Text="税号" />
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource SearchTextBoxStyle}"
|
||||
Text="{Binding TaxNo}" />
|
||||
</Grid>
|
||||
|
||||
<StackPanel
|
||||
Margin="0,25,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
Command="{Binding CloseInvoiceDialogCommand}"
|
||||
Content="取消"
|
||||
Style="{StaticResource DefaultButtonStyle}" />
|
||||
<Button
|
||||
Margin="10,0,0,0"
|
||||
Command="{Binding ConfirmInvoiceCommand}"
|
||||
Content="确认开票"
|
||||
Style="{StaticResource PrimaryButtonStyle}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Border>-->
|
||||
|
||||
<!-- 发票信息弹窗 -->
|
||||
<!--<Border
|
||||
Grid.RowSpan="3"
|
||||
Style="{StaticResource ModalMaskStyle}"
|
||||
Visibility="{Binding IsInvoiceDetailOpen, Converter={StaticResource BooleanToVisibility}}">
|
||||
<Border
|
||||
Width="520"
|
||||
Padding="24"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Background="White"
|
||||
CornerRadius="8">
|
||||
<StackPanel>
|
||||
<TextBlock
|
||||
Margin="0,0,0,24"
|
||||
FontSize="18"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{StaticResource TextPrimaryBrush}"
|
||||
Text="发票信息" />
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="30" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Style="{StaticResource DetailLabelStyle}"
|
||||
Text="订单号:" />
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource DetailValueStyle}"
|
||||
Text="{Binding SelectedOrder.OrderNo}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Style="{StaticResource DetailLabelStyle}"
|
||||
Text="发票类型:" />
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource DetailValueStyle}"
|
||||
Text="{Binding SelectedOrder.InvoiceType}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Style="{StaticResource DetailLabelStyle}"
|
||||
Text="发票号码:" />
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource DetailValueStyle}"
|
||||
Text="{Binding SelectedOrder.InvoiceNo}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Style="{StaticResource DetailLabelStyle}"
|
||||
Text="发票抬头:" />
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource DetailValueStyle}"
|
||||
Text="{Binding SelectedOrder.InvoiceTitle}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Style="{StaticResource DetailLabelStyle}"
|
||||
Text="税号:" />
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource DetailValueStyle}"
|
||||
Text="{Binding SelectedOrder.TaxNo}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Style="{StaticResource DetailLabelStyle}"
|
||||
Text="开票金额:" />
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource DetailValueStyle}"
|
||||
Text="{Binding SelectedOrder.InvoiceAmountText}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="6"
|
||||
Style="{StaticResource DetailLabelStyle}"
|
||||
Text="开票时间:" />
|
||||
<TextBlock
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Style="{StaticResource DetailValueStyle}"
|
||||
Text="{Binding SelectedOrder.InvoiceTime}" />
|
||||
</Grid>
|
||||
|
||||
<StackPanel
|
||||
Margin="0,25,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
Command="{Binding CloseInvoiceDetailCommand}"
|
||||
Content="关闭"
|
||||
Style="{StaticResource DefaultButtonStyle}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Border>-->
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,37 @@
|
||||
using _29WxOrderWpf.Ctrls.PDDInvoice.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace _29WxOrderWpf.Ctrls.PDDInvoice;
|
||||
|
||||
/// <summary>
|
||||
/// PDDInvoiceView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class PDDInvoiceView : UserControl
|
||||
{
|
||||
public PDDInvoiceView()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = new PDDInvoiceViewModel();
|
||||
}
|
||||
|
||||
private void txtSearch_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Enter && DataContext is PDDInvoiceViewModel viewModel)
|
||||
{
|
||||
viewModel.SearchCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using AllBase.Model.Result;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WPFCommon.Helpers;
|
||||
using WPFCommon.Models;
|
||||
|
||||
namespace _29WxOrderWpf.Ctrls.PDDInvoice.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// 订单发票Model
|
||||
/// </summary>
|
||||
public class PddBrowserOrderInvoiceViewModel : BindableBaseEx
|
||||
{
|
||||
|
||||
public string buyerId { get; set; } // 买手Id
|
||||
public string buyerName { get; set; } // 买手名称
|
||||
/// <summary>
|
||||
/// 订单价
|
||||
/// </summary>
|
||||
public int order_amount { get; set; }
|
||||
/// <summary>
|
||||
/// 实付款
|
||||
/// </summary>
|
||||
public string display_amount { get; set; }
|
||||
/// <summary>
|
||||
/// 下单时间
|
||||
/// </summary>
|
||||
public long order_time { get; set; }
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string order_sn { get; set; }
|
||||
|
||||
public int status { get; set; }
|
||||
public int pay_status { get; set; }
|
||||
public string order_status_prompt { get; set; }
|
||||
public List<order_good> order_Goods { get; set; }
|
||||
|
||||
|
||||
public List<OrderButtonItem> order_buttons { get; set; }
|
||||
|
||||
|
||||
public string GoodsName { get => order_Goods?.FirstOrDefault()?.goods_name ?? ""; }
|
||||
public bool IsInvoiced
|
||||
{
|
||||
get => order_buttons?.Any(a => a.button_code == 500) ?? false;
|
||||
}
|
||||
|
||||
public int Quantity => order_Goods?.Sum(a => a.goods_number.Value) ?? 0;
|
||||
/// <summary> 发票状态文案:已开票 / 待开票 </summary>
|
||||
public string InvoiceStatusText => IsInvoiced ? "已开票" : "待开票";
|
||||
public DateTime OrderTime
|
||||
{
|
||||
get => DateTimeHelper.ConvertFromUnixTimestampInSeconds(order_time);
|
||||
}
|
||||
public string ThumbUrl=> order_Goods?.FirstOrDefault()?.thumb_url ?? "";
|
||||
public string DisplayAmount => (order_amount / 100.0).ToString("F2");
|
||||
}
|
||||
|
||||
public class OrderButtonItem
|
||||
{
|
||||
public int button_code { get; set; }
|
||||
public string brief_prompt { get; set; }
|
||||
public ButtonTypeValue type_value { get; set; }
|
||||
}
|
||||
public class ButtonTypeValue
|
||||
{
|
||||
public string Url { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
using _29WxOrderWpf.CefHelper;
|
||||
using _29WxOrderWpf.Commands;
|
||||
using AllBase;
|
||||
using CefSharp;
|
||||
using CefSharp.Handler;
|
||||
using CefSharp.Wpf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Work._29Tools.CefTools;
|
||||
|
||||
namespace _29WxOrderWpf.Ctrls.PDDInvoice.ViewModels;
|
||||
|
||||
public partial class PDDInvoiceViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单列表浏览器
|
||||
/// </summary>
|
||||
public ChromiumWebBrowser Browser { get; private set; }
|
||||
/// <summary>
|
||||
/// 内容浏览器
|
||||
/// 订单详情
|
||||
/// 发票详情
|
||||
/// 申请发票
|
||||
/// </summary>
|
||||
public ChromiumWebBrowser BrowserDetail { get; private set; }
|
||||
|
||||
partial void InitBrowser()
|
||||
{
|
||||
BrowserZIndex = -1;
|
||||
BrowserDetailZIndex = -1;
|
||||
|
||||
Browser = WPFCEFBrowser.CreateChromiumWebBrowser("about:blank", false);
|
||||
|
||||
LocalResourceRequestHandler resourceRequestHandler = new LocalResourceRequestHandler();
|
||||
//resourceRequestHandler.BeforeResourceLoadEvent += RequestHandler_BeforeResourceLoad;
|
||||
resourceRequestHandler.ResourceLoadCompleteEvent += RequestHandler_ResourceLoadComplete;
|
||||
Browser.RequestHandler = new LocalRequestHandler(resourceRequestHandler);
|
||||
Browser.LifeSpanHandler = new LocalLifeSpanHandler(PopWindowType.SelfWindow);
|
||||
Browser.KeyboardHandler = new KeyboardHandler();
|
||||
|
||||
|
||||
BrowserDetail = WPFCEFBrowser.CreateChromiumWebBrowser("about:blank", false);
|
||||
LocalResourceRequestHandler detailResourceRequestHandler = new LocalResourceRequestHandler();
|
||||
detailResourceRequestHandler.ResourceLoadCompleteEvent += DetailRequestHandler_ResourceLoadComplete;
|
||||
BrowserDetail.RequestHandler = new LocalRequestHandler(resourceRequestHandler);
|
||||
BrowserDetail.LifeSpanHandler = new LocalLifeSpanHandler(PopWindowType.SelfWindow);
|
||||
BrowserDetail.KeyboardHandler = new KeyboardHandler();
|
||||
}
|
||||
|
||||
public ICommand CloseOrderBrowserCommand => new DelegateCommand(HidenOrderBrowser);
|
||||
public ICommand CloseInvoiceDetailCommand => new DelegateCommand(HidenOrderBrowserDetail);
|
||||
|
||||
public int BrowserZIndex
|
||||
{
|
||||
get => GetValue<int>();
|
||||
set => SetValue(value);
|
||||
}
|
||||
public int BrowserDetailZIndex
|
||||
{
|
||||
get => GetValue<int>();
|
||||
set => SetValue(value);
|
||||
}
|
||||
/// <summary>
|
||||
/// 显示主浏览器
|
||||
/// </summary>
|
||||
public void ShowOrderBrowser()
|
||||
{
|
||||
BrowserZIndex = 10;
|
||||
BrowserDetailZIndex = -1;
|
||||
}
|
||||
/// <summary>
|
||||
/// 显示子浏览器
|
||||
/// </summary>
|
||||
public void ShowOrderBrowserDetail()
|
||||
{
|
||||
BrowserZIndex = -1;
|
||||
BrowserDetailZIndex = 10;
|
||||
}
|
||||
public void HidenOrderBrowser()
|
||||
{
|
||||
BrowserZIndex = -1;
|
||||
}
|
||||
public void HidenOrderBrowserDetail()
|
||||
{
|
||||
BrowserDetailZIndex = -1;
|
||||
}
|
||||
public bool IsAutoScroll
|
||||
{
|
||||
get => GetValue<bool>();
|
||||
set => SetValue(value);
|
||||
}
|
||||
private int top = 0;
|
||||
private DateTime lastGetOrderDataTime = DateTime.Now;
|
||||
private void RequestHandler_ResourceLoadComplete(object sender, string url, string postData, string responseData, IRequest request)
|
||||
{
|
||||
if (url.StartsWith("https://mobile.yangkeduo.com/orders.html"))
|
||||
{
|
||||
//if (isAutoScroll == false)
|
||||
//{
|
||||
// StartAutoScroll();
|
||||
//}
|
||||
|
||||
StartAutoScroll();
|
||||
}
|
||||
if (url.StartsWith("https://mobile.yangkeduo.com/proxy/api/api/aristotle/order_list_v"))
|
||||
{
|
||||
lastGetOrderDataTime = DateTime.Now;
|
||||
parserData(responseData);
|
||||
|
||||
//File.WriteAllText(@$"E:\{Guid.NewGuid().ToString()}.txt", responseData);
|
||||
}
|
||||
}
|
||||
public void StartAutoScroll()
|
||||
{
|
||||
if (IsAutoScroll) return;
|
||||
IsAutoScroll = true;
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
_ = autoScroll(_cancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
// 停止滚动
|
||||
public void StopAutoScroll()
|
||||
{
|
||||
IsAutoScroll = false;
|
||||
_cancellationTokenSource?.Cancel();
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
}
|
||||
|
||||
private async Task autoScroll(CancellationToken token)
|
||||
{
|
||||
while (IsAutoScroll && !token.IsCancellationRequested)
|
||||
{
|
||||
if ((DateTime.Now - lastGetOrderDataTime).Seconds > 30) StopAutoScroll();
|
||||
|
||||
top += Randomx.GetId(450, 600);
|
||||
var jsStr = @"window.scroll({
|
||||
top: " + top + @",
|
||||
left: 0,
|
||||
behavior: 'smooth' // 可选,使滚动平滑
|
||||
});";
|
||||
|
||||
var client = Browser.GetDevToolsClient();
|
||||
if (client != null)
|
||||
{
|
||||
var result = client.Runtime.EvaluateAsync(jsStr, null, true, null, null, true, null, true);
|
||||
result.Wait(5000);
|
||||
}
|
||||
await Task.Delay(Randomx.GetId(100, 300));
|
||||
//Thread.Sleep();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DetailRequestHandler_ResourceLoadComplete(object sender, string url, string postData, string responseData, IRequest request)
|
||||
{
|
||||
if (url.StartsWith("https://mobile.yangkeduo.com/transac_return_compensation.html"))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
using _29WxOrderWpf.CefHelper;
|
||||
using _29WxOrderWpf.Commands;
|
||||
using AllBase;
|
||||
using AllBase.Helper;
|
||||
using AllBase.Model.DBModel;
|
||||
using AllBase.Model.Result;
|
||||
using AllBase.Util;
|
||||
using CefSharp;
|
||||
using CefSharp.Handler;
|
||||
using CefSharp.Wpf;
|
||||
using NaiBa.Util.Extension;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using Work._29Tools.CefTools;
|
||||
using WPFCommon.Models;
|
||||
|
||||
namespace _29WxOrderWpf.Ctrls.PDDInvoice.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// 拼多多发票助手 视图模型
|
||||
/// </summary>
|
||||
public partial class PDDInvoiceViewModel : BindableBaseEx
|
||||
{
|
||||
private readonly ObservableCollection<PddBrowserOrderInvoiceViewModel> _allOrders = new();
|
||||
private readonly HashSet<string> _orderSns = new();
|
||||
private string _searchText = "";
|
||||
private PddBrowserOrderInvoiceViewModel _selectedOrder;
|
||||
private bool _isInvoiceDialogOpen;
|
||||
private bool _isInvoiceDetailOpen;
|
||||
private string _invoiceType = "电子普通发票";
|
||||
private string _invoiceTitle = "XX科技有限公司";
|
||||
private string _taxNo = "91110000XXXXXXXXXX";
|
||||
private CancellationTokenSource _cancellationTokenSource; public PDDInvoiceViewModel()
|
||||
{
|
||||
Orders = new ObservableCollection<PddBrowserOrderInvoiceViewModel>();
|
||||
|
||||
BuyerLoginList = GlobalConfig.PDDBuyerLoginList;
|
||||
//Orders = new ObservableCollection<PDDInvoiceOrderModel>(_allOrders);
|
||||
|
||||
//_ = InitSampleData();
|
||||
|
||||
InitBrowser();
|
||||
}
|
||||
partial void InitBrowser();
|
||||
|
||||
|
||||
|
||||
private void parserData(string data)
|
||||
{
|
||||
List<PddBrowserOrderInvoiceViewModel> list = JsonHelper.DeserializeJsonToList<PddBrowserOrderInvoiceViewModel>(JsonHelper.JObjectParse(data)["orders"].ParseToString());
|
||||
if (list.Count == 0)
|
||||
{
|
||||
StopAutoScroll();
|
||||
return;
|
||||
}
|
||||
|
||||
var matched = list.Where(item => item.status == 4 && item.pay_status == 2).ToList();
|
||||
if (matched.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// CEF 回调运行在后台线程,ObservableCollection 的更新需要切回 UI 线程
|
||||
var dispatcher = Application.Current?.Dispatcher;
|
||||
if (dispatcher == null || dispatcher.CheckAccess())
|
||||
{
|
||||
AddOrders(matched);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatcher.BeginInvoke(new Action(() => AddOrders(matched)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> 将新订单写入总表,并按当前搜索关键字决定是否加入可见列表(自动去重) </summary>
|
||||
private void AddOrders(IEnumerable<PddBrowserOrderInvoiceViewModel> items)
|
||||
{
|
||||
var keyword = SearchText?.Trim();
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.order_sn) && !_orderSns.Add(item.order_sn))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
_allOrders.Add(item);
|
||||
if (IsKeywordMatch(item, keyword))
|
||||
{
|
||||
Orders.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ObservableCollectionThreadSafe<BuyerLoginInfo> BuyerLoginList { get; set; } = new ObservableCollectionThreadSafe<BuyerLoginInfo>();
|
||||
public BuyerLoginInfo SelectedBuyer
|
||||
{
|
||||
get => GetProperty(() => SelectedBuyer);
|
||||
set => SetProperty(() => SelectedBuyer, value, SelectedBuyerChanged);
|
||||
}
|
||||
|
||||
private void SelectedBuyerChanged()
|
||||
{
|
||||
WPFCEFBrowser.SetCookieAsync(SelectedBuyer.cookie, Browser.GetCookieManager()).GetAwaiter();
|
||||
WPFCEFBrowser.SetCookieAsync(SelectedBuyer.cookie, BrowserDetail.GetCookieManager()).GetAwaiter();
|
||||
|
||||
}
|
||||
|
||||
/// <summary> 订单列表 </summary>
|
||||
public ObservableCollection<PddBrowserOrderInvoiceViewModel> Orders { get; }
|
||||
|
||||
/// <summary> 搜索关键字:订单号 / 商品名称 / 买家 </summary>
|
||||
public string SearchText
|
||||
{
|
||||
get => _searchText;
|
||||
set => SetProperty(ref _searchText, value, nameof(SearchText));
|
||||
}
|
||||
|
||||
/// <summary> 开票弹窗是否打开 </summary>
|
||||
public bool IsInvoiceDialogOpen
|
||||
{
|
||||
get => _isInvoiceDialogOpen;
|
||||
set => SetProperty(ref _isInvoiceDialogOpen, value, nameof(IsInvoiceDialogOpen));
|
||||
}
|
||||
|
||||
/// <summary> 发票详情弹窗是否打开 </summary>
|
||||
public bool IsInvoiceDetailOpen
|
||||
{
|
||||
get => _isInvoiceDetailOpen;
|
||||
set => SetProperty(ref _isInvoiceDetailOpen, value, nameof(IsInvoiceDetailOpen));
|
||||
}
|
||||
|
||||
/// <summary> 当前操作的订单 </summary>
|
||||
public PddBrowserOrderInvoiceViewModel SelectedOrder
|
||||
{
|
||||
get => _selectedOrder;
|
||||
set => SetProperty(ref _selectedOrder, value, nameof(SelectedOrder));
|
||||
}
|
||||
|
||||
/// <summary> 开票类型 </summary>
|
||||
public string InvoiceType
|
||||
{
|
||||
get => _invoiceType;
|
||||
set => SetProperty(ref _invoiceType, value, nameof(InvoiceType));
|
||||
}
|
||||
|
||||
/// <summary> 发票抬头 </summary>
|
||||
public string InvoiceTitle
|
||||
{
|
||||
get => _invoiceTitle;
|
||||
set => SetProperty(ref _invoiceTitle, value, nameof(InvoiceTitle));
|
||||
}
|
||||
|
||||
/// <summary> 税号 </summary>
|
||||
public string TaxNo
|
||||
{
|
||||
get => _taxNo;
|
||||
set => SetProperty(ref _taxNo, value, nameof(TaxNo));
|
||||
}
|
||||
|
||||
public ICommand SearchCommand => new DelegateCommand(Search);
|
||||
|
||||
public ICommand ResetCommand => new DelegateCommand(ResetSearch);
|
||||
|
||||
public ICommand OpenInvoiceCommand => new DelegateCommand<PddBrowserOrderInvoiceViewModel>(OpenInvoice);
|
||||
|
||||
public ICommand ShowInvoiceCommand => new DelegateCommand<PddBrowserOrderInvoiceViewModel>(ShowInvoice);
|
||||
|
||||
public ICommand ViewOrderCommand => new DelegateCommand<PddBrowserOrderInvoiceViewModel>(ViewOrder);
|
||||
|
||||
public ICommand CloseInvoiceDialogCommand => new DelegateCommand(() => IsInvoiceDialogOpen = false);
|
||||
|
||||
public ICommand ConfirmInvoiceCommand => new DelegateCommand(ConfirmInvoice);
|
||||
|
||||
public ICommand ReadOrderCommand => new DelegateCommand(ReadOrder, () => !IsAutoScroll);
|
||||
|
||||
private void ReadOrder()
|
||||
{
|
||||
Browser.Load("https://mobile.yangkeduo.com/orders.html");
|
||||
|
||||
ShowOrderBrowser();
|
||||
}
|
||||
|
||||
|
||||
/// <summary> 按 订单号 / 商品名称 过滤订单 </summary>
|
||||
private void Search()
|
||||
{
|
||||
var keyword = SearchText?.Trim();
|
||||
Orders.Clear();
|
||||
foreach (var order in _allOrders.Where(o => IsKeywordMatch(o, keyword)))
|
||||
{
|
||||
Orders.Add(order);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsKeywordMatch(PddBrowserOrderInvoiceViewModel order, string keyword)
|
||||
{
|
||||
return string.IsNullOrEmpty(keyword)
|
||||
|| (!string.IsNullOrEmpty(order.order_sn) && order.order_sn.Contains(keyword))
|
||||
|| (!string.IsNullOrEmpty(order.GoodsName) && order.GoodsName.Contains(keyword));
|
||||
}
|
||||
|
||||
private void ResetSearch()
|
||||
{
|
||||
SearchText = "";
|
||||
Search();
|
||||
}
|
||||
|
||||
private void OpenInvoice(PddBrowserOrderInvoiceViewModel order)
|
||||
{
|
||||
SelectedOrder = order;
|
||||
BrowserDetail.Load($"https://mobile.yangkeduo.com/transac_return_compensation.html?_t_timestamp=transac_modify_invoice&order_sn={order.order_sn}");
|
||||
ShowOrderBrowserDetail();
|
||||
//InvoiceType = string.IsNullOrEmpty(order.InvoiceType) ? "电子普通发票" : order.InvoiceType;
|
||||
//InvoiceTitle = string.IsNullOrEmpty(order.InvoiceTitle) ? "XX科技有限公司" : order.InvoiceTitle;
|
||||
//TaxNo = string.IsNullOrEmpty(order.TaxNo) ? "91110000XXXXXXXXXX" : order.TaxNo;
|
||||
//IsInvoiceDialogOpen = true;
|
||||
}
|
||||
|
||||
private void ConfirmInvoice()
|
||||
{
|
||||
if (SelectedOrder == null)
|
||||
return;
|
||||
|
||||
//SelectedOrder.IsInvoiced = true;
|
||||
//SelectedOrder.InvoiceType = InvoiceType;
|
||||
//SelectedOrder.InvoiceTitle = InvoiceTitle;
|
||||
//SelectedOrder.TaxNo = TaxNo;
|
||||
//SelectedOrder.InvoiceNo = "25" + DateTime.Now.ToString("MMddHHmmss");
|
||||
//SelectedOrder.InvoiceAmountText = SelectedOrder.AmountText;
|
||||
//SelectedOrder.InvoiceTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
IsInvoiceDialogOpen = false;
|
||||
|
||||
//MessageBox.Show($"订单 {SelectedOrder.OrderNo} 开票成功");
|
||||
}
|
||||
|
||||
private void ShowInvoice(PddBrowserOrderInvoiceViewModel order)
|
||||
{
|
||||
SelectedOrder = order;
|
||||
IsInvoiceDetailOpen = true;
|
||||
}
|
||||
|
||||
private void ViewOrder(PddBrowserOrderInvoiceViewModel order)
|
||||
{
|
||||
//MessageBox.Show($"查看订单:{order.OrderNo}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原型演示数据(后续可替换为真实接口数据)
|
||||
/// </summary>
|
||||
private Task InitSampleData()
|
||||
{
|
||||
string directoryPath = @"E:\820";
|
||||
|
||||
// 3. 获取所有 txt 文件
|
||||
var txtFiles = Directory.GetFiles(directoryPath, "*.txt");
|
||||
|
||||
if (txtFiles.Length == 0)
|
||||
{
|
||||
Console.WriteLine("未找到任何 .txt 文件");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
foreach (var filePath in txtFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
string jsonContent = File.ReadAllText(filePath);
|
||||
parserData(jsonContent);
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
#region 进度条
|
||||
|
||||
private string _bottomMsg = "";
|
||||
public string BottomMsg
|
||||
{
|
||||
get => _bottomMsg;
|
||||
set => SetValue(ref _bottomMsg, value);
|
||||
}
|
||||
|
||||
private double _progressValue;
|
||||
public double ProgressValue
|
||||
{
|
||||
get => _progressValue;
|
||||
set => SetValue(ref _progressValue, value);
|
||||
}
|
||||
|
||||
private double _progressMaximum = 100;
|
||||
public double ProgressMaximum
|
||||
{
|
||||
get => _progressMaximum;
|
||||
set => SetValue(ref _progressMaximum, value);
|
||||
}
|
||||
public void SetProgress(int value, int maxValue)
|
||||
{
|
||||
StopUnknownTotalProgressTimer();
|
||||
ProgressValue = value;
|
||||
ProgressMaximum = maxValue;
|
||||
}
|
||||
|
||||
#region 未知总数百分比模拟进度
|
||||
private System.Threading.Timer _unknownTotalProgressTimer;
|
||||
private DateTime _unknownTotalProgressStartTime;
|
||||
|
||||
/// <summary>
|
||||
/// 开始未知总数的百分比模拟进度:80% 之前走得快,越到最后走得越慢,
|
||||
/// 理论上永远走不到 95% 以上,直到调用 <see cref="CompleteProgress"/> 才会变成 100%。
|
||||
/// </summary>
|
||||
public void StartProgress()
|
||||
{
|
||||
StopUnknownTotalProgressTimer();
|
||||
ProgressMaximum = 100;
|
||||
ProgressValue = 0;
|
||||
_unknownTotalProgressStartTime = DateTime.Now;
|
||||
_unknownTotalProgressTimer = new System.Threading.Timer(_ => UpdateUnknownTotalProgress(), null, 0, 200);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 结束进度:停止模拟,进度条立即变为 100%。
|
||||
/// </summary>
|
||||
public void CompleteProgress()
|
||||
{
|
||||
StopUnknownTotalProgressTimer();
|
||||
ProgressMaximum = 100;
|
||||
ProgressValue = 100;
|
||||
}
|
||||
|
||||
private void UpdateUnknownTotalProgress()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
var elapsed = (DateTime.Now - _unknownTotalProgressStartTime).TotalSeconds;
|
||||
double progress;
|
||||
if (elapsed <= 10)
|
||||
{
|
||||
// 前 10 秒内快速推进到 80%
|
||||
progress = Math.Max(0, Math.Min(80, elapsed * 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 超过 80% 后指数衰减越来越慢,渐近线为 95%,理论上永远走不到 95% 以上
|
||||
progress = 95.0 - 15.0 * Math.Exp(-(elapsed - 10.0) / 20.0);
|
||||
}
|
||||
if (progress > 95) progress = 95;
|
||||
ProgressValue = progress;
|
||||
}));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void StopUnknownTotalProgressTimer()
|
||||
{
|
||||
if (_unknownTotalProgressTimer == null) return;
|
||||
try
|
||||
{
|
||||
_unknownTotalProgressTimer.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_unknownTotalProgressTimer = null;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#F5F7FB">
|
||||
<TabControl Style="{StaticResource StatisticsTabControlStyle}" SelectionChanged="TabControl_SelectionChanged">
|
||||
<TabControl SelectionChanged="TabControl_SelectionChanged" Style="{StaticResource StatisticsTabControlStyle}">
|
||||
<TabItem Header="综合统计" Style="{StaticResource StatisticsTabItemStyle}">
|
||||
<ScrollViewer
|
||||
wpf:ScrollViewerBehavior.FixMouseWheel="True"
|
||||
@@ -283,12 +283,19 @@
|
||||
BorderThickness="1"
|
||||
Cursor="Hand"
|
||||
MouseLeftButtonDown="help_mouseLeftButtonDown">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontWeight="Black"
|
||||
Foreground="White"
|
||||
Text="利润计算逻辑" />
|
||||
<WrapPanel>
|
||||
<TextBlock
|
||||
Margin="0,0,10,0"
|
||||
Foreground="White"
|
||||
Style="{StaticResource TextBlockIcon}"
|
||||
Text="{StaticResource txt-chat_help}" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontWeight="Black"
|
||||
Foreground="White"
|
||||
Text="利润计算逻辑" />
|
||||
</WrapPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Popup 弹出层 -->
|
||||
@@ -307,11 +314,13 @@
|
||||
Margin="0,-10,-10,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Background="Transparent" Click="close"
|
||||
Background="Transparent"
|
||||
Click="close"
|
||||
Content="x" />
|
||||
<TextBlock Margin="0,10,0,0"
|
||||
<TextBlock
|
||||
x:Name="PopupText"
|
||||
MaxWidth="500"
|
||||
Margin="0,10,0,0"
|
||||
FontSize="16"
|
||||
Foreground="White"
|
||||
LineHeight="25"
|
||||
|
||||
Reference in new issue
Block a user