Merge branch 'master-jdk21' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
# Conflicts: # yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/errorcode/config/ErrorCodeProperties.java # yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApi.java # yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/dto/ErrorCodeAutoGenerateReqDTO.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApiImpl.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/sensitiveword/SensitiveWordApiImpl.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/ErrorCodeController.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeSaveReqVO.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordSaveVO.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeService.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceImpl.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java # yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceTest.java # yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.javaplp
commit
a27c040a8f
@ -1,30 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.errorcode.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 错误码的配置属性类
|
||||
*
|
||||
* @author dlyan
|
||||
*/
|
||||
@ConfigurationProperties("yudao.error-code")
|
||||
@Data
|
||||
@Validated
|
||||
public class ErrorCodeProperties {
|
||||
|
||||
/**
|
||||
* 是否开启
|
||||
*/
|
||||
private Boolean enable = true;
|
||||
/**
|
||||
* 错误码枚举类
|
||||
*/
|
||||
@NotNull(message = "错误码枚举类不能为空")
|
||||
private List<String> constantsClassList;
|
||||
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.errorcode.config;
|
||||
|
||||
import cn.iocoder.yudao.framework.errorcode.core.generator.ErrorCodeAutoGenerator;
|
||||
import cn.iocoder.yudao.framework.errorcode.core.generator.ErrorCodeAutoGeneratorImpl;
|
||||
import cn.iocoder.yudao.framework.errorcode.core.loader.ErrorCodeLoader;
|
||||
import cn.iocoder.yudao.framework.errorcode.core.loader.ErrorCodeLoaderImpl;
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* 错误码配置类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnProperty(prefix = "yudao.error-code", value = "enable", matchIfMissing = true) // 允许使用 yudao.error-code.enable=false 禁用访问日志
|
||||
@EnableConfigurationProperties(ErrorCodeProperties.class)
|
||||
@EnableScheduling // 开启调度任务的功能,因为 ErrorCodeRemoteLoader 通过定时刷新错误码
|
||||
public class YudaoErrorCodeAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public ErrorCodeAutoGenerator errorCodeAutoGenerator(@Value("${spring.application.name}") String applicationName,
|
||||
ErrorCodeProperties errorCodeProperties,
|
||||
ErrorCodeApi errorCodeApi) {
|
||||
return new ErrorCodeAutoGeneratorImpl(applicationName, errorCodeProperties.getConstantsClassList(), errorCodeApi);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ErrorCodeLoader errorCodeLoader(@Value("${spring.application.name}") String applicationName,
|
||||
ErrorCodeApi errorCodeApi) {
|
||||
return new ErrorCodeLoaderImpl(applicationName, errorCodeApi);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
package cn.iocoder.yudao.framework.errorcode.core.generator;
|
||||
|
||||
/**
|
||||
* 错误码的自动生成器
|
||||
*
|
||||
* @author dylan
|
||||
*/
|
||||
public interface ErrorCodeAutoGenerator {
|
||||
|
||||
/**
|
||||
* 将配置类到错误码写入数据库
|
||||
*/
|
||||
void execute();
|
||||
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.api.errorcode.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 错误码自动生成 DTO
|
||||
*
|
||||
* @author dylan
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ErrorCodeAutoGenerateReqDTO {
|
||||
|
||||
/**
|
||||
* 应用名
|
||||
*/
|
||||
@NotNull(message = "应用名不能为空")
|
||||
private String applicationName;
|
||||
/**
|
||||
* 错误码编码
|
||||
*/
|
||||
@NotNull(message = "错误码编码不能为空")
|
||||
private Integer code;
|
||||
/**
|
||||
* 错误码错误提示
|
||||
*/
|
||||
@NotEmpty(message = "错误码错误提示不能为空")
|
||||
private String message;
|
||||
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.api.errorcode.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 错误码的 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class ErrorCodeRespDTO {
|
||||
|
||||
/**
|
||||
* 错误码编码
|
||||
*/
|
||||
private Integer code;
|
||||
/**
|
||||
* 错误码错误提示
|
||||
*/
|
||||
private String message;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.api.sensitiveword;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 敏感词 API 接口
|
||||
*
|
||||
* @author 永不言败
|
||||
*/
|
||||
public interface SensitiveWordApi {
|
||||
|
||||
/**
|
||||
* 获得文本所包含的不合法的敏感词数组
|
||||
*
|
||||
* @param text 文本
|
||||
* @param tags 标签数组
|
||||
* @return 不合法的敏感词数组
|
||||
*/
|
||||
List<String> validateText(String text, List<String> tags);
|
||||
|
||||
/**
|
||||
* 判断文本是否包含敏感词
|
||||
*
|
||||
* @param text 文本
|
||||
* @param tags 表述数组
|
||||
* @return 是否包含
|
||||
*/
|
||||
boolean isTextValid(String text, List<String> tags);
|
||||
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.enums.errorcode;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 错误码的类型枚举
|
||||
*
|
||||
* @author dylan
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum ErrorCodeTypeEnum implements IntArrayValuable {
|
||||
|
||||
/**
|
||||
* 自动生成
|
||||
*/
|
||||
AUTO_GENERATION(1),
|
||||
/**
|
||||
* 手动编辑
|
||||
*/
|
||||
MANUAL_OPERATION(2);
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErrorCodeTypeEnum::getType).toArray();
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private final Integer type;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.api.errorcode;
|
||||
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeAutoGenerateReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeRespDTO;
|
||||
import cn.iocoder.yudao.module.system.service.errorcode.ErrorCodeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 错误码 Api 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ErrorCodeApiImpl implements ErrorCodeApi {
|
||||
|
||||
@Resource
|
||||
private ErrorCodeService errorCodeService;
|
||||
|
||||
@Override
|
||||
public void autoGenerateErrorCodeList(List<ErrorCodeAutoGenerateReqDTO> autoGenerateDTOs) {
|
||||
errorCodeService.autoGenerateErrorCodes(autoGenerateDTOs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ErrorCodeRespDTO> getErrorCodeList(String applicationName, LocalDateTime minUpdateTime) {
|
||||
return errorCodeService.getErrorCodeList(applicationName, minUpdateTime);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.api.sensitiveword;
|
||||
|
||||
import cn.iocoder.yudao.module.system.service.sensitiveword.SensitiveWordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 敏感词 API 实现类
|
||||
*
|
||||
* @author 永不言败
|
||||
*/
|
||||
@Service
|
||||
public class SensitiveWordApiImpl implements SensitiveWordApi {
|
||||
|
||||
@Resource
|
||||
private SensitiveWordService sensitiveWordService;
|
||||
|
||||
@Override
|
||||
public List<String> validateText(String text, List<String> tags) {
|
||||
return sensitiveWordService.validateText(text, tags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTextValid(String text, List<String> tags) {
|
||||
return sensitiveWordService.isTextValid(text, tags);
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
### 创建错误码
|
||||
POST {{baseUrl}}/inra/error-code/create
|
||||
Authorization: Bearer {{token}}
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenentId}}
|
||||
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"group": "test",
|
||||
"type": 1
|
||||
}
|
||||
|
||||
@ -1,93 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.errorcode;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.ErrorCodePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.ErrorCodeRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.ErrorCodeSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.errorcode.ErrorCodeDO;
|
||||
import cn.iocoder.yudao.module.system.service.errorcode.ErrorCodeService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 错误码")
|
||||
@RestController
|
||||
@RequestMapping("/system/error-code")
|
||||
@Validated
|
||||
public class ErrorCodeController {
|
||||
|
||||
@Resource
|
||||
private ErrorCodeService errorCodeService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建错误码")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:create')")
|
||||
public CommonResult<Long> createErrorCode(@Valid @RequestBody ErrorCodeSaveReqVO createReqVO) {
|
||||
return success(errorCodeService.createErrorCode(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新错误码")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:update')")
|
||||
public CommonResult<Boolean> updateErrorCode(@Valid @RequestBody ErrorCodeSaveReqVO updateReqVO) {
|
||||
errorCodeService.updateErrorCode(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除错误码")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:delete')")
|
||||
public CommonResult<Boolean> deleteErrorCode(@RequestParam("id") Long id) {
|
||||
errorCodeService.deleteErrorCode(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得错误码")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:query')")
|
||||
public CommonResult<ErrorCodeRespVO> getErrorCode(@RequestParam("id") Long id) {
|
||||
ErrorCodeDO errorCode = errorCodeService.getErrorCode(id);
|
||||
return success(BeanUtils.toBean(errorCode, ErrorCodeRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得错误码分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:query')")
|
||||
public CommonResult<PageResult<ErrorCodeRespVO>> getErrorCodePage(@Valid ErrorCodePageReqVO pageVO) {
|
||||
PageResult<ErrorCodeDO> pageResult = errorCodeService.getErrorCodePage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, ErrorCodeRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出错误码 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportErrorCodeExcel(@Valid ErrorCodePageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<ErrorCodeDO> list = errorCodeService.getErrorCodePage(exportReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "错误码.xls", "数据", ErrorCodeRespVO.class,
|
||||
BeanUtils.toBean(list, ErrorCodeRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.errorcode.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 错误码分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ErrorCodePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "错误码类型,参见 ErrorCodeTypeEnum 枚举类", example = "1")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "应用名", example = "dashboard")
|
||||
private String applicationName;
|
||||
|
||||
@Schema(description = "错误码编码", example = "1234")
|
||||
private Integer code;
|
||||
|
||||
@Schema(description = "错误码错误提示", example = "帅气")
|
||||
private String message;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.errorcode.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 错误码 Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class ErrorCodeRespVO {
|
||||
|
||||
@Schema(description = "错误码编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@ExcelProperty("错误码编号")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "错误码类型,参见 ErrorCodeTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty(value = "错误码类型", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.ERROR_CODE_TYPE)
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "dashboard")
|
||||
@ExcelProperty("应用名")
|
||||
private String applicationName;
|
||||
|
||||
@Schema(description = "错误码编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1234")
|
||||
@ExcelProperty("错误码编码")
|
||||
private Integer code;
|
||||
|
||||
@Schema(description = "错误码错误提示", requiredMode = Schema.RequiredMode.REQUIRED, example = "帅气")
|
||||
@ExcelProperty("错误码错误提示")
|
||||
private String message;
|
||||
|
||||
@Schema(description = "备注", example = "哈哈哈")
|
||||
@ExcelProperty("备注")
|
||||
private String memo;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.errorcode.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 错误码创建/修改 Request VO")
|
||||
@Data
|
||||
public class ErrorCodeSaveReqVO {
|
||||
|
||||
@Schema(description = "错误码编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "dashboard")
|
||||
@NotNull(message = "应用名不能为空")
|
||||
private String applicationName;
|
||||
|
||||
@Schema(description = "错误码编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1234")
|
||||
@NotNull(message = "错误码编码不能为空")
|
||||
private Integer code;
|
||||
|
||||
@Schema(description = "错误码错误提示", requiredMode = Schema.RequiredMode.REQUIRED, example = "帅气")
|
||||
@NotNull(message = "错误码错误提示不能为空")
|
||||
private String message;
|
||||
|
||||
@Schema(description = "备注", example = "哈哈哈")
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
### 请求 /system/sensitive-word/validate-text 接口 => 成功
|
||||
GET {{baseUrl}}/system/sensitive-word/validate-text?text=XXX&tags=短信&tags=蔬菜
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
||||
@ -1,108 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.sensitiveword;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordSaveVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
|
||||
import cn.iocoder.yudao.module.system.service.sensitiveword.SensitiveWordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 敏感词")
|
||||
@RestController
|
||||
@RequestMapping("/system/sensitive-word")
|
||||
@Validated
|
||||
public class SensitiveWordController {
|
||||
|
||||
@Resource
|
||||
private SensitiveWordService sensitiveWordService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建敏感词")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:create')")
|
||||
public CommonResult<Long> createSensitiveWord(@Valid @RequestBody SensitiveWordSaveVO createReqVO) {
|
||||
return success(sensitiveWordService.createSensitiveWord(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新敏感词")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:update')")
|
||||
public CommonResult<Boolean> updateSensitiveWord(@Valid @RequestBody SensitiveWordSaveVO updateReqVO) {
|
||||
sensitiveWordService.updateSensitiveWord(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除敏感词")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:delete')")
|
||||
public CommonResult<Boolean> deleteSensitiveWord(@RequestParam("id") Long id) {
|
||||
sensitiveWordService.deleteSensitiveWord(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得敏感词")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:query')")
|
||||
public CommonResult<SensitiveWordRespVO> getSensitiveWord(@RequestParam("id") Long id) {
|
||||
SensitiveWordDO sensitiveWord = sensitiveWordService.getSensitiveWord(id);
|
||||
return success(BeanUtils.toBean(sensitiveWord, SensitiveWordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得敏感词分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:query')")
|
||||
public CommonResult<PageResult<SensitiveWordRespVO>> getSensitiveWordPage(@Valid SensitiveWordPageReqVO pageVO) {
|
||||
PageResult<SensitiveWordDO> pageResult = sensitiveWordService.getSensitiveWordPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, SensitiveWordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出敏感词 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportSensitiveWordExcel(@Valid SensitiveWordPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<SensitiveWordDO> list = sensitiveWordService.getSensitiveWordPage(exportReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "敏感词.xls", "数据", SensitiveWordRespVO.class,
|
||||
BeanUtils.toBean(list, SensitiveWordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get-tags")
|
||||
@Operation(summary = "获取所有敏感词的标签数组")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:query')")
|
||||
public CommonResult<Set<String>> getSensitiveWordTagSet() {
|
||||
return success(sensitiveWordService.getSensitiveWordTagSet());
|
||||
}
|
||||
|
||||
@GetMapping("/validate-text")
|
||||
@Operation(summary = "获得文本所包含的不合法的敏感词数组")
|
||||
public CommonResult<List<String>> validateText(@RequestParam("text") String text,
|
||||
@RequestParam(value = "tags", required = false) List<String> tags) {
|
||||
return success(sensitiveWordService.validateText(text, tags));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 敏感词分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class SensitiveWordPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "敏感词", example = "敏感词")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "标签", example = "短信,评论")
|
||||
private String tag;
|
||||
|
||||
@Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.JsonConvert;
|
||||
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 敏感词 Response VO")
|
||||
@Data
|
||||
public class SensitiveWordRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("编号")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "敏感词", requiredMode = Schema.RequiredMode.REQUIRED, example = "敏感词")
|
||||
@ExcelProperty("敏感词")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "标签", requiredMode = Schema.RequiredMode.REQUIRED, example = "短信,评论")
|
||||
@ExcelProperty(value = "标签", converter = JsonConvert.class)
|
||||
private List<String> tags;
|
||||
|
||||
@Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty(value = "状态", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.COMMON_STATUS)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "描述", example = "污言秽语")
|
||||
@ExcelProperty("描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 敏感词创建/修改 Request VO")
|
||||
@Data
|
||||
public class SensitiveWordSaveVO {
|
||||
|
||||
@Schema(description = "编号", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "敏感词", requiredMode = Schema.RequiredMode.REQUIRED, example = "敏感词")
|
||||
@NotNull(message = "敏感词不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "标签", requiredMode = Schema.RequiredMode.REQUIRED, example = "短信,评论")
|
||||
@NotNull(message = "标签不能为空")
|
||||
private List<String> tags;
|
||||
|
||||
@Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "描述", example = "污言秽语")
|
||||
private String description;
|
||||
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.dal.mysql.errorcode;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.ErrorCodePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.errorcode.ErrorCodeDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ErrorCodeMapper extends BaseMapperX<ErrorCodeDO> {
|
||||
|
||||
default PageResult<ErrorCodeDO> selectPage(ErrorCodePageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<ErrorCodeDO>()
|
||||
.eqIfPresent(ErrorCodeDO::getType, reqVO.getType())
|
||||
.likeIfPresent(ErrorCodeDO::getApplicationName, reqVO.getApplicationName())
|
||||
.eqIfPresent(ErrorCodeDO::getCode, reqVO.getCode())
|
||||
.likeIfPresent(ErrorCodeDO::getMessage, reqVO.getMessage())
|
||||
.betweenIfPresent(ErrorCodeDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(ErrorCodeDO::getCode));
|
||||
}
|
||||
|
||||
default List<ErrorCodeDO> selectListByCodes(Collection<Integer> codes) {
|
||||
return selectList(ErrorCodeDO::getCode, codes);
|
||||
}
|
||||
|
||||
default ErrorCodeDO selectByCode(Integer code) {
|
||||
return selectOne(ErrorCodeDO::getCode, code);
|
||||
}
|
||||
|
||||
default List<ErrorCodeDO> selectListByApplicationNameAndUpdateTimeGt(String applicationName, LocalDateTime minUpdateTime) {
|
||||
return selectList(new LambdaQueryWrapperX<ErrorCodeDO>().eq(ErrorCodeDO::getApplicationName, applicationName)
|
||||
.gtIfPresent(ErrorCodeDO::getUpdateTime, minUpdateTime));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.dal.mysql.sensitiveword;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 敏感词 Mapper
|
||||
*
|
||||
* @author 永不言败
|
||||
*/
|
||||
@Mapper
|
||||
public interface SensitiveWordMapper extends BaseMapperX<SensitiveWordDO> {
|
||||
|
||||
default PageResult<SensitiveWordDO> selectPage(SensitiveWordPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<SensitiveWordDO>()
|
||||
.likeIfPresent(SensitiveWordDO::getName, reqVO.getName())
|
||||
.likeIfPresent(SensitiveWordDO::getTags, reqVO.getTag())
|
||||
.eqIfPresent(SensitiveWordDO::getStatus, reqVO.getStatus())
|
||||
.betweenIfPresent(SensitiveWordDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(SensitiveWordDO::getId));
|
||||
}
|
||||
default SensitiveWordDO selectByName(String name) {
|
||||
return selectOne(SensitiveWordDO::getName, name);
|
||||
}
|
||||
|
||||
@Select("SELECT COUNT(*) FROM system_sensitive_word WHERE update_time > #{maxUpdateTime}")
|
||||
Long selectCountByUpdateTimeGt(LocalDateTime maxTime);
|
||||
|
||||
}
|
||||
@ -1,167 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.errorcode;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeAutoGenerateReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeRespDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.ErrorCodePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.ErrorCodeSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.errorcode.ErrorCodeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.errorcode.ErrorCodeMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.errorcode.ErrorCodeTypeEnum;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.ERROR_CODE_DUPLICATE;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.ERROR_CODE_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 错误码 Service 实现类
|
||||
*
|
||||
* @author dlyan
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class ErrorCodeServiceImpl implements ErrorCodeService {
|
||||
|
||||
@Resource
|
||||
private ErrorCodeMapper errorCodeMapper;
|
||||
|
||||
@Override
|
||||
public Long createErrorCode(ErrorCodeSaveReqVO createReqVO) {
|
||||
// 校验 code 重复
|
||||
validateCodeDuplicate(createReqVO.getCode(), null);
|
||||
|
||||
// 插入
|
||||
ErrorCodeDO errorCode = BeanUtils.toBean(createReqVO, ErrorCodeDO.class)
|
||||
.setType(ErrorCodeTypeEnum.MANUAL_OPERATION.getType());
|
||||
errorCodeMapper.insert(errorCode);
|
||||
// 返回
|
||||
return errorCode.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateErrorCode(ErrorCodeSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateErrorCodeExists(updateReqVO.getId());
|
||||
// 校验 code 重复
|
||||
validateCodeDuplicate(updateReqVO.getCode(), updateReqVO.getId());
|
||||
|
||||
// 更新
|
||||
ErrorCodeDO updateObj = BeanUtils.toBean(updateReqVO, ErrorCodeDO.class)
|
||||
.setType(ErrorCodeTypeEnum.MANUAL_OPERATION.getType());
|
||||
errorCodeMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteErrorCode(Long id) {
|
||||
// 校验存在
|
||||
validateErrorCodeExists(id);
|
||||
// 删除
|
||||
errorCodeMapper.deleteById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验错误码的唯一字段是否重复
|
||||
*
|
||||
* 是否存在相同编码的错误码
|
||||
*
|
||||
* @param code 错误码编码
|
||||
* @param id 错误码编号
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public void validateCodeDuplicate(Integer code, Long id) {
|
||||
ErrorCodeDO errorCodeDO = errorCodeMapper.selectByCode(code);
|
||||
if (errorCodeDO == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的错误码
|
||||
if (id == null) {
|
||||
throw exception(ERROR_CODE_DUPLICATE);
|
||||
}
|
||||
if (!errorCodeDO.getId().equals(id)) {
|
||||
throw exception(ERROR_CODE_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateErrorCodeExists(Long id) {
|
||||
if (errorCodeMapper.selectById(id) == null) {
|
||||
throw exception(ERROR_CODE_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCodeDO getErrorCode(Long id) {
|
||||
return errorCodeMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ErrorCodeDO> getErrorCodePage(ErrorCodePageReqVO pageReqVO) {
|
||||
return errorCodeMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void autoGenerateErrorCodes(List<ErrorCodeAutoGenerateReqDTO> autoGenerateDTOs) {
|
||||
if (CollUtil.isEmpty(autoGenerateDTOs)) {
|
||||
return;
|
||||
}
|
||||
// 获得错误码
|
||||
List<ErrorCodeDO> errorCodeDOs = errorCodeMapper.selectListByCodes(
|
||||
convertSet(autoGenerateDTOs, ErrorCodeAutoGenerateReqDTO::getCode));
|
||||
Map<Integer, ErrorCodeDO> errorCodeDOMap = convertMap(errorCodeDOs, ErrorCodeDO::getCode);
|
||||
|
||||
// 遍历 autoGenerateBOs 数组,逐个插入或更新。考虑到每次量级不大,就不走批量了
|
||||
autoGenerateDTOs.forEach(autoGenerateDTO -> {
|
||||
ErrorCodeDO errorCode = errorCodeDOMap.get(autoGenerateDTO.getCode());
|
||||
// 不存在,则进行新增
|
||||
if (errorCode == null) {
|
||||
errorCode = BeanUtils.toBean(autoGenerateDTO, ErrorCodeDO.class)
|
||||
.setType(ErrorCodeTypeEnum.AUTO_GENERATION.getType());
|
||||
errorCodeMapper.insert(errorCode);
|
||||
return;
|
||||
}
|
||||
// 存在,则进行更新。更新有三个前置条件:
|
||||
// 条件 1. 只更新自动生成的错误码,即 Type 为 ErrorCodeTypeEnum.AUTO_GENERATION
|
||||
if (!ErrorCodeTypeEnum.AUTO_GENERATION.getType().equals(errorCode.getType())) {
|
||||
return;
|
||||
}
|
||||
// 条件 2. 分组 applicationName 必须匹配,避免存在错误码冲突的情况
|
||||
if (!autoGenerateDTO.getApplicationName().equals(errorCode.getApplicationName())) {
|
||||
log.error("[autoGenerateErrorCodes][自动创建({}/{}) 错误码失败,数据库中已经存在({}/{})]",
|
||||
autoGenerateDTO.getCode(), autoGenerateDTO.getApplicationName(),
|
||||
errorCode.getCode(), errorCode.getApplicationName());
|
||||
return;
|
||||
}
|
||||
// 条件 3. 错误提示语存在差异
|
||||
if (autoGenerateDTO.getMessage().equals(errorCode.getMessage())) {
|
||||
return;
|
||||
}
|
||||
// 最终匹配,进行更新
|
||||
errorCodeMapper.updateById(new ErrorCodeDO().setId(errorCode.getId()).setMessage(autoGenerateDTO.getMessage()));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ErrorCodeRespDTO> getErrorCodeList(String applicationName, LocalDateTime minUpdateTime) {
|
||||
List<ErrorCodeDO> list = errorCodeMapper.selectListByApplicationNameAndUpdateTimeGt(
|
||||
applicationName, minUpdateTime);
|
||||
return BeanUtils.toBean(list, ErrorCodeRespDTO.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.sensitiveword;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordSaveVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 敏感词 Service 接口
|
||||
*
|
||||
* @author 永不言败
|
||||
*/
|
||||
public interface SensitiveWordService {
|
||||
|
||||
/**
|
||||
* 创建敏感词
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createSensitiveWord(@Valid SensitiveWordSaveVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新敏感词
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateSensitiveWord(@Valid SensitiveWordSaveVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除敏感词
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteSensitiveWord(Long id);
|
||||
|
||||
/**
|
||||
* 获得敏感词
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 敏感词
|
||||
*/
|
||||
SensitiveWordDO getSensitiveWord(Long id);
|
||||
|
||||
/**
|
||||
* 获得敏感词列表
|
||||
*
|
||||
* @return 敏感词列表
|
||||
*/
|
||||
List<SensitiveWordDO> getSensitiveWordList();
|
||||
|
||||
/**
|
||||
* 获得敏感词分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 敏感词分页
|
||||
*/
|
||||
PageResult<SensitiveWordDO> getSensitiveWordPage(SensitiveWordPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得所有敏感词的标签数组
|
||||
*
|
||||
* @return 标签数组
|
||||
*/
|
||||
Set<String> getSensitiveWordTagSet();
|
||||
|
||||
/**
|
||||
* 获得文本所包含的不合法的敏感词数组
|
||||
*
|
||||
* @param text 文本
|
||||
* @param tags 标签数组
|
||||
* @return 不合法的敏感词数组
|
||||
*/
|
||||
List<String> validateText(String text, List<String> tags);
|
||||
|
||||
/**
|
||||
* 判断文本是否包含敏感词
|
||||
*
|
||||
* @param text 文本
|
||||
* @param tags 标签数组
|
||||
* @return 是否包含敏感词
|
||||
*/
|
||||
boolean isTextValid(String text, List<String> tags);
|
||||
|
||||
}
|
||||
@ -1,303 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.sensitiveword;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordSaveVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.sensitiveword.SensitiveWordMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_WORD_NOT_EXISTS;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link SensitiveWordServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 永不言败
|
||||
*/
|
||||
@Import(SensitiveWordServiceImpl.class)
|
||||
public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SensitiveWordServiceImpl sensitiveWordService;
|
||||
|
||||
@Resource
|
||||
private SensitiveWordMapper sensitiveWordMapper;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
SensitiveWordServiceImpl.ENABLED = true;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitLocalCache() {
|
||||
SensitiveWordDO wordDO1 = randomPojo(SensitiveWordDO.class, o -> o.setName("傻瓜")
|
||||
.setTags(singletonList("论坛")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
sensitiveWordMapper.insert(wordDO1);
|
||||
SensitiveWordDO wordDO2 = randomPojo(SensitiveWordDO.class, o -> o.setName("笨蛋")
|
||||
.setTags(singletonList("蔬菜")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
sensitiveWordMapper.insert(wordDO2);
|
||||
SensitiveWordDO wordDO3 = randomPojo(SensitiveWordDO.class, o -> o.setName("白")
|
||||
.setTags(singletonList("测试")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
sensitiveWordMapper.insert(wordDO3);
|
||||
SensitiveWordDO wordDO4 = randomPojo(SensitiveWordDO.class, o -> o.setName("白痴")
|
||||
.setTags(singletonList("测试")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
sensitiveWordMapper.insert(wordDO4);
|
||||
|
||||
// 调用
|
||||
sensitiveWordService.initLocalCache();
|
||||
// 断言 sensitiveWordTagsCache 缓存
|
||||
assertEquals(SetUtils.asSet("论坛", "蔬菜", "测试"), sensitiveWordService.getSensitiveWordTagSet());
|
||||
// 断言 sensitiveWordCache
|
||||
assertEquals(4, sensitiveWordService.getSensitiveWordCache().size());
|
||||
assertPojoEquals(wordDO1, sensitiveWordService.getSensitiveWordCache().get(0));
|
||||
assertPojoEquals(wordDO2, sensitiveWordService.getSensitiveWordCache().get(1));
|
||||
assertPojoEquals(wordDO3, sensitiveWordService.getSensitiveWordCache().get(2));
|
||||
// 断言 tagSensitiveWordTries 缓存
|
||||
assertNotNull(sensitiveWordService.getDefaultSensitiveWordTrie());
|
||||
assertEquals(3, sensitiveWordService.getTagSensitiveWordTries().size());
|
||||
assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("论坛"));
|
||||
assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("蔬菜"));
|
||||
assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("测试"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshLocalCache() {
|
||||
// mock 数据
|
||||
SensitiveWordDO wordDO1 = randomPojo(SensitiveWordDO.class, o -> o.setName("傻瓜")
|
||||
.setTags(singletonList("论坛")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
wordDO1.setUpdateTime(LocalDateTime.now());
|
||||
sensitiveWordMapper.insert(wordDO1);
|
||||
sensitiveWordService.initLocalCache();
|
||||
// mock 数据 ②
|
||||
SensitiveWordDO wordDO2 = randomPojo(SensitiveWordDO.class, o -> o.setName("笨蛋")
|
||||
.setTags(singletonList("蔬菜")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
wordDO2.setUpdateTime(LocalDateTimeUtils.addTime(Duration.ofMinutes(1))); // 避免时间相同
|
||||
sensitiveWordMapper.insert(wordDO2);
|
||||
|
||||
// 调用
|
||||
sensitiveWordService.refreshLocalCache();
|
||||
// 断言 sensitiveWordTagsCache 缓存
|
||||
assertEquals(SetUtils.asSet("论坛", "蔬菜"), sensitiveWordService.getSensitiveWordTagSet());
|
||||
// 断言 sensitiveWordCache
|
||||
assertEquals(2, sensitiveWordService.getSensitiveWordCache().size());
|
||||
assertPojoEquals(wordDO1, sensitiveWordService.getSensitiveWordCache().get(0));
|
||||
assertPojoEquals(wordDO2, sensitiveWordService.getSensitiveWordCache().get(1));
|
||||
// 断言 tagSensitiveWordTries 缓存
|
||||
assertNotNull(sensitiveWordService.getDefaultSensitiveWordTrie());
|
||||
assertEquals(2, sensitiveWordService.getTagSensitiveWordTries().size());
|
||||
assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("论坛"));
|
||||
assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("蔬菜"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSensitiveWord_success() {
|
||||
// 准备参数
|
||||
SensitiveWordSaveVO reqVO = randomPojo(SensitiveWordSaveVO.class)
|
||||
.setId(null); // 防止 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long sensitiveWordId = sensitiveWordService.createSensitiveWord(reqVO);
|
||||
// 断言
|
||||
assertNotNull(sensitiveWordId);
|
||||
// 校验记录的属性是否正确
|
||||
SensitiveWordDO sensitiveWord = sensitiveWordMapper.selectById(sensitiveWordId);
|
||||
assertPojoEquals(reqVO, sensitiveWord, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSensitiveWord_success() {
|
||||
// mock 数据
|
||||
SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class);
|
||||
sensitiveWordMapper.insert(dbSensitiveWord);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SensitiveWordSaveVO reqVO = randomPojo(SensitiveWordSaveVO.class, o -> {
|
||||
o.setId(dbSensitiveWord.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
sensitiveWordService.updateSensitiveWord(reqVO);
|
||||
// 校验是否更新正确
|
||||
SensitiveWordDO sensitiveWord = sensitiveWordMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, sensitiveWord);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSensitiveWord_notExists() {
|
||||
// 准备参数
|
||||
SensitiveWordSaveVO reqVO = randomPojo(SensitiveWordSaveVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> sensitiveWordService.updateSensitiveWord(reqVO), SENSITIVE_WORD_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSensitiveWord_success() {
|
||||
// mock 数据
|
||||
SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class);
|
||||
sensitiveWordMapper.insert(dbSensitiveWord);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSensitiveWord.getId();
|
||||
|
||||
// 调用
|
||||
sensitiveWordService.deleteSensitiveWord(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(sensitiveWordMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSensitiveWord_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> sensitiveWordService.deleteSensitiveWord(id), SENSITIVE_WORD_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSensitiveWord() {
|
||||
// mock 数据
|
||||
SensitiveWordDO sensitiveWord = randomPojo(SensitiveWordDO.class);
|
||||
sensitiveWordMapper.insert(sensitiveWord);
|
||||
// 准备参数
|
||||
Long id = sensitiveWord.getId();
|
||||
|
||||
// 调用
|
||||
SensitiveWordDO dbSensitiveWord = sensitiveWordService.getSensitiveWord(id);
|
||||
// 断言
|
||||
assertPojoEquals(sensitiveWord, dbSensitiveWord);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSensitiveWordList() {
|
||||
// mock 数据
|
||||
SensitiveWordDO sensitiveWord01 = randomPojo(SensitiveWordDO.class);
|
||||
sensitiveWordMapper.insert(sensitiveWord01);
|
||||
SensitiveWordDO sensitiveWord02 = randomPojo(SensitiveWordDO.class);
|
||||
sensitiveWordMapper.insert(sensitiveWord02);
|
||||
|
||||
// 调用
|
||||
List<SensitiveWordDO> list = sensitiveWordService.getSensitiveWordList();
|
||||
// 断言
|
||||
assertEquals(2, list.size());
|
||||
assertEquals(sensitiveWord01, list.get(0));
|
||||
assertEquals(sensitiveWord02, list.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSensitiveWordPage() {
|
||||
// mock 数据
|
||||
SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class, o -> { // 等会查询到
|
||||
o.setName("笨蛋");
|
||||
o.setTags(Arrays.asList("论坛", "蔬菜"));
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2022, 2, 8));
|
||||
});
|
||||
sensitiveWordMapper.insert(dbSensitiveWord);
|
||||
// 测试 name 不匹配
|
||||
sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setName("傻瓜")));
|
||||
// 测试 tags 不匹配
|
||||
sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setTags(Arrays.asList("短信", "日用品"))));
|
||||
// 测试 createTime 不匹配
|
||||
sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setCreateTime(buildTime(2022, 2, 16))));
|
||||
// 准备参数
|
||||
SensitiveWordPageReqVO reqVO = new SensitiveWordPageReqVO();
|
||||
reqVO.setName("笨");
|
||||
reqVO.setTag("论坛");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2022, 2, 1, 2022, 2, 12));
|
||||
|
||||
// 调用
|
||||
PageResult<SensitiveWordDO> pageResult = sensitiveWordService.getSensitiveWordPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbSensitiveWord, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateText_noTag() {
|
||||
testInitLocalCache();
|
||||
// 准备参数
|
||||
String text = "你是傻瓜,你是笨蛋";
|
||||
// 调用
|
||||
List<String> result = sensitiveWordService.validateText(text, null);
|
||||
// 断言
|
||||
assertEquals(Arrays.asList("傻瓜", "笨蛋"), result);
|
||||
|
||||
// 准备参数
|
||||
String text2 = "你是傻瓜,你是笨蛋,你是白";
|
||||
// 调用
|
||||
List<String> result2 = sensitiveWordService.validateText(text2, null);
|
||||
// 断言
|
||||
assertEquals(Arrays.asList("傻瓜", "笨蛋","白"), result2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateText_hasTag() {
|
||||
testInitLocalCache();
|
||||
// 准备参数
|
||||
String text = "你是傻瓜,你是笨蛋";
|
||||
// 调用
|
||||
List<String> result = sensitiveWordService.validateText(text, singletonList("论坛"));
|
||||
// 断言
|
||||
assertEquals(singletonList("傻瓜"), result);
|
||||
|
||||
|
||||
// 准备参数
|
||||
String text2 = "你是白";
|
||||
// 调用
|
||||
List<String> result2 = sensitiveWordService.validateText(text2, singletonList("测试"));
|
||||
// 断言
|
||||
assertEquals(singletonList("白"), result2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsTestValid_noTag() {
|
||||
testInitLocalCache();
|
||||
// 准备参数
|
||||
String text = "你是傻瓜,你是笨蛋";
|
||||
// 调用,断言
|
||||
assertFalse(sensitiveWordService.isTextValid(text, null));
|
||||
|
||||
// 准备参数
|
||||
String text2 = "你是白";
|
||||
// 调用,断言
|
||||
assertFalse(sensitiveWordService.isTextValid(text2, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsTestValid_hasTag() {
|
||||
testInitLocalCache();
|
||||
// 准备参数
|
||||
String text = "你是傻瓜,你是笨蛋";
|
||||
// 调用,断言
|
||||
assertFalse(sensitiveWordService.isTextValid(text, singletonList("论坛")));
|
||||
|
||||
// 准备参数
|
||||
String text2 = "你是白";
|
||||
// 调用,断言
|
||||
assertFalse(sensitiveWordService.isTextValid(text2, singletonList("测试")));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue