> list(@PathVariable String type);
+}
diff --git a/pigx-common/pigx-common-sensitive/src/main/java/com/pig4cloud/pigx/common/sensitive/util/SensitiveWordsProperties.java b/pigx-common/pigx-common-sensitive/src/main/java/com/pig4cloud/pigx/common/sensitive/util/SensitiveWordsProperties.java
new file mode 100644
index 000000000..fe71341ed
--- /dev/null
+++ b/pigx-common/pigx-common-sensitive/src/main/java/com/pig4cloud/pigx/common/sensitive/util/SensitiveWordsProperties.java
@@ -0,0 +1,88 @@
+package com.pig4cloud.pigx.common.sensitive.util;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * 敏感词配置类
+ *
+ * @author lengleng
+ * @date 2024/3/26
+ *
+ */
+@Data
+@ConfigurationProperties(SensitiveWordsProperties.PREFIX)
+public class SensitiveWordsProperties {
+
+ public static final String PREFIX = "pigx.sensitive.word";
+
+ /**
+ * The sensitive words to detect.
+ */
+ private String mask = "*";
+
+ /**
+ * Whether the sensitive words detection is enabled.
+ */
+ private boolean enabled = true;
+
+ /**
+ * Whether to ignore case when detecting sensitive words.
+ */
+ private boolean ignoreCase = true;
+
+ /**
+ * Whether to ignore width (full-width and half-width characters) when detecting
+ * sensitive words.
+ */
+ private boolean ignoreWidth = true;
+
+ /**
+ * Whether to ignore number style (Arabic numerals, Roman numerals, etc.) when
+ * detecting sensitive words.
+ */
+ private boolean ignoreNumStyle = true;
+
+ /**
+ * Whether to ignore Chinese style (simplified and traditional) when detecting
+ * sensitive words.
+ */
+ private boolean ignoreChineseStyle = true;
+
+ /**
+ * Whether to ignore English style (US and UK spelling) when detecting sensitive
+ * words.
+ */
+ private boolean ignoreEnglishStyle = true;
+
+ /**
+ * Whether to ignore repeated words when detecting sensitive words.
+ */
+ private boolean ignoreRepeat = true;
+
+ /**
+ * Whether to enable number check when detecting sensitive words.
+ */
+ private boolean enableNumCheck = true;
+
+ /**
+ * Whether to enable email check when detecting sensitive words.
+ */
+ private boolean enableEmailCheck = true;
+
+ /**
+ * Whether to enable URL check when detecting sensitive words.
+ */
+ private boolean enableUrlCheck = true;
+
+ /**
+ * The length of numbers to check when detecting sensitive words.
+ */
+ private int numCheckLen = 8;
+
+ /**
+ * The error message to return when sensitive words are detected.
+ */
+ private String errorMsg = "您的输入包含敏感词,请重新输入";
+
+}
diff --git a/pigx-common/pigx-common-sensitive/src/main/java/com/pig4cloud/pigx/common/sensitive/word/SensitiveWordCustomizer.java b/pigx-common/pigx-common-sensitive/src/main/java/com/pig4cloud/pigx/common/sensitive/word/SensitiveWordCustomizer.java
new file mode 100644
index 000000000..54dd162c6
--- /dev/null
+++ b/pigx-common/pigx-common-sensitive/src/main/java/com/pig4cloud/pigx/common/sensitive/word/SensitiveWordCustomizer.java
@@ -0,0 +1,44 @@
+package com.pig4cloud.pigx.common.sensitive.word;
+
+import com.github.houbb.sensitive.word.api.IWordAllow;
+import com.github.houbb.sensitive.word.api.IWordDeny;
+import com.pig4cloud.pigx.common.core.constant.enums.YesNoEnum;
+import com.pig4cloud.pigx.common.core.util.RetOps;
+import com.pig4cloud.pigx.common.sensitive.util.RemoteSensitiveService;
+import lombok.RequiredArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author lengleng
+ * @date 2024/7/6
+ *
+ * 敏感词定制
+ */
+@RequiredArgsConstructor
+public class SensitiveWordCustomizer implements IWordAllow, IWordDeny {
+
+ private final RemoteSensitiveService remoteSensitiveService;
+
+ /**
+ * 白名单列表
+ *
+ * @return List
+ */
+ @Override
+ public List allow() {
+ return RetOps.of(remoteSensitiveService.list(YesNoEnum.YES.getCode())).getData().orElseGet(ArrayList::new);
+ }
+
+ /**
+ * 黑名单列表
+ *
+ * @return List
+ */
+ @Override
+ public List deny() {
+ return RetOps.of(remoteSensitiveService.list(YesNoEnum.NO.getCode())).getData().orElseGet(ArrayList::new);
+
+ }
+}
diff --git a/pigx-common/pigx-common-sensitive/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports b/pigx-common/pigx-common-sensitive/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports
new file mode 100644
index 000000000..0d7c25b46
--- /dev/null
+++ b/pigx-common/pigx-common-sensitive/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports
@@ -0,0 +1 @@
+com.pig4cloud.pigx.common.sensitive.util.RemoteSensitiveService
diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSensitiveWordEntity.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSensitiveWordEntity.java
new file mode 100644
index 000000000..d1834ffac
--- /dev/null
+++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSensitiveWordEntity.java
@@ -0,0 +1,91 @@
+package com.pig4cloud.pigx.admin.api.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import com.pig4cloud.pigx.common.core.util.TenantTable;
+import java.time.LocalDateTime;
+
+/**
+ * 敏感词
+ *
+ * @author pig
+ * @date 2024-07-06 15:54:43
+ */
+@Data
+@TenantTable
+@TableName("sys_sensitive_word")
+@EqualsAndHashCode(callSuper = true)
+@Schema(description = "敏感词")
+public class SysSensitiveWordEntity extends Model {
+
+
+ /**
+ * 主键
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ @Schema(description="主键")
+ private Long sensitiveId;
+
+ /**
+ * 敏感词
+ */
+ @Schema(description="敏感词")
+ private String sensitiveWord;
+
+ /**
+ * 类型
+ */
+ @Schema(description="类型")
+ private String sensitiveType;
+
+ /**
+ * 备注
+ */
+ @Schema(description="备注")
+ private String remark;
+
+ /**
+ * 创建人
+ */
+ @TableField(fill = FieldFill.INSERT)
+ @Schema(description="创建人")
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ @Schema(description="创建时间")
+ private LocalDateTime createTime;
+
+ /**
+ * 修改人
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ @Schema(description="修改人")
+ private String updateBy;
+
+ /**
+ * 修改时间
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ @Schema(description="修改时间")
+ private LocalDateTime updateTime;
+
+ /**
+ * 删除标记
+ */
+ @TableLogic
+ @TableField(fill = FieldFill.INSERT)
+ @Schema(description="删除标记")
+ private String delFlag;
+
+ /**
+ * 租户ID
+ */
+ @Schema(description="租户ID")
+ private Long tenantId;
+}
diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java
index dced0bf44..1727f2b66 100755
--- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java
+++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysSocialDetails.java
@@ -23,11 +23,11 @@ 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 lombok.experimental.FieldNameConstants;
+import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
/**
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSensitiveWordController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSensitiveWordController.java
new file mode 100644
index 000000000..18b2d7c53
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSensitiveWordController.java
@@ -0,0 +1,172 @@
+package com.pig4cloud.pigx.admin.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.pig4cloud.pigx.admin.api.entity.SysSensitiveWordEntity;
+import com.pig4cloud.pigx.admin.service.SysSensitiveWordService;
+import com.pig4cloud.pigx.common.core.constant.CacheConstants;
+import com.pig4cloud.pigx.common.core.util.R;
+import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
+import com.pig4cloud.pigx.common.log.annotation.SysLog;
+import com.pig4cloud.pigx.common.security.annotation.Inner;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springdoc.api.annotations.ParameterObject;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 敏感词
+ *
+ * @author pig
+ * @date 2024-07-06 15:54:43
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/sysSensitiveWord")
+@Tag(description = "sysSensitiveWord", name = "敏感词管理")
+@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
+public class SysSensitiveWordController {
+
+ private final SysSensitiveWordService sysSensitiveWordService;
+
+ private final RedisTemplate redisTemplate;
+
+ /**
+ * 分页查询
+ *
+ * @param page 分页对象
+ * @param sysSensitiveWord 敏感词
+ * @return
+ */
+ @Operation(summary = "分页查询", description = "分页查询")
+ @GetMapping("/page")
+ @PreAuthorize("@pms.hasPermission('admin_sysSensitiveWord_view')")
+ public R getSysSensitiveWordPage(@ParameterObject Page page, @ParameterObject SysSensitiveWordEntity sysSensitiveWord) {
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
+ wrapper.like(StrUtil.isNotBlank(sysSensitiveWord.getSensitiveWord())
+ , SysSensitiveWordEntity::getSensitiveWord, sysSensitiveWord.getSensitiveWord());
+ wrapper.eq(StrUtil.isNotBlank(sysSensitiveWord.getSensitiveType())
+ , SysSensitiveWordEntity::getSensitiveType, sysSensitiveWord.getSensitiveType());
+ return R.ok(sysSensitiveWordService.page(page, wrapper));
+ }
+
+ @Inner
+ @Operation(summary = "查询所有敏感词", description = "查询所有敏感词")
+ @GetMapping("/remote/list/{type}")
+ public R list(@PathVariable String type) {
+ return R.ok(sysSensitiveWordService.list(Wrappers.lambdaQuery()
+ .eq(SysSensitiveWordEntity::getSensitiveType, type)).stream().map(SysSensitiveWordEntity::getSensitiveWord).collect(Collectors.toList()));
+ }
+
+ /**
+ * 通过id查询敏感词
+ *
+ * @return R
+ */
+ @Operation(summary = "通过id查询", description = "通过id查询")
+ @GetMapping("/details")
+ @PreAuthorize("@pms.hasPermission('admin_sysSensitiveWord_view')")
+ public R getById(@ParameterObject SysSensitiveWordEntity sysSensitiveWord) {
+ return R.ok(sysSensitiveWordService.getOne(Wrappers.lambdaQuery(sysSensitiveWord), false));
+ }
+
+ /**
+ * 新增敏感词
+ *
+ * @param sysSensitiveWord 敏感词
+ * @return R
+ */
+ @Operation(summary = "新增敏感词", description = "新增敏感词")
+ @SysLog("新增敏感词")
+ @PostMapping
+ @PreAuthorize("@pms.hasPermission('admin_sysSensitiveWord_add')")
+ public R save(@RequestBody SysSensitiveWordEntity sysSensitiveWord) {
+ return R.ok(sysSensitiveWordService.saveSensitive(sysSensitiveWord));
+ }
+
+ /**
+ * 修改敏感词
+ *
+ * @param sysSensitiveWord 敏感词
+ * @return R
+ */
+ @Operation(summary = "修改敏感词", description = "修改敏感词")
+ @SysLog("修改敏感词")
+ @PutMapping
+ @PreAuthorize("@pms.hasPermission('admin_sysSensitiveWord_edit')")
+ public R updateById(@RequestBody SysSensitiveWordEntity sysSensitiveWord) {
+ sysSensitiveWordService.updateById(sysSensitiveWord);
+ redisTemplate.convertAndSend(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC, "刷新敏感词缓存");
+ return R.ok();
+ }
+
+ /**
+ * 查询敏感词
+ *
+ * @param sysSensitiveWord 敏感词
+ * @return R
+ */
+ @Operation(summary = "查询敏感词", description = "查询敏感词")
+ @SysLog("查询敏感词")
+ @PostMapping("/match")
+ @PreAuthorize("@pms.hasPermission('admin_sysSensitiveWord_del')")
+ public R match(@RequestBody SysSensitiveWordEntity sysSensitiveWord) {
+ return R.ok(sysSensitiveWordService.matchSensitiveWord(sysSensitiveWord));
+ }
+
+ /**
+ * 通过id删除敏感词
+ *
+ * @param ids sensitiveId列表
+ * @return R
+ */
+ @Operation(summary = "通过id删除敏感词", description = "通过id删除敏感词")
+ @SysLog("通过id删除敏感词")
+ @DeleteMapping
+ @PreAuthorize("@pms.hasPermission('admin_sysSensitiveWord_del')")
+ public R removeById(@RequestBody Long[] ids) {
+ sysSensitiveWordService.removeBatchByIds(CollUtil.toList(ids));
+ redisTemplate.convertAndSend(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC, "刷新敏感词缓存");
+ return R.ok();
+ }
+
+
+ /**
+ * 导出excel 表格
+ *
+ * @param sysSensitiveWord 查询条件
+ * @param ids 导出指定ID
+ * @return excel 文件流
+ */
+ @ResponseExcel
+ @GetMapping("/export")
+ @PreAuthorize("@pms.hasPermission('admin_sysSensitiveWord_export')")
+ public List export(SysSensitiveWordEntity sysSensitiveWord, Long[] ids) {
+ return sysSensitiveWordService.list(Wrappers.lambdaQuery(sysSensitiveWord).in(ArrayUtil.isNotEmpty(ids), SysSensitiveWordEntity::getSensitiveId, ids));
+ }
+
+ /**
+ * 刷新敏感词缓存
+ *
+ * @return R
+ */
+ @Operation(summary = "刷新敏感词缓存", description = "刷新敏感词缓存")
+ @GetMapping("/refresh")
+ @PreAuthorize("@pms.hasPermission('admin_sysSensitiveWord_del')")
+ public R refresh() {
+ redisTemplate.convertAndSend(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC, "刷新敏感词缓存");
+ return R.ok();
+ }
+}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSensitiveWordMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSensitiveWordMapper.java
new file mode 100644
index 000000000..d479b6e49
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSensitiveWordMapper.java
@@ -0,0 +1,11 @@
+package com.pig4cloud.pigx.admin.mapper;
+
+import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
+import com.pig4cloud.pigx.admin.api.entity.SysSensitiveWordEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface SysSensitiveWordMapper extends PigxBaseMapper {
+
+
+}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSensitiveWordService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSensitiveWordService.java
new file mode 100644
index 000000000..b2c64af93
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSensitiveWordService.java
@@ -0,0 +1,23 @@
+package com.pig4cloud.pigx.admin.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.pig4cloud.pigx.admin.api.entity.SysSensitiveWordEntity;
+
+import java.util.List;
+
+public interface SysSensitiveWordService extends IService {
+
+ /**
+ * 查询敏感词
+ * @param sysSensitiveWord 敏感词
+ * @return 敏感词列表
+ */
+ List matchSensitiveWord(SysSensitiveWordEntity sysSensitiveWord);
+
+ /**
+ * 保存敏感词
+ * @param sysSensitiveWord
+ * @return
+ */
+ Boolean saveSensitive(SysSensitiveWordEntity sysSensitiveWord);
+}
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSensitiveWordServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSensitiveWordServiceImpl.java
new file mode 100644
index 000000000..f8e5d6e05
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSensitiveWordServiceImpl.java
@@ -0,0 +1,65 @@
+package com.pig4cloud.pigx.admin.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.houbb.sensitive.word.bs.SensitiveWordBs;
+import com.pig4cloud.pigx.admin.api.entity.SysSensitiveWordEntity;
+import com.pig4cloud.pigx.admin.mapper.SysSensitiveWordMapper;
+import com.pig4cloud.pigx.admin.service.SysSensitiveWordService;
+import com.pig4cloud.pigx.common.core.constant.CacheConstants;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 敏感词
+ *
+ * @author pig
+ * @date 2024-07-06 15:54:43
+ */
+@Service
+@RequiredArgsConstructor
+public class SysSensitiveWordServiceImpl extends ServiceImpl implements SysSensitiveWordService {
+
+ private final RedisTemplate redisTemplate;
+
+ /**
+ * 查询敏感词
+ *
+ * @param sysSensitiveWord 敏感词
+ * @return 敏感词列表
+ */
+ @Override
+ public List matchSensitiveWord(SysSensitiveWordEntity sysSensitiveWord) {
+ SensitiveWordBs sensitiveWordBs = SpringUtil.getBean(SensitiveWordBs.class);
+ return sensitiveWordBs.findAll(sysSensitiveWord.getSensitiveWord());
+ }
+
+ /**
+ * 保存敏感词
+ *
+ * @param sysSensitiveWord 敏感词
+ * @return success/false
+ */
+ @Override
+ public Boolean saveSensitive(SysSensitiveWordEntity sysSensitiveWord) {
+ List wordEntityList = baseMapper.selectList(Wrappers.lambdaQuery().
+ eq(SysSensitiveWordEntity::getSensitiveWord, sysSensitiveWord.getSensitiveWord()));
+
+ if (CollUtil.isEmpty(wordEntityList)) {
+ save(sysSensitiveWord);
+ } else {
+ wordEntityList.forEach(wordEntity -> {
+ wordEntity.setSensitiveType(sysSensitiveWord.getSensitiveType());
+ updateById(wordEntity);
+ });
+ }
+
+ redisTemplate.convertAndSend(CacheConstants.SENSITIVE_REDIS_RELOAD_TOPIC, "刷新敏感词缓存");
+ return Boolean.TRUE;
+ }
+}
diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysSensitiveWordMapper.xml b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysSensitiveWordMapper.xml
new file mode 100644
index 000000000..d325f8383
--- /dev/null
+++ b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysSensitiveWordMapper.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+