Greasy Fork

岐黄天使刷课助手 - 题库模块

岐黄天使刷课助手的题库管理模块。从 greasyfork.org/scripts/537085/questionBankDatasj.js 加载预定义题库数据,用于题目查找和显示。

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

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/537077/1594858/%E5%B2%90%E9%BB%84%E5%A4%A9%E4%BD%BF%E5%88%B7%E8%AF%BE%E5%8A%A9%E6%89%8B%20-%20%E9%A2%98%E5%BA%93%E6%A8%A1%E5%9D%97.js

// ==UserScript==
// @name         岐黄天使刷课助手 - 题库模块
// @namespace    http://tampermonkey.net/qhtx-modules
// @version      1.4.0
// @description  岐黄天使刷课助手的题库管理模块。从 greasyfork.org/scripts/537085/questionBankDatasj.js 加载预定义题库数据,用于题目查找和显示。
// @author       AI助手
// ==/UserScript==

// 题库模块
(function() {
    'use strict';

    window.qh = window.qh || {}; // 确保 qh 对象存在
    window.qh.questionBankData = window.qh.questionBankData || []; // 初始化题库数据容器

    // 初始化题库数据
    function initializeQuestionBank() {
        if (window.qhtxInitialQuestionBank && typeof window.qhtxInitialQuestionBank === 'object' && Array.isArray(window.qhtxInitialQuestionBank.questions)) {
            console.log('[题库模块] 从 window.qhtxInitialQuestionBank.questions 加载题库数据');
            // 使用深拷贝以避免意外修改原始数据,如果它是只读的,则直接赋值也行
            window.qh.questionBankData = JSON.parse(JSON.stringify(window.qhtxInitialQuestionBank.questions));
        } else if (window.qhtxInitialQuestionBank && Array.isArray(window.qhtxInitialQuestionBank)) {
            // 兼容直接提供数组的情况
            console.log('[题库模块] 从 window.qhtxInitialQuestionBank (array) 加载题库数据');
            window.qh.questionBankData = JSON.parse(JSON.stringify(window.qhtxInitialQuestionBank));
        }
        else {
            console.warn('[题库模块] 未找到预定义的题库数据 (window.qhtxInitialQuestionBank)。题库将为空。');
            window.qh.questionBankData = []; // 确保在没有数据时为空数组
        }
        console.log('[题库模块] 题库初始化完成,题目数量:', window.qh.questionBankData.length);
    }

    // 显示题目面板
    window.showQuestionPanel = function() {
        // 检查是否已存在题目面板
        let panel = document.getElementById('qh-question-panel');
        let overlay = document.getElementById('qh-question-overlay');

        if (panel && overlay) {
            panel.style.display = 'block';
            overlay.style.display = 'block';
            // 如果面板已存在,可能需要刷新内容
            initializeQuestionBank(); // 确保数据最新
            displayQuestions(window.qh.questionBankData);
            return;
        }

        // 创建遮罩层
        overlay = document.createElement('div');
        overlay.className = 'qh-question-overlay';
        overlay.id = 'qh-question-overlay';
        document.body.appendChild(overlay);

        // 创建题目面板
        panel = document.createElement('div');
        panel.className = 'qh-question-panel';
        panel.id = 'qh-question-panel';
        panel.innerHTML = `
            <div class="qh-question-title">
                题库查看器
                <span class="qh-question-close" id="qh-question-close">×</span>
            </div>
            <div class="qh-question-content" id="qh-question-content">
                <div style="text-align: center; padding: 20px;">正在加载题库...</div>
            </div>
            <div class="qh-question-status" id="qh-question-status">
                题库总数: 0 道
            </div>
            <div class="qh-question-btns">
                <button class="qh-question-btn" id="qh-copy-questions-btn">复制当前显示题目</button>
            </div>
        `;
        document.body.appendChild(panel);

        // 绑定关闭按钮事件
        document.getElementById('qh-question-close').addEventListener('click', function() {
            document.getElementById('qh-question-panel').style.display = 'none';
            document.getElementById('qh-question-overlay').style.display = 'none';
        });

        // 绑定复制题目按钮事件
        document.getElementById('qh-copy-questions-btn').addEventListener('click', function() {
            copyQuestionsToClipboard();
        });

        // 显示面板
        panel.style.display = 'block';
        overlay.style.display = 'block';

        // 初始化题库并显示
        initializeQuestionBank();
        displayQuestions(window.qh.questionBankData);
    };

    // 从元素中提取题目信息 (保留,可能被 autoAnswer.js 使用)
    function extractQuestionFromElement(element, iframe = null) {
        try {
            // 获取题目文本
            const questionTextElement = element.querySelector('.subject');
            if (!questionTextElement) return null;

            const questionText = questionTextElement.textContent.trim();
            if (!questionText) return null;

            // 生成唯一ID
            const questionId = generateQuestionId(questionText);

            // 获取选项
            const optionsElements = element.querySelectorAll('.option');
            const options = Array.from(optionsElements).map(option => option.textContent.trim());

            // 获取答案
            let answer = '';
            const answerElement = element.querySelector('.answer');
            if (answerElement) {
                answer = answerElement.textContent.replace('答案:', '').trim();
            }

            // 获取解析
            let analysis = '';
            const analysisElement = element.querySelector('.analysis');
            if (analysisElement) {
                analysis = analysisElement.textContent.replace('解析:', '').trim();
            }

            return {
                id: questionId,
                question: questionText,
                options: options,
                answer: answer,
                analysis: analysis,
                isInIframe: !!iframe,
                iframe: iframe
            };
        } catch (e) {
            console.error('提取题目信息出错:', e);
            return null;
        }
    }

    // 生成题目ID (保留,可能被 autoAnswer.js 使用)
    function generateQuestionId(questionText) {
        // 使用题目文本的哈希值作为ID
        let hash = 0;
        for (let i = 0; i < questionText.length; i++) {
            const char = questionText.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash; // 转换为32位整数
        }
        return 'q_' + Math.abs(hash).toString(16);
    }

    // 获取题目列表 (供其他模块使用,如 autoAnswer.js)
    window.getQuestionList = function() {
        initializeQuestionBank(); // 确保题库已加载
        return window.qh.questionBankData;
    };

    // 显示题目
    function displayQuestions(questionsToDisplay) {
        const contentElement = document.getElementById('qh-question-content');
        const statusElement = document.getElementById('qh-question-status');

        if (!contentElement) return;

        if (!questionsToDisplay || questionsToDisplay.length === 0) {
            contentElement.innerHTML = '<div style="text-align: center; padding: 20px; color: #f44336;">题库为空或加载失败。</div>';
            if (statusElement) {
                statusElement.textContent = '题库总数: 0 道';
            }
            return;
        }

        // 构建HTML
        let html = '';
        questionsToDisplay.forEach((question, index) => {
            html += `
                <div class="qh-question-item" data-id="${question.id || generateQuestionId(question.question)}">
                    <div class="qh-question-text">${index + 1}. ${question.question}</div>
                    <div class="qh-question-options">
                        ${(question.options && Array.isArray(question.options)) ? question.options.map((option, i) => `
                            <div class="qh-question-option">${String.fromCharCode(65 + i)}. ${option}</div>
                        `).join('') : '选项未提供'}
                    </div>
                    <div class="qh-question-answer">答案: ${question.answer || '未知'}</div>
                    ${question.analysis ? `<div class="qh-question-analysis">解析: ${question.analysis}</div>` : ''}
                </div>
            `;
        });

        contentElement.innerHTML = html;

        // 更新状态
        if (statusElement) {
            statusElement.textContent = `题库总数: ${questionsToDisplay.length} 道`;
        }
    }

    // 复制题目到剪贴板
    function copyQuestionsToClipboard() {
        try {
            const questionItems = document.querySelectorAll('#qh-question-panel .qh-question-item');
            if (questionItems.length === 0) {
                alert('面板中没有可复制的题目');
                return;
            }

            let text = '';
            questionItems.forEach((item, index) => {
                const questionTextElement = item.querySelector('.qh-question-text');
                const questionText = questionTextElement ? questionTextElement.textContent.replace(/^\d+\.\s*/, '') : '题目获取失败';

                const optionElements = item.querySelectorAll('.qh-question-option');
                const options = Array.from(optionElements).map(option => option.textContent.trim());

                const answerElement = item.querySelector('.qh-question-answer');
                const answerText = answerElement ? answerElement.textContent.replace('答案:', '').trim() : '未知';
                
                let analysisText = '';
                const analysisElement = item.querySelector('.qh-question-analysis');
                if (analysisElement) {
                    analysisText = analysisElement.textContent.replace('解析:', '').trim();
                }

                text += `${index + 1}. ${questionText}\n`;
                options.forEach(option => {
                    text += `   ${option}\n`;
                });
                text += `答案: ${answerText}\n`;
                if (analysisText) {
                    text += `解析: ${analysisText}\n`;
                }
                text += '\n';
            });

            GM_setClipboard(text);

            const statusElement = document.getElementById('qh-question-status');
            if (statusElement) {
                 statusElement.textContent = `已复制 ${questionItems.length} 道题目到剪贴板`;
            }
            alert(`已复制 ${questionItems.length} 道题目到剪贴板`);

        } catch (e) {
            console.error('[题库模块] 复制题目出错:', e);
            alert('复制题目出错: ' + e.message);
        }
    }

    // 导出函数供其他模块使用
    window.extractQuestionFromElement = extractQuestionFromElement;
    window.generateQuestionId = generateQuestionId;
    window.copyQuestionsToClipboard = copyQuestionsToClipboard; // 如果面板按钮直接调用此函数,也可不全局导出

    // 初始化时加载题库 (确保 qhtxInitialQuestionBank 已通过 @require 加载)
    initializeQuestionBank();

    console.log('[题库模块] 模块已加载并初始化。');
})();