diff --git a/buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java b/buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java index 30ef2cf8..4a8a523b 100644 --- a/buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java +++ b/buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java @@ -11,7 +11,7 @@ import cn.lili.modules.connect.entity.dto.ConnectAuthUser; import cn.lili.modules.connect.request.AuthRequest; import cn.lili.modules.connect.service.ConnectService; import cn.lili.modules.connect.util.ConnectUtil; -import cn.lili.modules.connect.util.UuidUtils; +import cn.lili.common.utils.UuidUtils; import cn.lili.modules.member.service.MemberService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; diff --git a/framework/pom.xml b/framework/pom.xml index 170bd277..4d26218a 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -26,6 +26,12 @@ + + + org.springframework.boot + spring-boot-starter-quartz + + org.springframework.boot spring-boot-starter-web @@ -74,11 +80,11 @@ org.springframework.boot spring-boot-starter-data-mongodb - - - - - + + + + + com.baomidou @@ -265,11 +271,11 @@ logstash-logback-encoder ${logstash-logback-encoder} - - - - - + + + + + de.codecentric spring-boot-admin-starter-client diff --git a/framework/src/main/java/cn/lili/cache/CachePrefix.java b/framework/src/main/java/cn/lili/cache/CachePrefix.java index 8b3bab3f..27740abe 100644 --- a/framework/src/main/java/cn/lili/cache/CachePrefix.java +++ b/framework/src/main/java/cn/lili/cache/CachePrefix.java @@ -480,7 +480,11 @@ public enum CachePrefix { /** * 订单暂时缓存 */ - ORDER; + ORDER, + /** + * 敏感词 + */ + SENSITIVE; public static String removePrefix(String str) { diff --git a/framework/src/main/java/cn/lili/common/sensitive/SensitiveWordsFilter.java b/framework/src/main/java/cn/lili/common/sensitive/SensitiveWordsFilter.java index 9191fc65..14f70b0c 100644 --- a/framework/src/main/java/cn/lili/common/sensitive/SensitiveWordsFilter.java +++ b/framework/src/main/java/cn/lili/common/sensitive/SensitiveWordsFilter.java @@ -1,4 +1,4 @@ -package cn.lili.modules.system.utils; +package cn.lili.common.sensitive; import lombok.extern.slf4j.Slf4j; @@ -34,7 +34,12 @@ public class SensitiveWordsFilter implements Serializable { * 类似HashMap的桶,比较稀疏。 * 使用2个字符的hash定位。 */ - protected static SensitiveWordsNode[] nodes; + protected static SensitiveWordsNode[] nodes = new SensitiveWordsNode[0]; + + /** + * 更新中的nodes,用于防止动态更新时,原有nodes被清空,导致无法正常写入过滤词 + */ + protected static SensitiveWordsNode[] nodesUpdate; /** @@ -150,13 +155,14 @@ public class SensitiveWordsFilter implements Serializable { * 初始化敏感词 */ public static void init(List words) { - nodes = new SensitiveWordsNode[DEFAULT_INITIAL_CAPACITY]; + log.info("开始初始化敏感词"); + nodesUpdate = new SensitiveWordsNode[DEFAULT_INITIAL_CAPACITY]; for (String word : words) { put(word); } + nodes = nodesUpdate; } - /** * 增加一个敏感词,如果词的长度(trim后)小于2,则丢弃
* 此方法(构建)并不是主要的性能优化点。 @@ -180,17 +186,17 @@ public class SensitiveWordsFilter implements Serializable { //计算头两个字符的mix表示(mix相同,两个字符相同) int mix = sp.nextTwoCharMix(0); //转为在hash桶中的位置 - int index = hash & (nodes.length - 1); + int index = hash & (nodesUpdate.length - 1); //从桶里拿第一个节点 - SensitiveWordsNode node = nodes[index]; + SensitiveWordsNode node = nodesUpdate[index]; if (node == null) { //如果没有节点,则放进去一个 node = new SensitiveWordsNode(mix); //并添加词 node.words.add(sp); //放入桶里 - nodes[index] = node; + nodesUpdate[index] = node; } else { //如果已经有节点(1个或多个),找到正确的节点 for (; node != null; node = node.next) { diff --git a/framework/src/main/java/cn/lili/common/sensitive/SensitiveWordsNode.java b/framework/src/main/java/cn/lili/common/sensitive/SensitiveWordsNode.java index 7932b773..aa3131f9 100644 --- a/framework/src/main/java/cn/lili/common/sensitive/SensitiveWordsNode.java +++ b/framework/src/main/java/cn/lili/common/sensitive/SensitiveWordsNode.java @@ -1,4 +1,4 @@ -package cn.lili.modules.system.utils; +package cn.lili.common.sensitive; import java.io.Serializable; import java.util.TreeSet; diff --git a/framework/src/main/java/cn/lili/common/sensitive/StringPointer.java b/framework/src/main/java/cn/lili/common/sensitive/StringPointer.java index 1f211a02..7e9e98f5 100644 --- a/framework/src/main/java/cn/lili/common/sensitive/StringPointer.java +++ b/framework/src/main/java/cn/lili/common/sensitive/StringPointer.java @@ -1,13 +1,14 @@ -package cn.lili.modules.system.utils; +package cn.lili.common.sensitive; import java.io.Serializable; /** + * 字符指针 * * @author Bulbasaur * @since 2020-02-25 14:10:16 */ -public class StringPointer implements Serializable, CharSequence, Comparable{ +public class StringPointer implements Serializable, CharSequence, Comparable { private static final long serialVersionUID = 1L; @@ -19,13 +20,13 @@ public class StringPointer implements Serializable, CharSequence, Comparable length - i){ + if (word.length > length - i) { return false; } //从尾开始判断 - for(int c = word.length - 1; c >= 0; c --){ - if(value[offset + i + c] != word.value[word.offset + c]){ + for (int c = word.length - 1; c >= 0; c--) { + if (value[offset + i + c] != word.value[word.offset + c]) { return false; } } @@ -76,31 +78,31 @@ public class StringPointer implements Serializable, CharSequence, Comparable sensitives = cache.get(CachePrefix.SENSITIVE.getPrefix()); + log.info("系统初始化敏感词"); if (sensitives == null || sensitives.isEmpty()) { return; } diff --git a/framework/src/main/java/cn/lili/common/sensitive/quartz/QuartzConfig.java b/framework/src/main/java/cn/lili/common/sensitive/quartz/QuartzConfig.java index 034c9fd2..9d971984 100644 --- a/framework/src/main/java/cn/lili/common/sensitive/quartz/QuartzConfig.java +++ b/framework/src/main/java/cn/lili/common/sensitive/quartz/QuartzConfig.java @@ -1,11 +1,31 @@ package cn.lili.common.sensitive.quartz; + +import org.quartz.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + /** - * - * QuartzConfig + * 定时执行配置 + * * @author Chopper * @version v1.0 * 2021-11-23 16:30 - * - */ + */ +@Configuration public class QuartzConfig { -} + @Bean + public JobDetail sensitiveQuartzDetail() { + return JobBuilder.newJob(SensitiveQuartz.class).withIdentity("sensitiveQuartz").storeDurably().build(); + } + + @Bean + public Trigger sensitiveQuartzTrigger() { + SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() + .withIntervalInSeconds(3600) + .repeatForever(); + return TriggerBuilder.newTrigger().forJob(sensitiveQuartzDetail()) + .withIdentity("sensitiveQuartz") + .withSchedule(scheduleBuilder) + .build(); + } +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/common/sensitive/quartz/SensitiveQuartz.java b/framework/src/main/java/cn/lili/common/sensitive/quartz/SensitiveQuartz.java index 3f237ff3..ab1f2bcc 100644 --- a/framework/src/main/java/cn/lili/common/sensitive/quartz/SensitiveQuartz.java +++ b/framework/src/main/java/cn/lili/common/sensitive/quartz/SensitiveQuartz.java @@ -1,11 +1,41 @@ package cn.lili.common.sensitive.quartz; + +import cn.lili.cache.Cache; +import cn.lili.cache.CachePrefix; +import cn.lili.common.sensitive.SensitiveWordsFilter; +import lombok.extern.slf4j.Slf4j; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.quartz.QuartzJobBean; + +import java.util.List; + /** - * - * SensitiveQuartz + * 间隔更新敏感词 + * * @author Chopper * @version v1.0 * 2021-11-23 16:31 - * - */ -public class SensitiveQuartz { -} + */ +@Slf4j +public class SensitiveQuartz extends QuartzJobBean { + + @Autowired + private Cache> cache; + + /** + * 定时更新敏感词信息 + * + * @param jobExecutionContext + */ + @Override + protected void executeInternal(JobExecutionContext jobExecutionContext) { + log.info("敏感词定时更新"); + List sensitives = cache.get(CachePrefix.SENSITIVE.getPrefix()); + if (sensitives == null || sensitives.isEmpty()) { + return; + } + SensitiveWordsFilter.init(sensitives); + } +} \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/common/utils/UuidUtils.java b/framework/src/main/java/cn/lili/common/utils/UuidUtils.java index af9b2cdd..b9f17bcb 100644 --- a/framework/src/main/java/cn/lili/common/utils/UuidUtils.java +++ b/framework/src/main/java/cn/lili/common/utils/UuidUtils.java @@ -1,4 +1,4 @@ -package cn.lili.modules.connect.util; +package cn.lili.common.utils; import java.nio.charset.StandardCharsets; import java.util.concurrent.ThreadLocalRandom; diff --git a/framework/src/main/java/cn/lili/modules/connect/request/BaseAuthRequest.java b/framework/src/main/java/cn/lili/modules/connect/request/BaseAuthRequest.java index 9e1274dc..51f0aa96 100644 --- a/framework/src/main/java/cn/lili/modules/connect/request/BaseAuthRequest.java +++ b/framework/src/main/java/cn/lili/modules/connect/request/BaseAuthRequest.java @@ -13,7 +13,7 @@ import cn.lili.modules.connect.entity.enums.AuthResponseStatus; import cn.lili.modules.connect.exception.AuthException; import cn.lili.modules.connect.util.AuthChecker; import cn.lili.common.utils.HttpUtils; -import cn.lili.modules.connect.util.UuidUtils; +import cn.lili.common.utils.UuidUtils; import com.xkcoding.http.util.UrlUtil; import lombok.extern.slf4j.Slf4j; diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberEvaluationServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberEvaluationServiceImpl.java index 6c6432e7..858bea4e 100644 --- a/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberEvaluationServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberEvaluationServiceImpl.java @@ -31,8 +31,7 @@ import cn.lili.modules.order.order.entity.dos.OrderItem; import cn.lili.modules.order.order.entity.enums.CommentStatusEnum; import cn.lili.modules.order.order.service.OrderItemService; import cn.lili.modules.order.order.service.OrderService; -import cn.lili.modules.system.utils.CharacterConstant; -import cn.lili.modules.system.utils.SensitiveWordsFilter; +import cn.lili.common.sensitive.SensitiveWordsFilter; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -121,7 +120,7 @@ public class MemberEvaluationServiceImpl extends ServiceImpl impleme } //过滤会员昵称敏感词 if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(managerMemberEditDTO.getNickName())) { - managerMemberEditDTO.setNickName(SensitiveWordsFilter.filter(managerMemberEditDTO.getNickName(), CharacterConstant.WILDCARD_STAR)); + managerMemberEditDTO.setNickName(SensitiveWordsFilter.filter(managerMemberEditDTO.getNickName())); } //如果密码不为空则加密密码 if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(managerMemberEditDTO.getPassword())) { diff --git a/framework/src/main/java/cn/lili/modules/system/service/SensitiveWordsService.java b/framework/src/main/java/cn/lili/modules/system/service/SensitiveWordsService.java index 239fa94d..ac772590 100644 --- a/framework/src/main/java/cn/lili/modules/system/service/SensitiveWordsService.java +++ b/framework/src/main/java/cn/lili/modules/system/service/SensitiveWordsService.java @@ -11,5 +11,9 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface SensitiveWordsService extends IService { + /** + * 重新写入缓存 + */ + void resetCache(); } \ No newline at end of file diff --git a/framework/src/main/java/cn/lili/modules/system/serviceimpl/SensitiveWordsServiceImpl.java b/framework/src/main/java/cn/lili/modules/system/serviceimpl/SensitiveWordsServiceImpl.java index 9a16a185..e4e51155 100644 --- a/framework/src/main/java/cn/lili/modules/system/serviceimpl/SensitiveWordsServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/system/serviceimpl/SensitiveWordsServiceImpl.java @@ -1,5 +1,7 @@ package cn.lili.modules.system.serviceimpl; +import cn.lili.cache.Cache; +import cn.lili.cache.CachePrefix; import cn.lili.modules.system.entity.dos.SensitiveWords; import cn.lili.modules.system.mapper.SensitiveWordsMapper; import cn.lili.modules.system.service.SensitiveWordsService; @@ -9,6 +11,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.stream.Collectors; + /** * 敏感词业务层实现 * @@ -17,5 +22,17 @@ import org.springframework.transaction.annotation.Transactional; */ @Service public class SensitiveWordsServiceImpl extends ServiceImpl implements SensitiveWordsService { + @Autowired + private Cache> cache; + @Override + public void resetCache() { + List sensitiveWordsList = this.list(); + + if (sensitiveWordsList == null || sensitiveWordsList.isEmpty()) { + return; + } + List sensitiveWords = sensitiveWordsList.stream().map(SensitiveWords::getSensitiveWord).collect(Collectors.toList()); + cache.put(CachePrefix.SENSITIVE.getPrefix(), sensitiveWords); + } } \ No newline at end of file diff --git a/manager-api/src/main/java/cn/lili/controller/other/SensitiveWordsManagerController.java b/manager-api/src/main/java/cn/lili/controller/other/SensitiveWordsManagerController.java index 5ca04bc2..4f635c2b 100644 --- a/manager-api/src/main/java/cn/lili/controller/other/SensitiveWordsManagerController.java +++ b/manager-api/src/main/java/cn/lili/controller/other/SensitiveWordsManagerController.java @@ -6,7 +6,7 @@ import cn.lili.common.vo.PageVO; import cn.lili.common.vo.ResultMessage; import cn.lili.modules.system.entity.dos.SensitiveWords; import cn.lili.modules.system.service.SensitiveWordsService; -import cn.lili.modules.system.utils.SensitiveWordsFilter; +import cn.lili.common.sensitive.SensitiveWordsFilter; import com.baomidou.mybatisplus.core.metadata.IPage; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -48,7 +48,7 @@ public class SensitiveWordsManagerController { @PostMapping public ResultMessage add(@Valid SensitiveWords sensitiveWords) { sensitiveWordsService.save(sensitiveWords); - SensitiveWordsFilter.put(sensitiveWords.getSensitiveWord()); + sensitiveWordsService.resetCache(); return ResultUtil.data(sensitiveWords); } @@ -58,7 +58,7 @@ public class SensitiveWordsManagerController { public ResultMessage edit(@PathVariable String id, SensitiveWords sensitiveWords) { sensitiveWords.setId(id); sensitiveWordsService.updateById(sensitiveWords); - SensitiveWordsFilter.put(sensitiveWords.getSensitiveWord()); + sensitiveWordsService.resetCache(); return ResultUtil.data(sensitiveWords); } @@ -66,12 +66,8 @@ public class SensitiveWordsManagerController { @ApiImplicitParam(name = "ids", value = "敏感词ID", required = true, dataType = "String", allowMultiple = true, paramType = "path") @DeleteMapping(value = "/delByIds/{ids}") public ResultMessage delAllByIds(@PathVariable List ids) { - for (String id : ids) { - String name = sensitiveWordsService.getById(id).getSensitiveWord(); - SensitiveWordsFilter.remove(name); - sensitiveWordsService.removeById(id); - } + sensitiveWordsService.removeByIds(ids); + sensitiveWordsService.resetCache(); return ResultUtil.success(); - } }