268 lines
6.5 KiB
Vue
268 lines
6.5 KiB
Vue
<template>
|
||
<view class="calendar" v-if="ifLoading">
|
||
<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 @tap="toDetail(item.status)" class="txt color-white bg-green" v-if="statusObj.ok.indexOf(item.status)!==-1&&statusObj.add.indexOf(item.status)==-1">{{item.date}}</view>
|
||
<view @tap="toDetail(item.status)" class="txt color-white bg-orange" v-if="statusObj.add.indexOf(item.status)!==-1">{{item.date}}</view>
|
||
<view @tap="toDetail(item.status)" 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:{}, //状态列表
|
||
ifLoading:false, //是否加载完成
|
||
};
|
||
},
|
||
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.$requst.get('/api/v1/user/month-sign-log',{date:`${this.curYear}-${this.curMonth<10?'0'+this.curMonth:this.curMonth}`}).then(res=>{
|
||
if(res.code==0){
|
||
console.log(res,'月度打卡信息');
|
||
this.statusObj = res.data;
|
||
this.ifLoading = true;
|
||
}
|
||
})
|
||
},
|
||
|
||
// 去查看打卡记录
|
||
toDetail(status){
|
||
let date = `${this.curYear}-${this.curMonth<10?'0'+this.curMonth:this.curMonth}-${status<10?'0'+status:status}`;
|
||
this.$emit('getDate', date);
|
||
},
|
||
|
||
// 上一月
|
||
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>
|