diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/BusinessFinancialServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/BusinessFinancialServiceImpl.java index acba854a6..8cbe41293 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/BusinessFinancialServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/BusinessFinancialServiceImpl.java @@ -49,6 +49,9 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.stream.Collectors; /** @@ -71,6 +74,17 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { private static final String SCALE_METRIC_SERVICE_AMOUNT = "SERVICE_AMOUNT"; private static final String SCALE_METRIC_USE_ELECTRICITY = "USE_ELECTRICITY"; + /** + * 财务查询通用线程池(支持多方法并行查询) + * 核心线程数4:覆盖经营规模(2路)、我的钱包(3路)、经营分析(2路)、枪均效率(2路)等场景 + */ + private static final ExecutorService FINANCIAL_THREAD_POOL = Executors.newFixedThreadPool( + 4, r -> { + Thread t = new Thread(r, "business-financial-query"); + t.setDaemon(true); + return t; + }); + @Autowired private SettleOrderReportService settleOrderReportService; @@ -91,47 +105,58 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { /** * 我的钱包查询 + * 优化:订单报表DB、汇付余额HTTP、提现金额DB 三个独立数据源并行查询 * @param dto * @return */ @Override public MerchantOrderReportVO getMyWallet(MerchantOrderReportDTO dto) { - // 查询运营商订单报表 - MerchantOrderReportVO result = settleOrderReportService.getMerchantOrderReportV2(dto); + String merchantId = dto.getMerchantId(); - // 查询账户余额 - AdapayAccountBalanceVO accountBalanceVO = new AdapayAccountBalanceVO(); + // 并行查询三个独立数据源 + CompletableFuture reportFuture = CompletableFuture.supplyAsync( + () -> settleOrderReportService.getMerchantOrderReportV2(dto), FINANCIAL_THREAD_POOL); + CompletableFuture balanceFuture = CompletableFuture.supplyAsync(() -> { + try { + return adapayService.queryAdapayAccountBalance(merchantId); + } catch (BaseAdaPayException e) { + log.error("查询汇付账户余额异常 merchantId:{}", merchantId, e); + return null; + } + }, FINANCIAL_THREAD_POOL); + CompletableFuture withdrawFuture = CompletableFuture.supplyAsync(() -> { + try { + BigDecimal withdraw = clearingWithdrawInfoService.queryTotalWithdraw(merchantId); + return withdraw != null ? withdraw : BigDecimal.ZERO; + } catch (Exception e) { + log.error("查询累计提现金额异常 merchantId:{}", merchantId, e); + return BigDecimal.ZERO; + } + }, FINANCIAL_THREAD_POOL); + + // 等待所有查询完成 + MerchantOrderReportVO result = reportFuture.join(); + AdapayAccountBalanceVO accountBalanceVO = balanceFuture.join(); + BigDecimal totalWithdraw = withdrawFuture.join(); + + // 设置账户余额 BigDecimal acctBalance = BigDecimal.ZERO; BigDecimal pendingAmount = BigDecimal.ZERO; - try { - accountBalanceVO = adapayService.queryAdapayAccountBalance(dto.getMerchantId()); - if (accountBalanceVO == null) { - log.error("我的钱包查询异常 查询出accountBalanceVO 为null"); - return result; - } + BigDecimal canWithdrawAmount = null; + if (accountBalanceVO != null) { if (accountBalanceVO.getAcctBalance() != null) { acctBalance = accountBalanceVO.getAcctBalance(); } if (accountBalanceVO.getPendingAmount() != null) { pendingAmount = accountBalanceVO.getPendingAmount(); } - } catch (BaseAdaPayException e) { - log.error("查询汇付账户余额异常 merchantId:{}", dto.getMerchantId(), e); + canWithdrawAmount = accountBalanceVO.getLastAvlBalance(); + } else { + log.error("我的钱包查询异常 查询出accountBalanceVO 为null"); } result.getMerchantOrderReport().setAcctBalance(acctBalance); result.getMerchantOrderReport().setPendingAmount(pendingAmount); - result.getMerchantOrderReport().setCanWithdrawAmount(accountBalanceVO.getLastAvlBalance()); - - // 查询累计提现金额 - BigDecimal totalWithdraw = BigDecimal.ZERO; - try { - BigDecimal withdraw = clearingWithdrawInfoService.queryTotalWithdraw(dto.getMerchantId()); - if (withdraw != null) { - totalWithdraw = withdraw; - } - } catch (Exception e) { - log.error("查询累计提现金额异常 merchantId:{}", dto.getMerchantId(), e); - } + result.getMerchantOrderReport().setCanWithdrawAmount(canWithdrawAmount); result.getMerchantOrderReport().setTotalWithdraw(totalWithdraw); return result; @@ -194,6 +219,7 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { /** * 查询经营分析 + * 优化:当前周期和上周期汇总并行查询 * * @param dto 查询条件 * @return 经营分析 @@ -212,10 +238,17 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { BusinessOperationDateRangeDTO range = buildDateRange(dto); List stationIdList = resolveStationIds(dto.getStationIdList()); - BusinessOperationSummaryDTO currentSummary = buildOperationSummary( - stationIdList, range.getCurrentStart(), range.getCurrentEnd()); - BusinessOperationSummaryDTO previousSummary = buildOperationSummary( - stationIdList, range.getPreviousStart(), range.getPreviousEnd()); + + // 并行查询当前周期和上周期原始数据 + CompletableFuture> currentReportFuture = CompletableFuture.supplyAsync( + () -> queryRawReports(stationIdList, range.getCurrentStart(), range.getCurrentEnd()), + FINANCIAL_THREAD_POOL); + CompletableFuture> previousReportFuture = CompletableFuture.supplyAsync( + () -> queryRawReports(stationIdList, range.getPreviousStart(), range.getPreviousEnd()), + FINANCIAL_THREAD_POOL); + + BusinessOperationSummaryDTO currentSummary = buildSummaryFromReports(currentReportFuture.join()); + BusinessOperationSummaryDTO previousSummary = buildSummaryFromReports(previousReportFuture.join()); List metricList = new ArrayList<>(); metricList.add(buildMetric(METRIC_ORDER_AMOUNT, "订单总额", @@ -239,6 +272,7 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { /** * 查询枪均效率分析 + * 优化:订单汇总DB查询与枪口数量DB查询并行执行 * * @param dto 查询条件 * @return 枪均效率分析 @@ -257,12 +291,21 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { BusinessOperationDateRangeDTO range = buildDateRange(dto); List stationIdList = resolveStationIds(dto.getStationIdList()); - BusinessOperationSummaryDTO summary = buildOperationSummary( - stationIdList, range.getCurrentStart(), range.getCurrentEnd()); - BigDecimal connectorCount = BigDecimal.valueOf(countConnectors(stationIdList)); + // 并行查询订单汇总和枪口数量 + CompletableFuture summaryFuture = CompletableFuture.supplyAsync( + () -> buildSummaryFromReports( + queryRawReports(stationIdList, range.getCurrentStart(), range.getCurrentEnd())), + FINANCIAL_THREAD_POOL); + CompletableFuture connectorCountFuture = CompletableFuture.supplyAsync( + () -> countConnectors(stationIdList), FINANCIAL_THREAD_POOL); + + BusinessOperationSummaryDTO summary = summaryFuture.join(); + int connectorCount = connectorCountFuture.join(); + + BigDecimal connectorCountBd = BigDecimal.valueOf(connectorCount); BigDecimal dayCount = BigDecimal.valueOf(calculateInclusiveDays(range.getCurrentStart(), range.getCurrentEnd())); - BigDecimal connectorDayCount = connectorCount.multiply(dayCount); + BigDecimal connectorDayCount = connectorCountBd.multiply(dayCount); BigDecimal gunAvgDailyServiceFee = BigDecimalUtils.safeDivide(summary.getServiceAmount(), connectorDayCount, 2); BigDecimal gunAvgDailyElectricity = BigDecimalUtils.safeDivide(summary.getUseElectricity(), connectorDayCount, 4); @@ -436,39 +479,6 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { return null; } - /** - * 汇总指定周期内的经营指标 - * - * @param stationIdList 站点ID列表 - * @param startTime 开始时间 - * @param endTime 结束时间 - * @return 汇总结果 - */ - private BusinessOperationSummaryDTO buildOperationSummary(List stationIdList, - String startTime, - String endTime) { - if (stationIdList != null && stationIdList.isEmpty()) { - return new BusinessOperationSummaryDTO(); - } - List reportList = settleOrderReportService.queryOrderReport( - stationIdList, startTime, endTime); - if (CollectionUtils.isEmpty(reportList)) { - return new BusinessOperationSummaryDTO(); - } - BusinessOperationSummaryDTO summary = new BusinessOperationSummaryDTO(); - for (SettleOrderReport report : reportList) { - summary.setOrderAmount(summary.getOrderAmount().add(BigDecimalUtils.nullToZero(report.getTotalAmount()))); - summary.setServiceAmount(summary.getServiceAmount().add(BigDecimalUtils.nullToZero(report.getServiceAmount()))); - summary.setUseElectricity(summary.getUseElectricity().add(BigDecimalUtils.nullToZero(report.getUseElectricity()))); - summary.setOrderCount(summary.getOrderCount().add(BigDecimalUtils.parseOrZero(report.getChargeNum()))); - summary.setChargeTime(summary.getChargeTime().add(BigDecimalUtils.parseOrZero(report.getChargeTime()))); - } - summary.setAvgServiceFee(BigDecimalUtils.safeDivide(summary.getServiceAmount(), summary.getOrderCount(), 2)); - summary.setAvgElectricity(BigDecimalUtils.safeDivide(summary.getUseElectricity(), summary.getOrderCount(), 2)); - summary.setAvgChargeTime(BigDecimalUtils.safeDivide(summary.getChargeTime(), summary.getOrderCount(), 2)); - return summary; - } - /** * 统计站点范围内的枪口数量 * @@ -534,12 +544,24 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { BusinessOperationDateRangeDTO range = buildDateRangeFromScale(dto); List stationIdList = resolveStationIds(dto.getStationIdList()); - // 当前周期汇总 - BusinessOperationSummaryDTO currentSummary = buildOperationSummary( - stationIdList, range.getCurrentStart(), range.getCurrentEnd()); - // 上周期汇总 - BusinessOperationSummaryDTO previousSummary = buildOperationSummary( - stationIdList, range.getPreviousStart(), range.getPreviousEnd()); + // 并行查询当前周期和上周期的原始报表数据,各只查一次 + CompletableFuture> currentReportFuture = CompletableFuture.supplyAsync( + () -> queryRawReports(stationIdList, range.getCurrentStart(), range.getCurrentEnd()), + FINANCIAL_THREAD_POOL); + CompletableFuture> previousReportFuture = CompletableFuture.supplyAsync( + () -> queryRawReports(stationIdList, range.getPreviousStart(), range.getPreviousEnd()), + FINANCIAL_THREAD_POOL); + + // 等待两个查询完成 + List currentReports = currentReportFuture.join(); + List previousReports = previousReportFuture.join(); + + // 从同一份原始数据分别构建汇总指标和每日明细 + BusinessOperationSummaryDTO currentSummary = buildSummaryFromReports(currentReports); + BusinessOperationSummaryDTO previousSummary = buildSummaryFromReports(previousReports); + + Map currentDailyMap = buildDailyMapFromReports(currentReports); + Map previousDailyMap = buildDailyMapFromReports(previousReports); // 构建指标卡片 List metricList = new ArrayList<>(); @@ -552,11 +574,11 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { metricList.add(buildScaleMetric(SCALE_METRIC_USE_ELECTRICITY, "充电电量", "度", currentSummary.getUseElectricity(), previousSummary.getUseElectricity())); - // 构建选中指标的曲线图数据 + // 构建选中指标的曲线图数据(复用已查询的dailyMap) String selectedMetricCode = StringUtils.isBlank(dto.getSelectedMetricCode()) ? SCALE_METRIC_USE_ELECTRICITY : dto.getSelectedMetricCode(); - BusinessScaleChartVO chartData = buildScaleChart( - selectedMetricCode, stationIdList, range); + BusinessScaleChartVO chartData = buildScaleChartFromMaps( + selectedMetricCode, range, currentDailyMap, previousDailyMap); return BusinessScaleVO.builder() .currentStartTime(range.getCurrentStart()) @@ -614,10 +636,77 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { } /** - * 构建经营规模曲线图数据 + * 查询原始报表数据(供并行调用) */ - private BusinessScaleChartVO buildScaleChart(String metricCode, List stationIdList, - BusinessOperationDateRangeDTO range) { + private List queryRawReports(List stationIdList, + String startTime, String endTime) { + if (stationIdList != null && stationIdList.isEmpty()) { + return new ArrayList<>(); + } + List reportList = settleOrderReportService.queryOrderReport( + stationIdList, startTime, endTime); + return CollectionUtils.isEmpty(reportList) ? new ArrayList<>() : reportList; + } + + /** + * 从原始报表数据构建汇总指标 + */ + private BusinessOperationSummaryDTO buildSummaryFromReports(List reportList) { + BusinessOperationSummaryDTO summary = new BusinessOperationSummaryDTO(); + if (CollectionUtils.isEmpty(reportList)) { + return summary; + } + for (SettleOrderReport report : reportList) { + summary.setOrderAmount(summary.getOrderAmount().add(BigDecimalUtils.nullToZero(report.getTotalAmount()))); + summary.setServiceAmount(summary.getServiceAmount().add(BigDecimalUtils.nullToZero(report.getServiceAmount()))); + summary.setUseElectricity(summary.getUseElectricity().add(BigDecimalUtils.nullToZero(report.getUseElectricity()))); + summary.setOrderCount(summary.getOrderCount().add(BigDecimalUtils.parseOrZero(report.getChargeNum()))); + summary.setChargeTime(summary.getChargeTime().add(BigDecimalUtils.parseOrZero(report.getChargeTime()))); + } + summary.setAvgServiceFee(BigDecimalUtils.safeDivide(summary.getServiceAmount(), summary.getOrderCount(), 2)); + summary.setAvgElectricity(BigDecimalUtils.safeDivide(summary.getUseElectricity(), summary.getOrderCount(), 2)); + summary.setAvgChargeTime(BigDecimalUtils.safeDivide(summary.getChargeTime(), summary.getOrderCount(), 2)); + return summary; + } + + /** + * 从原始报表数据构建按日期分组的Map + */ + private Map buildDailyMapFromReports(List reportList) { + Map dailyMap = new LinkedHashMap<>(); + if (CollectionUtils.isEmpty(reportList)) { + return dailyMap; + } + for (SettleOrderReport report : reportList) { + String tradeDate = report.getTradeDate(); + if (StringUtils.isBlank(tradeDate)) { + continue; + } + SettleOrderReport existing = dailyMap.get(tradeDate); + if (existing == null) { + dailyMap.put(tradeDate, report); + } else { + existing.setTotalAmount(existing.getTotalAmount().add( + BigDecimalUtils.nullToZero(report.getTotalAmount()))); + existing.setServiceAmount(existing.getServiceAmount().add( + BigDecimalUtils.nullToZero(report.getServiceAmount()))); + existing.setUseElectricity(existing.getUseElectricity().add( + BigDecimalUtils.nullToZero(report.getUseElectricity()))); + existing.setChargeNum(String.valueOf( + BigDecimalUtils.parseOrZero(existing.getChargeNum()) + .add(BigDecimalUtils.parseOrZero(report.getChargeNum())))); + } + } + return dailyMap; + } + + /** + * 从已有的dailyMap构建曲线图数据(不再重复查DB) + */ + private BusinessScaleChartVO buildScaleChartFromMaps(String metricCode, + BusinessOperationDateRangeDTO range, + Map currentDailyMap, + Map previousDailyMap) { String metricName; String unit; switch (metricCode) { @@ -639,13 +728,6 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { break; } - // 查询当前周期每日数据 - Map currentDailyMap = queryDailyReportMap( - stationIdList, range.getCurrentStart(), range.getCurrentEnd()); - // 查询上周期每日数据 - Map previousDailyMap = queryDailyReportMap( - stationIdList, range.getPreviousStart(), range.getPreviousEnd()); - LocalDate currentStart = LocalDate.parse(range.getCurrentStart()); LocalDate currentEnd = LocalDate.parse(range.getCurrentEnd()); LocalDate previousStart = LocalDate.parse(range.getPreviousStart()); @@ -684,44 +766,6 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { .build(); } - /** - * 查询每日报表数据,按日期分组返回Map - */ - private Map queryDailyReportMap(List stationIdList, - String startTime, String endTime) { - if (stationIdList != null && stationIdList.isEmpty()) { - return new LinkedHashMap<>(); - } - List reportList = settleOrderReportService.queryOrderReport( - stationIdList, startTime, endTime); - // 按tradeDate分组汇总 - Map dailyMap = new LinkedHashMap<>(); - if (!CollectionUtils.isEmpty(reportList)) { - for (SettleOrderReport report : reportList) { - String tradeDate = report.getTradeDate(); - if (StringUtils.isBlank(tradeDate)) { - continue; - } - SettleOrderReport existing = dailyMap.get(tradeDate); - if (existing == null) { - dailyMap.put(tradeDate, report); - } else { - // 合并同一天多个站点的数据 - existing.setTotalAmount(existing.getTotalAmount().add( - BigDecimalUtils.nullToZero(report.getTotalAmount()))); - existing.setServiceAmount(existing.getServiceAmount().add( - BigDecimalUtils.nullToZero(report.getServiceAmount()))); - existing.setUseElectricity(existing.getUseElectricity().add( - BigDecimalUtils.nullToZero(report.getUseElectricity()))); - existing.setChargeNum(String.valueOf( - BigDecimalUtils.parseOrZero(existing.getChargeNum()) - .add(BigDecimalUtils.parseOrZero(report.getChargeNum())))); - } - } - } - return dailyMap; - } - /** * 从报表记录中提取指定指标的值 */