zqy
2 天以前 28cf0afe5cb951bf34a60a1ee0f36d38c592a8c0
zhang-content/src/main/java/com/ruoyi/service/impl/InterfaceBasedSearchRouter.java
@@ -2,16 +2,19 @@
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.domain.ModuleSearchResult;
import com.ruoyi.service.ModuleSearchable;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -20,6 +23,7 @@
public class InterfaceBasedSearchRouter {
    private final Map<String, ModuleSearchable> moduleSearchMap;
    /**
     * 自动收集所有实现ModuleSearchable接口的Bean
@@ -39,6 +43,21 @@
        log.info("已注册搜索模块: {}", moduleSearchMap.keySet());
    }
    @Async // 声明此方法异步执行,将使用我们上面配置的Executor
    public CompletableFuture<ModuleSearchResult> searchModuleAsync(String moduleCode, ModuleSearchable service, String companion, Date startTime, Date endTime) {
        // 将原来在lambda表达式中的搜索逻辑移到这里
        long start = System.currentTimeMillis();
        try {
            List<?> data = service.search(companion, startTime, endTime);
            long searchTime = System.currentTimeMillis() - start;
            ModuleSearchResult result = ModuleSearchResult.success(moduleCode, service.getModuleName(), data, data.size(), searchTime);
            return CompletableFuture.completedFuture(result);
        } catch (Exception e) {
            log.error("模块[{}]搜索失败: {}", moduleCode, e.getMessage());
            ModuleSearchResult result = ModuleSearchResult.error(moduleCode, e.getMessage());
            return CompletableFuture.completedFuture(result);
        }
    }
    /**
     * 通用的路由搜索请求(支持不同参数类型)
     */
@@ -48,6 +67,12 @@
    public AjaxResult routeSearch(String moduleCode, Object... args) {
        log.info("路由搜索: moduleCode={}, args={}", moduleCode, Arrays.toString(args));
        // 全模块搜索:当moduleCode为空或特定标识时
        if (moduleCode == null || moduleCode.isEmpty() || "all".equalsIgnoreCase(moduleCode)) {
            return searchAllModules(args);
        }
        // 单个模块搜索(原有逻辑)
        ModuleSearchable searchService = moduleSearchMap.get(moduleCode);
        if (searchService == null) {
            String availableModules = String.join(", ", moduleSearchMap.keySet());
@@ -55,7 +80,6 @@
        }
        try {
            // 根据参数数量进行路由
            if (args.length == 3) {
                return handleFourArgs(searchService, args);
            } else {
@@ -67,9 +91,6 @@
        }
    }
    /**
     * 处理3个参数的情况(companion + happenStartTime + happenEndTime)
     */
    private AjaxResult handleFourArgs(ModuleSearchable searchService, Object[] args) {
        String companion = null;
        Date happenStartTime = null;
@@ -108,6 +129,98 @@
        return AjaxResult.success("搜索成功", result);
    }
    /**
     * 全模块搜索:获取所有模块的数据并分类
     */
    private AjaxResult searchAllModules(Object[] args) {
        log.info("执行全模块搜索,参数数量: {}", args.length);
        try {
            Map<String, Object> result = new LinkedHashMap<>();
            int totalCount = 0;
            int successCount = 0;
            // 处理搜索参数
            String companion = extractCompanion(args);
            Date happenStartTime = extractStartTime(args);
            Date happenEndTime = extractEndTime(args);
            System.out.println("全模块搜索 ------ 同伴: " + companion);
            System.out.println("全模块搜索 ------ 开始时间: " + happenStartTime);
            System.out.println("全模块搜索 ------ 结束时间: " + happenEndTime);
            // 并行处理所有模块搜索(提高性能)
            List<CompletableFuture<ModuleSearchResult>> futures = moduleSearchMap.entrySet().stream().map(entry ->
                searchModuleAsync(entry.getKey(),
                    entry.getValue(), companion,
                    happenStartTime, happenEndTime))
                .collect(Collectors.toList());
            // 等待所有搜索完成
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
            // 收集结果
            for (CompletableFuture<ModuleSearchResult> future : futures) {
                ModuleSearchResult moduleResult = future.get();
                if (moduleResult.isSuccess()) {
                    // 创建一个可变的HashMap并填入数据
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("data", moduleResult.getData());
                    resultMap.put("count", moduleResult.getCount());
                    resultMap.put("searchTime", moduleResult.getSearchTime());
                    // 将构建好的Map放入最终结果中
                    result.put(moduleResult.getModuleCode(), resultMap);
                    successCount++;
                    totalCount += moduleResult.getCount();
                } else {
                    Map<String, Object> errorInfo = new HashMap<>();
                    errorInfo.put("error", moduleResult.getErrorMessage());
                    errorInfo.put("success", false);
                    result.put(moduleResult.getModuleCode(), errorInfo);
                }
            }
            // 构建返回结果
            Map<String, Object> finalResult = new LinkedHashMap<>();
            finalResult.put("totalModules", moduleSearchMap.size());
            finalResult.put("successModules", successCount);
            finalResult.put("totalRecords", totalCount);
            finalResult.put("searchTime", new Date());
            finalResult.put("modules", result);
            log.info("全模块搜索完成: 成功{}/{}个模块,总计{}条记录",
                successCount, moduleSearchMap.size(), totalCount);
            return AjaxResult.success("全模块搜索成功", finalResult);
        } catch (Exception e) {
            log.error("全模块搜索执行失败", e);
            return AjaxResult.error("全模块搜索失败: " + e.getMessage());
        }
    }
    /**
     * 单个模块搜索包装方法
     */
    private ModuleSearchResult searchSingleModule(String moduleCode, ModuleSearchable service,
                                                  String companion, Date startTime, Date endTime) {
        long start = System.currentTimeMillis();
        try {
            List<?> data = service.search(companion, startTime, endTime);
            long searchTime = System.currentTimeMillis() - start;
            return ModuleSearchResult.success(moduleCode, service.getModuleName(),
                data, data.size(), searchTime);
        } catch (Exception e) {
            log.error("模块[{}]搜索失败: {}", moduleCode, e.getMessage());
            return ModuleSearchResult.error(moduleCode, e.getMessage());
        }
    }
//
//    /**
//     * 获取所有可搜索的模块信息
@@ -122,16 +235,22 @@
//    }
    /**
     * 检查模块是否支持搜索
     * 参数提取辅助方法
     */
    public boolean supports(String moduleCode) {
        return moduleSearchMap.containsKey(moduleCode);
    private String extractCompanion(Object[] args) {
        if (args.length > 0 && args[0] instanceof String) {
            return (String) args[0];
        } else if (args.length > 0 && args[0] != null) {
            return args[0].toString();
        }
        return null;
    }
    /**
     * 获取模块服务实例
     */
    public ModuleSearchable getModuleService(String moduleCode) {
        return moduleSearchMap.get(moduleCode);
    private Date extractStartTime(Object[] args) {
        return (args.length > 1 && args[1] instanceof Date) ? (Date) args[1] : null;
    }
    private Date extractEndTime(Object[] args) {
        return (args.length > 2 && args[2] instanceof Date) ? (Date) args[2] : null;
    }
}