// ==UserScript==
// @name 超星学习通自动答题 - 终极适配全功能版
// @namespace http://tampermonkey.net/
// @version 1.9
// @description DeepSeek搜题 + 自动翻页 + 进度监控 + 全题型适配 + 暂停功能
// @author dmhnb6
// @match *://mooc1.chaoxing.com/mooc-ans/mooc2/work/dowork*
// @grant GM_xmlhttpRequest
// @connect api.deepseek.com
// ==/UserScript==
(function() {
'use strict';
// ======== 用户配置区 ========
const API_KEY = '您的_DEEPSEEK_API_KEY';
const DELAY = 100; // 每题基础间隔(毫秒)
// ===========================
let isPaused = false;
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
// UI 组件变量
let progressBar, progressText, statusLabel, startBtn;
// 创建 UI 控制面板
function createUI() {
const panel = document.createElement('div');
panel.style = "position:fixed;top:10px;left:50%;transform:translateX(-50%);z-index:10000;width:420px;background:#fff;padding:15px;border-radius:10px;box-shadow:0 4px 15px rgba(0,0,0,0.3);font-family:sans-serif;border:1px solid #ddd;";
panel.innerHTML = `
学习通答题助手 (DeepSeek版)
待命
`;
document.body.appendChild(panel);
progressBar = document.getElementById('auto-progress-bar');
progressText = document.getElementById('auto-progress-text');
statusLabel = document.getElementById('auto-status-label');
startBtn = document.getElementById('auto-start-btn');
const pauseBtn = document.getElementById('auto-pause-btn');
startBtn.onclick = () => {
startBtn.style.display = 'none';
pauseBtn.style.display = 'inline-block';
startSolve();
};
pauseBtn.onclick = () => {
isPaused = !isPaused;
pauseBtn.innerText = isPaused ? '恢复' : '暂停';
pauseBtn.style.background = isPaused ? '#f1c40f' : '#e74c3c';
statusLabel.innerText = isPaused ? '已暂停' : '运行中';
};
}
// 调用 DeepSeek API
async function getAIResponse(question, options, type) {
let sys = "你是一个助手。";
if (type === "单选题" || type === "判断题") sys = "只回答案字母或'正确'/'错误',不解释。";
else if (type === "多选题") sys = "只回答正确字母组合,如ABC,不解释。";
else if (type === "填空题") sys = "多空答案用###分隔,不解释。";
else if (type === "简答题") sys = "提供精炼答案内容。";
return new Promise((resolve) => {
GM_xmlhttpRequest({
method: "POST",
url: "https://api.deepseek.com/chat/completions",
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${API_KEY}` },
data: JSON.stringify({
model: "deepseek-chat",
messages: [{ role: "system", content: sys }, { role: "user", content: `题型:${type}\n题目:${question}\n${options ? '选项:' + options : ''}` }],
temperature: 0.3
}),
onload: (res) => {
try { resolve(JSON.parse(res.responseText).choices[0].message.content.trim()); } catch { resolve(null); }
},
onerror: () => resolve(null)
});
});
}
async function startSolve() {
const sheetItems = document.querySelectorAll('.topicNumber_list li');
const total = sheetItems.length;
for (let i = 0; i < total; i++) {
while (isPaused) await sleep(500);
// 更新进度 UI
const percent = Math.floor(((i + 1) / total) * 100);
progressBar.style.width = `${percent}%`;
progressText.innerText = `${i + 1} / ${total} (${percent}%)`;
const item = sheetItems[i];
// 只有当前题没有被标记为 active(或根据逻辑调整)时执行跳转
statusLabel.innerText = `跳转至第 ${i+1} 题...`;
item.click();
await sleep(300);
const qId = item.getAttribute('data');
const q = document.querySelector(`.questionLi[data="${qId}"]`) || document.querySelector('.questionLi');
if (q) {
const type = q.getAttribute('typeName') || "单选题";
const titleEl = q.querySelector('h3.mark_name');
const questionText = titleEl ? titleEl.innerText.replace(/\s+/g, ' ').trim() : "";
statusLabel.innerText = `正在搜题: 第 ${i+1} 题...`;
if (type === "填空题" || type === "简答题") {
const response = await getAIResponse(questionText, null, type);
if (response) {
const answers = type === "填空题" ? response.split('###') : [response];
const editors = q.querySelectorAll('textarea[id^="answer"]');
for (let idx = 0; idx < editors.length; idx++) {
const editorId = editors[idx].id;
if (window.unsafeWindow && window.unsafeWindow.UE) {
const ue = window.unsafeWindow.UE.getEditor(editorId);
ue.ready(() => {
ue.setContent(answers[idx] || answers[0]);
if (window.unsafeWindow.loadEditorAnswerd) window.unsafeWindow.loadEditorAnswerd(qId, type === "填空题" ? 2 : 4);
});
}
}
}
} else {
const optionElements = q.querySelectorAll('.answerBg');
let opts = Array.from(optionElements).map(opt => opt.innerText.trim()).join(' | ');
const result = await getAIResponse(questionText, opts, type);
if (result) {
const resUpper = result.toUpperCase();
optionElements.forEach(opt => {
const letter = opt.querySelector('[class*="num_option"]')?.innerText.trim().toUpperCase();
if (letter && resUpper.includes(letter)) {
if (opt.getAttribute('aria-checked') !== 'true') opt.click();
} else if (resUpper.includes("正确") && opt.innerText.includes("正确")) {
opt.click();
} else if (resUpper.includes("错误") && opt.innerText.includes("错误")) {
opt.click();
}
});
}
}
}
statusLabel.innerText = `第 ${i+1} 题处理完,等待间隔...`;
await sleep(DELAY + Math.random() * 200);
}
statusLabel.innerText = "全部作答完成";
// 修改后的提示内容
alert("作答完毕,请人工检查后提交。\n(多次运行可提高正确率)");
}
window.addEventListener('load', () => setTimeout(createUI, 2000));
})();