您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
VPS续期提醒工具,支持自定义提醒周期和单个VPS续期。比如hax.co.id、woiden.id等
当前为
// ==UserScript== // @name VPS续期提醒 // @namespace http://tampermonkey.net/ // @version 0.6 // @description VPS续期提醒工具,支持自定义提醒周期和单个VPS续期。比如hax.co.id、woiden.id等 // @author Gally // @match *://*/* // @match https://hax.co.id/* // @match https://woiden.id/* // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @license MIT // <--- 添加许可证声明 // ==/UserScript== (function() { 'use strict'; // 添加样式 GM_addStyle(` #vps-reminder-container { position: fixed; right: 20px; bottom: 20px; width: 340px; background-color: rgba(255, 255, 255, 0.7); border: 1px solid rgba(255, 255, 255, 0.3); border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.15); padding: 20px; z-index: 9999; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: none; transition: all 0.3s ease; backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px); } #vps-reminder-title { font-size: 18px; font-weight: 600; margin-bottom: 15px; color: #333; display: flex; align-items: center; } #vps-reminder-title:before { content: ''; display: inline-block; width: 20px; height: 20px; margin-right: 8px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%234285F4"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></svg>'); background-size: contain; } #vps-reminder-content { margin-bottom: 18px; color: #555; max-height: 240px; overflow-y: auto; padding-right: 5px; } #vps-reminder-content::-webkit-scrollbar { width: 5px; } #vps-reminder-content::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 5px; } #vps-reminder-content::-webkit-scrollbar-thumb { background: #ccc; border-radius: 5px; } .vps-item { margin-bottom: 12px; padding: 12px 15px; border-radius: 8px; position: relative; transition: all 0.2s ease; box-shadow: 0 2px 5px rgba(0,0,0,0.05); border-left: 4px solid #4285F4; background-color: rgba(240, 240, 240, 0.3); } .vps-item:last-child { margin-bottom: 0; } .vps-item:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.1); } .vps-item-expired { border-left: 4px solid #EA4335; background-color: rgba(234, 67, 53, 0.08); } .vps-item-warning { border-left: 4px solid #FBBC05; background-color: rgba(251, 188, 5, 0.08); } .vps-item-notice { border-left: 4px solid #4285F4; background-color: rgba(66, 133, 244, 0.08); } .vps-item-normal { border-left: 4px solid #34A853; background-color: rgba(52, 168, 83, 0.08); } .vps-item-name { font-weight: 600; color: #333; margin-bottom: 5px; font-size: 15px; } .vps-item-date { font-size: 12px; color: #666; margin-bottom: 10px; } .vps-item-status { font-size: 13px; font-weight: 500; } .vps-status-expired { color: #EA4335; } .vps-status-warning { color: #FBBC05; } .vps-status-notice { color: #4285F4; } .vps-status-normal { color: #34A853; } .vps-item-renew { position: absolute; right: 12px; top: 12px; padding: 5px 10px; background-color: #4285F4; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 12px; transition: all 0.2s ease; font-weight: 500; } .vps-item-renew:hover { background-color: #3367D6; transform: scale(1.05); } #vps-reminder-buttons { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px; } #vps-reminder-renew-all, #vps-reminder-settings, #vps-reminder-dismiss { padding: 10px 16px; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; transition: all 0.2s ease; font-size: 13px; } #vps-reminder-renew-all { background-color: #4285F4; color: white; } #vps-reminder-renew-all:hover { background-color: #3367D6; } #vps-reminder-settings { background-color: rgba(240, 240, 240, 0.5); color: #333; } #vps-reminder-settings:hover { background-color: rgba(220, 220, 220, 0.7); } #vps-reminder-dismiss { background-color: rgba(240, 240, 240, 0.5); color: #333; flex: 1; margin-top: 10px; text-align: center; } #vps-reminder-dismiss:hover { background-color: rgba(220, 220, 220, 0.7); } #vps-settings-container { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 500px; max-height: 80vh; overflow-y: auto; background-color: rgba(255, 255, 255, 0.7); border: 1px solid rgba(255, 255, 255, 0.3); border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); padding: 25px; z-index: 10000; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: none; backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px); } #vps-settings-container::-webkit-scrollbar { width: 6px; } #vps-settings-container::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 6px; } #vps-settings-container::-webkit-scrollbar-thumb { background: #ccc; border-radius: 6px; } #vps-settings-title { font-size: 20px; font-weight: 600; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid rgba(0,0,0,0.1); color: #333; } .vps-settings-item { margin-bottom: 20px; position: relative; padding: 15px; border-radius: 8px; background-color: rgba(240, 240, 240, 0.3); transition: all 0.2s ease; } .vps-settings-item:hover { background-color: rgba(240, 240, 240, 0.5); } .vps-settings-item label { display: block; margin-bottom: 8px; font-weight: 500; color: #444; } .vps-settings-item input, .vps-settings-item select { width: 100%; padding: 10px 12px; border: 1px solid rgba(0,0,0,0.1); border-radius: 6px; font-family: inherit; transition: all 0.2s ease; background-color: white; } .vps-settings-item input:focus, .vps-settings-item select:focus { outline: none; border-color: #4285F4; box-shadow: 0 0 0 2px rgba(66, 133, 244, 0.2); } .vps-delete-btn { position: absolute; right: 15px; top: 15px; background-color: #EA4335; color: white; border: none; border-radius: 5px; padding: 5px 10px; cursor: pointer; font-size: 12px; transition: all 0.2s ease; } .vps-delete-btn:hover { background-color: #D62516; } #vps-settings-buttons { display: flex; justify-content: space-between; margin-top: 20px; } #vps-settings-save { padding: 10px 18px; background-color: #4285F4; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; transition: all 0.2s ease; } #vps-settings-save:hover { background-color: #3367D6; } #vps-settings-cancel { padding: 10px 18px; background-color: rgba(240, 240, 240, 0.5); color: #333; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; transition: all 0.2s ease; } #vps-settings-cancel:hover { background-color: rgba(220, 220, 220, 0.7); } #vps-add-new { padding: 10px 18px; background-color: #34A853; color: white; border: none; border-radius: 6px; cursor: pointer; margin-top: 15px; width: 100%; font-weight: 500; transition: all 0.2s ease; display: flex; justify-content: center; align-items: center; } #vps-add-new:hover { background-color: #2E8B57; } #vps-add-new:before { content: '+'; margin-right: 8px; font-size: 16px; font-weight: bold; } `); // 默认VPS数据 const defaultVpsData = [ { id: 1, name: 'VPS 1', cycle: 3, nextDate: '', needRemind: false }, { id: 2, name: 'VPS 2', cycle: 3, nextDate: '', needRemind: false }, { id: 3, name: 'VPS 3', cycle: 3, nextDate: '', needRemind: false }, { id: 4, name: 'VPS 4', cycle: 3, nextDate: '', needRemind: false }, { id: 5, name: 'VPS 5', cycle: 30, nextDate: '', needRemind: false } ]; // 获取VPS数据 let vpsData = GM_getValue('vpsData', defaultVpsData); // 用于记录今天是否已经关闭过提醒 let dismissedForToday = false; // 检查是否已经今天不再提醒 function checkDismissedForToday() { const dismissedData = GM_getValue('dismissedForToday', null); if (dismissedData) { const today = formatDate(new Date()); if (dismissedData.date === today) { dismissedForToday = true; return true; } } return false; } // 创建提醒容器 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); buttons.appendChild(dismissButton); container.appendChild(title); container.appendChild(content); container.appendChild(buttons); document.body.appendChild(container); } // 创建设置容器 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 settingsContent = document.createElement('div'); settingsContent.id = 'vps-settings-content'; container.appendChild(settingsContent); // 创建添加新VPS按钮 const addNewButton = document.createElement('button'); addNewButton.id = 'vps-add-new'; addNewButton.textContent = '添加新VPS'; addNewButton.addEventListener('click', addNewVps); container.appendChild(addNewButton); const buttons = document.createElement('div'); buttons.id = 'vps-settings-buttons'; const cancelButton = document.createElement('button'); cancelButton.id = 'vps-settings-cancel'; cancelButton.textContent = '取消'; cancelButton.addEventListener('click', () => { document.getElementById('vps-settings-container').style.display = 'none'; }); 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 settingsContent = document.getElementById('vps-settings-content'); settingsContent.innerHTML = ''; // 为每个VPS创建设置项 vpsData.forEach(vps => { const item = document.createElement('div'); item.className = 'vps-settings-item'; item.dataset.id = vps.id; // 删除按钮 if (vpsData.length > 1) { const deleteBtn = document.createElement('button'); deleteBtn.className = 'vps-delete-btn'; deleteBtn.textContent = '删除'; deleteBtn.addEventListener('click', function() { deleteVps(vps.id); }); item.appendChild(deleteBtn); } const nameLabel = document.createElement('label'); nameLabel.textContent = `${vps.name} 名称`; 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 = `${vps.name} 提醒周期(天)`; 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 = `${vps.name} 下次提醒日期`; 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); settingsContent.appendChild(item); }); } // 添加新VPS function addNewVps() { // 生成新ID let maxId = 0; vpsData.forEach(vps => { if (vps.id > maxId) maxId = vps.id; }); // 添加新VPS数据 const newVps = { id: maxId + 1, name: `VPS ${maxId + 1}`, cycle: 3, nextDate: formatDate(new Date()), needRemind: false }; vpsData.push(newVps); // 更新设置内容 updateSettingsContent(); } // 删除VPS function deleteVps(id) { vpsData = vpsData.filter(vps => vps.id !== id); updateSettingsContent(); } // 显示设置界面 function showSettings() { document.getElementById('vps-settings-container').style.display = 'block'; } // 保存设置 function saveSettings() { const newVpsData = []; // 获取所有设置项 const settingsItems = document.querySelectorAll('.vps-settings-item'); settingsItems.forEach(item => { const id = parseInt(item.dataset.id); const name = document.getElementById(`vps-name-${id}`).value; const cycle = parseInt(document.getElementById(`vps-cycle-${id}`).value); const nextDate = document.getElementById(`vps-date-${id}`).value; // 查找原始数据中的needRemind状态 const originalVps = vpsData.find(vps => vps.id === id); const needRemind = originalVps ? originalVps.needRemind : false; newVpsData.push({ id, name, cycle, nextDate, needRemind }); }); vpsData = newVpsData; GM_setValue('vpsData', vpsData); document.getElementById('vps-settings-container').style.display = 'none'; // 重新检查提醒 checkReminders(); } // 格式化日期为YYYY-MM-DD function formatDate(date) { 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对象 function parseDate(dateString) { return new Date(dateString); } // 计算两个日期之间的天数差 function daysBetween(date1, date2) { const oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数 const diffTime = Math.abs(date2 - date1); return Math.floor(diffTime / oneDay); } // 处理"今天不再提醒"按钮点击 function dismissForToday() { dismissedForToday = true; // 保存当前日期和状态到存储中 const today = formatDate(new Date()); GM_setValue('dismissedForToday', { date: today, dismissed: true }); document.getElementById('vps-reminder-container').style.display = 'none'; } // 检查是否需要提醒 function checkReminders() { // 如果今天已经关闭过提醒,则不再显示 if (dismissedForToday) { return; } const today = new Date(); today.setHours(0, 0, 0, 0); let hasRemindersNeedAttention = false; // 是否有VPS需要立即提醒 let allVpsWithInfo = []; // 所有VPS及其状态信息 // 为所有VPS计算到期状态和剩余天数 vpsData.forEach(vps => { if (!vps.nextDate) { vps.nextDate = formatDate(new Date()); } const nextDate = parseDate(vps.nextDate); nextDate.setHours(0, 0, 0, 0); // 计算距离到期日期的天数 const diff = nextDate - today; const daysUntil = Math.ceil(diff / (1000 * 60 * 60 * 24)); // 标记需要提醒的VPS if (daysUntil <= 0 || daysUntil === 1 || daysUntil === 2) { hasRemindersNeedAttention = true; vps.needRemind = true; } else { vps.needRemind = false; } // 将VPS信息和剩余天数添加到数组 allVpsWithInfo.push({ ...vps, daysUntil: daysUntil }); }); // 按剩余天数排序(升序) allVpsWithInfo.sort((a, b) => a.daysUntil - b.daysUntil); // 如果有需要提醒的VPS,显示所有VPS的信息 if (hasRemindersNeedAttention) { let reminderContent = ''; // 添加所有VPS信息,按剩余天数排序 allVpsWithInfo.forEach(vps => { let statusClass = ''; let statusText = ''; let itemClass = ''; // 根据剩余天数设置状态和样式 if (vps.daysUntil <= 0) { statusClass = 'vps-status-expired'; statusText = '即将过期,需要续期'; itemClass = 'vps-item-expired'; } else if (vps.daysUntil === 1) { statusClass = 'vps-status-warning'; statusText = '明天到期,需要续期'; itemClass = 'vps-item-warning'; } else if (vps.daysUntil === 2) { statusClass = 'vps-status-notice'; statusText = '后天到期,需要续期'; itemClass = 'vps-item-notice'; } else { statusClass = 'vps-status-normal'; statusText = `还有 ${vps.daysUntil} 天到期`; itemClass = 'vps-item-normal'; } // 根据是否需要提醒设置不透明度 const opacity = vps.needRemind ? '1' : '0.7'; reminderContent += `<div class="vps-item ${itemClass}" style="opacity: ${opacity}"> <div class="vps-item-name">${vps.name}</div> <div class="vps-item-date">下次续期日期: ${vps.nextDate}</div> <div class="vps-item-status ${statusClass}">${statusText}</div> ${vps.needRemind ? `<button class="vps-item-renew" data-id="${vps.id}">我已续期</button>` : ''} </div>`; }); document.getElementById('vps-reminder-content').innerHTML = reminderContent; document.getElementById('vps-reminder-container').style.display = 'block'; // 为每个单独的续期按钮添加事件 document.querySelectorAll('.vps-item-renew').forEach(button => { button.addEventListener('click', function(e) { e.stopPropagation(); handleRenewSingle(parseInt(this.dataset.id)); }); }); } // 更新存储的数据 GM_setValue('vpsData', vpsData); } // 处理单个VPS续期 function handleRenewSingle(id) { vpsData.forEach(vps => { if (vps.id === id && vps.needRemind) { // 使用原到期日期计算新的提醒日期,而不是当前日期 const originalDate = parseDate(vps.nextDate); const newDate = new Date(originalDate); newDate.setDate(originalDate.getDate() + vps.cycle); vps.nextDate = formatDate(newDate); vps.needRemind = false; } }); // 更新存储的数据 GM_setValue('vpsData', vpsData); // 重新检查是否还有需要提醒的VPS checkReminders(); } // 处理全部已续期按钮点击 function handleRenewAll() { vpsData.forEach(vps => { if (vps.needRemind) { // 使用原到期日期计算新的提醒日期,而不是当前日期 const originalDate = parseDate(vps.nextDate); const newDate = new Date(originalDate); newDate.setDate(originalDate.getDate() + vps.cycle); vps.nextDate = formatDate(newDate); vps.needRemind = false; } }); // 更新存储的数据 GM_setValue('vpsData', vpsData); // 隐藏提醒 document.getElementById('vps-reminder-container').style.display = 'none'; } // 初始化 function init() { createReminderContainer(); createSettingsContainer(); // 检查是否已设置"今天不再提醒" checkDismissedForToday(); // 如果是首次使用,显示设置界面 if (!GM_getValue('initialized', false)) { showSettings(); GM_setValue('initialized', true); } else { // 检查是否需要提醒 checkReminders(); } } // 等待页面加载完成后初始化 window.addEventListener('load', init); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址