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

news/2025/2/23 5:45:57

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>


http://www.niftyadmin.cn/n/5863032.html

相关文章

嵌入式硬件篇---数字电子技术中的触发器

文章目录 前言简介1. SR触发器&#xff08;Set-Reset Flip-Flop&#xff09;工作原理1.基本结构2.输入信号3.真值表4.缺点5.应用示例 2. 钟控SR触发器&#xff08;Clocked SR Flip-Flop&#xff09;工作原理1.改进点2.触发条件3.问题4.应用示例 3. D触发器&#xff08;Data Fli…

nodejs:express + js-mdict 作为后端,vue 3 + vite 作为前端,在线查询英汉词典

向 doubao.com/chat/ 提问&#xff1a; node.js js-mdict 作为后端&#xff0c;vue 3 vite 作为前端&#xff0c;编写在线查询英汉词典 后端部分&#xff08;express js-mdict &#xff09; 1. 项目结构 首先&#xff0c;创建一个项目目录&#xff0c;结构如下&#xff1…

kotlin的Int类型调用toString()会导致空指针吗

DeepSeek R1 思考 38 秒 思考过程 用户的问题是关于Kotlin中Int类型调用toString()是否会导致空指针异常。首先&#xff0c;我需要回忆Kotlin的基本类型系统。Kotlin中的Int属于基本数据类型&#xff0c;但它在语言层面被表示为非空类型。也就是说&#xff0c;Int变量本身不能…

node.js的版本管理

nvm&#xff08;Node Version Manager&#xff09; 适用系统&#xff1a; macOS、Linux&#xff0c;在 Windows 上也有移植版本 nvm - windows。 特点&#xff1a; 使用广泛&#xff0c;能方便地安装、切换不同版本的 Node.js&#xff0c;并且可以同时管理多个版本。 安装 nv…

基于 JavaWeb 的 Spring Boot 网上商城系统设计和实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

http、websocket与MQTT协议

网络通讯协议 1、http、websocket与MQTT协议 核心区别 特点httpwebsocketMQTT协议协议模型请求-响应&#xff08;单项&#xff09;全双工双向通讯发布/订阅&#xff08;多对多&#xff09;连接状态无状态&#xff08;断连接或长连接需要要手东维护&#xff09;持久长连接&am…

WPS PPT插入各种线型形状(如画直线)的时候总是有箭头,如何还原成只画直线

WPS PPT插入各种线型形状&#xff08;如画直线&#xff09;的时候总是有箭头&#xff0c;如何还原成只画直线 文章目录 WPS PPT插入各种线型形状&#xff08;如画直线&#xff09;的时候总是有箭头&#xff0c;如何还原成只画直线一、问题出现的原因二、解决方法 在使用 WPS 演…

运维Ansible面试题及参考答案

目录 简述 Ansible 的工作原理,它是如何实现对远程主机管理的? Ansible 是基于什么语言开发的?这门语言的特性对 Ansible 的功能实现有哪些帮助? 解释 Agentless 在 Ansible 中的含义,与基于 Agent 的自动化工具相比,优势体现在哪? Ansible 中的 Inventory 文件是什…