From 5bb4bd2d00dff384b639b316687338bf1f28e919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Fri, 15 May 2026 14:03:05 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=95=B0=E6=8D=AE=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Order/Dtos/OrderListOutput.cs | 26 +++++ YD_Event.Application/Order/OrderService.cs | 100 ++++++++++++++++++ YD_Event.Application/YD_Event.Application.xml | 30 ++++++ 3 files changed, 156 insertions(+) diff --git a/YD_Event.Application/Order/Dtos/OrderListOutput.cs b/YD_Event.Application/Order/Dtos/OrderListOutput.cs index 765d9c4..fbfd49e 100644 --- a/YD_Event.Application/Order/Dtos/OrderListOutput.cs +++ b/YD_Event.Application/Order/Dtos/OrderListOutput.cs @@ -397,3 +397,29 @@ public class RefundOrderInput /// public List? PersonIds { get; set; } } + +/// +/// 订单统计输出 +/// +public class OrderStatsOutput +{ + /// + /// 原金额:所有支付订单(排除报名失败)的原始报名费用总和 + /// + public decimal TotalOriginalAmount { get; set; } + + /// + /// 优惠金额:所有支付订单(排除报名失败)的折扣金额总和 + /// + public decimal TotalDiscountAmount { get; set; } + + /// + /// 实付金额:所有实际收款的金额总和,排除报名失败状态的订单记录 + /// + public decimal TotalActualAmount { get; set; } + + /// + /// 退款金额:所有退款数据中的金额总和,排除报名失败状态的退款记录 + /// + public decimal TotalRefundAmount { get; set; } +} diff --git a/YD_Event.Application/Order/OrderService.cs b/YD_Event.Application/Order/OrderService.cs index c69f634..c5dd7bc 100644 --- a/YD_Event.Application/Order/OrderService.cs +++ b/YD_Event.Application/Order/OrderService.cs @@ -824,4 +824,104 @@ public class OrderService : BaseService, ITransien style.VerticalAlignment = ExcelVerticalAlignment.Center; SetCellBorders(range, ExcelBorderStyle.Thin); } + + /// + /// 获取订单统计数据 + /// + [DisplayName("获取订单统计数据")] + [HttpGet("stats")] + public async Task GetStats([FromQuery] OrderQueryInput input) + { + var userId = _authManager.UserId; + // 判断是否是单位认证账号 + var certification = await _db.Queryable() + .FirstAsync(c => c.UserId == userId && c.AuditStatus == AuditStatus.Pass && !c.DeleteMark); + + var query = _orderRepository.AsQueryable() + .LeftJoin((o, e) => o.EventId == e.Id) + .LeftJoin((o, e, m) => o.MerchantId == m.Id) + .LeftJoin((o, e, m, r) => o.RegistrationId == r.Id) + .LeftJoin((o, e, m, r, ro) => o.RelatedOrderId == ro.Id) + // 默认只统计已完成支付流程的订单(已支付、已发货、已完成、已退款、报名失败) + .WhereIF(!input.OrderStatus.HasValue, (o, e, m, r, ro) => + o.OrderStatus == OrderStatus.Paid || + o.OrderStatus == OrderStatus.Shipped || + o.OrderStatus == OrderStatus.Completed || + o.OrderStatus == OrderStatus.Refunded || + o.OrderStatus == OrderStatus.RegistrationFailed) + .WhereIF(!string.IsNullOrWhiteSpace(input.OrderNo), (o, e, m, r, ro) => o.OrderNo.Contains(input.OrderNo)) + .WhereIF(!string.IsNullOrWhiteSpace(input.EventName), (o, e, m, r, ro) => e.EventName.Contains(input.EventName)) + .WhereIF(input.OrderType.HasValue, (o, e, m, r, ro) => o.OrderType == input.OrderType) + .WhereIF(input.OrderStatus.HasValue, (o, e, m, r, ro) => o.OrderStatus == input.OrderStatus) + .WhereIF(input.PaymentMethod.HasValue, (o, e, m, r, ro) => r.PaymentMethod == input.PaymentMethod) + .WhereIF(input.RegistrationMode.HasValue, (o, e, m, r, ro) => r.RegistrationMode == input.RegistrationMode) + .WhereIF(!string.IsNullOrWhiteSpace(input.ContactPhone), (o, e, m, r, ro) => r.ContactPhone.Contains(input.ContactPhone)) + .WhereIF(input.StartTime.HasValue, (o, e, m, r, ro) => o.CreatedTime >= input.StartTime) + .WhereIF(input.EndTime.HasValue, (o, e, m, r, ro) => o.CreatedTime <= input.EndTime); + + // 权限判断:如果是单位认证用户,只能查看自己单位认证的订单 + if (certification != null && !_authManager.IsSuperAdmin) + { + query = query.Where((o, e, m, r, ro) => o.MerchantCertificationId == certification.Id); + } + + var list = await query.Select((o, e, m, r, ro) => new OrderListOutput + { + OrderNo = o.OrderNo, + UnitName = SqlFunc.IsNullOrEmpty(m.MerchantName) ? "/" : m.MerchantName, + EventName = e.EventName, + OrderType = o.OrderType == 1 ? "收入" : "退款", + RelatedOrderNo = ro.OrderNo, + PaymentMethod = r.PaymentMethod == 2 ? "线上" : "线下", + RegistrationMode = r.RegistrationMode == 1 ? "个人" : "团队", + ContactName = r.ContactName, + ContactPhone = r.ContactPhone, + OriginalAmount = o.OriginalAmount, + DiscountAmount = o.DiscountAmount, + // 收款订单:实付金额=原金额-优惠金额;退款订单:显示原始订单的实付金额 + ActualAmount = o.OrderType == 1 + ? (o.OriginalAmount - o.DiscountAmount > 0 ? o.OriginalAmount - o.DiscountAmount : 0) + : o.ActualAmount, + OrderStatus = o.OrderStatus, + OrderStatusText = + o.OrderStatus == OrderStatus.Pending ? "待支付" : + o.OrderStatus == OrderStatus.Paid ? "已支付" : + o.OrderStatus == OrderStatus.Cancelled ? "已取消" : + o.OrderStatus == OrderStatus.Refunded ? "已退款" : + o.OrderStatus == OrderStatus.Shipped ? "已发货" : + o.OrderStatus == OrderStatus.Completed ? "已完成" : + o.OrderStatus == OrderStatus.RegistrationFailed ? "报名失败" : "", + CreatedTime = o.CreatedTime, + RefundAmount = o.OrderType == 2 ? o.ActualAmount : 0, + RelatedOrderActualAmount = o.OrderType == 2 ? (ro.OriginalAmount - ro.DiscountAmount) : null, + IsRefundOrder = o.OrderType == 2, + PayeeName = o.PayeeName, + PayeeBankName = o.PayeeBankName, + PayeeBankAccount = o.PayeeBankAccount + }) + .ToListAsync(); + + // 计算统计数据(与导出功能保持完全一致的逻辑) + // 1. 原金额:所有支付订单(排除报名失败)的原始报名费用总和 + var paymentOrders = list.Where(x => x.OrderType == "收入" && x.OrderStatus != OrderStatus.RegistrationFailed); + var totalOriginal = paymentOrders.Sum(x => x.OriginalAmount); + + // 2. 优惠金额:所有支付订单(排除报名失败)的折扣金额总和 + var totalDiscount = paymentOrders.Sum(x => x.DiscountAmount); + + // 3. 退款金额:所有退款数据中的金额总和,排除报名失败状态的退款记录 + var refundOrders = list.Where(x => x.OrderType == "退款" && x.OrderStatus != OrderStatus.RegistrationFailed); + var totalRefund = refundOrders.Sum(x => x.ActualAmount); + + // 4. 实付金额:所有实际收款的金额总和,排除报名失败状态的订单记录 + var totalActual = paymentOrders.Sum(x => x.ActualAmount); + + return new OrderStatsOutput + { + TotalOriginalAmount = totalOriginal, + TotalDiscountAmount = totalDiscount, + TotalActualAmount = totalActual, + TotalRefundAmount = totalRefund + }; + } } diff --git a/YD_Event.Application/YD_Event.Application.xml b/YD_Event.Application/YD_Event.Application.xml index 27217bb..14ba7af 100644 --- a/YD_Event.Application/YD_Event.Application.xml +++ b/YD_Event.Application/YD_Event.Application.xml @@ -11299,6 +11299,31 @@ 要取消的队员ID列表(部分取消时使用) + + + 订单统计输出 + + + + + 原金额:所有支付订单(排除报名失败)的原始报名费用总和 + + + + + 优惠金额:所有支付订单(排除报名失败)的折扣金额总和 + + + + + 实付金额:所有实际收款的金额总和,排除报名失败状态的订单记录 + + + + + 退款金额:所有退款数据中的金额总和,排除报名失败状态的退款记录 + + 订单查询输入 @@ -11419,6 +11444,11 @@ 设置数据行样式 + + + 获取订单统计数据 + + 添加机构输入