diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index 9411b4c74..d117b58bb 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -162,6 +162,11 @@
yudao-spring-boot-starter-captcha
${revision}
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-desensitize
+ ${revision}
+
diff --git a/yudao-framework/pom.xml b/yudao-framework/pom.xml
index 53d60b7bd..c2e7d6123 100644
--- a/yudao-framework/pom.xml
+++ b/yudao-framework/pom.xml
@@ -43,6 +43,7 @@
yudao-spring-boot-starter-flowable
yudao-spring-boot-starter-captcha
+ yudao-spring-boot-starter-desensitize
yudao-framework
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/pom.xml b/yudao-framework/yudao-spring-boot-starter-desensitize/pom.xml
new file mode 100644
index 000000000..32c640eb9
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ cn.iocoder.cloud
+ yudao-framework
+ ${revision}
+
+
+ yudao-spring-boot-starter-desensitize
+ 脱敏组件:支持 JSON 返回数据时,将邮箱、手机等字段进行脱敏
+
+
+
+ cn.iocoder.cloud
+ yudao-common
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+
+ cn.iocoder.cloud
+ yudao-spring-boot-starter-test
+ test
+
+
+
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/base/annotation/DesensitizeBy.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/base/annotation/DesensitizeBy.java
new file mode 100644
index 000000000..0166cb6ef
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/base/annotation/DesensitizeBy.java
@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.framework.desensitize.core.base.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler;
+import cn.iocoder.yudao.framework.desensitize.core.base.serializer.StringDesensitizeSerializer;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 顶级脱敏注解,自定义注解需要使用此注解
+ *
+ * @author gaibu
+ */
+@Documented
+@Target(ElementType.ANNOTATION_TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside // 此注解是其他所有 jackson 注解的元注解,打上了此注解的注解表明是 jackson 注解的一部分
+@JsonSerialize(using = StringDesensitizeSerializer.class) // 指定序列化器
+public @interface DesensitizeBy {
+
+ /**
+ * 脱敏处理器
+ */
+ @SuppressWarnings("rawtypes")
+ Class extends DesensitizationHandler> handler();
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/base/handler/DesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/base/handler/DesensitizationHandler.java
new file mode 100644
index 000000000..470a0becf
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/base/handler/DesensitizationHandler.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.core.base.handler;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * 脱敏处理器接口
+ *
+ * @author gaibu
+ */
+public interface DesensitizationHandler {
+
+ /**
+ * 脱敏
+ *
+ * @param origin 原始字符串
+ * @param annotation 注解信息
+ * @return 脱敏后的字符串
+ */
+ String desensitize(String origin, T annotation);
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/base/serializer/StringDesensitizeSerializer.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/base/serializer/StringDesensitizeSerializer.java
new file mode 100644
index 000000000..2c15a747d
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/base/serializer/StringDesensitizeSerializer.java
@@ -0,0 +1,92 @@
+package cn.iocoder.yudao.framework.desensitize.core.base.serializer;
+
+import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.lang.Singleton;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.ContextualSerializer;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+/**
+ * 脱敏序列化器
+ *
+ * 实现 JSON 返回数据时,使用 {@link DesensitizationHandler} 对声明脱敏注解的字段,进行脱敏处理。
+ *
+ * @author gaibu
+ */
+@SuppressWarnings("rawtypes")
+public class StringDesensitizeSerializer extends StdSerializer implements ContextualSerializer {
+
+ @Getter
+ @Setter
+ private DesensitizationHandler desensitizationHandler;
+
+ protected StringDesensitizeSerializer() {
+ super(String.class);
+ }
+
+ @Override
+ public JsonSerializer> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) {
+ DesensitizeBy annotation = beanProperty.getAnnotation(DesensitizeBy.class);
+ if (annotation == null) {
+ return this;
+ }
+ // 创建一个 StringDesensitizeSerializer 对象,使用 DesensitizeBy 对应的处理器
+ StringDesensitizeSerializer serializer = new StringDesensitizeSerializer();
+ serializer.setDesensitizationHandler(Singleton.get(annotation.handler()));
+ return serializer;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void serialize(String value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
+ if (StrUtil.isBlank(value)) {
+ gen.writeNull();
+ return;
+ }
+ // 获取序列化字段
+ Field field = getField(gen);
+
+ // 自定义处理器
+ DesensitizeBy[] annotations = AnnotationUtil.getCombinationAnnotations(field, DesensitizeBy.class);
+ if (ArrayUtil.isEmpty(annotations)) {
+ gen.writeString(value);
+ return;
+ }
+ for (Annotation annotation : field.getAnnotations()) {
+ if (AnnotationUtil.hasAnnotation(annotation.annotationType(), DesensitizeBy.class)) {
+ value = this.desensitizationHandler.desensitize(value, annotation);
+ gen.writeString(value);
+ return;
+ }
+ }
+ gen.writeString(value);
+ }
+
+ /**
+ * 获取字段
+ *
+ * @param generator JsonGenerator
+ * @return 字段
+ */
+ private Field getField(JsonGenerator generator) {
+ String currentName = generator.getOutputContext().getCurrentName();
+ Object currentValue = generator.getCurrentValue();
+ Class> currentValueClass = currentValue.getClass();
+ return ReflectUtil.getField(currentValueClass, currentName);
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/package-info.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/package-info.java
new file mode 100644
index 000000000..d56282535
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 脱敏组件:支持 JSON 返回数据时,将邮箱、手机等字段进行脱敏
+ */
+package cn.iocoder.yudao.framework.desensitize.core;
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/annotation/EmailDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/annotation/EmailDesensitize.java
new file mode 100644
index 000000000..2e7ae3498
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/annotation/EmailDesensitize.java
@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.framework.desensitize.core.regex.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.regex.handler.EmailDesensitizationHandler;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 邮箱脱敏注解
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = EmailDesensitizationHandler.class)
+public @interface EmailDesensitize {
+
+ /**
+ * 匹配的正则表达式
+ */
+ String regex() default "(^.)[^@]*(@.*$)";
+
+ /**
+ * 替换规则,邮箱;
+ *
+ * 比如:example@gmail.com 脱敏之后 为e****@gmail.com
+ */
+ String replacer() default "$1****$2";
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/annotation/RegexDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/annotation/RegexDesensitize.java
new file mode 100644
index 000000000..4ab7c7415
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/annotation/RegexDesensitize.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.framework.desensitize.core.regex.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.regex.handler.DefaultRegexDesensitizationHandler;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 正则脱敏注解
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = DefaultRegexDesensitizationHandler.class)
+public @interface RegexDesensitize {
+
+ /**
+ * 匹配的正则表达式(默认匹配所有)
+ */
+ String regex() default "^[\\s\\S]*$";
+
+ /**
+ * 替换规则,会将匹配到的字符串全部替换成 replacer
+ *
+ * 例如:regex=123; replacer=******
+ * 原始字符串 123456789
+ * 脱敏后字符串 ******456789
+ */
+ String replacer() default "******";
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/handler/AbstractRegexDesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/handler/AbstractRegexDesensitizationHandler.java
new file mode 100644
index 000000000..f43431b1d
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/handler/AbstractRegexDesensitizationHandler.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.framework.desensitize.core.regex.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * 正则表达式脱敏处理器抽象类,已实现通用的方法
+ *
+ * @author gaibu
+ */
+public abstract class AbstractRegexDesensitizationHandler
+ implements DesensitizationHandler {
+
+ @Override
+ public String desensitize(String origin, T annotation) {
+ String regex = getRegex(annotation);
+ String replacer = getReplacer(annotation);
+ return origin.replaceAll(regex, replacer);
+ }
+
+ /**
+ * 获取注解上的 regex 参数
+ *
+ * @param annotation 注解信息
+ * @return 正则表达式
+ */
+ abstract String getRegex(T annotation);
+
+ /**
+ * 获取注解上的 replacer 参数
+ *
+ * @param annotation 注解信息
+ * @return 待替换的字符串
+ */
+ abstract String getReplacer(T annotation);
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/handler/DefaultRegexDesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/handler/DefaultRegexDesensitizationHandler.java
new file mode 100644
index 000000000..f92414e0c
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/handler/DefaultRegexDesensitizationHandler.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.core.regex.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.RegexDesensitize;
+
+/**
+ * {@link RegexDesensitize} 的正则脱敏处理器
+ *
+ * @author gaibu
+ */
+public class DefaultRegexDesensitizationHandler extends AbstractRegexDesensitizationHandler {
+
+ @Override
+ String getRegex(RegexDesensitize annotation) {
+ return annotation.regex();
+ }
+
+ @Override
+ String getReplacer(RegexDesensitize annotation) {
+ return annotation.replacer();
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/handler/EmailDesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/handler/EmailDesensitizationHandler.java
new file mode 100644
index 000000000..8d1867a64
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/regex/handler/EmailDesensitizationHandler.java
@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.framework.desensitize.core.regex.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.EmailDesensitize;
+
+/**
+ * {@link EmailDesensitize} 的脱敏处理器
+ *
+ * @author gaibu
+ */
+public class EmailDesensitizationHandler extends AbstractRegexDesensitizationHandler {
+
+ @Override
+ String getRegex(EmailDesensitize annotation) {
+ return annotation.regex();
+ }
+
+ @Override
+ String getReplacer(EmailDesensitize annotation) {
+ return annotation.replacer();
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/BankCardDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/BankCardDesensitize.java
new file mode 100644
index 000000000..ca04b2b13
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/BankCardDesensitize.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.slider.handler.BankCardDesensitization;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 银行卡号
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = BankCardDesensitization.class)
+public @interface BankCardDesensitize {
+
+ /**
+ * 前缀保留长度
+ */
+ int prefixKeep() default 6;
+
+ /**
+ * 后缀保留长度
+ */
+ int suffixKeep() default 2;
+
+ /**
+ * 替换规则,银行卡号;比如:9988002866797031脱敏之后为998800********31
+ */
+ String replacer() default "*";
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/CarLicenseDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/CarLicenseDesensitize.java
new file mode 100644
index 000000000..82a99db20
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/CarLicenseDesensitize.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.slider.handler.CarLicenseDesensitization;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 车牌号
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = CarLicenseDesensitization.class)
+public @interface CarLicenseDesensitize {
+
+ /**
+ * 前缀保留长度
+ */
+ int prefixKeep() default 3;
+
+ /**
+ * 后缀保留长度
+ */
+ int suffixKeep() default 1;
+
+ /**
+ * 替换规则,车牌号;比如:粤A66666脱敏之后为粤A6***6
+ */
+ String replacer() default "*";
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/ChineseNameDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/ChineseNameDesensitize.java
new file mode 100644
index 000000000..73a0d0ee5
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/ChineseNameDesensitize.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.slider.handler.ChineseNameDesensitization;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 中文名
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = ChineseNameDesensitization.class)
+public @interface ChineseNameDesensitize {
+
+ /**
+ * 前缀保留长度
+ */
+ int prefixKeep() default 1;
+
+ /**
+ * 后缀保留长度
+ */
+ int suffixKeep() default 0;
+
+ /**
+ * 替换规则,中文名;比如:刘子豪脱敏之后为刘**
+ */
+ String replacer() default "*";
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/FixedPhoneDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/FixedPhoneDesensitize.java
new file mode 100644
index 000000000..e847954ca
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/FixedPhoneDesensitize.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.slider.handler.FixedPhoneDesensitization;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 固定电话
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = FixedPhoneDesensitization.class)
+public @interface FixedPhoneDesensitize {
+
+ /**
+ * 前缀保留长度
+ */
+ int prefixKeep() default 4;
+
+ /**
+ * 后缀保留长度
+ */
+ int suffixKeep() default 2;
+
+ /**
+ * 替换规则,固定电话;比如:01086551122脱敏之后为0108*****22
+ */
+ String replacer() default "*";
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/IdCardDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/IdCardDesensitize.java
new file mode 100644
index 000000000..05fb73ab9
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/IdCardDesensitize.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.slider.handler.IdCardDesensitization;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 身份证
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = IdCardDesensitization.class)
+public @interface IdCardDesensitize {
+
+ /**
+ * 前缀保留长度
+ */
+ int prefixKeep() default 6;
+
+ /**
+ * 后缀保留长度
+ */
+ int suffixKeep() default 2;
+
+ /**
+ * 替换规则,身份证号码;比如:530321199204074611脱敏之后为530321**********11
+ */
+ String replacer() default "*";
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/MobileDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/MobileDesensitize.java
new file mode 100644
index 000000000..90dbcacc7
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/MobileDesensitize.java
@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.slider.handler.MobileDesensitization;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 手机号
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = MobileDesensitization.class)
+public @interface MobileDesensitize {
+
+ /**
+ * 前缀保留长度
+ */
+ int prefixKeep() default 3;
+
+ /**
+ * 后缀保留长度
+ */
+ int suffixKeep() default 4;
+
+ /**
+ * 替换规则,手机号;比如:13248765917脱敏之后为132****5917
+ */
+ String replacer() default "*";
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/PasswordDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/PasswordDesensitize.java
new file mode 100644
index 000000000..99ca5d12c
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/PasswordDesensitize.java
@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.slider.handler.PasswordDesensitization;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 密码
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = PasswordDesensitization.class)
+public @interface PasswordDesensitize {
+
+ /**
+ * 前缀保留长度
+ */
+ int prefixKeep() default 0;
+
+ /**
+ * 后缀保留长度
+ */
+ int suffixKeep() default 0;
+
+ /**
+ * 替换规则,密码;
+ *
+ * 比如:123456脱敏之后为******
+ */
+ String replacer() default "*";
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/SliderDesensitize.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/SliderDesensitize.java
new file mode 100644
index 000000000..e13e9c47c
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/annotation/SliderDesensitize.java
@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.slider.handler.DefaultDesensitizationHandler;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 滑动脱敏注解
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = DefaultDesensitizationHandler.class)
+public @interface SliderDesensitize {
+
+ /**
+ * 后缀保留长度
+ */
+ int suffixKeep() default 0;
+
+ /**
+ * 替换规则,会将前缀后缀保留后,全部替换成 replacer
+ * 例如:prefixKeep = 1; suffixKeep = 2; replacer = "*";
+ * 原始字符串 123456
+ * 脱敏后 1***56
+ */
+ String replacer() default "*";
+
+ /**
+ * 前缀保留长度
+ */
+ int prefixKeep() default 0;
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/AbstractDesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/AbstractDesensitizationHandler.java
new file mode 100644
index 000000000..e41c57319
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/AbstractDesensitizationHandler.java
@@ -0,0 +1,78 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * 滑动脱敏处理器抽象类,已实现通用的方法
+ *
+ * @author gaibu
+ */
+public abstract class AbstractDesensitizationHandler
+ implements DesensitizationHandler {
+
+ @Override
+ public String desensitize(String origin, T annotation) {
+ int prefixKeep = getPrefixKeep(annotation);
+ int suffixKeep = getSuffixKeep(annotation);
+ String replacer = getReplacer(annotation);
+ int length = origin.length();
+
+ // 情况一:原始字符串长度小于等于保留长度,则原始字符串全部替换
+ if (prefixKeep >= length || suffixKeep >= length) {
+ return buildReplacerByLength(replacer, length);
+ }
+
+ // 情况二:原始字符串长度小于等于前后缀保留字符串长度,则原始字符串全部替换
+ if ((prefixKeep + suffixKeep) >= length) {
+ return buildReplacerByLength(replacer, length);
+ }
+
+ // 情况三:原始字符串长度大于前后缀保留字符串长度,则替换中间字符串
+ int interval = length - prefixKeep - suffixKeep;
+ return origin.substring(0, prefixKeep) +
+ buildReplacerByLength(replacer, interval) +
+ origin.substring(prefixKeep + interval);
+ }
+
+ /**
+ * 根据长度循环构建替换符
+ *
+ * @param replacer 替换符
+ * @param length 长度
+ * @return 构建后的替换符
+ */
+ private String buildReplacerByLength(String replacer, int length) {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ builder.append(replacer);
+ }
+ return builder.toString();
+ }
+
+ /**
+ * 前缀保留长度
+ *
+ * @param annotation 注解信息
+ * @return 前缀保留长度
+ */
+ abstract Integer getPrefixKeep(T annotation);
+
+ /**
+ * 后缀保留长度
+ *
+ * @param annotation 注解信息
+ * @return 后缀保留长度
+ */
+ abstract Integer getSuffixKeep(T annotation);
+
+ /**
+ * 替换符
+ *
+ * @param annotation 注解信息
+ * @return 替换符
+ */
+ abstract String getReplacer(T annotation);
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/BankCardDesensitization.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/BankCardDesensitization.java
new file mode 100644
index 000000000..1447f1a38
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/BankCardDesensitization.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.BankCardDesensitize;
+
+/**
+ * {@link BankCardDesensitize} 的脱敏处理器
+ *
+ * @author gaibu
+ */
+public class BankCardDesensitization extends AbstractDesensitizationHandler {
+
+ @Override
+ Integer getPrefixKeep(BankCardDesensitize annotation) {
+ return annotation.prefixKeep();
+ }
+
+ @Override
+ Integer getSuffixKeep(BankCardDesensitize annotation) {
+ return annotation.suffixKeep();
+ }
+
+ @Override
+ String getReplacer(BankCardDesensitize annotation) {
+ return annotation.replacer();
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/CarLicenseDesensitization.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/CarLicenseDesensitization.java
new file mode 100644
index 000000000..3b10ef7ef
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/CarLicenseDesensitization.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.CarLicenseDesensitize;
+
+/**
+ * {@link CarLicenseDesensitize} 的脱敏处理器
+ *
+ * @author gaibu
+ */
+public class CarLicenseDesensitization extends AbstractDesensitizationHandler {
+ @Override
+ Integer getPrefixKeep(CarLicenseDesensitize annotation) {
+ return annotation.prefixKeep();
+ }
+
+ @Override
+ Integer getSuffixKeep(CarLicenseDesensitize annotation) {
+ return annotation.suffixKeep();
+ }
+
+ @Override
+ String getReplacer(CarLicenseDesensitize annotation) {
+ return annotation.replacer();
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/ChineseNameDesensitization.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/ChineseNameDesensitization.java
new file mode 100644
index 000000000..f75984dfa
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/ChineseNameDesensitization.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.ChineseNameDesensitize;
+
+/**
+ * {@link ChineseNameDesensitize} 的脱敏处理器
+ *
+ * @author gaibu
+ */
+public class ChineseNameDesensitization extends AbstractDesensitizationHandler {
+
+ @Override
+ Integer getPrefixKeep(ChineseNameDesensitize annotation) {
+ return annotation.prefixKeep();
+ }
+
+ @Override
+ Integer getSuffixKeep(ChineseNameDesensitize annotation) {
+ return annotation.suffixKeep();
+ }
+
+ @Override
+ String getReplacer(ChineseNameDesensitize annotation) {
+ return annotation.replacer();
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/DefaultDesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/DefaultDesensitizationHandler.java
new file mode 100644
index 000000000..1a114624b
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/DefaultDesensitizationHandler.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.SliderDesensitize;
+
+/**
+ * {@link SliderDesensitize} 的脱敏处理器
+ *
+ * @author gaibu
+ */
+public class DefaultDesensitizationHandler extends AbstractDesensitizationHandler {
+ @Override
+ Integer getPrefixKeep(SliderDesensitize annotation) {
+ return annotation.prefixKeep();
+ }
+
+ @Override
+ Integer getSuffixKeep(SliderDesensitize annotation) {
+ return annotation.suffixKeep();
+ }
+
+ @Override
+ String getReplacer(SliderDesensitize annotation) {
+ return annotation.replacer();
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/FixedPhoneDesensitization.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/FixedPhoneDesensitization.java
new file mode 100644
index 000000000..c617e46d3
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/FixedPhoneDesensitization.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.FixedPhoneDesensitize;
+
+/**
+ * {@link FixedPhoneDesensitize} 的脱敏处理器
+ *
+ * @author gaibu
+ */
+public class FixedPhoneDesensitization extends AbstractDesensitizationHandler {
+ @Override
+ Integer getPrefixKeep(FixedPhoneDesensitize annotation) {
+ return annotation.prefixKeep();
+ }
+
+ @Override
+ Integer getSuffixKeep(FixedPhoneDesensitize annotation) {
+ return annotation.suffixKeep();
+ }
+
+ @Override
+ String getReplacer(FixedPhoneDesensitize annotation) {
+ return annotation.replacer();
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/IdCardDesensitization.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/IdCardDesensitization.java
new file mode 100644
index 000000000..35db2ccd9
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/IdCardDesensitization.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.IdCardDesensitize;
+
+/**
+ * {@link IdCardDesensitize} 的脱敏处理器
+ *
+ * @author gaibu
+ */
+public class IdCardDesensitization extends AbstractDesensitizationHandler {
+ @Override
+ Integer getPrefixKeep(IdCardDesensitize annotation) {
+ return annotation.prefixKeep();
+ }
+
+ @Override
+ Integer getSuffixKeep(IdCardDesensitize annotation) {
+ return annotation.suffixKeep();
+ }
+
+ @Override
+ String getReplacer(IdCardDesensitize annotation) {
+ return annotation.replacer();
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/MobileDesensitization.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/MobileDesensitization.java
new file mode 100644
index 000000000..6c31606c5
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/MobileDesensitization.java
@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.MobileDesensitize;
+
+/**
+ * {@link MobileDesensitize} 的脱敏处理器
+ *
+ * @author gaibu
+ */
+public class MobileDesensitization extends AbstractDesensitizationHandler {
+
+ @Override
+ Integer getPrefixKeep(MobileDesensitize annotation) {
+ return annotation.prefixKeep();
+ }
+
+ @Override
+ Integer getSuffixKeep(MobileDesensitize annotation) {
+ return annotation.suffixKeep();
+ }
+
+ @Override
+ String getReplacer(MobileDesensitize annotation) {
+ return annotation.replacer();
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/PasswordDesensitization.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/PasswordDesensitization.java
new file mode 100644
index 000000000..16013f87b
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/core/slider/handler/PasswordDesensitization.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.framework.desensitize.core.slider.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.PasswordDesensitize;
+
+/**
+ * {@link PasswordDesensitize} 的码脱敏处理器
+ *
+ * @author gaibu
+ */
+public class PasswordDesensitization extends AbstractDesensitizationHandler {
+ @Override
+ Integer getPrefixKeep(PasswordDesensitize annotation) {
+ return annotation.prefixKeep();
+ }
+
+ @Override
+ Integer getSuffixKeep(PasswordDesensitize annotation) {
+ return annotation.suffixKeep();
+ }
+
+ @Override
+ String getReplacer(PasswordDesensitize annotation) {
+ return annotation.replacer();
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/DesensitizeTest.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/DesensitizeTest.java
new file mode 100644
index 000000000..e5d22636c
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/DesensitizeTest.java
@@ -0,0 +1,97 @@
+package cn.iocoder.yudao.framework.desensitize.core;
+
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
+import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.EmailDesensitize;
+import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.RegexDesensitize;
+import cn.iocoder.yudao.framework.desensitize.core.annotation.Address;
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.BankCardDesensitize;
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.CarLicenseDesensitize;
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.ChineseNameDesensitize;
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.FixedPhoneDesensitize;
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.IdCardDesensitize;
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.PasswordDesensitize;
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.MobileDesensitize;
+import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.SliderDesensitize;
+import lombok.Data;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * {@link DesensitizeTest} 的单元测试
+ */
+public class DesensitizeTest {
+
+ @Test
+ public void test() {
+ // 准备参数
+ DesensitizeDemo desensitizeDemo = new DesensitizeDemo();
+ desensitizeDemo.setNickname("芋道源码");
+ desensitizeDemo.setBankCard("9988002866797031");
+ desensitizeDemo.setCarLicense("粤A66666");
+ desensitizeDemo.setFixedPhone("01086551122");
+ desensitizeDemo.setIdCard("530321199204074611");
+ desensitizeDemo.setPassword("123456");
+ desensitizeDemo.setPhoneNumber("13248765917");
+ desensitizeDemo.setSlider1("ABCDEFG");
+ desensitizeDemo.setSlider2("ABCDEFG");
+ desensitizeDemo.setSlider3("ABCDEFG");
+ desensitizeDemo.setEmail("1@email.com");
+ desensitizeDemo.setRegex("你好,我是芋道源码");
+ desensitizeDemo.setAddress("北京市海淀区上地十街10号");
+ desensitizeDemo.setOrigin("芋道源码");
+
+ // 调用
+ DesensitizeDemo d = JsonUtils.parseObject(JsonUtils.toJsonString(desensitizeDemo), DesensitizeDemo.class);
+ // 断言
+ assertNotNull(d);
+ assertEquals("芋***", d.getNickname());
+ assertEquals("998800********31", d.getBankCard());
+ assertEquals("粤A6***6", d.getCarLicense());
+ assertEquals("0108*****22", d.getFixedPhone());
+ assertEquals("530321**********11", d.getIdCard());
+ assertEquals("******", d.getPassword());
+ assertEquals("132****5917", d.getPhoneNumber());
+ assertEquals("#######", d.getSlider1());
+ assertEquals("ABC*EFG", d.getSlider2());
+ assertEquals("*******", d.getSlider3());
+ assertEquals("1****@email.com", d.getEmail());
+ assertEquals("你好,我是*", d.getRegex());
+ assertEquals("北京市海淀区上地十街10号*", d.getAddress());
+ assertEquals("芋道源码", d.getOrigin());
+ }
+
+ @Data
+ public static class DesensitizeDemo {
+
+ @ChineseNameDesensitize
+ private String nickname;
+ @BankCardDesensitize
+ private String bankCard;
+ @CarLicenseDesensitize
+ private String carLicense;
+ @FixedPhoneDesensitize
+ private String fixedPhone;
+ @IdCardDesensitize
+ private String idCard;
+ @PasswordDesensitize
+ private String password;
+ @MobileDesensitize
+ private String phoneNumber;
+ @SliderDesensitize(prefixKeep = 6, suffixKeep = 1, replacer = "#")
+ private String slider1;
+ @SliderDesensitize(prefixKeep = 3, suffixKeep = 3)
+ private String slider2;
+ @SliderDesensitize(prefixKeep = 10)
+ private String slider3;
+ @EmailDesensitize
+ private String email;
+ @RegexDesensitize(regex = "芋道源码", replacer = "*")
+ private String regex;
+ @Address
+ private String address;
+ private String origin;
+
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/annotation/Address.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/annotation/Address.java
new file mode 100644
index 000000000..735d25b34
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/annotation/Address.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.framework.desensitize.core.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.core.DesensitizeTest;
+import cn.iocoder.yudao.framework.desensitize.core.base.annotation.DesensitizeBy;
+import cn.iocoder.yudao.framework.desensitize.core.handler.AddressHandler;
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 地址
+ *
+ * 用于 {@link DesensitizeTest} 测试使用
+ *
+ * @author gaibu
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@DesensitizeBy(handler = AddressHandler.class)
+public @interface Address {
+
+ String replacer() default "*";
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/handler/AddressHandler.java b/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/handler/AddressHandler.java
new file mode 100644
index 000000000..7a8455f8d
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/core/handler/AddressHandler.java
@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.framework.desensitize.core.handler;
+
+import cn.iocoder.yudao.framework.desensitize.core.DesensitizeTest;
+import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler;
+import cn.iocoder.yudao.framework.desensitize.core.annotation.Address;
+
+/**
+ * {@link Address} 的脱敏处理器
+ *
+ * 用于 {@link DesensitizeTest} 测试使用
+ */
+public class AddressHandler implements DesensitizationHandler {
+
+ @Override
+ public String desensitize(String origin, Address annotation) {
+ return origin + annotation.replacer();
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java
index c9d178ac8..e43e2f0f8 100644
--- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java
+++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java
@@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
-import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import java.util.List;
@@ -20,7 +19,7 @@ public class SpringFoxHandlerProviderBeanPostProcessor implements BeanPostProces
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
+ if (bean instanceof WebMvcRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
index 50586d4a6..6069f8767 100644
--- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
@@ -145,9 +145,10 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
@Bean
@ConditionalOnMissingBean(name = "xssJacksonCustomizer")
@ConditionalOnBean(ObjectMapper.class)
- public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner, XssProperties xssProperties) {
+ @ConditionalOnProperty(value = "yudao.xss.enable", havingValue = "true")
+ public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssCleaner xssCleaner) {
// 在反序列化时进行 xss 过滤,可以替换使用 XssStringJsonSerializer,在序列化时进行处理
- return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner, xssProperties));
+ return builder -> builder.deserializerByType(String.class, new XssStringJsonDeserializer(xssCleaner));
}
diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
index a9e231285..1dd82c6fa 100644
--- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
+++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
@@ -13,7 +13,6 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.util.Assert;
import org.springframework.validation.BindException;
@@ -31,7 +30,6 @@ import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.time.LocalDateTime;
-import java.time.LocalDateTime;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.*;
@@ -249,7 +247,7 @@ public class GlobalExceptionHandler {
errorLog.setExceptionName(e.getClass().getName());
errorLog.setExceptionMessage(ExceptionUtil.getMessage(e));
errorLog.setExceptionRootCauseMessage(ExceptionUtil.getRootCauseMessage(e));
- errorLog.setExceptionStackTrace(ExceptionUtils.getStackTrace(e));
+ errorLog.setExceptionStackTrace(ExceptionUtil.stacktraceToString(e));
StackTraceElement[] stackTraceElements = e.getStackTrace();
Assert.notEmpty(stackTraceElements, "异常 stackTraceElements 不能为空");
StackTraceElement stackTraceElement = stackTraceElements[0];