Commit d85c499b authored by 万成波's avatar 万成波

敏感词

parent 6a781be8
......@@ -151,6 +151,20 @@
<artifactId>safe-campus-common</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 轻享模块-->
<dependency>
<groupId>com.tangguo</groupId>
<artifactId>safe-campus-moment</artifactId>
<version>3.8.5</version>
</dependency>
<!-- 积分模块-->
<dependency>
<groupId>com.tangguo</groupId>
<artifactId>safe-campus-points</artifactId>
<version>3.8.5</version>
</dependency>
</dependencies>
</dependencyManagement>
......
......@@ -31,6 +31,12 @@
<groupId>com.tangguo</groupId>
<artifactId>safe-campus-generator</artifactId>
</dependency>
<!-- 轻享模块 -->
<dependency>
<groupId>com.tangguo</groupId>
<artifactId>safe-campus-moment</artifactId>
</dependency>
</dependencies>
<build>
......
package com.tangguo.common.core.redis;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
......@@ -154,6 +155,33 @@ public class RedisCache {
return setOperation;
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param values 缓存的数据
* @return 缓存数据的对象
*/
public <T> void setAddValues(final String key, final T ...values) {
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
setOperation.add(values);
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param values 缓存的数据
* @return 缓存数据的对象
*/
public <T> void setDeleteValues(final String key, final T ...values) {
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
setOperation.remove(values);
}
/**
* 获得缓存的set
*
......
package com.tangguo.controller;
import com.tangguo.common.annotation.Log;
import com.tangguo.common.core.controller.BaseController;
import com.tangguo.common.core.domain.AjaxResult;
import com.tangguo.common.core.page.TableDataInfo;
import com.tangguo.common.enums.BusinessType;
import com.tangguo.common.utils.poi.ExcelUtil;
import com.tangguo.domain.BbsSensitiveWord;
import com.tangguo.domain.result.DataImportResult;
import com.tangguo.service.IBbsSensitiveWordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
/**
* 敏感词库Controller
*
* @author ruoyi
* @date 2025-08-27
*/
@Api(tags = "敏感词库管理")
@RestController
@RequestMapping("/bbs/moment/sensitive/word")
public class BbsSensitiveWordController extends BaseController {
@Resource
private IBbsSensitiveWordService bbsSensitiveWordService;
/**
* 查询敏感词库列表
*/
@ApiOperation("查询敏感词库列表")
@PreAuthorize("@ss.hasPermi('word:word:list')")
@GetMapping("/list")
public TableDataInfo list(BbsSensitiveWord bbsSensitiveWord) {
startPage();
List<BbsSensitiveWord> list = bbsSensitiveWordService.selectBbsSensitiveWordList(bbsSensitiveWord);
return getDataTable(list);
}
/**
* 获取敏感词库详细信息
*/
@ApiOperation("获取敏感词库详细信息")
@PreAuthorize("@ss.hasPermi('word:word:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(bbsSensitiveWordService.getById(id));
}
/**
* 新增敏感词库
*/
@ApiOperation("新增敏感词库")
@PreAuthorize("@ss.hasPermi('word:word:add')")
@Log(title = "敏感词库", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody BbsSensitiveWord word) {
this.bbsSensitiveWordService.addWord(word);
return AjaxResult.success();
}
/**
* 修改敏感词库
*/
@ApiOperation("修改敏感词库")
@PreAuthorize("@ss.hasPermi('word:word:edit')")
@Log(title = "敏感词库", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody BbsSensitiveWord word) {
this.bbsSensitiveWordService.editWord(word);
return AjaxResult.success();
}
/**
* 删除敏感词库
*/
@ApiOperation("删除敏感词库")
@PreAuthorize("@ss.hasPermi('word:word:remove')")
@Log(title = "敏感词库", businessType = BusinessType.DELETE)
@DeleteMapping("/{id}")
public AjaxResult remove(@PathVariable Long id) {
this.bbsSensitiveWordService.deleteWord(id);
return AjaxResult.success();
}
/**
* 修改敏感词库
*/
@ApiOperation("修改敏感词库")
@PreAuthorize("@ss.hasPermi('word:word:edit')")
@Log(title = "敏感词库", businessType = BusinessType.UPDATE)
@PostMapping("/import")
public AjaxResult importWords(MultipartFile file) {
DataImportResult<String> result = this.bbsSensitiveWordService.importWords(file);
return AjaxResult.success(result);
}
}
......@@ -13,7 +13,6 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
/**
......
package com.tangguo.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.tangguo.common.annotation.Excel;
import com.tangguo.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
/**
* 敏感词库对象 bbs_sensitive_word
*
* @author ruoyi
* @date 2025-08-27
*/
@Data
@ToString
@NoArgsConstructor
@Accessors(chain = true)
@TableName("bbs_sensitive_word")
@ApiModel(value = "BbsSensitiveWord", description = "敏感词库实体")
public class BbsSensitiveWord extends BaseEntity {
private static final long serialVersionUID = 1L;
/** ID */
@TableId(type = IdType.AUTO)
@ApiModelProperty("ID")
private Long id;
/** 敏感词名称 */
@Excel(name = "敏感词名称")
@ApiModelProperty("敏感词名称")
private String name;
/** 排序值 */
@Excel(name = "排序值")
@ApiModelProperty("排序值")
private Integer sort;
/** 启用状态:0 禁用、1 启用 */
@Excel(name = "启用状态:0 禁用、1 启用")
@ApiModelProperty("启用状态:0 禁用、1 启用")
private Integer enableStatus;
}
package com.tangguo.domain.result;
import lombok.Data;
import org.apache.poi.ss.formula.functions.T;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 数据导入结果
*
* @author 谈笑
* @createTime 2025-08-28 09:43:53 星期四
*/
@Data
public class DataImportResult<T> implements Serializable {
private static final long serialVersionUID = -1544586244818112713L;
/**
* 导入任务Id
*/
private String taskId;
/**
* 导入数据总条数
*/
private int totalCount;
/**
* 导入成功数据条数
*/
private int successCount;
/**
* 导入失败数据条数
*/
private int failCount;
/**
* 导入失败消息
*/
private String errorMessage;
/**
* 导入数据失败数据明细
*/
private List<Row<T>> failRows = new ArrayList<>(0);
@Data
public static class Row<T> implements Serializable {
private static final long serialVersionUID = -437773899860737658L;
/**
* 原始数据
*/
private T rowData;
/**
* 反馈消息
*/
private String message;
}
}
package com.tangguo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tangguo.domain.BbsSensitiveWord;
/**
* 敏感词库Mapper接口
*
* @author ruoyi
* @date 2025-08-27
*/
public interface BbsSensitiveWordMapper extends BaseMapper<BbsSensitiveWord> {
}
package com.tangguo.service;
import java.util.List;
import java.util.Set;
import com.baomidou.mybatisplus.extension.service.IService;
import com.tangguo.domain.BbsSensitiveWord;
import com.tangguo.domain.result.DataImportResult;
import org.springframework.web.multipart.MultipartFile;
/**
* 敏感词库Service接口
*
* @author ruoyi
* @date 2025-08-27
*/
public interface IBbsSensitiveWordService extends IService<BbsSensitiveWord> {
/**
* 查询敏感词
*
* @return 敏感词
*/
Set<String> getDbWords();
/**
* 查询敏感词库列表
*
* @param bbsSensitiveWord 敏感词库
* @return 敏感词库集合
*/
List<BbsSensitiveWord> selectBbsSensitiveWordList(BbsSensitiveWord bbsSensitiveWord);
/**
* 新增敏感词
*
* @param word 敏感词
*/
void addWord(BbsSensitiveWord word);
/**
* 修改敏感词
*
* @param word 敏感词
*/
void editWord(BbsSensitiveWord word);
/**
* 删除敏感词
*
* @param wordId 敏感词Id
*/
void deleteWord(Long wordId);
/**
* 导入敏感词
*
* @param file 铭感词文件
* @return 导入结果
*/
DataImportResult<String> importWords(MultipartFile file);
}
package com.tangguo.service.impl;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tangguo.common.core.redis.RedisCache;
import com.tangguo.common.exception.ServiceException;
import com.tangguo.common.utils.StringUtils;
import com.tangguo.domain.BbsSensitiveWord;
import com.tangguo.domain.result.DataImportResult;
import com.tangguo.mapper.BbsSensitiveWordMapper;
import com.tangguo.service.IBbsSensitiveWordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.*;
import java.nio.file.Files;
import java.util.*;
/**
* 敏感词库Service业务层处理
*
* @author ruoyi
* @date 2025-08-27
*/
@Slf4j
@Service
public class BbsSensitiveWordServiceImpl extends ServiceImpl<BbsSensitiveWordMapper, BbsSensitiveWord> implements IBbsSensitiveWordService {
private static final String WORD_CACHE_KEY = "sensitive:words";
@Resource
private BbsSensitiveWordMapper bbsSensitiveWordMapper;
@Resource
private RedisCache redisCache;
@PostConstruct
private void initCacheWords() {
Set<String> dbWords = this.getDbWords();
this.redisCache.setCacheSet(WORD_CACHE_KEY, new HashSet<>(dbWords));
log.info("=> 数据库敏感词已缓存,敏感词数量:{}", dbWords.size());
}
/**
* 查询敏感词
*
* @return 敏感词
*/
@Override
public Set<String> getDbWords() {
List<String> dbWords = this.listObjs(
Wrappers.lambdaQuery(BbsSensitiveWord.class).select(BbsSensitiveWord::getName), Objects::toString
);
return new HashSet<>(dbWords);
}
/**
* 查询敏感词库列表
*
* @param word 敏感词库
* @return 敏感词库
*/
@Override
public List<BbsSensitiveWord> selectBbsSensitiveWordList(BbsSensitiveWord word) {
LambdaQueryWrapper<BbsSensitiveWord> lqw = Wrappers.lambdaQuery();
lqw.orderByDesc(BbsSensitiveWord::getCreateTime);
lqw.like(StringUtils.isNotBlank(word.getName()), BbsSensitiveWord::getName, word.getName());
return bbsSensitiveWordMapper.selectList(lqw);
}
/**
* 新增敏感词
*
* @param word 敏感词
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void addWord(BbsSensitiveWord word) {
long wordCount = this.count(
Wrappers.lambdaQuery(BbsSensitiveWord.class).eq(BbsSensitiveWord::getName, word.getName())
);
if (wordCount > 0) {
throw new ServiceException("添加失败,当前敏感词已存在。");
}
BbsSensitiveWord addWord = new BbsSensitiveWord();
addWord.setName(word.getName());
addWord.setSort(word.getSort());
addWord.setEnableStatus(1);
this.save(addWord);
this.redisCache.setAddValues(WORD_CACHE_KEY, word.getName());
}
/**
* 修改敏感词
*
* @param word 敏感词
*/
@Override
public void editWord(BbsSensitiveWord word) {
BbsSensitiveWord dbWord = this.getById(word.getId());
if (Objects.isNull(dbWord)) {
throw new ServiceException("修改失败,未查询到当前敏感词数据。");
}
if (!dbWord.getName().equals(word.getName())) {
long wordCount = this.count(
Wrappers.lambdaQuery(BbsSensitiveWord.class).eq(BbsSensitiveWord::getName, word.getName())
);
if (wordCount > 0) {
throw new ServiceException("修改失败,当前敏感词已存在。");
}
}
BbsSensitiveWord updWord = new BbsSensitiveWord();
updWord.setId(word.getId());
updWord.setName(word.getName());
updWord.setSort(word.getSort());
this.updateById(updWord);
this.redisCache.setDeleteValues(WORD_CACHE_KEY, dbWord.getName());
this.redisCache.setAddValues(WORD_CACHE_KEY, word.getName());
}
/**
* 删除敏感词
*
* @param wordId 敏感词Id
*/
@Override
public void deleteWord(Long wordId) {
BbsSensitiveWord dbWord = this.getById(wordId);
if (Objects.nonNull(dbWord)) {
this.removeById(wordId);
this.redisCache.setDeleteValues(WORD_CACHE_KEY, dbWord.getName());
}
}
/**
* 导入敏感词
*
* @param file 铭感词文件
* @return 导入结果
*/
@Override
public DataImportResult<String> importWords(MultipartFile file) {
DataImportResult<String> result = new DataImportResult<>();
BufferedReader reader = null;
try {
// 读取敏感词
reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
String word;
Set<String> words = new LinkedHashSet<>(10);
while (Objects.nonNull(word = reader.readLine())) {
if (StrUtil.isNotBlank(word)) {
words.add(word);
}
}
// 校验敏感词
Set<String> cacheWords = this.redisCache.getCacheSet(WORD_CACHE_KEY);
List<String> addWords = new ArrayList<>(words.size());
for (String w : words) {
if (cacheWords.contains(w)) {
DataImportResult.Row<String> row = new DataImportResult.Row<>();
row.setRowData(w);
row.setMessage("当前敏感词已存在");
result.getFailRows().add(row);
} else {
addWords.add(w);
}
}
// 添加敏感词
List<BbsSensitiveWord> newWords = new ArrayList<>(addWords.size());
for (String addWord : addWords) {
BbsSensitiveWord newWord = new BbsSensitiveWord();
newWord.setName(addWord);
newWords.add(newWord);
}
super.saveBatch(newWords);
// 缓存敏感词
this.redisCache.setAddValues(WORD_CACHE_KEY, addWords.toArray());
result.setTotalCount(words.size());
result.setSuccessCount(addWords.size());
result.setFailCount(words.size() - addWords.size());
} catch (Exception e) {
log.error("=> 导入敏感词失败:", e);
} finally {
IoUtil.close(reader);
}
return result;
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tangguo.mapper.BbsSensitiveWordMapper">
<resultMap type="BbsSensitiveWord" id="BbsSensitiveWordResult">
<result property="id" column="id" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<result property="name" column="name" />
<result property="sort" column="sort" />
<result property="enableStatus" column="enable_status" />
</resultMap>
</mapper>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment