// ==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();
}
})();