yite

最近接到一个任务,是给一个线上的小程序添加一个签到的功能,具体功能包括:

1:按7天一轮显示时间

2:只计算连续签到天数,断签后自动归零

3:签到之后可以获得积分,连续签到前六天每天积分为1,六天之后每天积分为3

接到任务后,曾经尝试自己写界面,奈何道行太浅,都被领导否决了,无奈之下,便在网上找一些大神写的界面,最终找到一个还不错的,可惜没有后端,后来在大神同事的帮助下写了一个还算可以的后端功能,总算做出了草稿,具体代码如下,各位将就看一下。

 

前端(前端界面原创链接: https://blog.csdn.net/weixin_42211816/article/details/81985084

wxml

 

<!--pages/signIn/signIn.wxml-->
<view class=\'signIn\'>
  <view class=\'sign-com\'>
    <view class=\'thead\'>
      <view class=\'tt\'>您已连续签到</view>
        <view class=\'mm\'>
          <label class=\'n\'>
            {{signNum}}
          </label></view>  
      <view class=\'pp\'>连续签到7日后每日得3分</view>
    </view>
    <view class=\'modle\'>
        <view class=\'mol\'>
          <view class=\'mol-line\'></view>
            <view class=\'mol-ites\'>
              <view class="ite {{signNum>=min?\'hover\':\'\'}}" data-n=\'{{min}}\'>
                <label class=\'n\'>+{{min<7?1:3}}</label>  <!-- 若签到天数小于7天,则每天签到得1积分,若大于或等于7天,则每天签到得3积分 -->
              </view>
              <view class="ite {{signNum>=min+1?\'hover\':\'\'}}" data-n=\'{{min+1}}\'>
                <label class=\'n\'>+{{min+1<7?1:3}}</label>
              </view>
                <view class="ite {{signNum>=min+2?\'hover\':\'\'}}" data-n=\'{{min+2}}\'>
                <label class=\'n\'>+{{min+2<7?1:3}}</label>
              </view>
              <view class="ite {{signNum>=min+3?\'hover\':\'\'}}" data-n=\'{{min+3}}\'>
                <label class=\'n\'>+{{min+3<7?1:3}}</label>
              </view>
              <view class="ite {{signNum>=min+4?\'hover\':\'\'}}" data-n=\'{{min+4}}\'>
                <label class=\'n\'>+{{min+4<7?1:3}}</label>
              </view>
              <view class="ite {{signNum>=min+5?\'hover\':\'\'}}" data-n=\'{{min+5}}\'>
                <label class=\'n\'>+{{min+5<7?1:3}}</label>
              </view>
              <view class="ite {{signNum>=min+6?\'hover\':\'\'}}" data-n=\'{{max}}\'>
                <label class=\'n\'>+{{min+6<7?1:3}}</label>
              </view>
            </view>
        </view>

        <view class=\'moday\'>
          <label class=\'dd\'>{{min}}天</label>
          <label class=\'dd\'>{{min+1}}天</label>
          <label class=\'dd\'>{{min+2}}天</label>
          <label class=\'dd\'>{{min+3}}天</label>
          <label class=\'dd\'>{{min+4}}天</label>
          <label class=\'dd\'>{{min+5}}天</label>
          <label class=\'dd\'>{{min+6}}天</label>
        </view>

      </view>

    <view class=\'the-btn\'>
      <button type=\'button\' class=\'btn\' bindtap=\'bindSignIn\' data-num="{{signNum}}" disabled=\'{{signState}}\'
        data-min="{{min}}" data-max="{{max}}" data-be="{{be}}">
        签到
      </button>
    </view>

  </view>
</view>

<view class=\'explax\'>
  <view class=\'\'>日期开始:{{min}} </view>
  <view class=\'\'>日期结束:{{max}} </view>
  <view class=\'\'>签到数:{{signNum}}天</view>
  <view class=\'\'>切换周期的倍数:{{be}}</view>
</view>

 

 

wxss

/* pages/signIn/signIn.wxss */
.signIn{ width: 100%; height: auto;}

.sign-com{ width: 100%; height: auto; padding: 0 30rpx; box-sizing: border-box; overflow: hidden; }
.sign-com .thead{ width: 100%; text-align: center; padding: 50rpx 0 35rpx;}
.sign-com .thead .tt{ font-size: 24rpx;}
.sign-com .thead .mm{ margin-top: 10rpx; font-size: 24rpx;}
.sign-com .thead .mm .n{ font-size: 66rpx; margin-right: 25rpx;}
.sign-com .thead .pp{ color: #999; font-size: 24rpx; margin-top: 10rpx;}

.sign-com .modle{ width: 100%; height: 100rpx; margin-top: 10rpx; }
.sign-com .modle .mol{ width: 100%; height: 52rpx; position: relative;  }
.sign-com .mol-line{ width: 100%; height: 4rpx; background-color: #e6e6e6; position: absolute; left: 0; top: 50%; transform: translateY(-50%);}
.sign-com .mol-ites{ width: 100%; height: 100%;position: absolute;}
.mol-ites .ite{ width: 52rpx; height: 52rpx; border-radius: 50%; border: 1px solid #f5f5f5;
 background-color: #fff; box-sizing: border-box;  position: absolute; left: 0; top: 0; z-index: 2;}
.mol-ites .ite .n{ width: 44rpx; height: 44rpx; line-height: 44rpx; text-align: center; border-radius: 50%; background-color: #f5f5f5;position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); font-size: 22rpx;}
.mol-ites .ite::after{ content: ""; width: 80rpx; height: 4rpx; background-color: transparent; 
position: absolute; left: 52rpx; top: 50%; margin-top: -2rpx; z-index: 2;}
.mol-ites .ite:last-of-type::after{ width: 0;}
.mol-ites .ite:nth-of-type(2){ left: 107rpx;}
.mol-ites .ite:nth-of-type(3){ left: 214rpx;}
.mol-ites .ite:nth-of-type(4){ left: 321rpx;}
.mol-ites .ite:nth-of-type(5){ left: 428rpx;}
.mol-ites .ite:nth-of-type(6){ left: 535rpx;}
.mol-ites .ite:nth-of-type(7){ left: 642rpx;}
.mol-ites .ite.hover{ border-color: #ff614a;}
.mol-ites .ite.hover .n{ background-color: #ff614a; color: #fff;}
.mol-ites .ite.hover::after{ background-color: #ff614a; }
.moday{ width: 100%; height:40rpx; overflow: hidden; position: relative; margin-top:20rpx;}
.moday .dd{ width: 52rpx; height: 40rpx; line-height: 1; text-align: center; font-size: 22rpx;
 position: absolute; left: 0; bottom: 0;}
.moday .dd:nth-of-type(2){ left: 107rpx;}
.moday .dd:nth-of-type(3){ left: 214rpx;}
.moday .dd:nth-of-type(4){ left: 321rpx;}
.moday .dd:nth-of-type(5){ left: 428rpx;}
.moday .dd:nth-of-type(6){ left: 535rpx;}
.moday .dd:nth-of-type(7){ left: 642rpx;}

.the-btn{ margin: 50rpx 0;}
.the-btn .btn{ background-color: #ff614a; color: #fff;}
.the-btn.signed .btn{ background-color: rgba(153, 153, 153, 0.61); }

.explax{ padding: 0 30rpx; font-size: 28rpx; color: #666;}

 

js

 

// pages/signIn/signIn.js
//获取应用实例
const app = getApp();

Page({

  /**
   * 页面的初始数据
   */
  data: {
    //img_url: config.imgUrl, //图片地址

    //签到模块
    signNum: 1,  //签到数 
    signState: false, //签到状态
    min: 1,  //默认值日期第一天1
    max: 7,  //默认值日期最后一天7
    be: 0,  //默认倍数
 
  },

  onLoad: function (options) {
    let _this = this;

    var a = wx.getStorageSync("userInfo");
    a ? this.setData({
      uInfo: a
    }) : wx.showModal({
      title: "提示",
      content: "您未登陆,请先登陆!",
      success: function (t) {
        if (t.confirm) {
          var a = encodeURIComponent("/sqtg_sun/pages/public/pages/myorder/myorder?id=0");
          app.reTo("/sqtg_sun/pages/home/login/login?id=" + a);
        } else t.cancel && app.lunchTo("/sqtg_sun/pages/home/index/index");
      }
    });

    //接收后端数据
   this.getSignInfo();

  },

  getSignInfo(){
    let that = this;

    app.ajax({
      url: "Signin|getSignInfo",
      data: {
        id:this.data.uInfo.id
        
      },
      success: function (res) {
        console.log(\'连接成功\')
        that.setData({
          signNum: res.data.signNum,
          min: res.data.min //接收到的数据,页面调用的是这里的数据
        })
      },
      // fail: function (res) {
      //   console.log("连接失败")
      // }
    })

  },

  //签到
  bindSignIn(e) {
    var that = this,
      num = e.currentTarget.dataset.num;
    num++

    app.ajax({
      url: "Signin|sign",
      data: {
        id: this.data.uInfo.id

      },
      success: function (res) {

            that.setData({
              signNum: num,
              // signState: false //点击后是否继续允许点击,true为不允许,false为允许,正式使用时应为true
            })

            var min = e.currentTarget.dataset.min,
              max = e.currentTarget.dataset.max,
              be = e.currentTarget.dataset.be;

            if (num % 7 == 0) {
              be += 1;
              that.setData({
                be: be
              })
            }

            if (num == 7 * be + 1) {
              that.setData({
                min: 7 * be + 1,
                max: 7 * be + 7
              })
            }

        // wx.showToast({
        //   icon: \'success\',
        //   title: res.msg,
        // })

        console.log(\'连接成功1\')
        that.setData({
          // signNum: res.data,
          // min: res.data, //接收到的数据,页面调用的是这里的数据
          // signState: res.data//点击后是否继续允许点击,true为不允许,false为允许,正式使用时应为true
        })
      },
      // fail: function (res) {
      //   console.log("连接失败")
      // }
    })

  
    

  },


})

 

 

 

后端(PHP,使用thinkphp框架)

 

 

<?php

namespace app\api\controller;


use app\base\controller\Api;
use app\model\User;
use think\Db;

class Signin extends Api
{


    public function getSignInfo($id)
    {

//        此处的$id 等价于 $id=$_POST[\'id\'];

        //php获取今日开始时间戳和结束时间戳
        $today_start = mktime(0, 0, 0, date(\'m\'), date(\'d\'), date(\'Y\'));
        $today_end = mktime(0, 0, 0, date(\'m\'), date(\'d\') + 1, date(\'Y\')) - 1;

        //php获取昨日起始时间戳和结束时间戳
        $yesterday_start = mktime(0, 0, 0, date(\'m\'), date(\'d\') - 1, date(\'Y\'));
        $yesterday_end = mktime(0, 0, 0, date(\'m\'), date(\'d\'), date(\'Y\')) - 1;

        $user = User::get([\'id\' => $id]);//判断id是否存在


            //查询上一次签到时间
            $lastdata = Db::table(\'rs_signin\')
                ->where(\'ids\', \'=\', $id)
                ->where(\'time\',\'>=\',$yesterday_start)
                ->where(\'time\',\'<=\',$yesterday_end)
                ->find();

            if (!$lastdata) {

                $signNum = Db::table(\'rs_signin\')
                    ->where(\'ids\', \'=\', $id)
                    ->where(\'time\',\'>=\',strtotime(date(\'Y-m-d 00:00:00\')))
                    ->count();

            }else{

                $signNum = Db::table(\'rs_signin\')
                    ->where(\'ids\', \'=\', $id)
                    ->where(\'time\',\'>=\',$user[\'firsttime\'])
                    ->count();

            }

            if ($signNum<7){
                $min = 1;
            }elseif($signNum>=7){
                $min = $signNum-5;
            }

        success_json([\'signNum\'=>$signNum,\'min\'=>$min]);


            if ($lastdata >= $yesterday_start && $lastdata <= $yesterday_end) { //昨天有签到的情况

                //算出连续签到天数并输出值
//                    print_r($data);
//        return json($data); //thinkphp原先的发送信息的方法,这个版本被更改过,变成了下面的success_json()方法

                $dates = date(\'d\', time()) - date(\'d\', $data); //用今天的时间减去初始签到时间,得到中间相差的日数,即连续签到时间

                success_json($dates); //成功时的操作(输出连续签到天数),此方法相当于return,应放在最后执行

            } elseif ($lastdata < $yesterday_start) { //昨天没有签到的情况

//                $counts = $integrals + 1;

                //修改初始签到时间
                $time = time(); //time值为今天签到时的时间戳
                $data = Db::table(\'rs_signin\')
                    ->where(\'ids\', \'=\', 82)
                    ->update([\'time\' => $time]);//thinkphp的查询

            }




    } //getSignInfo()方法结束



    //签到
    public function sign($id)
    {


        //php获取今日开始时间戳和结束时间戳
        $today_start = mktime(0, 0, 0, date(\'m\'), date(\'d\'), date(\'Y\'));
        $today_end = mktime(0, 0, 0, date(\'m\'), date(\'d\') + 1, date(\'Y\')) - 1;

        //php获取昨日起始时间戳和结束时间戳
        $yesterday_start = mktime(0, 0, 0, date(\'m\'), date(\'d\') - 1, date(\'Y\'));
        $yesterday_end = mktime(0, 0, 0, date(\'m\'), date(\'d\'), date(\'Y\')) - 1;





        $issign = Db::table(\'rs_signin\')
            ->where(\'ids\', \'=\', $id)
            ->where(\'time\', \'>=\', $today_start)
            ->where(\'time\', \'<=\', $today_end)
            ->find();//判断今天是否已签到过



        if ($issign) { //如果今天已经签到过,便阻止点击并终止操作

            $signs = User::where(\'id\',$id)->column(\'sign\');
            error_json(\'今日已签到\');


            return;

        }


        $id_select = Db::table(\'rs_signin\')
            ->where(\'ids\', \'=\', $id)
            ->where(\'time\', \'>=\', $yesterday_start)
            ->where(\'time\', \'<=\', $yesterday_end)
            ->find();//判断昨天是否已签到过

        //查询积分
        $integrals = User::where(\'id\', \'=\', $id)->find();

        $integrals = $integrals[\'integral\'];
//        print_r($integrals);

        if ($id_select) { //如果昨天已经签到过,便算出今天签到之后与初始签到日之间的日数差,即连续签到天数



            $member = User::where(\'id\', \'=\', $id)->find();

//            $dates = date(\'d\', time()) - date(\'d\', $data); //用今天的时间减去初始签到时间,得到中间相差的日数,即连续签到时间
            $diff = date_diff((new \DateTime(date(\'Y-m-d 00:00:00\',$member[\'firsttime\']))), (new \DateTime(date(\'Y-m-d 00:00:00\'))));


            $day = $diff->days;

            if ($day+1 >= 7) {
                $integral_count = 3;
            } else {
                $integral_count = 1;
            }

            $counts = $integrals + $integral_count;

            Db::table(\'rs_signin\')->insert([\'ids\' => $id, \'time\' => time(), \'integral\' => $integral_count]);

            User::update([\'integral\' => $counts],[\'id\'=>$id]);


//            print_r($day);

        } else { //如果昨天没签到过,便更改user表中firsttime字段的值,并新增一条记录进rs_signin表中
//            print_r(\'----\');

            $counts = $integrals + 1;


            User::update([\'firsttime\' => strtotime(date(\'Y-m-d 00:00:00\')),\'integral\'=>$counts],[\'id\'=>$id]);



            Db::table(\'rs_signin\')->insert([\'ids\' => $id, \'time\' => time(), \'integral\' => 1]);


        }

    }


}//类结束

 

 

最终效果如下:

 

 

分类:

技术点:

相关文章: