采用Quartz任务调度框架,模拟微信步数排行
- 用户输入账号、密码登录
- 登陆成功,在个人中心页面,显示用户基本信息
- 在任务触发时间,刷新页面,可以看到当日步行排行榜
-
目录结构
添加pom依赖
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>quartz</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>quartz</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--thymeleaf模板引擎依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7-1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.8.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.8.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
-
实体类
- SportUser类
package com.example.quartz.entity;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
public class SportUser {
@GeneratedValue
@Id
private Integer id;
private String account;
private String password;
private String avatar;
private String nickName;
public SportUser() {
}
public SportUser(String account, String password, String avatar, String nickName) {
this.account = account;
this.password = password;
this.avatar = avatar;
this.nickName = nickName;
}
@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.REMOVE)
@JoinColumn(name = "sportUser_id")
private List<Step> steps = new ArrayList<>();
public SportUser(String account, String password, String avatar, String nickName, List<Step> steps) {
this.account = account;
this.password = password;
this.avatar = avatar;
this.nickName = nickName;
this.steps = steps;
}
}
- Step类
package com.example.quartz.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.util.Date;
@Entity
@Data
public class Step {
@GeneratedValue
@Id
private Integer id;
private String account;
private Date date;
private String number;
public Step() {
}
public Step(String account, Date date, String number) {
this.account = account;
this.date = date;
this.number = number;
}
}
DAO层
- LoginRepository
package com.example.quartz.dao;
import com.example.quartz.entity.SportUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface LoginRepository extends JpaRepository<SportUser,Integer> {
@Query("from SportUser u where u.account = :account")
SportUser findUser(@Param("account") String account);
}
- StepRepository
package com.example.quartz.dao;
import com.example.quartz.entity.Step;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface StepRepository extends JpaRepository<Step,Integer> {
@Query("FROM Step a WHERE DATEDIFF(a.date,NOW())=0 ORDER BY a.number DESC")
List<Step> find();
@Query("from Step u WHERE DATEDIFF(u.date,NOW())=0 and u.account = :account")
Step findUser(@Param("account") String account);
}
配置类
- QuartzConfig
package com.example.quartz.factory;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfig {
@Autowired
private SpringJobFactory springJobFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(springJobFactory);
return schedulerFactoryBean;
}
@Bean
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}
- SpringJobFactory
package com.example.quartz.factory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
@Component
public class SpringJobFactory extends AdaptableJobFactory {
@Autowired(required=true)
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
- SportJob
package com.example.quartz.factory;
import com.example.quartz.service.StepService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class SportJob {
@Resource
private StepService stepService;
//设置每天下午16:16分更新数据
@Scheduled(cron = "0 16 16 * * ? ")
public void updateTodayWalks() throws Exception {
stepService.updateWalks();
}
}
Service层
- LoginService
package com.example.quartz.service;
import com.example.quartz.entity.SportUser;
import com.example.quartz.entity.Step;
import java.util.List;
public interface LoginService {
List<SportUser> get (String account, String password);
SportUser check(String account,String password);
List<Step> getAll();
}
-LoginServiceImpl
package com.example.quartz.service.Impl;
import com.example.quartz.dao.LoginRepository;
import com.example.quartz.dao.StepRepository;
import com.example.quartz.entity.SportUser;
import com.example.quartz.entity.Step;
import com.example.quartz.service.LoginService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class LoginServiceImpl implements LoginService {
@Resource
private LoginRepository loginRepository;
@Resource
private StepRepository stepRepository;
@Override
public List<SportUser> get(String account, String password) {
return loginRepository.findAll();
}
@Override
public SportUser check(String account, String password) {
List<SportUser> users = loginRepository.findAll();
SportUser user = new SportUser();
for (int i=0;i<users.size();i++){
String name = users.get(i).getAccount();
String pass = users.get(i).getPassword();
if (name.equals(account)){
if (pass.equals(password)){
user = users.get(i);
}
}
}
return user;
}
@Override
public List<Step> getAll() {
return stepRepository.findAll();
}
}
-StepService
package com.example.quartz.service;
public interface StepService {
void updateWalks();
}
-StepServiceImpl
package com.example.quartz.service.Impl;
import com.example.quartz.dao.StepRepository;
import com.example.quartz.entity.Step;
import com.example.quartz.service.StepService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Random;
@Service
public class StepServiceImpl implements StepService{
@Resource
private StepRepository stepRepository;
@Override
public void updateWalks() {
List<Step> list = stepRepository.findAll();
Random random = new Random();
for (int i=0;i<list.size();i++){
Step step = list.get(i);
step.setNumber(String.valueOf(random.nextInt(20000)+20000));
step.setDate(new Date());
stepRepository.saveAndFlush(step);
}
}
}
Controller层
-LoginController
package com.example.quartz.controller;
import com.example.quartz.dao.StepRepository;
import com.example.quartz.entity.SportUser;
import com.example.quartz.service.LoginService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@Controller
@RequestMapping()
public class LoginController {
@Resource
private LoginService loginService;
@Resource
private StepRepository stepRepository;
@RequestMapping(value = "/SportUser")
public String show(HttpServletRequest request, ModelMap modelMap) {
String account = request.getParameter("account");
String password = request.getParameter("password");
SportUser sportUser = loginService.check(account,password);
modelMap.addAttribute("sportUser",sportUser);
modelMap.addAttribute("userStep",stepRepository.findUser(account));
modelMap.addAttribute("steps",stepRepository.find());
return "home";
}
@RequestMapping("/login")
public String login(){
return "login";
}
}
前端
- login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html>
<head>
<meta charset="UTF-8">
<title>登录界面</title>
<link rel="stylesheet" href="/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css" />
<style>
html,body{
width: 100%;
height: 100%;
background: url(http://p88kzenjw.bkt.clouddn.com/back.png) bottom center no-repeat #efeff4 ;
background-size: 100% 100%;
}
form#login {
-webkit-border-radius: 5px;
border-radius: 5px;
width: 400px;
margin: auto;
padding-top: 270px;
}
form#login tr td{
padding-top: 20px;
}
input#button{
width:90px;
height:30px;
color: white;
background-color:transparent;
border: 1px solid black;
text-decoration: none;
}
.table-set{
width: 570px;
height: 420px;
margin-top: -160px;
margin-left: -60px;
background: white;
border-radius: 3%;
}
.logo{
margin-left: 200px;
}
</style>
</head>
<body>
<div>
<form action="/SportUser" method="post" id="login">
<table align="center" class="table-set">
<tr>
<td class="logo-location"><img src="img/logo_blue.png" class="logo" ></td>
<td style="font-size: 30px;color: rgb(79,109,207);position:absolute;margin-left: -260px;margin-top: 30px;">趣运动</td>
</tr>
<tr>
<td><input type="text" name="account" placeholder="请输入您的用户名/账号"
style="width: 340px; height:38px;margin-left: 120px;margin-top: -10px;" th:align="center"></input></td>
</tr>
<tr>
<td style="margin-top: -50px;"><input type="password" name="password" placeholder="请输入您的密码"
style="width: 340px; height:38px;margin-left: 120px;margin-top: -40px;" th:align="center"></input></td>
</tr>
<tr style="margin-top: -160px;">
<td ><input type="submit" id="button" value="登 录" style="background: gray;width: 350px;height: 36px;margin-left: 120px;"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
- home.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html>
<head>
<meta charset="UTF-8">
<title>主界面</title>
<link rel="stylesheet" href="/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css" />
<style>
html,body{
width: 100%;
height: 100%;
background: url(https://wallpaper.infinitynewtab.com/wallpaper/3218.jpg) bottom center no-repeat #efeff4 ;
background-size: 100% 100%;
}
.avatar{
width: 40px;
height: 40px;
margin-left: 100px;
}
.top{
width: 100%;
height: 60px;
background: #DDDDDD;
margin-top: 14px;
display: flex;
}
.center-main{
width: 40%;
height: 400px;
background: #DDDDDD;
margin-top: 28px;
margin-left: 50px;
}
.friend{
color:gray;
font-size: 28px;text-align: center;
}
.right{
width: 460px;
height: 400px;
/*background: #DDDDDD;*/
margin-left: 660px;
margin-top: -390px;
}
</style>
</head>
<body>
<div class="container">
<div class="top">
<div>
<img th:src="${sportUser.avatar}" class="img-circle avatar center-block" style="margin-top: 16px;">
</div>
<div style="margin-left: 200px;margin-top: 14px;"><text th:text="'欢迎您 :' + ${sportUser.account}" ></text></div>
<text th:text="'您今日的步数为:'+${userStep.number}" style="color: #3CB371;font-size: 22px;margin-left: 160px;margin-top: 10px;"></text>
</div>
</div>
<div class="center-main">
<h2 style="color: gray;text-align: center">今日排行</h2>
<div class="row">
<div class="col-md-6">
<div style="margin-left: 110px">
<h4>用户姓名</h4>
</div>
</div>
<div class="col-md-6">
<div style="margin-left: 40px">
<h4>今日步数</h4>
</div>
</div>
<div class="row">
<div th:each="step:${steps}">
<div style="margin-top: 30px;height: 26px">
<div class="col-md-6">
<div style="margin-left: 124px;">
<p th:text="${step.account}"></p>
</div>
</div>
<div class="col-md-6">
<div style="margin-left: 44px">
<p th:text="${step.number}" style="color: #FFCC22;font-size: 24px"></p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="right">
<h3 style="margin-top: 70px">您今日的运动量</h3>
<p style="margin-top: 20px" >距离为7.3公里</p>
<p>今天走的路程较多,请注意休息哦,按摩小腿可以有效缓解酸痛感</p>
<p>合理定制运动计划,能让身体更能接受哦</p>
<p></p>
</div>
</div>
</body>
</html>
网友评论