zoukankan      html  css  js  c++  java
  • php七天签到功能及表设计

    最近开发一个商城app项目,需求表有个功能是写个七天签到功能,网上找了一圈才找到一个勉强可用的。

    经修改应用到项目后,记录一下需求开发流程及相关思路

    先看设计稿:

    功能需求如下:

    1.显示七天签到列表,每签到一天得到一积分,两天两积分,以此类推。在第八天的时候,重置归零为第一天

    2.显示连续签到天数、积分值

    3.签到日历中,已签到高亮显示

    4.切换年月,可以查询到那天签到的

    数据表设计:

    1.首先看数据库表的设计,因为预计这个商城项目用户量估计不大,所以采用了单表设计,数据量上去再说吧~

    2.我这边用户功能会有个打卡视频视频功能,不需要的话可以把这两个字段清除

    CREATE TABLE `cy_user_sign_log` (
      `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '序号',
      `uid` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户id',
      `days` int(10) DEFAULT '0' COMMENT '连续签到天数',
      `sign_time` int(10) DEFAULT NULL COMMENT '签到时间',
      `is_sign` tinyint(4) DEFAULT '0' COMMENT '是否签到过',
      `video` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '签到视频',
      `video_cover` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '签到视频封面',
      `create_time` int(10) NOT NULL COMMENT '新增时间',
      `update_time` int(10) DEFAULT NULL COMMENT '更新时间',
      `delete_time` int(10) DEFAULT NULL COMMENT '用来识别软删除
    只要这个字段的值不为NULL
    则视为已删除',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户签到记录表';

    php框架公司使用的是tp6,这里我就直接上控制器和模型的代码了

    控制器:

    1.涉及积分的功能,此处我就不上我的代码了,如果有需要直接写一个 方法就行了addScore($uid, $score);

    2.这里注意一下,接口返回的月份数据,time和sign对应的意思

     'days'   =>  '日期',
     'sign'  =>  '0=未签到,1=已签到',
     'time'   =>  '0=过去,1=现在,2=未来',
    /**
     * 用户签到列表
     * @return array 日期列表
     * @return array(
     *  'days'   =>  '天数',
     *  'sign'  =>  '0=未签到,1=已签到',
     *  'time'   =>  '0=过去,1=现在,2=未来',
     * );
     */
    public function getUserSignList()
    {
      $year = input('year', '');
      $month = input('month', '');
      $uid = request()->uid;
      // 日历列表
      if ($year && $month) {
        $monthSign = UserSignLog::build()->getMonthSign($year, $month);
        $dayList = UserSignLog::build()->showDays($monthSign, $year, $month);
      } else {
        $monthSign = UserSignLog::build()->getMonthSign();
        $dayList = UserSignLog::build()->showDays($monthSign);
      }
    
      $data['dayList'] = $dayList;
      // 今天签到数据
      $data['isSign'] = 0;
      $todayData = UserSignLog::build()->todayData();
      if ($todayData) {
        $data['isSign'] = 1;
      }
      $daysData = UserSignLog::build()->getInsertData($uid);
      $data['days'] = $daysData['days']; // 连续签到天数
      return json_success('用户签到列表', $data);
    }
    
    /**
     * 执行当天签到
     * @return json
     */
    public function userSign()
    {
      $todayData = UserSignLog::build()->todayData();
      if ($todayData['is_sign'] == 1) {
        return json_error('已签到,请勿重复提交');
      } else {
        $uid = request()->uid;
        $daysData = UserSignLog::build()->getInsertData($uid);
        try {
          // 无今天数据
          if ($todayData == NULL) {
            $daysData['uid'] = $uid;
            $daysData['create_time'] = time();
            UserSignLog::build()->create($daysData);
          } else {
            UserSignLog::build()->where("id = {$todayData['id']}")->save($daysData);
          }
          $score = UserSignLog::build()->getTodayScores($daysData['days']);
          // 为该用户添加积分
          // addScore($uid, $score);
        } catch (Exception $e) {
          return json_error($e->getMessage());
        }
        $data['score'] = $score;  // 积分
        $data['days'] = $daysData['days']; // 连续签到天数
        return json_success('签到成功', $data);
      }
    }

    模型代码:

    <?php
    
    declare(strict_types=1);
    
    namespace appmodeluser;
    
    use thinkModel;
    use 	hinkfacadeDb;
    use thinkmodelconcernSoftDelete;
    
    /**
     * @mixin thinkModel
     */
    class UserSignLog extends appmodelBaseModel
    {
      use SoftDelete;
    
      public static function build()
      {
        return new self();
      }
    
    
      /**
       * 返回每次签到要插入的数据
       *
       * @param int $uid 用户id
       * @return array(
       *  'days'   =>  '天数',
       *  'is_sign'  =>  '是否签到,用1表示已经签到',
       *  'sign_time'   =>  '签到时间',
       * );
       */
      public 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;
        $where[] = ['uid', '=', $uid];
        $where[] = ['sign_time', '>', $start_time];
        $where[] = ['sign_time', '<', $end_time];
        $yesterday = UserSignLog::build()->where($where)->find();
        $days = $yesterday['days'];
        if ($days) {
          $days++;
          // 七天签到,大于七天按一天算
          if ($days > 7) {
            $days = 1;
          }
        } else {
          $days = 1;
        }
        return array(
          'days'    => $days,
          'is_sign'  => 1,
          'sign_time'   => time()
        );
      }
    
      /**
       * 用户当天签到的数据
       * @return array 签到信息 is_sign,sign_time 等
       */
      public function todayData()
      {
        $uid = request()->uid;
        $time = time();
        $start_sign_time  = strtotime(date('Y-m-d 0:0:0', $time)) - 1;
        $end_sign_time = strtotime(date('Y-m-d 23:59:59', $time)) + 1;
        $where[] = ['uid', '=', $uid];
        $where[] = ['sign_time', '>', $start_sign_time];
        $where[] = ['sign_time', '<', $end_sign_time];
        $data = UserSignLog::build()->where($where)->find();
        return $data;
      }
    
      /**
       * 积分规则,返回连续签到的天数对应的积分
       * @param int $days 当天应该得的分数
       * @return int 积分
       */
      public function getTodayScores($days)
      {
        switch ($days) {
          case 1:
            return 1;
            break;
          case 2:
            return 2;
            break;
          case 3:
            return 3;
            break;
          case 4:
            return 4;
            break;
          case 5:
            return 5;
            break;
          case 6:
            return 6;
            break;
          case 7:
            return 7;
            break;
          default:
            return 7;
            break;
        }
      }
    
      /**
       * 显示签到列表
       *
       * @param array  $signDays 某月签到的日期 array(1,2,3,4,5,12,13)
       * @param int $year    可选,年份
       * @param int $month   可选,月份
       * @return string 日期列表1
       */
      public function showDays($signDays, $year = '', $month = '')
      {
        $time = time();
        $year = $year ? $year : date('Y', $time);
        $month = $month ? $month : date('m', $time);
        $yearMonth = $year . '-' . $month;
        $year = intval($year);
        $month = intval($month);
        $daysTotal = date('t', mktime(0, 0, 0, $month, 1, $year));
        $now = date('Y-m-d', $time);
        $str = [];
        // sign(0=未签到,1=已签到)
        // time(0=过去,1=现在,2=未来)
        for ($i = 0; $i < $daysTotal; $i++) {
          $j = $i + 1;
          $time = strtotime("$year-$month-$j");
          $someDay = date('Y-m-d', $time);
          // 小于今天的日期样式
          if ($someDay <= $now) {
            // 是否为当天
            if ($someDay == $now) {
              // 当天签到过的
              if (in_array($j, $signDays)) {
                $data['date'] = $yearMonth . '-' . $j;
                $data['sign'] = 1;
                $data['time'] = 1;
                $str[] = $data;
              } else {
                $data['date'] = $yearMonth . '-' . $j;
                $data['sign'] = 0;
                $data['time'] = 1;
                $str[] = $data;
              }
            } else {
              // 签到过的日期
              if (in_array($j, $signDays)) {
                $data['date'] = $yearMonth . '-' . $j;
                $data['sign'] = 1;
                $data['time'] = 0;
                $str[] = $data;
              } else {
                $data['date'] = $yearMonth . '-' . $j;
                $data['sign'] = 0;
                $data['time'] = 0;
                $str[] = $data;
              }
            }
          } else {
            $data['date'] = $yearMonth . '-' . $j;
            $data['sign'] = 0;
            $data['time'] = 2;
            $str[] = $data;
          }
    
        }
        return $str;
      }
    
      /**
       * 获取月签到的天数
       * @return 月签到日期 array(1,2,3,4,5,12,13)
       */
      public function getMonthSign($year = '', $month = '')
      {
        $uid = request()->uid;
        if (empty($year) && empty($month)) {
          $time  = time();
          $year  = date('Y', $time);
          $month = date('m', $time);
        }
    
        $day  = date("t", strtotime("$year-$month"));
        $start_sign_time  = strtotime("$year-$month-1 0:0:0") - 1;
        $end_sign_time = strtotime("$year-$month-$day 23:59:59") + 1;
        $where[] = ['uid', '=', $uid];
        $where[] = ['sign_time', '>', $start_sign_time];
        $where[] = ['sign_time', '<', $end_sign_time];
        $list = UserSignLog::build() ->where($where)->order('sign_time asc')->column('sign_time');
        foreach ($list as $key => $value) {
          $list[$key] = date('j', $value);
        }
        return $list;
      }
    
    }

    来源我是参考php中文网的一篇文章,也踩坑挺多,还是上一下原文链接把链接

  • 相关阅读:
    jar 命令 打包装class文件的文件夹
    快捷下载 sourceForge下的资源
    win7 解决git clone 连接被拒绝—hosts文件过期
    tp_link路由器 重新设置
    gradle研究
    开始玩mondrian
    让eclipse启动时拥有jre
    qt md5加密,base64编码解码
    qt 网络库使用介绍
    c 正则表达式
  • 原文地址:https://www.cnblogs.com/seanpan/p/14814277.html
Copyright © 2011-2022 走看看