case-data-api/src/main/java/com/example/caseData/service/BasicSensitiveWordService.java

134 lines
4.7 KiB
Java

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<String, String> redisTemplate;
@Resource
private BasicSensitiveWordDao basicSensitiveWordDao; // 假设你有这个 DAO
private final ObjectMapper objectMapper = new ObjectMapper();
// 主过滤方法
public FilterResult filter(String comment) {
List<String> wordList = loadSensitiveWords();
if (wordList == null || wordList.isEmpty()) {
return new FilterResult(comment, 0);
}
TrieNode root = buildTrie(wordList);
return doFilter(comment, root);
}
// 加载敏感词(可替换为数据库查询)
private List<String> loadSensitiveWords() {
List<String> wordList = new ArrayList<>();
// 尝试从 Redis 获取
String wordJson = redisTemplate.opsForValue().get(REDIS_SENSITIVE_WORD_KEY);
if (wordJson != null && !wordJson.isEmpty()) {
try {
// 反序列化 JSON 字符串为 List<String>
wordList = objectMapper.readValue(wordJson, new TypeReference<List<String>>() {});
} catch (Exception e) {
return wordList;
}
}else{
// Redis 无数据,则查询 DB
LambdaQueryWrapper<BasicSensitiveWordModel> queryWrapper = new LambdaQueryWrapper<>();
List<BasicSensitiveWordModel> 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<String> 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<Character, TrieNode> 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;
}
}
}