// ==UserScript== // @name 深圳教师教育网测试题库 // @namespace http://tampermonkey.net/ // @version 2.0 // @description 题库答案 // @author 伯乐 // @match https://www.0755tt.com/student/section* // @grant GM_addStyle // @grant GM_setClipboard // @grant GM_getValue // @grant GM_setValue // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // ==/UserScript== (function() { 'use strict'; // 获取存储的位置 const savedPosition = GM_getValue('extractorPosition', { x: 20, y: 20 }); const savedSize = GM_getValue('extractorSize', { width: 400, height: 500 }); const isCollapsed = GM_getValue('extractorCollapsed', false); // 添加样式 GM_addStyle(` #question-extractor-btn { position: fixed; bottom: 20px; right: 20px; z-index: 99999; padding: 10px 15px; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; box-shadow: 0 2px 10px rgba(0,0,0,0.2); transition: all 0.3s; } #question-extractor-btn:hover { background-color: #45a049; transform: scale(1.05); } #question-extractor-btn:active { transform: scale(0.95); } #extractor-panel { position: fixed; top: ${savedPosition.y}px; left: ${savedPosition.x}px; width: ${savedSize.width}px; height: ${savedSize.height}px; background: white; border-radius: 8px; box-shadow: 0 0 15px rgba(0,0,0,0.3); z-index: 99999; display: ${isCollapsed ? 'none' : 'block'}; overflow: hidden; font-family: 'Microsoft YaHei', sans-serif; transition: all 0.3s; } #panel-header { background: linear-gradient(to right, #3498db, #2980b9); color: white; padding: 8px 15px; cursor: move; display: flex; justify-content: space-between; align-items: center; } #panel-title { font-weight: bold; font-size: 16px; } #panel-controls { display: flex; gap: 8px; } .panel-btn { width: 24px; height: 24px; border-radius: 50%; background: rgba(255,255,255,0.3); color: white; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 14px; transition: all 0.2s; } .panel-btn:hover { background: rgba(255,255,255,0.5); } #panel-content { padding: 15px; overflow-y: auto; height: calc(100% - 60px); } .question-type-section { margin-bottom: 20px; } .section-title { background: #f1f1f1; padding: 5px 10px; border-left: 3px solid #3498db; font-weight: bold; margin-bottom: 10px; font-size: 16px; } .question-item { margin-bottom: 15px; padding: 10px; border-radius: 5px; background: #f9f9f9; transition: all 0.2s; } .question-item:hover { background: #f0f7ff; transform: translateX(5px); } .question-number { font-weight: bold; color: #2980b9; margin-right: 5px; } .question-text { margin-bottom: 8px; line-height: 1.5; } .options { margin-left: 20px; margin-bottom: 8px; } .option { margin: 4px 0; line-height: 1.4; } .answer { color: #e74c3c; font-weight: bold; margin-top: 5px; padding-top: 5px; border-top: 1px dashed #ddd; } #export-btn { margin-top: 10px; padding: 6px 12px; background-color: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer; width: 100%; } #export-btn:hover { background-color: #2980b9; } #resizer { position: absolute; bottom: 0; right: 0; width: 20px; height: 20px; background: #3498db; cursor: nwse-resize; border-top-left-radius: 3px; } .dragging { opacity: 0.9; box-shadow: 0 0 20px rgba(0,0,0,0.5); } `); // 创建按钮 function createButton() { const existingBtn = document.getElementById('question-extractor-btn'); if (existingBtn) existingBtn.remove(); const button = document.createElement('button'); button.id = 'question-extractor-btn'; button.innerHTML = '📚 题目答案'; document.body.appendChild(button); button.addEventListener('click', togglePanel); return button; } // 创建悬浮面板 function createPanel() { const existingPanel = document.getElementById('extractor-panel'); if (existingPanel) existingPanel.remove(); const panel = document.createElement('div'); panel.id = 'extractor-panel'; panel.innerHTML = `
【免费版】深圳教师教育网测试题
by伯乐
等待答案...
`; document.body.appendChild(panel); // 初始化拖拽功能 initDraggable(); // 初始化调整大小功能 initResizable(); // 初始化按钮事件 initControlButtons(); return panel; } // 初始化拖拽功能 function initDraggable() { const panel = document.getElementById('extractor-panel'); const header = document.getElementById('panel-header'); let isDragging = false; let offsetX, offsetY; header.addEventListener('mousedown', (e) => { isDragging = true; offsetX = e.clientX - panel.getBoundingClientRect().left; offsetY = e.clientY - panel.getBoundingClientRect().top; panel.classList.add('dragging'); e.preventDefault(); }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; const x = e.clientX - offsetX; const y = e.clientY - offsetY; // 限制在视窗内 const maxWidth = window.innerWidth - panel.offsetWidth; const maxHeight = window.innerHeight - panel.offsetHeight; panel.style.left = Math.max(0, Math.min(x, maxWidth)) + 'px'; panel.style.top = Math.max(0, Math.min(y, maxHeight)) + 'px'; }); document.addEventListener('mouseup', () => { if (isDragging) { isDragging = false; panel.classList.remove('dragging'); // 保存位置 const rect = panel.getBoundingClientRect(); GM_setValue('extractorPosition', { x: rect.left, y: rect.top }); } }); } // 初始化调整大小功能 function initResizable() { const panel = document.getElementById('extractor-panel'); const resizer = document.getElementById('resizer'); let isResizing = false; resizer.addEventListener('mousedown', (e) => { isResizing = true; document.body.style.cursor = 'nwse-resize'; e.preventDefault(); }); document.addEventListener('mousemove', (e) => { if (!isResizing) return; const rect = panel.getBoundingClientRect(); const width = e.clientX - rect.left; const height = e.clientY - rect.top; // 限制最小尺寸 panel.style.width = Math.max(300, width) + 'px'; panel.style.height = Math.max(300, height) + 'px'; }); document.addEventListener('mouseup', () => { if (isResizing) { isResizing = false; document.body.style.cursor = 'default'; // 保存尺寸 const rect = panel.getBoundingClientRect(); GM_setValue('extractorSize', { width: rect.width, height: rect.height }); } }); } // 初始化控制按钮 function initControlButtons() { document.getElementById('close-btn').addEventListener('click', () => { document.getElementById('extractor-panel').style.display = 'none'; GM_setValue('extractorCollapsed', true); }); document.getElementById('minimize-btn').addEventListener('click', togglePanel); } // 切换面板显示/隐藏 function togglePanel() { const panel = document.getElementById('extractor-panel'); const isHidden = panel.style.display === 'none'; panel.style.display = isHidden ? 'block' : 'none'; GM_setValue('extractorCollapsed', !isHidden); // 更新按钮文本 const btn = document.getElementById('question-extractor-btn'); btn.innerHTML = isHidden ? '📚 题目答案' : '◀ 展开'; } // 拦截XHR获取题目数据 function interceptXHR() { const open = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { if (url.includes('/api/exam/start') || url.includes('/api/exam/answer') || url.includes('paperId') || url.includes('test')) { this.addEventListener('load', function() { try { const response = JSON.parse(this.responseText); if (response.code === 200 && response.data && response.data.questions) { storeAndRenderQuestions(response.data); } } catch (e) { console.error('获取题目失败:', e); } }); } open.apply(this, arguments); }; } // 存储并渲染题目 function storeAndRenderQuestions(data) { window.examData = data; renderQuestions(data); } // 按题型分组题目 function groupQuestionsByType(questions) { const groups = { 'judgment': [], // 判断题 type=1 'single': [], // 单选题 type=2 'multiple': [] // 多选题 type=3 }; questions.forEach(q => { if (q.type === "1") { groups.judgment.push(q); } else if (q.type === "2") { groups.single.push(q); } else if (q.type === "3") { groups.multiple.push(q); } }); return groups; } // 格式化答案文本 function formatAnswer(q) { if (q.type === "1") { return q.answer === "T" ? "【答案】正确" : "【答案】错误"; } else if (q.type === "2") { return `【答案】${q.answer}`; } else if (q.type === "3") { return `【答案】${q.answer.split(',').join(', ')}`; } return `【答案】${q.answer}`; } // 渲染题目 - 修改了题型排序顺序 function renderQuestions(data) { const panelContent = document.getElementById('panel-content'); if (!panelContent) return; // 按题型分组 const grouped = groupQuestionsByType(data.questions); // 构建HTML let html = ''; // 课程信息 html += `
课程: ${data.paper.courseName || '未命名课程'}
章节: ${data.paper.chapterName || '未命名章节'}
测试: ${data.paper.paperName || '未命名测试'}
`; // 单选题 if (grouped.single.length > 0) { html += `
◉ 单选题 (${grouped.single.length}题)
`; grouped.single.forEach((q, index) => { html += `
${index + 1}.${q.question}
`; if (q.options && q.options.length > 0) { html += `
`; q.options.forEach(opt => { html += `
${opt.option}. ${opt.content}
`; }); html += `
`; } html += `
${formatAnswer(q)}
`; }); html += `
`; } // 多选题 if (grouped.multiple.length > 0) { html += `
◉ 多选题 (${grouped.multiple.length}题)
`; grouped.multiple.forEach((q, index) => { html += `
${index + 1}.${q.question}
`; if (q.options && q.options.length > 0) { html += `
`; q.options.forEach(opt => { html += `
${opt.option}. ${opt.content}
`; }); html += `
`; } html += `
${formatAnswer(q)}
`; }); html += `
`; } // 判断题 if (grouped.judgment.length > 0) { html += `
◉ 判断题 (${grouped.judgment.length}题)
`; grouped.judgment.forEach((q, index) => { html += `
${index + 1}.${q.question}
${formatAnswer(q)}
`; }); html += `
`; } // 添加导出按钮 html += ``; panelContent.innerHTML = html; // 添加导出按钮事件 document.getElementById('export-btn').addEventListener('click', exportAsText); } // 导出为文本 function exportAsText() { if (!window.examData) { alert('没有可导出的题目数据'); return; } const grouped = groupQuestionsByType(window.examData.questions); let text = ''; // 课程信息 text += `课程: ${window.examData.paper.courseName || '未命名课程'}\n`; text += `章节: ${window.examData.paper.chapterName || '未命名章节'}\n`; text += `测试: ${window.examData.paper.paperName || '未命名测试'}\n\n`; // 单选题 if (grouped.single.length > 0) { text += `◉ 单选题 (${grouped.single.length}题)\n`; grouped.single.forEach((q, index) => { text += `${index + 1}. ${q.question}\n`; if (q.options && q.options.length > 0) { q.options.forEach(opt => { text += ` ${opt.option}. ${opt.content}\n`; }); } text += `${formatAnswer(q).replace('【答案】', '答案: ')}\n\n`; }); } // 多选题 if (grouped.multiple.length > 0) { text += `\n◉ 多选题 (${grouped.multiple.length}题)\n`; grouped.multiple.forEach((q, index) => { text += `${index + 1}. ${q.question}\n`; if (q.options && q.options.length > 0) { q.options.forEach(opt => { text += ` ${opt.option}. ${opt.content}\n`; }); } text += `${formatAnswer(q).replace('【答案】', '答案: ')}\n\n`; }); } // 判断题 if (grouped.judgment.length > 0) { text += `\n◉ 判断题 (${grouped.judgment.length}题)\n`; grouped.judgment.forEach((q, index) => { text += `${index + 1}. ${q.question}\n`; text += `${formatAnswer(q).replace('【答案】', '答案: ')}\n\n`; }); } // 复制到剪贴板 if (GM_setClipboard) { GM_setClipboard(text); alert('题目内容已复制到剪贴板!'); } else { alert('请手动复制以下内容:\n\n' + text); } } // 初始化 function init() { createButton(); createPanel(); interceptXHR(); // 检查是否有已存储的题目数据 if (window.examData) { renderQuestions(window.examData); } } // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();