From e544b76db633b0d56deb2b9270b680286cc3e038 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=A7=A6=E9=B8=BF=E5=B1=95?= <18031053041@163.com>
Date: Sat, 25 Jul 2026 10:05:12 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=85=A5=E7=89=A9=E6=96=99BUG?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../MaterialBaseInfoApplicationService.java | 214 ++----------------
1 file changed, 14 insertions(+), 200 deletions(-)
diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java
index b78ffebcd..56f2c7319 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java
@@ -103,6 +103,10 @@ public class MaterialBaseInfoApplicationService {
@Resource
private MaterialBaseInfoMapper materialBaseInfoMapper;
+
+ @Autowired
+ private MaterialBaseInfoAsyncService materialBaseInfoAsyncService;
+
/**
* 分页查询物料基础信息列表
*/
@@ -472,202 +476,12 @@ public class MaterialBaseInfoApplicationService {
}
LoginUser loginUser = SecurityUtils.getLoginUser();
- // 异步执行导入
- doImportData(tmpFile, fileName, loginUser);
+ // 通过独立的异步 Service 执行导入(避免类内部 self-invocation 导致 @Async 失效)
+ materialBaseInfoAsyncService.doImportData(tmpFile, fileName, loginUser);
return AjaxResult.success("导入任务已提交,正在后台异步处理,请稍后查看导入结果日志");
}
- /**
- * 异步执行物料主数据导入
- *
- *
@Async 确保在独立线程中执行,不阻塞接口响应。
- * 每行独立事务,避免大事务锁表导致性能问题。
- */
- @Async
- public void doImportData(File tmpFile, String fileName, LoginUser loginUser) {
- long startTime = System.currentTimeMillis();
- log.info("=== 物料主数据异步导入开始,文件:{},大小:{}KB ===", fileName, tmpFile.length() / 1024);
- try {
- List rows;
- try (InputStream is = new java.io.FileInputStream(tmpFile)) {
- rows = MaterialBaseInfoImportExcelUtil.importRows(is);
- } catch (Exception e) {
- log.error("物料主数据异步导入失败 - 文件解析异常:{}", e.getMessage(), e);
- return;
- }
-
- if (CollectionUtils.isEmpty(rows)) {
- log.warn("物料主数据异步导入结束 - 导入数据为空");
- return;
- }
-
- Long loginOrgId = null;
- Long loginTopOrgId = null;
- if (loginUser != null && loginUser.getUserPo() != null) {
- loginOrgId = loginUser.getUserPo().getOrganizationId();
- loginTopOrgId = loginUser.getUserPo().getTopOrganizationId();
- }
-
- StringBuilder errors = new StringBuilder();
- Set duplicateInFile = new HashSet<>();
- int successCount = 0;
- int totalCount = rows.size();
-
- // 包装规格缓存:避免 5000 行数据对 system 服务发起 5000 次重复远程调用
- Map> packCache = new HashMap<>();
-
- for (int i = 0; i < rows.size(); i++) {
- MaterialBaseInfoDTO row = rows.get(i);
- int rowNum = i + 2;
- if (row == null) {
- continue;
- }
- try {
- if (StringUtils.isBlank(row.getMaterialCode())) {
- errors.append("第").append(rowNum).append("行:物料编码不能为空;");
- continue;
- }
- if (StringUtils.isBlank(row.getMaterialName())) {
- errors.append("第").append(rowNum).append("行:物料名称不能为空;");
- continue;
- }
- if (row.getNullify() == null) {
- row.setNullify(2);
- }
- if (row.getCommon() == null) {
- row.setCommon(2);
- }
- if (StringUtils.isBlank(row.getHsCode()) && StringUtils.isNotBlank(row.getHsCodeImport())) {
- row.setHsCode(row.getHsCodeImport().trim());
- }
- normalizeImportBarCodeWhenDuplicateOfHs(row);
- fillIdsFromExistingMasterData(row);
- fillOrganizationFromShipperIfNeeded(row);
- if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(loginOrgId)) {
- row.setOrganizationId(loginOrgId);
- }
- if (row.getTopOrganizationId() == null && isValidOrgId(loginTopOrgId)) {
- row.setTopOrganizationId(loginTopOrgId);
- }
- fillOrganizationName(row, loginUser);
-
- String shipperCode = StringUtils.defaultString(row.getShipperCode(), "");
- String duplicateKey = row.getOrganizationId() + "|" + shipperCode + "|" + row.getMaterialCode();
- if (!duplicateInFile.add(duplicateKey)) {
- errors.append("第").append(rowNum).append("行:文件内存在重复物料(组织+货主编码+物料编码);");
- continue;
- }
-
- LambdaQueryWrapper wrapper = new LambdaQueryWrapper()
- .eq(MaterialBaseInfo::getDelFlag, 1)
- .eq(MaterialBaseInfo::getOrganizationId, row.getOrganizationId())
- .eq(MaterialBaseInfo::getMaterialCode, row.getMaterialCode());
- if (StringUtils.isBlank(row.getShipperCode())) {
- wrapper.and(w -> w.isNull(MaterialBaseInfo::getShipperCode).or().eq(MaterialBaseInfo::getShipperCode, ""));
- } else {
- wrapper.eq(MaterialBaseInfo::getShipperCode, row.getShipperCode());
- }
- if (materialBaseInfoService.count(wrapper) > 0) {
- errors.append("第").append(rowNum).append("行:物料已存在(组织+货主编码+物料编码);");
- continue;
- }
- fillClassifyTypeAndUnit(row);
-
- // 包装规格查询(带本地缓存,避免 5000 行对 system 服务发起 5000 次远程调用)
- String packCacheKey = row.getOrganizationId() + "|" + StringUtils.defaultString(row.getPackName());
- Map cachedPack = packCache.get(packCacheKey);
- if (cachedPack == null) {
- Object result = systemServiceFeign.getPackList(null, row.getPackName(), row.getOrganizationId());
- if (result == null) {
- // 缓存空结果,避免重复查询不存在的包装规格
- packCache.put(packCacheKey, Collections.emptyMap());
- errors.append("第").append(rowNum).append("行:包装规格查询无返回,请稍后重试或检查系统服务;");
- continue;
- }
- Map resultMap = JSON.parseObject(JSONObject.toJSONString(result), new TypeReference