java
复制代码
/**
* 收入日报数据组装
*/
private <T extends StoreBaseStaDto> void getDoDailyIncomeReportInfo(List<OrganizeGeneralDetailVO> storeInfos
, T params, String tenantId, List<FtbDataAnalysisReportDetails> analysisReportDetails) {
Map<String, String> storeMap = storeInfos.stream().collect(Collectors.toMap(OrganizeGeneralDetailVO::getId, OrganizeGeneralDetailVO::getCashierStoreId));
Map<String, OrganizeGeneralDetailVO> storeInfoMap = storeInfos.stream()
.collect(Collectors.toMap(OrganizeGeneralDetailVO::getId, organizeGeneralDetailVO -> organizeGeneralDetailVO));
// 门店信息
StoreRevenueAnalysisStaDto aDTO = new StoreRevenueAnalysisStaDto();
aDTO.setDimension(DimensionTypeEnums.MONTH);
aDTO.setOpenStartDate(params.getOpenStartDate());
aDTO.setOpenEndDate(params.getOpenEndDate());
aDTO.setStartDate(params.getStartDate());
aDTO.setEndDate(params.getEndDate());
aDTO.setStoreMap(storeMap);
StoreRevenueAnalysisStaDto bDTO = new StoreRevenueAnalysisStaDto();
BeanUtils.copyProperties(aDTO, bDTO);
bDTO.setDimension(DimensionTypeEnums.DAY);
// 创建任务列表,每个任务都添加异常处理
CompletableFuture<Map<String, DailyIncomeReportStoreInfoVO>> storeMonthInfoStaMapFuture = CompletableFuture.supplyAsync(
() -> {
try {
return TenantSupplierWrapper.supplierWrapper(tenantId, () -> dailyIncomeReportService.getStoreMonthInfoStaMap(aDTO));
} catch (Exception e) {
log.error("门店信息目标查询失败", e);
return new HashMap<>();
}
}, executor);
CompletableFuture<Map<String, DailyIncomeReportIntegratedVO>> storeDaySynthesisInfoFuture = CompletableFuture.supplyAsync(
() -> {
try {
return TenantSupplierWrapper.supplierWrapper(tenantId, () -> dailyIncomeReportService.getStoreDaySynthesisInfoStaMap(bDTO));
} catch (Exception e) {
log.error("综合信息查询失败", e);
return new HashMap<>();
}
}, executor);
CompletableFuture<Map<String, DailyIncomeReportEatInVO>> storeDayEatInInfoStaMapFuture = CompletableFuture.supplyAsync(
() -> {
try {
return TenantSupplierWrapper.supplierWrapper(tenantId, () -> dailyIncomeReportService.getStoreDayDineInInfoStaMap(bDTO));
} catch (Exception e) {
log.error("堂食信息查询失败", e);
return new HashMap<>();
}
}, executor
);
CompletableFuture<Map<String, DailyIncomeReportTakeAwayFoodVO>> storeDayTakeOutInfoStaMapFuture = CompletableFuture.supplyAsync(
() -> {
try {
return TenantSupplierWrapper.supplierWrapper(tenantId, () -> dailyIncomeReportService.getStoreDayTakeOutInfoStaMap(bDTO));
} catch (Exception e) {
log.error("外卖信息查询失败", e);
return new HashMap<>();
}
}, executor
);
CompletableFuture<Map<String, DailyIncomeReportCorrectionVO>> storeDayBadCommentInfoStaMapFuture = CompletableFuture.supplyAsync(
() -> {
try {
return TenantSupplierWrapper.supplierWrapper(tenantId, () -> dailyIncomeReportService.getStoreDayCorrectionInfoStaMap(bDTO));
} catch (Exception e) {
log.error("中差评信息查询失败", e);
return new HashMap<>();
}
}, executor
);
CompletableFuture<Map<String, DailyIncomeReportDeskVisitVO>> storeDayTableVisitInfoStaMapFuture = CompletableFuture.supplyAsync(
() -> {
try {
return TenantSupplierWrapper.supplierWrapper(tenantId, () -> dailyIncomeReportService.getStoreDayDeskVisitInfoStaMap(bDTO, tenantId));
} catch (Exception e) {
log.error("桌访信息查询失败", e);
return new HashMap<>();
}
}, executor
);
// 合并所有任务
CompletableFuture<Void> allTasks = CompletableFuture.allOf(
storeMonthInfoStaMapFuture, storeDaySynthesisInfoFuture,
storeDayEatInInfoStaMapFuture, storeDayTakeOutInfoStaMapFuture,
storeDayBadCommentInfoStaMapFuture, storeDayTableVisitInfoStaMapFuture);
try {
// 设置超时时间,比如30秒
allTasks.get(30, TimeUnit.SECONDS);
} catch (TimeoutException e) {
log.error("收入日报数据查询超时,已取消未完成的任务", e);
// 取消所有未完成的任务
storeMonthInfoStaMapFuture.cancel(true);
storeDaySynthesisInfoFuture.cancel(true);
storeDayEatInInfoStaMapFuture.cancel(true);
storeDayTakeOutInfoStaMapFuture.cancel(true);
storeDayBadCommentInfoStaMapFuture.cancel(true);
storeDayTableVisitInfoStaMapFuture.cancel(true);
// 根据业务需求,可以选择抛出异常或返回部分结果
// 这里我们选择继续处理已完成的,但如果需要严格处理,可以抛出异常
} catch (InterruptedException e) {
log.error("收入日报数据查询被中断", e);
Thread.currentThread().interrupt();
// 同样取消所有任务
storeMonthInfoStaMapFuture.cancel(true);
storeDaySynthesisInfoFuture.cancel(true);
storeDayEatInInfoStaMapFuture.cancel(true);
storeDayTakeOutInfoStaMapFuture.cancel(true);
storeDayBadCommentInfoStaMapFuture.cancel(true);
storeDayTableVisitInfoStaMapFuture.cancel(true);
} catch (ExecutionException e) {
log.error("收入日报数据查询执行异常", e);
// 由于每个任务都有异常处理,这里通常不会发生,但为了安全起见
}
// 安全地获取结果,避免join()抛出异常
Map<String, DailyIncomeReportStoreInfoVO> storeMonthInfoStaMap = new HashMap<>();
Map<String, DailyIncomeReportIntegratedVO> storeDaySynthesisInfoStaMap = new HashMap<>();
Map<String, DailyIncomeReportEatInVO> storeDayEatInInfoStaMap = new HashMap<>();
Map<String, DailyIncomeReportTakeAwayFoodVO> storeDayTakeOutInfoStaMap = new HashMap<>();
Map<String, DailyIncomeReportCorrectionVO> storeDayBadCommentInfoStaMap = new HashMap<>();
Map<String, DailyIncomeReportDeskVisitVO> storeDayTableVisitInfoStaMap = new HashMap<>();
try {
if (!storeMonthInfoStaMapFuture.isCompletedExceptionally()) {
storeMonthInfoStaMap = storeMonthInfoStaMapFuture.get();
}
} catch (Exception e) {
log.error("获取门店信息目标结果失败", e);
}
try {
if (!storeDaySynthesisInfoFuture.isCompletedExceptionally()) {
storeDaySynthesisInfoStaMap = storeDaySynthesisInfoFuture.get();
}
} catch (Exception e) {
log.error("获取综合信息结果失败", e);
}
try {
if (!storeDayEatInInfoStaMapFuture.isCompletedExceptionally()) {
storeDayEatInInfoStaMap = storeDayEatInInfoStaMapFuture.get();
}
} catch (Exception e) {
log.error("获取堂食信息结果失败", e);
}
try {
if (!storeDayTakeOutInfoStaMapFuture.isCompletedExceptionally()) {
storeDayTakeOutInfoStaMap = storeDayTakeOutInfoStaMapFuture.get();
}
} catch (Exception e) {
log.error("获取外卖信息结果失败", e);
}
try {
if (!storeDayBadCommentInfoStaMapFuture.isCompletedExceptionally()) {
storeDayBadCommentInfoStaMap = storeDayBadCommentInfoStaMapFuture.get();
}
} catch (Exception e) {
log.error("获取中差评信息结果失败", e);
}
try {
if (!storeDayTableVisitInfoStaMapFuture.isCompletedExceptionally()) {
storeDayTableVisitInfoStaMap = storeDayTableVisitInfoStaMapFuture.get();
}
} catch (Exception e) {
log.error("获取桌访信息结果失败", e);
}
// 提前计算并缓存所有需要的数据
Map<String, BigDecimal> areaEfficiencyCache = new HashMap<>();
Map<String, BigDecimal> turnoverRateCache = new HashMap<>();
// 预计算坪效
for (Map.Entry<String, DailyIncomeReportIntegratedVO> entry : storeDaySynthesisInfoStaMap.entrySet()) {
DailyIncomeReportIntegratedVO vo = entry.getValue();
OrganizeGeneralDetailVO storeInfo = storeInfoMap.get(entry.getKey());
if (storeInfo != null && vo != null) {
vo.setStoreArea(storeInfo.getAreaNum());
if (vo.getStoreArea() != null && vo.getTodayIncome() != null) {
BigDecimal areaEfficiency = NumberUtil.div(vo.getTodayIncome(), vo.getStoreArea(), 2);
vo.setAreaEfficiency(areaEfficiency);
areaEfficiencyCache.put(entry.getKey(), areaEfficiency);
}
}
}
// 预计算翻台率
for (Map.Entry<String, DailyIncomeReportEatInVO> entry : storeDayEatInInfoStaMap.entrySet()) {
DailyIncomeReportEatInVO vo = entry.getValue();
OrganizeGeneralDetailVO storeInfo = storeInfoMap.get(entry.getKey());
if (storeInfo != null && vo != null) {
vo.setTableCount(storeInfo.getDeskCount());
if (vo.getTableCount() != null && vo.getOrderCount() != null) {
BigDecimal turnoverRate = NumberUtil.div(vo.getOrderCount(), vo.getTableCount(), 2);
vo.setTurnoverRate(turnoverRate);
turnoverRateCache.put(entry.getKey(), turnoverRate);
}
}
}
// 组装最终数据
for (FtbDataAnalysisReportDetails reportDetails : analysisReportDetails) {
OrganizeGeneralDetailVO organizeGeneralDetailVO = storeInfoMap.get(reportDetails.getStoreId());
if (organizeGeneralDetailVO == null) {
// 跳过没有门店信息的数据
continue;
}
DailyIncomeReportVO dailyIncomeReportVO = new DailyIncomeReportVO();
// 门店信息目标
DailyIncomeReportStoreInfoVO dailyIncomeReportStoreInfoVO = storeMonthInfoStaMap.get(reportDetails.getStoreId());
if (Objects.nonNull(dailyIncomeReportStoreInfoVO)) {
dailyIncomeReportStoreInfoVO.setStoreName(reportDetails.getStoreName());
dailyIncomeReportVO.setStoreInfo(dailyIncomeReportStoreInfoVO);
}
// 综合 - 直接从缓存中获取已计算的坪效
DailyIncomeReportIntegratedVO dailyIncomeReportIntegratedVO = storeDaySynthesisInfoStaMap.get(reportDetails.getStoreId());
if (Objects.nonNull(dailyIncomeReportIntegratedVO)) {
// 如果预计算时已经设置,这里可以直接使用
if (dailyIncomeReportIntegratedVO.getAreaEfficiency() == null && areaEfficiencyCache.containsKey(reportDetails.getStoreId())) {
dailyIncomeReportIntegratedVO.setAreaEfficiency(areaEfficiencyCache.get(reportDetails.getStoreId()));
}
dailyIncomeReportVO.setIntegrated(dailyIncomeReportIntegratedVO);
}
// 堂食 - 直接从缓存中获取已计算的翻台率
DailyIncomeReportEatInVO dailyIncomeReportEatInVO = storeDayEatInInfoStaMap.get(reportDetails.getStoreId());
if (Objects.nonNull(dailyIncomeReportEatInVO)) {
// 如果预计算时已经设置,这里可以直接使用
if (dailyIncomeReportEatInVO.getTurnoverRate() == null && turnoverRateCache.containsKey(reportDetails.getStoreId())) {
dailyIncomeReportEatInVO.setTurnoverRate(turnoverRateCache.get(reportDetails.getStoreId()));
}
dailyIncomeReportVO.setEatIn(dailyIncomeReportEatInVO);
}
// 外卖
DailyIncomeReportTakeAwayFoodVO dailyIncomeReportTakeAwayFoodVO = storeDayTakeOutInfoStaMap.get(reportDetails.getStoreId());
if (Objects.nonNull(dailyIncomeReportTakeAwayFoodVO)) {
dailyIncomeReportVO.setTakeAwayFood(dailyIncomeReportTakeAwayFoodVO);
}
// 中差评
DailyIncomeReportCorrectionVO dailyIncomeReportCorrectionVO = storeDayBadCommentInfoStaMap.get(reportDetails.getStoreId());
if (Objects.nonNull(dailyIncomeReportCorrectionVO)) {
dailyIncomeReportVO.setCorrection(dailyIncomeReportCorrectionVO);
}
// 桌访
DailyIncomeReportDeskVisitVO dailyIncomeReportDeskVisitVO = storeDayTableVisitInfoStaMap.get(reportDetails.getStoreId());
if (Objects.nonNull(dailyIncomeReportDeskVisitVO)) {
dailyIncomeReportVO.setDeskVisit(dailyIncomeReportDeskVisitVO);
}
reportDetails.setIncomeDailyReport(JSON.toJSONString(dailyIncomeReportVO));
}
}