// ==UserScript== // @name 湛江湛江答题2 // @namespace http://tampermonkey.net/ // @version 1.3 // @description 自动答题、题库记录和管理功能,支持填空和简答题,修复答案E支持 // @author You // @match *://*qsxueli.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_download // @require https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js // ==/UserScript== (function() { 'use strict'; class QuestionBank { constructor() { this.bank = GM_getValue('question_bank', {}); this.stats = GM_getValue('question_stats', { totalQuestions: 0, answeredQuestions: 0, unknownQuestions: 0, lastUpdate: '' }); } // 添加题目到题库 addQuestion(question, answer, type = 'choice') { const key = this.normalizeQuestion(question); if (!this.bank[key]) { this.bank[key] = { answer: answer, type: type, createdAt: new Date().toISOString() }; this.saveBank(); return true; } return false; } // 查找答案 findAnswer(question) { const key = this.normalizeQuestion(question); return this.bank[key] || null; } // 标准化题目文本 normalizeQuestion(question) { return question.replace(/\s+/g, ' ').trim(); } // 保存题库 saveBank() { GM_setValue('question_bank', this.bank); } // 导出题库 exportBank() { const data = JSON.stringify(this.bank, null, 2); const blob = new Blob([data], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `question_bank_${new Date().toISOString().split('T')[0]}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // 导入题库 importBank(file) { const reader = new FileReader(); reader.onload = (e) => { try { const importedBank = JSON.parse(e.target.result); this.bank = { ...this.bank, ...importedBank }; this.saveBank(); this.updateStats(); alert('题库导入成功!'); } catch (error) { alert('导入失败:文件格式错误'); } }; reader.readAsText(file); } // 更新统计信息 updateStats() { const questionElements = document.querySelectorAll('.title, .sp'); let total = questionElements.length; let answered = 0; let unknown = 0; questionElements.forEach((element, index) => { const questionText = this.normalizeQuestion(element.textContent.replace(/^\d+\./, '').trim()); if (this.findAnswer(questionText)) { answered++; } else { unknown++; } }); this.stats = { totalQuestions: total, answeredQuestions: answered, unknownQuestions: unknown, lastUpdate: new Date().toLocaleString() }; GM_setValue('question_stats', this.stats); return this.stats; } // 获取统计信息 getStats() { return this.updateStats(); } // 检测题目类型(修复版) detectQuestionType(questionElement) { const questionText = questionElement.textContent || ''; const parentLi = questionElement.closest('li'); if (!parentLi) return 'choice'; // 首先检查是否存在输入框或文本域 const hasTextInput = parentLi.querySelector('input[type="text"]'); const hasTextArea = parentLi.querySelector('textarea'); const hasRadioButtons = parentLi.querySelector('input[type="radio"]'); const hasCheckboxes = parentLi.querySelector('input[type="checkbox"]'); // 如果有文本输入框,优先判断为填空题 if (hasTextInput) { return 'fill'; } // 如果有文本域,判断为简答题 if (hasTextArea) { return 'essay'; } // 改进的填空题检测:只有当题目明确包含填空符号且没有选项时才判断为填空题 const hasFillBlankSymbols = questionText.includes('_') || questionText.includes('()') || questionText.includes('()') || questionText.includes('请填写') || questionText.includes('请填空'); // 如果有填空符号但没有单选/多选按钮,才是真正的填空题 if (hasFillBlankSymbols && !hasRadioButtons && !hasCheckboxes) { return 'fill'; } // 如果有单选或多选按钮,就是选择题 if (hasRadioButtons || hasCheckboxes) { return 'choice'; } // 默认情况 return 'choice'; } // 在结果页面检测题目类型 detectQuestionTypeInResult(questionElement) { const questionText = questionElement.textContent || ''; const parentLi = questionElement.closest('li'); if (!parentLi) return 'choice'; // 检查答案元素的特征 const hasChoiceAnswer = parentLi.querySelector('.daan'); const hasFillAnswer = parentLi.querySelector('.tiankong-da, .fill-answer'); const hasEssayAnswer = parentLi.querySelector('.jianda-da, .essay-answer'); if (hasFillAnswer) return 'fill'; if (hasEssayAnswer) return 'essay'; if (hasChoiceAnswer) return 'choice'; // 根据题目文本特征判断 const hasFillBlankSymbols = questionText.includes('_') || questionText.includes('()') || questionText.includes('()') || questionText.includes('请填写') || questionText.includes('请填空'); if (hasFillBlankSymbols) return 'fill'; // 默认 return 'choice'; } } class ControlPanel { constructor(questionBank) { this.questionBank = questionBank; this.panel = null; this.isDragging = false; this.offset = { x: 0, y: 0 }; this.createPanel(); } createPanel() { // 创建控制面板 this.panel = document.createElement('div'); this.panel.id = 'auto-answer-panel'; this.panel.innerHTML = `
题库管理 v1.3

统计信息

总题目数: 0
已收录: 0
未收录: 0
最后更新: -
`; // 添加样式 this.addStyles(); // 添加到页面 document.body.appendChild(this.panel); // 绑定事件 this.bindEvents(); this.updateDisplay(); } addStyles() { const styles = ` #auto-answer-panel { position: fixed; top: 100px; right: 20px; width: 320px; background: white; border: 2px solid #409EFF; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 10000; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; } .panel-header { background: #409EFF; color: white; padding: 10px 15px; cursor: move; display: flex; justify-content: space-between; align-items: center; border-radius: 6px 6px 0 0; user-select: none; } .close-btn { background: none; border: none; color: white; font-size: 18px; cursor: pointer; padding: 0; width: 20px; height: 20px; } .panel-content { padding: 15px; } .stats { margin-bottom: 15px; } .stats h4 { margin: 0 0 10px 0; color: #333; font-size: 14px; } .stat-item { display: flex; justify-content: space-between; margin-bottom: 5px; font-size: 12px; } .stat-item span:first-child { color: #666; } .stat-item span:last-child { color: #409EFF; font-weight: bold; } .actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } .actions button { padding: 8px 12px; border: 1px solid #409EFF; background: white; color: #409EFF; border-radius: 4px; cursor: pointer; font-size: 12px; transition: all 0.3s; } .actions button:hover { background: #409EFF; color: white; } #auto-answer-btn, #fill-blank-btn, #essay-btn { grid-column: 1 / -1; } /* 填空题样式 */ .fill-blank-input { border: 1px solid #409EFF; border-radius: 4px; padding: 4px 8px; margin: 2px; width: 120px; } /* 简答题样式 */ .essay-answer-input { width: 100%; min-height: 80px; border: 1px solid #409EFF; border-radius: 4px; padding: 8px; margin-top: 8px; font-family: inherit; resize: vertical; } .essay-submit-btn { background: #409EFF; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; margin-top: 8px; } `; const styleSheet = document.createElement('style'); styleSheet.textContent = styles; document.head.appendChild(styleSheet); } bindEvents() { // 拖拽功能 const header = this.panel.querySelector('.panel-header'); header.addEventListener('mousedown', this.startDrag.bind(this)); // 关闭按钮 this.panel.querySelector('.close-btn').addEventListener('click', () => { this.panel.style.display = 'none'; }); // 功能按钮 this.panel.querySelector('#auto-answer-btn').addEventListener('click', () => { this.autoAnswer(); }); this.panel.querySelector('#record-answers-btn').addEventListener('click', () => { this.recordAnswers(); }); this.panel.querySelector('#fill-blank-btn').addEventListener('click', () => { this.enableFillBlankMode(); }); this.panel.querySelector('#essay-btn').addEventListener('click', () => { this.enableEssayMode(); }); this.panel.querySelector('#export-btn').addEventListener('click', () => { this.questionBank.exportBank(); }); this.panel.querySelector('#import-btn').addEventListener('click', () => { document.getElementById('import-input').click(); }); document.getElementById('import-input').addEventListener('change', (e) => { if (e.target.files.length > 0) { this.questionBank.importBank(e.target.files[0]); this.updateDisplay(); } }); } startDrag(e) { if (e.target.classList.contains('close-btn')) return; this.isDragging = true; const rect = this.panel.getBoundingClientRect(); this.offset.x = e.clientX - rect.left; this.offset.y = e.clientY - rect.top; document.addEventListener('mousemove', this.drag.bind(this)); document.addEventListener('mouseup', this.stopDrag.bind(this)); } drag(e) { if (!this.isDragging) return; const x = e.clientX - this.offset.x; const y = e.clientY - this.offset.y; this.panel.style.left = x + 'px'; this.panel.style.top = y + 'px'; this.panel.style.right = 'auto'; } stopDrag() { this.isDragging = false; document.removeEventListener('mousemove', this.drag.bind(this)); document.removeEventListener('mouseup', this.stopDrag.bind(this)); } updateDisplay() { const stats = this.questionBank.getStats(); document.getElementById('total-questions').textContent = stats.totalQuestions; document.getElementById('answered-questions').textContent = stats.answeredQuestions; document.getElementById('unknown-questions').textContent = stats.unknownQuestions; document.getElementById('last-update').textContent = stats.lastUpdate; } // 自动答题功能(支持选择题、填空题、简答题)- 修复答案E支持 autoAnswer() { const questions = document.querySelectorAll('.title'); let answeredCount = 0; questions.forEach((questionElement, index) => { const questionText = this.questionBank.normalizeQuestion( questionElement.textContent.replace(/^\d+\./, '').trim() ); const questionData = this.questionBank.findAnswer(questionText); if (questionData) { const questionType = questionData.type || 'choice'; if (questionType === 'choice') { // 选择题 - 修复答案E支持 const options = questionElement.closest('li').querySelectorAll('input[type="radio"], input[type="checkbox"]'); options.forEach(option => { // 支持A-E的答案匹配,包括大小写 const optionValue = option.value.toUpperCase(); const answerValue = questionData.answer.toUpperCase(); if (optionValue === answerValue) { option.click(); answeredCount++; console.log(`选择题自动答题: 题目 "${questionText.substring(0, 30)}..." 选择答案 ${answerValue}`); } }); } else if (questionType === 'fill') { // 填空题 this.answerFillBlank(questionElement, questionData.answer); answeredCount++; } else if (questionType === 'essay') { // 简答题 this.answerEssay(questionElement, questionData.answer); answeredCount++; } } }); this.updateDisplay(); alert(`自动答题完成!已回答 ${answeredCount} 道题目`); } // 填空题答题 answerFillBlank(questionElement, answer) { const parentLi = questionElement.closest('li'); const textInputs = parentLi.querySelectorAll('input[type="text"]'); if (textInputs.length > 0) { // 如果有多个空,答案可能是数组或用分号分隔 let answers = []; if (Array.isArray(answer)) { answers = answer; } else if (typeof answer === 'string' && answer.includes(';')) { answers = answer.split(';'); } else { answers = [answer]; } textInputs.forEach((input, index) => { if (answers[index]) { input.value = answers[index].trim(); // 触发输入事件以确保表单检测到变化 input.dispatchEvent(new Event('input', { bubbles: true })); console.log(`填空题自动答题: 填入答案 "${answers[index].trim()}"`); } }); } } // 简答题答题 answerEssay(questionElement, answer) { const parentLi = questionElement.closest('li'); const textarea = parentLi.querySelector('textarea'); if (textarea) { textarea.value = answer; // 触发输入事件 textarea.dispatchEvent(new Event('input', { bubbles: true })); console.log(`简答题自动答题: 填写答案 "${answer.substring(0, 30)}..."`); } } // 启用填空题模式 enableFillBlankMode() { const questions = document.querySelectorAll('.title'); let processedCount = 0; questions.forEach((questionElement, index) => { const questionText = questionElement.textContent || ''; if (this.questionBank.detectQuestionType(questionElement) === 'fill') { const parentLi = questionElement.closest('li'); const textInputs = parentLi.querySelectorAll('input[type="text"]'); if (textInputs.length > 0) { // 检查是否已有答案 const questionData = this.questionBank.findAnswer( this.questionBank.normalizeQuestion(questionText.replace(/^\d+\./, '').trim()) ); if (questionData && questionData.answer) { this.answerFillBlank(questionElement, questionData.answer); } processedCount++; } } }); alert(`填空题模式已启用!处理了 ${processedCount} 道填空题`); } // 启用简答题模式 enableEssayMode() { const questions = document.querySelectorAll('.title'); let processedCount = 0; questions.forEach((questionElement, index) => { const questionText = questionElement.textContent || ''; if (this.questionBank.detectQuestionType(questionElement) === 'essay') { const parentLi = questionElement.closest('li'); const textarea = parentLi.querySelector('textarea'); if (textarea) { // 检查是否已有答案 const questionData = this.questionBank.findAnswer( this.questionBank.normalizeQuestion(questionText.replace(/^\d+\./, '').trim()) ); if (questionData && questionData.answer) { this.answerEssay(questionElement, questionData.answer); } processedCount++; } } }); alert(`简答题模式已启用!处理了 ${processedCount} 道简答题`); } // 记录答案功能(修复版)- 修复答案E支持 recordAnswers() { const resultPageQuestions = document.querySelectorAll('.sp'); let recordedCount = 0; if (resultPageQuestions.length > 0) { // 在结果页面记录答案(修复选择题记录问题,包括答案E) resultPageQuestions.forEach((questionElement, index) => { const questionText = this.questionBank.normalizeQuestion( questionElement.textContent.replace(/^\d+\./, '').trim() ); // 使用专门的结果页面题目类型检测 const questionType = this.questionBank.detectQuestionTypeInResult(questionElement); console.log(`题目 ${index + 1}: ${questionText.substring(0, 50)}... 类型: ${questionType}`); if (questionType === 'choice') { // 查找正确答案 - 修复选择题答案记录,支持答案E const answerElement = questionElement.closest('li').querySelector('.daan'); if (answerElement) { const answerText = answerElement.textContent.replace(/正确答案[::]?\s*/g, '').trim(); console.log(`找到选择题答案文本: ${answerText}`); // 改进的答案提取,支持A-E(包括E) const answerMatch = answerText.match(/[A-E]/); if (answerMatch) { const answer = answerMatch[0].toUpperCase(); console.log(`提取到选择题答案: ${answer}`); if (this.questionBank.addQuestion(questionText, answer, 'choice')) { recordedCount++; console.log(`成功记录选择题: ${answer}`); } } else { console.log(`未找到有效的选择题答案 (A-E)`); // 尝试其他格式的答案提取 if (answerText.length === 1 && /[A-E]/i.test(answerText)) { const answer = answerText.toUpperCase(); if (this.questionBank.addQuestion(questionText, answer, 'choice')) { recordedCount++; console.log(`通过备选方法记录选择题: ${answer}`); } } } } else { console.log(`未找到选择题答案元素`); } } else if (questionType === 'fill') { // 填空题答案记录 const answerElements = questionElement.closest('li').querySelectorAll('.tiankong-da, .fill-answer'); if (answerElements.length > 0) { const answers = Array.from(answerElements).map(el => el.textContent.trim()); if (answers.length > 0) { const answerStr = answers.join(';'); if (this.questionBank.addQuestion(questionText, answerStr, 'fill')) { recordedCount++; console.log(`记录填空题答案: ${answerStr}`); } } } } else if (questionType === 'essay') { // 简答题答案记录 const answerElement = questionElement.closest('li').querySelector('.jianda-da, .essay-answer'); if (answerElement) { const answerText = answerElement.textContent.trim(); if (answerText) { if (this.questionBank.addQuestion(questionText, answerText, 'essay')) { recordedCount++; console.log(`记录简答题答案: ${answerText.substring(0, 30)}...`); } } } } }); } else { // 在答题页面手动记录(需要用户交互) const questions = document.querySelectorAll('.title'); questions.forEach((questionElement, index) => { const questionText = this.questionBank.normalizeQuestion( questionElement.textContent.replace(/^\d+\./, '').trim() ); const questionType = this.questionBank.detectQuestionType(questionElement); if (questionType === 'choice') { // 检查是否已选择答案 - 支持答案E const selectedOption = questionElement.closest('li').querySelector('input[type="radio"]:checked, input[type="checkbox"]:checked'); if (selectedOption) { const answer = selectedOption.value.toUpperCase(); if (/[A-E]/.test(answer)) { if (this.questionBank.addQuestion(questionText, answer, 'choice')) { recordedCount++; console.log(`手动记录选择题答案: ${answer}`); } } } } else if (questionType === 'fill') { // 记录填空题答案 const textInputs = questionElement.closest('li').querySelectorAll('input[type="text"]'); if (textInputs.length > 0) { const answers = Array.from(textInputs).map(input => input.value.trim()).filter(val => val); if (answers.length > 0) { const answerStr = answers.join(';'); if (this.questionBank.addQuestion(questionText, answerStr, 'fill')) { recordedCount++; } } } } else if (questionType === 'essay') { // 记录简答题答案 const textarea = questionElement.closest('li').querySelector('textarea'); if (textarea && textarea.value.trim()) { if (this.questionBank.addQuestion(questionText, textarea.value.trim(), 'essay')) { recordedCount++; } } } }); } this.updateDisplay(); alert(`记录完成!新增 ${recordedCount} 道题目到题库`); } } // 初始化 let questionBank, controlPanel; function init() { questionBank = new QuestionBank(); controlPanel = new ControlPanel(questionBank); // 页面加载完成后自动更新统计 setTimeout(() => { controlPanel.updateDisplay(); }, 1000); // 如果是结果页面,自动记录答案 if (document.querySelector('.sp')) { setTimeout(() => { controlPanel.recordAnswers(); }, 2000); } // 自动检测并处理填空和简答题 setTimeout(() => { const hasFillQuestions = document.querySelector('input[type="text"]'); const hasEssayQuestions = document.querySelector('textarea'); if (hasFillQuestions || hasEssayQuestions) { console.log('检测到填空或简答题,自动启用相应模式'); if (hasFillQuestions) { controlPanel.enableFillBlankMode(); } if (hasEssayQuestions) { controlPanel.enableEssayMode(); } } }, 3000); } // 等待页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();