From c8668a4a71987199e610781e7ac8cc02faa4f082 Mon Sep 17 00:00:00 2001
From: feige <feige@qq.com>
Date: 星期二, 16 十二月 2025 22:12:16 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/zhang/EsSearchController.java   |   47 ++++
 zhang-content/src/main/java/com/ruoyi/service/impl/ZfEconomyServiceImpl.java       |   67 ++++++
 ruoyi-framework/pom.xml                                                            |    2 
 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/EsModel.java        |   20 +-
 zhang-content/src/main/java/com/ruoyi/domain/ModuleSearchResult.java               |   39 +++
 zhang-content/src/main/java/com/ruoyi/service/ModuleSearchable.java                |   25 ++
 zhang-content/src/main/java/com/ruoyi/service/impl/InterfaceBasedSearchRouter.java |  256 +++++++++++++++++++++++++
 ruoyi-common/src/main/java/com/ruoyi/common/config/AsyncConfig.java                |   23 ++
 zhang-content/src/main/java/com/ruoyi/domain/ZfDoctor.java                         |   26 ++
 zhang-content/src/main/java/com/ruoyi/domain/ZfEconomy.java                        |   17 +
 zhang-content/src/main/java/com/ruoyi/service/impl/ZfDoctorServiceImpl.java        |   45 ++++
 ruoyi-admin/src/main/resources/application.yml                                     |   10 
 12 files changed, 559 insertions(+), 18 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/zhang/EsSearchController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/zhang/EsSearchController.java
index 6826295..31efa74 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/zhang/EsSearchController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/zhang/EsSearchController.java
@@ -3,10 +3,17 @@
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.EsModel;
 import com.ruoyi.service.EsService;
+import com.ruoyi.service.ZfEconomyService;
+import com.ruoyi.service.impl.InterfaceBasedSearchRouter;
+import com.ruoyi.service.impl.ZfEconomyServiceImpl;
+import com.ruoyi.system.service.ISysMenuService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.websocket.server.PathParam;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -21,6 +28,12 @@
 
     @Resource
     EsService esService;
+
+    @Resource
+    InterfaceBasedSearchRouter interfaceBasedSearchRouter;
+
+    @Resource
+    ZfEconomyServiceImpl zfEconomyService;
 
     @GetMapping()
     public AjaxResult search(@PathParam("keyword") String keyword){
@@ -39,4 +52,38 @@
         List<EsModel> modelList = esService.getAll();
         return AjaxResult.success(modelList);
     }
+
+    @GetMapping("/companion/{moduleCode}")
+    public AjaxResult getAllbyCAY( @PathVariable("moduleCode") String moduleCode,@RequestParam(value = "companion", required = false) String companion,
+                                   @RequestParam(value = "happenStartTime", required = false)
+                                   @DateTimeFormat(pattern = "yyyy-MM-dd") Date happenStartTime,
+                                   @RequestParam(value = "happenEndTime", required = false)
+                                       @DateTimeFormat(pattern = "yyyy-MM-dd") Date happenEndTime){
+        System.out.println("[[[[[["+moduleCode);
+        System.out.println("[[[[[["+companion);
+
+
+        System.out.println("[[[[[["+happenStartTime);
+        System.out.println("[[[[[["+happenEndTime);
+        zfEconomyService.clearAllCache();
+    return interfaceBasedSearchRouter.routeSearch(moduleCode,companion,happenStartTime,happenEndTime);
+    }
+    /**
+     * 鏂板鍏ㄦā鍧楁悳绱㈡帴鍙o紙涓嶆寚瀹歮oduleCode锛�
+     */
+    @GetMapping("/companion")
+    public AjaxResult getAllModulesByCompanion(@RequestParam(value = "companion", required = false) String companion,
+                                               @RequestParam(value = "happenStartTime", required = false)
+                                               @DateTimeFormat(pattern = "yyyy-MM-dd") Date happenStartTime,
+                                               @RequestParam(value = "happenEndTime", required = false)
+                                               @DateTimeFormat(pattern = "yyyy-MM-dd") Date happenEndTime) {
+
+        System.out.println("鍏ㄦā鍧楁悳绱� - 鍚屼即: " + companion);
+        System.out.println("鍏ㄦā鍧楁悳绱� - 寮�濮嬫椂闂�: " + happenStartTime);
+        System.out.println("鍏ㄦā鍧楁悳绱� - 缁撴潫鏃堕棿: " + happenEndTime);
+        zfEconomyService.clearAllCache();
+        // 浣跨敤null鎴栫┖瀛楃涓茶〃绀哄叏妯″潡鎼滅储
+        return interfaceBasedSearchRouter.routeSearch(null, companion, happenStartTime, happenEndTime);
+    }
+
 }
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 7949ae7..739c6ba 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -65,7 +65,7 @@
   messages:
     # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
     basename: i18n/messages
-  profiles: 
+  profiles:
     active: druid
   # 鏂囦欢涓婁紶
   servlet:
@@ -120,6 +120,10 @@
       mail.smtp.ssl.trust: smtp.qq.com
       mail.smtp.ssl.protocols: TLSv1.2
     default-encoding: UTF-8
+    # 鐗瑰畾妯″潡鐨勭紦瀛樿繃鏈熸椂闂�
+    cache:
+      cache-names:
+        economy_search: 1800       # economy_search缂撳瓨1灏忔椂
 
 # token閰嶇疆
 token:
@@ -129,7 +133,7 @@
     secret: abcdefghijklmnopqrstuvwxyz
     # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
     expireTime: 100
-  
+
 # MyBatis閰嶇疆
 mybatis-plus:
     # 鎼滅储鎸囧畾鍖呭埆鍚�
@@ -140,7 +144,7 @@
 #    configLocation: classpath:mybatis/mybatis-config.xml
 
 # PageHelper鍒嗛〉鎻掍欢
-pagehelper: 
+pagehelper:
   helperDialect: mysql
   supportMethodsArguments: true
   params: count=countSql
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/AsyncConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/AsyncConfig.java
new file mode 100644
index 0000000..b78ec8a
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/AsyncConfig.java
@@ -0,0 +1,23 @@
+package com.ruoyi.common.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.security.task.DelegatingSecurityContextAsyncTaskExecutor;
+import org.springframework.core.task.SimpleAsyncTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+@Configuration
+@EnableAsync // 鍚敤寮傛鏀寔
+public class AsyncConfig implements AsyncConfigurer {
+
+    @Override
+    public Executor getAsyncExecutor() {
+        // 1. 鍒涘缓涓�涓熀纭�鐨勫紓姝ヤ换鍔℃墽琛屽櫒
+        SimpleAsyncTaskExecutor delegate = new SimpleAsyncTaskExecutor();
+        // 2. 浣跨敤DelegatingSecurityContextAsyncTaskExecutor杩涜鍖呰
+        // 瀹冧細鑷姩灏嗕富绾跨▼鐨勫畨鍏ㄤ笂涓嬫枃缁戝畾鍒板紓姝ヤ换鍔$殑绾跨▼涓�
+        return new DelegatingSecurityContextAsyncTaskExecutor(delegate);
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/EsModel.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/EsModel.java
index 5a93b8c..0be4d6e 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/EsModel.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/EsModel.java
@@ -105,17 +105,17 @@
     @Field(index = true,type = FieldType.Text,analyzer = "ik_max_word")
     private int by13;
 
-    /** 澶囩敤14 */
-    @Field(index = true,type = FieldType.Date,analyzer = "ik_max_wor")
-    private Date by14;
+//    /** 澶囩敤14 */
+//    @Field(index = true,type = FieldType.Date,analyzer = "ik_max_wor")
+//    private Date by14;
+//
+//    /** 澶囩敤15 */
+//    @Field(index = true,type = FieldType.Date,analyzer = "ik_max_wor")
+//    private Date by15;
 
-    /** 澶囩敤15 */
-    @Field(index = true,type = FieldType.Date,analyzer = "ik_max_wor")
-    private Date by15;
-
-    /** 澶囩敤16 */
-    @Field(index = true,type = FieldType.Date,analyzer = "ik_max_wor ")
-    private Timestamp by16;
+//    /** 澶囩敤16 */
+//    @Field(index = true,type = FieldType.Date,analyzer = "ik_max_wor")
+//    private Timestamp by16;
 
 
 }
diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml
index fae4bce..ea1319b 100644
--- a/ruoyi-framework/pom.xml
+++ b/ruoyi-framework/pom.xml
@@ -76,4 +76,4 @@
         </plugins>
     </build>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/zhang-content/src/main/java/com/ruoyi/domain/ModuleSearchResult.java b/zhang-content/src/main/java/com/ruoyi/domain/ModuleSearchResult.java
new file mode 100644
index 0000000..8acad81
--- /dev/null
+++ b/zhang-content/src/main/java/com/ruoyi/domain/ModuleSearchResult.java
@@ -0,0 +1,39 @@
+package com.ruoyi.domain;
+
+import java.util.List;
+
+public class ModuleSearchResult {
+    private final String moduleCode;
+    private final List<?> data;
+    private final int count;
+    private final long searchTime;
+    private final boolean success;
+    private final String errorMessage;
+
+    private ModuleSearchResult(String moduleCode, String moduleName, List<?> data,
+                               int count, long searchTime, boolean success, String errorMessage) {
+        this.moduleCode = moduleCode;
+        this.data = data;
+        this.count = count;
+        this.searchTime = searchTime;
+        this.success = success;
+        this.errorMessage = errorMessage;
+    }
+
+    public static ModuleSearchResult success(String moduleCode, String moduleName,
+                                             List<?> data, int count, long searchTime) {
+        return new ModuleSearchResult(moduleCode, moduleName, data, count, searchTime, true, null);
+    }
+
+    public static ModuleSearchResult error(String moduleCode, String errorMessage) {
+        return new ModuleSearchResult(moduleCode, null, null, 0, 0, false, errorMessage);
+    }
+
+    // getters...
+    public String getModuleCode() { return moduleCode; }
+    public List<?> getData() { return data; }
+    public int getCount() { return count; }
+    public long getSearchTime() { return searchTime; }
+    public boolean isSuccess() { return success; }
+    public String getErrorMessage() { return errorMessage; }
+}
diff --git a/zhang-content/src/main/java/com/ruoyi/domain/ZfDoctor.java b/zhang-content/src/main/java/com/ruoyi/domain/ZfDoctor.java
index 943de3e..2647465 100644
--- a/zhang-content/src/main/java/com/ruoyi/domain/ZfDoctor.java
+++ b/zhang-content/src/main/java/com/ruoyi/domain/ZfDoctor.java
@@ -11,10 +11,11 @@
 
 import java.io.Serializable;
 import java.util.Date;
+import java.util.List;
 
 /**
  * <p>
- * 
+ *
  * </p>
  *
  * @author ojq
@@ -97,4 +98,27 @@
     private Integer ownData;
 
     private Long shareId;
+
+    /**
+     * 鍙備笌鑰�
+     */
+    private String companion;
+
+    /**
+     * 鍙備笌鑰呭垪琛�
+     */
+    @TableField(exist = false)
+    private List<String> companionList;
+
+    /**
+     * 寮�濮嬫椂闂�
+     */
+    @TableField(exist = false)
+    private Date happenStartTime;
+
+    /**
+     * 缁撴潫鏃堕棿
+     */
+    @TableField(exist = false)
+    private Date happenEndTime;
 }
diff --git a/zhang-content/src/main/java/com/ruoyi/domain/ZfEconomy.java b/zhang-content/src/main/java/com/ruoyi/domain/ZfEconomy.java
index 0d26bba..236a681 100644
--- a/zhang-content/src/main/java/com/ruoyi/domain/ZfEconomy.java
+++ b/zhang-content/src/main/java/com/ruoyi/domain/ZfEconomy.java
@@ -8,10 +8,12 @@
 import com.ruoyi.common.annotation.Excel;
 import lombok.Data;
 import lombok.ToString;
+import org.springframework.data.annotation.Transient;
 
 import java.io.Serializable;
 import java.time.LocalDate;
 import java.util.Date;
+import java.util.List;
 
 /**
  * <p>
@@ -118,4 +120,19 @@
 
     private String cosKey;
 
+    /**
+     * 鍙備笌鑰�
+     */
+    private String companion;
+
+    /**
+     * 鍙備笌鑰呭垪琛�
+     */
+    @TableField(exist = false)
+    private List<String> companionList;
+
+//    @TableField(exist = false)
+//    private Integer year;
+
+
 }
diff --git a/zhang-content/src/main/java/com/ruoyi/service/ModuleSearchable.java b/zhang-content/src/main/java/com/ruoyi/service/ModuleSearchable.java
new file mode 100644
index 0000000..c9f6876
--- /dev/null
+++ b/zhang-content/src/main/java/com/ruoyi/service/ModuleSearchable.java
@@ -0,0 +1,25 @@
+package com.ruoyi.service;
+
+import com.ruoyi.domain.ZfEconomy;
+
+import java.util.Date;
+import java.util.List;
+
+public interface ModuleSearchable {
+    /**
+     * 鑾峰彇鏀寔鐨勬ā鍧楃紪鐮�
+     */
+    String getModuleCode();
+
+    /**
+     * 鎼滅储鏂规硶
+     */
+    List<?> search(String companion, Date happenStartTime,Date happenEndTime);
+
+    /**
+     * 妯″潡鍚嶇О
+     */
+    default String getModuleName() {
+        return getModuleCode();
+    }
+}
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
new file mode 100644
index 0000000..91509a9
--- /dev/null
+++ b/zhang-content/src/main/java/com/ruoyi/service/impl/InterfaceBasedSearchRouter.java
@@ -0,0 +1,256 @@
+package com.ruoyi.service.impl;
+
+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 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;
+
+@Service
+@Slf4j
+public class InterfaceBasedSearchRouter {
+
+    private final Map<String, ModuleSearchable> moduleSearchMap;
+
+
+    /**
+     * 鑷姩鏀堕泦鎵�鏈夊疄鐜癕oduleSearchable鎺ュ彛鐨凚ean
+     */
+    @Autowired
+    public InterfaceBasedSearchRouter(List<ModuleSearchable> searchServices) {
+        this.moduleSearchMap = searchServices.stream()
+            .collect(Collectors.toMap(
+                ModuleSearchable::getModuleCode,
+                Function.identity(),
+                (existing, replacement) -> {
+                    log.warn("鍙戠幇閲嶅鐨勬ā鍧楃紪鐮�: {}, 浣跨敤鍏堟敞鍐岀殑鏈嶅姟", existing.getModuleCode());
+                    return existing;
+                }
+            ));
+
+        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);
+        }
+    }
+    /**
+     * 閫氱敤鐨勮矾鐢辨悳绱㈣姹傦紙鏀寔涓嶅悓鍙傛暟绫诲瀷锛�
+     */
+    /**
+     * 閫氱敤鐨勮矾鐢辨悳绱㈣姹�
+     */
+    public AjaxResult routeSearch(String moduleCode, Object... args) {
+        log.info("璺敱鎼滅储: moduleCode={}, args={}", moduleCode, Arrays.toString(args));
+
+        // 鍏ㄦā鍧楁悳绱細褰搈oduleCode涓虹┖鎴栫壒瀹氭爣璇嗘椂
+        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());
+            return AjaxResult.error("涓嶆敮鎸佺殑鎼滅储妯″潡: " + moduleCode + "銆傚彲鐢ㄦā鍧�: [" + availableModules + "]");
+        }
+
+        try {
+            if (args.length == 3) {
+                return handleFourArgs(searchService, args);
+            } else {
+                return AjaxResult.error("涓嶆敮鎸佺殑鍙傛暟鏁伴噺锛岄渶瑕�3涓弬鏁帮紝瀹為檯鏀跺埌: " + args.length);
+            }
+        } catch (Exception e) {
+            log.error("鎼滅储鎵ц澶辫触: moduleCode={}", moduleCode, e);
+            return AjaxResult.error("鎼滅储鎵ц澶辫触: " + e.getMessage());
+        }
+    }
+
+    private AjaxResult handleFourArgs(ModuleSearchable searchService, Object[] args) {
+        String companion = null;
+        Date happenStartTime = null;
+        Date happenEndTime = null;
+
+        // 澶勭悊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);
+        } else {
+            // 鏃犳椂闂磋寖鍥达細鍙寜companion鎼滅储
+            log.info("鎵цcompanion鎼滅储: companion={}, 鏃堕棿鑼冨洿涓虹┖", companion);
+            result = searchService.search(companion, null, null);
+        }
+
+        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());
+
+                    // 灏嗘瀯寤哄ソ鐨凪ap鏀惧叆鏈�缁堢粨鏋滀腑
+                    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());
+        }
+    }
+//
+//    /**
+//     * 鑾峰彇鎵�鏈夊彲鎼滅储鐨勬ā鍧椾俊鎭�
+//     */
+//    public List<SysMenu> getAvailableModules() {
+//        return moduleSearchMap.values().stream()
+//            .map(service -> SysMenu.builder()
+//                .moduleCode(service.getModuleCode())
+//                .moduleName(service.getModuleName())
+//                .build())
+//            .collect(Collectors.toList());
+//    }
+
+    /**
+     * 鍙傛暟鎻愬彇杈呭姪鏂规硶
+     */
+    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;
+    }
+}
diff --git a/zhang-content/src/main/java/com/ruoyi/service/impl/ZfDoctorServiceImpl.java b/zhang-content/src/main/java/com/ruoyi/service/impl/ZfDoctorServiceImpl.java
index 1840a69..beb70cf 100644
--- a/zhang-content/src/main/java/com/ruoyi/service/impl/ZfDoctorServiceImpl.java
+++ b/zhang-content/src/main/java/com/ruoyi/service/impl/ZfDoctorServiceImpl.java
@@ -2,6 +2,7 @@
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.domain.AjaxResult;
@@ -39,7 +40,7 @@
  */
 @Service
 @Slf4j
-public class ZfDoctorServiceImpl extends ServiceImpl<ZfDoctorMapper, ZfDoctor> implements ZfDoctorService {
+public class ZfDoctorServiceImpl extends ServiceImpl<ZfDoctorMapper, ZfDoctor> implements ZfDoctorService,ModuleSearchable {
 
     @Resource
     ZInfoUserService zInfoUserService;
@@ -465,6 +466,29 @@
                 .like(StringUtils.isNotEmpty(zfDoctor.getWmedical()), ZfDoctor::getWmedical, zfDoctor.getWmedical())
                 .like(StringUtils.isNotEmpty(zfDoctor.getCmedical()), ZfDoctor::getCmedical, zfDoctor.getCmedical())
                 .like(StringUtils.isNotEmpty(zfDoctor.getRemark()), ZfDoctor::getRemark, zfDoctor.getRemark());
+//        lqw.like(StringUtils.isNotEmpty(zfDoctor.getCompanion()),ZfDoctor::getCompanion,zfDoctor.getCompanion());
+
+        if (CollectionUtils.isNotEmpty(zfDoctor.getCompanionList())) {
+            List<String> companionList = zfDoctor.getCompanionList();
+
+            // 娓呯悊鍜屽幓閲�
+            companionList = companionList.stream()
+                .map(String::trim)
+                .filter(s -> !s.isEmpty())
+                .distinct()
+                .collect(Collectors.toList());
+
+            if (!companionList.isEmpty()) {
+                // 纭繚鎵�鏈夊弬涓庝汉閮藉湪companion瀛楁涓�
+                for (String companion : companionList) {
+                    lqw.apply("FIND_IN_SET({0}, REPLACE(REPLACE(companion, ' ', ''), '锛�', ',')) > 0",
+                        companion);
+                }
+            }
+        }
+
+        lqw.between(zfDoctor.getHappenStartTime() != null && zfDoctor.getHappenEndTime() != null, ZfDoctor::getCreateTime, zfDoctor.getHappenStartTime(), zfDoctor.getHappenEndTime());
+
         if (StringUtils.isNotEmpty(zfDoctor.getPrescription())) {
             lqw.and(wrapper -> {
                 wrapper.like(StringUtils.isNotEmpty(zfDoctor.getPrescription()), ZfDoctor::getWmedical, zfDoctor.getPrescription())
@@ -473,6 +497,23 @@
             });
         }
         return lqw;
+    }
+
+    @Override
+    public String getModuleCode() {
+        return "2043";
+    }
+
+    @Override
+    public List<?> search(String companion, Date happenStartTime, Date happenEndTime) {
+
+        ZfDoctor zfDoctor = new ZfDoctor();
+        String[] split = companion.split(",");
+        List<String> list = Arrays.asList(split);
+
+        zfDoctor.setCompanionList(list);        zfDoctor.setHappenStartTime(happenStartTime);
+        zfDoctor.setHappenEndTime(happenEndTime);
+        return selectByCondition(zfDoctor);
     }
 
 //    public LambdaQueryWrapper<ZfDoctor> buildCondition2(List<Long> ids) {
@@ -516,4 +557,4 @@
 //    }
 
 
-}
\ No newline at end of file
+}
diff --git a/zhang-content/src/main/java/com/ruoyi/service/impl/ZfEconomyServiceImpl.java b/zhang-content/src/main/java/com/ruoyi/service/impl/ZfEconomyServiceImpl.java
index 0b82238..6655de3 100644
--- a/zhang-content/src/main/java/com/ruoyi/service/impl/ZfEconomyServiceImpl.java
+++ b/zhang-content/src/main/java/com/ruoyi/service/impl/ZfEconomyServiceImpl.java
@@ -2,6 +2,7 @@
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.domain.AjaxResult;
@@ -18,6 +19,8 @@
 import org.elasticsearch.action.update.UpdateRequest;
 import org.elasticsearch.client.RequestOptions;
 import org.elasticsearch.client.RestHighLevelClient;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
@@ -26,6 +29,7 @@
 import java.io.IOException;
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 import static com.ruoyi.constant.MenuAuthority.*;
@@ -40,7 +44,7 @@
  */
 @Service
 @Slf4j
-public class ZfEconomyServiceImpl extends ServiceImpl<ZfEconomyMapper, ZfEconomy> implements ZfEconomyService {
+public class ZfEconomyServiceImpl extends ServiceImpl<ZfEconomyMapper, ZfEconomy> implements ZfEconomyService,ModuleSearchable{
     @Resource
     ZfEconomyService zfEconomyService;
 
@@ -76,10 +80,41 @@
         lqw.like(StringUtils.isNotEmpty(zfEconomy.getUsePeople()),ZfEconomy::getUsePeople,zfEconomy.getUsePeople());
         lqw.like(StringUtils.isNotEmpty(zfEconomy.getBalance()),ZfEconomy::getBalance,zfEconomy.getBalance());
         lqw.like(StringUtils.isNotEmpty(zfEconomy.getRemark()),ZfEconomy::getRemark,zfEconomy.getRemark());
+//        lqw.in(StringUtils.isNotEmpty(zfEconomy.getCompanionList()),ZfEconomy::getCompanion,zfEconomy.getCompanionList());
+//        if (zfEconomy.getYear() != 0) {
+//            System.out.println("pppppppppppppppppppppppppppppppppppppppppppppppppppp"+zfEconomy.getYear());
+//            lqw.apply("YEAR(happen_time) = {0}", zfEconomy.getYear());
+//        }
+
+            if (CollectionUtils.isNotEmpty(zfEconomy.getCompanionList())) {
+                List<String> companionList = zfEconomy.getCompanionList();
+
+                // 娓呯悊鍜屽幓閲�
+                companionList = companionList.stream()
+                    .map(String::trim)
+                    .filter(s -> !s.isEmpty())
+                    .distinct()
+                    .collect(Collectors.toList());
+
+                if (!companionList.isEmpty()) {
+                    // 纭繚鎵�鏈夊弬涓庝汉閮藉湪companion瀛楁涓�
+                    for (String companion : companionList) {
+                        lqw.apply("FIND_IN_SET({0}, REPLACE(REPLACE(companion, ' ', ''), '锛�', ',')) > 0",
+                            companion);
+                    }
+                }
+            }
+
+
+
+
         lqw.eq(zfEconomy.getHappenTime() != null, ZfEconomy::getHappenTime, zfEconomy.getHappenTime());
         lqw.between(zfEconomy.getHappenStartTime() != null && zfEconomy.getHappenEndTime() != null, ZfEconomy::getHappenTime, zfEconomy.getHappenStartTime(), zfEconomy.getHappenEndTime());
+        System.out.println("鏌ヨ鏉′欢: " + lqw.getCustomSqlSegment());
+
         return lqw;
     }
+
 
     private LambdaQueryWrapper<ZfEconomy> uniqueCondition(ZfEconomy zfEconomy) {
         LambdaQueryWrapper<ZfEconomy> lqw = new LambdaQueryWrapper<>();
@@ -425,6 +460,9 @@
 
     @Override
     public AjaxResult addData(ZfEconomy zfEconomy) {
+        //娓呴櫎redis涓瓃fEconomy鐨勭紦瀛�
+        clearAllCache();
+
         ZInfoUser myself = zInfoUserService.getMyself();
         Long familyId = myself.getFamilyId();
 
@@ -479,6 +517,9 @@
 
     @Override
     public AjaxResult updateData(ZfEconomy zfEconomy) {
+        //娓呴櫎redis涓瓃fEconomy鐨勭紦瀛�
+        clearAllCache();
+
         ZInfoUser myself = zInfoUserService.getMyself();
         Long familyId = myself.getFamilyId();
 
@@ -600,4 +641,28 @@
     }
 
 
+    @Override
+    public String getModuleCode() {
+        return "2045";
+    }
+
+    @Override
+    @Cacheable(value = "economy_search", key = "T(String).format('2045_%s_%s_%s',#companion != null ? #companion : 'null',#happenStartTime != null ? #happenStartTime.getTime() : 0,#happenEndTime != null ? #happenEndTime.getTime() : 0)")
+    public List<?> search(String companion, Date happenStartTime,Date happenEndTime) {
+        ZfEconomy zfEconomy = new ZfEconomy();
+        zfEconomy.setCompanion(companion);
+        zfEconomy.setHappenStartTime(happenStartTime);
+        zfEconomy.setHappenEndTime(happenEndTime);
+
+        String[] split = companion.split(",");
+        List<String> list = Arrays.asList(split);
+
+        zfEconomy.setCompanionList(list);
+        return selectByCondition(zfEconomy);
+    }
+
+    @CacheEvict(value = "economy_search", allEntries = true)
+    public void clearAllCache() {
+        System.out.println("娓呴櫎鎵�鏈夌粡娴庢悳绱㈢紦瀛�");
+    }
 }

--
Gitblit v1.9.1