From 83b85ebe8d7c5cd66e88d61d5bbc95c9e256a352 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期二, 21 七月 2026 21:38:22 +0800
Subject: [PATCH] 充电时段统计fix

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java |  243 ++++++++++++++++++++++++++++++++---------------
 1 files changed, 164 insertions(+), 79 deletions(-)

diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java
index 9562cc2..5df6900 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java
@@ -23,6 +23,7 @@
 import com.ruoyi.order.api.vo.ChargingBillListVO;
 import com.ruoyi.order.api.vo.ChargingBillVO;
 import com.ruoyi.order.api.vo.ChargingBillWapper;
+import com.ruoyi.order.api.vo.AccountListVO;
 import com.ruoyi.order.mapper.TChargingBillMapper;
 import com.ruoyi.order.mapper.TChargingOrderMapper;
 import com.ruoyi.order.service.*;
@@ -87,6 +88,137 @@
     private TChargingOrderService chargingOrderService;
     @Resource
     private ITChargingSettlementBillService chargingSettlementBillService;
+    @Resource
+    private ITAccountSettlementStatementService accountSettlementStatementService;
+
+    @Override
+    public AccountListVO accountSettlementBillList(ChargingListQuery dto) {
+        SysUser sysUser = sysUserClient.getSysUser(tokenService.getLoginUser().getUserid()).getData();
+        List<Integer> siteIds = resolveAccountStatementSiteIds(dto, sysUser);
+        LocalDate[] cycleRange = resolveBillingCycleRange(dto.getDateRange());
+
+        PageInfo<TAccountSettlementStatement> statementPage = accountSettlementStatementService.queryPage(
+                dto, siteIds, cycleRange[0], cycleRange[1]);
+        AccountListVO result = accountSettlementStatementService.querySummary(
+                dto, siteIds, cycleRange[0], cycleRange[1]);
+        if (result == null) {
+            result = new AccountListVO();
+        }
+
+        Set<Integer> pageSiteIds = statementPage.getRecords().stream()
+                .map(TAccountSettlementStatement::getSiteId)
+                .filter(siteId -> siteId != null && siteId > 0)
+                .collect(Collectors.toSet());
+        Map<Integer, String> siteNameMap = pageSiteIds.isEmpty() ? Collections.emptyMap()
+                : safeData(siteClient.getSiteByIds(new ArrayList<>(pageSiteIds))).stream()
+                .collect(Collectors.toMap(Site::getId, Site::getName, (first, ignored) -> first));
+
+        List<ChargingBillListVO> records = statementPage.getRecords().stream()
+                .map(statement -> toAccountStatementVO(statement, siteNameMap))
+                .collect(Collectors.toList());
+        PageInfo<ChargingBillListVO> page = new PageInfo<>(statementPage.getCurrent(), statementPage.getSize());
+        page.setTotal(statementPage.getTotal());
+        page.setRecords(records);
+        result.setList(page);
+        result.setOrderList(Collections.emptyList());
+        result.setBillCount(result.getBillCount() == null ? 0 : result.getBillCount());
+        result.setTotalAmount(zeroIfNull(result.getTotalAmount()));
+        result.setPaymentAmount(zeroIfNull(result.getPaymentAmount()));
+        result.setRefundAmount(zeroIfNull(result.getRefundAmount()));
+        result.setCommissionAmount(zeroIfNull(result.getCommissionAmount()));
+        result.setSharingAmount(zeroIfNull(result.getSharingAmount()));
+        result.setPlatformIncome(zeroIfNull(result.getPlatformIncome()));
+        result.setPartnerIncome(zeroIfNull(result.getPartnerIncome()));
+        return result;
+    }
+
+    private List<Integer> resolveAccountStatementSiteIds(ChargingListQuery dto, SysUser sysUser) {
+        List<Integer> siteIds = new ArrayList<>();
+        if (dto.getSiteId() != null) {
+            siteIds.add(dto.getSiteId());
+        } else {
+            List<GetSiteListDTO> sites = safeData(siteClient.getSiteListByUserId(tokenService.getLoginUser().getUserid()));
+            siteIds.addAll(sites.stream().map(GetSiteListDTO::getId).filter(Objects::nonNull).collect(Collectors.toList()));
+        }
+        if (Integer.valueOf(2).equals(sysUser.getRoleType())) {
+            siteIds = siteIds.stream().filter(siteId -> {
+                List<Boolean> permissions = safeData(partnerClient.getAccountMenu(sysUser.getObjectId(), siteId));
+                return permissions.size() > 1 && Boolean.TRUE.equals(permissions.get(1));
+            }).collect(Collectors.toList());
+        }
+        if (Integer.valueOf(1).equals(sysUser.getRoleType())) {
+            siteIds.add(0);
+        }
+        if (siteIds.isEmpty()) {
+            siteIds.add(-1);
+        }
+        return siteIds.stream().distinct().collect(Collectors.toList());
+    }
+
+    private LocalDate[] resolveBillingCycleRange(List<String> dateRange) {
+        LocalDate start = null;
+        LocalDate end = null;
+        if (dateRange != null && !dateRange.isEmpty()) {
+            start = parseBillingMonth(dateRange.get(0));
+            String endValue = dateRange.size() > 1 ? dateRange.get(1) : dateRange.get(0);
+            LocalDate endMonth = parseBillingMonth(endValue);
+            end = endMonth == null ? null : endMonth.plusMonths(1);
+        }
+        return new LocalDate[]{start, end};
+    }
+
+    private LocalDate parseBillingMonth(String value) {
+        if (!StringUtils.hasLength(value) || value.length() < 7) {
+            return null;
+        }
+        return LocalDate.parse(value.substring(0, 7) + "-01");
+    }
+
+    private ChargingBillListVO toAccountStatementVO(TAccountSettlementStatement statement,
+                                                      Map<Integer, String> siteNameMap) {
+        ChargingBillListVO vo = new ChargingBillListVO();
+        vo.setId(statement.getId());
+        vo.setUid(String.valueOf(statement.getId()));
+        vo.setCode(statement.getCode());
+        vo.setType(Integer.valueOf(0).equals(statement.getSiteId()) ? 1 : 2);
+        vo.setSiteId(statement.getSiteId());
+        vo.setSiteName(Integer.valueOf(0).equals(statement.getSiteId())
+                ? "全站" : siteNameMap.getOrDefault(statement.getSiteId(), "-"));
+        vo.setStatus(statement.getStatus());
+        vo.setOrderState(2);
+        vo.setPayType(statement.getAccountType());
+        vo.setPayTypeName(accountTypeName(statement.getAccountType()));
+        vo.setBillWeek(statement.getBillingCycle() == null
+                ? null : statement.getBillingCycle().format(DateTimeFormatter.ofPattern("yyyy-MM")));
+        vo.setBillTime(statement.getCreateTime());
+        vo.setCreateTime(statement.getCreateTime());
+        vo.setPaymentAmount(zeroIfNull(statement.getRechargeAmount()));
+        vo.setRefundAmount(zeroIfNull(statement.getRefundAmount()));
+        vo.setCommissionAmount(zeroIfNull(statement.getPlatformFee()));
+        vo.setSharingAmount(zeroIfNull(statement.getTripartiteCommission()));
+        vo.setBillMoney(zeroIfNull(statement.getRecordedAmount()));
+        vo.setPlatformIncome(BigDecimal.ZERO);
+        vo.setPartnerIncome(BigDecimal.ZERO);
+        vo.setAuthDownLoad(false);
+        return vo;
+    }
+
+    private String accountTypeName(Integer accountType) {
+        if (Integer.valueOf(1).equals(accountType)) {
+            return "微信商户";
+        }
+        if (Integer.valueOf(2).equals(accountType)) {
+            return "支付宝商户";
+        }
+        if (Integer.valueOf(3).equals(accountType)) {
+            return "工商银行商户";
+        }
+        return "-";
+    }
+
+    private BigDecimal zeroIfNull(BigDecimal value) {
+        return value == null ? BigDecimal.ZERO : value;
+    }
 
 
     @Override
@@ -1063,6 +1195,7 @@
         Integer roleType = sysUser.getRoleType();
         //如果没传siteId,获取当前登陆人所有的siteIds
         List<Integer> siteIds = new ArrayList<>();
+        Map<Integer, List<Boolean>> chargingBillPermissionMap = new HashMap<>();
         List<GetSiteListDTO> data = siteClient.getSiteListByUserId(userId).getData();
         for (GetSiteListDTO datum : data) {
             siteIds.add(datum.getId());
@@ -1074,10 +1207,9 @@
                 List<Integer> integers = new ArrayList<>();
                 for (Integer siteId : siteIds) {
                     // 校验有没有这个站点的权限
-                    List<Boolean> t1= partnerClient.getChargingBillMenu(sysUser.getObjectId(),siteId).getData();
-
-                    Boolean b = t1.get(1);
-                    if (b){
+                    List<Boolean> permissions = safeData(partnerClient.getChargingBillMenu(sysUser.getObjectId(), siteId));
+                    chargingBillPermissionMap.put(siteId, permissions);
+                    if (permissions.size() > 1 && Boolean.TRUE.equals(permissions.get(1))){
                         integers.add(siteId);
                     }
                 }
@@ -1098,9 +1230,9 @@
         ChargingBillWapper chargingBillVO = new ChargingBillWapper();
         List<Map<String, Object>> pageList = new ArrayList<>();
         Map<Integer, BigDecimal> siteServiceShareRatioMap = loadSiteServiceShareRatioMap();
-        PageInfo<Map<String, Object>> sumPageInfo = new PageInfo<>(1, 100000);
-        List<Map<String, Object>> sumList = chargingSettlementBillService.queryList(sumPageInfo, dto.getType(), dto.getState(), dto.getDateRange(), statisticalDateType, dto.getSiteIds());
-        Map<String, Map<String, BigDecimal>> incomeIndex = buildChargingBillIncomeIndex(sumList, siteServiceShareRatioMap);
+        List<Map<String, Object>> incomeRows = chargingSettlementBillService.queryIncomeList(
+                dto.getState(), dto.getDateRange(), statisticalDateType, dto.getSiteIds());
+        Map<String, Map<String, BigDecimal>> incomeIndex = buildChargingBillIncomeIndex(incomeRows, siteServiceShareRatioMap);
 		Set<Integer> settlementSiteIds = new HashSet<>();
 		if (list != null) {
 			list.stream().map(item -> item.get("site_id")).filter(Objects::nonNull)
@@ -1147,9 +1279,8 @@
                 data1.put("serviceCharge", serviceCharge);
                 data1.put("authDownLoad", true);
                 if (roleType == 2 && 0 != site_id){
-                    // 校验有没有这个站点的权限
-                    List<Boolean> t1= partnerClient.getChargingBillMenu(sysUser.getObjectId(),site_id).getData();
-                    data1.put("authDownLoad", t1.get(0));
+                    List<Boolean> permissions = chargingBillPermissionMap.getOrDefault(site_id, Collections.emptyList());
+                    data1.put("authDownLoad", !permissions.isEmpty() && Boolean.TRUE.equals(permissions.get(0)));
                 }
                 pageList.add(data1);
             }
@@ -1167,8 +1298,8 @@
         BigDecimal discount = (null == map || null == map.get("couponDeduction")) ? BigDecimal.ZERO : new BigDecimal(map.get("couponDeduction").toString());
         BigDecimal platformIncome = BigDecimal.ZERO;
         BigDecimal partnerIncome = BigDecimal.ZERO;
-        if (sumList != null) {
-            for (Map<String, Object> row : sumList) {
+        if (incomeRows != null) {
+            for (Map<String, Object> row : incomeRows) {
                 Integer siteId = Integer.valueOf(row.get("site_id").toString());
                 String billingCycle = row.get("billingCycle").toString();
                 Map<String, BigDecimal> incomeMap = getChargingBillIncome(incomeIndex, siteId, billingCycle);
@@ -1192,86 +1323,40 @@
         return chargingBillVO;
     }
 
-    private Map<String, Map<String, BigDecimal>> buildChargingBillIncomeIndex(List<Map<String, Object>> billRows,
-                                                                               Map<Integer, BigDecimal> siteServiceShareRatioMap) {
+    Map<String, Map<String, BigDecimal>> buildChargingBillIncomeIndex(List<Map<String, Object>> billRows,
+                                                                      Map<Integer, BigDecimal> siteServiceShareRatioMap) {
         Map<String, Map<String, BigDecimal>> incomeIndex = new HashMap<>();
         if (billRows == null || billRows.isEmpty()) {
             return incomeIndex;
         }
-        Set<String> billingCycles = billRows.stream()
-                .map(row -> row.get("billingCycle"))
-                .filter(Objects::nonNull)
-                .map(Object::toString)
-                .collect(Collectors.toSet());
-        if (billingCycles.isEmpty()) {
-            return incomeIndex;
-        }
-        LocalDate firstMonth = billingCycles.stream()
-                .map(cycle -> LocalDate.parse(cycle + "-01"))
-                .min(LocalDate::compareTo)
-                .orElse(null);
-        LocalDate lastMonth = billingCycles.stream()
-                .map(cycle -> LocalDate.parse(cycle + "-01"))
-                .max(LocalDate::compareTo)
-                .orElse(null);
-        if (firstMonth == null || lastMonth == null) {
-            return incomeIndex;
-        }
-
-        List<TChargingOrder> orders = chargingOrderList.selectList(new LambdaQueryWrapper<>(TChargingOrder.class)
-                .select(TChargingOrder::getId, TChargingOrder::getSiteId, TChargingOrder::getPayTime, TChargingOrder::getOrderSource)
-                .ge(TChargingOrder::getPayTime, firstMonth.atStartOfDay())
-                .lt(TChargingOrder::getPayTime, lastMonth.plusMonths(1).atStartOfDay()));
-        if (orders == null || orders.isEmpty()) {
-            return incomeIndex;
-        }
-
-        Map<Long, BigDecimal[]> strategyAmountMap = new HashMap<>();
-        List<Long> orderIds = orders.stream().map(TChargingOrder::getId).filter(Objects::nonNull).collect(Collectors.toList());
-        final int batchSize = 1000;
-        for (int from = 0; from < orderIds.size(); from += batchSize) {
-            List<Long> batchIds = orderIds.subList(from, Math.min(from + batchSize, orderIds.size()));
-            List<TChargingOrderAccountingStrategy> strategies = chargingOrderAccountingStrategyService.list(
-                    new LambdaQueryWrapper<TChargingOrderAccountingStrategy>()
-                            .select(TChargingOrderAccountingStrategy::getChargingOrderId,
-                                    TChargingOrderAccountingStrategy::getPeriodElectricPrice,
-                                    TChargingOrderAccountingStrategy::getPeriodServicePrice)
-                            .in(TChargingOrderAccountingStrategy::getChargingOrderId, batchIds));
-            for (TChargingOrderAccountingStrategy strategy : strategies) {
-                BigDecimal[] amounts = strategyAmountMap.computeIfAbsent(strategy.getChargingOrderId(), key -> new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO});
-                amounts[0] = amounts[0].add(strategy.getPeriodElectricPrice() == null ? BigDecimal.ZERO : strategy.getPeriodElectricPrice());
-                amounts[1] = amounts[1].add(strategy.getPeriodServicePrice() == null ? BigDecimal.ZERO : strategy.getPeriodServicePrice());
-            }
-        }
-
-        for (TChargingOrder order : orders) {
-            if (order.getPayTime() == null || order.getSiteId() == null) {
+        for (Map<String, Object> row : billRows) {
+            if (row == null || row.get("site_id") == null || row.get("billingCycle") == null) {
                 continue;
             }
-            String billingCycle = order.getPayTime().format(DateTimeFormatter.ofPattern("yyyy-MM"));
-            if (!billingCycles.contains(billingCycle)) {
-                continue;
-            }
-            BigDecimal[] amounts = strategyAmountMap.getOrDefault(order.getId(), new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO});
-            BigDecimal paymentAmount;
+            Integer siteId = Integer.valueOf(row.get("site_id").toString());
+            String billingCycle = row.get("billingCycle").toString();
+            BigDecimal electricAmount = decimalValue(row.get("total_electricity_charge"));
+            BigDecimal serviceAmount = decimalValue(row.get("total_service_fee"));
+            BigDecimal tripartiteCommission = decimalValue(row.get("tripartite_commission"));
+            BigDecimal paymentAmount = electricAmount.add(serviceAmount).subtract(tripartiteCommission);
+            BigDecimal tripartiteServiceAmount = tripartiteCommission.multiply(new BigDecimal("5"));
+            BigDecimal commissionableServiceAmount = serviceAmount.subtract(tripartiteServiceAmount).max(BigDecimal.ZERO);
             BigDecimal partnerIncome = BigDecimal.ZERO;
-            if (Integer.valueOf(2).equals(order.getOrderSource())) {
-                paymentAmount = amounts[0].add(amounts[1].multiply(new BigDecimal("0.8")).setScale(2, RoundingMode.DOWN));
-            } else {
-                paymentAmount = amounts[0].add(amounts[1]);
-                if (Integer.valueOf(1).equals(order.getOrderSource())) {
-                    BigDecimal serviceShareRatio = siteServiceShareRatioMap.get(order.getSiteId());
-                    if (serviceShareRatio != null && serviceShareRatio.compareTo(BigDecimal.ZERO) > 0) {
-                        partnerIncome = amounts[1].multiply(serviceShareRatio).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
-                    }
-                }
+            BigDecimal serviceShareRatio = siteServiceShareRatioMap.get(siteId);
+            if (serviceShareRatio != null && serviceShareRatio.compareTo(BigDecimal.ZERO) > 0) {
+                partnerIncome = commissionableServiceAmount.multiply(serviceShareRatio)
+                        .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
             }
             addChargingBillIncome(incomeIndex, chargingBillIncomeKey(0, billingCycle), paymentAmount, partnerIncome);
-            addChargingBillIncome(incomeIndex, chargingBillIncomeKey(order.getSiteId(), billingCycle), paymentAmount, partnerIncome);
+            addChargingBillIncome(incomeIndex, chargingBillIncomeKey(siteId, billingCycle), paymentAmount, partnerIncome);
         }
         return incomeIndex;
     }
 
+    private BigDecimal decimalValue(Object value) {
+        return value == null ? BigDecimal.ZERO : new BigDecimal(value.toString());
+    }
+
     private void addChargingBillIncome(Map<String, Map<String, BigDecimal>> incomeIndex, String key,
                                        BigDecimal paymentAmount, BigDecimal partnerIncome) {
         Map<String, BigDecimal> income = incomeIndex.computeIfAbsent(key, ignored -> {

--
Gitblit v1.7.1