从选课弹窗中留下能选的课。
// ==UserScript==// @name SIT上应教务系统选课助手// @description 从选课弹窗中留下能选的课。// @author RainSlide// @namespace RainSlide// @match http://ems1.sit.edu.cn:85/student/selCourse/studentSel/teachclasslist.jsp*// @version 1.0// @grant none// @run-at document-idle// ==/UserScript==if (localStorage && !localStorage.selectedCourse)fetch('http://ems1.sit.edu.cn:85/student/selCourse/syllabuslist3.jsp', {credentials: 'include',}).then((response) =>new DOMParser().parseFromString(response.text(), 'text/html')).then((fetchedDoc) =>(localStorage.selectedCourse = Array.from((() => {const tables = fetchedDoc.getElementsByTagName('table');for (let i = 0; i < tables.length; i++) {if (// 表格首行元素内容为“课程表”tables[i].querySelector('th.list') &&tables[i].querySelector('th.list').textContent === '课程表')return tables[i];}alart('找不到选课课程表,请登录!');return null;})().querySelectorAll('tr')).slice(2).map((tr) =>Array.from(tr.querySelectorAll('td[rowspan]')).map((td) =>[td.cellIndex,+tr.firstElementChild.textContent,+tr.firstElementChild.textContent +td.rowSpan -1,].join(' '))).flat().join('\n'))).then(() => alart('请刷新一次!'));(() => {if (!localStorage) {alart('换个浏览器吧');return false;}const style = document.createElement('style');style.textContent = '.hidden { display: none; }';document.head.appendChild(style);// 已选课程上课时间数据// "2 1 2\n3 1 2\n5 1 2\n1 3 4\n2 3 4\n3 3 4\n5 3 4\n3 5 6\n4 5 6\n1 7 8\n2 7 8\n1 9 11\n2 9 11\n3 9 11"const selectedCourse = localStorage.selectedCourse.split('\n').map((str) =>str.replace(// 1 2 3 => 周1,第2-3节/(\d+) (\d+) (\d+)/g,(match, p1, p2, p3) => `周${p1},第${p2}-${p3}节`));// 隐藏课程并格式化打印内容const hideAndLog = (tr, str) => {tr.classList.add('hidden');const strArray = tr.textContent.trim().replace(/\s*选择$/g, '').replace(/\s*\n\s*/g, '\n').split('\n');if (strArray[1].length < 3)strArray[1] += ' '.repeat(3 - strArray[1].length);if (strArray[2].length < 3)strArray[2] += ' '.repeat(3 - strArray[2].length);if (strArray[3].length < 3)strArray[3] += ' '.repeat(3 - strArray[3].length);console.log(str + ':' + strArray.join(' | '));};Array.from(document.body.querySelectorAll('tr[style][onclick]')).forEach((tr) => {// 从指定索引的 <td> 子元素中获取字符串const getStringFromTd = (nthIndex) =>tr.querySelector(':scope > td:nth-of-type(' + nthIndex + ')').textContent;// 从指定索引的 <td> 子元素中获取数字const getNumberFromTd = (nthIndex) => +getStringFromTd(nthIndex);// 已选人数 >= 最大人数getNumberFromTd(3) >= getNumberFromTd(2) &&hideAndLog(tr, '选满了');// 检查上课时间selectedCourse.some((course) =>getStringFromTd(5).includes(course)) && hideAndLog(tr, '有冲突');});})();