最近接到一個任務,是給一個線上的小程序添加一個簽到的功能,具體功能包括:
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]); } } }//類結束
最終效果如下: