wsxy_autoLearn

网上学院函数库:自动学习

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/396002/898881/wsxy_autoLearn.js

  1. // ==UserScript==
  2. // @name wsxy_autoLearn
  3. // @namespace Vionlentmonkey
  4. // @version 0.14.5
  5. // @description 网上学院函数库:自动学习
  6. // ==/UserScript==
  7.  
  8. /**
  9. * 自动报名高学分课程。2020 年初,高于 1 学分的有且仅有 20 门 3 学分课程。
  10. * @param {Array} waitCourseInfo
  11. */
  12. const autoSignupMaxCredit = async (waitCourseInfo) => {
  13. // 需要 iframe 提升才会执行
  14. if (window.top !== window.self) return;
  15. const courses = document.querySelectorAll('#requiredCourseTable .course');
  16. for (const w of waitCourseInfo) {
  17. /**
  18. * 学分高且未报名
  19. * 取消报名的也有 apply_pk,不能作为判断依据
  20. * 但没有进度点数 jdpoint
  21. */
  22. if (w.courseCredit <= 1 || w.jdpoint) continue;
  23. console.log(w.course_name);
  24. for (const c of courses) {
  25. const coursePk = Number(c.getElementsByClassName('coursePk')[0].textContent);
  26. if (coursePk !== w.course_pk) continue;
  27. c.click();
  28. const btn = document.getElementsByClassName('layui-layer-btn0');
  29. if (btn.length !== 1) continue;
  30. btn[0].click();
  31. }
  32. }
  33. };
  34.  
  35. /**
  36. * 自动报名高学时课程
  37. * @param {Array} waitCourseInfo
  38. */
  39. const autoSignupMaxTime = async (waitCourseInfo) => {
  40. // 需要 iframe 提升才会执行
  41. if (window.top !== window.self) return;
  42. // 存储所有未报名课程的课时和对应编号
  43. let timesMap = new Map();
  44. for (const w of waitCourseInfo) {
  45. // 报名后等于零,undefined 代表未报名
  46. if (w.jdpoint !== undefined) continue;
  47. timesMap.set(w.courseTime, w.course_pk);
  48. }
  49. const timesArray = [...timesMap.keys()];
  50. const longest = Math.max(...timesArray);
  51. console.log(`+${longest}h`);
  52. const maxTimeCourse_pk = timesMap.get(longest);
  53. const courses = document.querySelectorAll('#requiredCourseTable .course');
  54. for (const c of courses) {
  55. const coursePk = Number(c.getElementsByClassName('coursePk')[0].textContent);
  56. if (coursePk !== maxTimeCourse_pk) continue;
  57. c.click();
  58. const btn = document.getElementsByClassName('layui-layer-btn0');
  59. if (btn.length !== 1) continue;
  60. btn[0].click();
  61. }
  62. };
  63.  
  64. /**
  65. * 自动打开考试
  66. * @param {NodeIterator} exams
  67. */
  68. const autoOpenExam = (exams) => {
  69. for (const exam of exams) {
  70. const examURL = location.origin + '/sfxzwsxy/' + exam.getAttribute('onclick').split("'")[1];
  71. // 魔法打开的考卷确认交卷后可能不能自动关闭,只得如此暴力处理,1分钟后强行关闭。
  72. const autoExam = GM_openInTab(examURL, true);
  73. setTimeout(autoExam.close, 60000);
  74. }
  75. };
  76.  
  77. /**
  78. * 自动打开待学习课程
  79. * @param {Array} waitCourseInfo
  80. */
  81. const autoOpenTrain = async (waitCourseInfo) => {
  82. let i = 0;
  83. // 全部未完成必修课程。为同时解决学时学分问题,只关注必修课。
  84. const courses = document.querySelectorAll('#requiredCourseTable .course');
  85. for (const c of courses) {
  86. const applyPk = Number(c.getElementsByClassName('applyPk')[0].textContent);
  87. const jdjs = c.getElementsByClassName('jdjs')[0].textContent; // 完成进度定性
  88. // 未报名课程 applyPk === '',取消报名的课程却能直接获取 applyPk,可能不适合使用 for length++ 循环
  89. if (jdjs !== '完成进度') continue;
  90. for (w of waitCourseInfo) {
  91. if (w.apply_pk !== applyPk) continue;
  92. const trainURL =
  93. location.origin +
  94. '/sfxzwsxy/jypxks/modules/train/ware/course_ware_view.jsp?applyPk=' +
  95. applyPk +
  96. '&courseType=1';
  97. const openClose = GM_openInTab(trainURL, true);
  98. // 25 分钟自动关闭
  99. setTimeout(openClose.close, 1500000);
  100. i++;
  101. if (i >= GM_config.get('batch')) {
  102. console.log(`已尝试批量打开${i}个课程`);
  103. return;
  104. }
  105. }
  106. }
  107. };
  108.  
  109. /**
  110. * 自动学习的主函数
  111. * @param {NodeIterator} exams
  112. * @param {Array} waitCourseInfo
  113. */
  114. const autoLearn = async (exams, waitCourseInfo) => {
  115. if (window.top !== window.self) return;
  116. // 30 分钟刷新一次
  117. setInterval(() => {
  118. location.reload();
  119. }, 1800000);
  120. const total_hour = Number(localStorage.getItem('total_hour')); //规定需达到的总学时
  121. const required_hour = Number(localStorage.getItem('required_hour')); //规定需达到的必修学时
  122. const required_credit = Number(localStorage.getItem('required_credit')); //规定需达到的总学分
  123. const user_total_hour = Number(localStorage.getItem('user_total_hour')); //用户已获得的总学时
  124. const user_required_hour = Number(localStorage.getItem('user_required_hour')); //用户已获得的必修学时
  125. const user_required_credit = Number(localStorage.getItem('user_required_credit')); //用户已获得的总学分
  126.  
  127. console.log(`已获得:必修学时:${user_required_hour},学分:${user_required_credit}`);
  128. // 判断是否已完成。首次在新标签页打开本页显然是未完成,但刷新后可能进入已完成状态。
  129. if (
  130. user_total_hour >= total_hour &&
  131. user_required_hour >= required_hour &&
  132. user_required_credit >= required_credit
  133. ) {
  134. console.log(`本学年任务已经完成`);
  135. return;
  136. } else {
  137. // 初始化预期学时/学分为已得值
  138. let pendingCredit = user_required_credit;
  139. let pendingTime = user_total_hour;
  140. // 向预期学时/学分添加已报名课程数据
  141. for (w of waitCourseInfo) {
  142. // jdpoint 保证已报名,否则无法处理取消报名的问题
  143. if (w.jdpoint >= 0) {
  144. pendingCredit += w.courseCredit;
  145. pendingTime += w.courseTime;
  146. }
  147. }
  148. if (user_required_credit < required_credit && exams.length > 0) {
  149. console.log('学分未满,有待考试课程');
  150. autoOpenExam(exams);
  151. // 1 分钟后考完关闭,1.5 分钟后刷新
  152. setTimeout(() => {
  153. location.reload();
  154. }, 90000);
  155. } else if (pendingTime < total_hour) {
  156. console.log(
  157. `已报名(不含待考试课程):必修学时:${pendingTime.toFixed(
  158. 1
  159. )},学分:${pendingCredit},继续报名。`
  160. );
  161. autoSignupMaxTime(waitCourseInfo);
  162. } else if (pendingTime >= total_hour && pendingCredit < required_credit) {
  163. // 因为全部学习必修课,出现本状况可能很小,暂不处理
  164. console.log(
  165. `已报名(不含待考试课程):必修学时:${pendingTime.toFixed(
  166. 1
  167. )},学分:${pendingCredit},有待处理。`
  168. );
  169. } else if (pendingTime >= total_hour && pendingCredit >= required_credit) {
  170. console.log(
  171. `已报名(不含待考试课程):必修学时:${pendingTime.toFixed(
  172. 1
  173. )},学分:${pendingCredit},已达预期。`
  174. );
  175. if (user_required_hour < total_hour) {
  176. console.log('学时未满,自动打开已报名课程,将定时关闭。');
  177. autoOpenTrain(waitCourseInfo);
  178. }
  179. }
  180. }
  181. };

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址