日历组件
<template>
<!-- 打卡日历页面 -->
<view class='all'>
<view class="bar">
<!-- 上一个月 -->
<view class="previous" @click="handleCalendar(0)">
<button class="barbtn" v-if="langType=='ch'">上一月</button>
<button class="barbtn" v-else>Last</button>
</view>
<!-- 显示年月 -->
<view class="date">{{cur_year || "--"}} 年 {{cur_month || "--"}} 月</view>
<!-- 下一个月 -->
<view class="next" @click="handleCalendar(1)">
<button class="barbtn" v-if="langType=='ch'">下一月</button>
<button class="barbtn" v-else>Next</button>
</view>
</view>
<!-- 显示星期 -->
<view class="week" v-if="langType=='ch'">
<view v-for="(item,index) in weeks_ch" :key="index">{{item}}</view>
</view>
<view class="week" v-else>
<view v-for="(item,index) in weeks_en" :key="index">{{item}}</view>
</view>
<view class="myDateTable">
<view v-for="(item,j) in days" :key="j" class='dateCell'>
<view v-if="item.date==undefined||item.date == null" class='cell'>
<text :decode="true"> </text>
</view>
<view v-else>
<!-- 已签到日期 -->
<view v-if="item.isSign == true" class='cell yellow' style="background: #ffde21;">
<text>{{item.date}}</text>
</view>
<!-- 漏签 -->
<!-- <view @click="clickSignUp(item.date,0)" class="cell redColor bgGray"
v-else-if="cur_year>
小程序不兼容这个 v-else-if="(new Date(cur_year+'-'+cur_month+'-'+item.date))<(new Date())">
<text>{{item.date}}</text>
</view> -->
<!-- 今日未签到-->
<view @click="clickSignUp(item.date)" class="cell white bg-red" v-else-if="item.date==today&&cur_month==toMonth&&cur_year==toYear">
<text>今日</text>
</view>
<!-- 当前日期之后 -->
<view class="whiteColor cell" v-else>
<text>{{item.date}}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
days: [],
SignUp: [],
cur_year: 0,
cur_month: 0,
today: parseInt(new Date().getDate()),
toMonth: parseInt(new Date().getMonth() + 1),
toYear: parseInt(new Date().getFullYear()),
weeks_ch: ['日', '一', '二', '三', '四', '五', '六'],
weeks_en: ['Sun', 'Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat']
};
},
props: {
sendYear: {
type: Number,
default: new Date().getFullYear()
},
sendMonth: {
type: Number,
default: new Date().getMonth() + 1
},
dataSource: {
type: Array,
default: () => {
return []
}
},
langType: {
type: String,
default: "ch"
},
},
created() {
this.cur_year = this.sendYear;
this.cur_month = this.sendMonth;
this.SignUp = this.dataSource;
this.calculateEmptyGrids(this.cur_year, this.cur_month);
this.calculateDays(this.cur_year, this.cur_month);
this.onJudgeSign();
},
watch: {
dataSource: 'onResChange',
},
methods: {
getThisMonthDays(year, month) {
return new Date(year, month, 0).getDate()
},
getFirstDayOfWeek(year, month) {
return new Date(Date.UTC(year, month - 1, 1)).getDay();
},
calculateEmptyGrids(year, month) {
this.days = [];
const firstDayOfWeek = this.getFirstDayOfWeek(year, month);
if (firstDayOfWeek > 0) {
for (let i = 0; i < firstDayOfWeek; i++) {
var obj = {
date: null,
isSign: false
}
this.days.push(obj);
}
}
},
calculateDays(year, month) {
const thisMonthDays = this.getThisMonthDays(year, month);
for (let i = 1; i <= thisMonthDays; i++) {
var obj = {
date: i,
isSign: false
}
this.days.push(obj);
}
},
onResChange(newD, oldD) {
this.SignUp = newD;
this.onJudgeSign();
},
onJudgeSign() {
var signs = this.SignUp;
var daysArr = this.days;
for (var i = 0; i < signs.length; i++) {
var current = new Date(signs[i].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 == this.cur_year && month == this.cur_month && daysArr[j].date == day) {
daysArr[j].isSign = true;
}
}
}
this.days = daysArr;
},
handleCalendar(type) {
const cur_year = parseInt(this.cur_year);
const cur_month = parseInt(this.cur_month);
var newMonth;
var newYear = cur_year;
if (type === 0) {
newMonth = cur_month - 1;
if (newMonth < 1) {
newYear = cur_year - 1;
newMonth = 12;
}
} else {
newMonth = cur_month + 1;
if (newMonth > 12) {
newYear = cur_year + 1;
newMonth = 1;
}
}
this.calculateEmptyGrids(newYear, newMonth);
this.calculateDays(newYear, newMonth);
this.cur_year = newYear;
this.cur_month = newMonth;
this.SignUp = [];
this.$emit('dateChange',this.cur_year+"-"+this.cur_month);
},
clickSignUp(date, type) {
this.onJudgeSign();
}
}
}
</script>
<style>
.all .bar {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 10rpx;
}
.bar .barbtn {
height: 30px;
line-height: 30px;
font-size: 12px;
}
.all .week {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 20rpx;
padding-left: 40rpx;
padding-right: 40rpx;
border-radius: 10px;
background-color: #fff;
}
.myDateTable {
margin: 2.5vw;
border-radius: 10px;
background: #fff;
}
.myDateTable .dateCell {
width: 11vw;
padding: 1vw;
display: inline-block;
text-align: center;
font-size: 16px;
}
.dateCell .cell {
display: flex;
border-radius: 50%;
height: 9vw;
justify-content: center;
align-items: center;
}
.greenColor {
color: #01b90b;
font-weight: bold;
}
.bgWhite {
background-color: #fff;
}
.bgGray {
background-color: rgba(255, 255, 255, 0.42);
}
.bgBlue {
font-size: 14px;
background-color: #4b95e6;
}
.redColor {
color: #ff0000;
}
.TipArea{
word-break:break-all;
word-wrap:break-word;
font-size: 14px;
padding: 10px;
}
.impTip{
display: inline-block;
color: #ff0000;
}
</style>
签到页面
<template>
<view class="w100 min100 sign pb-40">
<view style="padding:120rpx 0 40rpx; width: 100%;height: 340rpx;background: url(../../static/sign-top.png) no-repeat center center;background-size: contain;">
<view class="gray-2 text-center">已连续签到</view>
<view class="text-center mt-30 "><text style="font-size: 50rpx;margin-right: 10rpx;" class="yellow bold">{{sumCount}}</text>
天</view>
</view>
<view class="bg-white mlr-20 radius-10 ptb-20">
<model-calendar :sendYear="toYear" :sendMonth="toMonth" :dataSource="signData" :totalNum="sumCount" @dateChange="getRecord">
</model-calendar>
<view class="plr-40">
<u-button type="warning" @click="clickSign" :disabled="status" class="w100">{{!status?'立即签到':'今日已签到'}}</u-button>
</view>
</view>
<view class='count'>
<view class="bold">连续签到有机会领取以下奖励:</view>
<view class="mt-20 mb-6">连续 <text class="yellow">7</text>天,奖励积分<text class="yellow">{{set.signin_day_seven}}</text>分;</view>
<view>连续<text class="yellow">15</text>天,奖励积分<text class="yellow">{{set.signin_day_fifteen}}</text>
分</view>
</view>
</view>
</template>
<script>
import modelCalendar from '@/components/Calendar.vue';
export default {
data() {
return {
toYear: parseInt(new Date().getFullYear()),
toMonth: parseInt(new Date().getMonth() + 1),
sumCount: 0,
signData: [],
status: false,
set: {},
month: '',
};
},
components: {
modelCalendar
},
onLoad() {
this.init()
this.setSign()
},
methods: {
init() {
this.$http('/addons/ddshop/signin/signin_record', {
month: this.month
}).then(data => {
this.signData = data.signin_record
this.sumCount = data.succession_signin
this.status = data.is_signin_day
})
},
setSign() {
this.$http('/addons/ddshop/signin/signin_set').then(data => {
this.set = data.signin_set
})
},
getRecord(data) {
this.month = data
this.init()
},
clickSign() {
this.$http("/addons/ddshop/signin/signin").then(res => {
uni.showToast({
title: "签到成功",
icon: 'success',
duration: 2000
});
this.init()
})
},
getData(val) {
let y = val.split('-')[0];
let m = val.split('-')[1];
this.sumCount = 88;
if (y == this.toYear && m == this.toMonth) {
let num = ["2", "3", "6", "8", "12", "15"],
newSign = [],
today = new Date().getDate();
for (let i = 0; i < 6; i++) {
if (parseInt(num[i]) > today) {
break;
}
newSign.push(y + "-" + m + "-" + num[i])
}
this.signData = newSign;
console.log(this.signData);
} else {
this.signData = [];
}
},
}
}
</script>
<style lang='scss'>
.sign {
background: url("../../static/sign-bg.png") no-repeat top left;
background-size: cover;
}
.count .daynumber {
display: flex;
flex-direction: row;
justify-content: center;
}
.count .daynumber .day {
margin-top: 50rpx;
}
.count {
margin: 20rpx;
padding: 30rpx;
display: flex;
border-radius: 10px;
flex-direction: column;
background-color: #fff;
}
.count .number {
color: #fff;
font-size: 60rpx;
background-color: #94db98;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
margin: 20rpx;
}
.monthSum {
color: red;
font-size: 40rpx;
}
.count text {
margin: 10rpx;
}
</style>