Browse Source

初始化

lh_vote_java
lenghui 5 months ago
commit
40cb5c49df
  1. 33
      .gitignore
  2. 106
      pom.xml
  3. 13
      src/main/java/com/lh/VoteSystemApplication.java
  4. 19
      src/main/java/com/lh/bean/Candidate.java
  5. 82
      src/main/java/com/lh/bean/RespBean.java
  6. 18
      src/main/java/com/lh/bean/voter.java
  7. 22
      src/main/java/com/lh/config/ExceptionHandler.java
  8. 51
      src/main/java/com/lh/config/RedisConfig.java
  9. 31
      src/main/java/com/lh/controller/VoteController.java
  10. 7
      src/main/java/com/lh/exception/MyException.java
  11. 17
      src/main/java/com/lh/mapper/CandidatesMapper.java
  12. 17
      src/main/java/com/lh/mapper/VoterMapper.java
  13. 16
      src/main/java/com/lh/service/VoteService.java
  14. 101
      src/main/java/com/lh/service/VoteServiceImpl.java
  15. 32
      src/main/resources/application.properties
  16. 13
      src/main/resources/com/lh/mapper/CandidatesMapper.xml
  17. 14
      src/main/resources/com/lh/mapper/VoterMapper.xml
  18. 6
      src/main/resources/static/index.html
  19. 30
      src/test/java/com/lh/VoteSystemApplicationTests.java

33
.gitignore

@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

106
pom.xml

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lh</groupId>
<artifactId>vote_system</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>vote_system</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.4.2</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.lh.VoteSystemApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

13
src/main/java/com/lh/VoteSystemApplication.java

@ -0,0 +1,13 @@
package com.lh;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.lh")
public class VoteSystemApplication {
public static void main(String[] args) {
SpringApplication.run(VoteSystemApplication.class, args);
}
}

19
src/main/java/com/lh/bean/Candidate.java

@ -0,0 +1,19 @@
package com.lh.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Candidate {
private Long id;
private String jwCode;
private String name;
private String avatar;
private Integer votes = 0;
//是否被当前用户投票
private boolean isVoted;
}

82
src/main/java/com/lh/bean/RespBean.java

@ -0,0 +1,82 @@
package com.lh.bean;
public class RespBean {
//状态码 10000-成功 10001-失败
private Integer code;
//返回的附件信息
private String msg;
//返回的数据
private Object data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static RespBean ok() {
RespBean respBean = new RespBean();
respBean.setCode(10000);
return respBean;
}
public static RespBean ok(String msg) {
RespBean respBean = new RespBean();
respBean.setCode(10000);
respBean.setMsg(msg);
return respBean;
}
public static RespBean ok(String msg, Object data) {
RespBean respBean = new RespBean();
respBean.setCode(10000);
respBean.setMsg(msg);
respBean.setData(data);
return respBean;
}
public static RespBean error() {
RespBean respBean = new RespBean();
respBean.setCode(10001);
return respBean;
}
public static RespBean error(String msg) {
RespBean respBean = new RespBean();
respBean.setCode(10001);
respBean.setMsg(msg);
return respBean;
}
public static RespBean error(String msg, Object data) {
RespBean respBean = new RespBean();
respBean.setCode(10001);
respBean.setMsg(msg);
respBean.setData(data);
return respBean;
}
}

18
src/main/java/com/lh/bean/voter.java

@ -0,0 +1,18 @@
package com.lh.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class voter {
private Long id;
private String jwCode;
private String name;
private LocalDateTime voteTime;
private String candidateJwCode;
}

22
src/main/java/com/lh/config/ExceptionHandler.java

@ -0,0 +1,22 @@
package com.lh.config;
import com.lh.bean.RespBean;
import com.lh.exception.MyException;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Configuration
@RestControllerAdvice
public class ExceptionHandler {
@org.springframework.web.bind.annotation.ExceptionHandler(MyException.class)
public RespBean myException(MyException e) {
e.printStackTrace();
return RespBean.error(e.getMessage());
}
@org.springframework.web.bind.annotation.ExceptionHandler(Exception.class)
public RespBean exception(Exception e) {
e.printStackTrace();
return RespBean.error("未知错误,请联系管理员");
}
}

51
src/main/java/com/lh/config/RedisConfig.java

@ -0,0 +1,51 @@
package com.lh.config;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
// 基本配置
RedisCacheConfiguration defaultCacheConfiguration =
RedisCacheConfiguration
.defaultCacheConfig()
//设置key为String
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
//设置value为自动转Json的Object
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
//不缓存null
.disableCachingNullValues()
//缓存数据保存10分钟
.entryTtl(Duration.ofMinutes(10));
//创建一个redis缓存管理器
RedisCacheManager redisCacheManager =
RedisCacheManager.RedisCacheManagerBuilder
//Redis连接工厂
.fromConnectionFactory(redisConnectionFactory)
//缓存配置
.cacheDefaults(defaultCacheConfiguration)
.build();
return redisCacheManager;
}
@Bean
public StringRedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}

31
src/main/java/com/lh/controller/VoteController.java

@ -0,0 +1,31 @@
package com.lh.controller;
import com.lh.bean.RespBean;
import com.lh.service.VoteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@CrossOrigin
@RestController
@RequestMapping
public class VoteController {
@Autowired
private VoteService voteService;
//投票
@PostMapping("/vote")
public RespBean vote(String voterJwcode, String candidateJwcode, String voterName) throws Exception {
Integer result =voteService.insertVote(voterJwcode, candidateJwcode, voterName);
return RespBean.ok("投票成功!今日还可以投" + result + "次");
}
//获取所有候选人
@GetMapping ("/getCandidates/{voterJwcode}")
public RespBean getCandidates(@PathVariable("voterJwcode") String voterJwcode) {
return RespBean.ok("获取成功",voteService.getCandidates(voterJwcode));
}
//获取某个候选人的被投票记录
@GetMapping("/getVotesByCandidate/{candidateJwcode}")
public RespBean getVotesByCandidate(@PathVariable("candidateJwcode") String candidateJwcode) {
return RespBean.ok("获取成功",voteService.getVotesByCandidate(candidateJwcode));
}
}

7
src/main/java/com/lh/exception/MyException.java

@ -0,0 +1,7 @@
package com.lh.exception;
public class MyException extends Exception{
public MyException(String msg){
super(msg);
}
}

17
src/main/java/com/lh/mapper/CandidatesMapper.java

@ -0,0 +1,17 @@
package com.lh.mapper;
import com.lh.bean.Candidate;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface CandidatesMapper {
//获取所有候选人
List<Candidate> getCandidates();
//通过精网号搜索候选人
Candidate getByCandidateJwcode(@Param("jwcode") String jwcode);
//候选人票数+1
boolean addVotes(@Param("jwcode") String jwcode);
}

17
src/main/java/com/lh/mapper/VoterMapper.java

@ -0,0 +1,17 @@
package com.lh.mapper;
import com.lh.bean.voter;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface VoterMapper {
// 查询用户今日投票信息
List<voter> countVotesToday(@Param("jwcode") String jwcode);
//插入投票记录
void insertVote(@Param("jwcode") String jwcode, @Param("candidateJwcode") String candidateJwcode,@Param("name") String namne);
//根据候选人的jwcode查询投票记录
List<voter> getVotesByCandidate(@Param("candidateJwcode") String candidateJwcode);
}

16
src/main/java/com/lh/service/VoteService.java

@ -0,0 +1,16 @@
package com.lh.service;
import com.lh.bean.Candidate;
import com.lh.bean.voter;
import com.lh.exception.MyException;
import java.util.List;
public interface VoteService {
//投票
Integer insertVote(String voterJwcode, String candidateJwcode, String voterName) throws MyException;
//获取所有候选人
List<Candidate> getCandidates(String VoterJwcode);
//获取某个候选人的被投票记录
List<voter> getVotesByCandidate(String candidateJwcode);
}

101
src/main/java/com/lh/service/VoteServiceImpl.java

@ -0,0 +1,101 @@
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;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
public class VoteServiceImpl implements VoteService {
@Autowired
private VoterMapper voterMapper;
@Autowired
private CandidatesMapper candidatesMapper;
@Value("${vote.limit.daily}")
private int dailyVoteLimit; // 每日投票次数限制
@Autowired
private StringRedisTemplate redisTemplate;
//投票
@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 = redisTemplate.opsForValue().get(redisKey);
int voteCountToday = currentVoteCount == null ? 0 : Integer.parseInt(currentVoteCount);
if (voteCountToday >= dailyVoteLimit) {
throw new MyException("今日投票次数已达上限");
}
// 2. 获取候选人信息
Candidate candidate = candidatesMapper.getByCandidateJwcode(candidateJwcode);
if (candidate == null) {
throw new MyException("候选人不存在!");
}
// 3. 检查用户是否已经为该候选人投过票
List<voter> hasVotes = voterMapper.countVotesToday(voterJwcode);
//遍历列表判断是否有记录
for (voter vote : hasVotes) {
if (vote.getCandidateJwCode().equals(candidateJwcode)) {
throw new MyException("已投票,可以选择其他人试试哦~");
}
}
// 4. 增加候选人票数
if (!candidatesMapper.addVotes(candidateJwcode)) {
throw new MyException ("候选人票数更新失败,请联系管理员!");
}
// 5. 插入投票记录
voterMapper.insertVote(voterJwcode, candidateJwcode, voterName);
// 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);
//打印剩余长时间过期
System.out.println("Redis键" + redisKey + "将在" + secondsUntilEndOfDay + "秒后过期。");
return 2-voteCountToday;
}
//获取所有候选人
@Override
public List<Candidate> getCandidates(String VoterJwcode) {
//插入投票记录为List插入是否投过票的状态
List<Candidate> candidateList = candidatesMapper.getCandidates();
for (Candidate candidate : candidateList) {
List<voter> voters = voterMapper.countVotesToday(VoterJwcode);
for (voter voter : voters) {
if (voter.getCandidateJwCode().equals(candidate.getJwCode())) {
candidate.setVoted(true);
break;
}
}
}
return candidateList;
}
//获取候选人被投票记录
@Override
public List<voter> getVotesByCandidate(String candidateJwcode) {
return voterMapper.getVotesByCandidate(candidateJwcode);
}
}

32
src/main/resources/application.properties

@ -0,0 +1,32 @@
# 配置连接池
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/vote_system?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
# mybatis配置
# 打印log信息
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 开启驼峰命名法,自动将数据库的命名方式,映射成Java中的命名方式
mybatis.configuration.map-underscore-to-camel-case: true
#下面这些内容是为了让MyBatis映射
#指定Mybatis的Mapper文件
mybatis.mapper-locations=classpath:mappers/*xml
#指定Mybatis的实体目录
mybatis.type-aliases-package=com.lh.mybatis.entity
# 应用服务 WEB 访问端口
server.port=8080
#Redis 配置
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=123456
spring.redis.timeout=2000
spring.redis.jedis.pool.max-active=10
spring.redis.jedis.pool.max-idle=5
spring.redis.jedis.pool.min-idle=1
# 每日最大投票次数
vote.limit.daily=3

13
src/main/resources/com/lh/mapper/CandidatesMapper.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.lh.mapper.CandidatesMapper">
<insert id="addVotes">
update candidates set votes = votes + 1 where jwcode = #{jwcode}
</insert>
<select id="getCandidates" resultType="com.lh.bean.Candidate">
select * from candidates order by votes desc
</select>
<select id="getByCandidateJwcode" resultType="com.lh.bean.Candidate">
select * from candidates where jwcode = #{jwcode}
</select>
</mapper>

14
src/main/resources/com/lh/mapper/VoterMapper.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.lh.mapper.VoterMapper">
<insert id="insertVote">
INSERT INTO voters(jwcode, candidate_jwcode, name)
VALUES(#{jwcode}, #{candidateJwcode}, #{name})
</insert>
<select id="countVotesToday" resultType="com.lh.bean.voter">
SELECT * FROM voters WHERE jwcode = #{jwcode} AND DATE(vote_time) = CURDATE()
</select>
<select id="getVotesByCandidate" resultType="com.lh.bean.voter">
SELECT * FROM voters WHERE candidate_jwcode = #{candidateJwcode}
</select>
</mapper>

6
src/main/resources/static/index.html

@ -0,0 +1,6 @@
<html>
<body>
<h1>hello word!!!</h1>
<p>this is a html page</p>
</body>
</html>

30
src/test/java/com/lh/VoteSystemApplicationTests.java

@ -0,0 +1,30 @@
package com.lh;
import com.lh.mapper.CandidatesMapper;
import com.lh.mapper.VoterMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class VoteSystemApplicationTests {
@Autowired
private CandidatesMapper candidatesMapper;
@Autowired
private VoterMapper voterMapper;
@Test
void contextLoads() {
//candidatesMapper.getCandidates().forEach(System.out::println);
System.out.print( voterMapper.countVotesToday("10010"));
}
@Test
void contextLoads1() {
voterMapper.getVotesByCandidate("20010").forEach(System.out::println);
}
@Test
void contextLoads2() {
voterMapper.insertVote("10010","20010","王五");
}
}
Loading…
Cancel
Save