🏠 Home 

SWPU绩点计算

在jwxt.swpu.edu.cn的“综合查询-全部成绩”以及“本学期成绩”页面显示各个学期的平均学分绩点,加粗并打上“※”号的课程是计算进去的,有“(跳过)”注释的证明是英语四六级或暂时未出成绩的课程,不计算在内(若要不计算选修课,请把源代码最上面的skipElectives变量的值改为false),什么标记都没有的可能是没有计算进去,刷新网页即可。(结果可能有出入,仅供参考)


安装此脚本?
// ==UserScript==
// @name         SWPU绩点计算
// @namespace    http://merept.github.io/
// @version      1.4.4
// @license      MIT
// @description  在jwxt.swpu.edu.cn的“综合查询-全部成绩”以及“本学期成绩”页面显示各个学期的平均学分绩点,加粗并打上“※”号的课程是计算进去的,有“(跳过)”注释的证明是英语四六级或暂时未出成绩的课程,不计算在内(若要不计算选修课,请把源代码最上面的skipElectives变量的值改为false),什么标记都没有的可能是没有计算进去,刷新网页即可。(结果可能有出入,仅供参考)
// @author       MerePT
// @match        jwxt.swpu.edu.cn/loginAction.do
// @match        jwxt-swpu-edu-cn.###.swpu.edu.cn:8118/loginAction.do
// @icon         https://pic.imgdb.cn/item/6388c62816f2c2beb1c0909d.png
// @grant        unsafeWindow
// ==/UserScript==
const skipElectives = false; //true: 不计算选修课,false: 计算选修课,默认计算选修课
/**
* 判断是否为 CET 相关的课程
* @param {string} name 课程名称
* @returns {boolean} true: 是 CET 相关课程; false: 不是
*/
function isEnglishTest(name) {
return new RegExp("英语实践+").test(name) || new RegExp("全国英语+").test(name);
}
/**
* 判断是否为选修课, 若用户设置变量 {skipElectives} 为 false 则直接返回 false
* @param {string} course 课程号
* @returns {boolean} true: 是选修课; false: 不是或者用户设置不跳过选修课
*/
function isElectives(course) {
return skipElectives && course.substring(0, 2) === '00';
}
/**
* 判断字符串是否为空
* @param {string} str 输入字符串
* @returns {boolean} true: 字符串为空; false: 不为空
*/
function isNullOrEmpty(str) {
return !str || new RegExp("^[\s ]*$").test(str);
}
/**
* 判断课程是否缓考
* @param {HTMLCollection} datas 课程各项数据组成的数组
* @returns {boolean} true: 该课程缓考; false: 正常状态未缓考
*/
function isDeferrd(datas) {
return datas.length === 13 && !isNullOrEmpty(datas[11].innerText)
}
/**
* 判断该课程是否计入绩点
* @param {HTMLCollection} datas 课程各项数据组成的数组
* @param {number} p 成绩所在位置
* @returns {boolean} true: 不计入该课程成绩; false: 计入
*/
function isNotCount(datas, p) {
return isEnglishTest(datas[2].innerText) || isElectives(datas[0].innerText) ||
isNullOrEmpty(datas[p].innerText) || isDeferrd(datas);
}
/**
* 将挂科的课程标红
* @param {HTMLCollection} datas 挂科的课程
*/
function turnToRed(datas) {
for (let [i, d] of datas.entries()) {
if (i === 2) {
d.style = "font-weight:bolder;color:red"
} else {
d.style = "color:red"
}
}
}
/**
* 计算单个学期的平均学分绩点
* @param {HTMLCollection} obj 该学期的 HTML 集合
* @param {object} d 存有总学分、总成绩、已通过学分、挂科数的对象
* @param {number} scoreIndex 成绩所在的位置
* @returns {object} 存有总学分、总成绩、已通过学分、挂科数的对象
*/
function calSingleGpa(obj, d, scoreIndex, imgIndex) {
for (let o of obj) {
let datas = o.querySelectorAll('td');
var img = datas[imgIndex].firstElementChild;
if (img != null) {
img.attributes.onclick.value = img.attributes.onclick.value.replace('cjmx', 'window.open');
}
if (isNotCount(datas, scoreIndex)) {
datas[2].innerText += ' (跳过)';
continue;
}
// console.log(datas[2].innerText + ' - 学分:' + datas[4].innerText + ' - 成绩:' + datas[scoreIndex].children[0].innerText);
let p = Number(datas[4].innerText);
d.totalPoints += p
let score = Number(datas[scoreIndex].innerText);
let gradePoint = 0;
if (score >= 60) {
gradePoint = (score - 60) / 10 + 1;
d.totalNotFailedPoints += p;
datas[2].style = "font-weight:bolder";
} else {
d.fails++;
turnToRed(datas);
}
d.totalScores += gradePoint * p;
datas[2].innerText += ' ※';
// var img = datas[imgIndex].firstElementChild;
// img.attributes.onclick.value = img.attributes.onclick.value.replace('cjmx', 'window.open');
}
return d;
}
/**
* 计算平均学分绩点
* @param {HTMLIFrameElement} frame 记录了课程信息的网页框架
* @param {number} scoreIndex 成绩所在的位置
* @param imgIndex
* @returns {object[]} 返回包含总学分、总成绩、已通过学分、挂科数的对象的数组
*/
function calGpa(frame, scoreIndex, imgIndex) {
let data = {
totalPoints: 0,
totalScores: 0,
totalNotFailedPoints: 0,
fails: 0
};
let datas = [];
let scores = frame.document.querySelectorAll('.titleTop2');
for (let s of scores) {
let even = s.querySelectorAll('.even');
data = calSingleGpa(even, data, scoreIndex, imgIndex);
let ef = s.querySelectorAll('.evenfocus');
data = calSingleGpa(ef, data, scoreIndex, imgIndex);
let odd = s.querySelectorAll('.odd');
data = calSingleGpa(odd, data, scoreIndex, imgIndex);
datas.push(data);
data = {
totalPoints: 0,
totalScores: 0,
totalNotFailedPoints: 0,
fails: 0
};
}
return datas;
// console.log('totalPoints:' + totalPoints);
// console.log('totalScores:' + totalScores);
}
function main() {
// “综合查询 - 全部成绩”页面的 GPA 显示
setInterval(function() {
if (document.querySelector("frame[name='bottomFrame']").contentWindow.document.querySelector("#mainF").contentWindow.document.querySelector("iframe[name='lnqbIfra']") != null) {
if (document.querySelector("frame[name='bottomFrame']").contentWindow.document.querySelector("#mainF").contentWindow.document.querySelector("iframe[name='lnqbIfra']").contentWindow == undefined) {
return;
}
/**
* main 框架
*/
let mainF = document.querySelector("frame[name='bottomFrame']").contentWindow
.document.querySelector("#mainF").contentWindow;
/**
* 全部成绩页面内的 lnqbIfra 框架
*/
let scoreF = mainF.document.querySelector("iframe[name='lnqbIfra']").contentWindow;
if (scoreF.document.body != null && scoreF.document.body.getAttribute('is-calculated') == undefined && scoreF.document.querySelectorAll('.title').length != 0) {
// clearInterval(timer);
scoreF.document.body.setAttribute("is-calculated", "true"); // 设置属性避免延时时持续对框架内容进行操作
// 延时等待框架加载完成
setTimeout(function() {
let r###lts = calGpa(scoreF, 6, 7);
/**
* 每学期的标题位置
*/
let titles = scoreF.document.querySelectorAll('.title');
/**
* 每学期底部的汇总信息位置
*/
let pa = scoreF.document.querySelectorAll('.pageAlign');
/**
* “历年成绩”标题位置
*/
let headTitle = mainF.document.querySelector('#tblHead');
/**
* 侧边栏各学期跳转链接位置
*/
let slide = mainF.document.querySelector('.table_k')
.querySelectorAll('table')[7]
.querySelectorAll('a');
/**
* 全部成绩
*/
let total = {
/**
* 学分
*/
points: 0,
/**
* 绩点
*/
scores: 0
};
for (let i = 0; i < titles.length; i++) {
// console.log(titles[i]);
let b = document.createElement('b');
let r = r###lts[i].totalScores / r###lts[i].totalPoints
let gpa = isNaN(r) ? '0.00' : r.toFixed(2);
b.innerText = '\xa0本学期平均学分绩点: ' + gpa;
titles[i].getElementsByTagName('td')[2].appendChild(b);
pa[i].querySelectorAll('table')[1]
.querySelector('td').innerText += '\xa0\xa0平均学分绩点:\xa0\xa0' + gpa;
slide[i].innerText += slide[i].getAttribute('is-add')==undefined ? ("\xa0\xa0GPA: " + gpa) : '';
slide[i].setAttribute('is-add', 'true');
total.points += r###lts[i].totalPoints;
total.scores += r###lts[i].totalScores;
}
let s = "\xa0\xa0GPA: " + (total.scores / total.points).toFixed(2);
headTitle.querySelectorAll('td')[2]
.querySelector('b').innerText += headTitle.getAttribute('is-add')==undefined ? s : '';
headTitle.setAttribute('is-add', 'true');
}, 1500);
}
}
},30);
// “综合查询 - 本学期成绩”页面的 GPA 显示
setInterval(function() {
if (document.querySelector("frame[name='bottomFrame']").contentWindow
.document.querySelector("#mainF").contentWindow != undefined)
{
/**
* main 框架
*/
let mainF = document.querySelector("frame[name='bottomFrame']").contentWindow
.document.querySelector("#mainF").contentWindow;
/**
* 各页面 mainF 框架中的标题位置
*/
let titles = mainF.document.querySelectorAll('.title');
// 当标题位置的 innerText 为“本学期成绩”时执行
if (mainF.document.body != null && mainF.document.body.getAttribute('is-calculated') == undefined && titles.length != 0 && titles[0].getElementsByTagName('td')[2].innerText.trim() == '本学期成绩查询列表') {
// clearInterval(timer);
mainF.document.body.setAttribute("is-calculated", "true"); // 设置属性避免延时时持续对框架内容进行操作
setTimeout(function() {
let r###lts = calGpa(mainF, 9, 12);
/**
* “本学期成绩”标题位置
*/
let title = mainF.document.querySelector('.title');
let r = r###lts[0].totalScores / r###lts[0].totalPoints;
let gpa = isNaN(r) ? '0.00' : r.toFixed(2);
// console.log(titles[i]);
let b = document.createElement('b');
b.innerText = '\xa0平均学分绩点: ' + gpa;
title.getElementsByTagName('td')[2].appendChild(b);
let r###ltText = '总修读学分:\xa0' + r###lts[0].totalPoints
+ '\xa0\xa0已通过学分:\xa0' + r###lts[0].totalNotFailedPoints
+ '\xa0\xa0挂科数:\xa0' + r###lts[0].fails
+ '\xa0\xa0平均学分绩点: \xa0' + gpa;
let bottomHTML = `<table width="100%" align="center" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td height="21">`+ r###ltText +`</td>
</tr>
</tbody>
</table>`;
mainF.document.querySelectorAll('td')[8].innerHTML += bottomHTML;
}, 1500);
}
}
},30);
}
(function() {
let timer = setInterval(function() {
if (document.querySelector("frame[name='bottomFrame']").contentWindow
.document.querySelector("#mainF").contentWindow
.document.querySelectorAll("title")[0].innerText === '成绩查询') {
clearInterval(timer);
main();
}
},30);
})();