模仿微信步数定时刷新

首语:上一篇已经初步介绍了定时任务,这次贴上一个demo小例的代码,内容主要就是模仿微信步数的刷新,后端技术利用Quartz调度框架,前端采用vue
要求:
1.用户输入账号、密码登录。
2.登录成功,在个人中心页面,显示用户基本信息。
3.在任务触发时间(如每晚10:06),刷新页面,可以看到当日步行排行榜。
4.适当准备好一些数据,便于展示。


项目目录png.png

用户类
@Entity
@Data
public class Sporter {
@Id
@GeneratedValue
private Integer id;
private String account;
private String avatar;
private String password;
private String bgpic;
/**
* 一对多关系,另一张表的外键
*/
@OneToMany(fetch = FetchType.EAGER , cascade = CascadeType.REMOVE)
@JoinColumn(name = "sporter_id")
private List<Walks> walksList = new ArrayList<>();

public Sporter() {

}

public Sporter(String account, String avatar, String password, String bgpic) {
    this.account = account;
    this.avatar = avatar;
    this.password = password;
    this.bgpic = bgpic;
}

public Sporter(String account, String avatar, String password, String bgpic, List<Walks> walksList) {
    this.account = account;
    this.avatar = avatar;
    this.password = password;
    this.bgpic = bgpic;
    this.walksList = walksList;
}

}
步数类
@Data
@Entity
public class Walks {
@Id
@GeneratedValue
private Integer id;

/**
 * 行走的步数
 */
private Integer walkCount;

/**
 * 创建的时间
 */
private Date createTime;

public Walks() {

}

public Walks(Integer walkCount, Date createTime) {
    this.walkCount = walkCount;
    this.createTime = createTime;
}

public Integer getWalkCount() {
    return walkCount;
}

public void setWalkCount(Integer walkCount) {
    this.walkCount = walkCount;
}

public Date getCreateTime() {
    return createTime;
}

public void setCreateTime(Date createTime) {
    this.createTime = createTime;
}

}
登陆dao
public interface LoginRepository extends JpaRepository<Sporter,Integer> {
Sporter findByAccountAndPassword(String account, String password);
Sporter findByAccount(String account);
}
步数dao
public interface WalksRepository extends JpaRepository<Walks,Integer> {
List<Walks>findAll();
}
登陆service
public interface LoginService {
Sporter findone(String account, String password);
Sporter getOne(String account);
/**
* 查找所有用户的信息,以及该用户下的步数信息
* @return
/
List<Sporter> getAll();
}
更新步数service
public interface WalksService {
/
*
* 更新步数表中的数据
*/
void updateWalks();
}
登陆service实现类
@Service
public class LoginServiceImpl implements LoginService {
@Resource
private LoginRepository loginRepository;
@Override
public Sporter findone(String account, String password) {
return loginRepository.findByAccountAndPassword(account,password);
}
@Override
public Sporter getOne(String account) {
return loginRepository.findByAccount(account);
}
@Override
public List<Sporter> getAll() {
return loginRepository.findAll();
}
}
更新步数service实现类
@Service
public class WalksServiceImpl implements WalksService{
@Resource
private WalksRepository walksRepository;
@Override
public void updateWalks() {
List<Walks> list = walksRepository.findAll();
Random random = new Random();
for (int i=0;i<list.size();i++){
Walks walks = list.get(i);
System.out.println(walks);
walks.setWalkCount(random.nextInt(20000)+20000);
walks.setCreateTime(new Date());
walksRepository.saveAndFlush(walks);
}
}
}
用户登陆的controller层
@RestController
@CrossOrigin
@RequestMapping(value = "/st")
public class LoginController {
@Resource
private LoginService loginService;
@Resource
private WalksService walksService;

@GetMapping("/login")
public Sporter getuser(String account, String password){
    return loginService.findone(account,password);
}
@GetMapping("/oneuser")
public Sporter getone(String account){
    return loginService.getOne(account);
}
@GetMapping("/all")
public List<Sporter>getall(){
    return loginService.getAll();
}

}
自定义job类
/**

  • 自定义的Job任务类
    */
    @Component
    public class Jobs {
    @Resource
    private WalksService walksService;

    @Scheduled(cron = "0 36 0 * * ? ")
    public void updateTodayWalks() throws Exception {
    walksService.updateWalks();
    }

}
/**

  • @author wn

  • quartz的配置类
    */
    @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();
    }
    }
    /**

  • @author wn

  • 自定义的可配置的JobFactory
    */
    @Component
    public class SpringJobFactory extends AdaptableJobFactory {

    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

/**
 * 创建一个Job实列
 * @param bundle
 * @return
 * @throws Exception
 */
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
    Object jobInstance = super.createJobInstance(bundle);
    capableBeanFactory.autowireBean(jobInstance);
    return jobInstance;
}

}
前端代码
主页
<template>
<div>
<div class="header">

<div class="collapse-btn" @click="collapseChage">
<i class="el-icon-menu"></i>
</div>
<div class="logo">定时任务</div>
<div class="header-right">
<div class="header-user-con">

<div class="btn-fullscreen" @click="handleFullScreen">
<el-tooltip effect="dark" :content="fullscreen?取消全屏:全屏" placement="bottom">
<i class="el-icon-rank"></i>
</el-tooltip>
</div>

<div class="user-avator"><img :src="responseUser.avatar"></div>

<el-dropdown class="user-name" trigger="click" @command="handleCommand">
<span class="el-dropdown-link">
{{username}} <i class="el-icon-caret-bottom"></i>
</span>
<el-dropdown-menu slot="dropdown">
<a href="#" target="_blank">
<el-dropdown-item>个人信息</el-dropdown-item>
</a>
<el-dropdown-item divided command="loginout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
<div>
<img :src="sporters[0].bgpic" style="height: 100px;width: 1400px"/>
</div>
<div class="container">
<div class="row" v-for="sporter in sporters " :key="sporter.id">
<div class="el-col-md-6">
<img class="card-img-center" :src="sporter.avatar"/>
<div class="card-body">
<p class="card-text">{{sporter.walksList[0].walkCount}}</p >
<p class="card-text">{{sporter.walksList[0].createTime}}</p>
</div>
</div>
</div>
</div>
</div>
</template>

<script>
import bus from '../components/common/bus';
export default {
data() {
return {
collapse: false,
fullscreen: false,
name: 'taoranran',
message: 2,
responseUser:[],
sporters:[]
}
},
computed:{
username(){
let username = localStorage.getItem('ms_username');
return username ? username : this.name;
}
},
created(){
var _this=this;
this.http.get('http://localhost:8080/st/oneuser?account='+localStorage.getItem('ms_username')) .then(function (response) { _this.responseUser=response.data }) this.http.get('http://localhost:8080/st/all').then(function (res) {
_this.sporters=res.data
})
},
methods:{
// 用户名下拉菜单选择事件

  handleCommand(command) {
    if(command == 'loginout'){
      localStorage.removeItem('ms_username')
      this.$router.push('/');
    }
  },
  // 侧边栏折叠
  collapseChage(){
    this.collapse = !this.collapse;
    bus.$emit('collapse', this.collapse);
  },
  // 全屏事件
  handleFullScreen(){
    let element = document.documentElement;
    if (this.fullscreen) {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.webkitCancelFullScreen) {
        document.webkitCancelFullScreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
      }
    } else {
      if (element.requestFullscreen) {
        element.requestFullscreen();
      } else if (element.webkitRequestFullScreen) {
        element.webkitRequestFullScreen();
      } else if (element.mozRequestFullScreen) {
        element.mozRequestFullScreen();
      } else if (element.msRequestFullscreen) {
        // IE11
        element.msRequestFullscreen();
      }
    }
    this.fullscreen = !this.fullscreen;
  }
}

}
</script>

<style scoped>
.header {
position: relative;
box-sizing: border-box;
width: 100%;
height: 70px;
font-size: 22px;
color: #fff;
}
.collapse-btn{
float: left;
padding: 0 21px;
cursor: pointer;
line-height: 70px;
}
.header .logo{
float: left;
width:250px;
line-height: 70px;
}
.header-right{
float: right;
padding-right: 50px;
}
.header-user-con{
display: flex;
height: 70px;
align-items: center;
}
.btn-fullscreen{
transform: rotate(45deg);
margin-right: 5px;
font-size: 24px;
}
.user-name{
margin-left: 10px;
}
.user-avator{
margin-left: 20px;
}
.user-avator img{
display: block;
width:40px;
height:40px;
border-radius: 50%;
}
.el-dropdown-link{
color: #fff;
cursor: pointer;
}
</style>
登陆页
<template>
<div class="login-wrap">
<div class="ms-title">登   陆</div>
<div class="ms-login">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="0px" class="demo-ruleForm">
<el-form-item prop="username">
<el-input v-model="ruleForm.username" placeholder="username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="password" v-model="ruleForm.password"></el-input>
</el-form-item>
<div class="login-btn">
<el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
</div>
</el-form>
</div>
</div>
</template>

<script>
export default {
data: function(){
return{
ruleForm: {
username: '',
password: ''
},
rules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
]
}
}
},
methods: {
// login () {
// this.axios.get('http://localhost:8080/st/login', { // account: this.ruleForm.username, // password: this.ruleForm.password // }).then(successResponse => { // this.responseResult = JSON.stringify(successResponse.data); // this.router.push('/home')
// })
// .catch(failResponse => {})
// },
submitForm(formName) {
this.refs[formName].validate((valid) => { if (valid) { this.http.get('http://localhost:8080/st/login?account='+this.ruleForm.username+'&password='+this.ruleForm.password)
.then(res => {
localStorage.setItem('ms_username',res.data.account);
if (res.data.account!=undefined){
this.router.push('/home'); }else { this.alert("账号或密码错误!!!")
}
})
}else {
console.log('error submit!!');
return false;
}
});
}
}
}
</script>

<style scoped>
.login-wrap{
position: relative;
width:100%;
height:100%;
}
.ms-title{
position: absolute;
top:50%;
width:100%;
margin-top: -230px;
text-align: center;
font-size:30px;
color: #fff;

}
.ms-login{
position: absolute;
left:50%;
top:50%;
width:300px;
height:160px;
margin:-150px 0 0 -190px;
padding:40px;
border-radius: 5px;
background: #fff;
}
.login-btn{
text-align: center;
}
.login-btn button{
width:100%;
height:36px;
}
</style>
效果图


登陆.png
定时前.png
定时后.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • pom依赖 <?xml version="1.0"encoding="UTF-8"?> xsi:schemaLoc...
    逍遥_6b76阅读 673评论 0 0
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 2,027评论 0 2
  • 文/鸿运 春色异国独风景 水墨丹青无阴晴 雨雾朦胧不相见 闲听花落细无声 日斜千里永宁寺 草青树绿雁过鸣 忽闻四处...
    HONGYUNDANGTOU阅读 213评论 2 7
  • 推开窗,迎一团冷气 来自远方,来至房 不问安眠,不问食饭 只问一句:可还有思念 雪,白茫茫一片 几缕炊烟,阴冷小山...
    April石阅读 284评论 22 29
  • 复习
    huafu6688阅读 134评论 0 0