From 6e3918958b296f8a568a1c5e87be963c37b25a8e Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 11 May 2026 18:40:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=92=8C=E6=89=B9=E9=87=8F=E4=BF=9D=E5=AD=98=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FishDraftDataController.java | 26 +++++- .../service/impl/FishImportServiceImpl.java | 39 +++++++-- .../src/main/resources/application-prod.yml | 84 ++++++++++++++++++- 3 files changed, 138 insertions(+), 11 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java b/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java index 3133027..d4ce024 100644 --- a/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java +++ b/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java @@ -13,6 +13,9 @@ import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; @@ -77,6 +80,12 @@ public class FishDraftDataController { @Autowired private ThreadPoolTaskExecutor taskExecutor; + private final ExecutorService attachmentDeleteExecutor = Executors.newFixedThreadPool(4, r -> { + Thread t = new Thread(r, "attachment-delete"); + t.setDaemon(true); + return t; + }); + @PostMapping("/page") @Operation(summary = "分页查询过鱼数据(关联电站和设施)") public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) { @@ -260,7 +269,7 @@ public class FishDraftDataController { // log.error("异步删除附件失败, dataId: {}", fishDraftData.getId(), e); // } // } -// }, taskExecutor).exceptionally(ex -> { +// }, attachmentDeleteExecutor).exceptionally(ex -> { // log.error("异步删除任务执行异常", ex); // return null; // }); @@ -301,7 +310,7 @@ public class FishDraftDataController { log.error("异步删除附件失败, dataId: {}", fishDraftData.getId(), e); } } - }, taskExecutor).exceptionally(ex -> { + }, attachmentDeleteExecutor).exceptionally(ex -> { log.error("异步删除任务执行异常", ex); return null; }); @@ -1266,4 +1275,17 @@ public class FishDraftDataController { return errors; } + + @jakarta.annotation.PreDestroy + public void shutdown() { + attachmentDeleteExecutor.shutdown(); + try { + if (!attachmentDeleteExecutor.awaitTermination(30, TimeUnit.SECONDS)) { + attachmentDeleteExecutor.shutdownNow(); + } + } catch (InterruptedException e) { + attachmentDeleteExecutor.shutdownNow(); + Thread.currentThread().interrupt(); + } + } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java index 4dbb068..5d49a60 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java @@ -39,6 +39,9 @@ import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; @Service @Slf4j @@ -77,6 +80,12 @@ public class FishImportServiceImpl implements IFishImportService { @Resource private SysUserDataScopeMapper userDataScopeMapper; + private final ExecutorService attachmentExecutor = Executors.newFixedThreadPool(4, r -> { + Thread t = new Thread(r, "attachment-upload"); + t.setDaemon(true); + return t; + }); + private static final Map EXCEL_COLUMN_MAPPING = new LinkedHashMap<>(); private static final Map EXCEL_COLUMN_INDEX_MAPPING = new LinkedHashMap<>(); @@ -1507,7 +1516,7 @@ public class FishImportServiceImpl implements IFishImportService { String vdpth = data.getVdpth(); String picpth = data.getPicpth(); - if(StrUtil.isBlank(vdpth) && StrUtil.isBlank(picpth)){ + if (StrUtil.isBlank(vdpth) && StrUtil.isBlank(picpth)) { log.error("数据不完整, 忽略处理"); return; } @@ -1530,27 +1539,28 @@ public class FishImportServiceImpl implements IFishImportService { data.setPicpth(uploadedPicpth); } } - - fishDraftDataService.updateById(data); log.info("异步上传附件完成, dataId: {},{},{}", data.getId(), data.getPicpth(), data.getVdpth()); } catch (Exception e) { log.error("异步上传附件失败, dataId: {}", data.getId(), e); } finally { SecurityContextHolder.clearContext(); } - }); + }, attachmentExecutor); futures.add(future); } CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) .thenRun(() -> { - try { - // del 方法会递归删除目录及其所有内容 + fishDraftDataService.updateBatchById(dataList); + log.info("批量更新附件路径完成, 共{}条", dataList.size()); + } catch (Exception e) { + log.error("批量更新附件路径失败", e); + } + try { FileUtil.del(tempDir); } catch (Exception e) { - log.error("删除临时目录失败{}", e.getMessage()); + log.error("删除临时目录失败{}", e.getMessage()); } - }) .exceptionally(ex -> { log.error("等待异步任务完成时发生异常", ex); @@ -1734,4 +1744,17 @@ public class FishImportServiceImpl implements IFishImportService { } return null; } + + @jakarta.annotation.PreDestroy + public void shutdown() { + attachmentExecutor.shutdown(); + try { + if (!attachmentExecutor.awaitTermination(30, TimeUnit.SECONDS)) { + attachmentExecutor.shutdownNow(); + } + } catch (InterruptedException e) { + attachmentExecutor.shutdownNow(); + Thread.currentThread().interrupt(); + } + } } \ No newline at end of file diff --git a/backend/src/main/resources/application-prod.yml b/backend/src/main/resources/application-prod.yml index 392b634..f1d1cc7 100644 --- a/backend/src/main/resources/application-prod.yml +++ b/backend/src/main/resources/application-prod.yml @@ -13,12 +13,94 @@ spring: url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}" username: "${DB_MASTER_USERNAME:QGC_REFA}" password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}" + initial-size: 5 + min-idle: 5 + max-active: 20 + max-wait: 30000 + async-init: true + keep-alive-between-time-millis: 120000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 180000 + max-evictable-idle-time-millis: 300000 + phy-timeout-millis: 25200000 + validation-query: SELECT 1 FROM DUAL + validation-query-timeout: 3 + test-while-idle: true + test-on-borrow: false + test-on-return: false + keep-alive: true + remove-abandoned: true + remove-abandoned-timeout: 1800 + log-abandoned: true + break-after-acquire-failure: true + time-between-connect-error-millis: 300000 + pool-prepared-statements: true + max-open-prepared-statements: 100 + max-pool-prepared-statement-per-connection-size: 100 + connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 slave: driverClassName: oracle.jdbc.OracleDriver url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}" username: "${DB_SLAVE_USERNAME:QGC_REFA}" password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}" - + initial-size: 5 + min-idle: 5 + max-active: 20 + max-wait: 30000 + async-init: true + keep-alive-between-time-millis: 120000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 180000 + max-evictable-idle-time-millis: 300000 + phy-timeout-millis: 25200000 + validation-query: SELECT 1 FROM DUAL + validation-query-timeout: 3 + test-while-idle: true + test-on-borrow: false + test-on-return: false + keep-alive: true + remove-abandoned: true + remove-abandoned-timeout: 1800 + log-abandoned: true + break-after-acquire-failure: true + time-between-connect-error-millis: 300000 + pool-prepared-statements: true + max-open-prepared-statements: 100 + max-pool-prepared-statement-per-connection-size: 100 + connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 + filter: + stat: + enabled: true + log-slow-sql: true + slow-sql-millis: 3000 + merge-sql: true + slf4j: + enabled: true + wall: + enabled: true + log-violation: true + throw-exception: true + config: + select-where-alway-true-check: true + select-having-alway-true-check: true + delete-where-alway-true-check: true + update-where-alay-true-check: true + update-where-alway-true-check: true + update-where-none-check: true + multi-statement-allow: false + web-stat-filter: + enabled: true + url-pattern: /* + exclusions: '*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*' + session-stat-enable: true + principal-session-name: admin + profile-enable: true + stat-view-servlet: + enabled: true + url-pattern: /druid/* + login-username: admin + login-password: admin + reset-enable: false jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8