fix: 修复异步导入方法的阻塞调用问题

## 问题描述
Controller层使用了future.get()阻塞调用,导致异步导入失去意义

## 修复内容
1. 修改ICcdiEmployeeService接口:将返回类型从CompletableFuture<ImportResultVO>改为String
2. 修改CcdiEmployeeServiceImpl:importEmployeeAsync方法立即返回taskId
3. 修改CcdiEmployeeController:移除future.get()调用,直接使用返回的taskId
4. 移除不需要的CompletableFuture导入

## 技术细节
- Service方法保持@Async注解,在独立线程池中执行
- Controller立即返回taskId给前端,不等待导入完成
- 前端可通过/importStatus/{taskId}接口查询导入进度

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
wkc
2026-02-06 09:46:27 +08:00
parent d709183561
commit db46521c8b
3 changed files with 14 additions and 24 deletions

View File

@@ -28,7 +28,6 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* 员工信息Controller
@@ -137,11 +136,14 @@ public class CcdiEmployeeController extends BaseController {
return error("至少需要一条数据");
}
// 异步导入
CompletableFuture<ImportResultVO> future = employeeService.importEmployeeAsync(list, updateSupport);
// 异步导入,立即返回taskId
String taskId = employeeService.importEmployeeAsync(list, updateSupport);
// 立即返回taskId
ImportResultVO result = future.get();
// 构建返回结果
ImportResultVO result = new ImportResultVO();
result.setTaskId(taskId);
result.setStatus("PROCESSING");
result.setMessage("导入任务已提交,正在后台处理");
return success("导入任务已提交,正在后台处理", result);
}

View File

@@ -11,7 +11,6 @@ import com.ruoyi.ccdi.domain.vo.ImportResultVO;
import com.ruoyi.ccdi.domain.vo.ImportStatusVO;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* 员工信息 服务层
@@ -92,9 +91,9 @@ public interface ICcdiEmployeeService {
*
* @param excelList Excel数据列表
* @param isUpdateSupport 是否更新已存在的数据
* @return CompletableFuture包含导入结果
* @return 任务ID
*/
CompletableFuture<ImportResultVO> importEmployeeAsync(List<CcdiEmployeeExcel> excelList, Boolean isUpdateSupport);
String importEmployeeAsync(List<CcdiEmployeeExcel> excelList, Boolean isUpdateSupport);
/**
* 查询导入状态

View File

@@ -25,7 +25,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -232,12 +231,12 @@ public class CcdiEmployeeServiceImpl implements ICcdiEmployeeService {
*
* @param excelList Excel数据列表
* @param isUpdateSupport 是否更新已存在的数据
* @return CompletableFuture包含导入结果
* @return 任务ID
*/
@Override
@Async("importExecutor")
@Transactional
public CompletableFuture<ImportResultVO> importEmployeeAsync(List<CcdiEmployeeExcel> excelList, Boolean isUpdateSupport) {
public String importEmployeeAsync(List<CcdiEmployeeExcel> excelList, Boolean isUpdateSupport) {
String taskId = UUID.randomUUID().toString();
long startTime = System.currentTimeMillis();
@@ -264,12 +263,6 @@ public class CcdiEmployeeServiceImpl implements ICcdiEmployeeService {
String finalStatus = result.getFailureCount() == 0 ? "SUCCESS" : "PARTIAL_SUCCESS";
updateImportStatus(taskId, finalStatus, result, startTime);
ImportResultVO resultVO = new ImportResultVO();
resultVO.setTaskId(taskId);
resultVO.setStatus(finalStatus);
resultVO.setMessage("导入任务已提交");
return CompletableFuture.completedFuture(resultVO);
} catch (Exception e) {
// 处理异常
Map<String, Object> errorData = new HashMap<>();
@@ -277,14 +270,10 @@ public class CcdiEmployeeServiceImpl implements ICcdiEmployeeService {
errorData.put("message", "导入失败: " + e.getMessage());
errorData.put("endTime", System.currentTimeMillis());
redisTemplate.opsForHash().putAll(statusKey, errorData);
ImportResultVO resultVO = new ImportResultVO();
resultVO.setTaskId(taskId);
resultVO.setStatus("FAILED");
resultVO.setMessage("导入失败: " + e.getMessage());
return CompletableFuture.completedFuture(resultVO);
}
// 立即返回taskId,让调用者可以查询状态
return taskId;
}
/**