您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
按序批量打开支付页并自动执行“微信支付→去支付”,当微信支付页 modal-open 后,自动关闭付款页和原支付页。
// ==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); } })();