此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/537077/1594816/%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
你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式
(我已經安裝了使用者樣式管理器,讓我安裝!)
// ==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);
}
}
})();