VPS续期提醒

VPS续期提醒工具,支持自定义提醒周期和单个VPS续期,优化UI和排序,中文界面。

当前为 2025-05-31 提交的版本,查看 最新版本

// ==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已经触发
    }

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址