package com.example.caseData.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.example.caseData.dao.BasicSensitiveWordDao; import com.example.caseData.model.BasicSensitiveWordModel; import com.example.caseData.model.CaseClinicalArticleModel; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.type.TypeReference; import java.time.Duration; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Service public class BasicSensitiveWordService { private static final String REDIS_SENSITIVE_WORD_KEY = "sensitive:word:list"; private static final long REDIS_EXPIRE_MINUTES = 30; @Resource private RedisTemplate redisTemplate; @Resource private BasicSensitiveWordDao basicSensitiveWordDao; // 假设你有这个 DAO private final ObjectMapper objectMapper = new ObjectMapper(); // 主过滤方法 public FilterResult filter(String comment) { List wordList = loadSensitiveWords(); if (wordList == null || wordList.isEmpty()) { return new FilterResult(comment, 0); } TrieNode root = buildTrie(wordList); return doFilter(comment, root); } // 加载敏感词(可替换为数据库查询) private List loadSensitiveWords() { List wordList = new ArrayList<>(); // 尝试从 Redis 获取 String wordJson = redisTemplate.opsForValue().get(REDIS_SENSITIVE_WORD_KEY); if (wordJson != null && !wordJson.isEmpty()) { try { // 反序列化 JSON 字符串为 List wordList = objectMapper.readValue(wordJson, new TypeReference>() {}); } catch (Exception e) { return wordList; } }else{ // Redis 无数据,则查询 DB LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); List basicSensitiveWords = basicSensitiveWordDao.selectList(queryWrapper); // 你自己的 DAO 方法 if (basicSensitiveWords != null && !basicSensitiveWords.isEmpty()) { wordList = basicSensitiveWords.stream() .map(BasicSensitiveWordModel::getWord) .filter(Objects::nonNull) .collect(Collectors.toList()); try { String wordListJson = objectMapper.writeValueAsString(wordList); redisTemplate.opsForValue().set(REDIS_SENSITIVE_WORD_KEY, wordListJson, Duration.ofMinutes(REDIS_EXPIRE_MINUTES)); } catch (Exception e) { return wordList; } } } return wordList; } // 构建字典树 private TrieNode buildTrie(List words) { TrieNode root = new TrieNode(); for (String word : words) { TrieNode node = root; for (char ch : word.toCharArray()) { node.children.putIfAbsent(ch, new TrieNode()); node = node.children.get(ch); } node.isEnd = true; } return root; } // 实际过滤逻辑 private FilterResult doFilter(String comment, TrieNode root) { char[] chars = comment.toCharArray(); int isSensitive = 0; for (int i = 0; i < chars.length; i++) { TrieNode node = root; int j = i; while (j < chars.length && node.children.containsKey(chars[j])) { node = node.children.get(chars[j]); if (node.isEnd) { for (int k = i; k <= j; k++) { chars[k] = '*'; } isSensitive = 1; break; } j++; } } return new FilterResult(new String(chars), isSensitive); } // Trie 节点内部类 private static class TrieNode { boolean isEnd = false; Map children = new HashMap<>(); } // 返回结果封装 public static class FilterResult { public final String comment; public final int hasSensitive; public FilterResult(String comment, int hasSensitive) { this.comment = comment; this.hasSensitive = hasSensitive; } } }