微信小程序结合laravel完成签到功能
前端样式未做处理,可将后端数据传至前端进行处理
1.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> </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'>{{max}}天</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>
2wxss
.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;}
3:wxjs:
const app = getApp(); Page({ /** * 页面的初始数据 */ data: { //img_url: config.imgUrl, //图片地址 //签到模块 signNum: 0, //签到数 signState: false, //签到状态 min: 1, //默认值日期第一天1 max: 7, //默认值日期最后一天7 be: 0, //默认倍数 integral: '' }, //签到 bindSignIn(e) { // 获取token var token = wx.getStorageSync('token') // 用户id var userid = wx.getStorageSync('userid') wx.request({ url: 'http://www.yan.com/api/task16/sign', //仅为示例,并非真实的接口地址 data: { userid: userid }, header: { token }, method: 'POST', success(res) { if (res.data.code == 200) { wx.showToast({ title: '签到成功', }) } if (res.data.code == 500) { wx.showToast({ title: '网络异常', }) } if (res.data.code == 501) { wx.showToast({ title: '签到失败', }) } } }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })
laravel 路由:
Route::group(['namespace' => 'Task', 'middleware' => 'jwt'], function () { // 签到 Route::post('task16/sign','task16\TaskController@sign'); //积分明细表 Route::post('task16/details','task16\TaskController@details'); });
laravel控制器:
/* * * 签到*/ public function sign(Request $request) { $userId = $request->input('userid'); $user = WxUserInfo::where('id',$userId)->first(); $day = $user->days; //获取当前的时间 $yearMonthDay = date('Y-m-d',time()); //开启事务 DB::beginTransaction(); try { //将用户id 和 当前签到天数添加到表里面 $sign = \App\Models\week3\Sign::create(['userid'=>$userId,'ymd'=>$yearMonthDay]); $signId = $sign->id; //获取用户上次签到时间 $lastSignDayObj = \App\Models\week3\Sign::select('ymd')->where('userid',$userId)->where('id','<',$signId)->orderBy('id','desc')->limit(1)->first(); //根据上次的签到时间来判断是 断签 ,还是连续签到 ,还是第一次签到 if (empty($lastSignDayObj)){ //不存在 表示第一次签到 $days = 1; $number = BonusPoints::select('number')->where('day',$days)->first(); if ($number){ $score = $number->number; //存在 }else{ //不存在 $score = 7; } $status = '第一次签到,获得积分'.$score; }else{ $lastSignDay = $lastSignDayObj->ymd; //存在 将当前天数的时间戳 和 上次签到的时间戳作比较 $time = strtotime($yearMonthDay) - strtotime($lastSignDay); if ($time >= 24*3600 && $time < 48*3600){ //表示连续签到 签到天数加一 $days = $day +1; $number = BonusPoints::select('number')->where('day',$days)->first(); if ($number){ $score = $number->number; }else{ //不存在 $score = 7; } $status = '连续签到'.$days.'天,获得积分'.$score; }else if ($time >= 48*3600){ //表示断签 和 第一次签到是一样的 $days = 1; $number = BonusPoints::select('number')->where('day',$days)->first(); if ($number){ $score = $number->number; //存在 }else{ //不存在 $score = 7; } $status = '断签后第一次签到,获得积分'.$score; }else{ return ['code'=>500,'msg'=>'网路错误']; } } //记录用户的积分明细 SignUser::create(['userid'=>$userId,'score'=>$score,'type'=>1,'fid'=>$signId.'订单号']); //求用户的积分余额 $scores = SignUser::where('userid',$userId)->sum('score'); //更改用户的连续签到天数 和 积分 WxUserInfo::where('id',$userId)->update(['days'=>$days,'scores'=>$scores]); //事务提交 DB::commit(); return ['code'=>200,'msg'=>'签到成功','data'=>['score'=>$score,'status'=>$status]]; }catch (\Exception $e){ //事务回滚 DB::rollBack(); return ['code'=>501,'msg'=>'签到失败']; } }
相关的模型:用户表
CREATE TABLE `wxuserinfos` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `openid` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `session_key` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `avatarUrl` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '头像', `nickName` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '昵称', `days` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '签到天数', `scores` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '积分', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
<?php namespace App\Models\Task\task15; use Illuminate\Database\Eloquent\Model; class WxUserInfo extends Model { // protected $guarded=[]; public $timestamps=false; protected $table='WxUserInfos'; }
签到记录表
<?php namespace App\Models\week3; use Illuminate\Database\Eloquent\Model; class Sign extends Model { // protected $guarded=[]; public $timestamps=false; protected $table='sign_records'; }
CREATE TABLE `sign_records` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `userid` int(10) NOT NULL COMMENT '用户id', `ymd` date NOT NULL COMMENT '签到时间', `updated_at` datetime DEFAULT NULL, `created_at` datetime DEFAULT NULL COMMENT '签到具体时间', PRIMARY KEY (`id`,`userid`,`ymd`), UNIQUE KEY `唯一` (`userid`,`ymd`) USING BTREE ) ENGINE=MyISAM AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
签到积分规则表:
<?php namespace App\Models\week3; use Illuminate\Database\Eloquent\Model; class BonusPoints extends Model { // protected $table='sign_rule'; protected $guarded=[]; public $timestamps=false; }
CREATE TABLE `sign_rule` ( `id` int(11) NOT NULL AUTO_INCREMENT, `day` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '签到天数', `number` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '积分', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
积分明细表:
<?php namespace App\Models\week3; use Illuminate\Database\Eloquent\Model; class SignUser extends Model { // public $timestamps=false; protected $table='sign_detailed'; protected $guarded=[]; }
EATE TABLE `sign_detailed` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userid` int(11) DEFAULT NULL COMMENT '用户id', `type` tinyint(4) DEFAULT NULL COMMENT '获取积分的类型', `fid` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '积分来源', `score` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '获取到的积分', `time` datetime DEFAULT NULL COMMENT '时间', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;