Greasy Fork

Greasy Fork is available in English.

自动打开威海专技专业课购买页面

按序批量打开支付页并自动执行“微信支付→去支付”,当微信支付页 modal-open 后,自动关闭付款页和原支付页。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         自动打开威海专技专业课购买页面
// @namespace    http://tampermonkey.net/
// @version      0.7
// @description  按序批量打开支付页并自动执行“微信支付→去支付”,当微信支付页 modal-open 后,自动关闭付款页和原支付页。
// @match        https://sdwh-zyk.yxlearning.com/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // —— 延时参数(毫秒) ——
    const WX_CLICK_DELAY   = 500;
    const PAY_CLICK_DELAY  = 800;
    const POLL_INTERVAL    = 500;

    const href = location.href;

    // —— 简易日志输出 ——
    function appendLog(msg) {
        const ta = document.getElementById('tm-log-box');
        const time = new Date().toLocaleTimeString();
        const line = `[${time}] ${msg}\n`;
        if (ta) {
            ta.value += line;
            ta.scrollTop = ta.scrollHeight;
        }
        console.log(line.trim());
    }

    // —— 支付页:/order/pay?classId= 自动点击逻辑,不再自动关闭 ——
    if (/\/order\/pay\?classId=/.test(href)) {
        function waitAndClick(selector, delay, cb) {
            const el = document.querySelector(selector);
            if (el) {
                setTimeout(() => {
                    el.click();
                    appendLog(`点击 ${selector}`);
                    if (cb) cb();
                }, delay);
            } else {
                setTimeout(() => waitAndClick(selector, delay, cb), 300);
            }
        }

        // 先选中微信支付,再点击去支付
        waitAndClick('div[du-click="wxwebpay"]', WX_CLICK_DELAY, () => {
            waitAndClick('span[du-click="pay"]', PAY_CLICK_DELAY, () => {
                appendLog('已点击“去支付”,等待微信支付页面处理');
                // 不在此处关闭,等待子窗口 modal-open 后再统一关闭
            });
        });
        return;  // 不注入列表页面板
    }

    // —— 微信付款确认页:/order/pay-wechat-pay? 监控 modal-open 并关闭窗口 ——
    if (/\/order\/pay-wechat-pay\?/.test(href)) {
        appendLog('进入微信支付确认页,开始监控 body class');
        const observer = new MutationObserver(() => {
            if (document.body.classList.contains('modal-open')) {
                appendLog('检测到 modal-open,关闭当前窗口及原支付页');
                observer.disconnect();
                const openerWin = window.opener;
                window.close();  // 先关闭当前微信支付页
                if (openerWin && !openerWin.closed) {
                    openerWin.close();  // 再关闭原 /order/pay?classId= 支付页
                }
            }
        });
        observer.observe(document.body, { attributes: true, attributeFilter: ['class'] });
        return;  // 不注入列表页面板
    }

    // —— 其余页面:课程列表页按序批量打开逻辑 + 日志面板 ——
    const panel = document.createElement('div');
    Object.assign(panel.style, {
        position: 'fixed', top: '10px', right: '10px', zIndex: '9999',
        backgroundColor: '#fff', border: '1px solid #ccc',
        padding: '8px', borderRadius: '4px',
        boxShadow: '0 2px 6px rgba(0,0,0,0.2)', fontFamily: 'Arial, sans-serif'
    });

    // Start / Stop 按钮
    const startBtn = document.createElement('button');
    startBtn.textContent = 'Start';
    Object.assign(startBtn.style, { marginRight: '6px', padding: '4px 8px', cursor: 'pointer' });
    const stopBtn = document.createElement('button');
    stopBtn.textContent = 'Stop';
    stopBtn.disabled = true;
    Object.assign(stopBtn.style, { padding: '4px 8px', cursor: 'pointer' });

    // 日志输出框
    const logBox = document.createElement('textarea');
    logBox.id = 'tm-log-box';
    Object.assign(logBox.style, {
        display: 'block', width: '300px', height: '150px',
        marginTop: '8px', padding: '4px', fontSize: '12px',
        fontFamily: 'monospace', backgroundColor: '#f5f5f5',
        color: '#333', border: '1px solid #ccc', resize: 'none',
        overflowY: 'auto'
    });
    logBox.readOnly = true;

    panel.appendChild(startBtn);
    panel.appendChild(stopBtn);
    panel.appendChild(logBox);
    document.body.appendChild(panel);

    let urls = [], idx = 0, running = false;
    let childWin = null, pollTimer = null;

    startBtn.addEventListener('click', () => {
        if (running) return;
        const anchors = document.querySelectorAll('div.row.dd a[du-click="btnClick"]');
        urls = Array.from(anchors).map(a =>
            `https://sdwh-zyk.yxlearning.com/order/pay?classId=${encodeURIComponent(a.id)}`
        );
        if (!urls.length) {
            alert('未找到任何可批量打开的课程支付链接。');
            return;
        }
        running = true; idx = 0;
        startBtn.disabled = true; stopBtn.disabled = false;
        logBox.value = ''; appendLog(`准备打开 ${urls.length} 个支付页`);
        openNextSequential();
    });

    stopBtn.addEventListener('click', () => {
        running = false;
        startBtn.disabled = false; stopBtn.disabled = true;
        if (pollTimer) clearInterval(pollTimer);
        appendLog('已停止批量操作');
    });

    // 按序打开,每次等待子窗口关闭后再继续
    function openNextSequential() {
        if (!running || idx >= urls.length) {
            running = false;
            startBtn.disabled = false; stopBtn.disabled = true;
            appendLog('所有支付页已处理完毕');
            return;
        }
        const url = urls[idx];
        appendLog(`第 ${idx + 1} 个:打开 ${url}`);
        childWin = window.open(url, '_blank');
        pollTimer = setInterval(() => {
            if (!childWin || childWin.closed) {
                clearInterval(pollTimer);
                appendLog(`第 ${idx + 1} 个支付页已关闭`);
                idx++;
                openNextSequential();
            }
        }, POLL_INTERVAL);
    }

})();