update 运营端小程序优化接口查询速度

This commit is contained in:
Lemon
2026-04-10 14:38:27 +08:00
parent 0eb86c999d
commit 216613b67c

View File

@@ -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<MerchantOrderReportVO> reportFuture = CompletableFuture.supplyAsync(
() -> settleOrderReportService.getMerchantOrderReportV2(dto), FINANCIAL_THREAD_POOL);
CompletableFuture<AdapayAccountBalanceVO> balanceFuture = CompletableFuture.supplyAsync(() -> {
try {
return adapayService.queryAdapayAccountBalance(merchantId);
} catch (BaseAdaPayException e) {
log.error("查询汇付账户余额异常 merchantId:{}", merchantId, e);
return null;
}
}, FINANCIAL_THREAD_POOL);
CompletableFuture<BigDecimal> 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<String> stationIdList = resolveStationIds(dto.getStationIdList());
BusinessOperationSummaryDTO currentSummary = buildOperationSummary(
stationIdList, range.getCurrentStart(), range.getCurrentEnd());
BusinessOperationSummaryDTO previousSummary = buildOperationSummary(
stationIdList, range.getPreviousStart(), range.getPreviousEnd());
// 并行查询当前周期和上周期原始数据
CompletableFuture<List<SettleOrderReport>> currentReportFuture = CompletableFuture.supplyAsync(
() -> queryRawReports(stationIdList, range.getCurrentStart(), range.getCurrentEnd()),
FINANCIAL_THREAD_POOL);
CompletableFuture<List<SettleOrderReport>> previousReportFuture = CompletableFuture.supplyAsync(
() -> queryRawReports(stationIdList, range.getPreviousStart(), range.getPreviousEnd()),
FINANCIAL_THREAD_POOL);
BusinessOperationSummaryDTO currentSummary = buildSummaryFromReports(currentReportFuture.join());
BusinessOperationSummaryDTO previousSummary = buildSummaryFromReports(previousReportFuture.join());
List<BusinessOperationMetricVO> 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<String> stationIdList = resolveStationIds(dto.getStationIdList());
BusinessOperationSummaryDTO summary = buildOperationSummary(
stationIdList, range.getCurrentStart(), range.getCurrentEnd());
BigDecimal connectorCount = BigDecimal.valueOf(countConnectors(stationIdList));
// 并行查询订单汇总和枪口数量
CompletableFuture<BusinessOperationSummaryDTO> summaryFuture = CompletableFuture.supplyAsync(
() -> buildSummaryFromReports(
queryRawReports(stationIdList, range.getCurrentStart(), range.getCurrentEnd())),
FINANCIAL_THREAD_POOL);
CompletableFuture<Integer> 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<String> stationIdList,
String startTime,
String endTime) {
if (stationIdList != null && stationIdList.isEmpty()) {
return new BusinessOperationSummaryDTO();
}
List<SettleOrderReport> 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<String> stationIdList = resolveStationIds(dto.getStationIdList());
// 当前周期汇总
BusinessOperationSummaryDTO currentSummary = buildOperationSummary(
stationIdList, range.getCurrentStart(), range.getCurrentEnd());
// 上周期汇总
BusinessOperationSummaryDTO previousSummary = buildOperationSummary(
stationIdList, range.getPreviousStart(), range.getPreviousEnd());
// 并行查询当前周期和上周期的原始报表数据,各只查一次
CompletableFuture<List<SettleOrderReport>> currentReportFuture = CompletableFuture.supplyAsync(
() -> queryRawReports(stationIdList, range.getCurrentStart(), range.getCurrentEnd()),
FINANCIAL_THREAD_POOL);
CompletableFuture<List<SettleOrderReport>> previousReportFuture = CompletableFuture.supplyAsync(
() -> queryRawReports(stationIdList, range.getPreviousStart(), range.getPreviousEnd()),
FINANCIAL_THREAD_POOL);
// 等待两个查询完成
List<SettleOrderReport> currentReports = currentReportFuture.join();
List<SettleOrderReport> previousReports = previousReportFuture.join();
// 从同一份原始数据分别构建汇总指标和每日明细
BusinessOperationSummaryDTO currentSummary = buildSummaryFromReports(currentReports);
BusinessOperationSummaryDTO previousSummary = buildSummaryFromReports(previousReports);
Map<String, SettleOrderReport> currentDailyMap = buildDailyMapFromReports(currentReports);
Map<String, SettleOrderReport> previousDailyMap = buildDailyMapFromReports(previousReports);
// 构建指标卡片
List<BusinessScaleMetricVO> 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<String> stationIdList,
BusinessOperationDateRangeDTO range) {
private List<SettleOrderReport> queryRawReports(List<String> stationIdList,
String startTime, String endTime) {
if (stationIdList != null && stationIdList.isEmpty()) {
return new ArrayList<>();
}
List<SettleOrderReport> reportList = settleOrderReportService.queryOrderReport(
stationIdList, startTime, endTime);
return CollectionUtils.isEmpty(reportList) ? new ArrayList<>() : reportList;
}
/**
* 从原始报表数据构建汇总指标
*/
private BusinessOperationSummaryDTO buildSummaryFromReports(List<SettleOrderReport> 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<String, SettleOrderReport> buildDailyMapFromReports(List<SettleOrderReport> reportList) {
Map<String, SettleOrderReport> 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<String, SettleOrderReport> currentDailyMap,
Map<String, SettleOrderReport> previousDailyMap) {
String metricName;
String unit;
switch (metricCode) {
@@ -639,13 +728,6 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService {
break;
}
// 查询当前周期每日数据
Map<String, SettleOrderReport> currentDailyMap = queryDailyReportMap(
stationIdList, range.getCurrentStart(), range.getCurrentEnd());
// 查询上周期每日数据
Map<String, SettleOrderReport> 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<String, SettleOrderReport> queryDailyReportMap(List<String> stationIdList,
String startTime, String endTime) {
if (stationIdList != null && stationIdList.isEmpty()) {
return new LinkedHashMap<>();
}
List<SettleOrderReport> reportList = settleOrderReportService.queryOrderReport(
stationIdList, startTime, endTime);
// 按tradeDate分组汇总
Map<String, SettleOrderReport> 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;
}
/**
* 从报表记录中提取指定指标的值
*/