diff --git a/src/main/java/com/lh/controller/VoteController.java b/src/main/java/com/lh/controller/VoteController.java index 6bac3e4..7f7c8da 100644 --- a/src/main/java/com/lh/controller/VoteController.java +++ b/src/main/java/com/lh/controller/VoteController.java @@ -2,7 +2,6 @@ package com.lh.controller; import com.lh.bean.RespBean; import com.lh.bean.Voter; -import com.lh.service.VoteConsumer; import com.lh.service.VoteService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -13,8 +12,6 @@ import org.springframework.web.bind.annotation.*; public class VoteController { @Autowired private VoteService voteService; - @Autowired - private VoteConsumer voteConsumer; //投票 @PostMapping("/vote") public RespBean vote(@RequestBody Voter voter) throws Exception { diff --git a/src/main/java/com/lh/service/VoteConsumer.java b/src/main/java/com/lh/service/VoteConsumer.java index ce93e6e..1252fd1 100644 --- a/src/main/java/com/lh/service/VoteConsumer.java +++ b/src/main/java/com/lh/service/VoteConsumer.java @@ -1,7 +1,6 @@ package com.lh.service; import com.lh.bean.Candidate; -import com.lh.bean.Voter; import com.lh.exception.MyException; import com.lh.mapper.CandidatesMapper; import com.lh.mapper.VoterMapper; @@ -12,11 +11,6 @@ import org.springframework.kafka.annotation.EnableKafka; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Service; -import java.time.Duration; -import java.time.LocalDateTime; -import java.util.List; -import java.util.concurrent.TimeUnit; - @Service @EnableKafka public class VoteConsumer { @@ -52,13 +46,17 @@ public class VoteConsumer { } // 3. 检查用户是否已经为该候选人投过票 - List hasVotes = voterMapper.countVotesToday(voterJwcode); - //遍历列表,判断是否有记录 - for (Voter vote : hasVotes) { - if (vote.getCandidateJwCode().equals(candidateJwcode)) { - throw new MyException("已投票,可以选择其他人试试哦~"); - } - } + //List hasVotes = voterMapper.countVotesToday(voterJwcode); + ////遍历列表,判断是否有记录 + //boolean flag = true; + //for (Voter vote : hasVotes) { + // if (vote.getCandidateJwCode().equals(candidateJwcode)) { + // flag = false; + // } + //} + //if (!flag){ + // throw new MyException("已投票,可以选择其他人试试哦~"); + //} // 4. 增加候选人票数 if (!candidatesMapper.addVotes(candidateJwcode)) { @@ -68,16 +66,7 @@ public class VoteConsumer { // 5. 插入投票记录 voterMapper.insertVote(voterJwcode, candidateJwcode, voterName); - // 6. 更新 Redis 中的投票次数 - String redisKey = "vote_count:" + voterJwcode + ":" + LocalDateTime.now().toLocalDate(); - redisTemplate.opsForValue().increment(redisKey, 1); - // 设置 Redis 键的过期时间为当天的23:59:59 - LocalDateTime now = LocalDateTime.now(); - LocalDateTime endOfDay = now.toLocalDate().atTime(23, 59, 59); - long secondsUntilEndOfDay = Duration.between(now, endOfDay).getSeconds(); - redisTemplate.expire(redisKey, secondsUntilEndOfDay, TimeUnit.SECONDS); - //打印剩余长时间过期 - System.out.println("Redis键" + redisKey + "将在" + secondsUntilEndOfDay + "秒后过期。"); + System.out.println("投票成功!用户:" + voterJwcode + " 投给了 " + candidateJwcode); return true; } diff --git a/src/main/java/com/lh/service/VoteServiceImpl.java b/src/main/java/com/lh/service/VoteServiceImpl.java index 4e8d5ac..1acea68 100644 --- a/src/main/java/com/lh/service/VoteServiceImpl.java +++ b/src/main/java/com/lh/service/VoteServiceImpl.java @@ -16,10 +16,12 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.PostConstruct; import java.sql.Timestamp; +import java.time.Duration; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; @Service public class VoteServiceImpl implements VoteService { @@ -60,8 +62,35 @@ public class VoteServiceImpl implements VoteService { throw new MyException("今日投票次数已达上限"); } - //将redis中的candidates中的投票次数+1 + // 2. 检查该用户是否已经为该候选人投票 + String voteStatusKey = "vote_status:" + voterJwcode + ":" + candidateJwcode; + Boolean hasVoted = stringRedisTemplate.hasKey(voteStatusKey); + if (hasVoted != null && hasVoted) { + throw new MyException("您已经为该候选人投票,不能重复投票"); + } + + + // 2. 增加候选人的投票数(Hash 表和 ZSet 同步更新) + String candidateKey = "candidate:" + candidateJwcode; + + // 使用 Redis 的 Hash 增加候选人投票数 + redisTemplate.opsForHash().increment(candidateKey, "votes", 1); + + // 使用 Redis 的 ZSet 增加候选人投票数 + redisTemplate.opsForZSet().incrementScore("candidate:votes", candidateJwcode, 1); + // 6. 更新 Redis 中的投票次数 + redisTemplate.opsForValue().increment(redisKey, 1); + // 设置 Redis 键的过期时间为当天的23:59:59 + LocalDateTime now = LocalDateTime.now(); + LocalDateTime endOfDay = now.toLocalDate().atTime(23, 59, 59); + long secondsUntilEndOfDay = Duration.between(now, endOfDay).getSeconds(); + redisTemplate.expire(redisKey, secondsUntilEndOfDay, TimeUnit.SECONDS); + //更新投票重复键 + stringRedisTemplate.opsForValue().set(voteStatusKey, "true", secondsUntilEndOfDay, TimeUnit.SECONDS); + //打印剩余长时间过期 + System.out.println("Redis键" + redisKey + "将在" + secondsUntilEndOfDay + "秒后过期。"); + System.out.println("Redis键" + voteStatusKey + "将在" + secondsUntilEndOfDay + "秒后过期。"); //将投票请求发送到 Kafka 消息队列 voteProducer.sendVoteMessage(new VoteMessage(voterJwcode,