教务系统学分与GPA

武汉大学教务系统成绩页面各学分与GPA计算器

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         教务系统学分与GPA
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  武汉大学教务系统成绩页面各学分与GPA计算器
// @author       Arichy
// @match        http://210.42.121.132/stu/stu_index.jsp
// @match        http://210.42.121.133/stu/stu_index.jsp
// @match        http://210.42.121.134/stu/stu_index.jsp
// @match        http://210.42.121.241/stu/stu_index.jsp
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function calculate(courseArr){
        var gpSum = 0;//所有课程的绩点*学分的和
        var creditSum = 0;//所有课程学分的和

        var score;//每个课程的分数
        var credit;//每个课程的学分
        var gp;//每个课程的学分绩
        var course;//每个课程

        var credit0 = 0;//公选
        var credit1 = 0;//公必
        var credit2 = 0;//专选
        var credit3 = 0;//专必
        var gpa = 0;

        for(var i=0;i<courseArr.length;i++){
            course = courseArr[i];
            score = parseFloat(course.score);
            credit = parseFloat(course.credit);

            if(score>=90){
                gp = 4.0;
            }
            else if(score>=85){
                gp = 3.7;
            }
            else if(score>=82){
                gp = 3.3;
            }
            else if(score>=78){
                gp = 3.0;
            }
            else if(score>=75){
                gp = 2.7;
            }
            else if(score>=72){
                gp = 2.3;
            }
            else if(score>=68){
                gp = 2.0;
            }
            else if(score>=64){
                gp = 1.5;
            }
            else if(score>=60){
                gp = 1.0;
            }
            else{
                gp = 0.0;
            }

            switch(course.type){
                case 0: credit0 += credit; break;
                case 1: credit1 += credit; break;
                case 2: credit2 += credit; break;
                case 3: credit3 += credit; break;
            }

            creditSum += credit;
            gpSum += (credit*gp);
        }

        gpSum = parseFloat(gpSum.toFixed(4));
        gpa = gpSum/creditSum;

        return {
            '公共选修':credit0,
            '公共必修':credit1,
            '专业选修':credit2,
            '专业必修':credit3,
            '总学分':creditSum,
            'GPA':gpa.toFixed(3)
        };
    }

    var typeMap = {
        '公共选修':0,
        '公共必修':1,
        '专业选修':2,
        '专业必修':3
    };

    var btn = document.getElementById('btn3');

    var frame1,frame2,frame3;
    var j=0;
    btn.addEventListener('click',function(){

        frame1 = document.getElementById('page_iframe').contentWindow;
        frame3 = document.getElementById('bar_iframe').contentWindow;

        var timer = setInterval(function (){

            if(frame1.document.getElementById('iframe0')){//frame1已经加载完毕,此时可以获取成绩表格的frame2
                frame2 = frame1.document.getElementById('iframe0').contentWindow;

                if(frame2.document.getElementsByClassName('listTable')[0] && frame3.document.getElementById('listContent')){

                    var listContent = frame3.document.getElementById('listContent');
                    var resultTable = listContent.getElementsByClassName('listTable')[0];//右边结果的表格

                    var title = listContent.getElementsByClassName('listTitle')[0].innerHTML;

                    if(title=='学分和GPA统计'){
                        j++;
                        if(j>=8){//如果已经在成绩页面,此时点击成绩按钮,会由于js执行快于dom加载,js改变了dom之后,dom却刷新了。所以用j来多获取几次dom,目的是获取刷新之后的dom
                            j=0;
                            clearInterval(timer);

                            var gradeTable = frame2.document.getElementsByClassName('listTable')[0];//成绩的表格

                            var trs;
                            var tds;
                            var i;

                            trs = gradeTable.getElementsByTagName('tr');//成绩表格的每一行

                            var courseArr = [];

                            for(i=0;i<trs.length;i++){
                                tds = trs[i].getElementsByTagName('td');

                                if(tds[9] && tds[9].innerHTML){
                                    var course = {};
                                    course.name = tds[1].innerHTML;
                                    course.credit = tds[3].innerHTML;
                                    course.score = tds[9].innerHTML;
                                    course.type = typeMap[tds[2].innerHTML];

                                    courseArr.push(course);
                                }
                            }
                            var result = calculate(courseArr);


                            trs = resultTable.getElementsByTagName('tr');
                            console.log(trs);

                            for(i=1;i<trs.length;i++){
                                tds = trs[i].getElementsByTagName('td');
                                var key = tds[0].innerHTML;
                                if(result[key]!=null){
                                    tds[1].innerHTML = result[key];
                                }
                            }
                        }
                    }

                //按钮部分,由于没什么用所以暂时不做了
                /*var wraptr = document.createElement('tr');
                var wraptd = document.createElement('td');
                var calBtn = document.createElement('button');

                wraptd.setAttribute('colspan',2);

                calBtn.innerHTML = '计算学分和GPA';
                calBtn.onclick = function(e){
                    e.preventDefault();
                    e.returnValue = false;
                };
                var css = "padding:4px;margin:3px;border:1px solid black;border-radius:5px;cursor:pointer";
                calBtn.setAttribute('style',css);

                wraptr.appendChild(wraptd);
                wraptd.appendChild(calBtn);

                document.getElementById('bar_iframe').contentWindow.document.getElementById('listContent').getElementsByTagName('tbody')[0].appendChild(wraptr);*/
                }
            }
        },20);

    });
})();