// ==UserScript== // @name 广州华商答题助手 // @namespace http://tampermonkey.net/ // @version 5.0 // @description 自动答题、记录题库、智能匹配答案,支持单选、多选、判断、填空、简答题型 // @author ScriptCat // @match *://*.cx-online.net/* // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @run-at document-idle // ==/UserScript== (function() { 'use strict'; // 配置对象 const config = { // 运行模式 mode: 'idle', // 'idle':空闲, 'auto':自动答题, 'record':仅记录 isProcessing: false, // 防止重复处理标志 // 题库数据 questionBank: {}, currentQuestionId: '', // 当前题目ID // 控制面板 panelVisible: true, // 设置 autoDelay: 2500, // 自动答题延迟 autoSwitch: true, // 自动切换到下一题 useBankAnswers: true // 优先使用题库答案 }; // 初始化 function init() { console.log('🚀 初始化智能答题与题库记录助手 v5.0...'); // 加载题库 loadQuestionBank(); // 添加样式 addGlobalStyles(); // 创建控制面板 createControlPanel(); // 初始检查页面 setTimeout(() => { if (config.mode === 'auto') { startAutoMode(); } }, 1000); console.log('✅ 初始化完成'); } // 题库管理函数 function loadQuestionBank() { try { const saved = GM_getValue('questionBank', '{}'); config.questionBank = JSON.parse(saved); console.log(`📚 题库已加载,共有 ${Object.keys(config.questionBank).length} 道题目`); } catch (e) { console.error('❌ 加载题库失败:', e); config.questionBank = {}; } } function saveQuestionBank() { try { GM_setValue('questionBank', JSON.stringify(config.questionBank)); updateQuestionBankCount(); return true; } catch (e) { console.error('❌ 保存题库失败:', e); return false; } } // 核心功能:智能答题 function intelligentAnswer() { if (config.isProcessing) return; config.isProcessing = true; updateControlPanel(); console.log('🤖 开始智能答题...'); setTimeout(() => { try { // 获取当前题目 const currentQuestion = document.querySelector('.homeWork_cxt--left_item:not([style*="display: none"])'); if (!currentQuestion) { console.log('❌ 未找到当前题目'); config.isProcessing = false; return; } // 提取题目数据 const questionData = extractQuestionData(currentQuestion); if (!questionData) { console.log('❌ 无法提取题目数据'); config.isProcessing = false; return; } // 生成题目ID const questionId = generateQuestionId(questionData); config.currentQuestionId = questionId; console.log(`📝 题目类型: ${questionData.type}`); console.log(`📝 题目内容: ${questionData.title.substring(0, 50)}...`); // 1. 优先从题库获取答案 let answerToUse = null; if (config.useBankAnswers && config.questionBank[questionId]) { console.log('🎯 从题库中找到答案'); answerToUse = config.questionBank[questionId].answer; showNotification(`从题库获取答案: ${answerToUse}`, 'success'); } else { // 2. 从页面提取正确答案 answerToUse = extractCorrectAnswer(currentQuestion, questionData.type); if (!answerToUse) { console.log('❌ 无法提取正确答案'); config.isProcessing = false; showNotification('无法提取正确答案', 'error'); return; } // 3. 如果开启了记录模式,保存到题库 if (config.mode === 'record' || config.mode === 'auto') { saveToQuestionBank(questionId, questionData, answerToUse); } } // 4. 自动答题 const result = autoAnswerQuestion(currentQuestion, questionData.type, answerToUse); if (result.success) { showNotification(result.message, 'success'); // 5. 自动切换到下一题 if (config.autoSwitch && config.mode === 'auto') { setTimeout(switchToNextQuestion, config.autoDelay); } else { config.isProcessing = false; updateControlPanel(); } } else { showNotification(result.message, 'warning'); config.isProcessing = false; updateControlPanel(); } } catch (error) { console.error('❌ 智能答题出错:', error); showNotification('答题过程中出错', 'error'); config.isProcessing = false; updateControlPanel(); } }, 1000); } // 提取题目数据 function extractQuestionData(currentQuestion) { const typeElement = currentQuestion.querySelector('.multiple_head--queType'); const titleElement = currentQuestion.querySelector('.multiple_ctx--title'); if (!typeElement || !titleElement) { return null; } const questionType = typeElement.textContent.trim(); const questionTitle = titleElement.textContent.trim(); // 提取选项(如果是选择题) let options = null; if (questionType.includes('单项') || questionType.includes('多项') || questionType.includes('判断') || questionType.includes('选择')) { const optionElements = currentQuestion.querySelectorAll('.multiple_ctx--option'); if (optionElements.length > 0) { options = Array.from(optionElements).map(opt => { const title = opt.querySelector('.multiple_ctx--option_title'); return title ? title.textContent.trim() : ''; }).filter(text => text); } } return { type: questionType, title: questionTitle, options: options }; } // 提取正确答案 function extractCorrectAnswer(currentQuestion, questionType) { let correctAnswer = ''; // 方法1: 从正确答案区域提取 const rightAnsElement = currentQuestion.querySelector('.multiple_ctx--rightAns'); if (rightAnsElement) { const rightAnsText = rightAnsElement.textContent.trim(); // 提取答案部分 if (rightAnsText.includes('正确答案:')) { correctAnswer = rightAnsText.split('正确答案:')[1].trim(); } else if (rightAnsText.includes('正确答案:')) { correctAnswer = rightAnsText.split('正确答案:')[1].trim(); } else { // 尝试直接获取span中的内容 const answerSpan = rightAnsElement.querySelector('span'); if (answerSpan) { correctAnswer = answerSpan.textContent.trim(); } else { // 去除"正确答案"字样 correctAnswer = rightAnsText.replace(/正确答案[::]\s*/, '').trim(); } } if (correctAnswer) { console.log(`✅ 从正确答案区域提取: ${correctAnswer}`); return correctAnswer; } } // 方法2: 从解析中提取注释答案 const analysisElement = currentQuestion.querySelector('.multiple_ctx--analysis'); if (analysisElement) { const analysisText = analysisElement.textContent; if (questionType.includes('简答题') || questionType.includes('简答')) { // 简答题特殊处理 const answerDiv = analysisElement.querySelector('div:last-child'); if (answerDiv) { correctAnswer = answerDiv.textContent.trim(); } else if (analysisText.includes('详情解析:')) { const parts = analysisText.split('详情解析:'); if (parts.length > 1) { correctAnswer = parts[1].trim(); } } } else { // 选择题、判断题等提取注释 const answerMatches = analysisText.match(/\/\*([^*]+)\*\//g); if (answerMatches && answerMatches.length > 0) { // 取最后一个注释作为答案 const lastMatch = answerMatches[answerMatches.length - 1]; correctAnswer = lastMatch.replace(/\/\*/g, '').replace(/\*\//g, '').trim(); } } if (correctAnswer) { console.log(`✅ 从解析中提取: ${correctAnswer}`); return cleanAnswerText(correctAnswer); } } return null; } // 清理答案文本 function cleanAnswerText(answer) { return answer .replace(/\/\*/g, '') .replace(/\*\//g, '') .replace(/^答案[::]\s*/, '') .trim(); } // 保存到题库 function saveToQuestionBank(questionId, questionData, answer) { // 检查是否已存在 if (!config.questionBank[questionId]) { config.questionBank[questionId] = { type: questionData.type, title: questionData.title, answer: answer, options: questionData.options, timestamp: new Date().toISOString(), source: 'auto_record' }; if (saveQuestionBank()) { console.log(`✅ 已记录到题库: ${questionData.title.substring(0, 30)}...`); return true; } } else { console.log('⚠️ 题目已在题库中'); return false; } } // 自动答题 function autoAnswerQuestion(currentQuestion, questionType, answer) { console.log(`🤖 开始自动答题,答案: ${answer}`); if (!answer || answer.trim() === '') { return { success: false, message: '答案为空,无法答题' }; } try { if (questionType.includes('单项') || questionType.includes('单选')) { return handleSingleChoice(currentQuestion, answer); } else if (questionType.includes('多项') || questionType.includes('多选')) { return handleMultipleChoice(currentQuestion, answer); } else if (questionType.includes('判断')) { return handleJudgment(currentQuestion, answer); } else if (questionType.includes('填空')) { return handleFillInBlank(currentQuestion, answer); } else if (questionType.includes('简答')) { return handleShortAnswer(currentQuestion, answer); } else { return { success: false, message: '未知题型,无法答题' }; } } catch (error) { console.error('自动答题出错:', error); return { success: false, message: '答题过程中出错' }; } } // 处理单选题 function handleSingleChoice(currentQuestion, correctAnswer) { const options = currentQuestion.querySelectorAll('.multiple_ctx--option'); // 方法1: 按选项文本匹配 for (let i = 0; i < options.length; i++) { const option = options[i]; const optionText = option.querySelector('.multiple_ctx--option_title').textContent; if (optionText.includes(correctAnswer)) { simulateClick(option); return { success: true, message: `单选题已选择: ${optionText}` }; } } // 方法2: 按字母匹配 const letterMatch = correctAnswer.match(/^[A-E]/i); if (letterMatch) { const letter = letterMatch[0].toUpperCase(); for (let i = 0; i < options.length; i++) { const option = options[i]; const optionText = option.querySelector('.multiple_ctx--option_title').textContent; if (optionText.startsWith(letter)) { simulateClick(option); return { success: true, message: `单选题已选择: ${optionText}` }; } } } return { success: false, message: '未找到匹配的单选题选项' }; } // 处理多选题 function handleMultipleChoice(currentQuestion, correctAnswer) { const options = currentQuestion.querySelectorAll('.multiple_ctx--option'); let selectedCount = 0; // 分割多选题答案 const answerParts = splitMultipleChoiceAnswer(correctAnswer); if (answerParts.length === 0) { return { success: false, message: '多选题答案格式错误' }; } // 收集已选择的选项字母 const selectedLetters = new Set(); // 先处理字母答案 const letterAnswers = answerParts.filter(part => /^[A-E]$/i.test(part)); for (const letter of letterAnswers) { const upperLetter = letter.toUpperCase(); for (let i = 0; i < options.length; i++) { const option = options[i]; const optionText = option.querySelector('.multiple_ctx--option_title').textContent; if (optionText.startsWith(upperLetter) && !selectedLetters.has(upperLetter)) { simulateClick(option); selectedCount++; selectedLetters.add(upperLetter); } } } // 处理文本答案 const textAnswers = answerParts.filter(part => !/^[A-E]$/i.test(part)); for (const textAnswer of textAnswers) { for (let i = 0; i < options.length; i++) { const option = options[i]; const optionText = option.querySelector('.multiple_ctx--option_title').textContent; const optionLetter = optionText.charAt(0); if (selectedLetters.has(optionLetter)) continue; // 提取选项内容(去掉字母和标点) let optionContent = optionText; if (optionText.includes('、')) { optionContent = optionText.split('、')[1] || optionText; } else if (optionText.includes('. ')) { optionContent = optionText.split('. ')[1] || optionText; } else if (/^[A-E]/.test(optionText)) { optionContent = optionText.substring(1).trim(); } // 检查是否匹配 if (optionContent.includes(textAnswer) || textAnswer.includes(optionContent)) { simulateClick(option); selectedCount++; selectedLetters.add(optionLetter); break; } } } if (selectedCount > 0) { return { success: true, message: `多选题已选择 ${selectedCount} 个选项` }; } else { return { success: false, message: '未找到匹配的多选题选项' }; } } // 分割多选题答案 function splitMultipleChoiceAnswer(answer) { if (!answer) return []; let parts = []; // 按常见分隔符分割 const separators = ['、', ',', ',', ';', ';', ' ', ' ']; for (const sep of separators) { if (answer.includes(sep)) { parts = answer.split(sep).map(part => part.trim()).filter(part => part.length > 0); if (parts.length > 1) break; } } // 如果没有找到分隔符,尝试按连接词分割 if (parts.length <= 1) { const connectors = ['和', '与', '及', '以及']; for (const connector of connectors) { if (answer.includes(connector)) { parts = answer.split(connector).map(part => part.trim()).filter(part => part.length > 0); if (parts.length > 1) break; } } } // 如果还是没有分割,返回整个答案 if (parts.length === 0) { parts = [answer]; } return parts; } // 处理判断题 function handleJudgment(currentQuestion, correctAnswer) { const options = currentQuestion.querySelectorAll('.multiple_ctx--option'); // 规范化答案 const normalizedAnswer = correctAnswer.includes('正确') ? '正确' : correctAnswer.includes('错误') ? '错误' : correctAnswer; for (let i = 0; i < options.length; i++) { const option = options[i]; const optionText = option.querySelector('.multiple_ctx--option_title').textContent; if (optionText.includes(normalizedAnswer)) { simulateClick(option); return { success: true, message: `判断题已选择: ${optionText}` }; } } return { success: false, message: '未找到匹配的判断题选项' }; } // 处理填空题 function handleFillInBlank(currentQuestion, correctAnswer) { const inputElements = currentQuestion.querySelectorAll('input.el-input__inner'); if (inputElements.length === 0) { return { success: false, message: '未找到填空题输入框' }; } // 分割答案 let answers = [correctAnswer]; const separators = ['/', ';', ';', '、', ',', ',']; for (const sep of separators) { if (correctAnswer.includes(sep)) { answers = correctAnswer.split(sep).map(a => a.trim()); break; } } // 填充输入框 let filledCount = 0; for (let i = 0; i < inputElements.length; i++) { const input = inputElements[i]; const answerIndex = i < answers.length ? i : 0; // 复用第一个答案 const answer = answers[answerIndex]; if (answer && answer !== '') { input.value = answer; triggerInputEvent(input); input.style.backgroundColor = '#f0f9ff'; input.style.borderColor = '#409EFF'; filledCount++; setTimeout(() => { input.style.backgroundColor = ''; input.style.borderColor = ''; }, 500); } } if (filledCount > 0) { return { success: true, message: `填空题已填充 ${filledCount} 个空` }; } else { return { success: false, message: '填空题答案为空' }; } } // 处理简答题 function handleShortAnswer(currentQuestion, correctAnswer) { const editorElement = currentQuestion.querySelector('.ql-editor'); if (!editorElement) { return { success: false, message: '未找到简答题编辑器' }; } // 清理答案中的注释标记 let cleanAnswer = correctAnswer.replace(/\/\*/g, '').replace(/\*\//g, '').trim(); if (!cleanAnswer || cleanAnswer === '') { return { success: false, message: '简答题答案为空' }; } // 检查编辑器是否为空 const editorContent = editorElement.innerHTML.trim(); if (editorContent === '


' || editorContent === '' || editorContent === '
') { editorElement.innerHTML = ''; const p = document.createElement('p'); p.textContent = cleanAnswer; editorElement.appendChild(p); triggerEditorEvent(editorElement); editorElement.classList.add('auto-filled'); setTimeout(() => { editorElement.classList.remove('auto-filled'); }, 1000); return { success: true, message: '简答题已填写答案' }; } else { return { success: false, message: '简答题已有内容,跳过填写' }; } } // 切换到下一题 function switchToNextQuestion() { console.log('🔄 切换到下一题...'); const currentQuestion = document.querySelector('.homeWork_cxt--left_item:not([style*="display: none"])'); if (!currentQuestion) { config.isProcessing = false; return false; } // 查找下一题按钮 const nextButtons = currentQuestion.querySelectorAll('.el-button.el-button--primary:not(.is-disabled)'); for (const button of nextButtons) { if (button.textContent.includes('下一题')) { simulateClick(button); showNotification('已切换到下一题', 'info'); // 等待新题目加载后继续处理 setTimeout(() => { config.isProcessing = false; if (config.mode === 'auto') { setTimeout(intelligentAnswer, 1000); } }, 2000); return true; } } // 如果没有找到按钮,尝试手动切换 const items = document.querySelectorAll('.homeWork_cxt--left_item'); let currentIndex = -1; for (let i = 0; i < items.length; i++) { if (!items[i].style.display || items[i].style.display === '') { currentIndex = i; break; } } if (currentIndex >= 0 && currentIndex < items.length - 1) { items[currentIndex].style.display = 'none'; items[currentIndex + 1].style.display = ''; setTimeout(() => { config.isProcessing = false; if (config.mode === 'auto') { setTimeout(intelligentAnswer, 1000); } }, 1500); return true; } // 已到最后一道题 config.isProcessing = false; if (config.mode === 'auto') { stopAutoMode(); showNotification('所有题目已完成!', 'success'); } return false; } // 事件触发函数 function simulateClick(element) { const mouseEvents = ['mousedown', 'mouseup', 'click']; mouseEvents.forEach(eventType => { element.dispatchEvent(new MouseEvent(eventType, { bubbles: true, cancelable: true })); }); // 视觉反馈 element.style.transition = 'background-color 0.3s'; element.style.backgroundColor = '#f0f9ff'; setTimeout(() => element.style.backgroundColor = '', 500); } function triggerInputEvent(input) { const events = ['input', 'change', 'blur', 'focus']; events.forEach(eventType => { input.dispatchEvent(new Event(eventType, { bubbles: true })); }); } function triggerEditorEvent(editor) { const events = ['input', 'change', 'text-change']; events.forEach(eventType => { editor.dispatchEvent(new Event(eventType, { bubbles: true })); }); } // 生成题目ID function generateQuestionId(questionData) { const cleanTitle = questionData.title.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, ''); const cleanType = questionData.type.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, ''); return `${cleanType}-${cleanTitle}`; } // 模式控制函数 function startAutoMode() { if (config.mode === 'auto') return; config.mode = 'auto'; console.log('🚀 开启自动答题模式'); showNotification('已开启自动答题模式', 'success'); updateControlPanel(); // 立即开始处理当前题目 intelligentAnswer(); } function startRecordMode() { if (config.mode === 'record') return; config.mode = 'record'; console.log('📝 开启仅记录模式'); showNotification('已开启仅记录模式,将记录题目但不自动答题', 'info'); updateControlPanel(); } function stopAllModes() { config.mode = 'idle'; config.isProcessing = false; console.log('🛑 停止所有模式'); showNotification('已停止所有模式', 'info'); updateControlPanel(); } // 控制面板功能 function createControlPanel() { const panel = document.createElement('div'); panel.id = 'smart-assistant-panel'; panel.innerHTML = `
🤖 智能答题助手 v5.0
运行模式
题库管理
导航控制
题库数量: 0
当前模式: 空闲
处理状态: 空闲
`; document.body.appendChild(panel); // 添加事件监听 document.getElementById('panel-toggle').addEventListener('click', togglePanel); document.getElementById('btn-auto-mode').addEventListener('click', startAutoMode); document.getElementById('btn-record-mode').addEventListener('click', startRecordMode); document.getElementById('btn-stop-all').addEventListener('click', stopAllModes); document.getElementById('btn-single-answer').addEventListener('click', intelligentAnswer); document.getElementById('btn-clear-bank').addEventListener('click', clearQuestionBank); document.getElementById('btn-export-bank').addEventListener('click', exportQuestionBank); document.getElementById('btn-import-bank').addEventListener('click', importQuestionBank); document.getElementById('btn-prev-question').addEventListener('click', switchToPreviousQuestion); document.getElementById('btn-next-question').addEventListener('click', switchToNextQuestion); document.getElementById('cb-use-bank').addEventListener('change', (e) => { config.useBankAnswers = e.target.checked; }); document.getElementById('cb-auto-switch').addEventListener('change', (e) => { config.autoSwitch = e.target.checked; }); // 更新状态 updateQuestionBankCount(); updateControlPanel(); // 添加拖拽功能 makePanelDraggable(panel); } function togglePanel() { const panel = document.getElementById('smart-assistant-panel'); const toggleBtn = document.getElementById('panel-toggle'); if (panel.classList.contains('minimized')) { panel.classList.remove('minimized'); toggleBtn.textContent = '−'; } else { panel.classList.add('minimized'); toggleBtn.textContent = '+'; } } function makePanelDraggable(panel) { const header = panel.querySelector('.panel-header'); let isDragging = false; let dragOffset = { x: 0, y: 0 }; header.addEventListener('mousedown', (e) => { if (e.target.classList.contains('panel-toggle')) return; isDragging = true; const rect = panel.getBoundingClientRect(); dragOffset = { x: e.clientX - rect.left, y: e.clientY - rect.top }; header.style.cursor = 'grabbing'; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; panel.style.left = `${e.clientX - dragOffset.x}px`; panel.style.top = `${e.clientY - dragOffset.y}px`; panel.style.right = 'auto'; }); document.addEventListener('mouseup', () => { if (isDragging) { isDragging = false; header.style.cursor = ''; } }); } function updateControlPanel() { const modeText = document.getElementById('mode-text'); const statusText = document.getElementById('status-text'); if (modeText) { modeText.textContent = config.mode === 'auto' ? '自动答题' : config.mode === 'record' ? '仅记录' : '空闲'; modeText.className = `mode-${config.mode}`; } if (statusText) { statusText.textContent = config.isProcessing ? '处理中...' : '空闲'; statusText.className = config.isProcessing ? 'processing' : ''; } } function updateQuestionBankCount() { const count = Object.keys(config.questionBank).length; const countElement = document.getElementById('bank-count'); if (countElement) { countElement.textContent = count; } } // 切换到上一题 function switchToPreviousQuestion() { const currentQuestion = document.querySelector('.homeWork_cxt--left_item:not([style*="display: none"])'); if (!currentQuestion) return false; const prevButtons = currentQuestion.querySelectorAll('.el-button.el-button--primary:not(.is-disabled)'); for (const button of prevButtons) { if (button.textContent.includes('上一题')) { simulateClick(button); showNotification('已切换到上一题', 'info'); return true; } } // 手动切换 const items = document.querySelectorAll('.homeWork_cxt--left_item'); let currentIndex = -1; for (let i = 0; i < items.length; i++) { if (!items[i].style.display || items[i].style.display === '') { currentIndex = i; break; } } if (currentIndex > 0) { items[currentIndex].style.display = 'none'; items[currentIndex - 1].style.display = ''; return true; } return false; } // 题库管理函数 function clearQuestionBank() { if (confirm('确定要清空题库吗?此操作不可恢复!')) { config.questionBank = {}; saveQuestionBank(); showNotification('题库已清空', 'success'); } } function exportQuestionBank() { try { const data = { version: '5.0', timestamp: new Date().toISOString(), count: Object.keys(config.questionBank).length, questions: config.questionBank }; const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `题库备份_${new Date().toISOString().slice(0,10)}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); showNotification('题库导出成功', 'success'); } catch (e) { console.error('导出失败:', e); showNotification('导出失败', 'error'); } } function importQuestionBank() { const input = document.createElement('input'); input.type = 'file'; input.accept = '.json'; input.onchange = function(e) { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(event) { try { const data = JSON.parse(event.target.result); let imported = 0; if (data.questions) { for (const [key, value] of Object.entries(data.questions)) { if (!config.questionBank[key]) { config.questionBank[key] = value; imported++; } } } saveQuestionBank(); showNotification(`成功导入 ${imported} 道新题目`, 'success'); } catch (e) { console.error('导入失败:', e); showNotification('导入失败,文件格式错误', 'error'); } }; reader.readAsText(file); }; input.click(); } // 显示通知 function showNotification(message, type = 'info') { const id = 'smart-assistant-notification'; let notification = document.getElementById(id); if (!notification) { notification = document.createElement('div'); notification.id = id; document.body.appendChild(notification); } notification.textContent = message; notification.className = `notification notification-${type}`; notification.style.display = 'block'; setTimeout(() => { if (notification.parentNode) { notification.style.opacity = '0'; setTimeout(() => { if (notification.parentNode) { notification.style.display = 'none'; notification.style.opacity = '1'; } }, 300); } }, 3000); } // 添加全局样式 function addGlobalStyles() { const styles = ` /* 控制面板样式 */ #smart-assistant-panel { position: fixed !important; top: 100px !important; right: 20px !important; width: 300px !important; background: white !important; border-radius: 12px !important; box-shadow: 0 8px 32px rgba(0,0,0,0.2) !important; z-index: 100000 !important; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; overflow: hidden !important; border: 1px solid #e1e4e8 !important; transition: all 0.3s ease !important; } #smart-assistant-panel.minimized { height: 40px !important; } #smart-assistant-panel.minimized .panel-body { display: none !important; } .panel-header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; color: white !important; padding: 12px 16px !important; display: flex !important; justify-content: space-between !important; align-items: center !important; cursor: move !important; user-select: none !important; } .panel-title { font-weight: 600 !important; font-size: 14px !important; display: flex !important; align-items: center !important; gap: 8px !important; } .panel-toggle { background: rgba(255,255,255,0.2) !important; border: none !important; color: white !important; font-size: 18px !important; cursor: pointer !important; width: 24px !important; height: 24px !important; border-radius: 4px !important; display: flex !important; align-items: center !important; justify-content: center !important; } .panel-body { padding: 16px !important; } .panel-section { margin-bottom: 16px !important; padding-bottom: 16px !important; border-bottom: 1px solid #f0f0f0 !important; } .panel-section:last-child { margin-bottom: 0 !important; padding-bottom: 0 !important; border-bottom: none !important; } .section-title { font-size: 12px !important; color: #666 !important; margin-bottom: 8px !important; font-weight: 600 !important; text-transform: uppercase !important; letter-spacing: 0.5px !important; } .btn { display: block !important; width: 100% !important; padding: 10px 12px !important; margin: 6px 0 !important; border: none !important; border-radius: 8px !important; font-size: 14px !important; font-weight: 500 !important; cursor: pointer !important; text-align: center !important; transition: all 0.2s ease !important; position: relative !important; overflow: hidden !important; } .btn::after { content: '' !important; position: absolute !important; top: 50% !important; left: 50% !important; width: 5px !important; height: 5px !important; background: rgba(255, 255, 255, 0.5) !important; opacity: 0 !important; border-radius: 100% !important; transform: scale(1, 1) translate(-50%) !important; transform-origin: 50% 50% !important; } .btn:focus:not(:active)::after { animation: ripple 1s ease-out !important; } @keyframes ripple { 0% { transform: scale(0, 0) !important; opacity: 0.5 !important; } 20% { transform: scale(60, 60) !important; opacity: 0.3 !important; } 100% { transform: scale(100, 100) !important; opacity: 0 !important; } } .btn:hover { transform: translateY(-2px) !important; box-shadow: 0 4px 12px rgba(0,0,0,0.1) !important; } .btn:active { transform: translateY(0) !important; } .btn:disabled { opacity: 0.5 !important; cursor: not-allowed !important; transform: none !important; box-shadow: none !important; } .btn-success { background: linear-gradient(135deg, #67C23A 0%, #5db333 100%) !important; color: white !important; } .btn-danger { background: linear-gradient(135deg, #F56C6C 0%, #e05c5c 100%) !important; color: white !important; } .btn-primary { background: linear-gradient(135deg, #409EFF 0%, #3a8fe6 100%) !important; color: white !important; } .btn-secondary { background: linear-gradient(135deg, #909399 0%, #82848a 100%) !important; color: white !important; } .btn-outline { background: transparent !important; border: 1px solid #dcdfe6 !important; color: #606266 !important; } .btn-outline:hover { background: #f5f7fa !important; } .btn-sm { padding: 6px 10px !important; font-size: 12px !important; } .btn-group { display: flex !important; gap: 8px !important; margin-top: 8px !important; } .btn-group .btn { flex: 1 !important; margin: 0 !important; } .form-group { margin-top: 12px !important; display: flex !important; flex-direction: column !important; gap: 8px !important; } .form-group label { display: flex !important; align-items: center !important; gap: 6px !important; font-size: 13px !important; color: #606266 !important; cursor: pointer !important; } .form-group input[type="checkbox"] { width: 14px !important; height: 14px !important; cursor: pointer !important; } .panel-status { font-size: 12px !important; color: #666 !important; margin-top: 12px !important; padding: 12px !important; background: linear-gradient(135deg, #f5f7fa 0%, #f0f2f5 100%) !important; border-radius: 8px !important; } .panel-status div { margin: 4px 0 !important; display: flex !important; justify-content: space-between !important; } #mode-text.mode-auto { color: #67C23A !important; font-weight: bold !important; } #mode-text.mode-record { color: #409EFF !important; font-weight: bold !important; } #mode-text.mode-idle { color: #909399 !important; font-weight: normal !important; } #status-text.processing { color: #E6A23C !important; font-weight: bold !important; animation: pulse 2s infinite !important; } @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } /* 通知样式 */ .notification { position: fixed !important; top: 20px !important; right: 20px !important; padding: 14px 20px !important; border-radius: 8px !important; color: white !important; font-weight: 500 !important; z-index: 100001 !important; box-shadow: 0 8px 24px rgba(0,0,0,0.2) !important; transition: all 0.3s ease !important; max-width: 400px !important; font-size: 14px !important; display: none !important; backdrop-filter: blur(10px) !important; background: rgba(0,0,0,0.8) !important; border: 1px solid rgba(255,255,255,0.1) !important; } .notification-info { background: rgba(64, 158, 255, 0.9) !important; } .notification-success { background: rgba(103, 194, 58, 0.9) !important; } .notification-warning { background: rgba(230, 162, 60, 0.9) !important; } .notification-error { background: rgba(245, 108, 108, 0.9) !important; } /* 答题高亮样式 */ .multiple_ctx--option.auto-selected { background-color: #f0f9ff !important; border: 2px solid #409EFF !important; border-radius: 8px !important; transition: all 0.3s ease !important; } .multiple_ctx--option_radio.auto-selected { background-color: #409EFF !important; } input.el-input__inner.auto-filled { background-color: #f0f9ff !important; border-color: #409EFF !important; box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2) !important; } .ql-editor.auto-filled { background-color: #f0f9ff !important; border: 2px solid #409EFF !important; border-radius: 8px !important; } `; const style = document.createElement('style'); style.textContent = styles; document.head.appendChild(style); } // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { setTimeout(init, 1000); } // 监听页面变化 const observer = new MutationObserver(function(mutations) { if (config.mode === 'auto' && !config.isProcessing) { // 延迟执行,避免频繁触发 clearTimeout(window.delayedAnswer); window.delayedAnswer = setTimeout(() => { intelligentAnswer(); }, 1500); } }); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); // 暴露API供调试 window.SmartAnswerAssistant = { getConfig: () => config, startAutoMode: startAutoMode, startRecordMode: startRecordMode, stopAllModes: stopAllModes, answerCurrent: intelligentAnswer, clearBank: clearQuestionBank, exportBank: exportQuestionBank }; console.log('🎉 智能答题与题库记录助手已加载'); console.log('📋 使用指南:'); console.log(' 1. 自动答题模式:自动答题并记录新题目'); console.log(' 2. 仅记录模式:只记录题目不自动答题'); console.log(' 3. 优先使用题库答案:如果题库中有题目,直接使用题库答案'); console.log(' 4. 可在控制台使用 window.SmartAnswerAssistant 进行调试'); })();