diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/aspect/AsyncAnnotationAspect.java b/blade-service/logpm-report/src/main/java/com/logpm/report/aspect/AsyncAnnotationAspect.java new file mode 100644 index 000000000..43e374734 --- /dev/null +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/aspect/AsyncAnnotationAspect.java @@ -0,0 +1,51 @@ +package com.logpm.report.aspect; + +import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springblade.common.annotations.LogpmAsync; +import org.springblade.core.secure.utils.AuthUtil; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; + +@Aspect +@Component +@Slf4j +@Order(-1) +public class AsyncAnnotationAspect { + + /** + * 定义一个切点,匹配所有带有@LogpmAsync("asyncExecutor")注解的方法。 + * 注意:实际上Spring Framework自带对@LogpmAsync("asyncExecutor")的处理,直接这样配置可能会导致预期之外的行为。 + */ + @Around("@annotation(org.springblade.common.annotations.LogpmAsync)") + public Object logAroundAsyncMethods(ProceedingJoinPoint joinPoint) throws Throwable { + + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + + LogpmAsync myAsync = method.getAnnotation(LogpmAsync.class); + String annotationValue = myAsync.value(); + log.info(">>>>>>>>>>>>>>>>>> annotationValue={}",annotationValue); + + log.info("@LogpmAsync注解的值为asyncExecutor,进行数据源切换 "); + + // 在方法执行前的操作 + String tenantId = AuthUtil.getTenantId(); + log.info(">> tenandId {} ",tenantId); + DynamicDataSourceContextHolder.push(tenantId); + + // 执行原方法 + Object result = joinPoint.proceed(); + + // 在方法执行后的操作 + DynamicDataSourceContextHolder.poll(); + return result; + } + +} diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/config/ExecutorConfig.java b/blade-service/logpm-report/src/main/java/com/logpm/report/config/ExecutorConfig.java new file mode 100644 index 000000000..195483452 --- /dev/null +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/config/ExecutorConfig.java @@ -0,0 +1,82 @@ +package com.logpm.report.config; + +import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; +import org.springblade.core.secure.utils.AuthUtil; +import org.springblade.core.tool.utils.ThreadLocalUtil; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskDecorator; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; + +import javax.annotation.Nonnull; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@Slf4j +@EnableAsync +public class ExecutorConfig { + + @Bean + public Executor asyncExecutor() { + log.info("start async executor"); + ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); +// 配置核心线程数 + threadPoolTaskExecutor.setCorePoolSize(10); +// 配置最大线程数 + threadPoolTaskExecutor.setMaxPoolSize(20); +// 配置队列大小 + threadPoolTaskExecutor.setQueueCapacity(50); +// 配置线程池中线程的名称前缀 + threadPoolTaskExecutor.setThreadNamePrefix("ASYNC_THREAD_"); +// HelloWorldServiceImpl rejection-policy: 当pool已经达到max size时,如何处理新任务: +// CallerRunsPolicy: 不在新线程中执行任务,而是由调用者所在的线程来执行; +// AbortPolicy: 拒绝执行新任务,并抛出RejectedExecutionException异常; +// DiscardPolicy:丢弃当前将要加入队列的任务; +// DiscardOldestPolicy:丢弃任务队列中最旧的任务; + threadPoolTaskExecutor.setRejectedExecutionHandler( + new ThreadPoolExecutor.CallerRunsPolicy() + ); + threadPoolTaskExecutor.setTaskDecorator(new ContextCopyingDecorator()); + threadPoolTaskExecutor.initialize(); + return threadPoolTaskExecutor; + } + + + static class ContextCopyingDecorator implements TaskDecorator { + @Nonnull + @Override + public Runnable decorate(@Nonnull Runnable runnable) { + RequestAttributes context = RequestContextHolder.currentRequestAttributes(); + String tenantId = AuthUtil.getTenantId(); + Map all = ThreadLocalUtil.getAll(); + Map mdcMap = MDC.getCopyOfContextMap(); + return () -> { + try { + all.keySet().forEach(key -> ThreadLocalUtil.put(key, all.get(key))); + if (mdcMap != null && !mdcMap.isEmpty()) { + MDC.setContextMap(mdcMap); + } + RequestContextHolder.setRequestAttributes(context); + String tenantId1 = AuthUtil.getTenantId(); + + runnable.run(); + } finally { + RequestContextHolder.resetRequestAttributes(); + all.clear(); + if (mdcMap != null) { + mdcMap.clear(); + } + ThreadLocalUtil.clear(); + MDC.clear(); + } + }; + } + } + +} diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/mapper/ReportDeliverMapeer.java b/blade-service/logpm-report/src/main/java/com/logpm/report/mapper/ReportDeliverMapeer.java index 412cb0955..1136e53ed 100644 --- a/blade-service/logpm-report/src/main/java/com/logpm/report/mapper/ReportDeliverMapeer.java +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/mapper/ReportDeliverMapeer.java @@ -1,7 +1,6 @@ package com.logpm.report.mapper; import com.baomidou.mybatisplus.core.conditions.Wrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.logpm.report.dto.DeliveryTrainLoadedScanDTO; @@ -63,8 +62,8 @@ public interface ReportDeliverMapeer extends BaseMapper { * @param queryWrapper * @return */ - List getDetailsZeroPage(IPage page,@Param("ew") QueryWrapper queryWrapper); - Long getDetailsZeroPageCount(@Param("ew") QueryWrapper queryWrapper); + List getDetailsZeroPage(IPage page,@Param("ew") Wrapper queryWrapper); + Long getDetailsZeroPageCount(@Param("ew") Wrapper queryWrapper); List getDeliveryTrainLoadSacnByIds(@Param("idBatch") List idBatch); diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/reader/DeliveryDetailReader.java b/blade-service/logpm-report/src/main/java/com/logpm/report/reader/DeliveryDetailReader.java index 3d766d92d..8bf17ecbb 100644 --- a/blade-service/logpm-report/src/main/java/com/logpm/report/reader/DeliveryDetailReader.java +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/reader/DeliveryDetailReader.java @@ -4,14 +4,15 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.logpm.report.mapper.ReportDeliverMapeer; import com.logpm.report.service.ExportReader; +import io.prometheus.client.CollectorRegistry; import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.List; /** - * * @author zhaoqiaobo * @create 2024-03-08 9:50 */ @@ -20,17 +21,23 @@ public class DeliveryDetailReader implements ExportReader { @Resource private ReportDeliverMapeer reportDeliverMapeer; + @Autowired + private CollectorRegistry collectorRegistry; @Override public Long getCount(Wrapper query) { Page page = new Page(1, 1); reportDeliverMapeer.getDetailsPage(page, query); - return page.getTotal(); + Long detailsZeroPageCount = reportDeliverMapeer.getDetailsZeroPageCount(query); + return page.getTotal() + detailsZeroPageCount; } @Override public List findList(Page page, Wrapper query) { - return reportDeliverMapeer.getDetailsPage(page,query); + List detailsPage = reportDeliverMapeer.getDetailsPage(page, query); + List detailsZeroPage = reportDeliverMapeer.getDetailsZeroPage(page, query); + detailsPage.addAll(detailsZeroPage); + return detailsPage; } } diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/service/IAsyncService.java b/blade-service/logpm-report/src/main/java/com/logpm/report/service/IAsyncService.java new file mode 100644 index 000000000..6a040a52a --- /dev/null +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/service/IAsyncService.java @@ -0,0 +1,16 @@ +package com.logpm.report.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; + +public interface IAsyncService { + + CompletableFuture getListCompletableFuture(ExportReader service, Wrapper query, Long pageSize, Long count, int finalNum, Map> pageMap, int finalI); + + void initExportData(ExportReader service, Wrapper query, Long pageSize, Long count, int finalNum, Map> pageMap, int finalI, CountDownLatch countDownLatch); + +} diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/AsyncServiceImpl.java b/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/AsyncServiceImpl.java new file mode 100644 index 000000000..1cbda6745 --- /dev/null +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/AsyncServiceImpl.java @@ -0,0 +1,82 @@ +package com.logpm.report.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.logpm.report.service.ExportReader; +import com.logpm.report.service.IAsyncService; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.formula.functions.T; +import org.springblade.common.annotations.LogpmAsync; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; + +@Service +@Slf4j +public class AsyncServiceImpl implements IAsyncService { + + @Resource + private Executor asyncExecutor; + + @Override + public CompletableFuture getListCompletableFuture(ExportReader service, Wrapper query, Long pageSize, Long count, int finalNum, Map> pageMap, int finalI) { + CompletableFuture future = CompletableFuture.supplyAsync(() -> { + // 剩余数据 + long remaindNum = count - (finalNum * pageSize); + // 当前第几次查询 + int current = finalNum + 1; + // 当前查询需要查询几条数据 + long lastNum = remaindNum > pageSize ? pageSize : remaindNum; + // 分页查询对象 + Page page = new Page(current, lastNum); + // 执行查询操作返回数据 + return service.findList(page, query); + + }, asyncExecutor); + future.thenAccept(list -> { + if(CollUtil.isNotEmpty(list)){ + // 获取组装的数据列表 + List detailVo = pageMap.get(finalI); + // 将查询数据添加到本地缓存 + if (CollectionUtil.isEmpty(detailVo)) { + pageMap.put(finalI, list); + } else { + pageMap.get(finalI).addAll(list); + } + } + }); + return future; + } + + @Override + @LogpmAsync("asyncExecutor") + public void initExportData(ExportReader service, Wrapper query, Long pageSize, Long count, int finalNum, Map> pageMap, int finalI, CountDownLatch countDownLatch) { + // 剩余数据 + long remaindNum = count - (finalNum * pageSize); + // 当前第几次查询 + int current = finalNum + 1; + // 当前查询需要查询几条数据 + long lastNum = remaindNum > pageSize ? pageSize : remaindNum; + // 分页查询对象 + Page page = new Page(current, lastNum); + // 执行查询操作返回数据 + List deliveryTrainPage = service.findList(page, query); + // 获取组装的数据列表 + List detailVo = pageMap.get(finalI); + // 将查询数据添加到本地缓存 + if (CollectionUtil.isEmpty(detailVo)) { + pageMap.put(finalI, deliveryTrainPage); + } else { + pageMap.get(finalI).addAll(deliveryTrainPage); + } + // 当前线程执行完成 + countDownLatch.countDown(); + } +} diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportBillLoadingAsyncService.java b/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportBillLoadingAsyncService.java index d0121be9b..9535f6435 100644 --- a/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportBillLoadingAsyncService.java +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportBillLoadingAsyncService.java @@ -52,6 +52,7 @@ public class ReportBillLoadingAsyncService implements IReportBillLoadingAsyncSer private final BillLoadingTasksReader billLoadingTasksReader; private final IUserClient userClient; private final IBasicdataWarehouseClient warehouseClient; + private final ReportExcelUtil reportExcelUtil; @Override public IPage tasksPage(BillLoadingTasksVO vo, BillLoadingTasksQuery query) { @@ -86,7 +87,7 @@ public class ReportBillLoadingAsyncService implements IReportBillLoadingAsyncSer tasksCustomQuery(query, queryWrapper); // 仓库权限 ReportUtil.buildReportWarehouseAuth(vo.getWarehouse(), query.getWarehouseRange(), queryWrapper, warehouseClient); - new ReportExcelUtil().export(response, billLoadingTasksReader, BillLoadingTasksVO.class, queryWrapper, "自提任务维度报表"); + reportExcelUtil.export(response, billLoadingTasksReader, BillLoadingTasksVO.class, queryWrapper, "自提任务维度报表"); } @Override @@ -150,6 +151,6 @@ public class ReportBillLoadingAsyncService implements IReportBillLoadingAsyncSer detailsCustomQuery(query, queryWrapper); // 仓库权限 ReportUtil.buildReportWarehouseAuth(vo.getWarehouse(), query.getWarehouseRange(), queryWrapper, warehouseClient); - new ReportExcelUtil().export(response, billLoadingDetailsReader, BillLoadingDetailsVO.class, queryWrapper, "自提明细"); + reportExcelUtil.export(response, billLoadingDetailsReader, BillLoadingDetailsVO.class, queryWrapper, "自提明细"); } } diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportDeliverServiceImpl.java b/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportDeliverServiceImpl.java index 3a8cd3025..2136b5ea0 100644 --- a/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportDeliverServiceImpl.java +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportDeliverServiceImpl.java @@ -52,6 +52,7 @@ public class ReportDeliverServiceImpl implements ReportDeliverService { private final StockOrderReader stockOrderReader; private final IBasicdataWarehouseClient warehouseClient; private final ReportDataService reportDataService; + private final ReportExcelUtil reportExcelUtil; @Override public IPage deliveryTrainPage(ReportDevilerVO vo, ReportDevilerQuery query) { @@ -95,7 +96,7 @@ public class ReportDeliverServiceImpl implements ReportDeliverService { trainCustomQuery(query, queryWrapper); // 仓库权限 ReportUtil.buildReportWarehouseAuth(vo.getWarehouseName(), query.getWarehouseNameRange(), queryWrapper, warehouseClient); - new ReportExcelUtil().export(response, deliveryTrainReader, ReportDevilerVO.class, queryWrapper, "配送车次维度报表"); + reportExcelUtil.export(response, deliveryTrainReader, ReportDevilerVO.class, queryWrapper, "配送车次维度报表"); } @Override @@ -139,7 +140,7 @@ public class ReportDeliverServiceImpl implements ReportDeliverService { customerCustomQuery(query, queryWrapper); // 仓库权限 ReportUtil.buildReportWarehouseAuth(vo.getWarehouseName(), query.getWarehouseNameRange(), queryWrapper, warehouseClient); - new ReportExcelUtil().export(response, deliveryCustomerReader, ReportCustomerVO.class, queryWrapper, "配送客户维度报表"); + reportExcelUtil.export(response, deliveryCustomerReader, ReportCustomerVO.class, queryWrapper, "配送客户维度报表"); } @Override @@ -204,7 +205,7 @@ public class ReportDeliverServiceImpl implements ReportDeliverService { detailsCustomQuery(query, queryWrapper); // 仓库权限 ReportUtil.buildReportWarehouseAuth(vo.getWarehouseName(), query.getWarehouseNameRange(), queryWrapper, warehouseClient); - new ReportExcelUtil().export(response, deliveryDetailReader, ReportDetailVO.class, queryWrapper, "配送明细报表"); + reportExcelUtil.export(response, deliveryDetailReader, ReportDetailVO.class, queryWrapper, "配送明细报表"); } @Override @@ -253,7 +254,7 @@ public class ReportDeliverServiceImpl implements ReportDeliverService { stockOrderQuery(query, queryWrapper); // 仓库权限 ReportUtil.buildReportWarehouseAuth(vo.getWarehouse(), query.getWarehouseRange(), queryWrapper, warehouseClient); - new ReportExcelUtil().export(response, stockOrderReader, StockOrderVO.class, queryWrapper, "在库订单表"); + reportExcelUtil.export(response, stockOrderReader, StockOrderVO.class, queryWrapper, "在库订单表"); } @Override diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportStockServiceImpl.java b/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportStockServiceImpl.java index e0da39f0e..e98e9fa06 100644 --- a/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportStockServiceImpl.java +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/service/impl/ReportStockServiceImpl.java @@ -44,6 +44,7 @@ public class ReportStockServiceImpl implements ReportStockService { private final DeliveryOutStocksReader outStocksReader; private final IDictBizClient dictBizClient; private final IBasicdataWarehouseClient warehouseClient; + private final ReportExcelUtil reportExcelUtil; @Override public IPage detailsPage(StockDetailsVO vo, StockDetailsQuery query) { @@ -72,7 +73,7 @@ public class ReportStockServiceImpl implements ReportStockService { QueryWrapper queryWrapper = QueryUtil.buildQueryWrapper(vo, StockDetailsVO.class); detailsCustomQuery(query, queryWrapper); ReportUtil.buildReportWarehouseAuth(vo.getWarehouseName(), query.getWarehouseNameRange(), queryWrapper, warehouseClient); - new ReportExcelUtil().export(response, deliveryStockReader, StockDetailsVO.class, queryWrapper, "库存品表"); + reportExcelUtil.export(response, deliveryStockReader, StockDetailsVO.class, queryWrapper, "库存品表"); } @Override @@ -123,7 +124,7 @@ public class ReportStockServiceImpl implements ReportStockService { QueryWrapper queryWrapper = QueryUtil.buildQueryWrapper(vo, ReportInStockVO.class); inStocksCustomQuery(query, queryWrapper); ReportUtil.buildReportWarehouseAuth(vo.getWarehouseName(), query.getWarehouseNameRange(), queryWrapper, warehouseClient); - new ReportExcelUtil().export(response, inStocksReader, ReportInStockVO.class, queryWrapper, "库存入库表"); + reportExcelUtil.export(response, inStocksReader, ReportInStockVO.class, queryWrapper, "库存入库表"); } @Override @@ -158,7 +159,7 @@ public class ReportStockServiceImpl implements ReportStockService { QueryWrapper queryWrapper = QueryUtil.buildQueryWrapper(vo, ReportOutStockVO.class); outStocksCustomQuery(query, queryWrapper); ReportUtil.buildReportWarehouseAuth(vo.getWarehouseName(), query.getWarehouseNameRange(), queryWrapper, warehouseClient); - new ReportExcelUtil().export(response, outStocksReader, ReportOutStockVO.class, queryWrapper, "库存出库表"); + reportExcelUtil.export(response, outStocksReader, ReportOutStockVO.class, queryWrapper, "库存出库表"); } } diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/util/ReportExcelUtil.java b/blade-service/logpm-report/src/main/java/com/logpm/report/util/ReportExcelUtil.java index 9b0677c81..3c295715d 100644 --- a/blade-service/logpm-report/src/main/java/com/logpm/report/util/ReportExcelUtil.java +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/util/ReportExcelUtil.java @@ -1,5 +1,6 @@ package com.logpm.report.util; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; @@ -8,18 +9,27 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.logpm.report.constant.ReportConstants; import com.logpm.report.service.ExportReader; +import com.logpm.report.service.IAsyncService; +import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.formula.functions.T; +import org.jetbrains.annotations.NotNull; import org.springblade.core.log.exception.ServiceException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.HashMap; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; /** @@ -28,6 +38,8 @@ import java.util.concurrent.ExecutorService; * @author zhaoqiaobo * @create 2024-03-06 17:48 */ +@Slf4j +@Component public class ReportExcelUtil { public static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; @@ -41,6 +53,11 @@ public class ReportExcelUtil { */ public static final Long PAGESIZE = 100000L; + @Resource + private IAsyncService asyncService; + @Autowired + private Executor asyncExecutor; + /** * 设置excel导出的返回头 * @@ -88,7 +105,7 @@ public class ReportExcelUtil { ReportExcelUtil.setExportHeader(response, fileName); // 获取需要导出的总条数 Long count = service.getCount(query); - if(count > 500000L){ + if (count > 500000L) { throw new ServiceException("导出数据不能大于50w,请增加检索条件"); } // 每个 sheet 放多少条数据 @@ -98,7 +115,7 @@ public class ReportExcelUtil { // 总共需要查询数据库几次 int findNum = (int) Math.ceil((count / pageSize.doubleValue())); // 封装查询后需要导出的数据 - Map> pageMap = new HashMap<>(ReportConstants.HASHMAP_DEFAULT_SIZE); + Map> pageMap = new ConcurrentHashMap<>(ReportConstants.HASHMAP_DEFAULT_SIZE); // 定义线程池,大表导出使用一个线程池 ExecutorService executorService = ThreadPoolUtil.getThreadPool(); // 控制线程全部查询完后执行导出操作 @@ -111,6 +128,7 @@ public class ReportExcelUtil { e.printStackTrace(); } int num = 0; + List> futures = new ArrayList<>(); for (int i = 0; i < sheetNum; i++) { // sheet编号 int finalI = i + 1; @@ -123,28 +141,37 @@ public class ReportExcelUtil { // 查询次数+1 num = num + 1; // 提交线程执行查询 - executorService.submit(() -> { - // 剩余数据 - long remaindNum = count - (finalNum * pageSize); - // 当前第几次查询 - int current = finalNum + 1; - // 当前查询需要查询几条数据 - long lastNum = remaindNum > pageSize ? pageSize : remaindNum; - // 分页查询对象 - Page page = new Page(current, lastNum); - // 执行查询操作返回数据 - List deliveryTrainPage = service.findList(page, query); - // 获取组装的数据列表 - List detailVo = pageMap.get(finalI); - // 将查询数据添加到本地缓存 - if (CollectionUtil.isEmpty(detailVo)) { - pageMap.put(finalI, deliveryTrainPage); - } else { - pageMap.get(finalI).addAll(deliveryTrainPage); - } - // 当前线程执行完成 - countDownLatch.countDown(); - }); + // CompletableFuture future = asyncService.getListCompletableFuture(service, query, pageSize, count, finalNum, pageMap, finalI); + // CompletableFuture future = CompletableFuture.supplyAsync(() -> { + // // 剩余数据 + // long remaindNum = count - (finalNum * pageSize); + // // 当前第几次查询 + // int current = finalNum + 1; + // // 当前查询需要查询几条数据 + // long lastNum = remaindNum > pageSize ? pageSize : remaindNum; + // // 分页查询对象 + // Page page = new Page(current, lastNum); + // // 执行查询操作返回数据 + // return service.findList(page, query); + // }, asyncExecutor); + // future.thenAccept(list -> { + // if(CollUtil.isNotEmpty(list)){ + // // 获取组装的数据列表 + // List detailVo = pageMap.get(finalI); + // // 将查询数据添加到本地缓存 + // if (CollectionUtil.isEmpty(detailVo)) { + // pageMap.put(finalI, list); + // } else { + // pageMap.get(finalI).addAll(list); + // } + // } + // }); + // futures.add(future); + // asyncExecutor.execute(() -> { + + asyncService.initExportData(service, query, pageSize, count, finalNum, pageMap, finalI, countDownLatch); + + // }); } } try { @@ -153,6 +180,13 @@ public class ReportExcelUtil { } catch (InterruptedException e) { e.printStackTrace(); } + + // try { + // CompletableFuture allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + // allFutures.join(); + // } catch (Exception e) { + // log.error("系统异常:{}", e); + // } // 分sheet向excel中写数据, for (Map.Entry> entry : pageMap.entrySet()) { Integer key = entry.getKey(); @@ -164,4 +198,54 @@ public class ReportExcelUtil { excelWriter.finish(); } + private static void initExportData(ExportReader service, Wrapper query, Long pageSize, Long count, int finalNum, Map> pageMap, int finalI) { + // 剩余数据 + long remaindNum = count - (finalNum * pageSize); + // 当前第几次查询 + int current = finalNum + 1; + // 当前查询需要查询几条数据 + long lastNum = remaindNum > pageSize ? pageSize : remaindNum; + // 分页查询对象 + Page page = new Page(current, lastNum); + // 执行查询操作返回数据 + List deliveryTrainPage = service.findList(page, query); + // 获取组装的数据列表 + List detailVo = pageMap.get(finalI); + // 将查询数据添加到本地缓存 + if (CollectionUtil.isEmpty(detailVo)) { + pageMap.put(finalI, deliveryTrainPage); + } else { + pageMap.get(finalI).addAll(deliveryTrainPage); + } + } + + private static @NotNull CompletableFuture getListCompletableFuture(ExportReader service, Wrapper query, Long pageSize, Long count, int finalNum, Map> pageMap, int finalI) { + CompletableFuture future = CompletableFuture.supplyAsync(() -> { + // 剩余数据 + long remaindNum = count - (finalNum * pageSize); + // 当前第几次查询 + int current = finalNum + 1; + // 当前查询需要查询几条数据 + long lastNum = remaindNum > pageSize ? pageSize : remaindNum; + // 分页查询对象 + Page page = new Page(current, lastNum); + // 执行查询操作返回数据 + return service.findList(page, query); + + }); + future.thenAccept(list -> { + if (CollUtil.isNotEmpty(list)) { + // 获取组装的数据列表 + List detailVo = pageMap.get(finalI); + // 将查询数据添加到本地缓存 + if (CollectionUtil.isEmpty(detailVo)) { + pageMap.put(finalI, list); + } else { + pageMap.get(finalI).addAll(list); + } + } + }); + return future; + } + } diff --git a/blade-service/logpm-report/src/main/java/com/logpm/report/util/ReportUtil.java b/blade-service/logpm-report/src/main/java/com/logpm/report/util/ReportUtil.java index f70649cf9..56eb10c0a 100644 --- a/blade-service/logpm-report/src/main/java/com/logpm/report/util/ReportUtil.java +++ b/blade-service/logpm-report/src/main/java/com/logpm/report/util/ReportUtil.java @@ -60,12 +60,14 @@ public class ReportUtil { } public static void dateIsWithinOneMonth(String taskTime, Date startTaskTime, Date endTaskTime, String title) { - if (ObjectUtil.isEmpty(taskTime)) { + // if (ObjectUtil.isEmpty(taskTime)) { + if (ObjectUtil.isAllNotEmpty(startTaskTime, endTaskTime)) { boolean withinOneMonth = isWithinOneMonth(startTaskTime, endTaskTime); if (!withinOneMonth) { throw new ServiceException(title + "必选且时间不超过一个月"); } } + // } } }