当前位置: 首页 > news >正文

uniapp小程序自定义日历(签到、补签功能)

1、切换月份根据当前月判断,只能切换当前月份之前的时间。

2、补卡功能,根据后台设置自己写上即可,可补签多少天。

3、点击签到是签到当前天的,不能指定签到时间。

备注:当前代码只构建了排版样式和切换月份功能,签到状态根据个人开发以及接口返回的详细内容再次处理。

<template>
	<view class="sign-in">

		<view class="sign-in-date">
			<view>今日签到 <text
					style="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>

相关文章:

  • 《深度学习实战》第1集:深度学习基础回顾与框架选择
  • C++如何获取windows系统通知消息列表
  • 数据结构系列三:List+顺序表+ArrayList
  • langflow如何查看中间步骤的输出
  • 嵌入式硬件篇---数字电子技术中的时序逻辑
  • Unable to parse timestamp value: “20250220135445“, expected format is
  • Elasticsearch除了用作查找以外,还能可以做什么?
  • DAY08 List接口、Collections接口、Set接口
  • const 关键字在 C++ 中的应用
  • Cannot deserialize instance of java.lang.String out of START_ARRAY token
  • PDN目标阻抗的局限与恶劣波评估
  • C++ 智能指针 unique_ptr shared_ptr weak_ptr小练习
  • 【Java基础-49】Java线程池及其基本应用详解
  • 强化学习的数学原理-六、随机近似与随机梯度下降
  • HTML之JavaScript DOM简介
  • Python中的闭包和装饰器
  • 静态时序分析:时钟组间的逻辑独立、物理独立和异步的区别
  • Perplexity AI:通过OpenAI与DeepSeek彻底革新搜索和商业策略
  • 过程监督(Process Supervision)融入到 GRPO (Group Relative Policy Optimization)
  • MT7628基于原厂的SDK包, 修改ra1网卡的MAC方法。
  • 被取消总统候选人资格,金文洙:将采取政治法律措施讨回公道
  • 外交部:习近平主席同普京总统达成许多新的重要共识
  • 优秀“博主”在上海杨浦购房最高补贴200万元,有何条件?
  • 中国一重集团有限公司副总经理陆文俊被查
  • 盖茨:20年内将捐出几乎全部财富,盖茨基金会2045年关闭
  • 身临其境感受伟人思想力量,“马克思书房”在上海社科馆揭幕