您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
岐黄天使刷课助手的题库管理模块,负责题目的获取、存储、显示和复制。
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/537077/1594815/%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.3.0 // @description 岐黄天使刷课助手的题库管理模块,负责题目的获取、存储、显示和复制。 // @author AI助手 // ==/UserScript== // 题库模块 (function() { 'use strict'; // 显示题目面板 window.showQuestionPanel = function() { // 检查是否已存在题目面板 if (document.getElementById('qh-question-panel')) { document.getElementById('qh-question-panel').style.display = 'block'; document.getElementById('qh-question-overlay').style.display = 'block'; return; } // 创建遮罩层 const overlay = document.createElement('div'); overlay.className = 'qh-question-overlay'; overlay.id = 'qh-question-overlay'; document.body.appendChild(overlay); // 创建题目面板 const 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"> 已保存题目: ${window.qh.savedQuestionBank.length} 道 </div> <div class="qh-question-btns"> <button class="qh-question-btn" id="qh-save-questions-btn">保存题目</button> <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-save-questions-btn').addEventListener('click', function() { saveQuestions(); }); // 绑定复制题目按钮事件 document.getElementById('qh-copy-questions-btn').addEventListener('click', function() { copyQuestionsToClipboard(); }); // 显示面板 document.getElementById('qh-question-panel').style.display = 'block'; document.getElementById('qh-question-overlay').style.display = 'block'; // 获取题目和答案 getQuestionsAndAnswers(); }; // 获取题目和答案 function getQuestionsAndAnswers() { try { // 更新状态 updateStatus('正在获取题目和答案...'); // 查找题目容器 const questions = []; let questionContainer = null; // 尝试在主文档中查找题目 questionContainer = document.querySelector('.timu'); if (questionContainer) { // 从主文档中获取题目 const question = extractQuestionFromElement(questionContainer); if (question) { questions.push(question); } } else { // 尝试在iframe中查找题目 const frames = document.querySelectorAll('iframe'); for (const frame of frames) { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; questionContainer = frameDoc.querySelector('.timu'); if (questionContainer) { // 从iframe中获取题目 const question = extractQuestionFromElement(questionContainer, frame); if (question) { questions.push(question); } break; } } catch (e) { console.error('无法访问iframe内容:', e); } } } // 如果找到了题目,显示在面板中 if (questions.length > 0) { displayQuestions(questions); } else { // 如果没有找到题目,尝试查找题目列表 const questionList = getQuestionList(); if (questionList.length > 0) { displayQuestions(questionList); } else { // 如果仍然没有找到题目,显示错误信息 document.getElementById('qh-question-content').innerHTML = ` <div style="text-align: center; padding: 20px; color: #f44336;"> 未找到题目,请确保您在考试或练习页面。 </div> `; } } } catch (e) { console.error('获取题目和答案出错:', e); document.getElementById('qh-question-content').innerHTML = ` <div style="text-align: center; padding: 20px; color: #f44336;"> 获取题目出错: ${e.message} </div> `; } } // 从元素中提取题目信息 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 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); } // 获取题目列表 function getQuestionList() { const questions = []; // 尝试在主文档中查找题目列表 let questionElements = document.querySelectorAll('.timu'); if (questionElements.length > 0) { // 从主文档中获取题目列表 for (const element of questionElements) { const question = extractQuestionFromElement(element); if (question) { questions.push(question); } } } else { // 尝试在iframe中查找题目列表 const frames = document.querySelectorAll('iframe'); for (const frame of frames) { try { const frameDoc = frame.contentDocument || frame.contentWindow.document; questionElements = frameDoc.querySelectorAll('.timu'); if (questionElements.length > 0) { // 从iframe中获取题目列表 for (const element of questionElements) { const question = extractQuestionFromElement(element, frame); if (question) { questions.push(question); } } break; } } catch (e) { console.error('无法访问iframe内容:', e); } } } return questions; } // 显示题目 function displayQuestions(questions) { const contentElement = document.getElementById('qh-question-content'); if (!contentElement) return; // 构建HTML let html = ''; questions.forEach((question, index) => { html += ` <div class="qh-question-item" data-id="${question.id}"> <div class="qh-question-text">${index + 1}. ${question.question}</div> <div class="qh-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; // 更新状态 document.getElementById('qh-question-status').textContent = `共 ${questions.length} 道题目,已保存 ${window.qh.savedQuestionBank.length} 道题目`; } // 保存题目 function saveQuestions() { try { // 获取当前显示的题目 const questionItems = document.querySelectorAll('.qh-question-item'); if (questionItems.length === 0) { alert('没有可保存的题目'); return; } // 收集题目 const questions = []; questionItems.forEach(item => { const id = item.getAttribute('data-id'); const questionText = item.querySelector('.qh-question-text').textContent.replace(/^\d+\.\s*/, ''); const optionElements = item.querySelectorAll('.qh-question-option'); const options = Array.from(optionElements).map(option => option.textContent.trim()); const answerText = item.querySelector('.qh-question-answer').textContent.replace('答案:', '').trim(); let analysisText = ''; const analysisElement = item.querySelector('.qh-question-analysis'); if (analysisElement) { analysisText = analysisElement.textContent.replace('解析:', '').trim(); } questions.push({ id: id, question: questionText, options: options, answer: answerText, analysis: analysisText, updateTime: Date.now() }); }); // 合并题库 const newQuestions = []; const updatedQuestions = []; questions.forEach(newQuestion => { // 检查题目是否已存在 const existingIndex = window.qh.savedQuestionBank.findIndex(q => q.id === newQuestion.id); if (existingIndex === -1) { // 新题目 window.qh.savedQuestionBank.push(newQuestion); newQuestions.push(newQuestion); } else { // 更新已有题目 const existingQuestion = window.qh.savedQuestionBank[existingIndex]; // 只有在新题目有答案且旧题目没有答案,或者新题目更新时间更新时才更新 if ((!existingQuestion.answer && newQuestion.answer) || (newQuestion.updateTime && (!existingQuestion.updateTime || newQuestion.updateTime > existingQuestion.updateTime))) { window.qh.savedQuestionBank[existingIndex] = newQuestion; updatedQuestions.push(newQuestion); } } }); // 保存题库 GM_setValue('qh-question-bank', window.qh.savedQuestionBank); // 更新状态 document.getElementById('qh-question-status').textContent = `保存成功: 新增 ${newQuestions.length} 道题目, 更新 ${updatedQuestions.length} 道题目, 总计 ${window.qh.savedQuestionBank.length} 道题目`; // 更新主面板的题库状态 const statusElement = document.getElementById('qh-question-status'); if (statusElement) { statusElement.textContent = `题库状态: 已保存 ${window.qh.savedQuestionBank.length} 道题目`; } // 如果启用了远程题库自动同步,则上传题库 if (window.qh.remoteQuestionBankConfig.enabled && window.qh.remoteQuestionBankConfig.uploadEnabled && typeof uploadQuestionBank === 'function') { uploadQuestionBank(); } } catch (e) { console.error('保存题目出错:', e); alert('保存题目出错: ' + e.message); } } // 复制题目到剪贴板 function copyQuestionsToClipboard() { try { // 获取当前显示的题目 const questionItems = document.querySelectorAll('.qh-question-item'); if (questionItems.length === 0) { alert('没有可复制的题目'); return; } // 构建文本 let text = ''; questionItems.forEach((item, index) => { const questionText = item.querySelector('.qh-question-text').textContent.replace(/^\d+\.\s*/, ''); const optionElements = item.querySelectorAll('.qh-question-option'); const options = Array.from(optionElements).map(option => option.textContent.trim()); const answerText = item.querySelector('.qh-question-answer').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); // 更新状态 document.getElementById('qh-question-status').textContent = `已复制 ${questionItems.length} 道题目到剪贴板`; } catch (e) { console.error('复制题目出错:', e); alert('复制题目出错: ' + e.message); } } })();