✨ 新增 pigx-common-sensitive 脱敏模块

This commit is contained in:
冷冷 committed 2024-08-21 22:19:27 +08:00
1 parent 13f13d4813
commit f3341a4c67
24 files changed
+366 -216

No files matched your search

@@ -33,5 +33,10 @@
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-excel</artifactId>
</dependency>
<!-- 脱敏工具类-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-sensitive</artifactId>
</dependency>
</dependencies>
</project>
@@ -19,13 +19,13 @@ package com.pig4cloud.pigx.app.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.pig4cloud.pigx.common.core.sensitive.Sensitive;
import com.pig4cloud.pigx.common.core.util.ValidGroup;
import com.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
/**
@@ -1,8 +1,8 @@
package com.pig4cloud.pigx.app.api.vo;
import com.pig4cloud.pigx.app.api.entity.AppRole;
import com.pig4cloud.pigx.common.core.sensitive.Sensitive;
import com.pig4cloud.pigx.common.core.sensitive.SensitiveTypeEnum;
import com.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
import com.pig4cloud.pigx.common.sensitive.core.SensitiveTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
+6 -1
View File
@@ -14,7 +14,7 @@
<artifactId>pigx-common-bom</artifactId>
<packaging>pom</packaging>
<version>${pigx.version}</version>
<description>pigx 公共版本控制</description>
<description>pigx 公共版本控制,在此pom定义的依赖,全局业务微服务不需要指定版本。</description>
<properties>
<pigx.version>5.5.0</pigx.version>
@@ -110,6 +110,11 @@
<artifactId>pigx-common-security</artifactId>
<version>${pigx.version}</version>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-sensitive</artifactId>
<version>${pigx.version}</version>
</dependency>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-sentinel</artifactId>
@@ -1,117 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.common.core.sensitive;
import cn.hutool.core.util.DesensitizedUtil;
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.pig4cloud.pigx.common.core.util.DesensitizedUtils;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import java.io.IOException;
import java.util.Objects;
/**
* @author lengleng
* @date 2019-08-13
* <p>
* 脱敏序列化
*/
@NoArgsConstructor
@AllArgsConstructor
public class SensitiveSerialize extends JsonSerializer<String> implements ContextualSerializer {
private SensitiveTypeEnum type;
private Integer prefixNoMaskLen;
private Integer suffixNoMaskLen;
private String maskStr;
@Override
public void serialize(final String origin, final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider) throws IOException {
switch (type) {
case CHINESE_NAME:
jsonGenerator.writeString(DesensitizedUtils.chineseName(origin));
break;
case ID_CARD:
jsonGenerator.writeString(DesensitizedUtils.idCardNum(origin));
break;
case FIXED_PHONE:
jsonGenerator.writeString(DesensitizedUtils.fixedPhone(origin));
break;
case MOBILE_PHONE:
jsonGenerator.writeString(DesensitizedUtils.mobilePhone(origin));
break;
case ADDRESS:
jsonGenerator.writeString(DesensitizedUtils.address(origin));
break;
case EMAIL:
jsonGenerator.writeString(DesensitizedUtils.email(origin));
break;
case BANK_CARD:
jsonGenerator.writeString(DesensitizedUtils.bankCard(origin));
break;
case PASSWORD:
jsonGenerator.writeString(DesensitizedUtils.password(origin));
break;
case KEY:
jsonGenerator.writeString(DesensitizedUtils.key(origin));
break;
case IPV4:
jsonGenerator.writeString(DesensitizedUtils.ipv4(origin));
break;
case CAR_LICENSE:
jsonGenerator.writeString(DesensitizedUtil.carLicense(origin));
break;
case CUSTOMER:
jsonGenerator
.writeString(DesensitizedUtils.desValue(origin, prefixNoMaskLen, suffixNoMaskLen, maskStr));
break;
default:
throw new IllegalArgumentException("Unknow sensitive type enum " + type);
}
}
@Override
public JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,
final BeanProperty beanProperty) throws JsonMappingException {
if (beanProperty != null) {
if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
Sensitive sensitive = beanProperty.getAnnotation(Sensitive.class);
if (sensitive == null) {
sensitive = beanProperty.getContextAnnotation(Sensitive.class);
}
if (sensitive != null) {
return new SensitiveSerialize(sensitive.type(), sensitive.prefixNoMaskLen(),
sensitive.suffixNoMaskLen(), sensitive.maskStr());
}
}
return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
}
return serializerProvider.findNullValueSerializer(null);
}
}
@@ -1,78 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.common.core.sensitive;
/**
* 敏感信息枚举类
*
* @author mayee
* @version v1.0
**/
public enum SensitiveTypeEnum {
/**
* 自定义
*/
CUSTOMER,
/**
* 用户名, 刘*华, 徐*
*/
CHINESE_NAME,
/**
* 身份证号, 110110********1234
*/
ID_CARD,
/**
* 座机号, ****1234
*/
FIXED_PHONE,
/**
* 手机号, 176****1234
*/
MOBILE_PHONE,
/**
* 地址, 北京********
*/
ADDRESS,
/**
* 电子邮件, s*****o@xx.com
*/
EMAIL,
/**
* 银行卡, 622202************1234
*/
BANK_CARD,
/**
* 密码, 永远是 ******, 与长度无关
*/
PASSWORD,
/**
* 密钥, 【密钥】密钥除了最后三位其他都是***, 与长度无关
*/
KEY,
/**
* IPV4 类型 113.123.198.176 主机部分打码 113.123.*.123
*/
IPV4,
/**
* 中国大陆车牌,包含普通车辆、新能源车辆
*/
CAR_LICENSE
}
+64
View File
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~
~ Copyright (c) 2018-2025, lengleng All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
~ modification, are permitted provided that the following conditions are met:
~
~ Redistributions of source code must retain the above copyright notice,
~ this list of conditions and the following disclaimer.
~ Redistributions in binary form must reproduce the above copyright
~ notice, this list of conditions and the following disclaimer in the
~ documentation and/or other materials provided with the distribution.
~ Neither the name of the pig4cloud.com developer nor the names of its
~ contributors may be used to endorse or promote products derived from
~ this software without specific prior written permission.
~ Author: lengleng (wangiegie@gmail.com)
~
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common</artifactId>
<version>5.5.0</version>
</parent>
<artifactId>pigx-common-sensitive</artifactId>
<packaging>jar</packaging>
<description>pigx 输出脱敏工具类</description>
<dependencies>
<!--mvc 相关配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,48 @@
package com.pig4cloud.pigx.common.sensitive;
import com.pig4cloud.pigx.common.sensitive.core.SensitiveService;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.Objects;
/**
* 脱敏配置类
*
* @author lengleng
* @date 2024/6/27
*/
@AutoConfiguration
@Configuration(proxyBeanMethods = false)
public class SensitiveAutoConfiguration {
/**
* 不脱敏的权限
*/
public static String NO_MASK = "no_mask";
/**
* 注入默认的脱敏权限判断
*
* @return SensitiveService
*/
@Bean
@ConditionalOnMissingBean
public SensitiveService sensitiveService() {
return sensitive -> {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (Objects.isNull(authentication)) {
return true;
}
// 判断角色是否包含 no_mask 的权限
return authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority)
.noneMatch(s -> s.equals(NO_MASK));
};
}
}
@@ -15,10 +15,12 @@
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.common.core.sensitive;
package com.pig4cloud.pigx.common.sensitive.annotation;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.pig4cloud.pigx.common.sensitive.core.SensitiveSerialize;
import com.pig4cloud.pigx.common.sensitive.core.SensitiveTypeEnum;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.common.sensitive.core;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
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.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.Objects;
/**
* @author lengleng
* @date 2019-08-13
* <p>
* 脱敏序列化
*/
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class SensitiveSerialize extends JsonSerializer<String> implements ContextualSerializer {
private Sensitive sensitive;
@Override
public void serialize(final String origin, final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider) throws IOException {
if (StrUtil.isBlank(origin)) {
jsonGenerator.writeString(origin);
return;
}
// 判断是否有可以查看原文
SensitiveService sensitiveService = SpringUtil.getBean(SensitiveService.class);
if (!sensitiveService.isSensitive(sensitive)) {
jsonGenerator.writeString(origin);
return;
}
// 根据配置注解获取脱敏类型并处理
String result = sensitive.type().getStrategy().apply(sensitive, origin);
jsonGenerator.writeString(result);
}
@Override
public JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,
final BeanProperty beanProperty) throws JsonMappingException {
if (beanProperty != null) {
if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
Sensitive sensitive = beanProperty.getAnnotation(Sensitive.class);
if (sensitive == null) {
sensitive = beanProperty.getContextAnnotation(Sensitive.class);
}
if (sensitive != null) {
this.sensitive = sensitive;
return this;
}
}
return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
}
return serializerProvider.findNullValueSerializer(null);
}
}
@@ -0,0 +1,16 @@
package com.pig4cloud.pigx.common.sensitive.core;
import com.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
/**
* 脱敏逻辑增强处理
*
* @author lengleng
* @date 2024/6/27
*/
public interface SensitiveService {
/**
* 是否脱敏
*/
boolean isSensitive(Sensitive sensitive);
}
@@ -0,0 +1,11 @@
package com.pig4cloud.pigx.common.sensitive.core;
/**
* @author lengleng
* @date 2024/6/27
*/
@FunctionalInterface
public interface SensitiveStrategyFunction<T, U, R> {
R apply(T t, U u);
}
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.common.sensitive.core;
import cn.hutool.core.util.DesensitizedUtil;
import com.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
import com.pig4cloud.pigx.common.sensitive.util.DesensitizedUtils;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* 敏感信息枚举类
*
* @author mayee
* @version v1.0
**/
@RequiredArgsConstructor
public enum SensitiveTypeEnum {
/**
* 自定义
*/
CUSTOMER((sensitive, input) -> DesensitizedUtils.desValue(input, sensitive.prefixNoMaskLen(), sensitive.suffixNoMaskLen(), sensitive.maskStr())),
/**
* 用户名, 刘*华, 徐*
*/
CHINESE_NAME((sensitive, input) -> DesensitizedUtils.chineseName(input)),
/**
* 身份证号, 110110********1234
*/
ID_CARD((sensitive, input) -> DesensitizedUtils.idCardNum(input)),
/**
* 座机号, ****1234
*/
FIXED_PHONE((sensitive, input) -> DesensitizedUtils.fixedPhone(input)),
/**
* 手机号, 176****1234
*/
MOBILE_PHONE((sensitive, input) -> DesensitizedUtils.mobilePhone(input)),
/**
* 地址, 北京********
*/
ADDRESS((sensitive, input) -> DesensitizedUtils.address(input)),
/**
* 电子邮件, s*****o@xx.com
*/
EMAIL((sensitive, input) -> DesensitizedUtils.email(input)),
/**
* 银行卡, 622202************1234
*/
BANK_CARD((sensitive, input) -> DesensitizedUtils.bankCard(input)),
/**
* 密码, 永远是 ******, 与长度无关
*/
PASSWORD((sensitive, input) -> DesensitizedUtils.password(input)),
/**
* 密钥, 【密钥】密钥除第一位其他都是***, 与长度无关
*/
KEY((sensitive, input) -> DesensitizedUtils.key(input)),
/**
* IPV4 类型 113.123.198.176 主机部分打码 113.123.*.123
*/
IPV4((sensitive, input) -> DesensitizedUtils.ipv4(input)),
/**
* 中国大陆车牌,包含普通车辆、新能源车辆
*/
CAR_LICENSE((sensitive, input) -> DesensitizedUtil.carLicense(input));
/**
* 获取脱敏策略
*/
@Getter
private final SensitiveStrategyFunction<Sensitive, String, String> strategy;
}
@@ -15,7 +15,7 @@
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.common.core.util;
package com.pig4cloud.pigx.common.sensitive.util;
import cn.hutool.core.util.StrUtil;
@@ -0,0 +1 @@
com.pig4cloud.pigx.common.sensitive.SensitiveAutoConfiguration
+1
View File
@@ -49,6 +49,7 @@
<module>pigx-common-oss</module>
<module>pigx-common-seata</module>
<module>pigx-common-security</module>
<module>pigx-common-sensitive</module>
<module>pigx-common-sentinel</module>
<module>pigx-common-sequence</module>
<module>pigx-common-swagger</module>
+5
View File
@@ -64,5 +64,10 @@
<groupId>org.javers</groupId>
<artifactId>javers-core</artifactId>
</dependency>
<!-- 脱敏工具类-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-sensitive</artifactId>
</dependency>
</dependencies>
</project>
@@ -22,9 +22,9 @@ package com.pig4cloud.pigx.admin.api.entity;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.*;
import com.pig4cloud.pigx.common.core.sensitive.Sensitive;
import com.pig4cloud.pigx.common.core.sensitive.SensitiveTypeEnum;
import com.pig4cloud.pigx.common.core.util.TenantTable;
import com.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
import com.pig4cloud.pigx.common.sensitive.core.SensitiveTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.FieldNameConstants;
@@ -19,14 +19,13 @@ package com.pig4cloud.pigx.admin.api.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.pig4cloud.pigx.common.core.sensitive.Sensitive;
import com.pig4cloud.pigx.common.core.util.TenantTable;
import com.pig4cloud.pigx.common.core.util.ValidGroup;
import com.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import lombok.experimental.FieldNameConstants;
import java.time.LocalDateTime;
@@ -38,8 +37,8 @@ import java.time.LocalDateTime;
* @date 2018-08-16 21:30:41
*/
@Data
@TenantTable
@FieldNameConstants
@TenantTable
@Schema(description = "第三方账号信息")
@EqualsAndHashCode(callSuper = true)
public class SysSocialDetails extends Model<SysSocialDetails> {
@@ -21,8 +21,8 @@ package com.pig4cloud.pigx.admin.api.vo;
import com.pig4cloud.pigx.admin.api.entity.SysPost;
import com.pig4cloud.pigx.admin.api.entity.SysRole;
import com.pig4cloud.pigx.common.core.sensitive.Sensitive;
import com.pig4cloud.pigx.common.core.sensitive.SensitiveTypeEnum;
import com.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
import com.pig4cloud.pigx.common.sensitive.core.SensitiveTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
+5
View File
@@ -76,6 +76,11 @@
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-log</artifactId>
</dependency>
<!--必备:脱敏工具类-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-sensitive</artifactId>
</dependency>
<!-- sentinel-->
<dependency>
<groupId>com.pig4cloud</groupId>
@@ -18,9 +18,9 @@ package com.pig4cloud.pigx.mp.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.pig4cloud.pigx.common.core.sensitive.Sensitive;
import com.pig4cloud.pigx.common.core.sensitive.SensitiveTypeEnum;
import com.pig4cloud.pigx.common.core.util.TenantTable;
import com.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
import com.pig4cloud.pigx.common.sensitive.core.SensitiveTypeEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;
+4 -2
View File
@@ -70,10 +70,12 @@
<artifactId>pigx-common-sequence</artifactId>
</dependency>
<!--必备:脱敏工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-extra</artifactId>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-sensitive</artifactId>
</dependency>
<!--灰度支持-->
<dependency>
<groupId>com.pig4cloud</groupId>
@@ -19,9 +19,9 @@ package com.pig4cloud.pigx.pay.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.pig4cloud.pigx.common.core.sensitive.Sensitive;
import com.pig4cloud.pigx.common.core.sensitive.SensitiveTypeEnum;
import com.pig4cloud.pigx.common.core.util.TenantTable;
import com.pig4cloud.pigx.common.sensitive.annotation.Sensitive;
import com.pig4cloud.pigx.common.sensitive.core.SensitiveTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;