更新脚本版本号,增加课程列表刷新逻辑,优化等待条件处理
This commit is contained in:
parent
4f0302bc07
commit
e73d0b4698
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name 平顶山学院(青书学堂)自动学习脚本
|
||||
// @namespace http://tampermonkey.net/
|
||||
// @version 2026-06-03.2
|
||||
// @version 2026-06-04.1
|
||||
// @description try to take over the world!
|
||||
// @author You
|
||||
// @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseStudy*
|
||||
|
|
@ -23,6 +23,12 @@
|
|||
const TOAST_STYLE_ID = "qingshu-auto-toast-style";
|
||||
const TOAST_DEFAULT_DURATION = 4000;
|
||||
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,所以多个通知会一起堆叠显示。
|
||||
|
|
@ -126,7 +132,7 @@
|
|||
// 等待某个 DOM 条件成立。
|
||||
// 页面里的课程列表、视频、文本课件经常是后加载的,所以不用固定延迟,
|
||||
// 而是监听 DOM 变化,直到 getResult() 返回有效结果。
|
||||
const waitForCondition = (getResult) => {
|
||||
const waitForCondition = (getResult, timeoutMs) => {
|
||||
const result = getResult();
|
||||
|
||||
if (result) {
|
||||
|
|
@ -134,12 +140,23 @@
|
|||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
let timeoutId;
|
||||
|
||||
const finish = (result) => {
|
||||
observer.disconnect();
|
||||
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
|
||||
resolve(result);
|
||||
};
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
const result = getResult();
|
||||
|
||||
if (result) {
|
||||
observer.disconnect();
|
||||
resolve(result);
|
||||
finish(result);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -147,9 +164,47 @@
|
|||
childList: 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秒”这类文字换算成秒数,
|
||||
// 方便判断是否已经学满 5 分钟。
|
||||
const parseStudySeconds = (text) => {
|
||||
|
|
@ -220,12 +275,22 @@
|
|||
notify("进入准备阶段,等待课程列表", "info");
|
||||
|
||||
// 课程列表是异步渲染的,等到至少有一个课程节点后再开始遍历。
|
||||
const items = await waitForCondition(() => {
|
||||
const list = document.querySelector("#list");
|
||||
const items = list ? list.querySelectorAll("li > a.node") : [];
|
||||
const items = await waitForCondition(
|
||||
() => {
|
||||
const list = document.querySelector("#list");
|
||||
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");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue