更新脚本版本号,增加课程列表刷新逻辑,优化等待条件处理
This commit is contained in:
parent
4f0302bc07
commit
e73d0b4698
|
|
@ -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 items = list ? list.querySelectorAll("li > a.node") : [];
|
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");
|
notify("获取到课程数量:" + items.length, "success");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue