From 1fccd0a7eb0b06e757f677de6279edab0bc81236 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 22 五月 2026 13:08:34 +0800
Subject: [PATCH] refactor(home): 重构首页财务统计功能实现
---
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java | 270 ++++++++++++++++++++++++++++++------------------------
1 files changed, 150 insertions(+), 120 deletions(-)
diff --git a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
index a17c012..fac571b 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -3,8 +3,12 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.ruoyi.account.mapper.AccountStatementMapper;
import com.ruoyi.account.mapper.purchase.AccountPurchasePaymentMapper;
import com.ruoyi.account.mapper.sales.AccountSalesCollectionMapper;
+import com.ruoyi.account.pojo.AccountStatement;
+import com.ruoyi.account.pojo.purchase.AccountPurchasePayment;
+import com.ruoyi.account.pojo.sales.AccountSalesCollection;
import com.ruoyi.approve.mapper.ApproveProcessMapper;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.basic.mapper.CustomerMapper;
@@ -104,6 +108,7 @@
private final AccountPurchasePaymentMapper accountPurchasePaymentMapper;
private final AccountSalesCollectionMapper accountSalesCollectionMapper;
+ private final AccountStatementMapper accountStatementMapper;
private final ProductionAccountMapper productionAccountMapper;
@@ -394,43 +399,21 @@
*/
@Override
public StatisticsReceivablePayableDto statisticsReceivablePayable(Integer type) {
- StatisticsReceivablePayableDto statisticsReceivablePayableDto = new StatisticsReceivablePayableDto();
- LocalDate today = LocalDate.now();
- LocalDate startDate = null;
- LocalDate endDate = null;
- switch (type) {
- case 1:
- // 鑾峰彇鏈懆鍛ㄤ竴
- startDate = today.with(DayOfWeek.MONDAY);
- // 鑾峰彇鏈懆鍛ㄦ棩
- endDate = today.with(DayOfWeek.SUNDAY);
- break;
- case 2:
- startDate = today.with(TemporalAdjusters.firstDayOfMonth());
- endDate = today.with(TemporalAdjusters.lastDayOfMonth());
- break;
- case 3:
- Month currentMonth = today.getMonth();
- Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter();
- Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
+ StatisticsReceivablePayableDto dto = new StatisticsReceivablePayableDto();
+ LocalDate[] range = resolveFinanceRange(type);
+ LocalDate startDate = range[0];
+ LocalDate endDate = range[1];
- startDate = today.withMonth(firstMonthOfQuarter.getValue())
- .with(TemporalAdjusters.firstDayOfMonth());
- endDate = today.withMonth(lastMonthOfQuarter.getValue())
- .with(TemporalAdjusters.lastDayOfMonth());
- break;
- }
- // 搴旀敹
+ BigDecimal receivableBase = sumSalesContractAmount(startDate, endDate);
+ BigDecimal payableBase = sumPurchaseContractAmount(startDate, endDate);
+ BigDecimal advanceMoney = sumCollectionAmount(startDate, endDate);
+ BigDecimal prepayMoney = sumPaymentAmount(startDate, endDate);
- // 搴斾粯
-
- // 棰勬敹
-
- // 棰勪粯
-
-
-
- return statisticsReceivablePayableDto;
+ dto.setReceivableMoney(scaleMoney(maxZero(receivableBase.subtract(advanceMoney))));
+ dto.setPayableMoney(scaleMoney(maxZero(payableBase.subtract(prepayMoney))));
+ dto.setAdvanceMoney(scaleMoney(advanceMoney));
+ dto.setPrepayMoney(scaleMoney(prepayMoney));
+ return dto;
}
public static <T> BigDecimal sumAmount(List<T> list, java.util.function.Function<T, BigDecimal> amountExtractor) {
@@ -1239,102 +1222,58 @@
@Override
public MonthlyIncomeDto monthlyIncome() {
MonthlyIncomeDto dto = new MonthlyIncomeDto();
- LocalDate now = LocalDate.now();
- YearMonth currentMonth = YearMonth.from(now);
- LocalDateTime startOfMonth = currentMonth.atDay(1).atStartOfDay();
- LocalDateTime endOfMonth = currentMonth.atEndOfMonth().atTime(23, 59, 59);
+ LocalDate today = LocalDate.now();
+ YearMonth currentMonth = YearMonth.from(today);
+ LocalDate startDate = currentMonth.atDay(1);
+ LocalDate endDate = currentMonth.atEndOfMonth();
- LambdaQueryWrapper<SalesLedgerProduct> wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(SalesLedgerProduct::getType, 1);
- wrapper.ge(SalesLedgerProduct::getRegisterDate, startOfMonth);
- wrapper.le(SalesLedgerProduct::getRegisterDate, endOfMonth);
+ BigDecimal monthlyIncome = sumCollectionAmount(startDate, endDate);
+ BigDecimal receivableBase = sumSalesContractAmount(startDate, endDate);
+ String collectionRate = toRateString(monthlyIncome, receivableBase);
- List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(wrapper);
+ String currentMonthText = currentMonth.toString();
+ List<AccountStatement> receivableStatements = defaultList(accountStatementMapper.selectList(
+ new LambdaQueryWrapper<AccountStatement>()
+ .eq(AccountStatement::getAccountType, 1)
+ .le(AccountStatement::getStatementMonth, currentMonthText)));
- if (CollectionUtils.isEmpty(products)) {
- return dto;
- }
+ long overdueNum = receivableStatements.stream()
+ .filter(item -> item.getStatementMonth() != null && item.getStatementMonth().compareTo(currentMonthText) < 0)
+ .filter(item -> defaultDecimal(item.getClosingBalance()).compareTo(BigDecimal.ZERO) > 0)
+ .count();
+ long totalReceivableCount = receivableStatements.size();
+ String overdueRate = totalReceivableCount == 0
+ ? "0.00"
+ : BigDecimal.valueOf(overdueNum)
+ .multiply(BigDecimal.valueOf(100))
+ .divide(BigDecimal.valueOf(totalReceivableCount), 2, RoundingMode.HALF_UP)
+ .toString();
+
+ dto.setMonthlyIncome(scaleMoney(monthlyIncome));
+ dto.setCollectionRate(collectionRate);
+ dto.setOverdueNum(BigDecimal.valueOf(overdueNum));
+ dto.setOverdueRate(overdueRate);
return dto;
}
+ @Override
public MonthlyExpenditureDto monthlyExpenditure() {
-
MonthlyExpenditureDto dto = new MonthlyExpenditureDto();
+ LocalDate today = LocalDate.now();
+ YearMonth currentMonth = YearMonth.from(today);
+ LocalDate startDate = currentMonth.atDay(1);
+ LocalDate endDate = currentMonth.atEndOfMonth();
- // 褰撴湀鏃堕棿鑼冨洿
- LocalDate now = LocalDate.now();
- YearMonth currentMonth = YearMonth.from(now);
- LocalDateTime startOfMonth = currentMonth.atDay(1).atStartOfDay();
- LocalDateTime endOfMonth = currentMonth.atEndOfMonth().atTime(23, 59, 59);
+ BigDecimal monthlyExpenditure = sumPaymentAmount(startDate, endDate);
+ BigDecimal payableBase = sumPurchaseContractAmount(startDate, endDate);
+ BigDecimal monthlyIncome = sumCollectionAmount(startDate, endDate);
+ BigDecimal grossProfit = monthlyIncome.subtract(monthlyExpenditure);
- // 閲囪喘鍙拌处锛坱ype = 2锛�
- LambdaQueryWrapper<SalesLedgerProduct> purchaseWrapper = new LambdaQueryWrapper<>();
- purchaseWrapper.eq(SalesLedgerProduct::getType, 2);
- purchaseWrapper.ge(SalesLedgerProduct::getRegisterDate, startOfMonth);
- purchaseWrapper.le(SalesLedgerProduct::getRegisterDate, endOfMonth);
-
- List<SalesLedgerProduct> purchaseProducts = salesLedgerProductMapper.selectList(purchaseWrapper);
-
- BigDecimal rawMaterialCost = BigDecimal.ZERO; // 鍘熸潗鏂欐垚鏈�
- BigDecimal paidAmount = BigDecimal.ZERO; // 宸蹭粯娆鹃噾棰�
- BigDecimal pendingAmount = BigDecimal.ZERO; // 寰呬粯娆鹃噾棰�
-
- if (!CollectionUtils.isEmpty(purchaseProducts)) {
- for (SalesLedgerProduct p : purchaseProducts) {
-
- if (p.getTaxInclusiveTotalPrice() != null) {
- rawMaterialCost = rawMaterialCost.add(p.getTaxInclusiveTotalPrice());
- }
- }
- }
-
- // 鍏朵粬璐圭敤
-
-
- // 鏈堝害鎬绘敮鍑�
- BigDecimal monthlyExpenditure = BigDecimal.ZERO;
- dto.setMonthlyExpenditure(monthlyExpenditure);
-
- // 宸蹭粯娆� 梅锛堝凡浠樻 + 寰呬粯娆撅級
- BigDecimal totalPayable = paidAmount.add(pendingAmount);
- if (totalPayable.compareTo(BigDecimal.ZERO) > 0) {
- String paymentRate = paidAmount
- .divide(totalPayable, 4, RoundingMode.HALF_UP)
- .multiply(BigDecimal.valueOf(100))
- .setScale(2, RoundingMode.HALF_UP)
- .toString();
- dto.setPaymentRate(paymentRate);
- }
-
- // 鍞彴璐︼紙type = 1锛�
- LambdaQueryWrapper<SalesLedgerProduct> salesWrapper = new LambdaQueryWrapper<>();
- salesWrapper.eq(SalesLedgerProduct::getType, 1);
- salesWrapper.ge(SalesLedgerProduct::getRegisterDate, startOfMonth);
- salesWrapper.le(SalesLedgerProduct::getRegisterDate, endOfMonth);
-
- List<SalesLedgerProduct> salesProducts = salesLedgerProductMapper.selectList(salesWrapper);
-
- BigDecimal revenue = BigDecimal.ZERO;
-
- // 姣涘埄娑� & 鍒╂鼎鐜�
- if (revenue.compareTo(BigDecimal.ZERO) > 0) {
-
- // 姣涘埄娑� = 閿�鍞敹鍏� - 鍘熸潗鏂欐垚鏈�
- BigDecimal grossProfit = revenue.subtract(rawMaterialCost);
- dto.setGrossProfit(grossProfit);
-
- // 鍒╂鼎鐜� = (閿�鍞敹鍏� - 鏈堝害鎬绘敮鍑�) / 閿�鍞敹鍏�
- BigDecimal profit = revenue.subtract(monthlyExpenditure);
- String profitMarginRate = profit
- .divide(revenue, 4, RoundingMode.HALF_UP)
- .multiply(BigDecimal.valueOf(100))
- .setScale(2, RoundingMode.HALF_UP)
- .toString();
-
- dto.setProfitMarginRate(profitMarginRate);
- }
-
+ dto.setMonthlyExpenditure(scaleMoney(monthlyExpenditure));
+ dto.setPaymentRate(toRateString(monthlyExpenditure, payableBase));
+ dto.setGrossProfit(scaleMoney(grossProfit));
+ dto.setProfitMarginRate(toRateString(grossProfit, monthlyIncome));
return dto;
}
@@ -2331,6 +2270,97 @@
return productionOperationTaskMapper.calculateProductionStatistics(startDateTime, endDateTime, userId, processIds);
}
+ private LocalDate[] resolveFinanceRange(Integer type) {
+ LocalDate today = LocalDate.now();
+ int safeType = type == null ? 1 : type;
+ LocalDate startDate;
+ LocalDate endDate;
+ switch (safeType) {
+ case 1:
+ startDate = today.with(DayOfWeek.MONDAY);
+ endDate = today.with(DayOfWeek.SUNDAY);
+ break;
+ case 2:
+ startDate = today.with(TemporalAdjusters.firstDayOfMonth());
+ endDate = today.with(TemporalAdjusters.lastDayOfMonth());
+ break;
+ case 3:
+ Month firstMonthOfQuarter = today.getMonth().firstMonthOfQuarter();
+ startDate = LocalDate.of(today.getYear(), firstMonthOfQuarter, 1);
+ endDate = startDate.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth());
+ break;
+ default:
+ startDate = today.with(DayOfWeek.MONDAY);
+ endDate = today.with(DayOfWeek.SUNDAY);
+ break;
+ }
+ return new LocalDate[]{startDate, endDate};
+ }
+
+ private BigDecimal sumSalesContractAmount(LocalDate startDate, LocalDate endDate) {
+ List<SalesLedger> salesLedgers = defaultList(salesLedgerMapper.selectList(new LambdaQueryWrapper<SalesLedger>()
+ .ge(SalesLedger::getEntryDate, toDate(startDate))
+ .lt(SalesLedger::getEntryDate, toExclusiveEndDate(endDate))));
+ return sumAmount(salesLedgers, SalesLedger::getContractAmount);
+ }
+
+ private BigDecimal sumPurchaseContractAmount(LocalDate startDate, LocalDate endDate) {
+ List<PurchaseLedger> purchaseLedgers = defaultList(purchaseLedgerMapper.selectList(new LambdaQueryWrapper<PurchaseLedger>()
+ .ge(PurchaseLedger::getEntryDate, toDate(startDate))
+ .lt(PurchaseLedger::getEntryDate, toExclusiveEndDate(endDate))));
+ return sumAmount(purchaseLedgers, PurchaseLedger::getContractAmount);
+ }
+
+ private BigDecimal sumCollectionAmount(LocalDate startDate, LocalDate endDate) {
+ List<AccountSalesCollection> collections = defaultList(accountSalesCollectionMapper.selectList(
+ new LambdaQueryWrapper<AccountSalesCollection>()
+ .ge(AccountSalesCollection::getCollectionDate, startDate)
+ .le(AccountSalesCollection::getCollectionDate, endDate)));
+ return sumAmount(collections, AccountSalesCollection::getCollectionAmount);
+ }
+
+ private BigDecimal sumPaymentAmount(LocalDate startDate, LocalDate endDate) {
+ List<AccountPurchasePayment> payments = defaultList(accountPurchasePaymentMapper.selectList(
+ new LambdaQueryWrapper<AccountPurchasePayment>()
+ .ge(AccountPurchasePayment::getPaymentDate, startDate)
+ .le(AccountPurchasePayment::getPaymentDate, endDate)));
+ return sumAmount(payments, AccountPurchasePayment::getPaymentAmount);
+ }
+
+ private Date toDate(LocalDate localDate) {
+ return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
+ }
+
+ private Date toExclusiveEndDate(LocalDate localDate) {
+ return Date.from(localDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
+ }
+
+ private String toRateString(BigDecimal numerator, BigDecimal denominator) {
+ if (denominator == null || denominator.compareTo(BigDecimal.ZERO) <= 0) {
+ return "0.00";
+ }
+ return defaultDecimal(numerator)
+ .divide(denominator, 4, RoundingMode.HALF_UP)
+ .multiply(BigDecimal.valueOf(100))
+ .setScale(2, RoundingMode.HALF_UP)
+ .toString();
+ }
+
+ private BigDecimal maxZero(BigDecimal value) {
+ if (value == null) {
+ return BigDecimal.ZERO;
+ }
+ return value.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : value;
+ }
+
+ private BigDecimal scaleMoney(BigDecimal value) {
+ return defaultDecimal(value).setScale(2, RoundingMode.HALF_UP);
+ }
+
+ private <T> List<T> defaultList(List<T> list) {
+ return list == null ? List.of() : list;
+ }
+
private BigDecimal defaultDecimal(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value;
}
--
Gitblit v1.9.3