前端技术(26) : 全年排班日历

news2024/12/28 18:20:53

来源: 通义千问

效果图

代码

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="UTF-8">
		<title>年度日历</title>
		<style>
			body {
				font-family: Arial, sans-serif;
			}

			.calendar-container {
				margin: 20px auto;
				width: 90%;
				max-width: 1000px;
			}

			h1,
			h2 {
				text-align: center;
				color: #4a148c;
			}

			table {
				width: 100%;
				border-collapse: collapse;
				margin-bottom: 20px;
			}

			th,
			td {
				padding: 10px;
				text-align: center;
				border: 1px solid #ddd;

				position: relative;
			}

			th {
				background-color: #e0e0e0;
				color: #4a148c;
			}

			.workday {
				background-color: #ffffcc;
			}

			/* 浅黄色 */
			.holiday,
			.off-day {
				background-color: white;
			}

			/* 默认白色 */
			.makeup-workday {
				background-color: #ffffcc;
			}

			/* 调休补班时为浅黄色 */
			.special-date {
				background-color: #6a1b9a;
				color: white;
			}

			/* 紫色 */
			.service-day {
				border: 2px solid #42a5f5 !important;
			}

			/* 蓝色 */
			.today {
				background-color: #fff25d;
			}

			/* 当天日期为紫色边框 */
			.month-separator {
				border-top: 2px solid #4a148c;
				margin: 20px 0;
			}

			.today-display {
				text-align: center;
				color: #4a148c;
				margin-bottom: 20px;
			}

			.top-right-corner {
				position: absolute;
				top: 0;
				right: 0;
				background-color: #e3e3e3;
				/* 确保文字背景与单元格背景一致 */
				padding: 2px 5px;
				/* 根据需要调整内边距 */
				font-size: 0.8em;
				/* 调整字体大小 */
			}
		</style>
	</head>
	<body>

		<div class="calendar-container">
			<div class="today-display" id="todayDisplay"></div>
			<h1 id="yearTitle">2024年日历</h1>
			<input type="number" id="yearInput" value="2024">
			<button onclick="updateCalendar()">更新日历</button>
			<div style="float: right;">
				<table style="width: 300px;">
					<tbody>
						<tr>
							<td class="workday" style="width: 100px;">工作日</td>
							<td class="service-day workday" style="width: 100px;">服务日</td>
							<td class="workday" style="width: 100px;">驻场'<span class="top-right-corner">上海</span>'</td>
						</tr>
					</tbody>
				</table>

			</div>

			<div id="calendarContainer"></div>
		</div>

		<script>
			// 法定节假日列表
			const holidays = [
				/// 2024年
				'2024-01-01', // 元旦
				'2024-02-10', '2024-02-11', '2024-02-12', '2024-02-13', '2024-02-14', '2024-02-15', '2024-02-16',
				'2024-02-17', // 春节
				'2024-04-04', '2024-04-05', '2024-04-06', // 清明节
				'2024-05-01', '2024-05-02', '2024-05-03', '2024-05-04', '2024-05-05', // 劳动节
				'2024-06-08', '2024-06-09', '2024-06-10', // 端午节
				'2024-09-15', '2024-09-16', '2024-09-17', // 中秋节
				'2024-10-01', '2024-10-02', '2024-10-03', '2024-10-04', '2024-10-05', '2024-10-06', '2024-10-07', // 国庆节

				/// 2025年
				'2025-01-01', // 元旦
				'2025-01-28', '2025-01-29', '2025-01-30', '2024-01-31', '2025-02-02', '2025-02-03', '2025-02-04', // 春节
				'2025-04-04', '2025-04-05', '2025-04-06', // 清明节
				'2025-05-01', '2025-05-02', '2025-05-03', '2025-05-04', '2025-05-05', // 劳动节
				'2025-05-31', '2024-06-01', '2024-06-02', // 端午节
				'2025-10-01', '2025-10-02', '2025-10-03', '2025-10-04', '2025-10-05', '2025-10-06', '2025-10-07',
				'2025-10-08', // 国庆节中秋节

			];

			// 调休补班列表()
			const makeupDays = [
				/// 2024年
				'2024-02-04', '2024-02-18', // 春节调休补班
				'2024-04-07', // 清明节调休补班
				'2024-04-28', '2024-05-11', // 劳动节调休补班
				'2024-09-14', // 中秋节调休补班
				'2024-09-29', '2024-10-12', // 国庆节调休补班

				/// 2025年
				'2025-01-26', '2025-02-08', // 春节调休补班
				'2025-04-27', // 劳动节调休补班
				'2025-09-28', // 中秋节调休补班
				'2025-10-11', // 国庆节调休补班
			];

			// 驻场的日期
			const inSceneDates = [
				// 2024
				['2024-08-11', '2024-08-30'],
				['2024-09-02', '2024-09-14'],
				['2024-09-18', '2024-09-30'],
				['2024-10-08', '2024-10-25'],
				['2024-10-28', '2024-11-15'],
				['2024-12-02', '2024-12-20'],
				// 2025
				['2025-01-06', '2025-01-17'],
				['2025-02-17', '2025-03-07'],
				['2025-03-24', '2025-04-03'],
				['2025-04-21', '2025-04-30'],
				['2025-05-19', '2025-05-30'],
				['2025-06-16', '2025-07-04'],
				['2025-07-21', '2025-08-08'],
			]
			const finalInSceneDates = flattenDateRanges(inSceneDates);

			// 服务开始日期和天数
			const serviceStartDate = '2024-08-12'; // 示例:服务从3月1日开始
			const serviceWorkdaysCount = 7 * 30; // 示例:20个工作日
			var serviceWorkdaysPassed = 0;
			const serviceDays = []



			function updateCalendar() {
				const year = document.getElementById('yearInput').value;
				document.getElementById('yearTitle').innerText = `${year}年日历`;
				document.getElementById('calendarContainer').innerHTML = ''; // 清空旧日历

				for (let month = 1; month <= 12; month++) {
					if (month > 1) {
						document.getElementById('calendarContainer').insertAdjacentHTML('beforeend',
							'<hr class="month-separator">');
					}
					createMonthCalendar(year, month);
				}

				// 更新今天日期显示
				const today = new Date();
				document.getElementById('todayDisplay').textContent = `今天是:${today.toLocaleDateString()}`;
			}

			function createMonthCalendar(year, month) {
				const container = document.getElementById('calendarContainer');
				const table = document.createElement('table');
				const thead = document.createElement('thead');
				const tbody = document.createElement('tbody');

				// Create header row with days of week
				const headerRow = document.createElement('tr');
				const daysOfWeek = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
				daysOfWeek.forEach(day => {
					const th = document.createElement('th');
					th.textContent = day;
					headerRow.appendChild(th);
				});
				thead.appendChild(headerRow);
				table.appendChild(thead);

				// Fill in calendar days
				const date = new Date(year, month - 1, 1);
				const lastDay = new Date(year, month, 0).getDate();
				const startDay = date.getDay(); // Get the first day of the week (0=Sun, 1=Mon, ...)

				let day = 1;
					for (let i = 0;; i++) {
						for (let j = 0; j < 7; j++) {
							if (i === 0 && j < startDay || day > lastDay) {
							} else {
								const currentDate = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
								const isHoliday = holidays.includes(currentDate);
								const isMakeupDay = makeupDays.includes(currentDate);
								const isWorkday = !isHoliday && ((j >= 1 && j <= 5) || isMakeupDay);
								let isServiceDay = false

								if (isWorkday) {

									if (serviceDays.includes(currentDate)) {
										isServiceDay = true
										serviceDays.push(currentDate)
									} else {
										if (new Date(currentDate) >= new Date(serviceStartDate)) {
											if (isWorkday) {
												serviceWorkdaysPassed++;
												if (serviceWorkdaysPassed <= serviceWorkdaysCount) {
													isServiceDay = true
													serviceDays.push(currentDate)
												}
											}
										}
									}
								}
								day++;
							}
						}
						if (day > lastDay) break;
					}

				let endServiceDay = getMaxDate(serviceDays)
				console.log(endServiceDay)

				day = 1;
				for (let i = 0;; i++) {
					const row = document.createElement('tr');
					for (let j = 0; j < 7; j++) {
						if (i === 0 && j < startDay || day > lastDay) {
							row.appendChild(document.createElement('td'));
						} else {
							const cell = document.createElement('td');

							const currentDate = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
							const isHoliday = holidays.includes(currentDate);
							const isMakeupDay = makeupDays.includes(currentDate);
							const isInSceneDay = finalInSceneDates.includes(currentDate);
							const isWorkday = !isHoliday && ((j >= 1 && j <= 5) || isMakeupDay);
							const today = new Date().toJSON().slice(0, 10) === currentDate;
							let isServiceDay = false

							if (isWorkday) {
								cell.classList.add('workday');

								// Check if this is a service workday
								if (serviceDays.includes(currentDate)) {
									isServiceDay = true
									cell.classList.add('service-day');
								} else {
									if (new Date(currentDate) >= new Date(serviceStartDate)) {
										if (isWorkday) {
											serviceWorkdaysPassed++;
											if (serviceWorkdaysPassed <= serviceWorkdaysCount) {
												isServiceDay = true
												cell.classList.add('service-day');
												serviceDays.push(currentDate)
											}
										}
									}
								}
							} else {
								cell.classList.add('holiday');
							}
							let remake = ''
							if (isInSceneDay) {
								if (endServiceDay != null && new Date(currentDate) <= new Date(endServiceDay)) {
									remake += '<span class="top-right-corner">上海</span>'
								}
							}

							if (today) {
								cell.classList.add('today'); // Add purple border to today's date
							}

							cell.innerHTML = day + remake;
							day++;
							row.appendChild(cell);
						}
					}
					tbody.appendChild(row);
					if (day > lastDay) break;
				}
				table.appendChild(tbody);

				// Add month title
				const monthTitle = document.createElement('h2');
				const monthNames = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
				monthTitle.textContent = monthNames[month - 1];
				container.appendChild(monthTitle);

				container.appendChild(table);
			}

			// Initialize the calendar on page load
			window.onload = function() {
				updateCalendar();
			};

			function generateDateRange(startDate, endDate) {
				const dateArray = [];
				let currentDate = new Date(startDate);
				const end = new Date(endDate);

				while (currentDate <= end) {
					dateArray.push(currentDate.toISOString().split('T')[0]);
					currentDate.setDate(currentDate.getDate() + 1);
				}

				return dateArray;
			}

			function flattenDateRanges(dateRanges) {
				return dateRanges.reduce((acc, [start, end]) => {
					acc.push(...generateDateRange(start, end));
					return acc;
				}, []);
			}

			function getMaxDate(dateArray) {
				if (dateArray.length === 0) return null;

				// 将日期字符串数组映射为时间戳数组,并找到最大值
				const maxTimestamp = Math.max(...dateArray.map(dateStr => Date.parse(dateStr)));

				// 将最大时间戳转换回日期字符串
				const maxDate = new Date(maxTimestamp).toISOString().split('T')[0];

				return maxDate;
			}
		</script>

	</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2267053.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT-------认识QT

QT简介 QT是一个跨平台的C图形用户界面应用程序框架&#xff0c;由挪威Trolltech公司于1991年开发并发布。它为开发者提供了一套丰富的类库和工具&#xff0c;用于创建各种类型的应用程序&#xff0c;包括桌面应用、移动应用、嵌入式系统应用等。QT具有高度的可定制性和可扩展…

Hive 部署

1 下载并安装 1.1 Hadoop安装 参考另一篇博客&#xff1a;Hadoop 部署 1.2 安装包下载 可通过下面网站下载&#xff1a; 官网&#xff1a;https://dlcdn.apache.org/hive/。清华源&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/apache/hive/。 比如下载apache-hive-4…

Linux中QT应用IO状态设置失效问题

问题&#xff1a;在进入freeze休眠前需要设置特定IO关闭电源灯操作&#xff0c;唤醒后需要将特定IO恢复原来正常工作状态&#xff0c;此时出现偶然性&#xff08;概率很低&#xff09;的IO控制失效问题&#xff1b;【平台&#xff1a;君正X1600HN】 一、问题点分析 1、电路 …

empire靶机

打开靶机 我们先查看页面源代码&#xff0c;发现什么也没有 再去用nmap扫描 nmap -sV -p- 192.168.95.144 发现也没什么用 我们在用dirb扫一下 dirb http://192.168.95.144 我们发现了robots.txt并且响应码是200&#xff0c;去访问一下 又得到了一个目录&#xff0c;去访问…

三层交换原理及图示

大概 三层交换原理 需要提前掌握的&#xff08;VLAN基础知识&#xff09; 【Info-Finder 参考链接&#xff1a;什么是VLAN】 三层是IP层&#xff0c;即网络层。为了方便记忆的&#xff1a;“先有网络&#xff0c;才有传输”、“传输是为了验证有网络”、“IP不是Transfer”…

当AI遇见大数据:决策优化的下一个风口

引言 在信息化时代的浪潮中&#xff0c;数据已成为企业决策的重要资产。随着大数据技术的发展&#xff0c;企业积累了海量的用户行为数据、市场动态和内部运营信息&#xff0c;这些数据背后蕴藏着巨大的价值。然而&#xff0c;数据的价值并非天然显现&#xff0c;它需要通过有效…

sizeof和strlen区分,(好多例子)

sizeof算字节大小 带\0 strlen算字符串长度 \0之前

SmartAIChain荣获重要认可

2024年12月21日&#xff0c;洛杉矶尔湾市——在今年的圣诞艺术交流会上&#xff0c;黄荣先生的SmartAIChain项目获得了重要认可。此次活动汇聚了来自各地的艺术家以及社区代表&#xff0c;共同庆祝这一创新性艺术的时刻。 在活动中&#xff0c;核桃市议员伍立伦(Allen Wu)代表D…

【Compose multiplatform教程12】【组件】Box组件

查看全部组件文章浏览阅读493次&#xff0c;点赞17次&#xff0c;收藏11次。alignment。https://blog.csdn.net/b275518834/article/details/144751353 Box 功能说明&#xff1a;简单的布局组件&#xff0c;可容纳其他组件&#xff0c;并依据alignment属性精确指定内部组件的对…

RT-DETR学习笔记(3)

九、损失函数 整理所需参数 decoder的输出结果&#xff1a;6层decoderlayer的类别以及bbox预测 将500个query拆分成300&#xff08;300个query&#xff09;200(denoising query) 1. 最后一层的decoder的输出的300部分&#xff0c;单独存储到out中的"pred_logits"和“…

处理元素卡在视野边界,滚动到视野内

效果图如下&#xff1a; 本示例处理场景&#xff1a;点击底部的折叠面板&#xff0c;展开后移动端滚动条位置不变&#xff0c;导致展开内容在视图外。造成面板展开无内容的错觉。 处理核心API: IntersectionObserver 此API可绑定元素并监听元素是否在视野内。若在视野外​​​…

RAGFlow 基于深度文档理解构建的开源 RAG引擎 - 安装部署

RAGFlow 基于深度文档理解构建的开源 RAG引擎 - 安装部署 flyfish 1. 确保 vm.max_map_count ≥ 262144 这是指要调整Linux内核参数vm.max_map_count&#xff0c;以确保其值至少为262144。这个参数控制着进程可以映射的最大内存区域数量。对于某些应用程序&#xff08;如Ela…

鸿蒙项目云捐助第二十九讲云捐助项目云数据库商品的批量增加功能实现

鸿蒙项目云捐助第二十九讲云捐助项目云数据库商品的批量增加功能实现 关于鸿蒙云捐助项目&#xff0c;前面的内容已使用云函数&#xff0c;云数据库分别实现云捐助项目首页中的项分类导航&#xff0c;底部导航&#xff0c;轮播图功能&#xff0c;这里继续实现云数据库加载捐赠…

Confluent Cloud Kafka 可观测性最佳实践

Confluent Cloud 介绍 Confluent Cloud 是一个完全托管的 Apache Kafka 服务&#xff0c;提供高可用性和可扩展性&#xff0c;旨在简化数据流处理和实时数据集成。用户可以轻松创建和管理 Kafka 集群&#xff0c;而无需担心基础设施的维护和管理。Confluent Cloud 支持多种数据…

SpringCloudAlibaba升级手册-nacos问题记录

目录 一、前言 二、升级过程 1.问题 2.原因 3.出处 4.理论解决 5.测试环境问题 6.Spring Cloud Alibaba版本对比 7. Spring Cloud Alibaba适配组件版本对比 8.降低Spring Cloud版本 9.SpringCloud与SpringBoot兼容对比表 10.naocs-client版本对比 三、最终解决 一…

15、【OS】【Nuttx】OS裁剪,运行指定程序,周期打印当前任务

背景 接之前wiki【Nsh中运行第一个程序】https://blog.csdn.net/nobigdeal00/article/details/144728771 OS还是比较庞大&#xff0c;且上面搭载了Nsh&#xff08;Nuttx Shell&#xff09;&#xff0c;需要接入串口才能正常工作&#xff0c;一般调试的时候用&#xff0c;非调试…

C# 窗体应用程序嵌套web网页,基于谷歌浏览器内核(含源码)

有一个winform项目&#xff0c;需要借助一个web项目来显示&#xff0c;并且对web做一些操作,web页目是需要用谷歌内核&#xff0c;基于谷歌 Chromium项目的开源Web Browser控件来开发写了一个demo。 安装步骤 第一步&#xff1a;右键项目&#xff0c;点击 管理NuGet程序包 , 输…

通过远程控制软件实现企业高效协作

在这个信息技术迅猛发展的时代&#xff0c;远程办公已经成为一种趋势&#xff0c;而远程控制软件则是连接分散团队的重要工具。技术的革新不仅推动了远程控制软件的广泛应用&#xff0c;也为现代办公带来了高效的协作体验。本文将探讨远程控制软件的发展&#xff0c;并以RayLin…

赋能开发者 | 麒麟信安受邀参加2024开放原子开发者大会,以技术为引领,以人才创发展

12月20至21日&#xff0c;以“一切为了开发者”为主题的“2024开放原子开发者大会暨首届开源技术学术大会”在湖北武汉举办。本届大会由开放原子开源基金会、中国通信学会联合主办&#xff0c;旨在贯彻落实国家软件发展战略&#xff0c;加速培育壮大我国开源生态。工业和信息化…

每天40分玩转Django:Django国际化

Django国际化 一、今日学习内容概述 学习模块重要程度主要内容国际化基础⭐⭐⭐⭐⭐基本概念、配置设置字符串翻译⭐⭐⭐⭐⭐翻译标记、消息文件模板国际化⭐⭐⭐⭐模板标签、过滤器动态内容翻译⭐⭐⭐⭐模型字段、表单翻译 二、国际化基础配置 # settings.py# 启用国际化 …