8 changed files with 229 additions and 62 deletions
-
2pom.xml
-
3src/main/java/com/lh/controller/VoteController.java
-
2src/main/java/com/lh/mapper/VoterMapper.java
-
2src/main/java/com/lh/service/VoteService.java
-
123src/main/java/com/lh/service/VoteServiceImpl.java
-
151src/main/java/com/lh/service/VoteServiceImpl_copy.java
-
6src/main/resources/com/lh/mapper/VoterMapper.xml
-
2src/test/java/com/lh/VoteSystemApplicationTests.java
@ -0,0 +1,151 @@ |
|||
//package com.lh.service; |
|||
// |
|||
//import com.lh.bean.Candidate; |
|||
//import com.lh.bean.VoteMessage; |
|||
//import com.lh.bean.Voter; |
|||
//import com.lh.config.CandidateCacheRepository; |
|||
//import com.lh.exception.MyException; |
|||
//import com.lh.mapper.CandidatesMapper; |
|||
//import com.lh.mapper.VoterMapper; |
|||
//import org.springframework.beans.factory.annotation.Autowired; |
|||
//import org.springframework.beans.factory.annotation.Value; |
|||
//import org.springframework.data.redis.core.RedisTemplate; |
|||
//import org.springframework.data.redis.core.StringRedisTemplate; |
|||
//import org.springframework.stereotype.Service; |
|||
//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_copy implements VoteService { |
|||
// @Autowired |
|||
// private VoterMapper voterMapper; |
|||
// @Autowired |
|||
// private CandidatesMapper candidatesMapper; |
|||
// @Value("${vote.limit.daily}") |
|||
// private int dailyVoteLimit; // 每日投票次数限制 |
|||
// @Autowired |
|||
// private StringRedisTemplate stringRedisTemplate; |
|||
// @Autowired |
|||
// private VoteProducer voteProducer; |
|||
// @Autowired |
|||
// private RedisTemplate<String, Object> redisTemplate; |
|||
// @Autowired |
|||
// private CandidateCacheRepository candidateCacheRepository; |
|||
// |
|||
// |
|||
// |
|||
// // 初始化时加载所有候选人数据并缓存到 Redis |
|||
// @PostConstruct |
|||
// public void initCandidatesCache() { |
|||
// try { |
|||
// List<Candidate> candidates = candidatesMapper.getCandidates(); |
|||
// for (Candidate candidate : candidates) { |
|||
// candidateCacheRepository.saveCandidate(candidate); |
|||
// } |
|||
// System.out.println("Candidate cache initialized successfully."); |
|||
// } catch (Exception e) { |
|||
// System.out.println("Failed to initialize candidate cache."); |
|||
// } |
|||
// } |
|||
// |
|||
// //投票 |
|||
// @Override |
|||
// @Transactional(rollbackFor = Exception.class) |
|||
// public Integer insertVote(String voterJwcode, String candidateJwcode, String voterName) throws MyException { |
|||
// // 1. 检查 Redis 中用户今天的投票次数 |
|||
// String redisKey = "vote_count:" + voterJwcode + ":" + LocalDateTime.now().toLocalDate(); |
|||
// String currentVoteCount = stringRedisTemplate.opsForValue().get(redisKey); |
|||
// |
|||
// int voteCountToday = currentVoteCount == null ? 0 : Integer.parseInt(currentVoteCount); |
|||
// if (voteCountToday >= dailyVoteLimit) { |
|||
// throw new MyException("今日投票次数已达上限"); |
|||
// } |
|||
// |
|||
// // 2. 检查该用户是否已经为该候选人投票 |
|||
// String voteStatusKey = "vote_status:" + voterJwcode + ":" + candidateJwcode; |
|||
// Boolean hasVoted = stringRedisTemplate.hasKey(voteStatusKey); |
|||
// if (hasVoted != null && hasVoted) { |
|||
// throw new MyException("您已经为该候选人投票,不能重复投票"); |
|||
// } |
|||
// |
|||
// |
|||
// // 3. 增加候选人的投票数(Hash 表和 ZSet 同步更新) |
|||
// String candidateKey = "candidate:" + candidateJwcode; |
|||
// |
|||
// // 4.使用 Redis 的 Hash 增加候选人投票数 |
|||
// redisTemplate.opsForHash().increment(candidateKey, "votes", 1); |
|||
// |
|||
// // 5.使用 Redis 的 ZSet 增加候选人投票数 |
|||
// redisTemplate.opsForZSet().incrementScore("candidate:votes", candidateJwcode, 1); |
|||
// |
|||
// // 6. 更新 Redis 中的投票次数 |
|||
// redisTemplate.opsForValue().increment(redisKey, 1); |
|||
// // 7.设置 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); |
|||
// //8.更新投票重复键 |
|||
// stringRedisTemplate.opsForValue().set(voteStatusKey, "true", secondsUntilEndOfDay, TimeUnit.SECONDS); |
|||
// //9.控制台打印剩余长时间过期 |
|||
// System.out.println("Redis键" + redisKey + "将在" + secondsUntilEndOfDay + "秒后过期。"); |
|||
// System.out.println("Redis键" + voteStatusKey + "将在" + secondsUntilEndOfDay + "秒后过期。"); |
|||
// |
|||
// //10.将投票请求发送到 Kafka 消息队列 |
|||
// voteProducer.sendVoteMessage(new VoteMessage(voterJwcode, |
|||
// candidateJwcode, voterName, |
|||
// Timestamp.valueOf(LocalDateTime.now()).toString())); |
|||
// return dailyVoteLimit - voteCountToday - 1; |
|||
// } |
|||
// |
|||
// //获取所有候选人 |
|||
// //先查redis中有没有数据,没有就从数据库中查 |
|||
// @Override |
|||
// public List<Candidate> getCandidates(String voterJwcode) { |
|||
// // 从 Redis 中获取按投票数排序的候选人 jwCode 列表 |
|||
// Set<Object> jwCodes = candidateCacheRepository.getCandidateJwCodesByVotes(); |
|||
// //将jwCodes转为字符串类型 |
|||
// List<String> jwCodeList = new ArrayList<>(); |
|||
// for (Object jwCode : jwCodes) { |
|||
// jwCodeList.add(jwCode.toString()); |
|||
// } |
|||
// |
|||
// List<Candidate> candidateList = new ArrayList<>(); |
|||
// for (String jwCode : jwCodeList) { |
|||
// Candidate candidate = candidateCacheRepository.getCandidate(jwCode); |
|||
// candidateList.add(candidate); |
|||
// } |
|||
// |
|||
// // 插入投票记录,为 List 插入是否投过票的状态 |
|||
// for (Candidate candidate : candidateList) { |
|||
// //从redis查询该用户投票状态 |
|||
// String voteStatusKey = "vote_status:" + voterJwcode + ":"; |
|||
// //获取stringRedisTemplate的所有键值 |
|||
// Set<String> redisCandidateJwCode = stringRedisTemplate.keys(voteStatusKey + "*"); |
|||
// //提取最后5位 |
|||
// if (redisCandidateJwCode != null) { |
|||
// for (String redisKey : redisCandidateJwCode) { |
|||
// String candidateJwCode = redisKey.substring(redisKey.length() - 8); |
|||
// if (candidate.getJwCode().equals(candidateJwCode)) { |
|||
// candidate.setVoted(true); |
|||
// } |
|||
// } |
|||
// } |
|||
// } |
|||
// |
|||
// return candidateList; |
|||
// } |
|||
// //获取候选人被投票记录 |
|||
// @Override |
|||
// public List<Voter> getVotesByCandidate(String candidateJwcode) { |
|||
// return voterMapper.getVotesByCandidate(candidateJwcode); |
|||
// } |
|||
//} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue