From b10524103480a6834a2e8d5662f009c745143cc4 Mon Sep 17 00:00:00 2001
From: zqy <2522236926@qq.com>
Date: 星期五, 26 十二月 2025 09:22:31 +0800
Subject: [PATCH] 个人信息 修改时 新增一个最新更新时间
---
zhang-content/src/main/java/com/ruoyi/service/impl/InterfaceBasedSearchRouter.java | 397 +++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 321 insertions(+), 76 deletions(-)
diff --git a/zhang-content/src/main/java/com/ruoyi/service/impl/InterfaceBasedSearchRouter.java b/zhang-content/src/main/java/com/ruoyi/service/impl/InterfaceBasedSearchRouter.java
index b4ffc53..d6d25ed 100644
--- a/zhang-content/src/main/java/com/ruoyi/service/impl/InterfaceBasedSearchRouter.java
+++ b/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.apache.commons.lang3.StringUtils;
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,12 @@
public class InterfaceBasedSearchRouter {
private final Map<String, ModuleSearchable> moduleSearchMap;
+
+ // 妯″潡鍒嗗壊绗�
+ private static final String MODULE_SEPARATOR = ",";
+
+ // 鍏ㄦā鍧楁爣璇�
+ private static final String ALL_MODULES_FLAG = "all";
/**
* 鑷姩鏀堕泦鎵�鏈夊疄鐜癕oduleSearchable鎺ュ彛鐨凚ean
@@ -39,99 +48,335 @@
log.info("宸叉敞鍐屾悳绱㈡ā鍧�: {}", moduleSearchMap.keySet());
}
+ @Async
+ public CompletableFuture<ModuleSearchResult> searchModuleAsync(String moduleCode, ModuleSearchable service,
+ String companion, Date startTime, Date endTime,String hasAttachment) {
+ long start = System.currentTimeMillis();
+ try {
+ List<?> data = service.search(companion, startTime, endTime,hasAttachment);
+ 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);
+ }
+ }
+
/**
- * 閫氱敤鐨勮矾鐢辨悳绱㈣姹傦紙鏀寔涓嶅悓鍙傛暟绫诲瀷锛�
- */
- /**
- * 閫氱敤鐨勮矾鐢辨悳绱㈣姹�
+ * 閫氱敤鐨勮矾鐢辨悳绱㈣姹� - 缁熶竴鏁版嵁缁撴瀯鐗�
+ * 鏀寔鍔熻兘锛�
+ * 1. 鍗曚釜妯″潡锛� "module1"
+ * 2. 澶氫釜妯″潡锛� "module1,module2,module3" 锛堥�楀彿鍒嗛殧锛�
+ * 3. 鍏ㄦā鍧楋細 "all" 鎴� null 鎴� 绌哄瓧绗︿覆
+ * 4. 涓嶉�夋ā鍧楋細 鎸囧畾涓虹壒瀹氬�硷紝濡�"none"锛堝彲閫夊姛鑳斤級
+ *
+ * 缁熶竴杩斿洖鏁版嵁缁撴瀯锛�
+ * {
+ * "success": true,
+ * "data": {
+ * "modules": {
+ * "module1": { "data": [...], "count": 10, "searchTime": 100, "success": true },
+ * "module2": { "error": "閿欒淇℃伅", "success": false }
+ * },
+ * "totalSelectedModules": 2,
+ * "successModules": 1,
+ * "errorModules": ["module2"],
+ * "totalRecords": 10,
+ * "searchTime": "2023-01-01T00:00:00.000+00:00",
+ * "message": "鎼滅储瀹屾垚: 鎴愬姛1/2涓ā鍧楋紝鎬昏10鏉¤褰�"
+ * }
+ * }
*/
public AjaxResult routeSearch(String moduleCode, Object... args) {
log.info("璺敱鎼滅储: moduleCode={}, args={}", moduleCode, Arrays.toString(args));
- ModuleSearchable searchService = moduleSearchMap.get(moduleCode);
- if (searchService == null) {
+ // 楠岃瘉鍙傛暟鏁伴噺
+ if (args.length != 4) {
+ return buildErrorResponse("鍙傛暟鏁伴噺閿欒锛岄渶瑕�4涓弬鏁帮紝瀹為檯鏀跺埌: " + args.length, null);
+ }
+
+ // 瑙f瀽妯″潡浠g爜
+ List<String> targetModules = parseModuleCodes(moduleCode);
+
+ if (targetModules.isEmpty()) {
+ // 涓嶉�夋ā鍧楃殑鎯呭喌
+ return handleNoModuleSelected();
+ }
+
+ // 缁熶竴澶勭悊锛氬崟涓ā鍧椼�佸涓ā鍧楅兘浣跨敤鍚屾牱鐨勫鐞嗛�昏緫
+ return executeModulesSearch(targetModules, args);
+ }
+
+ /**
+ * 缁熶竴鎵ц妯″潡鎼滅储
+ * 鏃犺鏄崟涓ā鍧楄繕鏄涓ā鍧楋紝閮戒娇鐢ㄧ粺涓�鐨勬暟鎹粨鏋勮繑鍥�
+ */
+ private AjaxResult executeModulesSearch(List<String> moduleCodes, Object... args) {
+ log.info("鎵ц妯″潡鎼滅储: moduleCodes={}, 妯″潡鏁伴噺={}", moduleCodes, moduleCodes.size());
+
+ // 楠岃瘉鎵�鏈夋ā鍧楁槸鍚﹀瓨鍦�
+ List<String> invalidModules = moduleCodes.stream()
+ .filter(code -> !moduleSearchMap.containsKey(code))
+ .collect(Collectors.toList());
+
+ if (!invalidModules.isEmpty()) {
String availableModules = String.join(", ", moduleSearchMap.keySet());
- return AjaxResult.error("涓嶆敮鎸佺殑鎼滅储妯″潡: " + moduleCode + "銆傚彲鐢ㄦā鍧�: [" + availableModules + "]");
+ String errorMsg = String.format("浠ヤ笅妯″潡涓嶆敮鎸�: %s銆傚彲鐢ㄦā鍧�: [%s]",
+ invalidModules, availableModules);
+ return buildErrorResponse(errorMsg, moduleCodes);
}
- try {
- // 鏍规嵁鍙傛暟鏁伴噺杩涜璺敱
- if (args.length == 3) {
- return handleFourArgs(searchService, args);
- } else {
- return AjaxResult.error("涓嶆敮鎸佺殑鍙傛暟鏁伴噺锛岄渶瑕�3涓弬鏁帮紝瀹為檯鏀跺埌: " + args.length);
+ // 鎻愬彇鎼滅储鍙傛暟
+ String companion = extractCompanion(args);
+ Date happenStartTime = extractStartTime(args);
+ Date happenEndTime = extractEndTime(args);
+ String hasAttachment = extractHasAttachment(args);
+
+ // 寮傛骞惰鎼滅储
+ List<CompletableFuture<ModuleSearchResult>> futures = moduleCodes.stream()
+ .map(code -> searchModuleAsync(code, moduleSearchMap.get(code),
+ companion, happenStartTime, happenEndTime,hasAttachment))
+ .collect(Collectors.toList());
+
+ // 绛夊緟鎵�鏈夋悳绱㈠畬鎴�
+ CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
+
+ // 鏀堕泦缁撴灉
+ Map<String, Object> modulesResult = new LinkedHashMap<>();
+ int successCount = 0;
+ int totalCount = 0;
+ List<String> errorModules = new ArrayList<>();
+
+ for (int i = 0; i < futures.size(); i++) {
+ try {
+ ModuleSearchResult moduleResult = futures.get(i).get();
+ String moduleCode = moduleCodes.get(i);
+
+ if (moduleResult.isSuccess()) {
+ Map<String, Object> moduleData = new HashMap<>();
+ moduleData.put("data", moduleResult.getData());
+ moduleData.put("count", moduleResult.getCount());
+ moduleData.put("searchTime", moduleResult.getSearchTime());
+ moduleData.put("success", true);
+
+ modulesResult.put(moduleCode, moduleData);
+
+ successCount++;
+ totalCount += moduleResult.getCount();
+ } else {
+ Map<String, Object> errorInfo = new HashMap<>();
+ errorInfo.put("error", moduleResult.getErrorMessage());
+ errorInfo.put("success", false);
+ errorInfo.put("moduleName", getModuleName(moduleCode));
+ modulesResult.put(moduleCode, errorInfo);
+ errorModules.add(moduleCode);
+ }
+ } catch (Exception e) {
+ log.error("鑾峰彇妯″潡[{}]鎼滅储缁撴灉澶辫触", moduleCodes.get(i), e);
+ String moduleCode = moduleCodes.get(i);
+ Map<String, Object> errorInfo = new HashMap<>();
+ errorInfo.put("error", "鑾峰彇缁撴灉寮傚父: " + e.getMessage());
+ errorInfo.put("success", false);
+ errorInfo.put("moduleName", getModuleName(moduleCode));
+ modulesResult.put(moduleCode, errorInfo);
+ errorModules.add(moduleCode);
}
- } catch (Exception e) {
- log.error("鎼滅储鎵ц澶辫触: moduleCode={}", moduleCode, e);
- return AjaxResult.error("鎼滅储鎵ц澶辫触: " + e.getMessage());
}
+
+ // 鏋勫缓鏈�缁堣繑鍥炵粨鏋�
+ Map<String, Object> finalResult = new LinkedHashMap<>();
+ finalResult.put("modules", modulesResult);
+ finalResult.put("totalSelectedModules", moduleCodes.size());
+ finalResult.put("successModules", successCount);
+ finalResult.put("errorModules", errorModules);
+ finalResult.put("totalRecords", totalCount);
+ finalResult.put("searchTime", new Date());
+
+ // 鏋勫缓娑堟伅
+ String message = buildSuccessMessage(moduleCodes.size(), successCount, errorModules, totalCount);
+ finalResult.put("message", message);
+
+ return AjaxResult.success(message, finalResult);
}
/**
- * 澶勭悊3涓弬鏁扮殑鎯呭喌锛坈ompanion + happenStartTime + happenEndTime锛�
+ * 鑾峰彇妯″潡鍚嶇О
*/
- private AjaxResult handleFourArgs(ModuleSearchable searchService, Object[] args) {
- String companion = null;
- Date happenStartTime = null;
- Date happenEndTime = null;
+ private String getModuleName(String moduleCode) {
+ ModuleSearchable service = moduleSearchMap.get(moduleCode);
+ return service != null ? service.getModuleName() : "鏈煡妯″潡";
+ }
- // 澶勭悊companion鍙傛暟
- if (args[0] instanceof String) {
- companion = (String) args[0];
- } else if (args[0] != null) {
- companion = args[0].toString();
- }
-
- // 澶勭悊鏃堕棿鍙傛暟
- if (args[1] instanceof Date) {
- happenStartTime = (Date) args[1];
- }
-
- if (args[2] instanceof Date) {
- happenEndTime = (Date) args[2];
- }
-
- // 鍒ゆ柇鎼滅储绫诲瀷
- boolean hasTimeRange = happenStartTime != null && happenEndTime != null;
-
- List<?> result;
- if (hasTimeRange) {
- // 鏈夋椂闂磋寖鍥达細鎵ц鏃堕棿鑼冨洿鎼滅储
- log.info("鎵ц鏃堕棿鑼冨洿鎼滅储: companion={}, startTime={}, endTime={}",
- companion, happenStartTime, happenEndTime);
- result = searchService.search(companion, happenStartTime, happenEndTime);
+ /**
+ * 鏋勫缓鎴愬姛娑堟伅
+ */
+ private String buildSuccessMessage(int totalSelected, int successCount,
+ List<String> errorModules, int totalRecords) {
+ if (errorModules.isEmpty()) {
+ if (totalSelected == 1) {
+ return String.format("鎼滅储鎴愬姛: 鎵惧埌%s鏉¤褰�", totalRecords);
+ } else {
+ return String.format("鎼滅储瀹屾垚: 鎴愬姛%s/%s涓ā鍧楋紝鎬昏%s鏉¤褰�",
+ successCount, totalSelected, totalRecords);
+ }
} else {
- // 鏃犳椂闂磋寖鍥达細鍙寜companion鎼滅储
- log.info("鎵цcompanion鎼滅储: companion={}, 鏃堕棿鑼冨洿涓虹┖", companion);
- result = searchService.search(companion, null, null);
+ return String.format("鎼滅储瀹屾垚: 鎴愬姛%s/%s涓ā鍧楋紝鎬昏%s鏉¤褰曪紝澶辫触妯″潡: %s",
+ successCount, totalSelected, totalRecords, errorModules);
+ }
+ }
+
+ /**
+ * 鏋勫缓閿欒鍝嶅簲
+ */
+ private AjaxResult buildErrorResponse(String errorMessage, List<String> moduleCodes) {
+ Map<String, Object> errorData = new HashMap<>();
+ errorData.put("message", errorMessage);
+ errorData.put("success", false);
+
+ if (moduleCodes != null) {
+ errorData.put("selectedModules", moduleCodes);
}
- return AjaxResult.success("鎼滅储鎴愬姛", result);
- }
-//
-// /**
-// * 鑾峰彇鎵�鏈夊彲鎼滅储鐨勬ā鍧椾俊鎭�
-// */
-// public List<SysMenu> getAvailableModules() {
-// return moduleSearchMap.values().stream()
-// .map(service -> SysMenu.builder()
-// .moduleCode(service.getModuleCode())
-// .moduleName(service.getModuleName())
-// .build())
-// .collect(Collectors.toList());
-// }
+ errorData.put("totalSelectedModules", moduleCodes != null ? moduleCodes.size() : 0);
+ errorData.put("successModules", 0);
+ errorData.put("errorModules", moduleCodes != null ? moduleCodes : Collections.emptyList());
+ errorData.put("totalRecords", 0);
+ errorData.put("searchTime", new Date());
- /**
- * 妫�鏌ユā鍧楁槸鍚︽敮鎸佹悳绱�
- */
- public boolean supports(String moduleCode) {
- return moduleSearchMap.containsKey(moduleCode);
+ return AjaxResult.error(errorMessage, errorData);
}
/**
- * 鑾峰彇妯″潡鏈嶅姟瀹炰緥
+ * 瑙f瀽妯″潡浠g爜
+ * 鏀寔澶氱鏍煎紡锛�
+ * 1. 绌�/绌虹櫧/null -> 鍏ㄦā鍧楁悳绱�
+ * 2. "all" -> 鍏ㄦā鍧楁悳绱�
+ * 3. 鍗曚釜妯″潡 -> 杩斿洖鍗曚釜妯″潡
+ * 4. 閫楀彿鍒嗛殧鐨勫涓ā鍧� -> 杩斿洖妯″潡鍒楄〃
+ * 5. 鍏朵粬鐗规畩鏍囪瘑锛堝"none"锛�-> 杩斿洖绌哄垪琛ㄨ〃绀轰笉閫夋ā鍧�
*/
- public ModuleSearchable getModuleService(String moduleCode) {
- return moduleSearchMap.get(moduleCode);
+ private List<String> parseModuleCodes(String moduleCode) {
+ if (StringUtils.isBlank(moduleCode)) {
+ // 绌�/绌虹櫧/null -> 鍏ㄦā鍧楁悳绱�
+ return new ArrayList<>(moduleSearchMap.keySet());
+ }
+
+ String trimmedCode = moduleCode.trim();
+
+ // 澶勭悊鍏ㄦā鍧楁爣璇�
+ if (ALL_MODULES_FLAG.equalsIgnoreCase(trimmedCode)) {
+ return new ArrayList<>(moduleSearchMap.keySet());
+ }
+
+ // 澶勭悊涓嶉�夋ā鍧楃殑鎯呭喌锛堝彲閫夋墿灞曪級
+ if ("none".equalsIgnoreCase(trimmedCode) || "null".equalsIgnoreCase(trimmedCode)) {
+ return Collections.emptyList();
+ }
+
+ // 妫�鏌ユ槸鍚﹀寘鍚�楀彿锛堝涓ā鍧楋級
+ if (trimmedCode.contains(MODULE_SEPARATOR)) {
+ String[] moduleArray = trimmedCode.split(MODULE_SEPARATOR);
+ return Arrays.stream(moduleArray)
+ .map(String::trim)
+ .filter(code -> !code.isEmpty())
+ .collect(Collectors.toList());
+ }
+
+ // 鍗曚釜妯″潡
+ return Collections.singletonList(trimmedCode);
}
+
+ /**
+ * 涓嶉�夋ā鍧楃殑澶勭悊閫昏緫 - 浣跨敤缁熶竴鏁版嵁缁撴瀯
+ */
+ private AjaxResult handleNoModuleSelected() {
+ Map<String, Object> result = new LinkedHashMap<>();
+ result.put("modules", Collections.emptyMap());
+ result.put("totalSelectedModules", 0);
+ result.put("successModules", 0);
+ result.put("errorModules", Collections.emptyList());
+ result.put("totalRecords", 0);
+ result.put("searchTime", new Date());
+ result.put("message", "鏈�夋嫨鎼滅储妯″潡");
+ result.put("availableModules", new ArrayList<>(moduleSearchMap.keySet()));
+
+ return AjaxResult.success("鏈�夋嫨鎼滅储妯″潡锛岃閫夋嫨瑕佹悳绱㈢殑妯″潡", result);
+ }
+
+ /**
+ * 鑾峰彇鍙敤妯″潡鍒楄〃
+ */
+ public AjaxResult getAvailableModules() {
+ Map<String, Object> result = new HashMap<>();
+
+ List<Map<String, Object>> modules = moduleSearchMap.values().stream()
+ .map(service -> {
+ Map<String, Object> moduleInfo = new HashMap<>();
+ moduleInfo.put("moduleCode", service.getModuleCode());
+ moduleInfo.put("moduleName", service.getModuleName());
+ return moduleInfo;
+ })
+ .collect(Collectors.toList());
+
+ result.put("modules", modules);
+ result.put("total", modules.size());
+
+ return AjaxResult.success("鑾峰彇鍙敤妯″潡鎴愬姛", result);
+ }
+
+ /**
+ * 楠岃瘉妯″潡浠g爜鏄惁瀛樺湪
+ */
+ public boolean validateModule(String moduleCode) {
+ if (StringUtils.isBlank(moduleCode)) {
+ return false;
+ }
+
+ // 澶勭悊澶氫釜妯″潡鐨勬儏鍐�
+ if (moduleCode.contains(MODULE_SEPARATOR)) {
+ String[] moduleArray = moduleCode.split(MODULE_SEPARATOR);
+ for (String code : moduleArray) {
+ String trimmedCode = code.trim();
+ if (!moduleSearchMap.containsKey(trimmedCode) &&
+ !ALL_MODULES_FLAG.equalsIgnoreCase(trimmedCode)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // 鍗曚釜妯″潡鐨勬儏鍐�
+ String trimmedCode = moduleCode.trim();
+ return moduleSearchMap.containsKey(trimmedCode) ||
+ ALL_MODULES_FLAG.equalsIgnoreCase(trimmedCode);
+ }
+
+ /**
+ * 鍙傛暟鎻愬彇杈呭姪鏂规硶
+ */
+ 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;
+ }
+
+ 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;
+ }
+
+ private String extractHasAttachment(Object[] args) {
+ return (args.length > 3 && args[3] instanceof String) ? (String) args[3] : null;
+
+}
}
--
Gitblit v1.9.1