From e62830b2c2080f8bb2f80715e781076532c08daf Mon Sep 17 00:00:00 2001 From: ma-zhongxu Date: Thu, 5 Feb 2026 16:16:58 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=B1=A0=E5=AE=B0=E4=BF=A1=E6=81=AF=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E6=95=8F=E6=84=9F=E8=AF=8D=E6=B5=8B=E8=AF=95=202.?= =?UTF-8?q?=E6=95=8F=E6=84=9F=E8=AF=8Daop=E7=B1=BB=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/SysSlaughterInfoController.java | 4 + chenhai-common/pom.xml | 5 - .../common/annotation/SensitiveCheck.java | 17 ++ chenhai-framework/pom.xml | 5 + .../aspectj/SensitiveCheckAspect.java | 165 ++++++++++++++++++ .../src/views/system/slaughterInfo/index.vue | 6 +- 6 files changed, 194 insertions(+), 8 deletions(-) create mode 100644 chenhai-common/src/main/java/com/chenhai/common/annotation/SensitiveCheck.java create mode 100644 chenhai-framework/src/main/java/com/chenhai/framework/aspectj/SensitiveCheckAspect.java diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysSlaughterInfoController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysSlaughterInfoController.java index 4f53728..3fcd551 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysSlaughterInfoController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysSlaughterInfoController.java @@ -1,6 +1,8 @@ package com.chenhai.web.controller.system; import java.util.List; + +import com.chenhai.common.annotation.SensitiveCheck; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; @@ -72,6 +74,7 @@ public class SysSlaughterInfoController extends BaseController /** * 新增屠宰信息 */ + @SensitiveCheck @PreAuthorize("@ss.hasPermi('system:slaughterInfo:add')") @Log(title = "屠宰信息", businessType = BusinessType.INSERT) @PostMapping @@ -83,6 +86,7 @@ public class SysSlaughterInfoController extends BaseController /** * 修改屠宰信息 */ + @SensitiveCheck @PreAuthorize("@ss.hasPermi('system:slaughterInfo:edit')") @Log(title = "屠宰信息", businessType = BusinessType.UPDATE) @PutMapping diff --git a/chenhai-common/pom.xml b/chenhai-common/pom.xml index 98ad375..0d53e45 100644 --- a/chenhai-common/pom.xml +++ b/chenhai-common/pom.xml @@ -113,11 +113,6 @@ jakarta.servlet-api - - com.github.houbb - sensitive-word - - org.junit.jupiter junit-jupiter-engine diff --git a/chenhai-common/src/main/java/com/chenhai/common/annotation/SensitiveCheck.java b/chenhai-common/src/main/java/com/chenhai/common/annotation/SensitiveCheck.java new file mode 100644 index 0000000..a2e3624 --- /dev/null +++ b/chenhai-common/src/main/java/com/chenhai/common/annotation/SensitiveCheck.java @@ -0,0 +1,17 @@ +package com.chenhai.common.annotation; + +import java.lang.annotation.*; + +/** + * 敏感词校验注解 + * 加在Controller方法上,自动检查请求体中的敏感词 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface SensitiveCheck { + /** + * 是否抛出异常(默认false,直接返回错误响应) + */ + boolean throwException() default false; +} \ No newline at end of file diff --git a/chenhai-framework/pom.xml b/chenhai-framework/pom.xml index 22eaf12..fdb63f1 100644 --- a/chenhai-framework/pom.xml +++ b/chenhai-framework/pom.xml @@ -65,6 +65,11 @@ true + + com.github.houbb + sensitive-word + + \ No newline at end of file diff --git a/chenhai-framework/src/main/java/com/chenhai/framework/aspectj/SensitiveCheckAspect.java b/chenhai-framework/src/main/java/com/chenhai/framework/aspectj/SensitiveCheckAspect.java new file mode 100644 index 0000000..36412db --- /dev/null +++ b/chenhai-framework/src/main/java/com/chenhai/framework/aspectj/SensitiveCheckAspect.java @@ -0,0 +1,165 @@ +package com.chenhai.framework.aspectj; + +import com.chenhai.common.annotation.SensitiveCheck; +import com.chenhai.common.core.domain.AjaxResult; +import com.chenhai.common.exception.ServiceException; +import com.chenhai.common.utils.StringUtils; +import com.github.houbb.sensitive.word.core.SensitiveWordHelper; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint; +import org.springframework.aop.framework.ReflectiveMethodInvocation; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; + +@Aspect +@Component +public class SensitiveCheckAspect { + + @Around("@annotation(sensitiveCheck)") + public Object checkSensitiveWords(ProceedingJoinPoint joinPoint, SensitiveCheck sensitiveCheck) throws Throwable { + // 1. 收集所有敏感词 + Set allSensitiveWords = new HashSet<>(); + + Object[] args = joinPoint.getArgs(); + if (args != null) { + for (Object arg : args) { + if (arg != null) { + collectSensitiveWords(arg, allSensitiveWords); + } + } + } + + // 2. 如果有敏感词,直接返回 + if (!allSensitiveWords.isEmpty()) { + return handleResult(allSensitiveWords, sensitiveCheck); + } + + // 3. 没有敏感词,继续执行 + return joinPoint.proceed(); + } + + /** + * 递归收集敏感词 + */ + private void collectSensitiveWords(Object obj, Set sensitiveWords) { + if (obj == null) return; + + if (obj instanceof String) { + // 检查字符串 + String text = (String) obj; + if (StringUtils.isNotBlank(text)) { + sensitiveWords.addAll(SensitiveWordHelper.findAll(text)); + } + return; + } + + if (obj instanceof Collection) { + // 检查集合 + for (Object item : (Collection) obj) { + collectSensitiveWords(item, sensitiveWords); + } + } + else if (obj instanceof Map) { + // 检查Map + for (Object value : ((Map) obj).values()) { + collectSensitiveWords(value, sensitiveWords); + } + } + else if (obj.getClass().isArray()) { + // 检查数组 + if (!obj.getClass().getComponentType().isPrimitive()) { + for (Object item : (Object[]) obj) { + collectSensitiveWords(item, sensitiveWords); + } + } + } + else { + // 检查对象的所有字段 + checkObjectFields(obj, obj.getClass(), sensitiveWords); + } + } + + /** + * 检查对象字段 + */ + private void checkObjectFields(Object obj, Class clazz, Set sensitiveWords) { + // 基本类型不检查 + if (clazz.isPrimitive() || clazz == Integer.class || clazz == Long.class || + clazz == Double.class || clazz == Float.class || clazz == Boolean.class || + clazz == Byte.class || clazz == Character.class || clazz == Short.class || + clazz == Date.class) { + return; + } + + // 检查当前类的所有字段 + while (clazz != null && clazz != Object.class) { + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + // 跳过静态字段 + if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) { + continue; + } + + field.setAccessible(true); + try { + Object fieldValue = field.get(obj); + if (fieldValue != null) { + collectSensitiveWords(fieldValue, sensitiveWords); + } + } catch (IllegalAccessException e) { + // 忽略访问异常 + } + } + clazz = clazz.getSuperclass(); + } + } + + /** + * 处理结果 - 修改版:敏感词列表放在msg中 + */ + private Object handleResult(Set sensitiveWords, SensitiveCheck sensitiveCheck) { + // 转为List并排序 + List wordList = new ArrayList<>(sensitiveWords); + Collections.sort(wordList); + + // 构建消息:内容包含敏感词[词1,词2,词3] + String message = buildMessage(wordList); + + if (sensitiveCheck.throwException()) { + // 抛出异常 + throw new ServiceException(message, 400); + } else { + // 直接返回,敏感词列表在msg中 + return AjaxResult.error(message); + } + } + + /** + * 构建消息:内容包含敏感词[词1,词2,词3] + */ + private String buildMessage(List wordList) { + if (wordList.isEmpty()) { + return "内容包含敏感词"; + } + + StringBuilder sb = new StringBuilder(); + sb.append("内容包含敏感词["); + + for (int i = 0; i < wordList.size(); i++) { + if (i > 0) { + sb.append(","); + } + sb.append(wordList.get(i)); + } + + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/chenhai-ui/src/views/system/slaughterInfo/index.vue b/chenhai-ui/src/views/system/slaughterInfo/index.vue index ebcea34..f8dc5d9 100644 --- a/chenhai-ui/src/views/system/slaughterInfo/index.vue +++ b/chenhai-ui/src/views/system/slaughterInfo/index.vue @@ -168,9 +168,9 @@ >{{dict.label}} - - - + + +