抢购监控 Pro – 全流程自动化版

全自动抢购脚本

支持自定义设置商品和查看日志

0T9DBE]GVEZ$F%S0_UZ}ZOX

// ==UserScript==
// @name         抢购监控 Pro - 全流程自动化版
// @namespace    http://tampermonkey.net/
// @version      7.2
// @description  活动页监控 → 配置页加购 → 支付页确认 + 支付方式选择 + 启动/暂停控制 + 刷新间隔快捷调整
// @author       You
// @match        https://www.szhdy.com/activities/default.html?method=activity&id=14
// @match        https://www.szhdy.com/cart?action=configureproduct&pid=*
// @match        https://www.szhdy.com/cart?action=viewcart
// @grant        GM_notification
// @grant        GM_setValue
// @grant        GM_getValue
// @connect      *
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    const DEFAULT_IDS = "317,345,336";
    const CONFIG_KEY = "watched_product_ids_v70";
    const LOG_KEY = "purchase_monitor_logs_v70";
    const REFRESH_INTERVAL_KEY = "refresh_interval_ms_v70";
    const STOP_ON_SUCCESS_KEY = "stop_on_success_v70";
    const SCRIPT_ACTIVE_KEY = "script_active_v71";

    const DEFAULT_REFRESH_INTERVAL = 2000;
    const MIN_REFRESH_INTERVAL = 500;

    let watchedIds = [];
    const productStatus = {};
    let logPanel = null;
    let configPanel = null;
    let logs = [];
    let refreshTimeoutId = null;
    let stopOnSuccess = true;
    let isScriptActive = true; // 全局运行开关

    // ====== 工具函数 ======
    function nowStr() {
        const now = new Date();
        return `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}.${String(now.getMilliseconds()).padStart(3, '0')}`;
    }

    function logMessage(msg) {
        const entry = `[${nowStr()}] ${msg}`;
        logs.push(entry);
        if (logs.length > 300) logs.shift();
        try { GM_setValue(LOG_KEY, JSON.stringify(logs)); } catch (e) {}
        appendLogToPanel(entry);
    }

    function appendLogToPanel(msg) {
        if (!logPanel) return;
        const c = logPanel.querySelector('.log-content');
        if (!c) return;
        const d = document.createElement('div');
        d.textContent = msg;
        d.style.cssText = 'font-family:monospace;font-size:12px;color:#0f0;';
        c.appendChild(d);
        c.scrollTop = c.scrollHeight;
    }

    function loadConfig() {
        try {
            const saved = GM_getValue(CONFIG_KEY, DEFAULT_IDS);
            watchedIds = saved.split(',').map(id => id.trim()).filter(id => id !== '');
            stopOnSuccess = GM_getValue(STOP_ON_SUCCESS_KEY, true);
            isScriptActive = GM_getValue(SCRIPT_ACTIVE_KEY, true);
        } catch (e) {
            watchedIds = DEFAULT_IDS.split(',').map(id => id.trim());
            stopOnSuccess = true;
            isScriptActive = true;
        }
    }

    function saveConfig(ids) {
        GM_setValue(CONFIG_KEY, ids.join(','));
        watchedIds = [...ids];
    }

    function saveStopOnSuccess(value) {
        stopOnSuccess = value;
        GM_setValue(STOP_ON_SUCCESS_KEY, value);
    }

    function setScriptActive(active) {
        isScriptActive = active;
        GM_setValue(SCRIPT_ACTIVE_KEY, active);
        logMessage(active ? "▶️ 脚本已启动" : "⏸️ 脚本已暂停");
    }

    function getRefreshInterval() {
        return parseInt(GM_getValue(REFRESH_INTERVAL_KEY, DEFAULT_REFRESH_INTERVAL)) || DEFAULT_REFRESH_INTERVAL;
    }

    function setRefreshInterval(ms) {
        GM_setValue(REFRESH_INTERVAL_KEY, ms);
    }

    function stopAutoRefresh() {
        if (refreshTimeoutId) {
            clearTimeout(refreshTimeoutId);
            refreshTimeoutId = null;
            logMessage("🛑 自动刷新已停止(因抢购成功)");
        }
    }

    function schedulePageRefresh() {
        if (!isScriptActive) return;
        if (refreshTimeoutId) clearTimeout(refreshTimeoutId);
        const intervalMs = getRefreshInterval();
        if (intervalMs < MIN_REFRESH_INTERVAL) {
            setRefreshInterval(MIN_REFRESH_INTERVAL);
            logMessage(`⚠️ 刷新间隔不得低于 ${MIN_REFRESH_INTERVAL}ms`);
            setTimeout(schedulePageRefresh, 100);
            return;
        }
        logMessage(`🔄 将在 ${intervalMs}ms 后刷新页面`);
        refreshTimeoutId = setTimeout(() => {
            logMessage("🔄 正在刷新页面...");
            try { GM_setValue(LOG_KEY, JSON.stringify(logs)); } catch (e) {}
            location.reload();
        }, intervalMs);
    }

    // ====== 创建常驻配置面板 ======
    function createConfigPanel() {
        if (configPanel) return;

        const panel = document.createElement('div');
        panel.id = 'tampermonkey-config-panel';
        panel.style.cssText = `
            position: fixed;
            top: 10px;
            right: 10px;
            background: white;
            border: 2px solid #2196F3;
            border-radius: 8px;
            padding: 12px;
            z-index: 999999;
            box-shadow: 0 4px 12px rgba(0,0,0,0.2);
            max-width: 340px;
            font-family: Arial, sans-serif;
        `;

        const title = document.createElement('div');
        title.textContent = '⚙️ 抢购监控配置(常驻)';
        title.style.cssText = 'font-weight:bold;margin-bottom:8px;color:#1976D2;';

        const idInput = document.createElement('input');
        idInput.type = 'text';
        idInput.placeholder = '商品 data-id,如:317,345';
        idInput.value = watchedIds.join(',');
        idInput.style.cssText = 'width:100%;padding:6px;margin-bottom:8px;border:1px solid #ccc;border-radius:4px;';

        const refreshInput = document.createElement('input');
        refreshInput.type = 'number';
        refreshInput.min = MIN_REFRESH_INTERVAL;
        refreshInput.placeholder = `刷新间隔(毫秒,最低 ${MIN_REFRESH_INTERVAL})`;
        refreshInput.value = getRefreshInterval();
        refreshInput.style.cssText = 'width:100%;padding:6px;margin-bottom:8px;border:1px solid #ccc;border-radius:4px;';

        // 快捷调整按钮
        const quickBtns = document.createElement('div');
        quickBtns.style.cssText = 'display:flex;gap:6px;margin-bottom:10px;';

        const createQuickBtn = (text, delta) => {
            const btn = document.createElement('button');
            btn.textContent = text;
            btn.style.cssText = 'flex:1;padding:4px;font-size:12px;background:#e3f2fd;border:1px solid #90caf9;border-radius:4px;cursor:pointer;';
            btn.onclick = () => {
                let val = parseInt(refreshInput.value) || getRefreshInterval();
                val += delta;
                if (val < MIN_REFRESH_INTERVAL) val = MIN_REFRESH_INTERVAL;
                refreshInput.value = val;
                applyConfig();
            };
            return btn;
        };

        quickBtns.appendChild(createQuickBtn('-100ms', -100));
        quickBtns.appendChild(createQuickBtn('+100ms', +100));
        quickBtns.appendChild(createQuickBtn('-1s', -1000));
        quickBtns.appendChild(createQuickBtn('+1s', +1000));

        const stopCheckbox = document.createElement('label');
        stopCheckbox.style.cssText = 'display:flex;align-items:center;margin-bottom:10px;';
        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.checked = stopOnSuccess;
        checkbox.style.cssText = 'margin-right:8px;';
        const labelSpan = document.createElement('span');
        labelSpan.textContent = '抢购成功后自动停止刷新';
        stopCheckbox.appendChild(checkbox);
        stopCheckbox.appendChild(labelSpan);

        // 启动/暂停按钮
        const controlBtn = document.createElement('button');
        controlBtn.textContent = isScriptActive ? '⏸️ 暂停脚本' : '▶️ 启动脚本';
        controlBtn.style.cssText = `
            width: 100%;
            padding: 7px;
            margin-bottom: 8px;
            background: ${isScriptActive ? '#f44336' : '#4caf50'};
            color: white;
            border: none;
            border-radius: 4px;
            font-weight: bold;
            cursor: pointer;
        `;
        controlBtn.onclick = () => {
            setScriptActive(!isScriptActive);
            controlBtn.textContent = isScriptActive ? '⏸️ 暂停脚本' : '▶️ 启动脚本';
            controlBtn.style.background = isScriptActive ? '#f44336' : '#4caf50';

            if (!isScriptActive && refreshTimeoutId) {
                clearTimeout(refreshTimeoutId);
                refreshTimeoutId = null;
                logMessage("🛑 自动刷新已暂停");
            } else if (isScriptActive) {
                schedulePageRefresh();
            }
        };

        const applyBtn = document.createElement('button');
        applyBtn.textContent = '✅ 应用并重置状态';
        applyBtn.style.cssText = `
            width: 100%;
            padding: 7px;
            background: #2196F3;
            color: white;
            border: none;
            border-radius: 4px;
            font-weight: bold;
            cursor: pointer;
        `;

        function applyConfig() {
            const ids = idInput.value.split(',').map(id => id.trim()).filter(id => id !== '');
            let refreshMs = parseInt(refreshInput.value) || DEFAULT_REFRESH_INTERVAL;
            const newStopOnSuccess = checkbox.checked;

            if (ids.length === 0) {
                alert('请输入至少一个商品ID!');
                return;
            }
            if (refreshMs < MIN_REFRESH_INTERVAL) refreshMs = MIN_REFRESH_INTERVAL;

            saveConfig(ids);
            setRefreshInterval(refreshMs);
            saveStopOnSuccess(newStopOnSuccess);
            resetStatus();

            logMessage(`✅ 配置更新:监控 [${ids.join(', ')}],刷新 ${refreshMs}ms,成功停止:${newStopOnSuccess ? '开启' : '关闭'}`);

            if (refreshTimeoutId) clearTimeout(refreshTimeoutId);
            if (isScriptActive) schedulePageRefresh();
        }

        applyBtn.onclick = applyConfig;

        // 拖拽支持
        let isDragging = false, offsetX, offsetY;
        title.style.cursor = 'move';
        title.addEventListener('mousedown', (e) => {
            isDragging = true;
            offsetX = e.clientX - panel.offsetLeft;
            offsetY = e.clientY - panel.offsetTop;
            title.style.opacity = '0.7';
        });

        const mouseMove = (e) => {
            if (isDragging) {
                panel.style.left = (e.clientX - offsetX) + 'px';
                panel.style.top = (e.clientY - offsetY) + 'px';
            }
        };
        const mouseUp = () => {
            if (isDragging) {
                isDragging = false;
                title.style.opacity = '1';
            }
        };
        document.addEventListener('mousemove', mouseMove);
        document.addEventListener('mouseup', mouseUp);

        panel.appendChild(title);
        panel.appendChild(idInput);
        panel.appendChild(refreshInput);
        panel.appendChild(quickBtns);
        panel.appendChild(stopCheckbox);
        panel.appendChild(controlBtn); // ← 启动/暂停按钮
        panel.appendChild(applyBtn);
        document.body.appendChild(panel);
        configPanel = panel;
    }

    // ====== 日志面板 ======
    function createLogPanel() {
        if (logPanel) return;
        const panel = document.createElement('div');
        panel.id = 'tampermonkey-log-panel';
        panel.style.cssText = 'position:fixed;bottom:10px;left:10px;width:460px;height:220px;background:rgba(0,0,0,0.9);color:#0f0;border:1px solid #0a0;border-radius:6px;z-index:999990;font-family:monospace;font-size:12px;display:flex;flex-direction:column;';

        const header = document.createElement('div');
        header.textContent = '📝 抢购监控日志';
        header.style.cssText = 'padding:6px 10px;background:#002200;cursor:move;user-select:none;';

        let isDragging = false, ox, oy;
        header.addEventListener('mousedown', (e) => {
            isDragging = true; ox = e.clientX - panel.offsetLeft; oy = e.clientY - panel.offsetTop;
        });
        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                panel.style.left = (e.clientX - ox) + 'px';
                panel.style.top = (e.clientY - oy) + 'px';
            }
        });
        document.addEventListener('mouseup', () => isDragging = false);

        const content = document.createElement('div');
        content.className = 'log-content';
        content.style.cssText = 'flex:1;overflow-y:auto;padding:6px;';
        panel.appendChild(header);
        panel.appendChild(content);
        document.body.appendChild(panel);
        logPanel = panel;

        logs.forEach(msg => appendLogToPanel(msg));
    }

    // ====== 状态重置 ======
    function resetStatus() {
        for (const id of watchedIds) productStatus[id] = null;
    }

    function getProductName(card) {
        const h1 = card.querySelector('h1');
        return h1 ? h1.textContent.trim() : `商品ID:${card.dataset.id}`;
    }

    // ====== 活动页:监控商品 ======
    function checkAllProducts() {
        if (!isScriptActive) return;
        for (const id of watchedIds) {
            const card = document.querySelector(`.cat-styleC-promotion-card[data-id="${id}"]`) ||
                         document.querySelector(`.activity-promotion-card[data-id="${id}"]`);
            if (!card) continue;
            const button = card.querySelector('.form-footer-butt');
            if (!button) continue;
            const text = button.textContent.trim();
            const isAvailable = text === "立即购买";
            const isSoldOut = text.includes("商品已售罄");
            if (isAvailable && productStatus[id] !== "available") {
                productStatus[id] = "available";
                const name = getProductName(card);
                const href = button.hasAttribute('href') ? button.getAttribute('href') : '无 href';
                logMessage(`✅ ${name} (ID:${id}) 可购买!href: ${href}`);
                if (typeof GM_notification === 'function') {
                    GM_notification({title:"🔥 抢购成功!",text:`${name} 已开放购买!`,timeout:10000});
                }
                setTimeout(() => {
                    const btn = card.querySelector('.form-footer-butt');
                    if (btn && btn.textContent.trim() === "立即购买") {
                        logMessage(`🖱️ 自动点击购买:${name} (ID:${id})`);
                        btn.click();
                        if (stopOnSuccess) stopAutoRefresh();
                        else logMessage("ℹ️ 抢购成功,但未停止刷新(开关已关闭)");
                    }
                }, 200);
            } else if (isSoldOut && productStatus[id] !== "soldout") {
                productStatus[id] = "soldout";
                logMessage(`❌ 商品ID ${id}:已售罄`);
            }
        }
    }

    // ====== 配置页:自动加购 ======
    function autoAddToCartOnConfigPage() {
        if (!isScriptActive) return;
        if (!location.href.includes('/cart?action=configureproduct&pid=')) return;

        let attemptCount = 0;
        const maxAttempts = 3;

        function tryClickAddToCart() {
            const btn = document.getElementById('addToCartBtn');
            if (!btn) {
                if (attemptCount < maxAttempts) {
                    attemptCount++;
                    logMessage(`🛒 未找到“加入购物车”按钮,第 ${attemptCount} 次重试...`);
                    setTimeout(tryClickAddToCart, 300);
                } else {
                    logMessage("⚠️ 未找到加入购物车按钮,放弃自动加购");
                }
                return;
            }

            if (btn.hasAttribute('data-clicked')) {
                logMessage("ℹ️ 按钮已被点击,跳过重复操作");
                return;
            }

            if (btn.textContent.trim() !== "加入购物车") {
                logMessage("ℹ️ 按钮文本已变更,可能已在处理");
                return;
            }

            logMessage("✅ 找到“加入购物车”按钮,即将点击...");
            btn.setAttribute('data-clicked', 'true');
            btn.click();

            if (stopOnSuccess) {
                stopAutoRefresh();
                logMessage("🛑 已触发停止刷新(因成功加购)");
            } else {
                logMessage("ℹ️ 加购成功,但未停止刷新(开关已关闭)");
            }
        }

        setTimeout(tryClickAddToCart, 500);
    }

 // ====== 支付页分步自动化:先确认支付 → 再处理结账 ======
function autoProceedToPayment() {
    if (!isScriptActive) return;
    if (!location.href.includes('/cart?action=viewcart')) return;

    let attempt = 0;
    const maxAttempts = 6;

    function tryStep1() {
        // === 第一步:点击“确认支付” ===
        const confirmBtn = document.querySelector('.nextStep[onclick="cartnextStep()"]');
        if (confirmBtn && window.getComputedStyle(confirmBtn).display !== 'none') {
            logMessage("✅ 检测到“确认支付”按钮,即将点击...");
            confirmBtn.click();
            logMessage("🔄 已点击“确认支付”,等待页面更新...");
            // 等待页面切换到结账步骤
            setTimeout(tryStep2, 1200);
            return true;
        }
        return false;
    }

    function tryStep2() {
        // === 第二步:处理“立刻结账”阶段 ===
        const checkoutContainer = document.querySelector('.sky-viewcart-checkout-btn');
        if (!checkoutContainer || window.getComputedStyle(checkoutContainer).display === 'none') {
            if (attempt < maxAttempts) {
                attempt++;
                logMessage(`⏳ 等待“立刻结账”按钮显示...(第 ${attempt} 次)`);
                setTimeout(tryStep2, 800);
            } else {
                logMessage("⚠️ 未进入结账步骤,放弃操作");
            }
            return;
        }

        // --- 2.1 选择支付宝手机支付 ---
        const alipayBtn = document.querySelector('.addfunds-payment[data-payment="AliPay"]');
        if (alipayBtn) {
            const radio = alipayBtn.querySelector('input[type="radio"]');
            if (radio && !radio.checked) {
                logMessage("✅ 选择“支付宝手机支付”");
                alipayBtn.click();
            }
        }

        // --- 2.2 勾选服务条款 ---
        const termsCheckbox = document.getElementById('terms');
        if (termsCheckbox && !termsCheckbox.checked) {
            logMessage("✅ 勾选“同意服务条款”");
            termsCheckbox.click(); // 触发弹窗
            setTimeout(() => handleAgreementModal(), 600);
        } else {
            // 如果已勾选,直接尝试结账
            tryCheckout();
        }
    }

    function handleAgreementModal() {
        const agreeBtn = document.getElementById('agreeBtn');
        const modal = document.getElementById('modal');
        if (!agreeBtn || !modal || modal.style.display === 'none') {
            tryCheckout();
            return;
        }

        if (agreeBtn.disabled) {
            const modalContent = modal.querySelector('.hdy_modal-content');
            if (modalContent) {
                modalContent.scrollTo(0, modalContent.scrollHeight);
                logMessage("🔽 已滚动到服务条款底部");
            }
            // 检查按钮是否启用
            setTimeout(() => {
                if (agreeBtn && !agreeBtn.disabled) {
                    logMessage("✅ 点击“我已阅读并同意”");
                    agreeBtn.click();
                }
                tryCheckout();
            }, 600);
        } else {
            agreeBtn.click();
            tryCheckout();
        }
    }

    function tryCheckout() {
        const checkoutBtn = document.querySelector('.submit-btn[type="submit"]');
        if (checkoutBtn && !checkoutBtn.disabled) {
            logMessage("🛒 点击“立刻结账”按钮");
            checkoutBtn.click();
            if (stopOnSuccess) {
                stopAutoRefresh();
                logMessage("🛑 已停止刷新(因提交结账)");
            }
        } else {
            // 结账按钮可能稍后出现,重试一次
            setTimeout(() => {
                const btn = document.querySelector('.submit-btn[type="submit"]');
                if (btn && !btn.disabled) {
                    logMessage("🛒 点击“立刻结账”按钮(延迟)");
                    btn.click();
                    if (stopOnSuccess) stopAutoRefresh();
                }
            }, 500);
        }
    }

    // 启动流程
    if (!tryStep1()) {
        // 如果“确认支付”不可见,说明已在第二步
        tryStep2();
    }
}

    // ====== 初始化 ======
    loadConfig();
    try {
        logs = JSON.parse(GM_getValue(LOG_KEY, '[]'));
        if (!Array.isArray(logs)) logs = [];
    } catch (e) { logs = []; }

    resetStatus();

    if ("Notification" in window && Notification.permission === "default") {
        Notification.requestPermission();
    }

    createConfigPanel();
    createLogPanel();

    // 根据页面类型执行逻辑
    if (location.href.includes('/cart?action=configureproduct&pid=')) {
        autoAddToCartOnConfigPage();
    } else if (location.href.includes('/cart?action=viewcart')) {
        autoProceedToPayment();
    } else {
        if (isScriptActive) {
            setInterval(checkAllProducts, 300);
            setTimeout(checkAllProducts, 100);
            setTimeout(schedulePageRefresh, 500);
        }
    }

    window.addEventListener('beforeunload', () => {
        try { GM_setValue(LOG_KEY, JSON.stringify(logs)); } catch (e) {}
        if (refreshTimeoutId) clearTimeout(refreshTimeoutId);
    });
})();
请登录后发表评论

    没有回复内容