// ==UserScript==
// @name VPS续期提醒
// @namespace http://tampermonkey.net/
// @version 0.5
// @description VPS续期提醒工具,支持自定义提醒周期和单个VPS续期,优化UI和排序,中文界面。
// @author Gally
// @match *://*/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @license MIT // <--- 添加许可证声明
// ==/UserScript==
(function() {
'use strict';
// 添加样式
GM_addStyle(`
#vps-reminder-container, #vps-settings-container {
font-family: 'Microsoft YaHei', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* 优先使用微软雅黑 */
color: #333;
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 9999;
}
#vps-reminder-container {
position: fixed;
right: 20px;
bottom: 20px;
width: 360px; /* 调整宽度 */
padding: 20px;
display: none;
}
#vps-reminder-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
color: #2c3e50;
}
#vps-reminder-content {
margin-bottom: 20px;
max-height: 280px; /* 增加高度 */
overflow-y: auto;
padding-right: 10px; /* 为滚动条留出空间 */
}
.vps-item {
margin-bottom: 12px;
padding: 12px 15px;
border: 1px solid #e0e0e0;
border-radius: 6px;
background-color: #fff;
position: relative;
padding-left: 25px; /* 为颜色条留出空间 */
transition: background-color 0.2s ease;
}
.vps-item:hover {
background-color: #f5f5f5;
}
.vps-item::before { /* 颜色状态条 */
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 8px; /* 加宽颜色条 */
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
.vps-item.status-expired::before { background-color: #e74c3c; /* 红色 - 过期/今天到期 */ }
.vps-item.status-warning::before { background-color: #f1c40f; /* 黄色 - 1天内到期 */ }
.vps-item.status-soon::before { background-color: #e67e22; /* 橙色 - 2天内到期 */ }
.vps-item.status-ok::before { background-color: #2ecc71; /* 绿色 - 正常 */ }
.vps-item.not-needing-direct-attention { opacity: 0.75; } /* 非紧急提醒的条目稍作区分 */
.vps-item.not-needing-direct-attention:hover { opacity: 1; }
.vps-item strong {
font-size: 15px;
color: #34495e;
display: block;
margin-bottom: 5px;
}
.vps-item-info {
font-size: 13px;
color: #7f8c8d;
margin-bottom: 8px;
line-height: 1.4;
}
.vps-item-info .status-text {
font-weight: 500;
}
.vps-item-info .status-text.expired { color: #c0392b; }
.vps-item-info .status-text.warning { color: #d35400; }
.vps-item-renew {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
padding: 7px 12px;
background-color: #3498db; /* 蓝色 */
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
transition: background-color 0.2s ease;
}
.vps-item-renew:hover {
background-color: #2980b9;
}
#vps-reminder-buttons {
display: flex;
justify-content: space-between;
gap: 10px; /* 按钮间距 */
}
#vps-reminder-renew-all, #vps-reminder-settings, #vps-reminder-dismiss {
padding: 10px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: 500;
flex-grow: 1;
text-align: center;
transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}
#vps-reminder-renew-all {
background-color: #2ecc71; /* 绿色 */
color: white;
}
#vps-reminder-renew-all:hover { background-color: #27ae60; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
#vps-reminder-settings {
background-color: #ecf0f1; /* 浅灰色 */
color: #34495e;
}
#vps-reminder-settings:hover { background-color: #bdc3c7; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
#vps-reminder-dismiss {
background-color: #e67e22; /* 橙色 */
color: white;
}
#vps-reminder-dismiss:hover { background-color: #d35400; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
#vps-settings-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 500px;
max-height: 90vh; /* 增加最大高度 */
overflow-y: auto;
background-color: #fff; /* 设置面板背景改为纯白以示区分 */
padding: 25px;
display: none;
}
#vps-settings-title {
font-size: 20px; /* 增大标题字号 */
font-weight: 600;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
color: #2c3e50;
}
#vps-settings-list { /* 用于包裹所有vps设置项的容器 */
margin-bottom: 20px;
}
.vps-settings-item {
margin-bottom: 20px; /* 增加间距 */
padding: 15px;
border: 1px solid #eaeaea;
border-radius: 6px;
background-color: #fdfdfd;
position: relative;
}
.vps-settings-item label {
display: block;
margin-bottom: 6px;
font-weight: 500;
font-size: 14px;
color: #555;
}
.vps-settings-item input, .vps-settings-item select {
width: calc(100% - 18px); /* 减去padding */
padding: 9px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
box-sizing: border-box;
}
.vps-settings-item input[type="date"] {
padding: 7px; /* 日期输入框padding微调 */
}
.vps-delete-btn {
position: absolute;
right: 10px;
top: 10px;
background-color: #e74c3c; /* 红色 */
color: white;
border: none;
border-radius: 4px;
padding: 5px 9px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
transition: background-color 0.2s ease;
}
.vps-delete-btn:hover { background-color: #c0392b; }
#vps-settings-buttons {
display: flex;
justify-content: flex-end; /* 按钮靠右 */
gap: 12px;
margin-top: 20px;
padding-top: 15px;
border-top: 1px solid #eee;
}
#vps-settings-save, #vps-settings-cancel, #vps-add-new {
padding: 10px 18px;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: 500;
transition: background-color 0.2s ease, box-shadow 0.2s ease;
}
#vps-add-new {
background-color: #3498db; /* 蓝色 */
color: white;
width: auto; /* 不再是100%宽度 */
margin-right: auto; /* 将添加按钮推到左边 */
}
#vps-add-new:hover { background-color: #2980b9; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
#vps-settings-save {
background-color: #2ecc71; /* 绿色 */
color: white;
}
#vps-settings-save:hover { background-color: #27ae60; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
#vps-settings-cancel {
background-color: #bdc3c7; /* 中性灰色 */
color: #fff;
}
#vps-settings-cancel:hover { background-color: #95a5a6; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
`);
// 默认VPS数据
const defaultVpsData = [
{ id: 1, name: '服务器 1', cycle: 30, nextDate: '', needRemind: false },
{ id: 2, name: '服务器 2', cycle: 90, nextDate: '', needRemind: false },
{ id: 3, name: '服务器 3', cycle: 365, nextDate: '', needRemind: false }
];
// 获取VPS数据,如果不存在则使用默认数据
let vpsData = GM_getValue('vpsData', JSON.parse(JSON.stringify(defaultVpsData))); // 深拷贝默认数据
// 用于记录今天是否已经关闭过提醒
let dismissedForToday = GM_getValue('dismissedDate', '') === formatDate(new Date());
// 创建提醒容器
function createReminderContainer() {
const container = document.createElement('div');
container.id = 'vps-reminder-container';
const title = document.createElement('div');
title.id = 'vps-reminder-title';
title.textContent = 'VPS 续期提醒'; // 标题
const content = document.createElement('div');
content.id = 'vps-reminder-content';
const buttons = document.createElement('div');
buttons.id = 'vps-reminder-buttons';
const renewAllButton = document.createElement('button');
renewAllButton.id = 'vps-reminder-renew-all';
renewAllButton.textContent = '全部已续期'; // 按钮文字
renewAllButton.addEventListener('click', handleRenewAll);
const settingsButton = document.createElement('button');
settingsButton.id = 'vps-reminder-settings';
settingsButton.textContent = '设置'; // 按钮文字
settingsButton.addEventListener('click', showSettings);
const dismissButton = document.createElement('button');
dismissButton.id = 'vps-reminder-dismiss';
dismissButton.textContent = '今日不再提醒'; // 按钮文字
dismissButton.addEventListener('click', dismissForToday);
buttons.appendChild(renewAllButton);
buttons.appendChild(settingsButton);
container.appendChild(title);
container.appendChild(content);
container.appendChild(buttons); // "今日不再提醒"按钮放在底部,与其他操作按钮分开
document.body.appendChild(container);
// 单独添加 "今日不再提醒" 按钮,使其可以占据整行
const dismissButtonContainer = document.createElement('div');
dismissButtonContainer.style.marginTop = "10px";
dismissButtonContainer.appendChild(dismissButton);
container.appendChild(dismissButtonContainer);
}
// 创建设置容器
function createSettingsContainer() {
const container = document.createElement('div');
container.id = 'vps-settings-container';
const title = document.createElement('div');
title.id = 'vps-settings-title';
title.textContent = 'VPS 提醒设置'; // 标题
container.appendChild(title);
const settingsList = document.createElement('div'); // 新增一个 div 包裹所有设置项
settingsList.id = 'vps-settings-list';
container.appendChild(settingsList);
const buttons = document.createElement('div');
buttons.id = 'vps-settings-buttons';
// 创建添加新VPS按钮
const addNewButton = document.createElement('button');
addNewButton.id = 'vps-add-new';
addNewButton.textContent = '添加新VPS'; // 按钮文字
addNewButton.addEventListener('click', addNewVps);
buttons.appendChild(addNewButton); // 添加到按钮组的开头
const cancelButton = document.createElement('button');
cancelButton.id = 'vps-settings-cancel';
cancelButton.textContent = '取消'; // 按钮文字
cancelButton.addEventListener('click', () => {
document.getElementById('vps-settings-container').style.display = 'none';
updateSettingsContent(); // 取消时恢复到保存的状态
});
const saveButton = document.createElement('button');
saveButton.id = 'vps-settings-save';
saveButton.textContent = '保存'; // 按钮文字
saveButton.addEventListener('click', saveSettings);
buttons.appendChild(cancelButton);
buttons.appendChild(saveButton);
container.appendChild(buttons);
document.body.appendChild(container);
// 更新设置内容
updateSettingsContent();
}
// 更新设置内容
function updateSettingsContent() {
const settingsList = document.getElementById('vps-settings-list');
if (!settingsList) return; // 如果容器还未创建则返回
settingsList.innerHTML = '';
// 为每个VPS创建设置项
vpsData.forEach(vps => {
const item = document.createElement('div');
item.className = 'vps-settings-item';
item.dataset.id = vps.id;
const nameLabel = document.createElement('label');
nameLabel.textContent = `名称 (ID: ${vps.id})`; // 标签文字
nameLabel.htmlFor = `vps-name-${vps.id}`;
const nameInput = document.createElement('input');
nameInput.type = 'text';
nameInput.id = `vps-name-${vps.id}`;
nameInput.value = vps.name;
const cycleLabel = document.createElement('label');
cycleLabel.textContent = `提醒周期 (天)`; // 标签文字
cycleLabel.htmlFor = `vps-cycle-${vps.id}`;
const cycleInput = document.createElement('input');
cycleInput.type = 'number';
cycleInput.id = `vps-cycle-${vps.id}`;
cycleInput.value = vps.cycle;
cycleInput.min = 1;
const dateLabel = document.createElement('label');
dateLabel.textContent = `下次提醒日期`; // 标签文字
dateLabel.htmlFor = `vps-date-${vps.id}`;
const dateInput = document.createElement('input');
dateInput.type = 'date';
dateInput.id = `vps-date-${vps.id}`;
dateInput.value = vps.nextDate || formatDate(new Date());
item.appendChild(nameLabel);
item.appendChild(nameInput);
item.appendChild(cycleLabel);
item.appendChild(cycleInput);
item.appendChild(dateLabel);
item.appendChild(dateInput);
// 删除按钮,仅当VPS数量大于1时显示
if (vpsData.length > 1) {
const deleteBtn = document.createElement('button');
deleteBtn.className = 'vps-delete-btn';
deleteBtn.textContent = '删除'; // 按钮文字
deleteBtn.addEventListener('click', function() {
if (confirm(`确定要删除 VPS "${vps.name}" 吗?`)) { // 添加确认对话框
deleteVps(vps.id);
}
});
item.appendChild(deleteBtn);
}
settingsList.appendChild(item);
});
}
// 添加新VPS
function addNewVps() {
let maxId = 0;
vpsData.forEach(vps => {
if (vps.id > maxId) maxId = vps.id;
});
const newVps = {
id: maxId + 1,
name: `新服务器 ${maxId + 1}`, // 默认新VPS名称
cycle: 30, // 默认周期
nextDate: formatDate(new Date()), // 默认下次提醒日期为今天
needRemind: false
};
vpsData.push(newVps);
updateSettingsContent(); // 重新渲染设置列表以包含新项
}
// 删除VPS
function deleteVps(id) {
vpsData = vpsData.filter(vps => vps.id !== id);
GM_setValue('vpsData', vpsData); // 删除后立即保存
updateSettingsContent(); // 更新设置界面
checkReminders(); // 重新检查提醒状态
}
// 显示设置界面
function showSettings() {
updateSettingsContent(); // 打开设置时确保显示的是最新的数据
document.getElementById('vps-settings-container').style.display = 'block';
document.getElementById('vps-reminder-container').style.display = 'none'; // 打开设置时隐藏提醒弹窗
}
// 保存设置
function saveSettings() {
const newVpsData = [];
const settingsItems = document.querySelectorAll('#vps-settings-list .vps-settings-item');
let hasError = false; // 标记是否有错误
settingsItems.forEach(item => {
if (hasError) return; // 如果已经有错误,则不再处理后续条目
const id = parseInt(item.dataset.id);
const nameInput = document.getElementById(`vps-name-${id}`);
const cycleInput = document.getElementById(`vps-cycle-${id}`);
const dateInput = document.getElementById(`vps-date-${id}`);
const name = nameInput.value.trim();
let cycle = parseInt(cycleInput.value);
let nextDate = dateInput.value;
if (!name) {
alert(`ID 为 ${id} 的服务器名称不能为空!`); // 提示信息
nameInput.focus(); // 聚焦到出错的输入框
hasError = true;
return;
}
if (isNaN(cycle) || cycle < 1) {
alert(`ID 为 ${id} 的服务器提醒周期必须是大于0的数字!`); // 提示信息
cycleInput.focus();
hasError = true;
return;
}
if (!nextDate) {
alert(`ID 为 ${id} 的服务器下次提醒日期不能为空!`); // 提示信息
dateInput.focus();
hasError = true;
return;
}
// 简单校验日期格式 (YYYY-MM-DD)
if (!/^\d{4}-\d{2}-\d{2}$/.test(nextDate) || isNaN(parseDate(nextDate))) {
alert(`ID 为 ${id} 的服务器下次提醒日期格式不正确,请使用 YYYY-MM-DD 格式!`);
dateInput.focus();
hasError = true;
return;
}
const originalVps = vpsData.find(vps => vps.id === id);
newVpsData.push({
id,
name,
cycle,
nextDate,
needRemind: originalVps ? originalVps.needRemind : false // 保留原始的 needRemind 状态
});
});
if (hasError) {
return; // 如果有错误,则不保存和关闭设置窗口
}
vpsData = newVpsData;
GM_setValue('vpsData', vpsData);
document.getElementById('vps-settings-container').style.display = 'none';
checkReminders(); // 保存后重新检查提醒
}
// 格式化日期为YYYY-MM-DD
function formatDate(date) {
if (!(date instanceof Date) || isNaN(date)) {
return ''; // 处理无效日期
}
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
// 解析日期字符串为Date对象 (确保时间为0点,以便日期比较)
function parseDate(dateString) {
if (!dateString) return null;
const parts = dateString.split('-');
if (parts.length === 3) {
const year = parseInt(parts[0]);
const month = parseInt(parts[1]) - 1; // 月份是从0开始的
const day = parseInt(parts[2]);
const date = new Date(year, month, day);
// 再次校验生成的日期是否与输入一致,避免如2023-02-30这样的无效日期被错误解析
if (date.getFullYear() === year && date.getMonth() === month && date.getDate() === day) {
date.setHours(0,0,0,0);
return date;
}
}
return null; // 无效格式或无效日期
}
// 计算今天到目标日期还剩多少天
function getDaysUntil(targetDateStr) {
const today = new Date();
today.setHours(0, 0, 0, 0);
const targetDate = parseDate(targetDateStr);
if (!targetDate) return Infinity; // 无效日期视为无限远
const diffTime = targetDate - today;
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
}
// 获取VPS状态文本和CSS类
function getVpsStatus(daysUntil) {
let text = '';
let cssClass = 'status-ok'; // 默认绿色
if (daysUntil < 0) {
text = `已过期 ${Math.abs(daysUntil)} 天`;
cssClass = 'status-expired'; // 红色
} else if (daysUntil === 0) {
text = '今天到期';
cssClass = 'status-expired'; // 红色
} else if (daysUntil === 1) {
text = '明天到期';
cssClass = 'status-warning'; // 黄色
} else if (daysUntil === 2) {
text = `还有 2 天到期`;
cssClass = 'status-soon'; // 橙色
} else {
text = `还有 ${daysUntil} 天到期`;
// cssClass 保持 status-ok (绿色)
}
return { text, cssClass, days: daysUntil };
}
// 处理"今日不再提醒"按钮点击
function dismissForToday() {
dismissedForToday = true;
GM_setValue('dismissedDate', formatDate(new Date()));
document.getElementById('vps-reminder-container').style.display = 'none';
}
// 检查是否需要提醒
function checkReminders() {
// 检查当天是否已忽略
const todayStr = formatDate(new Date());
if (GM_getValue('dismissedDate', '') === todayStr) {
dismissedForToday = true;
document.getElementById('vps-reminder-container').style.display = 'none';
return;
} else {
// 如果记录的忽略日期不是今天,则重置忽略状态
if (dismissedForToday && GM_getValue('dismissedDate', '') !== todayStr) {
dismissedForToday = false;
GM_setValue('dismissedDate', ''); // 清除旧的忽略日期
}
}
let vpsWithStatus = vpsData.map(vps => {
const daysUntil = getDaysUntil(vps.nextDate);
const status = getVpsStatus(daysUntil);
// 标记是否需要紧急提醒 (到期、1天内、2天内)
vps.needsDirectAttention = daysUntil <= 2;
return { ...vps, daysUntil, statusText: status.text, statusClass: status.cssClass };
});
// 排序:需要紧急关注的优先,然后在这些内部按到期日近的优先,其他正常的也按到期日近的优先
vpsWithStatus.sort((a, b) => {
if (a.needsDirectAttention && !b.needsDirectAttention) return -1;
if (!a.needsDirectAttention && b.needsDirectAttention) return 1;
return a.daysUntil - b.daysUntil;
});
let reminderContentHtml = '';
let hasUrgentReminders = false;
vpsWithStatus.forEach(vps => {
if (vps.needsDirectAttention) {
hasUrgentReminders = true;
}
// 所有VPS都显示,但紧急的会排在前面且有颜色标记
const itemClass = `vps-item ${vps.statusClass} ${vps.needsDirectAttention ? '' : 'not-needing-direct-attention'}`;
reminderContentHtml += `
<div class="${itemClass}" data-id="${vps.id}">
<strong>${vps.name}</strong>
<div class="vps-item-info">
<span class="status-text ${vps.daysUntil <= 0 ? 'expired' : (vps.daysUntil === 1 ? 'warning' : '')}">${vps.statusText}</span>
<br><span>到期日: ${vps.nextDate || '未设置'}</span>
</div>
${vps.needsDirectAttention ? `<button class="vps-item-renew" data-id="${vps.id}">已续期</button>` : ''}
</div>`;
});
const reminderContentElement = document.getElementById('vps-reminder-content');
const reminderContainerElement = document.getElementById('vps-reminder-container');
if (hasUrgentReminders && !dismissedForToday) { // 再次检查 dismissedForToday
reminderContentElement.innerHTML = reminderContentHtml;
reminderContainerElement.style.display = 'block';
document.querySelectorAll('.vps-item-renew').forEach(button => {
button.removeEventListener('click', handleRenewSingleEvent); // 移除旧监听器
button.addEventListener('click', handleRenewSingleEvent);
});
} else {
reminderContainerElement.style.display = 'none';
}
// 更新 vpsData 中的 needRemind 状态(尽管这里主要用 needsDirectAttention 来控制显示)
vpsData.forEach(vps => {
const correspondingVps = vpsWithStatus.find(vs => vs.id === vps.id);
if (correspondingVps) {
vps.needRemind = correspondingVps.needsDirectAttention;
}
});
GM_setValue('vpsData', vpsData); // 保存更新后的 needRemind 状态
}
function handleRenewSingleEvent(event) {
event.stopPropagation();
const id = parseInt(this.dataset.id);
handleRenewSingle(id);
}
// 处理单个VPS续期
function handleRenewSingle(id) {
const vpsToRenew = vpsData.find(vps => vps.id === id);
if (vpsToRenew) {
const today = new Date();
const newDate = new Date(today); // 使用今天的日期作为基准
newDate.setDate(newDate.getDate() + vpsToRenew.cycle); // 直接加上周期天数
vpsToRenew.nextDate = formatDate(newDate);
vpsToRenew.needRemind = false; // 更新后不再立即提醒
}
GM_setValue('vpsData', vpsData);
checkReminders(); // 重新检查并更新列表
}
// 处理全部已续期按钮点击
function handleRenewAll() {
const today = new Date();
let renewedCount = 0;
vpsData.forEach(vps => {
// 只续期那些当前被标记为需要提醒的 (即显示在紧急列表中的)
if (vps.needRemind) { // 或者 vps.needsDirectAttention (取决于checkReminders中如何更新的vpsData.needRemind)
const newDate = new Date(today); // 使用今天的日期作为基准
newDate.setDate(newDate.getDate() + vps.cycle); // 直接加上周期天数
vps.nextDate = formatDate(newDate);
vps.needRemind = false;
renewedCount++;
}
});
if (renewedCount > 0) {
GM_setValue('vpsData', vpsData);
}
document.getElementById('vps-reminder-container').style.display = 'none'; // 隐藏提醒
// checkReminders(); // 隐藏后不需要立即重新检查,下次加载时会检查
}
let dailyCheckInterval = null; // 用于存储定时器ID
// 初始化
function init() {
createReminderContainer();
createSettingsContainer();
if (GM_getValue('vpsData') === undefined) { // 首次使用检查的是vpsData是否存在
GM_setValue('vpsData', JSON.parse(JSON.stringify(defaultVpsData))); // 初始化数据
vpsData = GM_getValue('vpsData'); // 重新获取
}
// 如果是首次使用或数据为空,显示设置界面
if (!GM_getValue('initialized', false) || vpsData.length === 0) {
showSettings();
GM_setValue('initialized', true);
} else {
checkReminders();
}
// 清除可能存在的旧定时器
if (dailyCheckInterval) {
clearInterval(dailyCheckInterval);
}
// 每日定时检查逻辑
function scheduleDailyCheck() {
const now = new Date();
// 设置目标检查时间,例如每天早上7点 (可以根据需要调整)
const checkTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 7, 0, 0, 0);
let delay;
if (now > checkTime) { // 如果已经过了今天的检查时间
checkTime.setDate(checkTime.getDate() + 1); // 设置为明天的检查时间
}
delay = checkTime - now;
setTimeout(() => {
console.log("VPS Reminder: Performing scheduled daily check.");
dismissedForToday = false; // 重置忽略状态
GM_setValue('dismissedDate', ''); // 清除存储的忽略日期
checkReminders(); // 执行检查
// 设置后续每24小时的定时器
dailyCheckInterval = setInterval(() => {
console.log("VPS Reminder: Performing scheduled daily check (interval).");
dismissedForToday = false;
GM_setValue('dismissedDate', '');
checkReminders();
}, 24 * 60 * 60 * 1000);
}, delay);
}
scheduleDailyCheck();
}
// 等待页面加载完成后初始化
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', init);
} else {
init(); // 如果DOMContentLoaded已经触发
}
})();