更新脚本版本号,增加课程列表刷新逻辑,优化等待条件处理

This commit is contained in:
竟康 2026-06-04 08:33:57 +08:00
parent 4f0302bc07
commit e73d0b4698
1 changed files with 74 additions and 9 deletions

View File

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name 平顶山学院(青书学堂)自动学习脚本 // @name 平顶山学院(青书学堂)自动学习脚本
// @namespace http://tampermonkey.net/ // @namespace http://tampermonkey.net/
// @version 2026-06-03.2 // @version 2026-06-04.1
// @description try to take over the world! // @description try to take over the world!
// @author You // @author You
// @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseStudy* // @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseStudy*
@ -23,6 +23,12 @@
const TOAST_STYLE_ID = "qingshu-auto-toast-style"; const TOAST_STYLE_ID = "qingshu-auto-toast-style";
const TOAST_DEFAULT_DURATION = 4000; const TOAST_DEFAULT_DURATION = 4000;
const HEARTBEAT_SECONDS = 10; const HEARTBEAT_SECONDS = 10;
const COURSE_LIST_WAIT_SECONDS = 60;
const MAX_COURSE_LIST_REFRESH_COUNT = 3;
const COURSE_LIST_REFRESH_KEY =
"qingshu_auto_course_list_refresh_count:" +
location.pathname +
location.search;
// 创建右下角 toast 容器和样式。 // 创建右下角 toast 容器和样式。
// 每次通知都会创建一个新的 toast所以多个通知会一起堆叠显示。 // 每次通知都会创建一个新的 toast所以多个通知会一起堆叠显示。
@ -126,7 +132,7 @@
// 等待某个 DOM 条件成立。 // 等待某个 DOM 条件成立。
// 页面里的课程列表、视频、文本课件经常是后加载的,所以不用固定延迟, // 页面里的课程列表、视频、文本课件经常是后加载的,所以不用固定延迟,
// 而是监听 DOM 变化,直到 getResult() 返回有效结果。 // 而是监听 DOM 变化,直到 getResult() 返回有效结果。
const waitForCondition = (getResult) => { const waitForCondition = (getResult, timeoutMs) => {
const result = getResult(); const result = getResult();
if (result) { if (result) {
@ -134,12 +140,23 @@
} }
return new Promise((resolve) => { return new Promise((resolve) => {
let timeoutId;
const finish = (result) => {
observer.disconnect();
if (timeoutId) {
clearTimeout(timeoutId);
}
resolve(result);
};
const observer = new MutationObserver(() => { const observer = new MutationObserver(() => {
const result = getResult(); const result = getResult();
if (result) { if (result) {
observer.disconnect(); finish(result);
resolve(result);
} }
}); });
@ -147,9 +164,47 @@
childList: true, childList: true,
subtree: true, subtree: true,
}); });
if (timeoutMs) {
timeoutId = setTimeout(() => {
finish(null);
}, timeoutMs);
}
}); });
}; };
// CourseStudy 偶尔会因为请求失败(例如 429导致课程列表一直不出现。
// 这里记录刷新次数:等 1 分钟还没有列表就刷新,最多刷新 3 次。
const refreshCourseStudyIfNeeded = () => {
const refreshCount = Number(sessionStorage.getItem(COURSE_LIST_REFRESH_KEY) || 0);
if (refreshCount >= MAX_COURSE_LIST_REFRESH_COUNT) {
notify(
"课程列表等待超时已刷新3次仍未加载停止自动刷新",
"error",
8000
);
return;
}
const nextRefreshCount = refreshCount + 1;
sessionStorage.setItem(COURSE_LIST_REFRESH_KEY, String(nextRefreshCount));
notify(
"课程列表等待超过1分钟准备刷新页面第" +
nextRefreshCount +
"/" +
MAX_COURSE_LIST_REFRESH_COUNT +
"次)",
"warning",
8000
);
location.reload();
};
const clearCourseStudyRefreshCount = () => {
sessionStorage.removeItem(COURSE_LIST_REFRESH_KEY);
};
// 把“共4分钟49秒”“共1小时2分钟3秒”这类文字换算成秒数 // 把“共4分钟49秒”“共1小时2分钟3秒”这类文字换算成秒数
// 方便判断是否已经学满 5 分钟。 // 方便判断是否已经学满 5 分钟。
const parseStudySeconds = (text) => { const parseStudySeconds = (text) => {
@ -220,12 +275,22 @@
notify("进入准备阶段,等待课程列表", "info"); notify("进入准备阶段,等待课程列表", "info");
// 课程列表是异步渲染的,等到至少有一个课程节点后再开始遍历。 // 课程列表是异步渲染的,等到至少有一个课程节点后再开始遍历。
const items = await waitForCondition(() => { const items = await waitForCondition(
() => {
const list = document.querySelector("#list"); const list = document.querySelector("#list");
const items = list ? list.querySelectorAll("li > a.node") : []; const items = list ? list.querySelectorAll("li > a.node") : [];
return items.length > 0 ? items : null; return items.length > 0 ? items : null;
}); },
COURSE_LIST_WAIT_SECONDS * 1000
);
if (!items) {
refreshCourseStudyIfNeeded();
return;
}
clearCourseStudyRefreshCount();
notify("获取到课程数量:" + items.length, "success"); notify("获取到课程数量:" + items.length, "success");