From da9fadef675cd239c461e56699a7c69a5ec5ff26 Mon Sep 17 00:00:00 2001 From: Wonder Date: Tue, 21 Oct 2025 23:28:04 +0800 Subject: [PATCH] =?UTF-8?q?=20=E2=9C=A8Feat:=20=E6=8E=A5=E5=85=A5=20Lua=20?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E5=AE=9E=E7=8E=B0=E7=82=B9=E8=B5=9E=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/ThumbServiceRedisImpl.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/main/java/cn/hezhaohui/thumb/service/impl/ThumbServiceRedisImpl.java diff --git a/src/main/java/cn/hezhaohui/thumb/service/impl/ThumbServiceRedisImpl.java b/src/main/java/cn/hezhaohui/thumb/service/impl/ThumbServiceRedisImpl.java new file mode 100644 index 0000000..418c2e0 --- /dev/null +++ b/src/main/java/cn/hezhaohui/thumb/service/impl/ThumbServiceRedisImpl.java @@ -0,0 +1,116 @@ +package cn.hezhaohui.thumb.service.impl; + +import cn.hezhaohui.thumb.constant.RedisLuaScriptConstant; +import cn.hezhaohui.thumb.exception.BusinessException; +import cn.hezhaohui.thumb.exception.ErrorCode; +import cn.hezhaohui.thumb.mapper.ThumbMapper; +import cn.hezhaohui.thumb.model.dto.DoThumbRequest; +import cn.hezhaohui.thumb.model.entity.Blog; +import cn.hezhaohui.thumb.model.entity.Thumb; +import cn.hezhaohui.thumb.model.entity.User; +import cn.hezhaohui.thumb.model.enums.LuaStatusEnum; +import cn.hezhaohui.thumb.service.BlogService; +import cn.hezhaohui.thumb.service.ThumbService; +import cn.hezhaohui.thumb.service.UserService; +import cn.hezhaohui.thumb.util.RedisKeyUtil; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; + +import java.util.Arrays; + +/** +* @author 23117 +* @description 针对表【thumb】的数据库操作Service实现 +* @createDate 2025-10-18 14:51:00 +*/ +@Service +public class ThumbServiceRedisImpl extends ServiceImpl + implements ThumbService{ + + @Resource + private UserService userService; + + @Resource + private RedisTemplate redisTemplate; + + @Override + public Boolean doThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) { + if (doThumbRequest == null || doThumbRequest.getBlogId() == null) { + throw new RuntimeException("参数异常"); + } + User loginUser = userService.getLoginUser(request); + Long blogId = doThumbRequest.getBlogId(); + String timeSlice = this.getTimeSlice(); + // Redis Key + String tempThumbKey = RedisKeyUtil.getTempThumbKey(timeSlice); + String userThumbKey = RedisKeyUtil.getUserThumbKey(loginUser.getId()); + // 执行 Lua 脚本 + long result = redisTemplate.execute( + RedisLuaScriptConstant.THUMB_SCRIPT, + // local tempThumbKey = KEYS[1] -- 临时计数键(如 thumb:temp:{timeSlice}) + // local userThumbKey = KEYS[2] -- 用户点赞状态键(如 thumb:{userId}) + Arrays.asList(tempThumbKey, userThumbKey), + // local userId = ARGV[1] -- 用户 ID + loginUser.getId(), + // local blogId = ARGV[2] -- 博客 ID + blogId + ); + // 成功 SUCCESS(1L), + // 失败 FAIL(0L); + if (LuaStatusEnum.FAIL.getValue() == result) { + throw new BusinessException(ErrorCode.OPERATION_ERROR, "用户已点赞"); + } + + return LuaStatusEnum.SUCCESS.getValue() == result; + } + + @Override + public Boolean undoThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) { + if (doThumbRequest == null || doThumbRequest.getBlogId() == null) { + throw new RuntimeException("参数异常"); + } + User loginUser = userService.getLoginUser(request); + Long blogId = doThumbRequest.getBlogId(); + String timeSlice = this.getTimeSlice(); + // Redis Key + String tempThumbKey = RedisKeyUtil.getTempThumbKey(timeSlice); + String userThumbKey = RedisKeyUtil.getUserThumbKey(loginUser.getId()); + // 执行 Lua 脚本 + long result = redisTemplate.execute( + RedisLuaScriptConstant.UNTHUMB_SCRIPT, + // local tempThumbKey = KEYS[1] -- 临时计数键(如 thumb:temp:{timeSlice}) + // local userThumbKey = KEYS[2] -- 用户点赞状态键(如 thumb:{userId}) + Arrays.asList(tempThumbKey, userThumbKey), + // local userId = ARGV[1] -- 用户 ID + loginUser.getId(), + // local blogId = ARGV[2] -- 博客 ID + blogId + ); + // 成功 SUCCESS(1L), + // 失败 FAIL(0L); + if (LuaStatusEnum.FAIL.getValue() == result) { + throw new BusinessException(ErrorCode.OPERATION_ERROR, "用户未点赞"); + } + return LuaStatusEnum.SUCCESS.getValue() == result; + } + + @Override + public Boolean hasThumb(Long blogId, Long userId) { + return redisTemplate.opsForHash().hasKey(RedisKeyUtil.getUserThumbKey(userId), blogId.toString()); + } + + private String getTimeSlice() { + DateTime nowDate = DateUtil.date(); + return DateUtil.format(nowDate, "HH:mm:" + (DateUtil.second(nowDate) / 10) * 10); + } +} + + + +