From 5c8e41b84791cf92cc45896071a6b96b49ba20e3 Mon Sep 17 00:00:00 2001
From: gaibu <1016771049@qq.com>
Date: Thu, 12 Jan 2023 14:54:33 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20vo=20=E8=BF=94?=
=?UTF-8?q?=E5=9B=9E=E7=9A=84=E8=84=B1=E6=95=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../pom.xml | 21 ++++-
.../desensitize/annotation/Desensitize.java | 40 +++-------
.../annotation/RegexDesensitize.java | 33 ++++++++
.../annotation/SliderDesensitize.java | 39 ++++++++++
.../constraints/BankCardDesensitize.java | 21 +++++
.../constraints/CarLicenseDesensitize.java | 21 +++++
.../constraints/ChineseNameDesensitize.java | 21 +++++
.../constraints/EmailDesensitize.java | 21 +++++
.../constraints/FixedPhoneDesensitize.java | 21 +++++
.../constraints/IdCardDesensitize.java | 21 +++++
.../constraints/PasswordDesensitize.java | 21 +++++
.../constraints/PhoneNumberDesensitize.java | 21 +++++
.../constants/DesensitizeConstants.java | 24 ------
.../enums/DesensitizationStrategyEnum.java | 49 ------------
.../DefaultDesensitizationHandler.java | 10 ---
.../handler/DesensitizationHandler.java | 2 +-
.../handler/DesensitizationHandlerHolder.java | 34 +++++++++
.../handler/RegexDesensitizationHandler.java | 13 ++++
.../handler/SliderDesensitizationHandler.java | 39 ++++++++++
.../StringDesensitizeSerializer.java | 76 +++++++++++++++++++
.../handler/DesensitizationHandlerTest.java | 25 ++++++
21 files changed, 457 insertions(+), 116 deletions(-)
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/RegexDesensitize.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/SliderDesensitize.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/BankCardDesensitize.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/CarLicenseDesensitize.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/ChineseNameDesensitize.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/EmailDesensitize.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/FixedPhoneDesensitize.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/IdCardDesensitize.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/PasswordDesensitize.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/PhoneNumberDesensitize.java
delete mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/constants/DesensitizeConstants.java
delete mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/enums/DesensitizationStrategyEnum.java
delete mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DefaultDesensitizationHandler.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandlerHolder.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/RegexDesensitizationHandler.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/SliderDesensitizationHandler.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/serializer/StringDesensitizeSerializer.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandlerTest.java
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/pom.xml
index 4119f8ea7..7f15d0d4c 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/pom.xml
@@ -4,9 +4,9 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- cn.iocoder.boot
yudao-framework
- 1.6.6-snapshot
+ cn.iocoder.boot
+ ${revision}
yudao-spring-boot-starter-biz-desensitize
@@ -22,5 +22,22 @@
cn.iocoder.boot
yudao-common
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-test
+ test
+
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/Desensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/Desensitize.java
index bf0f585c4..65dd2108d 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/Desensitize.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/Desensitize.java
@@ -1,7 +1,9 @@
package cn.iocoder.yudao.framework.desensitize.annotation;
-import cn.iocoder.yudao.framework.desensitize.enums.DesensitizationStrategyEnum;
import cn.iocoder.yudao.framework.desensitize.handler.DesensitizationHandler;
+import cn.iocoder.yudao.framework.desensitize.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;
@@ -11,40 +13,18 @@ import java.lang.annotation.Target;
/**
- * Desensitize 注解配置会覆盖 DesensitizationStrategyEnum 配置
+ * Desensitize 顶级脱敏注解
*/
-@Target({ElementType.FIELD})
-@Retention(RetentionPolicy.RUNTIME)
@Documented
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@JsonSerialize(using = StringDesensitizeSerializer.class)
public @interface Desensitize {
- /**
- * 脱敏策略
- */
- DesensitizationStrategyEnum strategy();
-
- /**
- * 脱敏替换字符
- */
- String replacer();
-
- /**
- * 正则表达式
- */
- String regex();
-
- /**
- * 前缀保留长度
- */
- int preKeep();
-
- /**
- * 后缀保留长度
- */
- int suffixKeep();
-
/**
* 脱敏处理器
*/
- Class extends DesensitizationHandler> handler();
+ Class extends DesensitizationHandler> desensitizationHandler();
+
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/RegexDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/RegexDesensitize.java
new file mode 100644
index 000000000..c2df586c4
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/RegexDesensitize.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.framework.desensitize.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.handler.RegexDesensitizationHandler;
+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;
+
+/**
+ * 正则脱敏注解
+ */
+@Documented
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@Desensitize(desensitizationHandler = RegexDesensitizationHandler.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-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/SliderDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/SliderDesensitize.java
new file mode 100644
index 000000000..ebafaa9bc
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/SliderDesensitize.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.framework.desensitize.annotation;
+
+import cn.iocoder.yudao.framework.desensitize.handler.SliderDesensitizationHandler;
+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;
+
+/**
+ * 滑动脱敏注解
+ */
+@Documented
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@Desensitize(desensitizationHandler = SliderDesensitizationHandler.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-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/BankCardDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/BankCardDesensitize.java
new file mode 100644
index 000000000..8fa73169a
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/BankCardDesensitize.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.annotation.constraints;
+
+import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize;
+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;
+
+/**
+ * 银行卡号
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@SliderDesensitize(prefixKeep = 6, suffixKeep = 2, replacer = "*") // 银行卡号;比如:9988002866797031脱敏之后为998800********31
+public @interface BankCardDesensitize {
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/CarLicenseDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/CarLicenseDesensitize.java
new file mode 100644
index 000000000..11f1f5814
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/CarLicenseDesensitize.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.annotation.constraints;
+
+import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize;
+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;
+
+/**
+ * 车牌号
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@SliderDesensitize(prefixKeep = 3, suffixKeep = 1, replacer = "*") // 车牌号;比如:粤A66666脱敏之后为粤A6***6
+public @interface CarLicenseDesensitize {
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/ChineseNameDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/ChineseNameDesensitize.java
new file mode 100644
index 000000000..97d2698ed
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/ChineseNameDesensitize.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.annotation.constraints;
+
+import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize;
+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;
+
+/**
+ * 中文名
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@SliderDesensitize(prefixKeep = 1, suffixKeep = 0, replacer = "*") // 中文名;比如:刘子豪脱敏之后为刘**
+public @interface ChineseNameDesensitize {
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/EmailDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/EmailDesensitize.java
new file mode 100644
index 000000000..142e7c0f6
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/EmailDesensitize.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.annotation.constraints;
+
+import cn.iocoder.yudao.framework.desensitize.annotation.RegexDesensitize;
+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;
+
+/**
+ * 邮箱
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@RegexDesensitize(regex = "(^.)[^@]*(@.*$)", replacer ="$1****$2") // 邮箱;比如:example@gmail.com脱敏之后为e****@gmail.com
+public @interface EmailDesensitize {
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/FixedPhoneDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/FixedPhoneDesensitize.java
new file mode 100644
index 000000000..f91988735
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/FixedPhoneDesensitize.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.annotation.constraints;
+
+import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize;
+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;
+
+/**
+ * 固定电话
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@SliderDesensitize(prefixKeep = 4, suffixKeep = 2, replacer = "*") // 固定电话;比如:01086551122脱敏之后为0108*****22
+public @interface FixedPhoneDesensitize {
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/IdCardDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/IdCardDesensitize.java
new file mode 100644
index 000000000..921019c5d
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/IdCardDesensitize.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.annotation.constraints;
+
+import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize;
+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;
+
+/**
+ * 身份证
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@SliderDesensitize(prefixKeep = 6, suffixKeep = 2, replacer = "*") // 身份证号码;比如:530321199204074611脱敏之后为530321**********11
+public @interface IdCardDesensitize {
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/PasswordDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/PasswordDesensitize.java
new file mode 100644
index 000000000..8d823a139
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/PasswordDesensitize.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.annotation.constraints;
+
+import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize;
+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;
+
+/**
+ * 密码
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@SliderDesensitize(prefixKeep = 0, suffixKeep = 0, replacer = "*") // 密码;比如:123456脱敏之后为******
+public @interface PasswordDesensitize {
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/PhoneNumberDesensitize.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/PhoneNumberDesensitize.java
new file mode 100644
index 000000000..0829c6a45
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/annotation/constraints/PhoneNumberDesensitize.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.desensitize.annotation.constraints;
+
+import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize;
+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;
+
+/**
+ * 手机号
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@JacksonAnnotationsInside
+@SliderDesensitize(prefixKeep = 3, suffixKeep = 4, replacer = "*") // 手机号;比如:13248765917脱敏之后为132****5917
+public @interface PhoneNumberDesensitize {
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/constants/DesensitizeConstants.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/constants/DesensitizeConstants.java
deleted file mode 100644
index f883173c3..000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/constants/DesensitizeConstants.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.framework.desensitize.constants;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class DesensitizeConstants {
-
- /**
- * 默认正则
- */
- public static final String DEFAULT_REGEX = null;
-
- /**
- * 默认保持长度
- */
- public static final int DEFAULT_KEEP_LENGTH = -1;
-
- /**
- * 默认替换字符
- */
- public static final String DEFAULT_REPLACER = "****";
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/enums/DesensitizationStrategyEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/enums/DesensitizationStrategyEnum.java
deleted file mode 100644
index 89a1f63c8..000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/enums/DesensitizationStrategyEnum.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package cn.iocoder.yudao.framework.desensitize.enums;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
-import static cn.iocoder.yudao.framework.desensitize.constants.DesensitizeConstants.DEFAULT_KEEP_LENGTH;
-import static cn.iocoder.yudao.framework.desensitize.constants.DesensitizeConstants.DEFAULT_REGEX;
-import static cn.iocoder.yudao.framework.desensitize.constants.DesensitizeConstants.DEFAULT_REPLACER;
-
-@Getter
-@RequiredArgsConstructor
-public enum DesensitizationStrategyEnum {
- // 常用脱敏业务
- PHONE_NUMBER(DEFAULT_REGEX, 3, 4, DEFAULT_REPLACER), // 手机号;比如:13248765917脱敏之后为132****5917
- FIXED_PHONE(DEFAULT_REGEX, 4, 2, DEFAULT_REPLACER), // 固定电话;比如:01086551122脱敏之后为0108*****22
- ID_CARD(DEFAULT_REGEX, 6, 2, DEFAULT_REPLACER), // 身份证号码;比如:530321199204074611脱敏之后为530321**********11
- BANK_CARD(DEFAULT_REGEX, 6, 2, DEFAULT_REPLACER), // 银行卡号;比如:9988002866797031脱敏之后为998800********31
- CHINESE_NAME(DEFAULT_REGEX, 1, 0, "**"),// 中文名;比如:刘子豪脱敏之后为刘**
- ADDRESS("[\\s\\S]+区", DEFAULT_KEEP_LENGTH, DEFAULT_KEEP_LENGTH, DEFAULT_REPLACER), // 地址只显示到地区,不显示详细地址;比如:广州市天河区幸福小区102号脱敏之后为广州市天河区********
- EMAIL("(^.)[^@]*(@.*$)", DEFAULT_KEEP_LENGTH, DEFAULT_KEEP_LENGTH, "$1****$2"), // 邮箱;比如:example@gmail.com脱敏之后为e******@gmail.com
- CAR_LICENSE(DEFAULT_REGEX, 3, 1, DEFAULT_REPLACER), // 车牌号;比如:粤A66666脱敏之后为粤A6***6
- PASSWORD(DEFAULT_REGEX, 0, 0, DEFAULT_REPLACER), // 密码;比如:123456脱敏之后为******
-
- // 自定义脱敏业务
- REGEX(DEFAULT_REGEX, DEFAULT_KEEP_LENGTH, DEFAULT_KEEP_LENGTH, DEFAULT_REPLACER), // 自定义正则表达式
- SLIDE(DEFAULT_REGEX, DEFAULT_KEEP_LENGTH, DEFAULT_KEEP_LENGTH, DEFAULT_REPLACER), // 滑动脱敏
- CUSTOM_HANDLE(DEFAULT_REGEX, DEFAULT_KEEP_LENGTH, DEFAULT_KEEP_LENGTH, DEFAULT_REPLACER); // 自定义处理器
- ;
-
- /**
- * 正则表达式
- */
- private final String regex;
-
- /**
- * 前缀保留长度
- */
- private final int preKeep;
-
- /**
- * 后缀保留长度
- */
- private final int suffixKeep;
-
- /**
- * 脱敏替换字符
- */
- private final String replacer;
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DefaultDesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DefaultDesensitizationHandler.java
deleted file mode 100644
index 4f8883c50..000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DefaultDesensitizationHandler.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package cn.iocoder.yudao.framework.desensitize.handler;
-
-public class DefaultDesensitizationHandler implements DesensitizationHandler {
-
- @Override
- public String handle(String origin) {
- return origin;
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandler.java
index d718aae1b..a5d06feb1 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandler.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandler.java
@@ -8,6 +8,6 @@ public interface DesensitizationHandler {
* @param origin 原始字符串
* @return 脱敏后的字符串
*/
- String handle(String origin);
+ String desensitize(String origin, Object... arg);
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandlerHolder.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandlerHolder.java
new file mode 100644
index 000000000..23336b0cf
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandlerHolder.java
@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.framework.desensitize.handler;
+
+import cn.hutool.core.util.ReflectUtil;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class DesensitizationHandlerHolder {
+ /**
+ * handler 缓存,默认初始化内置的处理器
+ */
+ private static final Map, DesensitizationHandler> HANDLER_MAP = new ConcurrentHashMap<>() {{
+ put(RegexDesensitizationHandler.class, new RegexDesensitizationHandler());
+ put(SliderDesensitizationHandler.class, new SliderDesensitizationHandler());
+ }};
+
+ public static DesensitizationHandler getDesensitizationHandler(Class extends DesensitizationHandler> clazz) {
+ DesensitizationHandler handler = HANDLER_MAP.get(clazz);
+ if (handler != null) {
+ return handler;
+ }
+ synchronized (DesensitizationHandlerHolder.class) {
+ handler = HANDLER_MAP.get(clazz);
+ // 双重校验锁
+ if (handler != null) {
+ return handler;
+ }
+ handler = ReflectUtil.newInstanceIfPossible(clazz);
+ HANDLER_MAP.put(clazz, handler);
+ }
+ return handler;
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/RegexDesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/RegexDesensitizationHandler.java
new file mode 100644
index 000000000..1846156d4
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/RegexDesensitizationHandler.java
@@ -0,0 +1,13 @@
+package cn.iocoder.yudao.framework.desensitize.handler;
+
+public class RegexDesensitizationHandler implements DesensitizationHandler {
+
+ @Override
+ public String desensitize(String origin, Object... arg) {
+ String regex = (String) arg[0];
+ String replacer = (String) arg[1];
+
+ return origin.replaceAll(regex, replacer);
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/SliderDesensitizationHandler.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/SliderDesensitizationHandler.java
new file mode 100644
index 000000000..81b9ccc50
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/handler/SliderDesensitizationHandler.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.framework.desensitize.handler;
+
+public class SliderDesensitizationHandler implements DesensitizationHandler {
+
+ @Override
+ public String desensitize(String origin, Object... arg) {
+ int prefixKeep = (Integer) arg[0];
+ int suffixKeep = (Integer) arg[1];
+ String replacer = (String) arg[2];
+
+ 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) {
+ return String.valueOf(replacer).repeat(Math.max(0, length));
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/serializer/StringDesensitizeSerializer.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/serializer/StringDesensitizeSerializer.java
new file mode 100644
index 000000000..a43b3e28e
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/main/java/cn/iocoder/yudao/framework/desensitize/serializer/StringDesensitizeSerializer.java
@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.framework.desensitize.serializer;
+
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.desensitize.annotation.Desensitize;
+import cn.iocoder.yudao.framework.desensitize.annotation.RegexDesensitize;
+import cn.iocoder.yudao.framework.desensitize.annotation.SliderDesensitize;
+import cn.iocoder.yudao.framework.desensitize.handler.DesensitizationHandler;
+import cn.iocoder.yudao.framework.desensitize.handler.DesensitizationHandlerHolder;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JsonMappingException;
+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 java.io.IOException;
+import java.lang.reflect.Field;
+
+/**
+ * 脱敏序列化器
+ */
+public class StringDesensitizeSerializer extends StdSerializer implements ContextualSerializer {
+ private final DesensitizationHandler desensitizationHandler;
+
+ protected StringDesensitizeSerializer(DesensitizationHandler desensitizationHandler) {
+ super(String.class);
+ this.desensitizationHandler = desensitizationHandler;
+ }
+
+
+ @Override
+ public JsonSerializer> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
+ Desensitize annotation = beanProperty.getAnnotation(Desensitize.class);
+ if (annotation == null) {
+ return this;
+ }
+
+ return new StringDesensitizeSerializer(DesensitizationHandlerHolder.getDesensitizationHandler(annotation.desensitizationHandler()));
+ }
+
+ @Override
+ public void serialize(String value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
+ if (StrUtil.isBlank(value)) {
+ gen.writeNull();
+ return;
+ }
+
+ String currentName = gen.getOutputContext().getCurrentName();
+ Object currentValue = gen.getCurrentValue();
+ Class> currentValueClass = currentValue.getClass();
+ Field field = ReflectUtil.getField(currentValueClass, currentName);
+
+ // 滑动处理器
+ SliderDesensitize sliderDesensitize = field.getAnnotation(SliderDesensitize.class);
+ if (sliderDesensitize != null) {
+ value = this.desensitizationHandler.desensitize(value, sliderDesensitize.prefixKeep(), sliderDesensitize.suffixKeep(), sliderDesensitize.replacer());
+ }
+
+ // 正则处理器
+ RegexDesensitize regexDesensitize = field.getAnnotation(RegexDesensitize.class);
+ if (regexDesensitize != null) {
+ value = this.desensitizationHandler.desensitize(value, regexDesensitize.regex(), regexDesensitize.replacer());
+ }
+
+ // 自定义处理器
+ Desensitize desensitize = field.getAnnotation(Desensitize.class);
+ if (desensitize != null) {
+ value = this.desensitizationHandler.desensitize(value);
+ }
+
+ gen.writeString(value);
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandlerTest.java b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandlerTest.java
new file mode 100644
index 000000000..63b4eaabf
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-desensitize/src/test/java/cn/iocoder/yudao/framework/desensitize/handler/DesensitizationHandlerTest.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.framework.desensitize.handler;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class DesensitizationHandlerTest {
+
+ @Test
+ public void testSliderDesensitizationHandler() {
+ DesensitizationHandler handler = DesensitizationHandlerHolder.getDesensitizationHandler(SliderDesensitizationHandler.class);
+
+ Assertions.assertEquals("A****FG", handler.desensitize("ABCDEFG", 1, 2, "*"));
+ Assertions.assertEquals("芋**码", handler.desensitize("芋道源码", 1, 1, "*"));
+ Assertions.assertEquals("****", handler.desensitize("芋道源码", 4, 0, "*"));
+ }
+
+ @Test
+ public void testRegexDesensitizationHandler() {
+ DesensitizationHandler handler = DesensitizationHandlerHolder.getDesensitizationHandler(RegexDesensitizationHandler.class);
+
+ Assertions.assertEquals("e****@gmail.com", handler.desensitize("example@gmail.com", "(^.)[^@]*(@.*$)", "$1****$2"));
+ Assertions.assertEquals("***,铁***", handler.desensitize("他妈的,铁废物", "他妈的|去你大爷|卧槽|草泥马|废物", "***"));
+ }
+
+}