项目需要增加一个签到功能。
很简单。登陆后点击【签到】,即可签到。
这里写图片描述

1.建数据库表

表结构如下:
这里写图片描述
id是自增的主键,uid是用户的数字id,clicked_time是签到的日期。
CURRENT_TIMESTAMP是插入sql语句的时间。
格式是这样的:2018-03-14 19:00:12

2.写php【查询当前用户,今天是否签到】的接口

$uid = $_GET['uid'];//地址栏参数
//定义查询语句,并执行
//"select clicked_time from daily_bonus where uid = $uid order by id desc limit 1;"
if(mysqli_num_rows($result) > 0) {
    //获取数据库的日期
    $row = mysqli_fetch_array($result);
    $db_year = substr($row["clicked_time"],0,4);
    $db_month = substr($row["clicked_time"],5,2);
    $db_day = substr($row["clicked_time"],8,2);
    //获取php当前的日期
    date_default_timezone_set("Asia/Shanghai");
    $this_year = date("Y");
    $this_month = date("m");
    $today = date("d");
    //判断是否相等
    if($db_year == $this_year && $db_month == $this_month && $db_day == $today)
        echo "had_clicked";
    else
        echo "no_clicked";
}
else{
    echo "no_clicked";
}

3.写php【当前用户签到】的接口

$uid = $_GET['uid'];  
//验证本次请求是否合法。(cookie/token是否正确)  
//INSERT INTO daily_bonus (uid) VALUES ('$uid')
if 执行成功
	return "success";
else
	return "error";

4.写vue前端的css样式

.can_clicked{
	blabla...
}
.clicked{
	blabla...
}

5.写html模板

<div class="daily_bonus" @click="click_daily_bonus" 
	:class="[daily_bonus_click_able?'can_clicked':'clicked']">
    <span>{{daily_bonus_text}}</span>
</div>

6.优化

在mounted里面请求ajax方法。
然后绑定签到的方法。
这样签到功能就做完了。

但是!有两个问题。

每次打开页面都需要请求AJAX,导致:

浪费服务器资源。页面载入速度慢。

我们需要对服务器返回的结果,进行缓存。


希望实现这样的效果:

 用户首次打开页面,开始查询后台接口,今天用户是否签到过。  
 若签到过,则在本地保存【最后一次签到的日期】(今天)。
 再次打开页面时,首先判断本地是否有值。
 若有值,则判断【最后一次签到的日期】是否等于今天。
 若不相等,则重新查询后台接口。

现在,我们修改一下刚才的代码。
1.把数据库表中的clicked_time的默认值删除。
2.修改php接口。

①【查询当前用户,今天是否签到】的接口

若用户今天已签到,返回今天的日期。

$clicked_time = $this_year."-".$this_month."-".$today;
if($db_year == $this_year && $db_month == $this_month && $db_day == $today)
	echo "$clicked_time";

②【当前用户签到】的接口

生成当前时间,插入到数据库。
若数据库插入成功,返回今天的日期。

//获取php当前的日期、时间
date_default_timezone_set("Asia/Shanghai");
$date=date_create();
$clicked_time = date_format($date,"Y-m-d H:i:s");
$return_day = date_format($date,"Y-m-d");

//定义查询语句,并执行
$sql2="INSERT INTO daily_bonus (uid,clicked_time) VALUES ($uid,'$clicked_time')";
if (mysqli_query($con, $sql2)) {
    echo "$return_day";
} else {
    echo "error";
}

③写Vue(JS)逻辑

data() {
    return {
        uid: '',
        daily_bonus_text: '签到',
        daily_bonus_click_able: true,//【签到】按钮是否可以点击
        }
    }
computed:{
	//最后一天签到的日期是不是今天。
	if_today_daily_bonus_local(){
		//获取本地储存
	   let last_daily_bonus_date = Date.parse(localStorage.getItem('last_daily_bonus_date'));
	   //获取今天日期
	   let date = new Date();
	   let month = date.getMonth()+1;
	   let current_date = date.getFullYear()+"/"+ month +"/"+date.getDate()+" 08:00:00";
	   let today = Date.parse(current_date);
	   //判断是否相等
	   if(last_daily_bonus_date === today)
	       return true;
	   else
	       return false;
	}
}
mounted(){
	this.uid = this.$store.state.uid;
	//若本地没有签到的记录,或者签到的日期不是今天。则向接口发送AJAX请求。
	if(localStorage.getItem('last_daily_bonus_date')===null||this.if_today_daily_bonus_local===false){
	//查询当前登录用户,今天是否签到。
	    axios.get('/api/if_daily_bonus.php?uid='+this.uid)
	        .then((res)=>{
	            console.log(res.data);
	            if(res.data !== "no_clicked"){
	                this.daily_bonus_click_able = false;
	                this.daily_bonus_text = "已签到";
	                //缓存本次查询结果。今天不用再次查询数据库,减小服务器压力。
	                localStorage.setItem('last_daily_bonus_date',res.data);
	            }
	            else{
	                this.daily_bonus_click_able = true;//插入失败,允许再次尝试签到
	            }
	            this.daily_bonus_ajaxing = false;//ajax结束
	        })
	        .catch((error)=> {
	            console.log(error);
	        });
	}else{
	    this.daily_bonus_text = "已签到";
	    this.daily_bonus_click_able = false;
	}
}
mothods:{
	click_daily_bonus(){
	     //若正在ajax中/已签到
	     if((this.daily_bonus_click_able === false)||(this.daily_bonus_ajaxing === false))
	         return;
	     //禁止再次点击【签到】按钮(防止用户手速过快,重复点击)
	     this.daily_bonus_click_able = false;
	     axios.get('/api/click_daily_bonus.php?uid='+ this.uid)
	         .then((res)=>{
	             console.log(res.data);
	             if(res.data !== "error") {
	                 this.daily_bonus_text = "已签到";
	                 //缓存本次查询结果。今天不用再次查询数据库,减小服务器压力。
	                 localStorage.setItem('last_daily_bonus_date',res.data);
	             }
	             else{
	                 this.daily_bonus_click_able = true;//允许再次签到
	             }
	         })
	         .catch( (error)=> {
	             console.log(error);
	         });
	}
}
Logo

前往低代码交流专区

更多推荐