mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-04-19 18:45:03 +08:00
update 运营端小程序优化接口查询速度
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从报表记录中提取指定指标的值
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user