Commit 9a31613e5b766977df62a4977a40ef08bdeefa0b
1 parent
8093ef3b
【移除】敏感词的管理,简化项目的复杂度
Showing
17 changed files
with
0 additions
and
1204 deletions
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sensitiveword/SensitiveWordApi.java deleted
| 1 | -package cn.iocoder.yudao.module.system.api.sensitiveword; | |
| 2 | - | |
| 3 | -import java.util.List; | |
| 4 | - | |
| 5 | -/** | |
| 6 | - * 敏感词 API 接口 | |
| 7 | - * | |
| 8 | - * @author 永不言败 | |
| 9 | - */ | |
| 10 | -public interface SensitiveWordApi { | |
| 11 | - | |
| 12 | - /** | |
| 13 | - * 获得文本所包含的不合法的敏感词数组 | |
| 14 | - * | |
| 15 | - * @param text 文本 | |
| 16 | - * @param tags 标签数组 | |
| 17 | - * @return 不合法的敏感词数组 | |
| 18 | - */ | |
| 19 | - List<String> validateText(String text, List<String> tags); | |
| 20 | - | |
| 21 | - /** | |
| 22 | - * 判断文本是否包含敏感词 | |
| 23 | - * | |
| 24 | - * @param text 文本 | |
| 25 | - * @param tags 表述数组 | |
| 26 | - * @return 是否包含 | |
| 27 | - */ | |
| 28 | - boolean isTextValid(String text, List<String> tags); | |
| 29 | - | |
| 30 | -} |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
| ... | ... | @@ -115,10 +115,6 @@ public interface ErrorCodeConstants { |
| 115 | 115 | ErrorCode TENANT_PACKAGE_USED = new ErrorCode(1_002_016_001, "租户正在使用该套餐,请给租户重新设置套餐后再尝试删除"); |
| 116 | 116 | ErrorCode TENANT_PACKAGE_DISABLE = new ErrorCode(1_002_016_002, "名字为【{}】的租户套餐已被禁用"); |
| 117 | 117 | |
| 118 | - // ========== 错误码模块 1-002-017-000 ========== | |
| 119 | - ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1_002_017_000, "错误码不存在"); | |
| 120 | - ErrorCode ERROR_CODE_DUPLICATE = new ErrorCode(1_002_017_001, "已经存在编码为【{}】的错误码"); | |
| 121 | - | |
| 122 | 118 | // ========== 社交用户 1-002-018-000 ========== |
| 123 | 119 | ErrorCode SOCIAL_USER_AUTH_FAILURE = new ErrorCode(1_002_018_000, "社交授权失败,原因是:{}"); |
| 124 | 120 | ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1_002_018_001, "社交授权失败,找不到对应的用户"); |
| ... | ... | @@ -127,10 +123,6 @@ public interface ErrorCodeConstants { |
| 127 | 123 | ErrorCode SOCIAL_CLIENT_NOT_EXISTS = new ErrorCode(1_002_018_201, "社交客户端不存在"); |
| 128 | 124 | ErrorCode SOCIAL_CLIENT_UNIQUE = new ErrorCode(1_002_018_202, "社交客户端已存在配置"); |
| 129 | 125 | |
| 130 | - // ========== 系统敏感词 1-002-019-000 ========= | |
| 131 | - ErrorCode SENSITIVE_WORD_NOT_EXISTS = new ErrorCode(1_002_019_000, "系统敏感词在所有标签中都不存在"); | |
| 132 | - ErrorCode SENSITIVE_WORD_EXISTS = new ErrorCode(1_002_019_001, "系统敏感词已在标签中存在"); | |
| 133 | - | |
| 134 | 126 | // ========== OAuth2 客户端 1-002-020-000 ========= |
| 135 | 127 | ErrorCode OAUTH2_CLIENT_NOT_EXISTS = new ErrorCode(1_002_020_000, "OAuth2 客户端不存在"); |
| 136 | 128 | ErrorCode OAUTH2_CLIENT_EXISTS = new ErrorCode(1_002_020_001, "OAuth2 客户端编号已存在"); | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/sensitiveword/SensitiveWordApiImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.system.api.sensitiveword; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.module.system.service.sensitiveword.SensitiveWordService; | |
| 4 | -import org.springframework.stereotype.Service; | |
| 5 | - | |
| 6 | -import jakarta.annotation.Resource; | |
| 7 | -import java.util.List; | |
| 8 | - | |
| 9 | -/** | |
| 10 | - * 敏感词 API 实现类 | |
| 11 | - * | |
| 12 | - * @author 永不言败 | |
| 13 | - */ | |
| 14 | -@Service | |
| 15 | -public class SensitiveWordApiImpl implements SensitiveWordApi { | |
| 16 | - | |
| 17 | - @Resource | |
| 18 | - private SensitiveWordService sensitiveWordService; | |
| 19 | - | |
| 20 | - @Override | |
| 21 | - public List<String> validateText(String text, List<String> tags) { | |
| 22 | - return sensitiveWordService.validateText(text, tags); | |
| 23 | - } | |
| 24 | - | |
| 25 | - @Override | |
| 26 | - public boolean isTextValid(String text, List<String> tags) { | |
| 27 | - return sensitiveWordService.isTextValid(text, tags); | |
| 28 | - } | |
| 29 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.http deleted
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java deleted
| 1 | -package cn.iocoder.yudao.module.system.controller.admin.sensitiveword; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; | |
| 4 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 5 | -import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 6 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 7 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 8 | -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | |
| 9 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO; | |
| 10 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordRespVO; | |
| 11 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordSaveVO; | |
| 12 | -import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO; | |
| 13 | -import cn.iocoder.yudao.module.system.service.sensitiveword.SensitiveWordService; | |
| 14 | -import io.swagger.v3.oas.annotations.Operation; | |
| 15 | -import io.swagger.v3.oas.annotations.Parameter; | |
| 16 | -import io.swagger.v3.oas.annotations.tags.Tag; | |
| 17 | -import jakarta.annotation.Resource; | |
| 18 | -import jakarta.servlet.http.HttpServletResponse; | |
| 19 | -import jakarta.validation.Valid; | |
| 20 | -import org.springframework.security.access.prepost.PreAuthorize; | |
| 21 | -import org.springframework.validation.annotation.Validated; | |
| 22 | -import org.springframework.web.bind.annotation.*; | |
| 23 | - | |
| 24 | -import java.io.IOException; | |
| 25 | -import java.util.List; | |
| 26 | -import java.util.Set; | |
| 27 | - | |
| 28 | -import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; | |
| 29 | -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 30 | - | |
| 31 | -@Tag(name = "管理后台 - 敏感词") | |
| 32 | -@RestController | |
| 33 | -@RequestMapping("/system/sensitive-word") | |
| 34 | -@Validated | |
| 35 | -public class SensitiveWordController { | |
| 36 | - | |
| 37 | - @Resource | |
| 38 | - private SensitiveWordService sensitiveWordService; | |
| 39 | - | |
| 40 | - @PostMapping("/create") | |
| 41 | - @Operation(summary = "创建敏感词") | |
| 42 | - @PreAuthorize("@ss.hasPermission('system:sensitive-word:create')") | |
| 43 | - public CommonResult<Long> createSensitiveWord(@Valid @RequestBody SensitiveWordSaveVO createReqVO) { | |
| 44 | - return success(sensitiveWordService.createSensitiveWord(createReqVO)); | |
| 45 | - } | |
| 46 | - | |
| 47 | - @PutMapping("/update") | |
| 48 | - @Operation(summary = "更新敏感词") | |
| 49 | - @PreAuthorize("@ss.hasPermission('system:sensitive-word:update')") | |
| 50 | - public CommonResult<Boolean> updateSensitiveWord(@Valid @RequestBody SensitiveWordSaveVO updateReqVO) { | |
| 51 | - sensitiveWordService.updateSensitiveWord(updateReqVO); | |
| 52 | - return success(true); | |
| 53 | - } | |
| 54 | - | |
| 55 | - @DeleteMapping("/delete") | |
| 56 | - @Operation(summary = "删除敏感词") | |
| 57 | - @Parameter(name = "id", description = "编号", required = true) | |
| 58 | - @PreAuthorize("@ss.hasPermission('system:sensitive-word:delete')") | |
| 59 | - public CommonResult<Boolean> deleteSensitiveWord(@RequestParam("id") Long id) { | |
| 60 | - sensitiveWordService.deleteSensitiveWord(id); | |
| 61 | - return success(true); | |
| 62 | - } | |
| 63 | - | |
| 64 | - @GetMapping("/get") | |
| 65 | - @Operation(summary = "获得敏感词") | |
| 66 | - @Parameter(name = "id", description = "编号", required = true, example = "1024") | |
| 67 | - @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')") | |
| 68 | - public CommonResult<SensitiveWordRespVO> getSensitiveWord(@RequestParam("id") Long id) { | |
| 69 | - SensitiveWordDO sensitiveWord = sensitiveWordService.getSensitiveWord(id); | |
| 70 | - return success(BeanUtils.toBean(sensitiveWord, SensitiveWordRespVO.class)); | |
| 71 | - } | |
| 72 | - | |
| 73 | - @GetMapping("/page") | |
| 74 | - @Operation(summary = "获得敏感词分页") | |
| 75 | - @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')") | |
| 76 | - public CommonResult<PageResult<SensitiveWordRespVO>> getSensitiveWordPage(@Valid SensitiveWordPageReqVO pageVO) { | |
| 77 | - PageResult<SensitiveWordDO> pageResult = sensitiveWordService.getSensitiveWordPage(pageVO); | |
| 78 | - return success(BeanUtils.toBean(pageResult, SensitiveWordRespVO.class)); | |
| 79 | - } | |
| 80 | - | |
| 81 | - @GetMapping("/export-excel") | |
| 82 | - @Operation(summary = "导出敏感词 Excel") | |
| 83 | - @PreAuthorize("@ss.hasPermission('system:sensitive-word:export')") | |
| 84 | - @ApiAccessLog(operateType = EXPORT) | |
| 85 | - public void exportSensitiveWordExcel(@Valid SensitiveWordPageReqVO exportReqVO, | |
| 86 | - HttpServletResponse response) throws IOException { | |
| 87 | - exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); | |
| 88 | - List<SensitiveWordDO> list = sensitiveWordService.getSensitiveWordPage(exportReqVO).getList(); | |
| 89 | - // 导出 Excel | |
| 90 | - ExcelUtils.write(response, "敏感词.xls", "数据", SensitiveWordRespVO.class, | |
| 91 | - BeanUtils.toBean(list, SensitiveWordRespVO.class)); | |
| 92 | - } | |
| 93 | - | |
| 94 | - @GetMapping("/get-tags") | |
| 95 | - @Operation(summary = "获取所有敏感词的标签数组") | |
| 96 | - @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')") | |
| 97 | - public CommonResult<Set<String>> getSensitiveWordTagSet() { | |
| 98 | - return success(sensitiveWordService.getSensitiveWordTagSet()); | |
| 99 | - } | |
| 100 | - | |
| 101 | - @GetMapping("/validate-text") | |
| 102 | - @Operation(summary = "获得文本所包含的不合法的敏感词数组") | |
| 103 | - public CommonResult<List<String>> validateText(@RequestParam("text") String text, | |
| 104 | - @RequestParam(value = "tags", required = false) List<String> tags) { | |
| 105 | - return success(sensitiveWordService.validateText(text, tags)); | |
| 106 | - } | |
| 107 | - | |
| 108 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 5 | -import lombok.Data; | |
| 6 | -import lombok.EqualsAndHashCode; | |
| 7 | -import lombok.ToString; | |
| 8 | -import org.springframework.format.annotation.DateTimeFormat; | |
| 9 | - | |
| 10 | -import java.time.LocalDateTime; | |
| 11 | - | |
| 12 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 13 | - | |
| 14 | -@Schema(description = "管理后台 - 敏感词分页 Request VO") | |
| 15 | -@Data | |
| 16 | -@EqualsAndHashCode(callSuper = true) | |
| 17 | -@ToString(callSuper = true) | |
| 18 | -public class SensitiveWordPageReqVO extends PageParam { | |
| 19 | - | |
| 20 | - @Schema(description = "敏感词", example = "敏感词") | |
| 21 | - private String name; | |
| 22 | - | |
| 23 | - @Schema(description = "标签", example = "短信,评论") | |
| 24 | - private String tag; | |
| 25 | - | |
| 26 | - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1") | |
| 27 | - private Integer status; | |
| 28 | - | |
| 29 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 30 | - @Schema(description = "创建时间") | |
| 31 | - private LocalDateTime[] createTime; | |
| 32 | - | |
| 33 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; | |
| 4 | -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; | |
| 5 | -import cn.iocoder.yudao.framework.excel.core.convert.JsonConvert; | |
| 6 | -import cn.iocoder.yudao.module.system.enums.DictTypeConstants; | |
| 7 | -import com.alibaba.excel.annotation.ExcelProperty; | |
| 8 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 9 | -import lombok.Data; | |
| 10 | -import lombok.EqualsAndHashCode; | |
| 11 | -import lombok.ToString; | |
| 12 | - | |
| 13 | -import java.time.LocalDateTime; | |
| 14 | -import java.util.List; | |
| 15 | - | |
| 16 | -@Schema(description = "管理后台 - 敏感词 Response VO") | |
| 17 | -@Data | |
| 18 | -public class SensitiveWordRespVO { | |
| 19 | - | |
| 20 | - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 21 | - @ExcelProperty("编号") | |
| 22 | - private Long id; | |
| 23 | - | |
| 24 | - @Schema(description = "敏感词", requiredMode = Schema.RequiredMode.REQUIRED, example = "敏感词") | |
| 25 | - @ExcelProperty("敏感词") | |
| 26 | - private String name; | |
| 27 | - | |
| 28 | - @Schema(description = "标签", requiredMode = Schema.RequiredMode.REQUIRED, example = "短信,评论") | |
| 29 | - @ExcelProperty(value = "标签", converter = JsonConvert.class) | |
| 30 | - private List<String> tags; | |
| 31 | - | |
| 32 | - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 33 | - @ExcelProperty(value = "状态", converter = DictConvert.class) | |
| 34 | - @DictFormat(DictTypeConstants.COMMON_STATUS) | |
| 35 | - private Integer status; | |
| 36 | - | |
| 37 | - @Schema(description = "描述", example = "污言秽语") | |
| 38 | - @ExcelProperty("描述") | |
| 39 | - private String description; | |
| 40 | - | |
| 41 | - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 42 | - @ExcelProperty("创建时间") | |
| 43 | - private LocalDateTime createTime; | |
| 44 | - | |
| 45 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordSaveVO.java deleted
| 1 | -package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo; | |
| 2 | - | |
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | -import lombok.Data; | |
| 5 | - | |
| 6 | -import jakarta.validation.constraints.NotNull; | |
| 7 | -import java.util.List; | |
| 8 | - | |
| 9 | -@Schema(description = "管理后台 - 敏感词创建/修改 Request VO") | |
| 10 | -@Data | |
| 11 | -public class SensitiveWordSaveVO { | |
| 12 | - | |
| 13 | - @Schema(description = "编号", example = "1") | |
| 14 | - private Long id; | |
| 15 | - | |
| 16 | - @Schema(description = "敏感词", requiredMode = Schema.RequiredMode.REQUIRED, example = "敏感词") | |
| 17 | - @NotNull(message = "敏感词不能为空") | |
| 18 | - private String name; | |
| 19 | - | |
| 20 | - @Schema(description = "标签", requiredMode = Schema.RequiredMode.REQUIRED, example = "短信,评论") | |
| 21 | - @NotNull(message = "标签不能为空") | |
| 22 | - private List<String> tags; | |
| 23 | - | |
| 24 | - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 25 | - @NotNull(message = "状态不能为空") | |
| 26 | - private Integer status; | |
| 27 | - | |
| 28 | - @Schema(description = "描述", example = "污言秽语") | |
| 29 | - private String description; | |
| 30 | - | |
| 31 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/sensitiveword/SensitiveWordDO.java deleted
| 1 | -package cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 4 | -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 5 | -import cn.iocoder.yudao.framework.mybatis.core.type.StringListTypeHandler; | |
| 6 | -import com.baomidou.mybatisplus.annotation.KeySequence; | |
| 7 | -import com.baomidou.mybatisplus.annotation.TableField; | |
| 8 | -import com.baomidou.mybatisplus.annotation.TableId; | |
| 9 | -import com.baomidou.mybatisplus.annotation.TableName; | |
| 10 | -import lombok.*; | |
| 11 | - | |
| 12 | -import java.util.List; | |
| 13 | - | |
| 14 | -/** | |
| 15 | - * 敏感词 DO | |
| 16 | - * | |
| 17 | - * @author 永不言败 | |
| 18 | - */ | |
| 19 | -@TableName(value = "system_sensitive_word", autoResultMap = true) | |
| 20 | -@KeySequence("system_sensitive_word_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | |
| 21 | -@Data | |
| 22 | -@EqualsAndHashCode(callSuper = true) | |
| 23 | -@ToString(callSuper = true) | |
| 24 | -@Builder | |
| 25 | -@NoArgsConstructor | |
| 26 | -@AllArgsConstructor | |
| 27 | -public class SensitiveWordDO extends BaseDO { | |
| 28 | - | |
| 29 | - /** | |
| 30 | - * 编号 | |
| 31 | - */ | |
| 32 | - @TableId | |
| 33 | - private Long id; | |
| 34 | - /** | |
| 35 | - * 敏感词 | |
| 36 | - */ | |
| 37 | - private String name; | |
| 38 | - /** | |
| 39 | - * 描述 | |
| 40 | - */ | |
| 41 | - private String description; | |
| 42 | - /** | |
| 43 | - * 标签数组 | |
| 44 | - * | |
| 45 | - * 用于实现不同的业务场景下,需要使用不同标签的敏感词。 | |
| 46 | - * 例如说,tag 有短信、论坛两种,敏感词 "推广" 在短信下是敏感词,在论坛下不是敏感词。 | |
| 47 | - * 此时,我们会存储一条敏感词记录,它的 name 为"推广",tag 为短信。 | |
| 48 | - */ | |
| 49 | - @TableField(typeHandler = StringListTypeHandler.class) | |
| 50 | - private List<String> tags; | |
| 51 | - /** | |
| 52 | - * 状态 | |
| 53 | - * | |
| 54 | - * 枚举 {@link CommonStatusEnum} | |
| 55 | - */ | |
| 56 | - private Integer status; | |
| 57 | - | |
| 58 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sensitiveword/SensitiveWordMapper.java deleted
| 1 | -package cn.iocoder.yudao.module.system.dal.mysql.sensitiveword; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 5 | -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 6 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO; | |
| 7 | -import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO; | |
| 8 | -import org.apache.ibatis.annotations.Mapper; | |
| 9 | -import org.apache.ibatis.annotations.Select; | |
| 10 | - | |
| 11 | -import java.time.LocalDateTime; | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * 敏感词 Mapper | |
| 15 | - * | |
| 16 | - * @author 永不言败 | |
| 17 | - */ | |
| 18 | -@Mapper | |
| 19 | -public interface SensitiveWordMapper extends BaseMapperX<SensitiveWordDO> { | |
| 20 | - | |
| 21 | - default PageResult<SensitiveWordDO> selectPage(SensitiveWordPageReqVO reqVO) { | |
| 22 | - return selectPage(reqVO, new LambdaQueryWrapperX<SensitiveWordDO>() | |
| 23 | - .likeIfPresent(SensitiveWordDO::getName, reqVO.getName()) | |
| 24 | - .likeIfPresent(SensitiveWordDO::getTags, reqVO.getTag()) | |
| 25 | - .eqIfPresent(SensitiveWordDO::getStatus, reqVO.getStatus()) | |
| 26 | - .betweenIfPresent(SensitiveWordDO::getCreateTime, reqVO.getCreateTime()) | |
| 27 | - .orderByDesc(SensitiveWordDO::getId)); | |
| 28 | - } | |
| 29 | - default SensitiveWordDO selectByName(String name) { | |
| 30 | - return selectOne(SensitiveWordDO::getName, name); | |
| 31 | - } | |
| 32 | - | |
| 33 | - @Select("SELECT COUNT(*) FROM system_sensitive_word WHERE update_time > #{maxUpdateTime}") | |
| 34 | - Long selectCountByUpdateTimeGt(LocalDateTime maxTime); | |
| 35 | - | |
| 36 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java deleted
| 1 | -package cn.iocoder.yudao.module.system.service.sensitiveword; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO; | |
| 5 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordSaveVO; | |
| 6 | -import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO; | |
| 7 | - | |
| 8 | -import jakarta.validation.Valid; | |
| 9 | -import java.util.List; | |
| 10 | -import java.util.Set; | |
| 11 | - | |
| 12 | -/** | |
| 13 | - * 敏感词 Service 接口 | |
| 14 | - * | |
| 15 | - * @author 永不言败 | |
| 16 | - */ | |
| 17 | -public interface SensitiveWordService { | |
| 18 | - | |
| 19 | - /** | |
| 20 | - * 创建敏感词 | |
| 21 | - * | |
| 22 | - * @param createReqVO 创建信息 | |
| 23 | - * @return 编号 | |
| 24 | - */ | |
| 25 | - Long createSensitiveWord(@Valid SensitiveWordSaveVO createReqVO); | |
| 26 | - | |
| 27 | - /** | |
| 28 | - * 更新敏感词 | |
| 29 | - * | |
| 30 | - * @param updateReqVO 更新信息 | |
| 31 | - */ | |
| 32 | - void updateSensitiveWord(@Valid SensitiveWordSaveVO updateReqVO); | |
| 33 | - | |
| 34 | - /** | |
| 35 | - * 删除敏感词 | |
| 36 | - * | |
| 37 | - * @param id 编号 | |
| 38 | - */ | |
| 39 | - void deleteSensitiveWord(Long id); | |
| 40 | - | |
| 41 | - /** | |
| 42 | - * 获得敏感词 | |
| 43 | - * | |
| 44 | - * @param id 编号 | |
| 45 | - * @return 敏感词 | |
| 46 | - */ | |
| 47 | - SensitiveWordDO getSensitiveWord(Long id); | |
| 48 | - | |
| 49 | - /** | |
| 50 | - * 获得敏感词列表 | |
| 51 | - * | |
| 52 | - * @return 敏感词列表 | |
| 53 | - */ | |
| 54 | - List<SensitiveWordDO> getSensitiveWordList(); | |
| 55 | - | |
| 56 | - /** | |
| 57 | - * 获得敏感词分页 | |
| 58 | - * | |
| 59 | - * @param pageReqVO 分页查询 | |
| 60 | - * @return 敏感词分页 | |
| 61 | - */ | |
| 62 | - PageResult<SensitiveWordDO> getSensitiveWordPage(SensitiveWordPageReqVO pageReqVO); | |
| 63 | - | |
| 64 | - /** | |
| 65 | - * 获得所有敏感词的标签数组 | |
| 66 | - * | |
| 67 | - * @return 标签数组 | |
| 68 | - */ | |
| 69 | - Set<String> getSensitiveWordTagSet(); | |
| 70 | - | |
| 71 | - /** | |
| 72 | - * 获得文本所包含的不合法的敏感词数组 | |
| 73 | - * | |
| 74 | - * @param text 文本 | |
| 75 | - * @param tags 标签数组 | |
| 76 | - * @return 不合法的敏感词数组 | |
| 77 | - */ | |
| 78 | - List<String> validateText(String text, List<String> tags); | |
| 79 | - | |
| 80 | - /** | |
| 81 | - * 判断文本是否包含敏感词 | |
| 82 | - * | |
| 83 | - * @param text 文本 | |
| 84 | - * @param tags 标签数组 | |
| 85 | - * @return 是否包含敏感词 | |
| 86 | - */ | |
| 87 | - boolean isTextValid(String text, List<String> tags); | |
| 88 | - | |
| 89 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.system.service.sensitiveword; | |
| 2 | - | |
| 3 | -import cn.hutool.core.collection.CollUtil; | |
| 4 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 5 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 7 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 8 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO; | |
| 9 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordSaveVO; | |
| 10 | -import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO; | |
| 11 | -import cn.iocoder.yudao.module.system.dal.mysql.sensitiveword.SensitiveWordMapper; | |
| 12 | -import cn.iocoder.yudao.module.system.util.collection.SimpleTrie; | |
| 13 | -import com.google.common.collect.HashMultimap; | |
| 14 | -import com.google.common.collect.Multimap; | |
| 15 | -import lombok.Getter; | |
| 16 | -import lombok.extern.slf4j.Slf4j; | |
| 17 | -import org.springframework.scheduling.annotation.Scheduled; | |
| 18 | -import org.springframework.stereotype.Service; | |
| 19 | -import org.springframework.util.Assert; | |
| 20 | -import org.springframework.validation.annotation.Validated; | |
| 21 | - | |
| 22 | -import jakarta.annotation.PostConstruct; | |
| 23 | -import jakarta.annotation.Resource; | |
| 24 | -import java.time.LocalDateTime; | |
| 25 | -import java.util.*; | |
| 26 | -import java.util.concurrent.TimeUnit; | |
| 27 | - | |
| 28 | -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 29 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; | |
| 30 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue; | |
| 31 | -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_WORD_EXISTS; | |
| 32 | -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_WORD_NOT_EXISTS; | |
| 33 | - | |
| 34 | -/** | |
| 35 | - * 敏感词 Service 实现类 | |
| 36 | - * | |
| 37 | - * @author 永不言败 | |
| 38 | - */ | |
| 39 | -@Service | |
| 40 | -@Slf4j | |
| 41 | -@Validated | |
| 42 | -public class SensitiveWordServiceImpl implements SensitiveWordService { | |
| 43 | - | |
| 44 | - /** | |
| 45 | - * 是否开启敏感词功能 | |
| 46 | - */ | |
| 47 | - public static Boolean ENABLED = false; | |
| 48 | - | |
| 49 | - /** | |
| 50 | - * 敏感词列表缓存 | |
| 51 | - */ | |
| 52 | - @Getter | |
| 53 | - private volatile List<SensitiveWordDO> sensitiveWordCache = Collections.emptyList(); | |
| 54 | - /** | |
| 55 | - * 敏感词标签缓存 | |
| 56 | - * key:敏感词编号 {@link SensitiveWordDO#getId()} | |
| 57 | - * <p> | |
| 58 | - * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 | |
| 59 | - */ | |
| 60 | - @Getter | |
| 61 | - private volatile Set<String> sensitiveWordTagsCache = Collections.emptySet(); | |
| 62 | - | |
| 63 | - @Resource | |
| 64 | - private SensitiveWordMapper sensitiveWordMapper; | |
| 65 | - | |
| 66 | - /** | |
| 67 | - * 默认的敏感词的字典树,包含所有敏感词 | |
| 68 | - */ | |
| 69 | - @Getter | |
| 70 | - private volatile SimpleTrie defaultSensitiveWordTrie = new SimpleTrie(Collections.emptySet()); | |
| 71 | - /** | |
| 72 | - * 标签与敏感词的字段数的映射 | |
| 73 | - */ | |
| 74 | - @Getter | |
| 75 | - private volatile Map<String, SimpleTrie> tagSensitiveWordTries = Collections.emptyMap(); | |
| 76 | - | |
| 77 | - /** | |
| 78 | - * 初始化缓存 | |
| 79 | - */ | |
| 80 | - @PostConstruct | |
| 81 | - public void initLocalCache() { | |
| 82 | - if (!ENABLED) { | |
| 83 | - return; | |
| 84 | - } | |
| 85 | - | |
| 86 | - // 第一步:查询数据 | |
| 87 | - List<SensitiveWordDO> sensitiveWords = sensitiveWordMapper.selectList(); | |
| 88 | - log.info("[initLocalCache][缓存敏感词,数量为:{}]", sensitiveWords.size()); | |
| 89 | - | |
| 90 | - // 第二步:构建缓存 | |
| 91 | - // 写入 sensitiveWordTagsCache 缓存 | |
| 92 | - Set<String> tags = new HashSet<>(); | |
| 93 | - sensitiveWords.forEach(word -> tags.addAll(word.getTags())); | |
| 94 | - sensitiveWordTagsCache = tags; | |
| 95 | - sensitiveWordCache = sensitiveWords; | |
| 96 | - // 写入 defaultSensitiveWordTrie、tagSensitiveWordTries 缓存 | |
| 97 | - initSensitiveWordTrie(sensitiveWords); | |
| 98 | - } | |
| 99 | - | |
| 100 | - private void initSensitiveWordTrie(List<SensitiveWordDO> wordDOs) { | |
| 101 | - // 过滤禁用的敏感词 | |
| 102 | - wordDOs = filterList(wordDOs, word -> word.getStatus().equals(CommonStatusEnum.ENABLE.getStatus())); | |
| 103 | - | |
| 104 | - // 初始化默认的 defaultSensitiveWordTrie | |
| 105 | - this.defaultSensitiveWordTrie = new SimpleTrie(CollectionUtils.convertList(wordDOs, SensitiveWordDO::getName)); | |
| 106 | - | |
| 107 | - // 初始化 tagSensitiveWordTries | |
| 108 | - Multimap<String, String> tagWords = HashMultimap.create(); | |
| 109 | - for (SensitiveWordDO word : wordDOs) { | |
| 110 | - if (CollUtil.isEmpty(word.getTags())) { | |
| 111 | - continue; | |
| 112 | - } | |
| 113 | - word.getTags().forEach(tag -> tagWords.put(tag, word.getName())); | |
| 114 | - } | |
| 115 | - // 添加到 tagSensitiveWordTries 中 | |
| 116 | - Map<String, SimpleTrie> tagSensitiveWordTries = new HashMap<>(); | |
| 117 | - tagWords.asMap().forEach((tag, words) -> tagSensitiveWordTries.put(tag, new SimpleTrie(words))); | |
| 118 | - this.tagSensitiveWordTries = tagSensitiveWordTries; | |
| 119 | - } | |
| 120 | - | |
| 121 | - /** | |
| 122 | - * 通过定时任务轮询,刷新缓存 | |
| 123 | - * | |
| 124 | - * 目的:多节点部署时,通过轮询”通知“所有节点,进行刷新 | |
| 125 | - */ | |
| 126 | - @Scheduled(initialDelay = 60, fixedRate = 60, timeUnit = TimeUnit.SECONDS) | |
| 127 | - public void refreshLocalCache() { | |
| 128 | - // 情况一:如果缓存里没有数据,则直接刷新缓存 | |
| 129 | - if (CollUtil.isEmpty(sensitiveWordCache)) { | |
| 130 | - initLocalCache(); | |
| 131 | - return; | |
| 132 | - } | |
| 133 | - | |
| 134 | - // 情况二,如果缓存里数据,则通过 updateTime 判断是否有数据变更,有变更则刷新缓存 | |
| 135 | - LocalDateTime maxTime = getMaxValue(sensitiveWordCache, SensitiveWordDO::getUpdateTime); | |
| 136 | - if (sensitiveWordMapper.selectCountByUpdateTimeGt(maxTime) > 0) { | |
| 137 | - initLocalCache(); | |
| 138 | - } | |
| 139 | - } | |
| 140 | - | |
| 141 | - @Override | |
| 142 | - public Long createSensitiveWord(SensitiveWordSaveVO createReqVO) { | |
| 143 | - // 校验唯一性 | |
| 144 | - validateSensitiveWordNameUnique(null, createReqVO.getName()); | |
| 145 | - | |
| 146 | - // 插入 | |
| 147 | - SensitiveWordDO sensitiveWord = BeanUtils.toBean(createReqVO, SensitiveWordDO.class); | |
| 148 | - sensitiveWordMapper.insert(sensitiveWord); | |
| 149 | - | |
| 150 | - // 刷新缓存 | |
| 151 | - initLocalCache(); | |
| 152 | - return sensitiveWord.getId(); | |
| 153 | - } | |
| 154 | - | |
| 155 | - @Override | |
| 156 | - public void updateSensitiveWord(SensitiveWordSaveVO updateReqVO) { | |
| 157 | - // 校验唯一性 | |
| 158 | - validateSensitiveWordExists(updateReqVO.getId()); | |
| 159 | - validateSensitiveWordNameUnique(updateReqVO.getId(), updateReqVO.getName()); | |
| 160 | - | |
| 161 | - // 更新 | |
| 162 | - SensitiveWordDO updateObj = BeanUtils.toBean(updateReqVO, SensitiveWordDO.class); | |
| 163 | - sensitiveWordMapper.updateById(updateObj); | |
| 164 | - | |
| 165 | - // 刷新缓存 | |
| 166 | - initLocalCache(); | |
| 167 | - } | |
| 168 | - | |
| 169 | - @Override | |
| 170 | - public void deleteSensitiveWord(Long id) { | |
| 171 | - // 校验存在 | |
| 172 | - validateSensitiveWordExists(id); | |
| 173 | - // 删除 | |
| 174 | - sensitiveWordMapper.deleteById(id); | |
| 175 | - | |
| 176 | - // 刷新缓存 | |
| 177 | - initLocalCache(); | |
| 178 | - } | |
| 179 | - | |
| 180 | - private void validateSensitiveWordNameUnique(Long id, String name) { | |
| 181 | - SensitiveWordDO word = sensitiveWordMapper.selectByName(name); | |
| 182 | - if (word == null) { | |
| 183 | - return; | |
| 184 | - } | |
| 185 | - // 如果 id 为空,说明不用比较是否为相同 id 的敏感词 | |
| 186 | - if (id == null) { | |
| 187 | - throw exception(SENSITIVE_WORD_EXISTS); | |
| 188 | - } | |
| 189 | - if (!word.getId().equals(id)) { | |
| 190 | - throw exception(SENSITIVE_WORD_EXISTS); | |
| 191 | - } | |
| 192 | - } | |
| 193 | - | |
| 194 | - private void validateSensitiveWordExists(Long id) { | |
| 195 | - if (sensitiveWordMapper.selectById(id) == null) { | |
| 196 | - throw exception(SENSITIVE_WORD_NOT_EXISTS); | |
| 197 | - } | |
| 198 | - } | |
| 199 | - | |
| 200 | - @Override | |
| 201 | - public SensitiveWordDO getSensitiveWord(Long id) { | |
| 202 | - return sensitiveWordMapper.selectById(id); | |
| 203 | - } | |
| 204 | - | |
| 205 | - @Override | |
| 206 | - public List<SensitiveWordDO> getSensitiveWordList() { | |
| 207 | - return sensitiveWordMapper.selectList(); | |
| 208 | - } | |
| 209 | - | |
| 210 | - @Override | |
| 211 | - public PageResult<SensitiveWordDO> getSensitiveWordPage(SensitiveWordPageReqVO pageReqVO) { | |
| 212 | - return sensitiveWordMapper.selectPage(pageReqVO); | |
| 213 | - } | |
| 214 | - | |
| 215 | - @Override | |
| 216 | - public Set<String> getSensitiveWordTagSet() { | |
| 217 | - return sensitiveWordTagsCache; | |
| 218 | - } | |
| 219 | - | |
| 220 | - @Override | |
| 221 | - public List<String> validateText(String text, List<String> tags) { | |
| 222 | - Assert.isTrue(ENABLED, "敏感词功能未开启,请将 ENABLED 设置为 true"); | |
| 223 | - | |
| 224 | - // 无标签时,默认所有 | |
| 225 | - if (CollUtil.isEmpty(tags)) { | |
| 226 | - return defaultSensitiveWordTrie.validate(text); | |
| 227 | - } | |
| 228 | - // 有标签的情况 | |
| 229 | - Set<String> result = new HashSet<>(); | |
| 230 | - tags.forEach(tag -> { | |
| 231 | - SimpleTrie trie = tagSensitiveWordTries.get(tag); | |
| 232 | - if (trie == null) { | |
| 233 | - return; | |
| 234 | - } | |
| 235 | - result.addAll(trie.validate(text)); | |
| 236 | - }); | |
| 237 | - return new ArrayList<>(result); | |
| 238 | - } | |
| 239 | - | |
| 240 | - @Override | |
| 241 | - public boolean isTextValid(String text, List<String> tags) { | |
| 242 | - Assert.isTrue(ENABLED, "敏感词功能未开启,请将 ENABLED 设置为 true"); | |
| 243 | - | |
| 244 | - // 无标签时,默认所有 | |
| 245 | - if (CollUtil.isEmpty(tags)) { | |
| 246 | - return defaultSensitiveWordTrie.isValid(text); | |
| 247 | - } | |
| 248 | - // 有标签的情况 | |
| 249 | - for (String tag : tags) { | |
| 250 | - SimpleTrie trie = tagSensitiveWordTries.get(tag); | |
| 251 | - if (trie == null) { | |
| 252 | - continue; | |
| 253 | - } | |
| 254 | - // 如果有一个标签不合法,则返回 false 不合法 | |
| 255 | - if (!trie.isValid(text)) { | |
| 256 | - return false; | |
| 257 | - } | |
| 258 | - } | |
| 259 | - return true; | |
| 260 | - } | |
| 261 | - | |
| 262 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/collection/SimpleTrie.java deleted
| 1 | -package cn.iocoder.yudao.module.system.util.collection; | |
| 2 | - | |
| 3 | -import cn.hutool.core.collection.CollUtil; | |
| 4 | - | |
| 5 | -import java.util.*; | |
| 6 | - | |
| 7 | -/** | |
| 8 | - * 基于前缀树,实现敏感词的校验 | |
| 9 | - * <p> | |
| 10 | - * 相比 Apache Common 提供的 PatriciaTrie 来说,性能可能会更加好一些。 | |
| 11 | - * | |
| 12 | - * @author 芋道源码 | |
| 13 | - */ | |
| 14 | -@SuppressWarnings("unchecked") | |
| 15 | -public class SimpleTrie { | |
| 16 | - | |
| 17 | - /** | |
| 18 | - * 一个敏感词结束后对应的 key | |
| 19 | - */ | |
| 20 | - private static final Character CHARACTER_END = '\0'; | |
| 21 | - | |
| 22 | - /** | |
| 23 | - * 使用敏感词,构建的前缀树 | |
| 24 | - */ | |
| 25 | - private final Map<Character, Object> children; | |
| 26 | - | |
| 27 | - /** | |
| 28 | - * 基于字符串,构建前缀树 | |
| 29 | - * | |
| 30 | - * @param strs 字符串数组 | |
| 31 | - */ | |
| 32 | - public SimpleTrie(Collection<String> strs) { | |
| 33 | - // 排序,优先使用较短的前缀 | |
| 34 | - strs = CollUtil.sort(strs, String::compareTo); | |
| 35 | - // 构建树 | |
| 36 | - children = new HashMap<>(); | |
| 37 | - for (String str : strs) { | |
| 38 | - Map<Character, Object> child = children; | |
| 39 | - // 遍历每个字符 | |
| 40 | - for (Character c : str.toCharArray()) { | |
| 41 | - // 如果已经到达结束,就没必要在添加更长的敏感词。 | |
| 42 | - // 例如说,有两个敏感词是:吃饭啊、吃饭。输入一句话是 “我要吃饭啊”,则只要匹配到 “吃饭” 这个敏感词即可。 | |
| 43 | - if (child.containsKey(CHARACTER_END)) { | |
| 44 | - break; | |
| 45 | - } | |
| 46 | - if (!child.containsKey(c)) { | |
| 47 | - child.put(c, new HashMap<>()); | |
| 48 | - } | |
| 49 | - child = (Map<Character, Object>) child.get(c); | |
| 50 | - } | |
| 51 | - // 结束 | |
| 52 | - child.put(CHARACTER_END, null); | |
| 53 | - } | |
| 54 | - } | |
| 55 | - | |
| 56 | - /** | |
| 57 | - * 验证文本是否合法,即不包含敏感词 | |
| 58 | - * | |
| 59 | - * @param text 文本 | |
| 60 | - * @return 是否 true-合法 false-不合法 | |
| 61 | - */ | |
| 62 | - public boolean isValid(String text) { | |
| 63 | - // 遍历 text,使用每一个 [i, n) 段的字符串,使用 children 前缀树匹配,是否包含敏感词 | |
| 64 | - for (int i = 0; i < text.length(); i++) { | |
| 65 | - Map<Character, Object> child = (Map<Character, Object>) children.get(text.charAt(i)); | |
| 66 | - if (child == null) { | |
| 67 | - continue; | |
| 68 | - } | |
| 69 | - boolean ok = recursion(text, i + 1, child); | |
| 70 | - if (!ok) { | |
| 71 | - return false; | |
| 72 | - } | |
| 73 | - } | |
| 74 | - return true; | |
| 75 | - } | |
| 76 | - | |
| 77 | - /** | |
| 78 | - * 验证文本从指定位置开始,是否不包含某个敏感词 | |
| 79 | - * | |
| 80 | - * @param text 文本 | |
| 81 | - * @param index 开始位置 | |
| 82 | - * @param child 节点(当前遍历到的) | |
| 83 | - * @return 是否不包含 true-不包含 false-包含 | |
| 84 | - */ | |
| 85 | - private boolean recursion(String text, int index, Map<Character, Object> child) { | |
| 86 | - if (child.containsKey(CHARACTER_END)) { | |
| 87 | - return false; | |
| 88 | - } | |
| 89 | - if (index == text.length()) { | |
| 90 | - return true; | |
| 91 | - } | |
| 92 | - child = (Map<Character, Object>) child.get(text.charAt(index)); | |
| 93 | - return child == null || !child.containsKey(CHARACTER_END) && recursion(text, ++index, child); | |
| 94 | - } | |
| 95 | - | |
| 96 | - /** | |
| 97 | - * 获得文本所包含的不合法的敏感词 | |
| 98 | - * | |
| 99 | - * 注意,才当即最短匹配原则。例如说:当敏感词存在 “煞笔”,“煞笔二货 ”时,只会返回 “煞笔”。 | |
| 100 | - * | |
| 101 | - * @param text 文本 | |
| 102 | - * @return 匹配的敏感词 | |
| 103 | - */ | |
| 104 | - public List<String> validate(String text) { | |
| 105 | - Set<String> results = new HashSet<>(); | |
| 106 | - for (int i = 0; i < text.length(); i++) { | |
| 107 | - Character c = text.charAt(i); | |
| 108 | - Map<Character, Object> child = (Map<Character, Object>) children.get(c); | |
| 109 | - if (child == null) { | |
| 110 | - continue; | |
| 111 | - } | |
| 112 | - StringBuilder result = new StringBuilder().append(c); | |
| 113 | - boolean ok = recursionWithResult(text, i + 1, child, result); | |
| 114 | - if (!ok) { | |
| 115 | - results.add(result.toString()); | |
| 116 | - } | |
| 117 | - } | |
| 118 | - return new ArrayList<>(results); | |
| 119 | - } | |
| 120 | - | |
| 121 | - /** | |
| 122 | - * 返回文本从 index 开始的敏感词,并使用 StringBuilder 参数进行返回 | |
| 123 | - * | |
| 124 | - * 逻辑和 {@link #recursion(String, int, Map)} 是一致,只是多了 result 返回结果 | |
| 125 | - * | |
| 126 | - * @param text 文本 | |
| 127 | - * @param index 开始未知 | |
| 128 | - * @param child 节点(当前遍历到的) | |
| 129 | - * @param result 返回敏感词 | |
| 130 | - * @return 是否有敏感词 | |
| 131 | - */ | |
| 132 | - @SuppressWarnings("unchecked") | |
| 133 | - private static boolean recursionWithResult(String text, int index, Map<Character, Object> child, StringBuilder result) { | |
| 134 | - if (child.containsKey(CHARACTER_END)) { | |
| 135 | - return false; | |
| 136 | - } | |
| 137 | - if (index == text.length()) { | |
| 138 | - return true; | |
| 139 | - } | |
| 140 | - Character c = text.charAt(index); | |
| 141 | - child = (Map<Character, Object>) child.get(c); | |
| 142 | - if (child == null) { | |
| 143 | - return true; | |
| 144 | - } | |
| 145 | - if (child.containsKey(CHARACTER_END)) { | |
| 146 | - result.append(c); | |
| 147 | - return false; | |
| 148 | - } | |
| 149 | - return recursionWithResult(text, ++index, child, result.append(c)); | |
| 150 | - } | |
| 151 | - | |
| 152 | -} |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java deleted
| 1 | -package cn.iocoder.yudao.module.system.service.sensitiveword; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 4 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | -import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 6 | -import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; | |
| 7 | -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 8 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO; | |
| 9 | -import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordSaveVO; | |
| 10 | -import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO; | |
| 11 | -import cn.iocoder.yudao.module.system.dal.mysql.sensitiveword.SensitiveWordMapper; | |
| 12 | -import org.junit.jupiter.api.BeforeEach; | |
| 13 | -import org.junit.jupiter.api.Test; | |
| 14 | -import org.springframework.context.annotation.Import; | |
| 15 | - | |
| 16 | -import jakarta.annotation.Resource; | |
| 17 | -import java.time.Duration; | |
| 18 | -import java.time.LocalDateTime; | |
| 19 | -import java.util.Arrays; | |
| 20 | -import java.util.List; | |
| 21 | - | |
| 22 | -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; | |
| 23 | -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; | |
| 24 | -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; | |
| 25 | -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | |
| 26 | -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | |
| 27 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; | |
| 28 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 29 | -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_WORD_NOT_EXISTS; | |
| 30 | -import static java.util.Collections.singletonList; | |
| 31 | -import static org.junit.jupiter.api.Assertions.*; | |
| 32 | - | |
| 33 | -/** | |
| 34 | - * {@link SensitiveWordServiceImpl} 的单元测试类 | |
| 35 | - * | |
| 36 | - * @author 永不言败 | |
| 37 | - */ | |
| 38 | -@Import(SensitiveWordServiceImpl.class) | |
| 39 | -public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | |
| 40 | - | |
| 41 | - @Resource | |
| 42 | - private SensitiveWordServiceImpl sensitiveWordService; | |
| 43 | - | |
| 44 | - @Resource | |
| 45 | - private SensitiveWordMapper sensitiveWordMapper; | |
| 46 | - | |
| 47 | - @BeforeEach | |
| 48 | - public void setUp() { | |
| 49 | - SensitiveWordServiceImpl.ENABLED = true; | |
| 50 | - } | |
| 51 | - | |
| 52 | - @Test | |
| 53 | - public void testInitLocalCache() { | |
| 54 | - SensitiveWordDO wordDO1 = randomPojo(SensitiveWordDO.class, o -> o.setName("傻瓜") | |
| 55 | - .setTags(singletonList("论坛")).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 56 | - sensitiveWordMapper.insert(wordDO1); | |
| 57 | - SensitiveWordDO wordDO2 = randomPojo(SensitiveWordDO.class, o -> o.setName("笨蛋") | |
| 58 | - .setTags(singletonList("蔬菜")).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 59 | - sensitiveWordMapper.insert(wordDO2); | |
| 60 | - SensitiveWordDO wordDO3 = randomPojo(SensitiveWordDO.class, o -> o.setName("白") | |
| 61 | - .setTags(singletonList("测试")).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 62 | - sensitiveWordMapper.insert(wordDO3); | |
| 63 | - SensitiveWordDO wordDO4 = randomPojo(SensitiveWordDO.class, o -> o.setName("白痴") | |
| 64 | - .setTags(singletonList("测试")).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 65 | - sensitiveWordMapper.insert(wordDO4); | |
| 66 | - | |
| 67 | - // 调用 | |
| 68 | - sensitiveWordService.initLocalCache(); | |
| 69 | - // 断言 sensitiveWordTagsCache 缓存 | |
| 70 | - assertEquals(SetUtils.asSet("论坛", "蔬菜", "测试"), sensitiveWordService.getSensitiveWordTagSet()); | |
| 71 | - // 断言 sensitiveWordCache | |
| 72 | - assertEquals(4, sensitiveWordService.getSensitiveWordCache().size()); | |
| 73 | - assertPojoEquals(wordDO1, sensitiveWordService.getSensitiveWordCache().get(0)); | |
| 74 | - assertPojoEquals(wordDO2, sensitiveWordService.getSensitiveWordCache().get(1)); | |
| 75 | - assertPojoEquals(wordDO3, sensitiveWordService.getSensitiveWordCache().get(2)); | |
| 76 | - // 断言 tagSensitiveWordTries 缓存 | |
| 77 | - assertNotNull(sensitiveWordService.getDefaultSensitiveWordTrie()); | |
| 78 | - assertEquals(3, sensitiveWordService.getTagSensitiveWordTries().size()); | |
| 79 | - assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("论坛")); | |
| 80 | - assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("蔬菜")); | |
| 81 | - assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("测试")); | |
| 82 | - } | |
| 83 | - | |
| 84 | - @Test | |
| 85 | - public void testRefreshLocalCache() { | |
| 86 | - // mock 数据 | |
| 87 | - SensitiveWordDO wordDO1 = randomPojo(SensitiveWordDO.class, o -> o.setName("傻瓜") | |
| 88 | - .setTags(singletonList("论坛")).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 89 | - wordDO1.setUpdateTime(LocalDateTime.now()); | |
| 90 | - sensitiveWordMapper.insert(wordDO1); | |
| 91 | - sensitiveWordService.initLocalCache(); | |
| 92 | - // mock 数据 ② | |
| 93 | - SensitiveWordDO wordDO2 = randomPojo(SensitiveWordDO.class, o -> o.setName("笨蛋") | |
| 94 | - .setTags(singletonList("蔬菜")).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 95 | - wordDO2.setUpdateTime(LocalDateTimeUtils.addTime(Duration.ofMinutes(1))); // 避免时间相同 | |
| 96 | - sensitiveWordMapper.insert(wordDO2); | |
| 97 | - | |
| 98 | - // 调用 | |
| 99 | - sensitiveWordService.refreshLocalCache(); | |
| 100 | - // 断言 sensitiveWordTagsCache 缓存 | |
| 101 | - assertEquals(SetUtils.asSet("论坛", "蔬菜"), sensitiveWordService.getSensitiveWordTagSet()); | |
| 102 | - // 断言 sensitiveWordCache | |
| 103 | - assertEquals(2, sensitiveWordService.getSensitiveWordCache().size()); | |
| 104 | - assertPojoEquals(wordDO1, sensitiveWordService.getSensitiveWordCache().get(0)); | |
| 105 | - assertPojoEquals(wordDO2, sensitiveWordService.getSensitiveWordCache().get(1)); | |
| 106 | - // 断言 tagSensitiveWordTries 缓存 | |
| 107 | - assertNotNull(sensitiveWordService.getDefaultSensitiveWordTrie()); | |
| 108 | - assertEquals(2, sensitiveWordService.getTagSensitiveWordTries().size()); | |
| 109 | - assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("论坛")); | |
| 110 | - assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("蔬菜")); | |
| 111 | - } | |
| 112 | - | |
| 113 | - @Test | |
| 114 | - public void testCreateSensitiveWord_success() { | |
| 115 | - // 准备参数 | |
| 116 | - SensitiveWordSaveVO reqVO = randomPojo(SensitiveWordSaveVO.class) | |
| 117 | - .setId(null); // 防止 id 被赋值 | |
| 118 | - | |
| 119 | - // 调用 | |
| 120 | - Long sensitiveWordId = sensitiveWordService.createSensitiveWord(reqVO); | |
| 121 | - // 断言 | |
| 122 | - assertNotNull(sensitiveWordId); | |
| 123 | - // 校验记录的属性是否正确 | |
| 124 | - SensitiveWordDO sensitiveWord = sensitiveWordMapper.selectById(sensitiveWordId); | |
| 125 | - assertPojoEquals(reqVO, sensitiveWord, "id"); | |
| 126 | - } | |
| 127 | - | |
| 128 | - @Test | |
| 129 | - public void testUpdateSensitiveWord_success() { | |
| 130 | - // mock 数据 | |
| 131 | - SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class); | |
| 132 | - sensitiveWordMapper.insert(dbSensitiveWord);// @Sql: 先插入出一条存在的数据 | |
| 133 | - // 准备参数 | |
| 134 | - SensitiveWordSaveVO reqVO = randomPojo(SensitiveWordSaveVO.class, o -> { | |
| 135 | - o.setId(dbSensitiveWord.getId()); // 设置更新的 ID | |
| 136 | - }); | |
| 137 | - | |
| 138 | - // 调用 | |
| 139 | - sensitiveWordService.updateSensitiveWord(reqVO); | |
| 140 | - // 校验是否更新正确 | |
| 141 | - SensitiveWordDO sensitiveWord = sensitiveWordMapper.selectById(reqVO.getId()); // 获取最新的 | |
| 142 | - assertPojoEquals(reqVO, sensitiveWord); | |
| 143 | - } | |
| 144 | - | |
| 145 | - @Test | |
| 146 | - public void testUpdateSensitiveWord_notExists() { | |
| 147 | - // 准备参数 | |
| 148 | - SensitiveWordSaveVO reqVO = randomPojo(SensitiveWordSaveVO.class); | |
| 149 | - | |
| 150 | - // 调用, 并断言异常 | |
| 151 | - assertServiceException(() -> sensitiveWordService.updateSensitiveWord(reqVO), SENSITIVE_WORD_NOT_EXISTS); | |
| 152 | - } | |
| 153 | - | |
| 154 | - @Test | |
| 155 | - public void testDeleteSensitiveWord_success() { | |
| 156 | - // mock 数据 | |
| 157 | - SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class); | |
| 158 | - sensitiveWordMapper.insert(dbSensitiveWord);// @Sql: 先插入出一条存在的数据 | |
| 159 | - // 准备参数 | |
| 160 | - Long id = dbSensitiveWord.getId(); | |
| 161 | - | |
| 162 | - // 调用 | |
| 163 | - sensitiveWordService.deleteSensitiveWord(id); | |
| 164 | - // 校验数据不存在了 | |
| 165 | - assertNull(sensitiveWordMapper.selectById(id)); | |
| 166 | - } | |
| 167 | - | |
| 168 | - @Test | |
| 169 | - public void testDeleteSensitiveWord_notExists() { | |
| 170 | - // 准备参数 | |
| 171 | - Long id = randomLongId(); | |
| 172 | - | |
| 173 | - // 调用, 并断言异常 | |
| 174 | - assertServiceException(() -> sensitiveWordService.deleteSensitiveWord(id), SENSITIVE_WORD_NOT_EXISTS); | |
| 175 | - } | |
| 176 | - | |
| 177 | - @Test | |
| 178 | - public void testGetSensitiveWord() { | |
| 179 | - // mock 数据 | |
| 180 | - SensitiveWordDO sensitiveWord = randomPojo(SensitiveWordDO.class); | |
| 181 | - sensitiveWordMapper.insert(sensitiveWord); | |
| 182 | - // 准备参数 | |
| 183 | - Long id = sensitiveWord.getId(); | |
| 184 | - | |
| 185 | - // 调用 | |
| 186 | - SensitiveWordDO dbSensitiveWord = sensitiveWordService.getSensitiveWord(id); | |
| 187 | - // 断言 | |
| 188 | - assertPojoEquals(sensitiveWord, dbSensitiveWord); | |
| 189 | - } | |
| 190 | - | |
| 191 | - @Test | |
| 192 | - public void testGetSensitiveWordList() { | |
| 193 | - // mock 数据 | |
| 194 | - SensitiveWordDO sensitiveWord01 = randomPojo(SensitiveWordDO.class); | |
| 195 | - sensitiveWordMapper.insert(sensitiveWord01); | |
| 196 | - SensitiveWordDO sensitiveWord02 = randomPojo(SensitiveWordDO.class); | |
| 197 | - sensitiveWordMapper.insert(sensitiveWord02); | |
| 198 | - | |
| 199 | - // 调用 | |
| 200 | - List<SensitiveWordDO> list = sensitiveWordService.getSensitiveWordList(); | |
| 201 | - // 断言 | |
| 202 | - assertEquals(2, list.size()); | |
| 203 | - assertEquals(sensitiveWord01, list.get(0)); | |
| 204 | - assertEquals(sensitiveWord02, list.get(1)); | |
| 205 | - } | |
| 206 | - | |
| 207 | - @Test | |
| 208 | - public void testGetSensitiveWordPage() { | |
| 209 | - // mock 数据 | |
| 210 | - SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class, o -> { // 等会查询到 | |
| 211 | - o.setName("笨蛋"); | |
| 212 | - o.setTags(Arrays.asList("论坛", "蔬菜")); | |
| 213 | - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 214 | - o.setCreateTime(buildTime(2022, 2, 8)); | |
| 215 | - }); | |
| 216 | - sensitiveWordMapper.insert(dbSensitiveWord); | |
| 217 | - // 测试 name 不匹配 | |
| 218 | - sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setName("傻瓜"))); | |
| 219 | - // 测试 tags 不匹配 | |
| 220 | - sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setTags(Arrays.asList("短信", "日用品")))); | |
| 221 | - // 测试 createTime 不匹配 | |
| 222 | - sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setCreateTime(buildTime(2022, 2, 16)))); | |
| 223 | - // 准备参数 | |
| 224 | - SensitiveWordPageReqVO reqVO = new SensitiveWordPageReqVO(); | |
| 225 | - reqVO.setName("笨"); | |
| 226 | - reqVO.setTag("论坛"); | |
| 227 | - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 228 | - reqVO.setCreateTime(buildBetweenTime(2022, 2, 1, 2022, 2, 12)); | |
| 229 | - | |
| 230 | - // 调用 | |
| 231 | - PageResult<SensitiveWordDO> pageResult = sensitiveWordService.getSensitiveWordPage(reqVO); | |
| 232 | - // 断言 | |
| 233 | - assertEquals(1, pageResult.getTotal()); | |
| 234 | - assertEquals(1, pageResult.getList().size()); | |
| 235 | - assertPojoEquals(dbSensitiveWord, pageResult.getList().get(0)); | |
| 236 | - } | |
| 237 | - | |
| 238 | - @Test | |
| 239 | - public void testValidateText_noTag() { | |
| 240 | - testInitLocalCache(); | |
| 241 | - // 准备参数 | |
| 242 | - String text = "你是傻瓜,你是笨蛋"; | |
| 243 | - // 调用 | |
| 244 | - List<String> result = sensitiveWordService.validateText(text, null); | |
| 245 | - // 断言 | |
| 246 | - assertEquals(Arrays.asList("傻瓜", "笨蛋"), result); | |
| 247 | - | |
| 248 | - // 准备参数 | |
| 249 | - String text2 = "你是傻瓜,你是笨蛋,你是白"; | |
| 250 | - // 调用 | |
| 251 | - List<String> result2 = sensitiveWordService.validateText(text2, null); | |
| 252 | - // 断言 | |
| 253 | - assertEquals(Arrays.asList("傻瓜", "笨蛋","白"), result2); | |
| 254 | - } | |
| 255 | - | |
| 256 | - @Test | |
| 257 | - public void testValidateText_hasTag() { | |
| 258 | - testInitLocalCache(); | |
| 259 | - // 准备参数 | |
| 260 | - String text = "你是傻瓜,你是笨蛋"; | |
| 261 | - // 调用 | |
| 262 | - List<String> result = sensitiveWordService.validateText(text, singletonList("论坛")); | |
| 263 | - // 断言 | |
| 264 | - assertEquals(singletonList("傻瓜"), result); | |
| 265 | - | |
| 266 | - | |
| 267 | - // 准备参数 | |
| 268 | - String text2 = "你是白"; | |
| 269 | - // 调用 | |
| 270 | - List<String> result2 = sensitiveWordService.validateText(text2, singletonList("测试")); | |
| 271 | - // 断言 | |
| 272 | - assertEquals(singletonList("白"), result2); | |
| 273 | - } | |
| 274 | - | |
| 275 | - @Test | |
| 276 | - public void testIsTestValid_noTag() { | |
| 277 | - testInitLocalCache(); | |
| 278 | - // 准备参数 | |
| 279 | - String text = "你是傻瓜,你是笨蛋"; | |
| 280 | - // 调用,断言 | |
| 281 | - assertFalse(sensitiveWordService.isTextValid(text, null)); | |
| 282 | - | |
| 283 | - // 准备参数 | |
| 284 | - String text2 = "你是白"; | |
| 285 | - // 调用,断言 | |
| 286 | - assertFalse(sensitiveWordService.isTextValid(text2, null)); | |
| 287 | - } | |
| 288 | - | |
| 289 | - @Test | |
| 290 | - public void testIsTestValid_hasTag() { | |
| 291 | - testInitLocalCache(); | |
| 292 | - // 准备参数 | |
| 293 | - String text = "你是傻瓜,你是笨蛋"; | |
| 294 | - // 调用,断言 | |
| 295 | - assertFalse(sensitiveWordService.isTextValid(text, singletonList("论坛"))); | |
| 296 | - | |
| 297 | - // 准备参数 | |
| 298 | - String text2 = "你是白"; | |
| 299 | - // 调用,断言 | |
| 300 | - assertFalse(sensitiveWordService.isTextValid(text2, singletonList("测试"))); | |
| 301 | - } | |
| 302 | - | |
| 303 | -} |
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql
| ... | ... | @@ -21,7 +21,6 @@ DELETE FROM "system_social_user"; |
| 21 | 21 | DELETE FROM "system_social_user_bind"; |
| 22 | 22 | DELETE FROM "system_tenant"; |
| 23 | 23 | DELETE FROM "system_tenant_package"; |
| 24 | -DELETE FROM "system_sensitive_word"; | |
| 25 | 24 | DELETE FROM "system_oauth2_client"; |
| 26 | 25 | DELETE FROM "system_oauth2_approve"; |
| 27 | 26 | DELETE FROM "system_oauth2_access_token"; | ... | ... |
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -416,20 +416,6 @@ CREATE TABLE IF NOT EXISTS "system_tenant_package" ( |
| 416 | 416 | PRIMARY KEY ("id") |
| 417 | 417 | ) COMMENT '租户套餐表'; |
| 418 | 418 | |
| 419 | -CREATE TABLE IF NOT EXISTS "system_sensitive_word" ( | |
| 420 | - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 421 | - "name" varchar(255) NOT NULL, | |
| 422 | - "tags" varchar(1024) NOT NULL, | |
| 423 | - "status" bit NOT NULL DEFAULT FALSE, | |
| 424 | - "description" varchar(512), | |
| 425 | - "creator" varchar(64) DEFAULT '', | |
| 426 | - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 427 | - "updater" varchar(64) DEFAULT '', | |
| 428 | - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 429 | - "deleted" bit NOT NULL DEFAULT FALSE, | |
| 430 | - PRIMARY KEY ("id") | |
| 431 | -) COMMENT '系统敏感词'; | |
| 432 | - | |
| 433 | 419 | CREATE TABLE IF NOT EXISTS "system_oauth2_client" ( |
| 434 | 420 | "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, |
| 435 | 421 | "client_id" varchar NOT NULL, | ... | ... |
yudao-server/src/main/resources/application-local.yaml
| ... | ... | @@ -170,7 +170,6 @@ logging: |
| 170 | 170 | cn.iocoder.yudao.module.pay.dal.mysql: debug |
| 171 | 171 | cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskMapper: INFO # 配置 JobLogMapper 的日志级别为 info |
| 172 | 172 | cn.iocoder.yudao.module.system.dal.mysql: debug |
| 173 | - cn.iocoder.yudao.module.system.dal.mysql.sensitiveword.SensitiveWordMapper: INFO # 配置 SensitiveWordMapper 的日志级别为 info | |
| 174 | 173 | cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info |
| 175 | 174 | cn.iocoder.yudao.module.tool.dal.mysql: debug |
| 176 | 175 | cn.iocoder.yudao.module.member.dal.mysql: debug | ... | ... |