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

U校园题目答案显示;支持视听说、新视野;不支持单元测试

当前为 2024-11-14 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         【U校园答案显示】 自用版
// @namespace    gongchen
// @version      2.9
// @description  U校园题目答案显示;支持视听说、新视野;不支持单元测试
// @author       gongchen
// @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(); // 刷新页面
    });
}


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