|
|
@@ -22,6 +22,12 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import org.jsoup.Jsoup;
|
|
|
+import org.jsoup.nodes.Document;
|
|
|
+import org.jsoup.nodes.Element;
|
|
|
+import org.jsoup.nodes.TextNode;
|
|
|
+import org.jsoup.select.NodeTraversor;
|
|
|
+import org.jsoup.select.NodeVisitor;
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
@@ -59,13 +65,14 @@ import vip.xiaonuo.sys.api.SysUserApi;
|
|
|
import javax.annotation.Resource;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
-import java.text.SimpleDateFormat;
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.time.format.DateTimeParseException;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
@@ -202,7 +209,9 @@ public class ForumPostInfoServiceImpl extends ServiceImpl<ForumPostInfoMapper, F
|
|
|
forumPostInfo.setUserId(loginUser.getId());
|
|
|
// 过滤敏感词(标题)
|
|
|
String titleIsIllegal = filterSensitiveWordsTitle(forumPostInfoAddParam.getPostTitle());
|
|
|
- if("1".equals(titleIsIllegal))return CommonResult.error("帖子标题含有敏感词");
|
|
|
+ if("1".equals(titleIsIllegal)) {
|
|
|
+ return CommonResult.error("帖子标题含有敏感词");
|
|
|
+ }
|
|
|
// 过滤敏感词(内容)
|
|
|
String postContent = filterSensitiveWords(forumPostInfoAddParam.getPostContent(), loginUser, uuid);
|
|
|
forumPostInfo.setPostContent(postContent);
|
|
|
@@ -260,26 +269,92 @@ public class ForumPostInfoServiceImpl extends ServiceImpl<ForumPostInfoMapper, F
|
|
|
*
|
|
|
* @param postContent 帖子内容
|
|
|
*/
|
|
|
+// public String filterSensitiveWords(String postContent, SaBaseLoginUser loginUser, String uuid) {
|
|
|
+// List<ForumSensitivity> forumSensitivities = forumSensitivityMapper.selectList(new QueryWrapper<>());
|
|
|
+// if (forumSensitivities.size() > 0) {
|
|
|
+// // 过滤敏感词
|
|
|
+// for (ForumSensitivity forumSensitivity : forumSensitivities) {
|
|
|
+// // 过滤逻辑
|
|
|
+// if (postContent.contains(forumSensitivity.getSensitivityWord())) {
|
|
|
+// // 替换句子中敏感词为*号
|
|
|
+// postContent = postContent.replace(forumSensitivity.getSensitivityWord(), "******");
|
|
|
+// // 记录敏感词命中情况
|
|
|
+// ForumSensitivityRecord forumSensitivityRecord = new ForumSensitivityRecord();
|
|
|
+// forumSensitivityRecord.setSensitivityWord(forumSensitivity.getSensitivityWord()); // 敏感词
|
|
|
+// forumSensitivityRecord.setUserId(loginUser.getId()); // 用户id
|
|
|
+// forumSensitivityRecord.setRecordType(0); // 发帖子类型
|
|
|
+// forumSensitivityRecord.setPostId(uuid); // 帖子id
|
|
|
+// forumSensitivityRecordMapper.insert(forumSensitivityRecord);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// return postContent;
|
|
|
+// }
|
|
|
+
|
|
|
public String filterSensitiveWords(String postContent, SaBaseLoginUser loginUser, String uuid) {
|
|
|
+ // 查询敏感词列表
|
|
|
List<ForumSensitivity> forumSensitivities = forumSensitivityMapper.selectList(new QueryWrapper<>());
|
|
|
- if (forumSensitivities.size() > 0) {
|
|
|
- // 过滤敏感词
|
|
|
- for (ForumSensitivity forumSensitivity : forumSensitivities) {
|
|
|
- // 过滤逻辑
|
|
|
- if (postContent.contains(forumSensitivity.getSensitivityWord())) {
|
|
|
- // 替换句子中敏感词为*号
|
|
|
- postContent = postContent.replace(forumSensitivity.getSensitivityWord(), "******");
|
|
|
- // 记录敏感词命中情况
|
|
|
- ForumSensitivityRecord forumSensitivityRecord = new ForumSensitivityRecord();
|
|
|
- forumSensitivityRecord.setSensitivityWord(forumSensitivity.getSensitivityWord()); // 敏感词
|
|
|
- forumSensitivityRecord.setUserId(loginUser.getId()); // 用户id
|
|
|
- forumSensitivityRecord.setRecordType(0); // 发帖子类型
|
|
|
- forumSensitivityRecord.setPostId(uuid); // 帖子id
|
|
|
- forumSensitivityRecordMapper.insert(forumSensitivityRecord);
|
|
|
+ if (forumSensitivities == null || forumSensitivities.isEmpty()) {
|
|
|
+ return postContent;
|
|
|
+ }
|
|
|
+ // 解析 HTML
|
|
|
+ Document doc = Jsoup.parseBodyFragment(postContent);
|
|
|
+ // 遍历所有节点
|
|
|
+ NodeTraversor.traverse(new NodeVisitor() {
|
|
|
+ @Override
|
|
|
+ public void head(org.jsoup.nodes.Node node, int depth) {
|
|
|
+ if (node instanceof TextNode) {
|
|
|
+ TextNode textNode = (TextNode) node;
|
|
|
+ String text = textNode.text();
|
|
|
+ if (text.contains("data:image") || text.contains("base64")) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ org.jsoup.nodes.Node nodeParent = textNode.parent();
|
|
|
+ if (nodeParent instanceof Element) {
|
|
|
+ Element parent = (Element) nodeParent;
|
|
|
+ String tag = parent.tagName().toLowerCase();
|
|
|
+ if ("script".equals(tag) || "style".equals(tag)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 遍历敏感词进行替换
|
|
|
+ String newText = text;
|
|
|
+ for (ForumSensitivity s : forumSensitivities) {
|
|
|
+ String word = s.getSensitivityWord();
|
|
|
+ if (word == null || word.trim().isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Pattern pattern = Pattern.compile(
|
|
|
+ "\\b" + Pattern.quote(word) + "\\b",
|
|
|
+ Pattern.CASE_INSENSITIVE
|
|
|
+ );
|
|
|
+ Matcher matcher = pattern.matcher(newText);
|
|
|
+ if (matcher.find()) {
|
|
|
+ newText = matcher.replaceAll("****");
|
|
|
+ // 记录数据库
|
|
|
+ ForumSensitivityRecord record = new ForumSensitivityRecord();
|
|
|
+ record.setSensitivityWord(word);
|
|
|
+ record.setUserId(loginUser.getId());
|
|
|
+ record.setRecordType(0);
|
|
|
+ record.setPostId(uuid);
|
|
|
+ forumSensitivityRecordMapper.insert(record);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 更新节点文本
|
|
|
+ if (!newText.equals(text)) {
|
|
|
+ textNode.text(newText);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- return postContent;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void tail(org.jsoup.nodes.Node node, int depth) {
|
|
|
+ // 不用处理
|
|
|
+ }
|
|
|
+ }, doc.body());
|
|
|
+
|
|
|
+ // 返回完整 HTML
|
|
|
+ return doc.body().html();
|
|
|
}
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
@@ -297,7 +372,9 @@ public class ForumPostInfoServiceImpl extends ServiceImpl<ForumPostInfoMapper, F
|
|
|
}
|
|
|
// 确认标题是否有敏感词,有直接拦截(标题)
|
|
|
String titleIsIllegal = filterSensitiveWordsTitle(forumPostInfoEditParam.getPostTitle());
|
|
|
- if("1".equals(titleIsIllegal))return CommonResult.error("帖子标题含有敏感词");
|
|
|
+ if("1".equals(titleIsIllegal)) {
|
|
|
+ return CommonResult.error("帖子标题含有敏感词");
|
|
|
+ }
|
|
|
// 过滤敏感词(内容)
|
|
|
String postContent = filterSensitiveWords(forumPostInfoEditParam.getPostContent(), loginUser, forumPostInfoEditParam.getPostId());
|
|
|
forumPostInfoEditParam.setPostContent(postContent);
|