259 lines
6.0 KiB
Vue
259 lines
6.0 KiB
Vue
<template>
|
|
<view class="calendar">
|
|
<view class="data font28 color-white">
|
|
<view class="btn btn-pro" @tap="proEv"></view>
|
|
<view class="txt">{{curYear}}年{{curMonth<10?'0'+curMonth:curMonth}}月</view>
|
|
<view class="btn btn-next" @tap="nextEv"></view>
|
|
</view>
|
|
<view class="week font24">
|
|
<view class="item" v-for="(item,index) in weeks" :key="index">{{item}}</view>
|
|
</view>
|
|
<view class="days bg-white font26">
|
|
<view class="item" v-for="(item,index) in days" :key="index">
|
|
<view class="txt color-99" v-if="item.status==-2">{{item.date}}</view>
|
|
<view class="txt color-white bg-green" v-if="statusObj.ok.indexOf(item.status)!==-1">{{item.date}}</view>
|
|
<view class="txt color-white bg-orange" v-if="statusObj.add.indexOf(item.status)!==-1">{{item.date}}</view>
|
|
<view class="txt color-white bg-red" v-if="statusObj.no.indexOf(item.status)!==-1">{{item.date}}</view>
|
|
<view class="txt" v-if="statusObj.ok.indexOf(item.status)==-1&&statusObj.add.indexOf(item.status)==-1&&statusObj.no.indexOf(item.status)==-1&&item.status!==-2">{{item.date}}</view>
|
|
</view>
|
|
</view>
|
|
<view class="tips font22">
|
|
<view class="item">正常打卡</view>
|
|
<view class="item">补打卡</view>
|
|
<view class="item">非正常打卡</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
<script>
|
|
import {
|
|
mapState
|
|
} from 'vuex'; //引入mapState
|
|
export default {
|
|
name: 'sign-calendar',
|
|
data() {
|
|
return {
|
|
weeks: ['日', '一', '二', '三', '四', '五', '六'], //星期列表
|
|
days:[], //天数
|
|
curYear:new Date().getFullYear(), //当前年
|
|
curMonth:new Date().getMonth() + 1, //当前月
|
|
statusObj:{}, //状态列表
|
|
};
|
|
},
|
|
mounted() {
|
|
// 获取数组,绘制格子
|
|
this.getDaysList();
|
|
},
|
|
methods: {
|
|
// 获取数组,绘制格子
|
|
getDaysList(){
|
|
// 清空数组
|
|
this.days = [];
|
|
// 计算当月天数
|
|
let curDays = new Date(this.curYear,this.curMonth, 0).getDate();
|
|
// 计算当月第一天星期几
|
|
let firstWeek = new Date(Date.UTC(this.curYear, this.curMonth-1, 1)).getDay();
|
|
// 计算当月最后一天星期几
|
|
let lastWeek = new Date(Date.UTC(this.curYear, this.curMonth-1,curDays)).getDay();
|
|
|
|
// 上月还有展示
|
|
if(firstWeek!==0){
|
|
// 绘制上月天数占的格子
|
|
this.proMonthDays(firstWeek,curDays);
|
|
}else{
|
|
// 绘制当月天数占的格子
|
|
this.curMonthDays(curDays);
|
|
}
|
|
// 下月还有展示
|
|
if(lastWeek!==6){
|
|
// 绘制下月天数占的格子
|
|
this.nextMonthDays(lastWeek)
|
|
}
|
|
},
|
|
|
|
// 绘制上月天数占的格子
|
|
proMonthDays(firstWeek,curDays){
|
|
// 计算上月天数
|
|
let proDays = 0;
|
|
if(this.curMonth==1){
|
|
proDays = new Date(this.curYear-1,12, 0).getDate();
|
|
}else{
|
|
proDays = new Date(this.curYear,this.curMonth-1, 0).getDate();
|
|
}
|
|
// 创建上月天数数组
|
|
let proDaysArr=[];
|
|
for (let i=proDays-firstWeek+1; i<=proDays;i++) {
|
|
let proObj = {
|
|
date: i,
|
|
status: -2
|
|
}
|
|
proDaysArr.push(proObj);
|
|
}
|
|
this.days = proDaysArr;
|
|
// 绘制当月天数占的格子
|
|
this.curMonthDays(curDays);
|
|
},
|
|
|
|
// 绘制当月天数占的格子
|
|
curMonthDays(curDays) {
|
|
// 创建当月天数数组
|
|
let curDaysArr=[];
|
|
for (let i=1; i<=curDays;i++) {
|
|
let curObj = {
|
|
date: i,
|
|
status: i
|
|
}
|
|
curDaysArr.push(curObj);
|
|
}
|
|
this.days = this.days.concat(curDaysArr);
|
|
// 获取状态列表
|
|
this.getStatusObj();
|
|
},
|
|
|
|
// 绘制下月天数占的格子
|
|
nextMonthDays(lastWeek) {
|
|
// 创建上月天数数组
|
|
let nextDaysArr=[];
|
|
for (let i=1; i<=6-lastWeek;i++) {
|
|
let nextObj = {
|
|
date: i,
|
|
status: -2
|
|
}
|
|
nextDaysArr.push(nextObj);
|
|
}
|
|
this.days = this.days.concat(nextDaysArr);
|
|
},
|
|
|
|
// 获取状态列表
|
|
getStatusObj(){
|
|
this.statusObj = {
|
|
'ok':[2,5,6,8,12],
|
|
'add':[4,7,11,22],
|
|
'no':[19,28]
|
|
}
|
|
},
|
|
|
|
// 上一月
|
|
proEv(){
|
|
if(this.curMonth!==1){
|
|
this.curMonth--;
|
|
}else{
|
|
this.curMonth = 12;
|
|
this.curYear--;
|
|
}
|
|
// 获取数组,绘制格子
|
|
this.getDaysList();
|
|
},
|
|
|
|
// 下一月
|
|
nextEv(){
|
|
if(this.curMonth!==12){
|
|
this.curMonth++
|
|
}else{
|
|
this.curMonth = 1;
|
|
this.curYear++;
|
|
}
|
|
// 获取数组,绘制格子
|
|
this.getDaysList();
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.calendar .data{
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
width: 100%;
|
|
height: 92rpx;
|
|
padding: 0 22rpx;
|
|
background-color: #0788ff;
|
|
}
|
|
|
|
.calendar .btn{
|
|
width: 42rpx;
|
|
height: 42rpx;
|
|
background-image: url(/static/icon/icon-calendar-btn.png);
|
|
background-size: cover;
|
|
}
|
|
|
|
.calendar .btn-next{
|
|
transform: rotateY(180deg);
|
|
}
|
|
|
|
.calendar .week{
|
|
display: flex;
|
|
align-items: center;
|
|
background-color: #ececec;
|
|
}
|
|
|
|
.calendar .week .item{
|
|
width: calc(100%/7);
|
|
line-height: 58rpx;
|
|
text-align: center;
|
|
}
|
|
|
|
.calendar .days{
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
}
|
|
|
|
.calendar .days .item{
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
width: calc(100%/7);
|
|
height: 86rpx;
|
|
border-top: 2rpx solid #ececec;
|
|
border-right: 2rpx solid #ececec;
|
|
}
|
|
|
|
.calendar .days .item:nth-of-type(7n){
|
|
border-right: 0;
|
|
}
|
|
|
|
.calendar .days .item .txt{
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
width: 58rpx;
|
|
height: 58rpx;
|
|
border-radius: 100%;
|
|
}
|
|
|
|
.calendar .tips{
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 30rpx 0;
|
|
}
|
|
|
|
.calendar .tips .item{
|
|
display: flex;
|
|
align-items: center;
|
|
height: 30rpx;
|
|
margin: 0 12rpx;
|
|
}
|
|
|
|
.calendar .tips .item:before{
|
|
content: '';
|
|
display: block;
|
|
width: 12rpx;
|
|
height: 12rpx;
|
|
background-color: #ec7807;
|
|
border-radius: 100%;
|
|
margin-right: 9rpx;
|
|
}
|
|
|
|
.calendar .tips .item:first-child:before{
|
|
background-color: #25a63b;
|
|
}
|
|
|
|
.calendar .tips .item:last-child:before{
|
|
background-color: #ec0707;
|
|
}
|
|
</style>
|