// ==UserScript== // @name 湛江湛江答题 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 自动答题、题库记录和管理功能 // @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) { const key = this.normalizeQuestion(question); if (!this.bank[key]) { this.bank[key] = answer; 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(); } } 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 = `
题库管理

统计信息

总题目数: 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: 300px; 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 { grid-column: 1 / -1; } `; 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('#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; } // 自动答题功能 autoAnswer() { const questions = document.querySelectorAll('.title'); let answeredCount = 0; questions.forEach((questionElement, index) => { const questionText = this.questionBank.normalizeQuestion( questionElement.textContent.replace(/^\d+\./, '').trim() ); const answer = this.questionBank.findAnswer(questionText); if (answer) { const options = questionElement.closest('li').querySelectorAll('input[type="radio"]'); options.forEach(option => { if (option.value === answer) { option.click(); answeredCount++; } }); } }); this.updateDisplay(); alert(`自动答题完成!已回答 ${answeredCount} 道题目`); } // 记录答案功能 recordAnswers() { const resultPageQuestions = document.querySelectorAll('.sp'); let recordedCount = 0; if (resultPageQuestions.length > 0) { // 在结果页面记录答案 resultPageQuestions.forEach((questionElement, index) => { const questionText = this.questionBank.normalizeQuestion( questionElement.textContent.replace(/^\d+\./, '').trim() ); // 查找正确答案 const answerElement = questionElement.closest('li').querySelector('.daan'); if (answerElement) { const answerText = answerElement.textContent.replace('正确答案', '').trim(); if (answerText && answerText.length === 1) { if (this.questionBank.addQuestion(questionText, answerText)) { recordedCount++; } } } }); } else { // 在答题页面手动记录(需要用户交互) const questions = document.querySelectorAll('.title'); questions.forEach((questionElement, index) => { const questionText = this.questionBank.normalizeQuestion( questionElement.textContent.replace(/^\d+\./, '').trim() ); // 检查是否已选择答案 const selectedOption = questionElement.closest('li').querySelector('input[type="radio"]:checked'); if (selectedOption) { if (this.questionBank.addQuestion(questionText, selectedOption.value)) { 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); } } // 等待页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();