feige
4 天以前 c8668a4a71987199e610781e7ac8cc02faa4f082
Merge remote-tracking branch 'origin/master'
4个文件已添加
8个文件已修改
577 ■■■■■ 已修改文件
ruoyi-admin/src/main/java/com/ruoyi/web/controller/zhang/EsSearchController.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/AsyncConfig.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/EsModel.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhang-content/src/main/java/com/ruoyi/domain/ModuleSearchResult.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhang-content/src/main/java/com/ruoyi/domain/ZfDoctor.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhang-content/src/main/java/com/ruoyi/domain/ZfEconomy.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhang-content/src/main/java/com/ruoyi/service/ModuleSearchable.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhang-content/src/main/java/com/ruoyi/service/impl/InterfaceBasedSearchRouter.java 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhang-content/src/main/java/com/ruoyi/service/impl/ZfDoctorServiceImpl.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhang-content/src/main/java/com/ruoyi/service/impl/ZfEconomyServiceImpl.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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);
    }
    /**
     * 新增全模块搜索接口(不指定moduleCode)
     */
    @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);
    }
}
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
ruoyi-common/src/main/java/com/ruoyi/common/config/AsyncConfig.java
New file
@@ -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);
    }
}
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;
}
ruoyi-framework/pom.xml
@@ -76,4 +76,4 @@
        </plugins>
    </build>
</project>
</project>
zhang-content/src/main/java/com/ruoyi/domain/ModuleSearchResult.java
New file
@@ -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; }
}
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;
}
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;
}
zhang-content/src/main/java/com/ruoyi/service/ModuleSearchable.java
New file
@@ -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();
    }
}
zhang-content/src/main/java/com/ruoyi/service/impl/InterfaceBasedSearchRouter.java
New file
@@ -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;
    /**
     * 自动收集所有实现ModuleSearchable接口的Bean
     */
    @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));
        // 全模块搜索:当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());
            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());
                    // 将构建好的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());
        }
    }
//
//    /**
//     * 获取所有可搜索的模块信息
//     */
//    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;
    }
}
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 @@
//    }
}
}
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中zfEconomy的缓存
        clearAllCache();
        ZInfoUser myself = zInfoUserService.getMyself();
        Long familyId = myself.getFamilyId();
@@ -479,6 +517,9 @@
    @Override
    public AjaxResult updateData(ZfEconomy zfEconomy) {
        //清除redis中zfEconomy的缓存
        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("清除所有经济搜索缓存");
    }
}