1、切换月份根据当前月判断,只能切换当前月份之前的时间。
2、补卡功能,根据后台设置自己写上即可,可补签多少天。
3、点击签到是签到当前天的,不能指定签到时间。
备注:当前代码只构建了排版样式和切换月份功能,签到状态根据个人开发以及接口返回的详细内容再次处理。
<template><view class="sign-in"><view class="sign-in-date"><view>今日签到 <textstyle="color: #F05C1C;display: inline-block;margin-left: 15rpx;margin-right: 15rpx;">18积分</text> 待领取</view><view><view class="date-icon" @click="LastMonth"><image src="/static/left-Date.png" style="width: 100%;height: 100%;"></image></view><text>{{DateTitle}}</text><view class="date-icon"><image src="/static/right-Date.png" style="width: 100%;height: 100%;" @click="NextMonth"v-if="!hideDateIcon"></image></view></view><view><view><view class="week" v-for="(item,index) in weekFor" :key="index">{{item}}</view></view><view><view class="date" v-for="(item,index) in DateFor" :key="index"><image src="/static/success-QD.png" class="SuccessCss" v-if="item==22"></image><image src="/static/error-QD.png" class="SuccessCss" v-if="item==21"></image><text v-if="item!==22 && item!==21">{{item}}</text></view></view></view><view>签到</view></view></view>
</template><script>export default {data() {return {weekFor: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],DateTitle: '',MeDateTitle: '',DateFor: [],hideDateIcon: false}},onShow() {const currentDate = new Date();const year = currentDate.getFullYear();const month = currentDate.getMonth() + 1; // getMonth() 返回的月份是从0开始的,所以要加1 const day = currentDate.getDate();const formattedDate = `${year}年${month}月`;const daysInMonth = new Date(year, month, 0).getDate(); // 0代表上一个月的最后一天 const firstDayOfMonth = new Date(year, month - 1, 1); // month - 1 因为月份是从0开始的 const firstDayOfWeek = firstDayOfMonth.getDay(); // 0=周日, 1=周一, ..., 6=周六 const daysOfWeek = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];const firstDayOfWeekStr = daysOfWeek[firstDayOfWeek];console.log(`当前日期: ${formattedDate}`);this.DateTitle = ` ${formattedDate}`this.MeDateTitle = ` ${formattedDate}`console.log(`该月份的天数: ${daysInMonth}天`);this.DateFor = []for (let i = 1; i <= daysInMonth; i++) {this.DateFor.push(i);}console.log(`今天是: ${day}号`);console.log(`当前月份的第一天是: ${firstDayOfWeekStr}`);const emptyDaysMap = {'周一': 0,'周二': 1,'周三': 2,'周四': 3,'周五': 4,'周六': 5,'周日': 6};const emptyDaysCount = emptyDaysMap[firstDayOfWeekStr];for (let i = 0; i < emptyDaysCount; i++) {this.DateFor.unshift('');}this.checkDate();},methods: {//上个月LastMonth() {const [year, month] = this.DateTitle.split('年').map(part => part.replace('月', ''));const date = new Date(year, month - 1);date.setMonth(date.getMonth() - 1);const newYear = date.getFullYear();const newMonth = date.getMonth() + 1;this.DateTitle = `${newYear}年${newMonth}月`;this.getMonthInfo(); // 获取当前月份的信息 },//下个月NextMonth() {const [year, month] = this.DateTitle.split('年').map(part => part.replace('月', ''));const date = new Date(year, month - 1);date.setMonth(date.getMonth() + 1);const newYear = date.getFullYear();const newMonth = date.getMonth() + 1; // 获取新的月份,注意要加1 this.DateTitle = `${newYear}年${newMonth}月`;this.getMonthInfo(); // 获取当前月份的信息 },getMonthInfo() {const [year, month] = this.DateTitle.split('年').map(part => part.replace('月', ''));const numDays = new Date(year, month, 0).getDate(); // 获取当前月份的天数 const firstDay = new Date(year, month - 1, 1).getDay(); // 获取当前月份第一天是星期几 console.log(`当前月份有 ${numDays} 天,第一天是星期 ${firstDay === 0 ? '日' : firstDay}`);this.DateFor = [];for (let i = 1; i <= numDays; i++) {this.DateFor.push(i);}const daysOfWeek = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];const firstDayOfWeekStr = daysOfWeek[firstDay]; // 获取第一天的星期几字符串 // 计算空白天数 const emptyDaysMap = {'周一': 0,'周二': 1,'周三': 2,'周四': 3,'周五': 4,'周六': 5,'周日': 6,};const emptyDaysCount = emptyDaysMap[firstDayOfWeekStr]; // 获取空白天数 for (let i = 0; i < emptyDaysCount; i++) {this.DateFor.unshift('');}this.checkDate();},checkDate() {const meDateParts = this.MeDateTitle.match(/(\d+)年(\d+)月/);const dateParts = this.DateTitle.match(/(\d+)年(\d+)月/);if (meDateParts && dateParts) {const meYear = meDateParts[1];const meMonth = meDateParts[2];const dateYear = dateParts[1];const dateMonth = dateParts[2];// 判断是否为同一年月 this.hideDateIcon = (meYear === dateYear && meMonth === dateMonth);}},}}
</script><style lang="scss">.sign-in {width: 100vw;min-height: 100vh;float: left;background: #0F0817;.sign-in-date {width: 702rpx;border-radius: 24rpx;margin: 0 auto;background: linear-gradient(161deg, #1B1B24 29%, rgba(240, 92, 28, 0.33) 100%);padding-top: 32rpx;padding-bottom: 32rpx;}.sign-in-date>view:nth-child(1) {width: 654rpx;height: 30rpx;margin: 0 auto;display: flex;align-items: center;color: #FFFFFF;font-size: 24rpx;}.sign-in-date>view:nth-child(2) {width: 654rpx;height: 30rpx;margin: 49rpx auto 0;display: flex;align-items: center;justify-content: space-between;font-family: Akkurat Pro, Akkurat Pro;font-weight: bold;font-size: 28rpx;color: #FFFFFF;.date-icon {width: 44rpx;height: 44rpx;text-align: center;line-height: 44rpx;}}.sign-in-date>view:nth-child(3) {width: 654rpx;margin: 40rpx auto 0;}.sign-in-date>view:nth-child(3)>view:nth-child(1) {width: 100%;height: 93.4rpx;display: flex;align-items: center;.week {width: 93.4rpx;height: 93.4rpx;text-align: center;line-height: 93.4rpx;font-family: Akkurat Pro, Akkurat Pro;font-weight: bold;font-size: 24rpx;color: #FFFFFF;}}.sign-in-date>view:nth-child(3)>view:nth-child(2) {width: 100%;display: flex;align-items: center;flex-wrap: wrap;.date {width: 93.4rpx;height: 93.4rpx;text-align: center;line-height: 93.4rpx;font-family: Akkurat Pro, Akkurat Pro;font-weight: bold;font-size: 24rpx;color: #FFFFFF;display: flex;align-items: center;justify-content: center;.SuccessCss {width: 55rpx;height: 55rpx;text-align: center;line-height: 55rpx;}}}.sign-in-date>view:nth-child(4) {width: 654rpx;height: 88rpx;background: #F05C1C;border-radius: 59rpx;text-align: center;line-height: 88rpx;font-family: PingFang HK, PingFang HK;font-weight: 600;font-size: 32rpx;color: #FFFFFF;margin: 50rpx auto 0;}}
</style>