本文为原创作品,引用请注明出处,欢迎转载。
生活中有各种可以打卡的app,例如背单词打卡什么的,本人觉得很有意思,于是本人在大二时做了一款诚信状打卡的微信小程序,这里讲述一下编写的过程。
先说一下开发环境:用的是微信web开发工具开发的,后台采用了Bmob后台,比较方便。
话不多说,直接上代码,里面也有挺多的注释,以防自己忘记,当然各位如果直接复制过去肯定不能有当前的效果,注意后台数据的交互,不过做一个界面还是没有问题的。
Calendar.wxml 页面文件
页面上显示出来的东西,布局上主要是一个年月栏、上一个月和下一个月的按钮;然后是星期栏,就是日一二三四五六,然后就是每个月的日期,注意每个月的前面可能有空的地方。这里面用wx:if标签来区分当前日期有无打卡的情况。
{{cur_year || "--"}} 年 {{cur_month || "--"}} 月
{{item}}
{{days[j+k].date}}
{{days[j+k].date}}
截至目前,你已坚持打卡
{{count}}
天
请再接再厉,继续努力
Calendar.wxss 样式文件
这个就是让页面显示得更好看一点了,里面有些属性更改之后可能会导致整个页面的格式变得很乱,说明自己的功夫还是不到家。
/* pages/Calendar/Calendar.wxss */
/* 打卡日历 */
.all{
margin-top: 20rpx;
}
.all .bar{
display: flex;
flex-direction: row;
justify-content: space-between;
margin: 30rpx 20rpx;
padding: 10rpx;
}
.all .bar image{
width: 50rpx;
height: 50rpx;
}
.all .week{
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 20rpx;
padding-left: 40rpx;
padding-right: 40rpx;
margin: 20rpx;
border-radius: 10px;
background-color: #acd;
}
.all .days{
margin: 20rpx;
padding: 10rpx;
border-radius: 10px;
background-color: #acd;
}
.all .columns{
display: flex;
flex-direction: column;
justify-content: space-between;
}
.all .columns .rows{
display: flex;
flex-direction: row;
justify-content: space-between;
}
.all .columns .rows .cell{
width: 84rpx;
height: 88rpx;
margin: 3rpx;
text-align: center;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
}
.count .daynumber{
display: flex;
flex-direction: row;
justify-content: center;
}
.count .daynumber .day{
margin-top: 50rpx;
}
.count{
margin: 20rpx;
padding: 30rpx;
display: flex;
text-align: center;
border-radius: 10px;
flex-direction: column;
justify-content: center;
background-color: #acd;
align-items: center;
}
.count .number{
color: red;
font-size: 60rpx;
background-color: #fff;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
margin: 20rpx;
}
.count text{
margin: 10rpx;
}
Calendar.js JavaScript文件
js文件里面涉及到Bmob的操作,这里就不多说Bmob的操作了,感兴趣的同学可以去参考它的官方文档。
然后里面主要是对上一个月、下一个月的点击函数进行处理,以及对某年某月的每个日期进行初始化(尤其是每个月前的可能有的几个空格进行了处理),然后就是判断某个日期在后台数据中是否有打卡。
// pages/Calendar/Calendar.js
//打卡日历页面
var util = require('../../utils/util.js');
var Bmob = require('../../utils/bmob.js');
Page({
/**
* 页面的初始数据
*/
data: {
objectId:'',
days:[],
signUp:[],
cur_year:0,
cur_month:0,
count:0
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.setData({objectId : options.objectId});
//获取当前年月
const date = new Date();
const cur_year = date.getFullYear();
const cur_month = date.getMonth() + 1;
const weeks_ch = ['日', '一', '二', '三', '四', '五', '六'];
this.calculateEmptyGrids(cur_year, cur_month);
this.calculateDays(cur_year, cur_month);
//获取当前用户当前任务的签到状态
this.onGetSignUp();
this.setData({
cur_year,
cur_month,
weeks_ch
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
// 获取当月共多少天
getThisMonthDays:function(year, month){
return new Date(year, month, 0).getDate()
},
// 获取当月第一天星期几
getFirstDayOfWeek:function(year, month) {
return new Date(Date.UTC(year, month - 1, 1)).getDay();
},
// 计算当月1号前空了几个格子,把它填充在days数组的前面
calculateEmptyGrids:function(year, month) {
var that = this;
//计算每个月时要清零
that.setData({days:[]});
const firstDayOfWeek = this.getFirstDayOfWeek(year, month);
if (firstDayOfWeek > 0) {
for (let i = 0; i < firstDayOfWeek; i++) {
var obj = {
date:null,
isSign:false
}
that.data.days.push(obj);
}
this.setData({
days:that.data.days
});
//清空
} else {
this.setData({
days: []
});
}
},
// 绘制当月天数占的格子,并把它放到days数组中
calculateDays:function(year, month) {
var that = this;
const thisMonthDays = this.getThisMonthDays(year, month);
for (let i = 1; i <= thisMonthDays; i++) {
var obj = {
date: i,
isSign: false
}
that.data.days.push(obj);
}
this.setData({
days:that.data.days
});
},
//匹配判断当月与当月哪些日子签到打卡
onJudgeSign:function(){
var that = this;
var signs = that.data.signUp;
var daysArr = that.data.days;
for (var i=0; i < signs.length;i++){
var current = new Date(signs[i].date.replace(/-/g, "/"));
var year = current.getFullYear();
var month = current.getMonth()+1;
var day = current.getDate();
day = parseInt(day);
for (var j = 0; j < daysArr.length;j++){
//年月日相同并且已打卡
if (year == that.data.cur_year && month == that.data.cur_month && daysArr[j].date == day && signs[i].isSign == "今日已打卡"){
daysArr[j].isSign = true;
}
}
}
that.setData({days:daysArr});
},
// 切换控制年月,上一个月,下一个月
handleCalendar:function(e) {
const handle = e.currentTarget.dataset.handle;
const cur_year = this.data.cur_year;
const cur_month = this.data.cur_month;
if (handle === 'prev') {
let newMonth = cur_month - 1;
let newYear = cur_year;
if (newMonth < 1) {
newYear = cur_year - 1;
newMonth = 12;
}
this.calculateEmptyGrids(newYear, newMonth);
this.calculateDays(newYear, newMonth);
this.onGetSignUp();
this.setData({
cur_year: newYear,
cur_month: newMonth
})
} else {
let newMonth = cur_month + 1;
let newYear = cur_year;
if (newMonth > 12) {
newYear = cur_year + 1;
newMonth = 1;
}
this.calculateEmptyGrids(newYear, newMonth);
this.calculateDays(newYear, newMonth);
this.onGetSignUp();
this.setData({
cur_year: newYear,
cur_month: newMonth
})
}
},
//获取当前用户该任务的签到数组
onGetSignUp:function(){
var that = this;
var Task_User = Bmob.Object.extend("task_user");
var q = new Bmob.Query(Task_User);
q.get(that.data.objectId, {
success: function (result) {
that.setData({
signUp : result.get("signUp"),
count : result.get("score")
});
//获取后就判断签到情况
that.onJudgeSign();
},
error: function (object, error) {
}
});
}
})
Calendar.json json文件
这里仅仅是改变了导航栏上的标题文字
{
"navigationBarTitleText": "打卡日历"
}
做这个的时候还是废了一番功夫的,欢迎大家来试用一下我写的微信小程序。
以下是微信小程序山东大学唐仲英爱心社的链接。
如果出现引入错误或者需要完整项目的资源,可以前往github上下载,记得给个星星山东大学唐仲英爱心社