晚风知到答题小助手

智慧树章节测试自动答题

// ==UserScript==
// @name        晚风知到答题小助手
// @namespace    晚风
// @version      1.0
// @description  智慧树章节测试自动答题
// @author       晚风
// @match        *://*.zhihuishu.com/stuExamWeb*
// @connect      fengtingwanli.cn
// @run-at       document-start
// @grant        unsafeWindow
// @grant        GM_xmlhttpRequest
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @grant        GM_setClipboard
// @grant        GM_setValue
// @grant        GM_getValue
// @resource     css https://unpkg.com/[email protected]/lib/theme-chalk/index.css
// @license      MIT
// @antifeature  ads
// ==/UserScript==

const qrCode = ``;
let isCollapsed = false; // 折叠状态
const logMessages = []; // 日志消息存储
let windowState = { // 窗口状态存储
    width: 500, // 增大宽度以适应左右布局
    height: 450, // 减小高度
    left: 20,
    top: 20,
    collapsed: false
};

function loadWindowState() {
    try {
        const savedState = GM_getValue('windowState', null);
        if (savedState) {
            windowState = JSON.parse(savedState);
            isCollapsed = windowState.collapsed;
        }
    } catch (e) {
        logMessage('加载窗口状态失败: ' + e.message, 'warning');
    }
}

function saveWindowState() {
    try {
        const floatingWindow = document.getElementById('floating-window');
        if (floatingWindow) {
            windowState.width = parseInt(getComputedStyle(floatingWindow).width);
            windowState.height = parseInt(getComputedStyle(floatingWindow).height);
            windowState.left = parseInt(floatingWindow.style.left);
            windowState.top = parseInt(floatingWindow.style.top);
            windowState.collapsed = isCollapsed;
            GM_setValue('windowState', JSON.stringify(windowState));
        }
    } catch (e) {
        logMessage('保存窗口状态失败: ' + e.message, 'warning');
    }
}

enableWebpackHook();

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

const config = {
    awaitTime: 5000,
    stopTimer: false,
    questionCount: 0,
    finishCount: 0,
    questionType: {
        '判断题': 10,
        '单选题': 20,
        '多选题': 25,
        '填空题': 30,
        '问答题': 40,
    },
    apiKey: GM_getValue('apiKey', '')
};

function logMessage(message, type = 'info') {
    const timestamp = new Date().toLocaleTimeString();
    logMessages.push({ timestamp, message, type });
    if (logMessages.length > 30) logMessages.shift();
    updateLogDisplay();
}
function showTip(message, type = 'info', duration = 2000) {
    const tipEl = document.createElement('div');
    tipEl.textContent = message;
    tipEl.style.position = 'relative'; // 原来是 fixed 改成 relative
    tipEl.style.display = 'inline-block';
    tipEl.style.marginTop = '8px';      // 输入框下方间距
    tipEl.style.padding = '6px 12px';
    tipEl.style.borderRadius = '4px';
    tipEl.style.color = 'white';
    tipEl.style.fontSize = '13px';
    tipEl.style.fontWeight = '500';
    tipEl.style.zIndex = '1000';
    tipEl.style.opacity = '0';
    tipEl.style.transition = 'opacity 0.3s';

    // 根据类型设置背景色
    switch(type) {
        case 'success': tipEl.style.backgroundColor = '#67c23a'; break;
        case 'warning': tipEl.style.backgroundColor = '#e6a23c'; break;
        case 'error': tipEl.style.backgroundColor = '#f56c6c'; break;
        default: tipEl.style.backgroundColor = '#909399';
    }

    // 插入到 API Key 按钮下方
    const apiContainer = document.getElementById('save-api-key-btn').parentElement;
    apiContainer.appendChild(tipEl);

    // 渐显
    requestAnimationFrame(() => tipEl.style.opacity = '1');

    // 定时移除
    setTimeout(() => {
        tipEl.style.opacity = '0';
        setTimeout(() => tipEl.remove(), 300);
    }, duration);
}

function updateLogDisplay() {
    const logContainer = document.getElementById('log-container');
    if (!logContainer) return;

    logContainer.innerHTML = '';

    logMessages.forEach(entry => {
        const logItem = document.createElement('div');
        logItem.className = `log-item log-${entry.type}`;
        logItem.innerHTML = `
            <span class="log-timestamp">${entry.timestamp}</span>
            <span class="log-content">${entry.message}</span>
        `;
        logContainer.appendChild(logItem);
    });

    logContainer.scrollTop = logContainer.scrollHeight;
}

function answerQuestion(questionBody, questionIndex) {
    // 获取题目
    const questionTitle = questionBody.querySelector('.subject_describe div,.smallStem_describe p')
        .__Ivue__._data.shadowDom.textContent
        .replace(/%C2%A0/g, '%20')
        .replace(/\s+/g, ' ');

    console.log(`第 ${questionIndex} 题:`, questionTitle);

    // 获取选项
    const options = questionBody.querySelectorAll(".node_detail");
    if (options.length) {
        options.forEach((option, idx) => {
            console.log(`选项 ${idx + 1}:`, option.innerText.trim());
        });
    } else {
        console.log('未检测到选项');
    }

    appendToTable(questionTitle, "", questionIndex);
    logMessage(`正在处理第 ${questionIndex} 题: ${questionTitle.substring(0, 30)}...`);

    const questionType = questionBody.querySelector(".subject_type").innerText.match(/【(.+)】|$/)[1];
    let type = config.questionType[questionType];
    type = type !== undefined ? type : -1;

    // 构造 API URL
    const apiurl = `https://www.fengtingwanli.cn/answer.php?question=${encodeURIComponent(questionTitle)}${config.apiKey ? `&key=${config.apiKey}` : ''}`;
    console.log(apiurl)
GM_xmlhttpRequest({
    method: "GET",
    url: apiurl,
    onload: xhr => {
        try {
            const res = JSON.parse(xhr.responseText);
            const msg = res.msg;
            const answerString = res.answer;

            const questionTypeText = questionBody.querySelector(".subject_type").innerText.match(/【(.+)】|$/)[1];
            let type = config.questionType[questionTypeText];
            type = type !== undefined ? type : -1;

            if (msg === "暂无答案") {
                updateAnswerInTable(questionIndex, "暂无答案", false);
                logMessage(`第 ${questionIndex} 题: 暂无答案`, 'warning');
            } else if (msg === "无效的API,请检查后重试") {
                updateAnswerInTable(questionIndex, "API Key无效,请检查后重试", false);
                logMessage(`第 ${questionIndex} 题: API Key无效`, 'error');
            } else {
                updateAnswerInTable(questionIndex, answerString, true);
                logMessage(`第 ${questionIndex} 题: 已获取答案`, 'success');

                // **这里添加调用选择答案**
                const selected = chooseAnswer(type, questionBody, answerString);
                if (!selected) {
                    logMessage(`第 ${questionIndex} 题: 未匹配到网页选项,需要手动选择`, 'warning');
                }
            }

            // 自动切换下一题
            document.querySelectorAll('.switch-btn-box > button')[1]?.click();
        } catch (error) {
            logMessage(`第 ${questionIndex} 题: 解析答案出错 - ${error.message}`, 'error');
        }
    }
});
}
function chooseAnswer(questionType, questionBody, answerString) {
    let isSelect = false;
    const answers = answerString.split(/[\u0001,#=;=-|;、,]+/).map(a => a.trim()).filter(Boolean);

    if (!questionBody) return isSelect;

    switch (questionType) {
        case 10: // 判断题
            return handleJudgment(questionBody, answers);
        case 20: // 单选题
            return handleSingleChoice(questionBody, answers);
        case 25: // 多选题
            return handleMultipleChoice(questionBody, answers);
        case 30: // 填空题
            return handleFillInBlank(questionBody, answers);
        case 40: // 问答题
            return handleEssay(questionBody, answerString);
        default:
            return isSelect;
    }
}

// 判断题
function handleJudgment(questionBody, answers) {
    const firstOption = questionBody.querySelector(".nodeLab");
    const secondOption = questionBody.querySelectorAll(".nodeLab")[1];
    if (!firstOption || !secondOption) return false;

    const optionText = questionBody.querySelector(".node_detail")?.innerText || "";
    const givenAnswer = answers[0]?.toLowerCase();

    const isCorrectAnswer = /正确|是|对|√|t|true/i.test(givenAnswer);
    const isOptionCorrect = /正确|是|对|√|t|true/i.test(optionText);

    if (isCorrectAnswer === isOptionCorrect) {
        firstOption.click();
    } else if (!isOptionCorrect && !isCorrectAnswer) {
        firstOption.click();
    } else if (isCorrectAnswer !== isOptionCorrect) {
        secondOption.click();
    } else {
        return false;
    }

    return true;
}

function handleSingleChoice(questionBody, answers) {
    const options = questionBody.querySelectorAll(".node_detail");
    if (!options.length) return false;

    const targetAnswer = answers[0];
    if (!targetAnswer) return false;

    for (let i = 0; i < options.length; i++) {
        const optionText = options[i].innerText.trim();
        if (optionText === targetAnswer){ // 直接完全匹配
            clickOption(i, questionBody);
            return true;
        }
    }

    return false; // 网页选项中没有对应答案
}

function handleMultipleChoice(questionBody, answers) {
    const options = questionBody.querySelectorAll(".node_detail");
    if (!options.length || !answers.length) return false;

    let matched = false;
    const selectedOptions = new Set();

    answers.forEach(answer => {
        for (let i = 0; i < options.length; i++) {
            if (selectedOptions.has(i)) continue;
            const optionText = options[i].innerText.trim();
            if (optionText === answer) {
                clickOption(i, questionBody);
                selectedOptions.add(i);
                matched = true;
                break;
            }
        }
    });

    return matched;
}

function handleFillInBlank(questionBody, answers) {
    const blanks = questionBody.querySelectorAll(".blankInput");
    if (!blanks.length) return false;

    for (let i = 0; i < blanks.length; i++) {
        const blank = blanks[i];
        if (i < answers.length) {
            blank.value = answers[i];
        } else {

            blank.value = answers[0] || "";
        }
    }
    return blanks.length > 0;
}

function handleEssay(questionBody, answerString) {
    const answerArea = questionBody.querySelector("textarea");
    if (answerArea) {
        answerArea.value = answerString;
        return true;
    }
    return false;
}

function clickOption(index, questionBody) {
    const optionLabel = questionBody.querySelectorAll(".nodeLab")[index];
    if (optionLabel) optionLabel.click();
}

function appendToTable(questionTitle, answerString, questionIndex) {
    const table = document.querySelector("#record-table tbody");
    table.innerHTML += `<tr><td>${questionIndex}</td><td>${questionTitle}</td><td id="answer${questionIndex}">正在搜索...</td></tr>`;
}

function changeAnswerInTable(answerString, questionIndex, isSelect) {
    const answerCell = document.querySelector(`#answer${questionIndex}`);
    answerCell.innerHTML = answerString;
    if (answerString === "暂无答案") {
        answerCell.insertAdjacentHTML('beforeend', `<p style="color:red"><i class="el-icon-error"></i> 暂无答案</p>`);
    }
    if (!isSelect) {
        answerCell.insertAdjacentHTML('beforeend', `<p style="color:red"><i class="el-icon-warning"></i> 未匹配答案,请根据搜索结果手动选择答案</p>`);
    }
}

function enableWebpackHook() {
    const originCall = Function.prototype.call;
    Function.prototype.call = function (...args) {
        const result = originCall.apply(this, args);
        if (args[2]?.default?.version === '2.5.2') {
            args[2]?.default?.mixin({
                mounted: function () {
                    this.$el['__Ivue__'] = this;
                }
            });
        }
        return result;
    }
}

function makeElementResizableDraggable(el) {
    loadWindowState();

    el.style.position = 'absolute';
    el.style.width = `${windowState.width}px`;
    el.style.height = `${windowState.height}px`;
    el.style.left = `${windowState.left}px`;
    el.style.top = `${windowState.top}px`;
    if (isCollapsed) {
        const dialogContent = document.querySelector('.el-dialog__body');
        const collapseBtn = document.querySelector('#collapse-btn i');
        dialogContent.style.display = 'none';
        collapseBtn.className = 'el-icon-circle-plus';
    }
    const header = el.querySelector('.el-dialog__header');
    header.style.cursor = 'move';

    header.onmousedown = function (event) {
        if (event.target.id === 'collapse-btn' || event.target.parentElement.id === 'collapse-btn') {
            return;
        }

        let shiftX = event.clientX - el.getBoundingClientRect().left;
        let shiftY = event.clientY - el.getBoundingClientRect().top;

        function moveAt(pageX, pageY) {
            el.style.left = pageX - shiftX + 'px';
            el.style.top = pageY - shiftY + 'px';
        }

        function onMouseMove(event) {
            moveAt(event.pageX, event.pageY);
        }

        document.addEventListener('mousemove', onMouseMove);

        el.onmouseup = function () {
            document.removeEventListener('mousemove', onMouseMove);
            el.onmouseup = null;
            saveWindowState();
        };
    };

    el.ondragstart = function () {
        return false;
    };
    const resizer = document.createElement('div');
    resizer.style.position = 'absolute';
    resizer.style.bottom = '0';
    resizer.style.right = '0';
    resizer.style.width = '15px';
    resizer.style.height = '15px';
    resizer.style.cursor = 'se-resize';
    resizer.style.zIndex = '100';
    resizer.className = 'el-icon-crop';
    resizer.style.color = '#409EFF';
    el.appendChild(resizer);

    resizer.onmousedown = function (event) {
        const startX = event.clientX;
        const startY = event.clientY;
        const startWidth = el.offsetWidth;
        const startHeight = el.offsetHeight;

        function resizeAt(pageX, pageY) {
            const newWidth = startWidth + (pageX - startX);
            const newHeight = startHeight + (pageY - startY);

            if (newWidth >= 500) { 
                el.style.width = newWidth + 'px';
            }
            if (newHeight >= 370) { 
                el.style.height = newHeight + 'px';
            }
        }

        function onMouseMove(event) {
            resizeAt(event.pageX, event.pageY);
        }

        document.addEventListener('mousemove', onMouseMove);

        document.onmouseup = function () {
            document.removeEventListener('mousemove', onMouseMove);
            document.onmouseup = null;
            saveWindowState(); 
        };

        event.preventDefault(); 
    };
}

function toggleCollapse() {
    isCollapsed = !isCollapsed;
    const dialogContent = document.querySelector('.el-dialog__body');
    const collapseBtn = document.querySelector('#collapse-btn i');

    if (isCollapsed) {
        dialogContent.style.display = 'none';
        collapseBtn.className = 'el-icon-circle-plus';
       
        const floatingWindow = document.getElementById('floating-window');
        floatingWindow.style.height = '40px';
    } else {
        dialogContent.style.display = 'block';
        collapseBtn.className = 'el-icon-circle-minus';
       
        const floatingWindow = document.getElementById('floating-window');
        floatingWindow.style.height = `${windowState.height}px`;
    }

    saveWindowState(); 
}

function updateAnswerInTable(questionIndex, msg, isSelect = true) {
    const answerCell = document.querySelector(`#answer${questionIndex}`);
    if (!answerCell) return;

    answerCell.innerHTML = '';
    const mainMsg = document.createElement('div');
    mainMsg.textContent = msg;
    answerCell.appendChild(mainMsg);

    if (!isSelect) {
        const warn = document.createElement('p');
        warn.style.color = 'red';
        warn.innerHTML = '<i class="el-icon-warning"></i> 未匹配答案,请根据搜索结果手动选择';
        answerCell.appendChild(warn);
    }

    const tbody = answerCell.closest('tbody');
    if (tbody) tbody.scrollTop = tbody.scrollHeight;
}



function saveApiKey() {
    const apiKeyInput = document.getElementById('api-key-input');
    const newApiKey = apiKeyInput.value.trim();
    if (newApiKey) {
        GM_setValue('apiKey', newApiKey);
        config.apiKey = newApiKey; // 更新本地配置
        logMessage('API Key 保存成功', 'success');
        showTip('API Key 保存成功', 'success'); // 显示提示在按钮下方
    } else {
        logMessage('API Key 不能为空', 'warning');
        showTip('API Key 不能为空', 'warning');
    }
}

function clearApiKey() {
    GM_setValue('apiKey', '');
    config.apiKey = ''; // 清空本地配置
    document.getElementById('api-key-input').value = ''; // 清空输入框
    logMessage('API Key 已清除', 'info');
    showTip('API Key 已清除', 'info'); // 显示提示在按钮下方
}

unsafeWindow.onload = (() => (async () => {
    // 加载 Element UI 样式
    GM_addStyle(GM_getResourceText("css"));

    // ================== CSS 优化 ==================
    GM_addStyle(`
    /* 全局字体 & 行高 */
    body, .el-dialog, .el-card, .el-table, .el-input__inner, .el-button {
        font-family: 'Helvetica', 'Microsoft YaHei', sans-serif;
        line-height: 1.6;
    }

    /* 整体窗口 */
    .el-dialog {
        border-radius: 10px;
        overflow: hidden;
        box-shadow: 0 8px 25px rgba(0,0,0,0.15);
    }
    .el-dialog__header {
        background: linear-gradient(90deg, #409EFF, #66b1ff);
        color: white;
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 10px 15px;
        font-size: 16px;
        cursor: move;
    }
    .el-dialog__title i { margin-right: 8px; font-size: 18px; }
    #collapse-btn i { font-size: 16px; color: white; }
    .el-dialog__headerbtn .el-dialog__close {
        color: white; font-size: 16px; transition: transform 0.3s;
    }
    .el-dialog__headerbtn:hover .el-dialog__close { transform: rotate(90deg); }


    /* 答题记录表格优化 */
#record-table th:nth-child(1),
#record-table td:nth-child(1) { width: 50px; text-align: center; }
#record-table th:nth-child(2),
#record-table td:nth-child(2) { width: 45%; }
#record-table th:nth-child(3),
#record-table td:nth-child(3) { width: 45%; word-wrap: break-word; }

    /* 导航栏 */
    .nav-bar {
        display: flex;
        background-color: #f5f7fa;
        border-bottom: 1px solid #dcdfe6;
    }
    .nav-bar button {
        flex: 1; border: none; background: transparent;
        padding: 10px 0; font-size: 14px; cursor: pointer;
        transition: background 0.2s, color 0.2s;
    }
    .nav-bar button:hover { background-color: #e6f0ff; }
    .nav-bar button.active {
        background-color: #409EFF; color: white; border-radius: 4px 4px 0 0;
    }

    /* 页面内容 */
    .page { display: none; padding: 10px; height: calc(100% - 40px - 35px); overflow-y: auto; }
    .page.active { display: block; }

    /* 卡片 */
    .el-card {
        border-radius: 8px;
        box-shadow: 0 4px 12px rgba(0,0,0,0.05);
        margin-bottom: 15px;
        overflow: hidden;
    }
    .el-card__header {
        background-color: #f5f7fa;
        padding: 10px 15px;
        font-weight: 500;
        display: flex;
        align-items: center;
    }
    .el-card__header i { margin-right: 5px; color: #409EFF; }
    .el-card__body {
        padding: 12px;
        display: flex;
        flex-direction: column;
        gap: 10px;
        box-sizing: border-box;
    }

    /* 表格 */
    .el-table {
        border-radius: 6px;
        width: 100%;
        border-collapse: collapse;
    }
    .el-table th, .el-table td {
        padding: 10px 12px;
        font-size: 14px;
        border-bottom: 1px solid #ebeef5;
        text-align: left;
        vertical-align: middle; /* 垂直居中 */
        white-space: normal;
        word-break: break-word;
    }
    .el-table th {
        background-color: #f5f7fa;
        font-weight: 600;
    }

    /* 日志容器 */
    #log-container {
        font-size: 13px;
        max-height: 250px;
        overflow-y: auto;
        background: #f9fafc;
        padding: 10px;
        line-height: 1.5;
        border-radius: 6px;
    }
    .log-item { margin-bottom: 5px; }
    .log-info { color: #909399; }
    .log-success { color: #67c23a; }
    .log-warning { color: #e6a23c; }
    .log-error { color: #f56c6c; }

    /* 输入框和按钮 */
    .el-input__inner {
        height: 36px;
        line-height: 36px;
        border-radius: 6px;
        box-sizing: border-box;
    }
    .el-button--medium { padding: 6px 12px; font-size: 13px; border-radius: 4px; }
    .el-button--primary { background-color: #409EFF; border-color: #409EFF; }
    .el-button--primary:hover { background-color: #66b1ff; border-color: #66b1ff; }
    .el-button--danger { background-color: #f56c6c; border-color: #f56c6c; }
    .el-button--danger:hover { background-color: #f78989; }

    /* 二维码卡片居中显示 */
    .qr-code-container {
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
    }
    .qr-code-container img {
        width: auto;
        max-width: 200px;
        height: auto;
        margin: 0 auto;
        border-radius: 6px;
        border: 1px solid #ebeef5;
    }
    .qr-code-container p {
        font-size: 12px;
        color: #606266;
        margin-top: 8px;
    }
    `);

    // ================== HTML 部分(保持不变) ==================
    const dialogStyle = `
    <div id="floating-window" class="el-dialog" style="width: 600px; max-width: 90%; min-height: 350px;">
        <div class="el-dialog__header">
            <span class="el-dialog__title">
                <i class="el-icon-lightning" style="color: #ffd700;"></i> 智慧树小助手
            </span>
            <span id="collapse-btn"><i class="el-icon-circle-minus"></i></span>
            <button type="button" class="el-dialog__headerbtn"><i class="el-icon-close"></i></button>
        </div>

        <div class="nav-bar">
            <button class="nav-btn active" data-page="log-page">首页</button>
            <button class="nav-btn" data-page="qa-page">答题</button>
            <button class="nav-btn" data-page="api-page">API</button>
            <button class="nav-btn" data-page="qr-page">联系我</button>
        </div>

        <div class="page active" id="log-page">
            <div class="el-card">
                <div class="el-card__header"><i class="el-icon-document"></i> 操作日志</div>
                <div class="el-card__body"><div id="log-container"></div></div>
            </div>
        </div>

        <div class="page" id="qa-page">
            <div class="el-card">
                <div class="el-card__header"><i class="el-icon-document"></i> 答题记录</div>
                <div class="el-card__body">
                    <div class="el-table__body-wrapper">
                        <table id="record-table" class="el-table__body">
                            <thead>
                                <tr class="el-table__header">
                                    <th><div class="cell">序号</div></th>
                                    <th><div class="cell">题目</div></th>
                                    <th><div class="cell">答案</div></th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>

        <div class="page" id="api-page">
            <div class="el-card">
                <div class="el-card__header"><i class="el-icon-key"></i> API设置</div>
                <div class="el-card__body">
                    <div class="el-input el-input--medium">
                        <input id="api-key-input" type="text" placeholder="请输入API Key" class="el-input__inner" value="${config.apiKey}">
                    </div>
                    <div style="margin-top: 8px;">
                        <button id="save-api-key-btn" class="el-button el-button--primary el-button--medium"><i class="el-icon-check"></i> 保存</button>
                        <button id="clear-api-key-btn" class="el-button el-button--danger el-button--medium" style="margin-left:10px"><i class="el-icon-delete"></i> 清除</button>
                    </div>
                </div>
            </div>
        </div>

        <div class="page" id="qr-page">
            <div class="el-card qr-code-container">
                <div class="el-card__header"><i class="el-icon-mobile-phone"></i> 扫码联系我更新题库</div>
                <div class="el-card__body">
                    <img src="https://www.fengtingwanli.cn/wp-content/uploads/2024/10/1730359368-4bbfc02656cc0da1a6b2d0481a89ff7.jpg" alt="联系我">
                    <p>联系我更新题库</p>
                </div>
            </div>
        </div>
    </div>
    `;

    document.body.insertAdjacentHTML('beforeend', dialogStyle);

    // 可拖拽缩放
    makeElementResizableDraggable(document.getElementById('floating-window'));

    // 导航栏切换
    document.querySelectorAll('.nav-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            document.querySelectorAll('.nav-btn').forEach(b => b.classList.remove('active'));
            document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
            btn.classList.add('active');
            document.getElementById(btn.dataset.page).classList.add('active');
        });
    });

    // 折叠、关闭、API事件
    document.querySelector('.el-dialog__headerbtn').addEventListener('click', () => document.getElementById('floating-window').style.display='none');
    document.getElementById('collapse-btn').addEventListener('click', toggleCollapse);
    document.getElementById('save-api-key-btn').addEventListener('click', saveApiKey);
    document.getElementById('clear-api-key-btn').addEventListener('click', clearApiKey);

    // 启动日志
    logMessage('智慧树小助手已启动', 'info');

    await sleep(config.awaitTime);

    const questionBodyAll = document.querySelectorAll(".examPaper_subject.mt20");
    if (questionBodyAll.length === 0) {
        logMessage('未检测到题目', 'warning');
        return;
    }

    config.questionCount = questionBodyAll.length;
    logMessage(`共检测到 ${config.questionCount} 道题目`, 'info');

    answerQuestion(questionBodyAll[0], 1);
    let finishCount = 1;
    const interval = setInterval(() => {
        if (finishCount < questionBodyAll.length) {
            answerQuestion(questionBodyAll[finishCount], finishCount + 1);
            finishCount += 1;
        } else {
            clearInterval(interval);
            logMessage("所有题目已处理完成!", 'success');
        }
    }, 3000);
}))();