package com.sinata.appointment.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.sinata.appointment.constants.CacheNames;
|
import com.sinata.appointment.entity.BizSensitiveWord;
|
import com.sinata.appointment.mapper.BizSensitiveWordMapper;
|
import java.util.Comparator;
|
import java.util.List;
|
import java.util.Locale;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.cache.Cache;
|
import org.springframework.cache.CacheManager;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.StringUtils;
|
|
@Service
|
@RequiredArgsConstructor
|
public class SensitiveWordFilterService {
|
|
private final BizSensitiveWordMapper bizSensitiveWordMapper;
|
private final CacheManager cacheManager;
|
|
public String filter(String text) {
|
if (!StringUtils.hasText(text)) {
|
return text;
|
}
|
List<String> words = enabledWords();
|
if (words.isEmpty()) {
|
return text;
|
}
|
|
String result = text;
|
for (String word : words) {
|
result = replaceIgnoreCase(result, word);
|
}
|
return result;
|
}
|
|
public void evictCache() {
|
Cache cache = cacheManager.getCache(CacheNames.BIZ_SENSITIVE_WORD);
|
if (cache != null) {
|
cache.evict(CacheNames.BIZ_SENSITIVE_WORD_ENABLED_KEY);
|
}
|
}
|
|
@SuppressWarnings("unchecked")
|
public List<String> enabledWords() {
|
Cache cache = cacheManager.getCache(CacheNames.BIZ_SENSITIVE_WORD);
|
if (cache != null) {
|
Cache.ValueWrapper cached = cache.get(CacheNames.BIZ_SENSITIVE_WORD_ENABLED_KEY);
|
if (cached != null && cached.get() instanceof List<?> list) {
|
return (List<String>) list;
|
}
|
}
|
|
List<String> words = bizSensitiveWordMapper
|
.selectList(
|
new LambdaQueryWrapper<BizSensitiveWord>()
|
.eq(BizSensitiveWord::getDelFlag, 0)
|
.eq(BizSensitiveWord::getEnabled, 1))
|
.stream()
|
.map(BizSensitiveWord::getWord)
|
.filter(StringUtils::hasText)
|
.map(String::trim)
|
.distinct()
|
.sorted(Comparator.comparingInt(String::length).reversed())
|
.toList();
|
if (cache != null) {
|
cache.put(CacheNames.BIZ_SENSITIVE_WORD_ENABLED_KEY, words);
|
}
|
return words;
|
}
|
|
private String replaceIgnoreCase(String source, String word) {
|
if (!StringUtils.hasText(source) || !StringUtils.hasText(word)) {
|
return source;
|
}
|
|
String lowerSource = source.toLowerCase(Locale.ROOT);
|
String lowerWord = word.toLowerCase(Locale.ROOT);
|
StringBuilder builder = new StringBuilder(source.length());
|
int cursor = 0;
|
int matchIndex = lowerSource.indexOf(lowerWord, cursor);
|
while (matchIndex >= 0) {
|
builder.append(source, cursor, matchIndex);
|
builder.append("*".repeat(word.length()));
|
cursor = matchIndex + word.length();
|
matchIndex = lowerSource.indexOf(lowerWord, cursor);
|
}
|
builder.append(source, cursor, source.length());
|
return builder.toString();
|
}
|
}
|