Greasy Fork

Greasy Fork is available in English.

学习助手

学习通测试成绩查看,批改网解除复制粘贴限制。

当前为 2025-05-29 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name          学习助手
// @namespace     https://zac.social/
// @version       0.3.0
// @description   学习通测试成绩查看,批改网解除复制粘贴限制。
// @author        zac517
// @match         mooc1.chaoxing.com/*
// @match         www.pigai.org/*
// @icon          https://one.hfut.edu.cn/favicon.ico
// @run-at        document-start
// @grant         unsafeWindow
// ==/UserScript==

(function () {
    'use strict';

    let site = null;
    const siteConfigs = {
        'mooc1.chaoxing.com': {
            config: {
                onPageLoaded: () => {
                    const requiredParams = ['courseid', 'clazzid', 'cpi'];

                    function generateNewUrl() {
                        const urlParams = new URLSearchParams(unsafeWindow.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();
                            unsafeWindow.open(newUrl, '_blank');
                        });

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

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

                    createJumpButton();
                }
            }
        },
        'www.pigai.org': {
            'c=v2&a=write': {
                config: {
                    onScriptLoaded: {
                        'script[src="https://cdn.pigai.org//res/javascript/spss.js?d=2022111501"]': {
                            callback: () => {
                                unsafeWindow.init_no_paste = () => { return false };
                            },
                            times: 1,
                        }
                    },
                    onPageLoaded: () => {
                        const node = document.querySelector('#request_y');
                        node.unselectable = 'off';
                        node.onselectstart = '';
                        const childNode = document.querySelector('.no_paste > div');
                        if (childNode) childNode.style = '';
                    }
                }
            },
            'c=v2&a=view': {
                config: {
                    data: {
                        score: 0,
                    },
                    onScriptLoaded: {
                        'script[src="https://cdn.pigai.org//res/javascript/view.js?d=2024112903"]': {
                            callback: () => {
                                unsafeWindow.init_no_paste_by_snt = () => { return false };
                            },
                            times: 1,
                        },
                    },
                    onElementAdded: {
                        'b#rescoreTxt': {
                            callback: (node) => site.data.score = node.innerText,
                            times: 1,
                        },
                    },
                    onPageLoaded: () => {
                        function genPromptFromPage() {
                            const commentElement = document.getElementById('allpingyu_txt');
                            const articleComment = commentElement ? commentElement.textContent.trim() : '';

                            const elements = document.querySelectorAll('.view3Item:not(.view3duan)');
                            let totalString = '';

                            elements.forEach(element => {
                                const view3xh = element.querySelector('.view3xh');
                                const sentenceNumber = view3xh ? view3xh.textContent.trim() : '';

                                const view3Sent = element.querySelector('.view3Sent');
                                const sentTxt = view3Sent ? view3Sent.querySelector('.sentTxt') : null;
                                const sentenceContent = sentTxt ? sentTxt.textContent.trim() : '';

                                const view3Error = element.querySelector('.view3Error');
                                const errorList = view3Error ? view3Error.querySelector('ul') : null;
                                const errorItems = errorList ? errorList.querySelectorAll('li') : [];

                                let relevantComments = [];

                                errorItems.forEach(item => {
                                    if (item.classList.contains('error') || item.classList.contains('warn')) {
                                        let commentText = '';
                                        const childNodes = item.childNodes;
                                        childNodes.forEach(node => {
                                            if (node.nodeType === Node.TEXT_NODE) {
                                                commentText += node.textContent;
                                            } else if (node.nodeType === Node.ELEMENT_NODE &&
                                                !node.classList.contains('stips') &&
                                                !node.classList.contains('snt_info')) {
                                                commentText += node.textContent;
                                            }
                                        });
                                        relevantComments.push(commentText.trim().replace(/[\u0009\u000A]/g, ''));
                                    }
                                });

                                if (relevantComments.length > 0) {
                                    const combinedComments = relevantComments.join('\n');
                                    totalString += `${sentenceNumber} ${sentenceContent}\n 点评:\n${combinedComments}\n\n`;
                                }
                            });

                            let finalString = `当前作文分数为 ${site.data.score}。\n作文评语为:${articleComment}。\n可改进的句子如下:\n${totalString}`
                                + `注意:
1. 网站给出的点评虽然说是让你检查,但实际上你不修改他就会一直扣分,所以无论你觉得对不对,一定要想办法修改。
2. 点评中,所有提到存在拼写有误的地方,如果点评中给出了具体的修改方案就按给出的方案改,没有就自己改。
3. 作文的评分系统是通过识别每个词实现的,所以被他指出有问题的词,就算你觉得没问题,为了得到更高的分也必须修改,否则会一直被指出。
4. 如果你觉得难以改正,就尝试换成其他意思相近的表达(不能还含有原被指出的拼写)。
5. 作文中应只使用英文,绝对不能出现中文,即使是在引用中文词语或俗语。
6. 回答时,英语作文使用英语回答,要给出修改后的完整文章,不省略不修改的部分。
7. 回答时,提供的其他信息(比如向我解释修改了哪些内容)必须使用中文给出。
请跟据以上相关信息和要求进行修改,提高作文的分数。`;

                            return finalString;
                        }
                        console.log(genPromptFromPage());
                    }
                }
            }
        }
    };

    const currentHostname = unsafeWindow.location.hostname;
    const currentPathAndQuery = unsafeWindow.location.pathname + unsafeWindow.location.search;

    function getEffectiveConfigRecursive(currentNode, pathQuery) {
        let candidateConfigsFromChildren = [];

        for (const key in currentNode) {
            if (key === 'config') continue;

            if (pathQuery.includes(key)) {
                const deeperConfig = getEffectiveConfigRecursive(currentNode[key], pathQuery);
                if (deeperConfig) {
                    candidateConfigsFromChildren.push({ config: deeperConfig, specificity: key.length });
                }
            }
        }

        if (candidateConfigsFromChildren.length > 0) {
            candidateConfigsFromChildren.sort((a, b) => b.specificity - a.specificity);
            return candidateConfigsFromChildren[0].config;
        } else {
            return currentNode.config || null;
        }
    }

    if (siteConfigs[currentHostname]) {
        const domainNode = siteConfigs[currentHostname];
        site = getEffectiveConfigRecursive(domainNode, currentPathAndQuery);
    }
    
    if ((site?.onElementAdded && Object.keys(site.onElementAdded).length > 0) || (site?.onScriptLoaded && Object.keys(site.onScriptLoaded).length > 0)) {
        const callback = function (mutationsList) {
            const needsObserver = false;
            for (const mutation of mutationsList) {
                if (mutation.type === 'childList') {
                    for (const addedNode of mutation.addedNodes) {
                        if (site?.onElementAdded) {
                            Object.keys(site.onElementAdded).forEach((element) => {
                                if (site.onElementAdded[element].times != 0 && addedNode === document.querySelector(element)) {
                                    site.onElementAdded[element].callback(addedNode);
                                    site.onElementAdded[element].times -= 1;
                                    if (site.onElementAdded[element].times != 0) needsObserver = true;
                                }
                            })
                        }
                        if (site?.onScriptLoaded) {
                            Object.keys(site.onScriptLoaded).forEach((element) => {
                                if (site.onScriptLoaded[element].times != 0 && addedNode === document.querySelector(element)) {
                                    addedNode.onload = site.onScriptLoaded[element].callback;
                                    site.onScriptLoaded[element].times -= 1;
                                    if (site.onScriptLoaded[element].times != 0) needsObserver = true;
                                }
                            })
                        }
                    }
                }
            }
        };

        const observer = new MutationObserver(callback);
        observer.observe(document, { attributes: true, childList: true, subtree: true });
    }

    if (site?.onPageLoaded) {
        unsafeWindow.addEventListener('load', () => site.onPageLoaded());
    };

    function createMenu() {
        const css = `
        #study-tool-menu {
            display: inline-block !important;
            margin: 0 !important;
            position: fixed !important;
            left: 40px;
            top: calc(50vh - 150px);
            width: 200px;
            height: 300px;
            border-radius: 10px !important;
            background-color: white !important;
            border: 1px solid rgba(0, 0, 0, 0.1) !important;
            box-shadow: 0 0 40px 0 rgba(0, 0, 0, 0.05) !important;
            padding: 10px !important;
            z-index: 9999 !important;
            cursor: grab;
            overflow: hidden !important;
            box-sizing: border-box !important;
        }

        #study-tool-menu.collapsed-left, #study-tool-menu.collapsed-right {
            height: 60px !important;
        }

        #study-tool-menu.collapsed-left {
            left: -190px;
        }

        #study-tool-menu.collapsed-right {
            left: calc(100% - 10px);
        }

        #study-tool-menu.collapsed-left:hover {
            left: -140px;
        }

        #study-tool-menu.collapsed-right:hover {
            left: calc(100% - 60px);
        }
        `;

        const style = document.createElement('style');
        style.textContent = css;
        document.head.appendChild(style);

        const div = document.createElement('div');
        div.id = 'study-tool-menu';
        div.innerHTML = `
        <div>666</div>
        <h1>123</h1>
        `;

        let isDragging = false;
        let offsetX, offsetY, startX, startY;

        div.addEventListener('mousedown', (e) => {
            isDragging = true;
            div.style.cursor = 'grabbing';
            div.style.transition = 'none';
            const divRect = div.getBoundingClientRect();
            offsetX = e.clientX - divRect.left;
            offsetY = e.clientY - divRect.top;
            startX = e.clientX;
            startY = e.clientY;
        });

        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                div.style.left = (e.clientX - offsetX) + 'px';
                div.style.top = (e.clientY - offsetY) + 'px';
            }
        });

        document.addEventListener('mouseup', (e) => {
            isDragging = false;
            div.style.transition = 'left 0.5s';
            const windowWidth = window.innerWidth;
            const divRect = div.getBoundingClientRect();
            if (divRect.left <= 0 || divRect.right >= windowWidth) {
                if (startX == e.clientX && startY == e.clientY) expandMenu();
                else {
                    if (divRect.left <= 0) {
                        div.style.left = '';
                        div.classList.add('collapsed-left');
                    }
                    else {
                        div.style.left = '';
                        div.classList.add('collapsed-right');
                    }
                }
            }
            else expandMenu();
            div.style.cursor = 'grab';
        });

        function expandMenu() {
            div.classList.remove('collapsed-left', 'collapsed-right');
            const windowWidth = window.innerWidth;
            const divRect = div.getBoundingClientRect();
            if (divRect.left < 0) div.style.left = '40px';
            else if (divRect.right > windowWidth) div.style.left = 'calc(100% - 240px)';
        }

        document.body.appendChild(div);
    }

})();