【U校园答案显示】 自用版

U校园题目答案显示;不支持单元测试

目前為 2024-11-14 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         【U校园答案显示】 自用版
// @namespace    jayhyy
// @version      1.2
// @description  U校园题目答案显示;不支持单元测试
// @author       jayhyy
// @match        *://ucontent.unipus.cn/_pc_default/pc.html?*
// @connect      *://ucontent.unipus.cn/*
// @connect      unipus.cn
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// @require      https://lib.baomitu.com/jquery/3.6.0/jquery.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js
// @license      MIT
// ==/UserScript==

$('head').append('<link href="https://lib.baomitu.com/layui/2.6.8/css/layui.css" rel="stylesheet" type="text/css" />');
$.getScript("https://lib.baomitu.com/layui/2.6.8/layui.js", function(data, status, jqxhr) {
    layui.use('element', function(){
        var element = layui.element;
    });
    layer.closeAll();
    show();
    showanswer();
});

// 感谢ssmjae提供的解密代码
function decryptContent(json) {
    if (json) {
        let r = json.content.slice(7)
        , o = CryptoJS.enc.Utf8.parse("1a2b3c4d" + json.k)
        , i = CryptoJS.enc.Hex.parse(r)
        , a = CryptoJS.enc.Base64.stringify(i)
        , contentJson = JSON.parse(CryptoJS.AES.decrypt(a, o, {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.ZeroPadding
        }).toString(CryptoJS.enc.Utf8));
        json = contentJson;
        console.log(json);
    }
    return json;
}

var show = ()=>{
    layer.open({
        type: 1,
        area: ['500px', '600px'],
        offset: 'l',
        id: 'msgt',
        closeBtn: 1,
        title: "U校园网课助手(答案显示,支持单选、多选、填空、简答、问答)",
        shade: 0,
        maxmin: true,
        anim: 2,
        content:'<div class="layui-collapse"><div class="layui-colla-item"><h2 class="layui-colla-title">公告</h2><div class="layui-colla-content layui-show">脚本已修复</div>'+
        '</div></div>'+
        '<div id="content"><ul></ul><table class="layui-table"> <colgroup> <col width="100"> <col> <col> </colgroup> <thead> <tr>  </tr> </thead> <tbody>  </tbody> </table></div></div></div>'
    });
}

let isShow = true
var showanswer = ()=>{
    if (isShow){
        let url = location.href
        let arr = url.split("/")
        let book = arr[arr.length-7]
        let unit = arr[arr.length-2]
        let answer = []
        GM_xmlhttpRequest({
            method: 'GET',
            url: 'https://ucontentapi.unipus.cn/course/api/content/'+book+'/'+unit+'/default/',
            headers: {
                'X-ANNOTATOR-AUTH-TOKEN': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvcGVuX2lkIjoidHV4NkNCQVc4aGRrcnFZdzc5SEpEWDF2aTR5Z2ptcDUiLCJuYW1lIjoiIiwiZW1haWwiOiIiLCJhZG1pbmlzdHJhdG9yIjoiZmFsc2UiLCJleHAiOjE5MDI5NzAxNTcwMDAsImlzcyI6IlI0aG03RmxQOFdvS0xaMUNmTkllIiwiYXVkIjoiZWR4LnVuaXB1cy5jbiJ9.CwuQmnSmIuts3hHAMf9lT954rKHXUNkps-PfRJp0KnU'
            },
            timeout: 5000,
            onload: function(xhr) {
                if (xhr.status == 200) {
                    let el = '<tr class="layui-bg">' + '</td></tr>'
                    console.log('https://ucontentapi.unipus.cn/course/api/content/'+book+'/'+unit+'/default/')

                    console.log(xhr.responseText)
                    let obj = JSON.parse(xhr.responseText) || {};
                    let deObj = decryptContent(obj);
                    let keyList = Object.keys(deObj);
                    console.log(keyList)
                    Array.prototype.contains = function (obj) {
                        var index = this.length;
                        while (index--) {
                            if (this[index] === obj) {
                                return true;
                            }
                        }
                        return false;
                    }
                    // 选择题
                    if (keyList.contains('questions:questions')) {
                        let questionList = deObj['questions:questions'].questions;
                        let lineCount = 0; // 初始化行数计数器

                        for (let question of questionList) {
                            let result = '';
                            
                            if (question.answers) {
                                result += question.answers.join(' ');
                            }

                            // 在每一行前加上行号
                            lineCount++; // 增加行数
                            el = el + '<tr><td>第' + lineCount + '题: ' + result + question.analysis.html + '</td></tr>';
                        }

                        // 可选:在最后添加总行数统计
                        el = el + '<tr><td colspan="2">总题数: ' + lineCount + '</td></tr>';
                    }
                // 简答题
                if (keyList.contains('shortanswer:shortanswer')) {
                    let questionList = deObj['shortanswer:shortanswer'].questions;
                    let lineCount = 0; // 初始化行数计数器

                    for (let question of questionList) {
                        lineCount++; // 每处理一个题目,行数加 1
                        el = el + '<tr><td>第' + lineCount + '题: ' + deObj['shortanswer:shortanswer'].analysis.html + question.content.html + question.analysis.html + '</td></tr>';
                    }

                    // 可选:在最后添加总行数统计
                    el = el + '<tr><td colspan="2">总题数: ' + lineCount + '</td></tr>';
                }
                    // 填空题
                    if (keyList.contains('questions:scoopquestions')) {
                        let questionList = deObj['questions:scoopquestions'].questions;
                        let lineCount = 0; // 初始化行数计数器

                        for (let question of questionList) {
                            lineCount++; // 每处理一个题目,行数加 1

                            let result = '';
                            if (question.answers) {
                                result += question.answers.join(' ');
                            }

                            // 输出包含行号的 HTML 和复制按钮
                            el = el + '<tr><td>第' + lineCount + '题: ' + result + question.analysis.html + '</td>';
                            el += '<td><button class="layui-btn layui-btn-xs copy-btn" data-content="' + result + '">复制</button></td></tr>';
                        }

                        // 可选:在最后添加总行数统计
                        el = el + '<tr><td colspan="2">总题数: ' + lineCount + '</td></tr>';
                    }

                    // 为复制按钮添加事件监听
                    $(document).on('click', '.copy-btn', function() {
                        var content = $(this).data('content'); // 获取该按钮对应的内容
                        var textarea = document.createElement("textarea"); // 创建一个临时的textarea元素
                        textarea.value = content; // 将内容设置为textarea的值
                        document.body.appendChild(textarea); // 将textarea添加到DOM中
                        textarea.select(); // 选择textarea中的内容
                        document.execCommand("copy"); // 执行复制操作
                        document.body.removeChild(textarea); // 删除临时textarea

                        // 提示用户已复制
                        layer.msg('已复制: ' + content, {icon: 1});
                    });                // 短回答题
                if (keyList.contains('questions:shortanswer')) {
                    let questionList = deObj['questions:shortanswer'].questions;
                    let lineCount = 0; // 初始化行数计数器

                    for (let question of questionList) {
                        lineCount++; // 每处理一个题目,行数加 1

                        let result = '';
                        if (question.answers) {
                            result += question.answers.join(' ');
                        }

                        // 输出包含行号的 HTML
                        el = el + '<tr><td>第' + lineCount + '题: ' + result + question.analysis.html + '</td></tr>';
                    }

                    // 可选:在最后添加总行数统计
                    el = el + '<tr><td colspan="2">总题数: ' + lineCount + '</td></tr>';
                }
                    el = el + '<td>答案结束,如果没有答案,尝试刷新试试</td></td></tr>'
                    $("#content>table>tbody").append($(el));
                }
            }
        });
    }
    isShow = !isShow
}

var show = () => {
    layer.open({
        type: 1,
        area: ['500px', '600px'],
        offset: ['10px', 'auto'], // 将弹框定位到右侧
        id: 'msgt',
        closeBtn: 1,
        title: "U校园网课助手(答案显示,支持单选、多选、填空、简答、问答)",
        shade: 0,
        maxmin: true,
        anim: 2,
        content: '<div class="layui-collapse"><div class="layui-colla-item"><h2 class="layui-colla-title">公告</h2><div class="layui-colla-content layui-show">脚本已修复普通测试答案获取,单元测试的相关答案已录入app</div>' +
            '</div></div>' +
            '<div id="content"><ul></ul><table class="layui-table"> <colgroup> <col width="100"> <col> <col> </colgroup> <thead> <tr>  </tr> </thead> <tbody>  </tbody> </table>' +
            // 添加刷新按钮
            '<button id="refresh-btn" class="layui-btn layui-btn-normal">一键刷新</button>' +
            '</div></div></div>',
        // 确保显示在右侧
        success: function(layero, index) {
            var windowWidth = $(window).width();
            var layerWidth = $(layero).outerWidth();
            var rightOffset = windowWidth - layerWidth - 10; // 距离右边界10px
            $(layero).css('right', rightOffset + 'px');
        }
    });

    // 为刷新按钮绑定点击事件
    $('#refresh-btn').click(function() {
        console.log('刷新页面');
        location.reload(); // 刷新页面
    });
}

$(document).ready(function() {
    // 页面加载完毕时初始化点击检查
    function autoClickConfirmButton() {
        var interval = setInterval(function() {
            var confirmButton = $("span[style*='font-size: 14px'][style*='text-transform: uppercase']");
            if (confirmButton.length > 0) {
                confirmButton.click(); // 自动点击
                console.log("已自动点击确定按钮");
                clearInterval(interval); // 点击后停止检查
            }
        }, 500); // 每500ms检查一次
    }

    // 初始时调用函数检查按钮
    autoClickConfirmButton();

    // 监听URL的变化,检测页面切换
    window.onhashchange = function() {
        console.log("页面切换 detected");
        $("#content>table>tbody").empty(); // 清空之前的内容
        showanswer(); // 重新加载答案
        autoClickConfirmButton(); // 每次页面切换后重新调用点击函数
    };
});



window.onhashchange=()=>{
    $("#content>table>tbody").empty();
    showanswer();
}