From 944e3862a5bac58b8d453280d258bfd71895a541 Mon Sep 17 00:00:00 2001
From: daiwencheng <daiwencheng@shengqugames.com>
Date: Sun, 15 Oct 2023 14:30:43 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=95=8F=E6=84=9F=E8=AF=8D?=
 =?UTF-8?q?=E6=A3=80=E9=AA=8C=E9=97=AE=E9=A2=98=201.=E4=BF=AE=E5=A4=8D?=
 =?UTF-8?q?=E6=8E=92=E5=BA=8F=EF=BC=8C=E4=BC=98=E5=85=88=E4=BD=BF=E7=94=A8?=
 =?UTF-8?q?=E8=BE=83=E7=9F=AD=E7=9A=84=E5=89=8D=E7=BC=80=E5=A4=B1=E6=95=88?=
 =?UTF-8?q?=E9=97=AE=E9=A2=98=202.=E4=BF=AE=E5=A4=8D=E6=95=8F=E6=84=9F?=
 =?UTF-8?q?=E8=AF=8D=E4=B8=BA=E5=8D=95=E4=B8=AA=E5=AD=97=E7=AC=A6=E6=A0=A1?=
 =?UTF-8?q?=E9=AA=8C=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../sensitiveword/SensitiveWordService.java   |  6 +--
 .../SensitiveWordServiceImpl.java             |  4 +-
 .../system/util/collection/SimpleTrie.java    | 20 ++++++---
 .../SensitiveWordServiceImplTest.java         | 44 +++++++++++++++++--
 4 files changed, 58 insertions(+), 16 deletions(-)

diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java
index 658039cd2..ab23a15c4 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java
@@ -88,11 +88,11 @@ public interface SensitiveWordService {
     List<String> validateText(String text, List<String> tags);
 
     /**
-     * 判断文本是否包含敏感词
+     * 判断文本是否合法
      *
      * @param text 文本
-     * @param tags 表述数组
-     * @return 是否包含
+     * @param tags 标签数组
+     * @return 是否合法 true-合法 false-不合法
      */
     boolean isTextValid(String text, List<String> tags);
 
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java
index ea0402dfc..9c41941ef 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java
@@ -258,9 +258,7 @@ public class SensitiveWordServiceImpl implements SensitiveWordService {
             if (trie == null) {
                 continue;
             }
-            if (!trie.isValid(text)) {
-                return false;
-            }
+            return trie.isValid(text);
         }
         return true;
     }
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/collection/SimpleTrie.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/collection/SimpleTrie.java
index 817eee355..1a0a5c055 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/collection/SimpleTrie.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/collection/SimpleTrie.java
@@ -32,7 +32,7 @@ public class SimpleTrie {
     public SimpleTrie(Collection<String> strs) {
         children = new HashMap<>();
         // 构建树
-        CollUtil.sort(strs, String::compareTo); // 排序,优先使用较短的前缀
+        strs = CollUtil.sort(strs, String::compareTo); // 排序,优先使用较短的前缀
         for (String str : strs) {
             Map<Character, Object> child = children;
             // 遍历每个字符
@@ -56,11 +56,11 @@ public class SimpleTrie {
      * 验证文本是否合法,即不包含敏感词
      *
      * @param text 文本
-     * @return 是否 ok
+     * @return 是否 true-合法 false-不合法
      */
     public boolean isValid(String text) {
         // 遍历 text,使用每一个 [i, n) 段的字符串,使用 children 前缀树匹配,是否包含敏感词
-        for (int i = 0; i < text.length() - 1; i++) {
+        for (int i = 0; i < text.length() ; i++) {
             Map<Character, Object> child = (Map<Character, Object>) children.get(text.charAt(i));
             if (child == null) {
                 continue;
@@ -74,14 +74,17 @@ public class SimpleTrie {
     }
 
     /**
-     * 验证文本从指定位置开始,是否包含某个敏感词
+     * 验证文本从指定位置开始,是否不包含某个敏感词
      *
      * @param text  文本
      * @param index 开始位置
      * @param child 节点(当前遍历到的)
-     * @return 是否包含
+     * @return 是否不包含 true-不包含 false-包含
      */
     private boolean recursion(String text, int index, Map<Character, Object> child) {
+        if (child.containsKey(CHARACTER_END)) {
+            return false;
+        }
         if (index == text.length()) {
             return true;
         }
@@ -99,7 +102,7 @@ public class SimpleTrie {
      */
     public List<String> validate(String text) {
         Set<String> results = new HashSet<>();
-        for (int i = 0; i < text.length() - 1; i++) {
+        for (int i = 0; i < text.length(); i++) {
             Character c = text.charAt(i);
             Map<Character, Object> child = (Map<Character, Object>) children.get(c);
             if (child == null) {
@@ -123,10 +126,13 @@ public class SimpleTrie {
      * @param index  开始未知
      * @param child  节点(当前遍历到的)
      * @param result 返回敏感词
-     * @return 是否有敏感词
+     * @return 是否无敏感词 true-无 false-有
      */
     @SuppressWarnings("unchecked")
     private static boolean recursionWithResult(String text, int index, Map<Character, Object> child, StringBuilder result) {
+        if (child.containsKey(CHARACTER_END)) {
+            return false;
+        }
         if (index == text.length()) {
             return true;
         }
diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java
index 72ce16692..be566e2ed 100644
--- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java
+++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java
@@ -56,20 +56,28 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
         SensitiveWordDO wordDO2 = randomPojo(SensitiveWordDO.class, o -> o.setName("笨蛋")
                 .setTags(singletonList("蔬菜")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
         sensitiveWordMapper.insert(wordDO2);
+        SensitiveWordDO wordDO3 = randomPojo(SensitiveWordDO.class, o -> o.setName("白")
+                .setTags(singletonList("测试")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        sensitiveWordMapper.insert(wordDO3);
+        SensitiveWordDO wordDO4 = randomPojo(SensitiveWordDO.class, o -> o.setName("白痴")
+                .setTags(singletonList("测试")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        sensitiveWordMapper.insert(wordDO4);
 
         // 调用
         sensitiveWordService.initLocalCache();
         // 断言 sensitiveWordTagsCache 缓存
-        assertEquals(SetUtils.asSet("论坛", "蔬菜"), sensitiveWordService.getSensitiveWordTagSet());
+        assertEquals(SetUtils.asSet("论坛", "蔬菜","测试"), sensitiveWordService.getSensitiveWordTagSet());
         // 断言 sensitiveWordCache
-        assertEquals(2, sensitiveWordService.getSensitiveWordCache().size());
+        assertEquals(4, sensitiveWordService.getSensitiveWordCache().size());
         assertPojoEquals(wordDO1, sensitiveWordService.getSensitiveWordCache().get(0));
         assertPojoEquals(wordDO2, sensitiveWordService.getSensitiveWordCache().get(1));
+        assertPojoEquals(wordDO3, sensitiveWordService.getSensitiveWordCache().get(2));
         // 断言 tagSensitiveWordTries 缓存
         assertNotNull(sensitiveWordService.getDefaultSensitiveWordTrie());
-        assertEquals(2, sensitiveWordService.getTagSensitiveWordTries().size());
+        assertEquals(3, sensitiveWordService.getTagSensitiveWordTries().size());
         assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("论坛"));
         assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("蔬菜"));
+        assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("测试"));
     }
 
     @Test
@@ -236,6 +244,14 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
         List<String> result = sensitiveWordService.validateText(text, null);
         // 断言
         assertEquals(Arrays.asList("傻瓜", "笨蛋"), result);
+
+        // 准备参数
+        String text2 = "你是傻瓜,你是笨蛋,你是白";
+
+        // 调用
+        List<String> result2 = sensitiveWordService.validateText(text2, null);
+        // 断言
+        assertEquals(Arrays.asList("傻瓜", "笨蛋","白"), result2);
     }
 
     @Test
@@ -248,6 +264,16 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
         List<String> result = sensitiveWordService.validateText(text, singletonList("论坛"));
         // 断言
         assertEquals(singletonList("傻瓜"), result);
+
+
+        // 准备参数
+        String text2 = "你是白";
+
+        // 调用
+        List<String> result2 = sensitiveWordService.validateText(text2, singletonList("测试"));
+        // 断言
+        assertEquals(singletonList("白"), result2);
+
     }
 
     @Test
@@ -258,6 +284,12 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
 
         // 调用,断言
         assertFalse(sensitiveWordService.isTextValid(text, null));
+
+        // 准备参数
+        String text2 = "你是白";
+
+        // 调用,断言
+        assertFalse(sensitiveWordService.isTextValid(text2, null));
     }
 
     @Test
@@ -268,6 +300,12 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
 
         // 调用,断言
         assertFalse(sensitiveWordService.isTextValid(text, singletonList("论坛")));
+
+        // 准备参数
+        String text2 = "你是白";
+
+        // 调用,断言
+        assertFalse(sensitiveWordService.isTextValid(text2, singletonList("测试")));
     }
 
 }