RevenueReport.razor.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. using AI.Platform.Core;
  2. using Microsoft.AspNetCore.Components;
  3. using Org.BouncyCastle.Asn1.X509;
  4. using System;
  5. using AntDesign;
  6. using System.Collections.Generic;
  7. using System.Globalization;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. using ZhonTai.Admin.Contracts.Domain.VehicleTerminal.Payment;
  11. using ZhonTai.Admin.Contracts.Domain.VehicleTerminal.Transaction;
  12. using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
  13. namespace AI.Platform.Page.Pages.Report
  14. {
  15. public partial class RevenueReport : ComponentBase
  16. {
  17. [Inject] private SqlSugarRepository<TransactionEntity> TransactionRepository { get; set; } = default!;
  18. [Inject] private SqlSugarRepository<PayTypeEntity> PayTypeRepository { get; set; } = default!;
  19. [Inject] private SqlSugarRepository<RechargeRecordEntity> _RechargeRecordPository { get; set; }
  20. private RevenueReportViewModel ViewModel { get; set; } = new();
  21. protected override async Task OnInitializedAsync()
  22. {
  23. base.OnInitialized();
  24. await ViewModel.InitializeData(TransactionRepository, PayTypeRepository, _RechargeRecordPository);
  25. }
  26. // 格式化货币显示
  27. private string FormatCurrency(decimal? value, bool withoutSymbol = false)
  28. {
  29. return ViewModel.FormatCurrency(value, withoutSymbol);
  30. }
  31. // 格式化数字显示
  32. private string FormatNumber(decimal? value)
  33. {
  34. return ViewModel.FormatNumber(value);
  35. }
  36. // 查询处理
  37. private async Task HandleQuery()
  38. {
  39. await ViewModel.HandleQuery();
  40. StateHasChanged();
  41. }
  42. // 重置处理
  43. private void HandleReset()
  44. {
  45. ViewModel.HandleReset();
  46. StateHasChanged();
  47. }
  48. }
  49. // ViewModel 类
  50. public class RevenueReportViewModel
  51. {
  52. // 筛选条件模型
  53. public class FilterData
  54. {
  55. public DateTime? Date { get; set; } = DateTime.Parse("2025-12-01");
  56. public DateTime? EDate { get; set; } = DateTime.Parse("2025-12-31");
  57. public string CarNumber { get; set; } = "";
  58. public string PlateNumber { get; set; } = "";
  59. }
  60. // 营业收入(车)数据模型
  61. public class CarRevenueItem
  62. {
  63. public int Id { get; set; }
  64. public string CarNumber { get; set; } = "";
  65. public decimal? UnitPrice { get; set; }
  66. public int OrderCount { get; set; }
  67. public decimal SalesLiters { get; set; }
  68. public decimal ReceivableAmount { get; set; }
  69. public decimal ActualAmount { get; set; }
  70. public string OilType { get; set; } = "";
  71. }
  72. // 营业收入(油品)数据模型
  73. public class OilRevenueItem
  74. {
  75. public int Id { get; set; }
  76. public string OilType { get; set; } = "";
  77. public decimal UnitPrice { get; set; }
  78. public int OrderCount { get; set; }
  79. public decimal SalesLiters { get; set; }
  80. public decimal ReceivableAmount { get; set; }
  81. public decimal ActualAmount { get; set; }
  82. }
  83. // 营业收入(充值)数据模型
  84. public class RechargeRevenueItem
  85. {
  86. public int Id { get; set; }
  87. public string RechargeType { get; set; } = "";
  88. public int RechargeCount { get; set; }
  89. public decimal RechargeAmount { get; set; }
  90. }
  91. // 营业收支款项明细数据模型
  92. public class PaymentDetailItem
  93. {
  94. public int Id { get; set; }
  95. public string PaymentMethod { get; set; } = "";
  96. public string Category { get; set; } = "";
  97. public int OrderCount { get; set; }
  98. public decimal SalesLiters { get; set; }
  99. public decimal ReceivableAmount { get; set; }
  100. public decimal ActualAmount { get; set; }
  101. }
  102. // 统计摘要模型
  103. public class SummaryData
  104. {
  105. public int TotalOrders { get; set; }
  106. public decimal TotalReceivable { get; set; }
  107. public decimal TotalActual { get; set; }
  108. public decimal TotalRecharge { get; set; }
  109. }
  110. // 合计模型 - 修改类名以避免冲突
  111. public class CarRevenueSummary
  112. {
  113. public int OrderCount { get; set; }
  114. public decimal SalesLiters { get; set; }
  115. public decimal ReceivableAmount { get; set; }
  116. public decimal ActualAmount { get; set; }
  117. }
  118. public class OilRevenueSummary
  119. {
  120. public int OrderCount { get; set; }
  121. public decimal SalesLiters { get; set; }
  122. public decimal ReceivableAmount { get; set; }
  123. public decimal ActualAmount { get; set; }
  124. }
  125. public class RechargeRevenueSummary
  126. {
  127. public int RechargeCount { get; set; }
  128. public decimal RechargeAmount { get; set; }
  129. }
  130. public class PaymentDetailSummary
  131. {
  132. public int OrderCount { get; set; }
  133. public decimal SalesLiters { get; set; }
  134. public decimal ReceivableAmount { get; set; }
  135. public decimal ActualAmount { get; set; }
  136. }
  137. // 公共属性
  138. public FilterData Filter { get; set; } = new();
  139. public List<CarRevenueItem> CarRevenue { get; set; } = new();
  140. public List<OilRevenueItem> OilRevenue { get; set; } = new();
  141. public List<RechargeRevenueItem> RechargeRevenue { get; set; } = new();
  142. public List<PaymentDetailItem> PaymentDetails { get; set; } = new();
  143. public SummaryData Summary { get; set; } = new();
  144. // 计算属性 - 合计 - 修改属性名以避免冲突
  145. public CarRevenueSummary CarRevenueTotalResult => CalculateCarRevenueTotal();
  146. public OilRevenueSummary OilRevenueTotalResult => CalculateOilRevenueTotal();
  147. public RechargeRevenueSummary RechargeRevenueTotalResult => CalculateRechargeRevenueTotal();
  148. public PaymentDetailSummary PaymentDetailsTotalResult => CalculatePaymentDetailsTotal();
  149. public SqlSugarRepository<TransactionEntity> _TransactionRepository;
  150. public SqlSugarRepository<PayTypeEntity> _PayTypeRepository;
  151. public SqlSugarRepository<RechargeRecordEntity> _RechargeRepository;
  152. // 初始化数据
  153. public async Task InitializeData(SqlSugarRepository<TransactionEntity> TransactionRepository,
  154. SqlSugarRepository<PayTypeEntity> PayTypeRepository,
  155. SqlSugarRepository<RechargeRecordEntity> _RechargeRecordPository)
  156. {
  157. _TransactionRepository = TransactionRepository;
  158. _PayTypeRepository = PayTypeRepository;
  159. _RechargeRepository = _RechargeRecordPository;
  160. await Query();
  161. }
  162. public async Task Query()
  163. {
  164. await Reset();
  165. var trxQuery = _TransactionRepository.AsQueryable().Where(_ => _.OrderStatus == 1);
  166. if (Filter.Date.HasValue && Filter.EDate.HasValue)
  167. {
  168. trxQuery = trxQuery.Where(_ => _.TransactionTime >= Filter.Date.Value
  169. && _.TransactionTime <= Filter.EDate.Value);
  170. }
  171. if (!string.IsNullOrEmpty(Filter.CarNumber))
  172. {
  173. trxQuery = trxQuery.Where(_ => _.DeviceId == Filter.CarNumber);
  174. }
  175. if (!string.IsNullOrEmpty(Filter.PlateNumber))
  176. {
  177. trxQuery = trxQuery.Where(_ => _.LicencePlate == Filter.PlateNumber);
  178. }
  179. var trxs = await trxQuery.ToListAsync();
  180. var Paytype = await _PayTypeRepository.AsQueryable().ToListAsync();
  181. var RechargeQuery = _RechargeRepository.AsQueryable().Where(_ => _.OrderStatus == 1);
  182. var Recharge = new List<RechargeRecordEntity>();
  183. if (Filter.Date.HasValue && Filter.EDate.HasValue)
  184. {
  185. RechargeQuery = RechargeQuery.Where(_ => _.TransactionTime >= Filter.Date.Value
  186. && _.TransactionTime <= Filter.EDate.Value);
  187. }
  188. if (string.IsNullOrEmpty(Filter.CarNumber) && string.IsNullOrEmpty(Filter.PlateNumber))
  189. {
  190. Recharge = await RechargeQuery.ToListAsync();
  191. }
  192. // 初始化营业收入(车)数据
  193. trxs.GroupBy(_ => _.LicencePlate).ToList().ForEach(_ => {
  194. CarRevenue.Add(new CarRevenueItem
  195. {
  196. CarNumber = _.Key,
  197. UnitPrice = _.FirstOrDefault()?.OilPrice,
  198. OrderCount = _.Count(),
  199. SalesLiters = _.Sum(a => a.OilVolume),
  200. ReceivableAmount = _.Sum(a => a.PayableAmount),
  201. ActualAmount = _.Sum(a => a.PayableAmount),
  202. OilType = _.FirstOrDefault()?.OilProduct
  203. });
  204. });
  205. // 初始化营业收入(油品)数据
  206. trxs.GroupBy(_ => _.OilProduct).ToList().ForEach(_ => {
  207. OilRevenue.Add(new OilRevenueItem
  208. {
  209. OilType = _.Key,
  210. UnitPrice = _.FirstOrDefault().OilPrice,
  211. OrderCount = _.Count(),
  212. SalesLiters = _.Sum(a => a.OilVolume),
  213. ReceivableAmount = _.Sum(a => a.ActualAmount),
  214. ActualAmount = _.Sum(a => a.ActualAmount)
  215. });
  216. });
  217. // 初始化营业收入(充值)数据
  218. Recharge.GroupBy(_ => _.PaymentMethod).ToList().ForEach(_ => {
  219. var payName = Paytype.Where(a => a.Id == _.Key).FirstOrDefault()?.Name;
  220. RechargeRevenue.Add(new RechargeRevenueItem
  221. {
  222. RechargeType = payName,
  223. RechargeCount = _.Count(),
  224. RechargeAmount = _.Sum(a => a.OriginalAmount)
  225. });
  226. });
  227. // 初始化营业收支款项明细数据
  228. var PaymentMethod = trxs.GroupBy(x => x.PaymentMethod).ToList();
  229. foreach (var item in PaymentMethod)
  230. {
  231. foreach (var a in trxs.Where(_ => _.PaymentMethod == item.Key).ToList().GroupBy(_ => _.OilProduct).ToList())
  232. {
  233. PaymentDetails.Add(new PaymentDetailItem
  234. {
  235. PaymentMethod = Paytype.Where(_ => _.Id == item.Key).FirstOrDefault()?.Name,
  236. Category = a.Key,
  237. OrderCount = a.Count(),
  238. SalesLiters = a.Sum(_ => _.OilVolume),
  239. ReceivableAmount = a.Sum(_ => _.PayableAmount),
  240. ActualAmount = a.Sum(_ => _.PayableAmount)
  241. });
  242. }
  243. //trxs.Where(_ => _.PaymentMethod == item.Key).ToList().GroupBy(_ => _.OilProduct).ForEach(a => {
  244. // PaymentDetails.Add(new PaymentDetailItem
  245. // {
  246. // PaymentMethod = Paytype.Where(_ => _.Id == item.Key).FirstOrDefault()?.Name,
  247. // Category = a.Key,
  248. // OrderCount = a.Count(),
  249. // SalesLiters = a.Sum(_ => _.OilVolume),
  250. // ReceivableAmount = a.Sum(_ => _.PayableAmount),
  251. // ActualAmount = a.Sum(_ => _.PayableAmount)
  252. // });
  253. //});
  254. }
  255. // 初始化统计摘要
  256. Summary = new SummaryData
  257. {
  258. TotalOrders = trxs.Count() + Recharge.Count(),
  259. TotalReceivable = trxs.Sum(_ => _.PayableAmount),
  260. TotalActual = trxs.Sum(_ => _.PayableAmount),
  261. TotalRecharge = Recharge.Sum(_ => _.OriginalAmount)
  262. };
  263. }
  264. // 计算合计方法 - 修改返回类型
  265. private CarRevenueSummary CalculateCarRevenueTotal()
  266. {
  267. var total = new CarRevenueSummary();
  268. foreach (var item in CarRevenue)
  269. {
  270. total.OrderCount += item.OrderCount;
  271. total.SalesLiters += item.SalesLiters;
  272. total.ReceivableAmount += item.ReceivableAmount;
  273. total.ActualAmount += item.ActualAmount;
  274. }
  275. return total;
  276. }
  277. private OilRevenueSummary CalculateOilRevenueTotal()
  278. {
  279. var total = new OilRevenueSummary();
  280. foreach (var item in OilRevenue)
  281. {
  282. total.OrderCount += item.OrderCount;
  283. total.SalesLiters += item.SalesLiters;
  284. total.ReceivableAmount += item.ReceivableAmount;
  285. total.ActualAmount += item.ActualAmount;
  286. }
  287. return total;
  288. }
  289. private RechargeRevenueSummary CalculateRechargeRevenueTotal()
  290. {
  291. var total = new RechargeRevenueSummary();
  292. foreach (var item in RechargeRevenue)
  293. {
  294. total.RechargeCount += item.RechargeCount;
  295. total.RechargeAmount += item.RechargeAmount;
  296. }
  297. return total;
  298. }
  299. private PaymentDetailSummary CalculatePaymentDetailsTotal()
  300. {
  301. var total = new PaymentDetailSummary();
  302. foreach (var item in PaymentDetails)
  303. {
  304. total.OrderCount += item.OrderCount;
  305. total.SalesLiters += item.SalesLiters;
  306. total.ReceivableAmount += item.ReceivableAmount;
  307. total.ActualAmount += item.ActualAmount;
  308. }
  309. return total;
  310. }
  311. // 格式化货币显示
  312. public string FormatCurrency(decimal? value, bool withoutSymbol = false)
  313. {
  314. if (value == null) return "-";
  315. if (withoutSymbol)
  316. {
  317. return value.Value.ToString("N2", CultureInfo.CreateSpecificCulture("zh-CN"));
  318. }
  319. return value.Value.ToString("C", CultureInfo.CreateSpecificCulture("zh-CN"));
  320. }
  321. // 格式化数字显示
  322. public string FormatNumber(decimal? value)
  323. {
  324. if (value == null) return "-";
  325. return value.Value.ToString("N2", CultureInfo.CreateSpecificCulture("zh-CN"));
  326. }
  327. // 查询处理
  328. public async Task HandleQuery()
  329. {
  330. await Query();
  331. }
  332. public async Task Reset()
  333. {
  334. CarRevenue = new List<CarRevenueItem>();
  335. OilRevenue = new List<OilRevenueItem>();
  336. RechargeRevenue = new List<RechargeRevenueItem>();
  337. PaymentDetails = new List<PaymentDetailItem>();
  338. Summary = new SummaryData();
  339. }
  340. // 重置处理
  341. public void HandleReset()
  342. {
  343. Filter.Date = DateTime.Parse("2025-12-01");
  344. Filter.EDate = DateTime.Parse("2025-12-31");
  345. Filter.CarNumber = "";
  346. Filter.PlateNumber = "";
  347. HandleQuery();
  348. }
  349. }
  350. }