Greasy Fork

来自缓存

Greasy Fork is available in English.

uooc自动ai答题

使用deepseek模型,用于深圳大学uooc自动答题,首次使用需要提供deepseek api。理论上所有openai类型的api都能通过本脚本使用,后续将进行更新

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         uooc自动ai答题
// @namespace    http://tampermonkey.net/
// @version      1.0.1
// @description  使用deepseek模型,用于深圳大学uooc自动答题,首次使用需要提供deepseek api。理论上所有openai类型的api都能通过本脚本使用,后续将进行更新
// @author       lyccccy
// @license      CC-BY-NC-SA-4.0
// @match        *://www.uooc.net.cn/exam/*
// @match        *://www.uooc.net.cn/home/learn/*
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
    'use strict';
    // 第一次手动设置 Key


    async function getAnswerFromAPI(type, question, options) {
        const apiKey = GM_getValue('OPENAI_API_KEY');
        // 拼接 prompt
        const prompt = `你是一个答题助手。题目类型:${type}
        题目:${question}
        选项:${options.join('\n')}
        请返回 JSON 字符串,格式如下:
{
  "answer": ["选项字母..."],
  "explanation": "简短理由"
}
注意:
- "answer" 必须是数组
- 不要包含多余文字`;
        //console.log(prompt)
        // 调用 API
        const response = await fetch('https://api.deepseek.com/chat/completions', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${apiKey}` // 你的 API Key
            },
            body: JSON.stringify({
                model: 'deepseek-chat', // 假设使用 GPT-4o-mini
                messages: [
                    { role: 'system', content: '你是一个答题助手。' },
                    { role: 'user', content: prompt }
                ],
                temperature: 0
            })
        });

        const data = await response.json();
        const text = data.choices[0].message.content.trim();

        let jsonAnswer;
        try {
            jsonAnswer = JSON.parse(text); // 解析成对象
        } catch (e) {
            console.error('解析 JSON 失败:', text);
        }

        //console.log(jsonAnswer.answer); // ["A", "C"]
        //console.log(jsonAnswer.explanation);
        return jsonAnswer;
    }

    function selectAnswer(tiEl, answerJson) {
        if (!tiEl || !answerJson) return;

        // 确保 answer 是数组形式,单选也转换成数组
        const answers = Array.isArray(answerJson.answer) ? answerJson.answer : [answerJson.answer];

        // 找到选项
        const optionsContainer = tiEl.querySelector('.ti-alist');
        if (!optionsContainer) return;

        const optionLabels = [...optionsContainer.querySelectorAll('label.ti-a')];

        answers.forEach(ans => {
            // 找到对应 value 的 input
            const input = optionLabels.find(label => label.querySelector('input')?.value === ans)?.querySelector('input');
            if (input && !input.checked) {
                input.click();
                //console.log(`✅ 已选择 ${ans} :${tiEl.querySelector('.ti-q-c')?.innerText}`);
            }
        });
}

    // 打印一题
    async function printQuestion(tiEl) {
    // 题干
        const qText = tiEl.querySelector('.ti-q-c')?.innerText.trim() || '[无题干]';

        // 选项
        const optionsContainer = tiEl.querySelector('.ti-alist');
        const options = optionsContainer ? [...optionsContainer.querySelectorAll('label.ti-a')] : [];
        // 找到题目类型
        let typeText = '[未找到类型]';
        const queItems = tiEl.closest('.queItems');
        if (queItems) {
            const h2 = queItems.querySelector('h2.queItems-type');
            if (h2) {
                // 只保留“单选题”、“多选题”、“判断题”等文字
                typeText = h2.innerText.replace(/\s*\(.*?\)/, '').trim();
            }
        }
        console.log('========================');
        console.log('题目类型:', typeText);
        console.log('题干:', qText);
        console.log('选项:');

        if (options.length === 0) {
            console.log('  [未找到选项]');
            return;
        }
        const optionsText = options.map(label => {
            const key = label.querySelector('.ti-a-i')?.innerText?.trim().replace('.', '') || '?';
            const text = label.querySelector('.ti-a-c')?.innerText.trim() || '[无内容]';
            return `${key}. ${text}`;
        });
        options.forEach(label => {
            const key = label.querySelector('.ti-a-i')?.innerText?.trim().replace('.', '') || '?';
            const text = label.querySelector('.ti-a-c')?.innerText.trim() || '[无内容]';
            console.log(`  ${key}. ${text}`);
        });
        const answer = await getAnswerFromAPI(typeText, qText, optionsText);
        console.log('模型推荐答案:', answer);
        selectAnswer(tiEl,answer)
}

    // 查找所有单选题并打印
    function processAllSingleChoice() {
        if (document.querySelector('.answerBox')) {
            return}
        const questions = document.querySelectorAll('.ti');
        console.log(`检测到 ${questions.length} 道题:`);
        questions.forEach(printQuestion);
    }

    // 页面加载后运行
    window.addEventListener('load', () => {
        if (!GM_getValue('OPENAI_API_KEY')) {
            const key = prompt('请输入你的apiKey');
            GM_setValue('OPENAI_API_KEY', key);
        }

        const OPENAI_API_KEY = GM_getValue('OPENAI_API_KEY');
        console.log('当前 API Key:', OPENAI_API_KEY);
        setTimeout(processAllSingleChoice, 2000);
    });
})();