feat(comment): 新增敏感词过滤并拦截评论发送
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package com.test.musichouduan.service;
|
||||
|
||||
/**
|
||||
* 敏感词服务接口
|
||||
*/
|
||||
public interface SensitiveWordService {
|
||||
|
||||
/**
|
||||
* 校验评论内容是否包含敏感词
|
||||
*
|
||||
* @param content 评论内容
|
||||
*/
|
||||
void validateCommentContent(String content);
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import com.test.musichouduan.repository.PlaylistRepository;
|
||||
import com.test.musichouduan.repository.SingerRepository;
|
||||
import com.test.musichouduan.repository.UserRepository;
|
||||
import com.test.musichouduan.service.CommentService;
|
||||
import com.test.musichouduan.service.SensitiveWordService;
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate; // 添加导入
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -55,6 +56,9 @@ public class CommentServiceImpl implements CommentService {
|
||||
@Autowired
|
||||
private SimpMessagingTemplate messagingTemplate; // 注入 SimpMessagingTemplate
|
||||
|
||||
@Autowired
|
||||
private SensitiveWordService sensitiveWordService; // 注入敏感词服务
|
||||
|
||||
@Override
|
||||
public CommentDTO getCommentById(Long id) {
|
||||
Comment comment = commentRepository.findById(id)
|
||||
@@ -114,6 +118,9 @@ public class CommentServiceImpl implements CommentService {
|
||||
User user = userRepository.findById(userId)
|
||||
.orElseThrow(() -> new BusinessException("用户不存在"));
|
||||
|
||||
// 保存前统一校验评论内容,覆盖音乐/歌单/歌手评论及回复评论
|
||||
sensitiveWordService.validateCommentContent(commentDTO.getContent());
|
||||
|
||||
// 创建评论实体
|
||||
Comment comment = new Comment();
|
||||
comment.setContent(commentDTO.getContent());
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.test.musichouduan.service.impl;
|
||||
|
||||
import cn.hutool.dfa.SensitiveUtil;
|
||||
import com.test.musichouduan.exception.BusinessException;
|
||||
import com.test.musichouduan.service.SensitiveWordService;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 敏感词服务实现
|
||||
*/
|
||||
@Service
|
||||
public class SensitiveWordServiceImpl implements SensitiveWordService {
|
||||
|
||||
/**
|
||||
* 服务启动后加载一次词库
|
||||
*/
|
||||
@PostConstruct
|
||||
public void initSensitiveWords() {
|
||||
List<String> words = new ArrayList<>();
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(new ClassPathResource("sensitive-words.txt").getInputStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
String word = line.trim();
|
||||
// 忽略空行和注释行
|
||||
if (!word.isEmpty() && !word.startsWith("#")) {
|
||||
words.add(word);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("敏感词词库加载失败");
|
||||
}
|
||||
|
||||
// 若词库为空,直接跳过初始化,避免影响正常启动
|
||||
if (words.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 兼容不同版本 Hutool 的 init 方法签名
|
||||
Method[] methods = SensitiveUtil.class.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (!"init".equals(method.getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (parameterTypes.length == 1) {
|
||||
Class<?> type = parameterTypes[0];
|
||||
if (type.isAssignableFrom(List.class) || type.isAssignableFrom(java.util.Collection.class)) {
|
||||
method.invoke(null, words);
|
||||
return;
|
||||
}
|
||||
if (type.isArray() && type.getComponentType() == String.class) {
|
||||
method.invoke(null, (Object) words.toArray(new String[0]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (parameterTypes.length == 2) {
|
||||
Class<?> firstType = parameterTypes[0];
|
||||
Class<?> secondType = parameterTypes[1];
|
||||
if ((firstType.isAssignableFrom(List.class) || firstType.isAssignableFrom(java.util.Collection.class))
|
||||
&& (secondType == boolean.class || secondType == Boolean.class)) {
|
||||
// 默认关闭异步,确保启动即生效
|
||||
method.invoke(null, words, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new BusinessException("敏感词工具初始化失败");
|
||||
} catch (BusinessException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("敏感词工具初始化失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateCommentContent(String content) {
|
||||
if (content == null || content.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Method containsMethod = SensitiveUtil.class.getMethod("containsSensitive", String.class);
|
||||
Object result = containsMethod.invoke(null, content);
|
||||
boolean hasSensitive = result instanceof Boolean && (Boolean) result;
|
||||
if (hasSensitive) {
|
||||
throw new BusinessException("评论包含敏感词,请修改后再发布");
|
||||
}
|
||||
} catch (BusinessException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("评论敏感词校验失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
3
music-houduan/src/main/resources/sensitive-words.txt
Normal file
3
music-houduan/src/main/resources/sensitive-words.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
# 敏感词词库(每行一个,支持后续自行维护)
|
||||
# 示例词条:
|
||||
# 坏词示例
|
||||
Reference in New Issue
Block a user