update 大数据屏接口

This commit is contained in:
jsowell
2026-08-04 16:29:17 +08:00
parent bfa209becb
commit 9315e701e6
22 changed files with 320 additions and 83 deletions

View File

@@ -185,16 +185,29 @@ public class indexController extends BaseController {
() -> pileBasicInfoService.aggregateReportByMerchantIds(midList), threadPoolTaskExecutor);
totalPilesFuture = CompletableFuture.supplyAsync(
() -> pileBasicInfoService.countTotalPilesByMerchantIds(midList), threadPoolTaskExecutor);
} else {
} else if (!CollectionUtils.isEmpty(finalStationIdList)) {
// 站点管理员按stationId查
final List<String> sidList = finalStationIdList;
situationFuture = CompletableFuture.supplyAsync(
() -> pileBasicInfoService.aggregateReportByStationIds(sidList), threadPoolTaskExecutor);
totalPilesFuture = CompletableFuture.supplyAsync(
() -> pileBasicInfoService.countTotalPilesByStationIds(sidList), threadPoolTaskExecutor);
} else {
// 非平台管理员但未解析出任何可查维度(商户未绑定/部门下无站点):
// 返回空数据,避免空列表退化为无过滤的全量查询导致越权
logger.warn("大数据平台总览数据查询:当前账号无任何可查的商户/站点维度,返回空数据");
situationFuture = CompletableFuture.completedFuture(emptySituationVO());
totalPilesFuture = CompletableFuture.completedFuture(0L);
}
// 不需要权限过滤的全局查询(日期在代码中生成,不在数据库中运算)
// 数据范围平台管理员不限制null下级账号按各自的merchantIdList/stationIdList过滤
final boolean hasDataScope = isPlatformAdmin
|| !CollectionUtils.isEmpty(finalMerchantIdList)
|| !CollectionUtils.isEmpty(finalStationIdList);
final List<String> scopeMerchantIds = isPlatformAdmin ? null : finalMerchantIdList;
final List<String> scopeStationIds = isPlatformAdmin ? null : finalStationIdList;
// 其余指标查询(与累计字段同一数据范围;日期在代码中生成,不在数据库中运算)
java.time.LocalDate today = java.time.LocalDate.now();
String todayStart = today.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00:00:00";
String todayEnd = today.plusDays(1).format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00:00:00";
@@ -205,26 +218,46 @@ public class indexController extends BaseController {
final String fMonthStart = monthStart;
final String fMonthEnd = monthEnd;
CompletableFuture<Long> totalUsersFuture = CompletableFuture.supplyAsync(
() -> memberBasicInfoService.countTotalMembers(), threadPoolTaskExecutor);
CompletableFuture<Long> totalStationsFuture = CompletableFuture.supplyAsync(
() -> pileStationInfoService.countTotalStations(), threadPoolTaskExecutor);
CompletableFuture<Long> dailyNewUsersFuture = CompletableFuture.supplyAsync(
() -> memberBasicInfoService.countTodayNewMembers(fTodayStart, fTodayEnd), threadPoolTaskExecutor);
CompletableFuture<BigDecimal> todayAmountFuture = CompletableFuture.supplyAsync(
() -> orderBasicInfoService.getTodayTransactionAmount(fTodayStart, fTodayEnd), threadPoolTaskExecutor);
CompletableFuture<BigDecimal> todayElecFuture = CompletableFuture.supplyAsync(
() -> orderBasicInfoService.getTodayElectricity(fTodayStart, fTodayEnd), threadPoolTaskExecutor);
CompletableFuture<BigDecimal> monthlyAvgFuture = CompletableFuture.supplyAsync(
() -> pileBasicInfoService.getMonthlyAvgElectricity(fMonthStart, fMonthEnd), threadPoolTaskExecutor);
CompletableFuture<Long> totalGunsFuture = CompletableFuture.supplyAsync(
() -> pileConnectorInfoService.countTotalConnectors(), threadPoolTaskExecutor);
CompletableFuture<Long> onlinePilesFuture = CompletableFuture.supplyAsync(
() -> pileConnectorInfoService.countOnlinePiles(), threadPoolTaskExecutor);
CompletableFuture<Long> dcPilesFuture = CompletableFuture.supplyAsync(
() -> pileConnectorInfoService.countDcPiles(), threadPoolTaskExecutor);
CompletableFuture<Long> acPilesFuture = CompletableFuture.supplyAsync(
() -> pileConnectorInfoService.countAcPiles(), threadPoolTaskExecutor);
CompletableFuture<Long> totalUsersFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> memberBasicInfoService.countTotalMembers(scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(0L);
CompletableFuture<Long> totalStationsFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> pileStationInfoService.countTotalStations(scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(0L);
CompletableFuture<Long> dailyNewUsersFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> memberBasicInfoService.countTodayNewMembers(fTodayStart, fTodayEnd, scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(0L);
CompletableFuture<BigDecimal> todayAmountFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> orderBasicInfoService.getTodayTransactionAmount(fTodayStart, fTodayEnd, scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(java.math.BigDecimal.ZERO);
CompletableFuture<BigDecimal> todayElecFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> orderBasicInfoService.getTodayElectricity(fTodayStart, fTodayEnd, scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(java.math.BigDecimal.ZERO);
CompletableFuture<BigDecimal> monthlyAvgFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> pileBasicInfoService.getMonthlyAvgElectricity(fMonthStart, fMonthEnd, scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(java.math.BigDecimal.ZERO);
CompletableFuture<Long> totalGunsFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> pileConnectorInfoService.countTotalConnectors(scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(0L);
CompletableFuture<Long> onlinePilesFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> pileConnectorInfoService.countOnlinePiles(scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(0L);
CompletableFuture<Long> dcPilesFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> pileConnectorInfoService.countDcPiles(scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(0L);
CompletableFuture<Long> acPilesFuture = hasDataScope
? CompletableFuture.supplyAsync(
() -> pileConnectorInfoService.countAcPiles(scopeMerchantIds, scopeStationIds), threadPoolTaskExecutor)
: CompletableFuture.completedFuture(0L);
// 等待所有异步查询完成
CompletableFuture.allOf(
@@ -244,15 +277,6 @@ public class indexController extends BaseController {
Long totalOrderCount = (totalOrderCountStr != null && !totalOrderCountStr.isEmpty())
? Long.parseLong(totalOrderCountStr.replaceAll("[.](.*)", "")) : 0L;
// demo账号数据放大3倍
if (isDemo) {
BigDecimal multiplier = new BigDecimal(Constants.THREE);
totalChargingAmount = new BigDecimal(situation.getTotalSettleAmount()).multiply(multiplier).toString();
totalChargingDegree = new BigDecimal(totalChargingDegree).multiply(multiplier).toString();
totalPileCount = totalPileCount != null ? totalPileCount * 3 : 0L;
totalOrderCount = totalOrderCount * 3;
}
overviewVO.setTotalUsers(totalUsersFuture.get());
overviewVO.setTotalOrders(totalOrderCount);
overviewVO.setTotalTransactionAmount(totalChargingAmount);
@@ -268,8 +292,8 @@ public class indexController extends BaseController {
overviewVO.setMonthlyAvgElectricity(monthlyAvg != null ? monthlyAvg.toPlainString() : "0");
overviewVO.setTotalGuns(totalGunsFuture.get());
overviewVO.setOnlinePiles(onlinePilesFuture.get());
overviewVO.setOnlineStations(dcPilesFuture.get());
overviewVO.setOnlineGuns(acPilesFuture.get());
overviewVO.setDcPileCount(dcPilesFuture.get());
overviewVO.setAcPileCount(acPilesFuture.get());
// 节能减排计算
BigDecimal totalElecKwh = new BigDecimal(totalChargingDegree);
@@ -289,6 +313,11 @@ public class indexController extends BaseController {
.setScale(2, RoundingMode.HALF_UP);
overviewVO.setStandardCoalSaved(coalSaved.toPlainString());
// demo账号全部指标同步放大3倍节能减排基于放大后的电量/订单数重算)
if (isDemo) {
amplifyDemoData(overviewVO);
}
response = new RestApiResponse<>(overviewVO);
} catch (Exception e) {
logger.error("大数据平台总览数据查询错误", e);
@@ -343,6 +372,68 @@ public class indexController extends BaseController {
return params;
}
/**
* 空权限维度时的占位汇总数据全为0避免下游NPE
*/
private static IndexGeneralSituationVO emptySituationVO() {
IndexGeneralSituationVO vo = new IndexGeneralSituationVO();
vo.setTotalChargingAmount("0");
vo.setTotalSettleAmount("0");
vo.setTotalChargingDegree("0");
vo.setTotalChargingQuantity("0");
return vo;
}
/**
* demo账号数据放大3倍
* 所有总量类指标(用户、订单、金额、电量、站点、桩、枪等)同步放大,保证各维度数据比例一致;
* 节能减排基于放大后的累计电量/订单数重算,其中"单次充电平均减碳量"为比值型指标,放大后保持不变
*/
private static void amplifyDemoData(BigDataOverviewVO vo) {
BigDecimal multiplier = new BigDecimal(Constants.THREE);
vo.setTotalUsers(multiply(vo.getTotalUsers(), multiplier));
vo.setTotalOrders(multiply(vo.getTotalOrders(), multiplier));
vo.setTotalTransactionAmount(multiply(vo.getTotalTransactionAmount(), multiplier));
vo.setTotalElectricity(multiply(vo.getTotalElectricity(), multiplier));
vo.setTotalPiles(multiply(vo.getTotalPiles(), multiplier));
vo.setTotalStations(multiply(vo.getTotalStations(), multiplier));
vo.setDailyNewUsers(multiply(vo.getDailyNewUsers(), multiplier));
vo.setTodayTransactionAmount(multiply(vo.getTodayTransactionAmount(), multiplier));
vo.setTodayElectricity(multiply(vo.getTodayElectricity(), multiplier));
vo.setMonthlyAvgElectricity(multiply(vo.getMonthlyAvgElectricity(), multiplier));
vo.setTotalGuns(multiply(vo.getTotalGuns(), multiplier));
vo.setOnlinePiles(multiply(vo.getOnlinePiles(), multiplier));
vo.setDcPileCount(multiply(vo.getDcPileCount(), multiplier));
vo.setAcPileCount(multiply(vo.getAcPileCount(), multiplier));
// 节能减排按放大后的累计电量/订单数重算
BigDecimal totalElecKwh = new BigDecimal(vo.getTotalElectricity());
BigDecimal carbonKg = totalElecKwh.multiply(new BigDecimal("0.5306"));
BigDecimal carbonTon = carbonKg.divide(new BigDecimal("1000"), 2, RoundingMode.HALF_UP);
vo.setCarbonReduction(carbonTon.toPlainString());
Long totalOrderCount = vo.getTotalOrders();
if (totalOrderCount != null && totalOrderCount > 0) {
BigDecimal avgCarbon = carbonKg.divide(new BigDecimal(totalOrderCount), 2, RoundingMode.HALF_UP);
vo.setAvgCarbonPerOrder(avgCarbon.toPlainString());
} else {
vo.setAvgCarbonPerOrder("0");
}
BigDecimal fuelSaved = totalElecKwh.multiply(new BigDecimal("8"))
.divide(new BigDecimal("15"), 2, RoundingMode.HALF_UP);
vo.setFuelSaved(fuelSaved.toPlainString());
BigDecimal coalSaved = totalElecKwh.multiply(new BigDecimal("0.000404"))
.setScale(2, RoundingMode.HALF_UP);
vo.setStandardCoalSaved(coalSaved.toPlainString());
}
private static Long multiply(Long value, BigDecimal multiplier) {
return value == null ? null : new BigDecimal(value).multiply(multiplier).longValue();
}
private static String multiply(String value, BigDecimal multiplier) {
return value == null ? null : new BigDecimal(value).multiply(multiplier).toString();
}
/**
* 大数据平台-充电站地图数据
*/