From 9c93cf950d7f68af8dc5e8b89a5e4df6a66647b3 Mon Sep 17 00:00:00 2001 From: Qing Date: Fri, 8 Mar 2024 16:25:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20redis=E7=82=B9=E8=B5=9E=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=90=8C=E6=AD=A5=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SubjectLikedController.java | 41 +++++-- .../convert/SubjectLikedDTOConverter.java | 4 + .../application/dto/SubjectInfoDTO.java | 17 +++ .../application/dto/SubjectLikedDTO.java | 3 +- .../qing-yu-club-domain/pom.xml | 10 ++ .../subject/domain/config/XxlJobConfig.java | 78 +++++++++++++ .../convert/SubjectLikedBOConverter.java | 5 + .../subject/domain/entity/SubjectInfoBO.java | 18 +++ .../subject/domain/entity/SubjectLikedBO.java | 3 +- .../subject/domain/job/SyncLikedJob.java | 38 +++++++ .../subject/domain/redis/RedisUtil.java | 31 ++++- .../service/SubjectLikedDomainService.java | 18 ++- .../impl/SubjectInfoDomainServiceImpl.java | 6 + .../impl/SubjectLikedDomainServiceImpl.java | 107 +++++++++++++++++- .../infra/basic/mapper/SubjectLikedDao.java | 10 ++ .../basic/service/SubjectLikedService.java | 8 ++ .../service/impl/SubjectLikedServiceImpl.java | 16 +++ .../main/resources/mapper/SubjectLikedDao.xml | 30 +++++ .../src/main/resources/application.yml | 12 ++ 19 files changed, 436 insertions(+), 19 deletions(-) create mode 100644 qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/config/XxlJobConfig.java create mode 100644 qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/job/SyncLikedJob.java diff --git a/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/controller/SubjectLikedController.java b/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/controller/SubjectLikedController.java index 912a733..5686de9 100644 --- a/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/controller/SubjectLikedController.java +++ b/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/controller/SubjectLikedController.java @@ -4,10 +4,13 @@ import com.alibaba.fastjson.JSON; import com.google.common.base.Preconditions; import com.landaiqing.subject.application.convert.SubjectLikedDTOConverter; import com.landaiqing.subject.application.dto.SubjectLikedDTO; +import com.landaiqing.subject.common.entity.PageResult; import com.landaiqing.subject.common.entity.Result; +import com.landaiqing.subject.common.util.LoginUtil; import com.landaiqing.subject.domain.entity.SubjectLikedBO; import com.landaiqing.subject.domain.service.SubjectLikedDomainService; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -38,17 +41,15 @@ public class SubjectLikedController { if (log.isInfoEnabled()) { log.info("SubjectLikedController.add.dto:{}", JSON.toJSONString(subjectLikedDTO)); } - Preconditions.checkNotNull(subjectLikedDTO.getId(), "不能为空"); - Preconditions.checkNotNull(subjectLikedDTO.getSubjectId(), "不能为空"); - Preconditions.checkNotNull(subjectLikedDTO.getLikeUserId(), "不能为空"); - Preconditions.checkNotNull(subjectLikedDTO.getStatus(), "不能为空"); - Preconditions.checkNotNull(subjectLikedDTO.getCreatedBy(), "创建人不能为空"); - Preconditions.checkNotNull(subjectLikedDTO.getCreatedTime(), "创建时间不能为空"); - Preconditions.checkNotNull(subjectLikedDTO.getUpdateBy(), "更新人不能为空"); - Preconditions.checkNotNull(subjectLikedDTO.getUpdateTime(), "更新时间不能为空"); - Preconditions.checkNotNull(subjectLikedDTO.getIsDeleted(), "不能为空"); + Preconditions.checkNotNull(subjectLikedDTO.getSubjectId(), "题目id不能为空"); + Preconditions.checkNotNull(subjectLikedDTO.getStatus(), "点赞状态 1点赞 0不点赞 不能为空"); + String loginId = LoginUtil.getLoginId(); + subjectLikedDTO.setLikeUserId(loginId); + Preconditions.checkNotNull(subjectLikedDTO.getLikeUserId(), "点赞人不能为空"); + SubjectLikedBO SubjectLikedBO = SubjectLikedDTOConverter.INSTANCE.convertDTOToBO(subjectLikedDTO); - return Result.ok(subjectLikedDomainService.add(SubjectLikedBO)); + subjectLikedDomainService.add(SubjectLikedBO); + return Result.ok(true); } catch (Exception e) { log.error("SubjectLikedController.register.error:{}", e.getMessage(), e); return Result.fail("新增题目点赞表失败"); @@ -112,4 +113,24 @@ public class SubjectLikedController { } + /** + * 查询我的点赞列表 + */ + @PostMapping("/getSubjectLikedPage") + public Result> getSubjectLikedPage(@RequestBody SubjectLikedDTO subjectLikedDTO) { + try { + if (log.isInfoEnabled()) { + log.info("SubjectController.getSubjectLikedPage.dto:{}", JSON.toJSONString(subjectLikedDTO)); + } + SubjectLikedBO subjectLikedBO = SubjectLikedDTOConverter.INSTANCE.convertDTOToBO(subjectLikedDTO); + subjectLikedBO.setPageNo(subjectLikedDTO.getPageNo()); + subjectLikedBO.setPageSize(subjectLikedDTO.getPageSize()); + PageResult boPageResult = subjectLikedDomainService.getSubjectLikedPage(subjectLikedBO); + return Result.ok(boPageResult); + } catch (Exception e) { + log.error("SubjectCategoryController.getSubjectLikedPage.error:{}", e.getMessage(), e); + return Result.fail("分页查询我的点赞失败"); + } + } + } diff --git a/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/convert/SubjectLikedDTOConverter.java b/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/convert/SubjectLikedDTOConverter.java index 102834b..1a7819b 100644 --- a/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/convert/SubjectLikedDTOConverter.java +++ b/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/convert/SubjectLikedDTOConverter.java @@ -2,9 +2,12 @@ package com.landaiqing.subject.application.convert; import com.landaiqing.subject.application.dto.SubjectLikedDTO; import com.landaiqing.subject.domain.entity.SubjectLikedBO; +import com.landaiqing.subject.infra.basic.entity.SubjectLiked; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; +import java.util.List; + /** * 题目点赞表 dto转换器 * @@ -17,5 +20,6 @@ public interface SubjectLikedDTOConverter { SubjectLikedDTOConverter INSTANCE = Mappers.getMapper(SubjectLikedDTOConverter.class); SubjectLikedBO convertDTOToBO(SubjectLikedDTO subjectLikedDTO); + List convertListInfoToBO(List subjectLikedList); } diff --git a/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/dto/SubjectInfoDTO.java b/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/dto/SubjectInfoDTO.java index 9e27797..3b83734 100644 --- a/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/dto/SubjectInfoDTO.java +++ b/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/dto/SubjectInfoDTO.java @@ -85,6 +85,23 @@ public class SubjectInfoDTO extends PageInfo implements Serializable { * 题目数量 */ private Integer subjectCount; + /** + * 是否被当前用户点赞 + */ + private Boolean liked; + + /** + * 当前题目点赞的数量 + */ + private Integer likedCount; + /** + * 下一题 + */ + private Long nextSubjectId; + /** + * 上一题 + */ + private Long lastSubjectId; } diff --git a/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/dto/SubjectLikedDTO.java b/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/dto/SubjectLikedDTO.java index c09b85c..536ada3 100644 --- a/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/dto/SubjectLikedDTO.java +++ b/qing-yu-club-subject/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/subject/application/dto/SubjectLikedDTO.java @@ -1,5 +1,6 @@ package com.landaiqing.subject.application.dto; +import com.landaiqing.subject.common.entity.PageInfo; import lombok.Data; import java.io.Serializable; @@ -12,7 +13,7 @@ import java.util.Date; * @since 2024-03-08 13:44:59 */ @Data -public class SubjectLikedDTO implements Serializable { +public class SubjectLikedDTO extends PageInfo implements Serializable { /** * diff --git a/qing-yu-club-subject/qing-yu-club-domain/pom.xml b/qing-yu-club-subject/qing-yu-club-domain/pom.xml index 352c083..e556661 100644 --- a/qing-yu-club-subject/qing-yu-club-domain/pom.xml +++ b/qing-yu-club-subject/qing-yu-club-domain/pom.xml @@ -62,5 +62,15 @@ commons-pool2 2.9.0 + + com.xuxueli + xxl-job-core + 2.3.1 + + + org.springframework + spring-context + 5.3.27 + diff --git a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/config/XxlJobConfig.java b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/config/XxlJobConfig.java new file mode 100644 index 0000000..1de0483 --- /dev/null +++ b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/config/XxlJobConfig.java @@ -0,0 +1,78 @@ +package com.landaiqing.subject.domain.config; + +import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * xxl-job config + * + * @author landaiqing + */ +@Configuration +public class XxlJobConfig { + private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class); + + @Value("${xxl.job.admin.addresses}") + private String adminAddresses; + + @Value("${xxl.job.accessToken}") + private String accessToken; + + @Value("${xxl.job.executor.appname}") + private String appname; + + @Value("${xxl.job.executor.address}") + private String address; + + @Value("${xxl.job.executor.ip}") + private String ip; + + @Value("${xxl.job.executor.port}") + private int port; + + @Value("${xxl.job.executor.logpath}") + private String logPath; + + @Value("${xxl.job.executor.logretentiondays}") + private int logRetentionDays; + + + @Bean + public XxlJobSpringExecutor xxlJobExecutor() { + logger.info(">>>>>>>>>>> xxl-job config init."); + XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); + xxlJobSpringExecutor.setAdminAddresses(adminAddresses); + xxlJobSpringExecutor.setAppname(appname); + xxlJobSpringExecutor.setAddress(address); + xxlJobSpringExecutor.setIp(ip); + xxlJobSpringExecutor.setPort(port); + xxlJobSpringExecutor.setAccessToken(accessToken); + xxlJobSpringExecutor.setLogPath(logPath); + xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); + + return xxlJobSpringExecutor; + } + + /** + * 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP; + * + * 1、引入依赖: + * + * org.springframework.cloud + * spring-cloud-commons + * ${version} + * + * + * 2、配置文件,或者容器启动变量 + * spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.' + * + * 3、获取IP + * String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress(); + */ + + +} \ No newline at end of file diff --git a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/convert/SubjectLikedBOConverter.java b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/convert/SubjectLikedBOConverter.java index 591cdef..f25601a 100644 --- a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/convert/SubjectLikedBOConverter.java +++ b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/convert/SubjectLikedBOConverter.java @@ -5,6 +5,8 @@ import com.landaiqing.subject.infra.basic.entity.SubjectLiked; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; +import java.util.List; + /** * 题目点赞表 bo转换器 * @@ -18,4 +20,7 @@ public interface SubjectLikedBOConverter { SubjectLiked convertBOToEntity(SubjectLikedBO subjectLikedBO); + List convertListInfoToBO(List subjectLikedList); + + } diff --git a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/entity/SubjectInfoBO.java b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/entity/SubjectInfoBO.java index 87f9a07..26ae357 100644 --- a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/entity/SubjectInfoBO.java +++ b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/entity/SubjectInfoBO.java @@ -88,6 +88,24 @@ public class SubjectInfoBO extends PageInfo implements Serializable { */ private Integer subjectCount; + /** + * 是否被当前用户点赞 + */ + private Boolean liked; + + /** + * 当前题目点赞的数量 + */ + private Integer likedCount; + + /** + * 下一题 + */ + private Long nextSubjectId; + /** + * 上一题 + */ + private Long lastSubjectId; } diff --git a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/entity/SubjectLikedBO.java b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/entity/SubjectLikedBO.java index a201b0a..317bd1b 100644 --- a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/entity/SubjectLikedBO.java +++ b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/entity/SubjectLikedBO.java @@ -1,5 +1,6 @@ package com.landaiqing.subject.domain.entity; +import com.landaiqing.subject.common.entity.PageInfo; import lombok.Data; import java.io.Serializable; @@ -12,7 +13,7 @@ import java.util.Date; * @since 2024-03-08 13:44:59 */ @Data -public class SubjectLikedBO implements Serializable { +public class SubjectLikedBO extends PageInfo implements Serializable { /** * diff --git a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/job/SyncLikedJob.java b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/job/SyncLikedJob.java new file mode 100644 index 0000000..0557baf --- /dev/null +++ b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/job/SyncLikedJob.java @@ -0,0 +1,38 @@ +package com.landaiqing.subject.domain.job; + +import com.landaiqing.subject.domain.service.SubjectLikedDomainService; +import com.xxl.job.core.context.XxlJobHelper; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 同步点赞数据 + * + * @author landaiqing + */ +@Component +@Slf4j +public class SyncLikedJob { + @Resource + private SubjectLikedDomainService subjectLikedDomainService; + + + /** + * 同步点赞任务 + */ + @XxlJob("syncLikedJobHandler") + public void syncLikedJobHandler() throws Exception { + XxlJobHelper.log("syncLikedJobHandler.starter"); + try { + subjectLikedDomainService.syncLiked(); + } catch (Exception e) { + XxlJobHelper.log("syncLikedJobHandler.error", e.getMessage()); + } + + } + + +} diff --git a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/redis/RedisUtil.java b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/redis/RedisUtil.java index 0c179c5..500921e 100644 --- a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/redis/RedisUtil.java +++ b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/redis/RedisUtil.java @@ -1,11 +1,15 @@ package com.landaiqing.subject.domain.redis; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -105,10 +109,33 @@ public class RedisUtil { } - public Set rankWithScore(String key,long start,long end){ + public Set rankWithScore(String key, long start, long end) { Set> set = redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end); return set; } - + public void putHash(String key, String hashKey, Object hashVal) { + redisTemplate.opsForHash().put(key, hashKey, hashVal); + } + + public Integer getInt(String key) { + return (Integer) redisTemplate.opsForValue().get(key); + } + + public void increment(String key, Integer count) { + redisTemplate.opsForValue().increment(key,count); + } + public Map getHashAndDelete(String key) { + Map map = new HashMap<>(); + Cursor> cursor = redisTemplate.opsForHash().scan(key, ScanOptions.NONE); + while (cursor.hasNext()) { + Map.Entry entry = cursor.next(); + Object hashKey = entry.getKey(); + Object value = entry.getValue(); + map.put(hashKey, value); + redisTemplate.opsForHash().delete(key, hashKey); + } + return map; + } + } diff --git a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/SubjectLikedDomainService.java b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/SubjectLikedDomainService.java index 7ec3d9a..07cc8f2 100644 --- a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/SubjectLikedDomainService.java +++ b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/SubjectLikedDomainService.java @@ -1,5 +1,6 @@ package com.landaiqing.subject.domain.service; +import com.landaiqing.subject.common.entity.PageResult; import com.landaiqing.subject.domain.entity.SubjectLikedBO; @@ -14,7 +15,17 @@ public interface SubjectLikedDomainService { /** * 添加 题目点赞表 信息 */ - Boolean add(SubjectLikedBO subjectLikedBO); + void add(SubjectLikedBO subjectLikedBO); + + /** + * 获取当前是否被点赞过 + */ + Boolean isLiked(String subjectId, String userId); + + /** + * 获取点赞数量 + */ + Integer getLikedCount(String subjectId); /** * 更新 题目点赞表 信息 @@ -25,5 +36,10 @@ public interface SubjectLikedDomainService { * 删除 题目点赞表 信息 */ Boolean delete(SubjectLikedBO subjectLikedBO); + /** + * 同步点赞数据 + */ + void syncLiked(); + PageResult getSubjectLikedPage(SubjectLikedBO subjectLikedBO); } diff --git a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/impl/SubjectInfoDomainServiceImpl.java b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/impl/SubjectInfoDomainServiceImpl.java index b0c2923..54ef506 100644 --- a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/impl/SubjectInfoDomainServiceImpl.java +++ b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/impl/SubjectInfoDomainServiceImpl.java @@ -12,6 +12,7 @@ import com.landaiqing.subject.domain.handler.subject.SubjectTypeHandler; import com.landaiqing.subject.domain.handler.subject.SubjectTypeHandlerFactory; import com.landaiqing.subject.domain.redis.RedisUtil; import com.landaiqing.subject.domain.service.SubjectInfoDomainService; +import com.landaiqing.subject.domain.service.SubjectLikedDomainService; import com.landaiqing.subject.infra.basic.entity.SubjectInfo; import com.landaiqing.subject.infra.basic.entity.SubjectInfoEs; import com.landaiqing.subject.infra.basic.entity.SubjectLabel; @@ -54,6 +55,9 @@ public class SubjectInfoDomainServiceImpl implements SubjectInfoDomainService { @Resource private RedisUtil redisUtil; + @Resource + private SubjectLikedDomainService subjectLikedDomainService; + private static final String RANK_KEY = "subject_rank"; @@ -148,6 +152,8 @@ public class SubjectInfoDomainServiceImpl implements SubjectInfoDomainService { List labelList = subjectLabelService.batchQueryById(labelIdList); List labelNameList = labelList.stream().map(SubjectLabel::getLabelName).collect(Collectors.toList()); bo.setLabelName(labelNameList); + bo.setLiked(subjectLikedDomainService.isLiked(subjectInfoBO.getId().toString(), LoginUtil.getLoginId())); + bo.setLikedCount(subjectLikedDomainService.getLikedCount(subjectInfoBO.getId().toString())); return bo; } diff --git a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/impl/SubjectLikedDomainServiceImpl.java b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/impl/SubjectLikedDomainServiceImpl.java index 574d2cf..1dbdd67 100644 --- a/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/impl/SubjectLikedDomainServiceImpl.java +++ b/qing-yu-club-subject/qing-yu-club-domain/src/main/java/com/landaiqing/subject/domain/service/impl/SubjectLikedDomainServiceImpl.java @@ -1,15 +1,25 @@ package com.landaiqing.subject.domain.service.impl; +import com.alibaba.fastjson.JSON; +import com.landaiqing.subject.common.entity.PageResult; import com.landaiqing.subject.common.enums.IsDeletedFlagEnum; +import com.landaiqing.subject.common.enums.SubjectLikedStatusEnum; +import com.landaiqing.subject.common.util.LoginUtil; import com.landaiqing.subject.domain.convert.SubjectLikedBOConverter; import com.landaiqing.subject.domain.entity.SubjectLikedBO; +import com.landaiqing.subject.domain.redis.RedisUtil; import com.landaiqing.subject.domain.service.SubjectLikedDomainService; import com.landaiqing.subject.infra.basic.entity.SubjectLiked; import com.landaiqing.subject.infra.basic.service.SubjectLikedService; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.MapUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; /** * 题目点赞表 领域service实现了 @@ -23,12 +33,53 @@ public class SubjectLikedDomainServiceImpl implements SubjectLikedDomainService @Resource private SubjectLikedService subjectLikedService; + @Resource + private RedisUtil redisUtil; + + private static final String SUBJECT_LIKED_KEY = "subject.liked"; + private static final String SUBJECT_LIKED_COUNT_KEY = "subject.liked.count"; + private static final String SUBJECT_LIKED_DETAIL_KEY = "subject.liked.detail"; @Override - public Boolean add(SubjectLikedBO subjectLikedBO) { - SubjectLiked subjectLiked = SubjectLikedBOConverter.INSTANCE.convertBOToEntity(subjectLikedBO); - subjectLiked.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode()); - return subjectLikedService.insert(subjectLiked) > 0; + public void add(SubjectLikedBO subjectLikedBO) { + Long subjectId = subjectLikedBO.getSubjectId(); + String likeUserId = subjectLikedBO.getLikeUserId(); + Integer status = subjectLikedBO.getStatus(); + String hashKey = buildSubjectLikedKey(subjectId.toString(), likeUserId); + redisUtil.putHash(SUBJECT_LIKED_KEY, hashKey, status); + String countKey = SUBJECT_LIKED_COUNT_KEY + "." + subjectId; + String detailKey = SUBJECT_LIKED_DETAIL_KEY + "." + subjectId + "." + likeUserId; + if (SubjectLikedStatusEnum.LIKED.getCode() == status) { + redisUtil.increment(countKey, 1); + redisUtil.set(detailKey, "1"); + } else { + Integer count = redisUtil.getInt(countKey); + if (Objects.isNull(count) || count <= 0) { + return; + } + redisUtil.increment(countKey, -1); + redisUtil.del(detailKey); + } + } + + @Override + public Boolean isLiked(String subjectId, String userId) { + String detailKey = SUBJECT_LIKED_DETAIL_KEY + "." + subjectId + "." + userId; + return redisUtil.exist(detailKey); + } + + @Override + public Integer getLikedCount(String subjectId) { + String countKey = SUBJECT_LIKED_COUNT_KEY + "." + subjectId; + Integer count = redisUtil.getInt(countKey); + if (Objects.isNull(count) || count <= 0) { + return 0; + } + return redisUtil.getInt(countKey); + } + + private String buildSubjectLikedKey(String subjectId, String userId) { + return subjectId + ":" + userId; } @Override @@ -45,4 +96,52 @@ public class SubjectLikedDomainServiceImpl implements SubjectLikedDomainService return subjectLikedService.update(subjectLiked) > 0; } + @Override + public void syncLiked() { + Map subjectLikedMap = redisUtil.getHashAndDelete(SUBJECT_LIKED_KEY); + if (log.isInfoEnabled()) { + log.info("syncLiked.subjectLikedMap:{}", JSON.toJSONString(subjectLikedMap)); + } + if (MapUtils.isEmpty(subjectLikedMap)) { + return; + } + //批量同步到数据库 + List subjectLikedList = new LinkedList<>(); + subjectLikedMap.forEach((key, val) -> { + SubjectLiked subjectLiked = new SubjectLiked(); + String[] keyArr = key.toString().split(":"); + String subjectId = keyArr[0]; + String likedUser = keyArr[1]; + subjectLiked.setSubjectId(Long.valueOf(subjectId)); + subjectLiked.setLikeUserId(likedUser); + subjectLiked.setStatus(Integer.valueOf(val.toString())); + subjectLiked.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode()); + subjectLikedList.add(subjectLiked); + }); + subjectLikedService.batchInsert(subjectLikedList); + } + + @Override + public PageResult getSubjectLikedPage(SubjectLikedBO subjectLikedBO) { + PageResult pageResult = new PageResult<>(); + pageResult.setPageNo(subjectLikedBO.getPageNo()); + pageResult.setPageSize(subjectLikedBO.getPageSize()); + int start = (subjectLikedBO.getPageNo() - 1) * subjectLikedBO.getPageSize(); + SubjectLiked subjectLiked = SubjectLikedBOConverter.INSTANCE.convertBOToEntity(subjectLikedBO); + subjectLiked.setLikeUserId(LoginUtil.getLoginId()); + int count = subjectLikedService.countByCondition(subjectLiked); + if (count == 0) { + return pageResult; + } + List subjectLikedList = subjectLikedService.queryPage(subjectLiked, start, + subjectLikedBO.getPageSize()); + List subjectInfoBOS = SubjectLikedBOConverter.INSTANCE.convertListInfoToBO(subjectLikedList); + + + + pageResult.setRecords(subjectInfoBOS); + pageResult.setTotal(count); + return pageResult; + } + } diff --git a/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/mapper/SubjectLikedDao.java b/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/mapper/SubjectLikedDao.java index b4285a0..3ba88a9 100644 --- a/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/mapper/SubjectLikedDao.java +++ b/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/mapper/SubjectLikedDao.java @@ -2,8 +2,11 @@ package com.landaiqing.subject.infra.basic.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.landaiqing.subject.infra.basic.entity.SubjectLiked; +import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; +import java.util.List; + /** * 题目点赞表 表数据库访问层 * @@ -13,5 +16,12 @@ import org.springframework.stereotype.Repository; @Repository public interface SubjectLikedDao extends BaseMapper { + void insertBatch(@Param("entities") List subjectLikedList); + + int countByCondition(SubjectLiked subjectLiked); + + List queryPage(@Param("entity") SubjectLiked subjectLiked, + @Param("start") int start, + @Param("pageSize") Integer pageSize); } diff --git a/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/service/SubjectLikedService.java b/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/service/SubjectLikedService.java index a73fd23..848492a 100644 --- a/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/service/SubjectLikedService.java +++ b/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/service/SubjectLikedService.java @@ -2,6 +2,8 @@ package com.landaiqing.subject.infra.basic.service; import com.landaiqing.subject.infra.basic.entity.SubjectLiked; +import java.util.List; + /** * 题目点赞表 表服务接口 @@ -48,4 +50,10 @@ public interface SubjectLikedService { */ SubjectLiked queryByCondition(SubjectLiked subjectLiked); + void batchInsert(List subjectLikedList); + + + int countByCondition(SubjectLiked subjectLiked); + + List queryPage(SubjectLiked subjectLiked, int start, Integer pageSize); } diff --git a/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/service/impl/SubjectLikedServiceImpl.java b/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/service/impl/SubjectLikedServiceImpl.java index 113a317..82f0d47 100644 --- a/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/service/impl/SubjectLikedServiceImpl.java +++ b/qing-yu-club-subject/qing-yu-club-infra/src/main/java/com/landaiqing/subject/infra/basic/service/impl/SubjectLikedServiceImpl.java @@ -8,6 +8,7 @@ import com.landaiqing.subject.infra.basic.service.SubjectLikedService; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.util.List; import java.util.Objects; /** @@ -90,4 +91,19 @@ public class SubjectLikedServiceImpl implements SubjectLikedService { } + @Override + public void batchInsert(List subjectLikedList) { + this.subjectLikedDao.insertBatch(subjectLikedList); + } + + @Override + public int countByCondition(SubjectLiked subjectLiked) { + return this.subjectLikedDao.countByCondition(subjectLiked); + } + + @Override + public List queryPage(SubjectLiked subjectLiked, int start, Integer pageSize) { + return this.subjectLikedDao.queryPage(subjectLiked, start, pageSize); + } + } diff --git a/qing-yu-club-subject/qing-yu-club-infra/src/main/resources/mapper/SubjectLikedDao.xml b/qing-yu-club-subject/qing-yu-club-infra/src/main/resources/mapper/SubjectLikedDao.xml index fca2511..2b2c403 100644 --- a/qing-yu-club-subject/qing-yu-club-infra/src/main/resources/mapper/SubjectLikedDao.xml +++ b/qing-yu-club-subject/qing-yu-club-infra/src/main/resources/mapper/SubjectLikedDao.xml @@ -13,5 +13,35 @@ + + insert into subject_liked(id, subject_id, like_user_id, status, created_by, created_time, update_by, + update_time, is_deleted) + values + + (#{entity.id}, + #{entity.subjectId}, + #{entity.likeUserId}, + #{entity.status}, + #{entity.createdBy}, + #{entity.createdTime}, + #{entity.updateBy}, #{entity.updateTime}, #{entity.isDeleted}) + + + + + + diff --git a/qing-yu-club-subject/qing-yu-club-starter/src/main/resources/application.yml b/qing-yu-club-subject/qing-yu-club-starter/src/main/resources/application.yml index 9a02136..984eb53 100644 --- a/qing-yu-club-subject/qing-yu-club-starter/src/main/resources/application.yml +++ b/qing-yu-club-subject/qing-yu-club-starter/src/main/resources/application.yml @@ -57,5 +57,17 @@ es: es-cluster-configs[0]: name: 5fdd534ef33c nodes: 116.196.80.239:9200 +xxl: + job: + admin: + addresses: http://127.0.0.1:8080/xxl-job-admin + accessToken: default_token + executor: + appname: qing-yu-club-subject + address: + ip: 127.0.0.1 + port: 9999 + logpath: /data/applogs/xxl-job/jobhandler + logretentiondays: 30