thinkPHP实现签到功能的方法


Posted in PHP onMarch 15, 2017

本文实例讲述了thinkPHP实现签到功能的方法。分享给大家供大家参考,具体如下:

数据表:

CREATE TABLE `members_sign` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `uid` int(11) unsigned NOT NULL COMMENT '用户id',
 `days` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '连续签到的天数',
 `is_share` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否分享过',
 `is_sign` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否签到过',
 `stime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '签到的时间',
 `atime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '添加时间',
 PRIMARY KEY (`id`),
 KEY `index_uid` (`uid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=162 DEFAULT CHARSET=utf8 COMMENT='签到分享表';

Controller:

<?php
namespace Member\Controller;
use Member\Controller\MController;
class IndexController extends MController {
  /**
  * 用户中心
  * @param
  */
  public function index(){
    $pre = C('DB_PREFIX');
        // 日历列表
    $monthSign = $this->getMonthSign();
    $dayList = $this->showDays($monthSign);
    // 今天签到
    $data = $this->todayData();
    if($data['is_sign'] == 1){
      $this->assign('isSign',true);
    }
    $this->display();
  }
  /**
  * 执行当天签到
  * @return json 签到成功返回 {status:1,info:'已签到'}
  */
  public function sign(){
    $todayData = $this->todayData();
    if($todayData['is_sign'] == 1){
      $this->successMsg('已签到');
    }else{
      $data = $this->getInsertData($this->uid);
      // 无今天数据
      if($todayData == NULL){
        $data['uid'] = $this->uid;
        $data['atime'] = time();
        $id = M('members_sign')->add($data);
      }else{
        $save = M('members_sign')->where("id = {$todayData['id']}")->save($data);
      }
      if($id or $save){
        $score = $this->getTodayScores($data['days']);
        // 为该用户添加积分
        addScore($this->uid,$score);
        $this->successMsg('已签到',array('score' => $score,'days'=>$data['days']));
      }else{
        $this->errorMsg('签到失败,请刷新后重试!');
      }
    }
  }
  /**
  * 返回每次签到要插入的数据
  *
  * @param int $uid 用户id
  * @return array(
  *  'days'   =>  '天数',
  *  'is_sign'  =>  '是否签到,用1表示已经签到',
  *  'stime'   =>  '签到时间',
  * );
  */
  protected function getInsertData($uid){
    // 昨天的连续签到天数
    $start_time = strtotime(date('Y-m-d 0:0:0',time()-86400))-1;
    $end_time  = strtotime(date('Y-m-d 23:59:59',time()-86400))+1;
    $days = M('members_sign')->where("uid = $uid and atime > $start_time and atime < $end_time")->getField('days');
    if($days){
      $days++;
      if($days > 30){
        $days = 1;
      }
    }else{
      $days = 1;
    }
    return array(
      'days'    => $days,
      'is_sign'  => 1,
      'stime'   => time()
    );
  }
  /**
  * 用户当天签到的数据
  * @return array 签到信息 is_sign,stime 等
  */
  protected function todayData(){
    $time = time();
    $start_stime  = strtotime(date('Y-m-d 0:0:0',$time))-1;
    $end_stime = strtotime(date('Y-m-d 23:59:59',$time))+1;
    return M('members_sign')->field('atime',true)->where("uid = {$this->uid} and atime > $start_stime and atime < $end_stime")->find();
  }
  /**
  * 积分规则,返回连续签到的天数对应的积分
  *
  * @param int $days 当天应该得的分数
  * @return int 积分
  */
  protected function getTodayScores($days){
    if($days == 30){
      return 50;
    }else if($days > 19){
      return 8;
    }else if($days > 9){
      return 5;
    }else{
      return 3;
    }
  }
  /**
  * 显示签到列表
  *
  * @param array  $signDays 某月签到的日期 array(1,2,3,4,5,12,13)
  * @param int $year    可选,年份
  * @param int $month   可选,月份
  * @return string 日期列表<li>1</li>....
  */
  protected function showDays($signDays,$year,$month){
    $time = time();
    $year = $year ? $year : date('Y',$time);
    $month = $month ? $month : date('m',$time);
    $daysTotal = date('t', mktime(0, 0, 0, $month, 1, $year));
    $now = date('Y-m-d',$time);
    $str = '';
    for ($j = 1; $j <= $daysTotal; $j++) {
      $i++;
      $someDay = date('Y-m-d',strtotime("$year-$month-$j"));
      // 小于今天的日期样式
      if ($someDay <= $now){
        // 当天日期样式 tdc = todayColor
        if($someDay == $now){
          // 当天签到过的
          if(in_array($j,$signDays)){
            $str .= '<li class="current fw tdc">'.$j.'</li>';
          }else{
            $str .= '<li class="today fw tdc">'.$j.'</li>';
          }
        }else{
          // 签到过的日期样式 current bfc = beforeColor , fw = font-weight
          if(in_array($j,$signDays)){
            $str .= '<li class="current fw bfc">'.$j.'</li>';
          }else{
            $str .= '<li class="fw bfc">'.$j.'</li>';
          }
        }
      }else{
        $str .= '<li>'.$j.'</li>';
      }
    }
    return $str;
  }
  /**
  * 获取当月签到的天数,与 $this->showDays() 配合使用
  * @return 当月签到日期 array(1,2,3,4,5,12,13)
  */
  protected function getMonthSign(){
    $time  = time();
    $year  = date('Y',$time);
    $month = date('m',$time);
    $day  = date("t",strtotime("$year-$month"));
    $start_stime  = strtotime("$year-$month-1 0:0:0")-1;
    $end_stime = strtotime("$year-$month-$day 23:59:59")+1;
    $list = M('members_sign')->where("uid = {$this->uid} and stime > $start_stime and stime < $end_stime")->order('stime asc')->getField('stime',true);
    foreach ($list as $key => $value){
      $list[$key] = date('j',$value);
    }
    return $list;
  }
}

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
让你同时上传 1000 个文件 (二)
Oct 09 PHP
Notice: Trying to get property of non-object problem(PHP)解决办法
Mar 11 PHP
基于php缓存的详解
May 15 PHP
测试php连接mysql是否成功的代码分享
Jan 24 PHP
ThinkPHP自动转义存储富文本编辑器内容导致读取出错的解决方法
Aug 08 PHP
又一个PHP实现的冒泡排序算法分享
Aug 21 PHP
PHP判断是否为空的几个函数对比
Apr 21 PHP
如何使用微信公众平台开发模式实现多客服
Jan 06 PHP
php array_slice 取出数组中的一段序列实例
Nov 04 PHP
PHP与JavaScript针对Cookie的读写、交互操作方法详解
Aug 07 PHP
Bootstrap+PHP实现多图上传功能实例详解
Apr 08 PHP
如何在Mac上通过docker配置PHP开发环境
May 29 PHP
thinkPHP框架实现图像裁剪、缩放、加水印的方法
Mar 14 #PHP
ThinkPHP框架分布式数据库连接方法详解
Mar 14 #PHP
让ThinkPHP的模板引擎达到最佳效率的方法详解
Mar 14 #PHP
thinkphp3.2实现跨控制器调用其他模块的方法
Mar 14 #PHP
Yii2下点击验证码的切换实例代码
Mar 14 #PHP
php分页查询的简单实现代码
Mar 14 #PHP
php实现购物车产品删除功能(2)
Jul 23 #PHP
You might like
PHP 使用MySQL管理Session的回调函数详解
2013/06/21 PHP
php检索或者复制远程文件的方法
2015/03/13 PHP
PHP使用strrev翻转中文乱码问题的解决方法
2017/01/13 PHP
页面中iframe相互传值传参
2009/12/13 Javascript
jquery 选择器引擎sizzle浅析
2013/02/06 Javascript
在JavaScript中实现类的方式探讨
2013/08/28 Javascript
js 通过cookie实现刷新不变化树形菜单
2014/10/30 Javascript
在JavaScript中使用对数Math.log()方法的教程
2015/06/15 Javascript
jQuery过滤HTML标签并高亮显示关键字的方法
2015/08/07 Javascript
jQuery+Ajax实现无刷新分页
2015/10/30 Javascript
jQuery 移动端artEditor富文本编辑器
2016/01/11 Javascript
webpack使用 babel-loader 转换 ES6代码示例
2017/08/21 Javascript
React Native之TextInput组件解析示例
2017/08/22 Javascript
微信小程序实现表单校验功能
2020/03/30 Javascript
ReactNative之FlatList的具体使用方法
2017/11/29 Javascript
vue动态路由配置及路由传参的方式
2018/05/23 Javascript
jQuery阻止事件冒泡实例分析
2018/07/03 jQuery
vue2中使用sass并配置全局的sass样式变量的方法
2018/09/04 Javascript
layui动态渲染生成select的option值方法
2019/09/23 Javascript
在js文件中引入(调用)另一个js文件的三种方法
2020/09/11 Javascript
vue-cli4使用全局less文件中的变量配置操作
2020/10/21 Javascript
[37:45]完美世界DOTA2联赛PWL S3 LBZS vs Phoenix 第二场 12.09
2020/12/11 DOTA
对于Python中RawString的理解介绍
2016/07/07 Python
Python+Pyqt实现简单GUI电子时钟
2021/02/22 Python
python字典setdefault方法和get方法使用实例
2019/12/25 Python
详解使用python爬取抖音app视频(appium可以操控手机)
2021/01/26 Python
HTML5是什么 HTML5是什么意思 HTML5简介
2012/10/26 HTML / CSS
NBA欧洲商店(法国):NBA Europe Store FR
2016/10/19 全球购物
Sport-Thieme荷兰:购买体育用品
2019/08/25 全球购物
Servlet的实例是在生命周期什么时候创建的?配置servlet最重要的是什么?
2012/05/30 面试题
文秘专业自荐信
2013/10/14 职场文书
英语教师岗位职责
2014/03/16 职场文书
意向协议书范本
2014/04/23 职场文书
我有一个梦想演讲稿
2014/05/05 职场文书
详解JS WebSocket断开原因和心跳机制
2021/05/07 Javascript
sql查询结果列拼接成逗号分隔的字符串方法
2021/05/25 SQL Server