Html手机端上实现每日签到的功能,感谢GitHub上的这两位的贡献 ( ^ _ ^ )
签到 https://github.com/zhicaizhu123/qiandao
日历 https://github.com/rxhluck/signDate
上图镇楼:
![](https://img.haomeiwen.com/i4445477/cc3d5bef80db6da7.png)
![](https://img.haomeiwen.com/i4445477/e0ad50aae32552f2.png)
1.思路
签到---中主要是用swiper实现上下滑动切换
日历---中主要是计算了并制作table的当月日历,还能上下切换
2.html界面
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="qiandao">
<div class="qiandao-content">
<div class="qiandao-icon">
<div class="hangxian">
<span></span>
</div>
<div class="icon-circle">
<img class="icon-avatar" src="{{$user->avatar}}">
</div>
<div class="hangxian">
<span></span>
</div>
</div>
<div class="qiandao-text">
<p>{{$user->name}}</p>
</div>
<div class="qiandao-btn">
@if($countSigns == 0)
<a href="javascript:;" class="qd-btn">点击签到</a>
@else
<a href="javascript:;" class="qd-btn disabled">已签到</a>
@endif
<div class="hasqiandao">
签到成功
<span class="caret"></span>
</div>
</div>
</div>
<div class="qiandao-desc">
<p>每个好习惯都始于点滴积累</p>
<p>加入党员之家,蜕变更好的自己。</p>
</div>
<div class="qiandao-info">
<ul>
<li class="time continue">
<span class="day"><em>{{$f_countsign}}</em>天</span>
<span class="qiandao-tip">连续签到</span>
</li>
<li class="time sum">
<span class="day"><em>{{$countMonth}}</em>天</span>
<span class="qiandao-tip">当月签到</span>
</li>
<li class="time read">
<span class="day"><em>{{$countYear}}</em>天</span>
<span class="qiandao-tip">共计签到</span>
</li>
</ul>
</div>
</div>
</div>
<div class="swiper-slide">
<div class="qiandao">
<div class="qiandao-detail qiandao-content">
<div class="qiandao-icon">
<div class="hangxian">
<span></span>
</div>
<div class="icon-circle">
<img class="icon-avatar" src="{{$user->avatar}}">
</div>
<div class="hangxian">
<span></span>
</div>
</div>
<div class="qiandao-text">
<p>{{$user->name}}</p>
</div>
<div class="qiandao-btn">
@if($countSigns == 0)
<a href="javascript:;" class="qd-btn">点击签到</a>
@else
<a href="javascript:;" class="qd-btn disabled">已签到</a>
@endif
<div class="hasqiandao">
签到成功
<span class="caret"></span>
</div>
</div>
</div>
<div class="qiandao-calendar">
<div id="signDate">
<div class="monthAndyear">
<span class="date-left"></span>
<span class="date-time"></span>
<span class="date-right"></span>
</div>
<table></table>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="jiantou"></div>
<div class="jiantou2"></div>
<link rel="stylesheet" href="{{url('packages/common/Swiper-3.3.1/css/swiper.min.css')}}">
<link rel="stylesheet" href="{{url('packages/common/signDate/css/signDate.css')}}"/>
<link rel="stylesheet" href="{{url('/packages/common/iosOverlay/css/iosOverlay.css')}}">
<script src="{{url('packages/common/signDate/js/Calendar.js')}}"></script>
<script src="{{url('packages/common/Swiper-3.3.1/js/swiper.min.js')}}"></script>
<script src="packages/common/iosOverlay/js/iosOverlay.js"></script>
3.Js实现
主要是签到点击,历史签到获取,日历切换3部分
$(function () {
var isSwiper = true;
var calendar = new DuCalendar('signDate');
calendar.init();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$(".qiandao-btn").on("click", ".qd-btn", function (e) {
e.preventDefault();
if (!$(".qd-btn").hasClass("disabled")) {
$.ajax({
method: "POST",
url: "/sign_in",
dataType: "json",
success: function (data) {
if (data.success) {
$(".continue > span > em").html(parseInt($(".continue > span > em").html()) + 1);
$(".sum > span > em").html(parseInt($(".sum > span > em").html()) + 1);
$(".read > span > em").html(parseInt($(".read > span > em").html()) + 1);
$(".qd-btn").addClass("disabled").html("已签到");
var tip = $(".qd-btn").parent().find(".hasqiandao");
tip.addClass("active");
var timeout = setTimeout(function () {
tip.removeClass("active");
}, 2000);
} else {
alert(data.msg);
}
},
error: function (xhr, type) {
alert("未连接到服务器");
}
});
} else {
return;
}
});
var myswiper = new Swiper('.swiper-container', {
direction: 'vertical',
height: window.innerHeight,
onSlideChangeEnd: function (swiper) {
if (swiper.isEnd) {
$(".jiantou").hide();
$(".jiantou2").show();
if (isSwiper) {
var overlay = iosOverlay({
text: "Loading",
duration: 20e3,
icon: "/packages/common/iosOverlay/img/load.gif"
});
$.ajax({
method: "POST",
data: {month: calendar.month},
url: "/sign_calendar",
dataType: "json",
success: function (data) {
if (data.success) {
var signs = data.data;
var ids = "#day_8888";
for (var i = 0; i < signs.length; i++) {
var date = new Date(signs[i].created_at);
ids = ids + " ,#day_" + date.getDate();
}
$(ids).remove("today");
$(ids).addClass("today");
overlay.update({
icon: "/packages/common/iosOverlay/img/check.png",
text: data.msg
});
isSwiper = false;
} else {
overlay.update({
icon: "/packages/common/iosOverlay/img/cross.png",
text: data.msg
});
}
},
error: function (xhr, type) {
overlay.update({
icon: "/packages/common/iosOverlay/img/cross.png",
text: "服务器连接错误"
});
}
});
}
} else {
$(".jiantou2").hide();
$(".jiantou").show();
}
},
});
});
日历切换获取历史数据rxhluck写的已经封装的差不多了,扩展一下就好
//初始化属性数据
DuCalendar.prototype.getData = function () {
var overlay = iosOverlay({
text: "Loading",
duration: 20e3,
icon: "/packages/common/iosOverlay/img/load.gif"
});
$.ajax({
method: "POST",
data: {month: this.month},
url: "/sign_calendar",
dataType: "json",
success: function(data){
if(data.success){
var signs = data.data;
var ids = "#day_8888";
for (var i = 0;i<signs.length;i++){
var date = new Date(signs[i].created_at);
ids = ids+" ,#day_"+ date.getDate();
}
$(ids).remove("today");
$(ids).addClass("today");
overlay.update({
icon: "/packages/common/iosOverlay/img/check.png",
text: data.msg
});
}else{
overlay.update({
icon: "/packages/common/iosOverlay/img/cross.png",
text: data.msg
});
}
},
error: function(xhr, type){
overlay.update({
icon: "/packages/common/iosOverlay/img/cross.png",
text: "服务器连接错误"
});
}
});
}
//左键
this.leftBtn.onclick=function(){
_tag--
var dateObj;
if(_tag == 0){
dateObj = new Date();
}else{
var y = parseInt(This.year);
var m = parseInt(This.month)-1;
if(m<0){
m = 11 ;
y--;
}
dateObj = new Date(y,m,1);
}
This.addProDate(dateObj);
This.showType();
This.addTable();
This.getData();
}
//右键
this.rightBtn.onclick=function(){
_tag++
var dateObj;
if(_tag == 0){
dateObj = new Date();
}else{
var y = parseInt(This.year);
var m = parseInt(This.month)+1;
if(m>11){
m = 0;
y++;
}
var dateObj = new Date(y,m,1);
}
This.addProDate(dateObj);
This.showType();
This.addTable();
This.getData();
}
4.后端Laravel写接口
界面初始化
/***
* 每日签到查询
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function sign(){
$title = '每日签到';
$user = session('user');
$user = Users::find($user->id);
if($user->apply_state != 5){
return redirect()->route('returnBlade', ['您还不是党员,需要先进行报道。', 'dybd']);
}
$f_countsign = DB::select('SELECT f_countsign_days(:id,:date) as countsign', ['id' => $user->id,'date'=> date("Y-m-d ", time())]);
$f_countsign = $f_countsign[0]->countsign;
$countYear = Signs::where('users_id','=',$user->id)->whereBetween('created_at', [
date("Y",time())."-01-01 00:00:00",
date("Y",strtotime("+1 year"))."-12-31 23:59:59"
])->count();
$countMonth = Signs::where('users_id','=',$user->id)->whereBetween('created_at', [
date("Y-m-01",time())." 00:00:00",
date("Y-m-t",time())." 23:59:59"
])->count();
$countSigns = Signs::where('users_id','=',$user->id)->whereBetween('created_at', [
date("Y-m-d",time()),
date("Y-m-d",strtotime("+1 day"))
])->count();
if($countSigns>0){
$f_countsign++;
}
return view('mobile.sign', [
'title'=>$title,
'user'=>$user,
'f_countsign'=>$f_countsign,
'countSigns'=>$countSigns,
'countYear'=>$countYear,
'countMonth'=>$countMonth]);
}
签到Ajax
/***
* 每日签到
* @return array
*/
public function sign_in(){
$user = session('user');
$countSigns = Signs::where('users_id','=',$user->id)->whereBetween('created_at', [
date("Y-m-d",time()),
date("Y-m-d",strtotime("+1 day"))
])->count();
if($countSigns == 0){
DB::transaction(function () use ($user) {
$integral = new Integrals();
$integral->name = config('bgjd.sign')[0]['name'];
$integral->integral = config('bgjd.sign')[0]['integral'];
$integral->users_id = $user->id;
$integral->save();
$sign = new Signs();
$sign->name = config('bgjd.sign')[0]['name'];
$sign->users_id = $user->id;
$sign->integrals_id = $integral->id;
$sign->save();
});
$res = ['success'=>true,'msg'=>'签到成功'];
}else{
$res = ['success'=>false,'msg'=>'已签到'];
}
return $res;
}
历史月份的签到数据
/***
* 历史签到查询
* @param Request $request
* @return array
*/
public function sign_calendar(Request $request){
$data = $request->all();
$rules = [
'month' => 'required'
];
$messages = [
'month.required' => '月份必须填写'
];
$validator = Validator($data, $rules, $messages);
if ($validator->passes()){
$user = session('user');
$Signs = Signs::where('users_id','=',$user->id)->whereBetween('created_at', [
date("Y",time())."-".($data['month']+1)."-01 00:00:00",
date("Y",time())."-".($data['month']+1)."-".date("t",time())." 23:59:59"
])->get();
if($Signs){
$res = ['success'=>true,'msg'=>($data['month']+1).'月签到','data'=>$Signs];
}else{
$res = ['success'=>false,'msg'=>'已签到'];
}
}else{
$res = ['success'=>false,'msg'=>$validator->messages()->first()];
}
return $res;
}
5.连续签到数据库方法
这个还是比较关键的,所以提一下
BEGIN
DECLARE days INT;
DECLARE flag INT;
DECLARE previous_day DATE;
SET days := 0;
SET flag := 1;
SET previous_day := DATE_SUB(end_time,INTERVAL 1 DAY);
WHILE flag>0 DO
SELECT COUNT(DISTINCT(DATE(created_at))) INTO flag FROM signs
WHERE users_id = id
AND DATE(created_at) = previous_day ;
IF flag > 0 THEN
SET days := days + 1;
SET previous_day := DATE_SUB(previous_day,INTERVAL 1 DAY);
END IF;
END WHILE;
RETURN days;
END
基本这样就全部完成了,Css就不附上了。
网友评论