// ==UserScript==
// @name 81联聘-批量自动学完助手 v1.2
// @namespace https://github.com/yourname
// @version 1.2
// @description 修复稳定性问题,增强错误处理和元素检测
// @author You
// @match https://learn.81lianpin.com/myCourses/details/*
// @grant none
// ==/UserScript==
/* 让页面自身的未捕获异常不再抛到控制台(仅视觉清爽,不影响功能) */
window.addEventListener('error', e => {
if (e.filename?.includes('index.vue')) e.preventDefault();
});
(() => {
'use strict';
const log = (...a) => console.log('[81批量助手]', ...a);
const sleep = t => new Promise(r => setTimeout(r, t));
let isProcessing = false;
let isCompletedAlertShown = false; // 用于控制完成提示只显示一次
/* -------------------- 路由 -------------------- */
const onList = () => location.pathname === '/myCourses';
const onChapter = () => location.pathname.includes('/myCourses/details/');
/* -------------------- 面板 -------------------- */
function drawPanel(list) {
const old = document.getElementById('lp-helper-panel');
if (old) old.remove();
const box = document.createElement('div');
box.id = 'lp-helper-panel';
box.innerHTML = `
未学完小节(共 ${list.length} 个)
${list.map((it, i) => `- ${it.title}
`).join('')}
`;
document.body.appendChild(box);
/* 单独学 */
box.querySelectorAll('.btn:not([id])').forEach(b => {
b.onclick = () => handleOne(list[+b.dataset.index]);
});
/* 重新扫描 */
box.querySelector('#lp-rescan').onclick = () => {
box.remove();
main();
};
}
/* -------------------- 单个小节 -------------------- */
async function handleOne(item) {
log('进入小节', item.title);
// 滚动到元素并点击
item.node.scrollIntoView({ behavior: 'smooth', block: 'center' });
await sleep(800);
try {
item.node.click();
} catch (e) {
log('点击元素失败:', e);
// 尝试其他方式触发点击
const event = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
});
item.node.dispatchEvent(event);
}
/* 改进的视频检测机制 */
let video = null;
const maxWaitTime = 15000; // 15秒超时
const startTime = Date.now();
while (!video && Date.now() - startTime < maxWaitTime) {
video = document.querySelector('video');
if (video) break;
await sleep(500);
}
if (!video) {
log('未检测到