thinkphp5连续签到;php连续签到奖励不同积分案例

最近项目有个需求,需要实现连续签到奖励不同积分,中间断签则重新计算的功能,弄了一晚上,写了一个雏形demo,记下开发思路。

需要考虑部分:

1,会员基数大,如果每个人的签到记录都存入数据库,每次签到查询会造成较大的查询和写入压力

2,签到不同天数积分的获取问题

初步设定优化方案:每次会员签到,触发删除签到记录,删除掉该会员数据两天前的签到数据,保留前一天的签到作为签到存档

开发思路:会员表增加连续签到天数字段,每次签到优先判断昨天是否有签到,如果有,则根据会员签到天数表去获取对应的奖励,同时需更新会员表连续签到次数;如果没有,则表示今天第一天敲到,则更新对应奖励和设置会员连续签到字段值为1.

数据库设计:user 表增加continuity_day(连续签到天数),jifen(积分)字段,签到记录表:member_id,aword_jifen,create_time 三个字段。

前端:


js:

$("#LAY_signin").click(function(){{
  $have_session = $("#have_session").val();
  if($have_session == 'no'){
    layer.msg('请先登录');
  }else{
    $.post('{:url("index/user/qiandao")}',{}, function(data){
      console.log(data);
      if(data.code==200){
        var icon = 6;
      }else{
        var icon = 2;
      }
      layer.alert(data.msg, {icon: 6,title:'温馨提示'});
    }, 'json');
  }
}})

php用到的公共函数

//验证数组是否存在
function havedata($array){
    if(isset($array) && !empty($array)){
        return true;
    }else{
        return false;
    }
}

//获取指定时间间隔的是时间戳
function getLastTime($day,$type="before"){
    $data = array();
    if($type == "before"){
        $str = date("Y-m-d",strtotime("-{$day} day"))." 0:0:0";
        $data["star"] = strtotime($str);
        $str = date("Y-m-d",strtotime("-{$day} day"))." 24:00:00";
        $data["end"] = strtotime($str);
    }else{
        $str = date("Y-m-d",strtotime("+{$day} day"))." 0:0:0";
        $data["star"] = strtotime($str);
        $str = date("Y-m-d",strtotime("+{$day} day"))." 24:00:00";
        $data["end"] = strtotime($str);
    }
    return $data;
}

控制器:

//用户签到
public function qiandao(){
    $qiandao_effect = Loader::model('Member')->qiandao();
    return $qiandao_effect;
}

模型:

//用户签到
public function qiandao(){
    if(!Session::has('member_info')){
        return info("您还没有登录",4001);
    }else{
        $member_session = Session::get("member_info");
        $this->del_qiandao($member_session['member_id']);
        $now_time = strtotime(date("Y-m-d 0:0:0",time()));
        $check_qiandao = Db::name("qiandao")->where("create_time",">=",$now_time)->where('member_id',$member_session['member_id'])->find();
        if(havedata($check_qiandao)){
            return info("您今天已经签到过了",4002);
        }else{
            //检查昨天是否有签到过,如果有,则为连续签到,根据签到规则,设置相对应积分
            $qiandao_array = [5,6,7,8,9,10,15]; //签到积分奖励
            $yestaday = getLastTime(1,'before');
            $check_before_qiandao = $this->check_qiandao($yestaday['star'],$yestaday['end']);
            $member_info = $this->member_info($member_session['member_id']);
            if($check_before_qiandao){
                //说明昨天有签到,则获取连续签到天数
                if($member_info['continuity_day'] >= 7){
                    $aword_jifen = 15;
                }else{
                    $aword_jifen = $qiandao_array[$member_info['continuity_day']];
                }
                $first_qian = "no";
            }else{
                //昨天没有签到,则今天算是第一个签到
                $aword_jifen = $qiandao_array[0]; //没有连续签到,则从开始计算
                $first_qian = "yes";
            }

            //更新账户积分余额和签到次数
            if($first_qian == "yes"){
                $update_data = [
                    'jifen' => $member_info['jifen']+$aword_jifen,
                    'continuity_day' => 1
                ];
            }else{
                $update_data = [
                    'jifen' => $member_info['jifen']+$aword_jifen,
                    'continuity_day' => $member_info['continuity_day']+1
                ];
            }
            //更新会员数据
            $update_member = Db::name("member")->where("member_id",$member_session['member_id'])->update($update_data);
            //增加签到记录
            $insert_qiandao = [
                'member_id' => $member_info['member_id'],
                'aword_jifen' => $aword_jifen,
                'create_time' => time(),
            ];
            $insert_effect = Db::name("qiandao")->insert($insert_qiandao);
            if($insert_effect){
                return info('签到成功',200);
            }else{
                return info('签到失败',4001);
            }
        }
    }
}

//清除掉用户两天前的登录记录,防止用户登录数据过大,同时为连续签到保存依据
public function del_qiandao($member_id){
    $two_days_before = getLastTime(2,'before');
    Db::name('qiandao')->where("create_time","<=",$two_days_before['star'])->where('member_id',$member_id)->delete();
}

 

你可能感兴趣的:(thinkphp5开发总结)