Greasy Fork

Greasy Fork is available in English.

合工大学习助手

合工大学习助手,支持学习通测试成绩查询和导出、批改网解除复制粘贴限制等。

当前为 2025-04-09 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         合工大学习助手
// @namespace    https://zac.social/scripts
// @version      0.0.1
// @description  合工大学习助手,支持学习通测试成绩查询和导出、批改网解除复制粘贴限制等。
// @author       zac517
// @match        mooc1.chaoxing.com/*
// @match        https://www.pigai.org/*
// @icon         https://one.hfut.edu.cn/favicon.ico
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // 后续可以在这里添加更多域名和对应功能的映射
    const domainFunctions = {
        'chaoxing.com': function() {
            // 定义目标参数列表
            const requiredParams = ['courseid', 'clazzid', 'cpi'];

            // 生成新链接的函数
            function generateNewUrl() {
                const urlParams = new URLSearchParams(window.location.search);
                const params = requiredParams.reduce((acc, param) => {
                    const value = urlParams.get(param);
                    if (value) acc[param] = value;
                    return acc;
                }, {});

                // 检查必要参数是否齐全
                if (requiredParams.every(param => params[param])) {
                    const newParams = new URLSearchParams();
                    for (const key in params) {
                        if (params.hasOwnProperty(key)) {
                            newParams.append(key, params[key]);
                        }
                    }
                    newParams.append('ut', 's');
                    return `https://stat2-ans.chaoxing.com/exam-stastics/index?${newParams.toString()}`;
                }
                return null;
            }

            // 创建跳转按钮
            function createJumpButton() {
                const newUrl = generateNewUrl();
                if (!newUrl) return;

                const button = document.createElement('a');
                button.href = '#';
                button.target = '_blank';
                button.className = 'jb_btn jb_btn_104 createTopic fl fs14 marginRight30 ';
                button.style.cssText = `
                    z-index: 999;
                    width: 104px;
                    height: 36px;
                    background: url(https://groupweb.chaoxing.com/res/course/images/discuss/jb_btn_104.png) no-repeat 0 0;
                    position: relative;
                    top: -29px;
                    float: right;
                `;
                button.textContent = '查看成绩';

                button.addEventListener('click', (e) => {
                    e.preventDefault();
                    window.open(newUrl, '_blank');
                });

                const topBackElement = document.querySelector('.top-back');

                if (topBackElement) {
                    topBackElement.appendChild(button);
                }
            }

            // 页面加载完成后执行
            window.addEventListener('load', createJumpButton);
        },
        'pigai.org': function() {
            const urlParams = new URLSearchParams(window.location.search);
            if (urlParams.get('c') === 'v2' && urlParams.get('a') === 'write') {
                const originalAddEventListener = Element.prototype.addEventListener;
                Element.prototype.addEventListener = function(type, listener, options) {
                    if ((type === 'contextmenu' || type === 'dragenter' || type === 'paste') && this.matches('textarea[name="contents"]#contents.from_contents')) {
                        return;
                    }
                    return originalAddEventListener.call(this, type, listener, options);
                };

                Object.defineProperty(document, 'onpaste', {
                    get: function() {
                        return null;
                    },
                    set: function() {
                        return;
                    }
                });
            }
        }
    };

    const currentHostname = window.location.hostname;
    for (const domain in domainFunctions) {
        if (currentHostname.includes(domain)) {
            domainFunctions[domain]();
            break;
        }
    }
})();