diff --git a/29WxOrderWpf/App.xaml b/29WxOrderWpf/App.xaml
index a779701..1c7d122 100644
--- a/29WxOrderWpf/App.xaml
+++ b/29WxOrderWpf/App.xaml
@@ -15,6 +15,7 @@
+
diff --git a/29WxOrderWpf/Converters/FenToYuanConverter.cs b/29WxOrderWpf/Converters/FenToYuanConverter.cs
new file mode 100644
index 0000000..4264c7d
--- /dev/null
+++ b/29WxOrderWpf/Converters/FenToYuanConverter.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace _29WxOrderWpf.Converters
+{
+ ///
+ /// 金额转换:分 -> 元(除以 100)。
+ /// 用于把后台返回的以“分”为单位的金额字段显示为“元”。
+ ///
+ public class FenToYuanConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ decimal fen;
+ if (value is int intValue)
+ fen = intValue;
+ else if (value is long longValue)
+ fen = longValue;
+ else if (value is decimal decimalValue)
+ fen = decimalValue;
+ else if (value is double doubleValue)
+ fen = (decimal)doubleValue;
+ else
+ return 0m;
+
+ return fen / 100m;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ // 单向绑定,反向转换不实现
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/29WxOrderWpf/Ctrls/Statistics/RevenueSummaryCards.xaml b/29WxOrderWpf/Ctrls/Statistics/RevenueSummaryCards.xaml
index 4ec5398..36172ba 100644
--- a/29WxOrderWpf/Ctrls/Statistics/RevenueSummaryCards.xaml
+++ b/29WxOrderWpf/Ctrls/Statistics/RevenueSummaryCards.xaml
@@ -7,6 +7,7 @@
xmlns:vm="clr-namespace:_29WxOrderWpf.Ctrls.Statistics.ViewModels"
d:DataContext="{d:DesignInstance Type=vm:ShopRevenueStatisticsViewModel,
IsDesignTimeCreatable=True}"
+ d:Width="1200"
mc:Ignorable="d">
@@ -55,26 +56,45 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -178,7 +198,7 @@
Text="预计技术服务费" />
-
+
@@ -201,44 +221,60 @@
-
-
+
+
+
+
+
+
+
+
+
-
+ FontSize="24"
+ Style="{StaticResource TextBlockIcon}"
+ Text="{StaticResource txt-more_horizontal}" />
+
+
+ FontSize="14"
+ Foreground="#888888"
+ Text="总采购金额" />
+ Margin="0,12,0,0"
+ FontSize="30"
+ FontWeight="Bold"
+ Foreground="#333333"
+ Text="{Binding Summary.BuyerRefundAmount, StringFormat={}¥{0:N2}}" />
+ Margin="0,10,0,0"
+ FontSize="12"
+ Foreground="#999999"
+ Text="售后采购金额" />
@@ -263,26 +299,42 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+ FontSize="24"
+ Style="{StaticResource TextBlockIcon}"
+ Text="{StaticResource txt-more_horizontal}" />
+
+
diff --git a/29WxOrderWpf/Ctrls/Statistics/Services/ShopRevenueStatisticsService.cs b/29WxOrderWpf/Ctrls/Statistics/Services/ShopRevenueStatisticsService.cs
index 7941294..ee66da0 100644
--- a/29WxOrderWpf/Ctrls/Statistics/Services/ShopRevenueStatisticsService.cs
+++ b/29WxOrderWpf/Ctrls/Statistics/Services/ShopRevenueStatisticsService.cs
@@ -45,6 +45,9 @@ namespace _29WxOrderWpf.Ctrls.Statistics.Services
/// 获取店铺下拉列表(用于查询条件)
Task> GetShopOptionsAsync();
+
+
+
}
///
@@ -133,8 +136,8 @@ namespace _29WxOrderWpf.Ctrls.Statistics.Services
int totalOrderCount = list.Count();
int refundOrderCount = refunded.Select(r => r.OrderId).Distinct().Count();
Debug.WriteLine($"计算利润:{(salesAmount - buyerPaymentAmount - platformFeeTotal)}");
- Debug.WriteLine($"正常订单利润:{valid.Sum(r => (decimal)(r.Profit))/100}");
- Debug.WriteLine($"售后订单利润:{refunded.Sum(r => (decimal)(r.Profit))/100}");
+ Debug.WriteLine($"正常订单利润:{valid.Sum(r => (decimal)(r.Profit)) / 100}");
+ Debug.WriteLine($"售后订单利润:{refunded.Sum(r => (decimal)(r.Profit)) / 100}");
return new ShopRevenueSummary
{
SalesAmount = salesAmount,
@@ -152,6 +155,41 @@ namespace _29WxOrderWpf.Ctrls.Statistics.Services
BuyerRefundSuccessedAmount = buyerRefundSuccessedAmount,
};
}
+ ///
+ /// 获取有效订单
+ ///
+ ///
+ ///
+ public static List GetValidOrder(IEnumerable rows)
+ {
+ var list = GetPaymentOrderList(rows); //买手付钱后的订单数量
+ return list.Where(IsValidOrder).ToList();
+ }
+ ///
+ /// 获取退款订单
+ ///
+ ///
+ ///
+ public static List GetRefundOrder(IEnumerable rows)
+ {
+ var list = GetPaymentOrderList(rows); //买手付钱后的订单数量
+ return list.Where(IsRefunded).ToList();
+ }
+ ///
+ /// 获取退款订单
+ ///
+ ///
+ ///
+ public static List GetBuyerRefundRemainingOrder(IEnumerable rows)
+ {
+ var list = GetPaymentOrderList(rows); //买手付钱后的订单数量
+ var refunded = list.Where(IsRefunded).ToList();
+
+ decimal buyerRefundAmount = refunded.Sum(r => (decimal)(r.OutAmount)) / 100m; //买手号退款金额(采购退款金额)
+ decimal buyerRefundSuccessedAmount = refunded.Where(a => IsBuyerRefundSuccessful(a) == false).Sum(r => (decimal)(r.BuyerRefundAmount)) / 100m; //买手号退款成功金额
+
+ return refunded.Where(a => IsBuyerRefundSuccessful(a) == false).ToList();
+ }
/// 销售趋势(按天,缺失日期补 0,仅统计有效订单)
public static List GetSalesTrend(IEnumerable rows, DateTime startDate, DateTime endDate)
diff --git a/29WxOrderWpf/Ctrls/Statistics/ShowOrderDialogView.xaml b/29WxOrderWpf/Ctrls/Statistics/ShowOrderDialogView.xaml
new file mode 100644
index 0000000..6eb7118
--- /dev/null
+++ b/29WxOrderWpf/Ctrls/Statistics/ShowOrderDialogView.xaml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/29WxOrderWpf/Ctrls/Statistics/ShowOrderDialogView.xaml.cs b/29WxOrderWpf/Ctrls/Statistics/ShowOrderDialogView.xaml.cs
new file mode 100644
index 0000000..8bbb966
--- /dev/null
+++ b/29WxOrderWpf/Ctrls/Statistics/ShowOrderDialogView.xaml.cs
@@ -0,0 +1,50 @@
+using _29WxOrderWpf.Ctrls.Statistics.Models;
+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.Statistics;
+
+///
+/// ShowOrderDialogView.xaml 的交互逻辑
+///
+public partial class ShowOrderDialogView : UserControl
+{
+ public ShowOrderDialogView(List list)
+ {
+ InitializeComponent();
+ this.DataContext = new ShowOrderDialogViewModel(list);
+ }
+
+ ///
+ /// 复制订单号到剪贴板
+ ///
+ private void CopyOrderId_Click(object sender, RoutedEventArgs e)
+ {
+ if (sender is FrameworkElement element
+ && element.DataContext is ShopRevenueStatisticsRow row
+ && !string.IsNullOrEmpty(row.OrderId))
+ {
+ Clipboard.SetText(row.OrderId);
+ }
+ }
+}
+class ShowOrderDialogViewModel
+{
+ public List Data { get; set; }
+ public ShowOrderDialogViewModel(List list)
+ {
+ Data = list ?? new List();
+ }
+}
diff --git a/29WxOrderWpf/Ctrls/Statistics/ViewModels/PeriodRevenueStatisticsViewModel.cs b/29WxOrderWpf/Ctrls/Statistics/ViewModels/PeriodRevenueStatisticsViewModel.cs
index b41b843..39b55cc 100644
--- a/29WxOrderWpf/Ctrls/Statistics/ViewModels/PeriodRevenueStatisticsViewModel.cs
+++ b/29WxOrderWpf/Ctrls/Statistics/ViewModels/PeriodRevenueStatisticsViewModel.cs
@@ -1,14 +1,15 @@
-using System;
+using _29WxOrderWpf.Commands;
+using _29WxOrderWpf.Common;
+using _29WxOrderWpf.Ctrls.Statistics.Models;
+using _29WxOrderWpf.Ctrls.Statistics.Services;
+using AllBase.Model.MvvmBaseClasses;
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
-using System.Windows.Input;
using System.Windows;
-using AllBase.Model.MvvmBaseClasses;
-using _29WxOrderWpf.Ctrls.Statistics.Models;
-using _29WxOrderWpf.Ctrls.Statistics.Services;
-using _29WxOrderWpf.Commands;
+using System.Windows.Input;
namespace _29WxOrderWpf.Ctrls.Statistics.ViewModels
{
@@ -545,5 +546,42 @@ namespace _29WxOrderWpf.Ctrls.Statistics.ViewModels
}
#endregion
+
+
+
+ public ICommand ShowOrderListCommand => new AsyncDelegateCommand(ShowOrderList);
+
+ private async Task ShowOrderList(string type)
+ {
+ var query = new ShopRevenueStatisticsQuery
+ {
+ StartDate = StartDate,
+ EndDate = EndDate,
+ ShopKeys = BuildSelectedShopKeys(),
+ };
+ var rows = await _service.QueryRowsAsync(query);
+ List showList = new List();
+ switch (type)
+ {
+ case "ValidOrderCount":
+ showList = RevenueStatisticsAggregator.GetValidOrder(rows);
+ break; //有效订单
+ case "RefundOrderCount":
+ showList = RevenueStatisticsAggregator.GetRefundOrder(rows);
+ break;//退款订单
+ case "BuyerRefundRemainingAmount":
+ showList = RevenueStatisticsAggregator.GetBuyerRefundRemainingOrder(rows);
+ break;//待退回采购金额
+ default:
+ break;
+ }
+
+ new DialogWindow()
+ {
+ Title = "订单列表",
+ Content = new ShowOrderDialogView(showList),
+ DataContext = rows
+ }.ShowDialog();
+ }
}
}
\ No newline at end of file
diff --git a/29WxOrderWpf/Ctrls/Statistics/ViewModels/ShopRevenueStatisticsViewModel.cs b/29WxOrderWpf/Ctrls/Statistics/ViewModels/ShopRevenueStatisticsViewModel.cs
index ca2b6da..979a401 100644
--- a/29WxOrderWpf/Ctrls/Statistics/ViewModels/ShopRevenueStatisticsViewModel.cs
+++ b/29WxOrderWpf/Ctrls/Statistics/ViewModels/ShopRevenueStatisticsViewModel.cs
@@ -1,14 +1,16 @@
-using System;
+using _29WxOrderWpf.Commands;
+using _29WxOrderWpf.Common;
+using _29WxOrderWpf.Ctrls.Statistics.Models;
+using _29WxOrderWpf.Ctrls.Statistics.Services;
+using AllBase.Model.MvvmBaseClasses;
+using CefSharp;
+using NPOI.SS.Formula.Functions;
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
-using AllBase.Model.MvvmBaseClasses;
-using _29WxOrderWpf.Ctrls.Statistics.Models;
-using _29WxOrderWpf.Ctrls.Statistics.Services;
-using CefSharp;
-using _29WxOrderWpf.Commands;
namespace _29WxOrderWpf.Ctrls.Statistics.ViewModels
{
@@ -300,5 +302,41 @@ namespace _29WxOrderWpf.Ctrls.Statistics.ViewModels
}
#endregion
+
+
+ public ICommand ShowOrderListCommand => new AsyncDelegateCommand(ShowOrderList);
+
+ private async Task ShowOrderList(string type)
+ {
+ var query = new ShopRevenueStatisticsQuery
+ {
+ StartDate = StartDate,
+ EndDate = EndDate,
+ ShopKeys = BuildSelectedShopKeys(),
+ };
+ var rows = await _service.QueryRowsAsync(query);
+ List showList = new List();
+ switch (type)
+ {
+ case "ValidOrderCount":
+ showList = RevenueStatisticsAggregator.GetValidOrder(rows);
+ break; //有效订单
+ case "RefundOrderCount":
+ showList = RevenueStatisticsAggregator.GetRefundOrder(rows);
+ break;//退款订单
+ case "BuyerRefundRemainingAmount":
+ showList = RevenueStatisticsAggregator.GetBuyerRefundRemainingOrder(rows);
+ break;//待退回采购金额
+ default:
+ break;
+ }
+
+ new DialogWindow()
+ {
+ Title="订单列表",
+ Content = new ShowOrderDialogView(showList),
+ DataContext = rows
+ }.ShowDialog();
+ }
}
}
\ No newline at end of file
diff --git a/29WxOrderWpf/Styles/BaseButtonStyle.xaml b/29WxOrderWpf/Styles/BaseButtonStyle.xaml
index 9c6e70b..79c3141 100644
--- a/29WxOrderWpf/Styles/BaseButtonStyle.xaml
+++ b/29WxOrderWpf/Styles/BaseButtonStyle.xaml
@@ -229,4 +229,47 @@
+
+
+
\ No newline at end of file