longz
2026-07-20 1494c13bfe2b16e34e503cf2527c38e2c2091fc4
fix: 优化财务结算查询
4个文件已修改
225 ■■■■■ 已修改文件
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingSettlementBillMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java
@@ -42,6 +42,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -100,14 +101,6 @@
            startTime2 = split[1];
        }
        List<Site> siteList = siteClient.getSiteAll().getData();
        List<TChargingGun> gunList = chargingGunClient.getAllGun().getData();
        List<TChargingPile> pileList = chargingGunClient.getAllPile().getData();
        List<TAppUser> userList = appUserClient.getAllUser().getData();
        List<TAppUserCar> carList = appUserCarClient.getAllCar().getData();
        List<TChargingOrder> total = chargingOrderList.selectList(new LambdaQueryWrapper<>(TChargingOrder.class)
                .isNotNull(TChargingOrder::getPayTime));
        List<TChargingOrderRefund> totalRefund = chargingOrderRefundService.lambdaQuery().eq(TChargingOrderRefund::getRefundStatus, 2).list();
        Long userId = tokenService.getLoginUser().getUserid();
        // 查询当前登陆人按钮权限
        SysUser sysUser = sysUserClient.getSysUser(tokenService.getLoginUser().getUserid()).getData();
@@ -152,6 +145,47 @@
        List<ChargingBillListVO> list = this.baseMapper.chargingBillList1(pageInfo,dto,startTime1,startTime2);
        List<ChargingBillListVO> list1 = this.baseMapper.chargingBillList1Nolimt(dto,startTime1,startTime2);
        List<ChargingBillListVO> billScope = list1.isEmpty() ? list : list1;
        LocalDateTime scopeStart = billScope.stream()
                .map(ChargingBillListVO::getBillTime)
                .filter(Objects::nonNull)
                .map(time -> time.minusMonths(1).with(TemporalAdjusters.firstDayOfMonth()).toLocalDate().atStartOfDay())
                .min(LocalDateTime::compareTo)
                .orElse(null);
        LocalDateTime scopeEnd = billScope.stream()
                .map(ChargingBillListVO::getBillTime)
                .filter(Objects::nonNull)
                .map(time -> time.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth()).withHour(23).withMinute(59).withSecond(59))
                .max(LocalDateTime::compareTo)
                .orElse(null);
        Set<Integer> scopedSiteIds = billScope.stream()
                .filter(item -> Integer.valueOf(2).equals(item.getType()))
                .map(ChargingBillListVO::getSiteId)
                .filter(id -> id != null && id > 0)
                .collect(Collectors.toSet());
        boolean onlySiteBills = !billScope.isEmpty() && billScope.stream().allMatch(item -> Integer.valueOf(2).equals(item.getType()));
        LambdaQueryWrapper<TChargingOrder> orderQuery = new LambdaQueryWrapper<TChargingOrder>()
                .isNotNull(TChargingOrder::getPayTime)
                .between(scopeStart != null && scopeEnd != null, TChargingOrder::getPayTime, scopeStart, scopeEnd)
                .in(onlySiteBills && !scopedSiteIds.isEmpty(), TChargingOrder::getSiteId, scopedSiteIds);
        List<TChargingOrder> total = billScope.isEmpty() ? Collections.emptyList() : chargingOrderList.selectList(orderQuery);
        List<Long> orderIds = total.stream().map(TChargingOrder::getId).filter(Objects::nonNull).collect(Collectors.toList());
        List<TChargingOrderRefund> totalRefund = orderIds.isEmpty() ? Collections.emptyList()
                : chargingOrderRefundService.lambdaQuery()
                .eq(TChargingOrderRefund::getRefundStatus, 2)
                .in(TChargingOrderRefund::getChargingOrderId, orderIds)
                .list();
        Set<Integer> lookupSiteIds = total.stream().map(TChargingOrder::getSiteId).filter(Objects::nonNull).filter(id -> id > 0).collect(Collectors.toSet());
        lookupSiteIds.addAll(scopedSiteIds);
        List<Site> siteList = lookupSiteIds.isEmpty() ? Collections.emptyList() : safeData(siteClient.getSiteByIds(new ArrayList<>(lookupSiteIds)));
        List<TChargingPile> pileList = lookupSiteIds.isEmpty() ? Collections.emptyList() : safeData(chargingPileClient.getChargingPileBySiteIds(new ArrayList<>(lookupSiteIds)));
        List<Integer> gunIds = total.stream().map(TChargingOrder::getChargingGunId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<TChargingGun> gunList = gunIds.isEmpty() ? Collections.emptyList() : safeData(chargingGunClient.getChargingGunByIds(gunIds));
        List<Long> userIds = total.stream().map(TChargingOrder::getAppUserId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<TAppUser> userList = userIds.isEmpty() ? Collections.emptyList() : safeData(appUserClient.getUserByIds(userIds));
        List<Long> carIds = total.stream().map(TChargingOrder::getAppUserCarId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<TAppUserCar> carList = carIds.isEmpty() ? Collections.emptyList() : safeData(appUserCarClient.getCarByIds(carIds));
        BigDecimal paymentAmountTotal = new BigDecimal("0");
        BigDecimal orderAmountTotal = new BigDecimal("0");
        BigDecimal refundAmountTotal = new BigDecimal("0");
@@ -163,7 +197,10 @@
        BigDecimal partnerIncomeTotal = new BigDecimal("0");
        BigDecimal chargingCapacityTotal = new BigDecimal("0");
        BigDecimal discountTotal = new BigDecimal("0");
        List<TChargingOrderAccountingStrategy> list3 = chargingOrderAccountingStrategyService.list();
        List<TChargingOrderAccountingStrategy> list3 = orderIds.isEmpty() ? Collections.emptyList()
                : chargingOrderAccountingStrategyService.lambdaQuery()
                .in(TChargingOrderAccountingStrategy::getChargingOrderId, orderIds)
                .list();
        Map<Integer, BigDecimal> siteServiceShareRatioMap = loadSiteServiceShareRatioMap();
@@ -1064,13 +1101,22 @@
        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);
        Set<Integer> settlementSiteIds = new HashSet<>();
        if (list != null) {
            list.stream().map(item -> item.get("site_id")).filter(Objects::nonNull)
                    .map(value -> Integer.valueOf(value.toString())).filter(id -> id > 0).forEach(settlementSiteIds::add);
        }
        Map<Integer, String> settlementSiteNameMap = settlementSiteIds.isEmpty() ? Collections.emptyMap()
                : safeData(siteClient.getSiteByIds(new ArrayList<>(settlementSiteIds))).stream()
                .filter(Objects::nonNull).filter(site -> site.getId() != null)
                .collect(Collectors.toMap(Site::getId, Site::getName, (left, right) -> left));
        if(null != list){
            for (Map<String, Object> map : list) {
                Integer site_id = Integer.valueOf(map.get("site_id").toString());
                String code = map.get("code").toString();
                String billingCycle = map.get("billingCycle").toString();
                String createTime = map.get("createTime").toString();
                String siteName = 1 == dto.getType() ? "全站" : map.get("siteName").toString();
                String siteName = 1 == dto.getType() ? "全站" : settlementSiteNameMap.getOrDefault(site_id, "");
                Long charging_duration = Long.valueOf(map.get("charging_duration").toString());
                Integer order_number = Integer.valueOf(map.get("order_number").toString());
                String orderAmount = map.get("total_amount").toString();
@@ -1788,6 +1834,10 @@
                .collect(Collectors.toList());
    }
    private <T> List<T> safeData(R<List<T>> result) {
        return result == null || result.getData() == null ? Collections.emptyList() : result.getData();
    }
    private boolean accountSettlementOrderMatches(TChargingOrder order, Integer payType) {
        if (order == null || payType == null) {
            return true;
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -3343,6 +3343,11 @@
        List<ChargingOrderListVO> list = new ArrayList<>();
        Map<Integer, BigDecimal> siteServiceShareRatioMap = loadSiteServiceShareRatioMap();
        List<Map<String, Object>> maps = this.baseMapper.chargingList1(pageInfo, dto, startTime1, startTime2, endTime1, endTime2);
        Map<Integer, Site> siteMap = loadChargingPeriodSites(maps);
        Map<Integer, TChargingPile> pileMap = loadChargingPeriodPiles(maps);
        Map<Integer, TChargingGun> gunMap = loadChargingPeriodGuns(maps);
        Map<Long, TAppUser> userMap = loadChargingPeriodUsers(maps);
        Map<Long, TAppUserCar> carMap = loadChargingPeriodCars(maps);
        for (Map<String, Object> map : maps) {
            if(null == map){
                continue;
@@ -3358,9 +3363,16 @@
            chargingOrderListVO.setId(Long.valueOf(map.get("id").toString()));
            chargingOrderListVO.setSiteId(Integer.valueOf(map.get("siteId").toString()));
            chargingOrderListVO.setOrderSource(Integer.valueOf(map.get("orderSource").toString()));
            chargingOrderListVO.setSiteName(map.get("siteName").toString());
            Site site = siteMap.get(chargingOrderListVO.getSiteId());
            chargingOrderListVO.setSiteName(site == null ? "" : site.getName());
            chargingOrderListVO.setOrderType(map.get("orderType").toString());
            chargingOrderListVO.setTerminalName(map.get("terminalName").toString());
            Integer pileId = getNullableInteger(map, "chargingPileId");
            Integer gunId = getNullableInteger(map, "chargingGunId");
            TChargingPile pile = pileMap.get(pileId);
            TChargingGun gun = gunMap.get(gunId);
            String pileName = pile == null || pile.getName() == null ? "" : pile.getName();
            String gunName = gun == null || gun.getName() == null ? "" : gun.getName();
            chargingOrderListVO.setTerminalName(pileName.isEmpty() ? gunName : (gunName.isEmpty() ? pileName : pileName + "-" + gunName));
            chargingOrderListVO.setElectricity(null == map.get("electricity") ? BigDecimal.ZERO : new BigDecimal(map.get("electricity").toString()));
            chargingOrderListVO.setChargingCapacity(chargingOrderListVO.getElectricity());
            BigDecimal periodElectricPrice = getSummaryDecimal(map, "periodElectricPrice");
@@ -3411,12 +3423,10 @@
            if(null != map.get("endMode")){
                chargingOrderListVO.setEndMode(Integer.valueOf(map.get("endMode").toString()));
            }
            if(null != map.get("phone")){
                chargingOrderListVO.setPhone(map.get("phone").toString());
            }
            if(null != map.get("licensePlate")){
                chargingOrderListVO.setLicensePlate(map.get("licensePlate").toString());
            }
            TAppUser appUser = userMap.get(getNullableLong(map, "appUserId"));
            if (appUser != null) chargingOrderListVO.setPhone(appUser.getPhone());
            TAppUserCar appUserCar = carMap.get(getNullableLong(map, "appUserCarId"));
            if (appUserCar != null) chargingOrderListVO.setLicensePlate(appUserCar.getLicensePlate());
            chargingOrderListVO.setIsWhitelist(null == map.get("isWhitelist") ? 0 : Integer.valueOf(map.get("isWhitelist").toString()));
            // 白名单退款金额由电费退款和服务费退款组成,列表展示总额,财务导出继续保留拆分字段。
            chargingOrderListVO.setWhitelistElectricRefundAmount(getSummaryDecimal(map, "whitelistElectricRefundAmount"));
@@ -3560,6 +3570,73 @@
        return chargingOrderTimeVO;
    }
    private Map<Integer, Site> loadChargingPeriodSites(List<Map<String, Object>> rows) {
        List<Integer> ids = collectIntegerIds(rows, "siteId");
        if (ids.isEmpty()) return Collections.emptyMap();
        R<List<Site>> result = siteClient.getSiteByIds(ids);
        return indexByIntegerId(result == null ? null : result.getData(), Site::getId);
    }
    private Map<Integer, TChargingPile> loadChargingPeriodPiles(List<Map<String, Object>> rows) {
        List<Integer> siteIds = collectIntegerIds(rows, "siteId");
        if (siteIds.isEmpty()) return Collections.emptyMap();
        R<List<TChargingPile>> result = chargingPileClient.getChargingPileBySiteIds(siteIds);
        return indexByIntegerId(result == null ? null : result.getData(), TChargingPile::getId);
    }
    private Map<Integer, TChargingGun> loadChargingPeriodGuns(List<Map<String, Object>> rows) {
        List<Integer> ids = collectIntegerIds(rows, "chargingGunId");
        if (ids.isEmpty()) return Collections.emptyMap();
        R<List<TChargingGun>> result = chargingGunClient.getChargingGunByIds(ids);
        return indexByIntegerId(result == null ? null : result.getData(), TChargingGun::getId);
    }
    private Map<Long, TAppUser> loadChargingPeriodUsers(List<Map<String, Object>> rows) {
        List<Long> ids = collectLongIds(rows, "appUserId");
        if (ids.isEmpty()) return Collections.emptyMap();
        R<List<TAppUser>> result = appUserClient.getUserByIds(ids);
        return indexByLongId(result == null ? null : result.getData(), TAppUser::getId);
    }
    private Map<Long, TAppUserCar> loadChargingPeriodCars(List<Map<String, Object>> rows) {
        List<Long> ids = collectLongIds(rows, "appUserCarId");
        if (ids.isEmpty()) return Collections.emptyMap();
        R<List<TAppUserCar>> result = appUserCarClient.getCarByIds(ids);
        return indexByLongId(result == null ? null : result.getData(), TAppUserCar::getId);
    }
    private List<Integer> collectIntegerIds(List<Map<String, Object>> rows, String key) {
        if (rows == null) return Collections.emptyList();
        return rows.stream().map(row -> getNullableInteger(row, key)).filter(Objects::nonNull).distinct().collect(Collectors.toList());
    }
    private List<Long> collectLongIds(List<Map<String, Object>> rows, String key) {
        if (rows == null) return Collections.emptyList();
        return rows.stream().map(row -> getNullableLong(row, key)).filter(Objects::nonNull).distinct().collect(Collectors.toList());
    }
    private Integer getNullableInteger(Map<String, Object> row, String key) {
        Object value = row == null ? null : row.get(key);
        return value == null ? null : Integer.valueOf(value.toString());
    }
    private Long getNullableLong(Map<String, Object> row, String key) {
        Object value = row == null ? null : row.get(key);
        return value == null ? null : Long.valueOf(value.toString());
    }
    private <T> Map<Integer, T> indexByIntegerId(List<T> items, java.util.function.Function<T, Integer> idGetter) {
        if (items == null) return Collections.emptyMap();
        return items.stream().filter(Objects::nonNull).filter(item -> idGetter.apply(item) != null)
                .collect(Collectors.toMap(idGetter, item -> item, (left, right) -> left));
    }
    private <T> Map<Long, T> indexByLongId(List<T> items, java.util.function.Function<T, Long> idGetter) {
        if (items == null) return Collections.emptyMap();
        return items.stream().filter(Objects::nonNull).filter(item -> idGetter.apply(item) != null)
                .collect(Collectors.toMap(idGetter, item -> item, (left, right) -> left));
    }
    @Override
    public List<ChargingOrderListVO> export(ChargingListQuery dto) {
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
@@ -1212,9 +1212,11 @@
        b.id,
        b.`code`,
        b.site_id as siteId,
        c.`name` as siteName,
        b.charging_pile_id as chargingPileId,
        b.charging_gun_id as chargingGunId,
        b.app_user_id as appUserId,
        b.app_user_car_id as appUserCarId,
        b.order_type as orderType,
        CONCAT(d.`name`, '-', e.`name`) as terminalName,
        b.electricity,
        b.recharge_amount as rechargeAmount,
        b.recharge_payment_type as rechargePaymentType,
@@ -1237,32 +1239,25 @@
        b.end_soc as endSoc,
        b.`status`,
        b.end_mode as endMode,
        f.phone,
        g.license_plate as licensePlate,
        (select SUM(a.period_electric_price)
         from `charging_pile_order`.t_charging_order_accounting_strategy a
         where a.charging_order_id = b.id) as periodElectricPrice,
        (select SUM(a.period_service_price)
         from `charging_pile_order`.t_charging_order_accounting_strategy a
         where a.charging_order_id = b.id) as periodServicePrice,
        (select SUM(CASE WHEN a.type = 1 THEN a.charging_capacity ELSE 0 END)
         from `charging_pile_order`.t_charging_order_accounting_strategy a
         where a.charging_order_id = b.id) as jian,
        (select SUM(CASE WHEN a.type = 2 THEN a.charging_capacity ELSE 0 END)
         from `charging_pile_order`.t_charging_order_accounting_strategy a
         where a.charging_order_id = b.id) as feng,
        (select SUM(CASE WHEN a.type = 3 THEN a.charging_capacity ELSE 0 END)
         from `charging_pile_order`.t_charging_order_accounting_strategy a
         where a.charging_order_id = b.id) as ping,
        (select SUM(CASE WHEN a.type = 4 THEN a.charging_capacity ELSE 0 END)
         from `charging_pile_order`.t_charging_order_accounting_strategy a
         where a.charging_order_id = b.id) as gu
        from `charging_pile_order`.t_charging_order b
        left join `charging_pile_service`.t_site c on (b.site_id = c.id)
        left join `charging_pile_service`.t_charging_pile d on (b.charging_pile_id = d.id)
        left join `charging_pile_service`.t_charging_gun e on (b.charging_gun_id = e.id)
        left join `charging_pile_account`.t_app_user f on (b.app_user_id = f.id)
        left join `charging_pile_account`.t_app_user_car g on (b.app_user_car_id = g.id)
        a.periodElectricPrice,
        a.periodServicePrice,
        a.jian,
        a.feng,
        a.ping,
        a.gu
        from t_charging_order b
        inner join (
            select
            charging_order_id,
            sum(period_electric_price) as periodElectricPrice,
            sum(period_service_price) as periodServicePrice,
            sum(CASE WHEN type = 1 THEN charging_capacity ELSE 0 END) as jian,
            sum(CASE WHEN type = 2 THEN charging_capacity ELSE 0 END) as feng,
            sum(CASE WHEN type = 3 THEN charging_capacity ELSE 0 END) as ping,
            sum(CASE WHEN type = 4 THEN charging_capacity ELSE 0 END) as gu
            from t_charging_order_accounting_strategy
            group by charging_order_id
        ) a on a.charging_order_id = b.id
        where b.del_flag = 0 and b.recharge_payment_status = 2
        <if test="null != req.code and req.code!=''">
            and b.code LIKE CONCAT('%',#{req.code},'%')
@@ -1304,11 +1299,6 @@
            and b.end_time between #{endTime1} and #{endTime2}
        </if>
        and b.start_time IS NOT NULL and b.end_time is not null
        and exists (
            select 1
            from `charging_pile_order`.t_charging_order_accounting_strategy a
            where a.charging_order_id = b.id
        )
        order by b.start_time desc
    </select>
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingSettlementBillMapper.xml
@@ -5,11 +5,9 @@
    <select id="queryList" resultType="map">
        select
        a.*,
        b.`name` as siteName,
        DATE_FORMAT(a.billing_cycle, '%Y-%m') as billingCycle,
        DATE_FORMAT(a.create_time, '%Y-%m-%d %H:%i:%s') as createTime
        from `charging_pile_order`.t_charging_settlement_bill a
        left join `charging_pile_service`.t_site b on (a.site_id = b.id)
        from t_charging_settlement_bill a
        <where>
            <if test="null != type and 1 == type">
                and a.site_id = 0
@@ -79,4 +77,4 @@
            </if>
        </where>
    </select>
</mapper>
</mapper>