Greasy Fork

来自缓存

Greasy Fork is available in English.

问卷星自动答题脚本

自动采集问卷星题目并设置答案,支持固定答案和问题高亮

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         问卷星自动答题脚本
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  自动采集问卷星题目并设置答案,支持固定答案和问题高亮
// @license MIT
// @author       ruby
// @match        https://www.wjx.cn/vm/*
// @match        https://www.wjx.cn/wjx/join/complete.aspx*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 问题类型枚举
    const QuestionType = {
        RADIO: 'radio',           // 单选题
        CHECKBOX: 'checkbox',     // 多选题
        SCALE: 'scale',          // 量表题
        TEXT: 'text',            // 文本题
    };

    // 存储所有题目信息的数组
    let questions = [];

    // 全局变量存储固定答案
    let fixedAnswers = {};

    // 当前选中的问题编号
    let selectedQuestionNumber = null;

    // CSS样式
    const css = `
        .wjx-panel {
            position: fixed;
            top: 20px;
            right: 20px;
            background: white;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 8px;
            z-index: 9999;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            width: 320px;
            max-height: 90vh;
            overflow-y: auto;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            transition: all 0.3s ease;
        }

        .wjx-panel-title {
            margin: 0 0 15px 0;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
            font-size: 18px;
            font-weight: 600;
            color: #333;
        }

        .wjx-btn-group {
            display: flex;
            gap: 8px;
            margin-bottom: 15px;
        }

        .wjx-btn {
            flex: 1;
            padding: 8px 12px;
            border: none;
            border-radius: 4px;
            background-color: #4a6ee0;
            color: white;
            font-size: 14px;
            font-weight: 500;
            cursor: pointer;
            transition: background-color 0.2s;
        }

        .wjx-btn:hover {
            background-color: #3a5cc9;
        }

        .wjx-btn-secondary {
            background-color: #e6e6e6;
            color: #333;
        }

        .wjx-btn-secondary:hover {
            background-color: #d9d9d9;
        }

        .wjx-btn-danger {
            background-color: #e74c3c;
        }

        .wjx-btn-danger:hover {
            background-color: #c0392b;
        }

        .wjx-btn-success {
            background-color: #2ecc71;
        }

        .wjx-btn-success:hover {
            background-color: #27ae60;
        }

        .wjx-fixed-section {
            margin-bottom: 20px;
            padding: 12px;
            background-color: #f5f7fa;
            border-radius: 6px;
        }

        .wjx-fixed-title {
            margin: 0 0 10px 0;
            font-size: 16px;
            font-weight: 600;
            color: #444;
        }

        .wjx-fixed-table {
            width: 100%;
            border-collapse: collapse;
        }

        .wjx-fixed-table th {
            padding: 6px;
            border-bottom: 1px solid #ddd;
            text-align: left;
            font-weight: 600;
            color: #555;
        }

        .wjx-fixed-table td {
            padding: 6px;
            border-bottom: 1px solid #eee;
            font-size: 13px;
        }

        .wjx-form {
            max-height: 500px;
            overflow-y: auto;
            margin-top: 15px;
            padding: 5px;
            border: 1px solid #eee;
            border-radius: 6px;
        }

        .wjx-question {
            margin-bottom: 15px;
            padding: 10px;
            background-color: #f9f9f9;
            border-radius: 6px;
            transition: all 0.2s ease;
        }

        .wjx-question:hover {
            background-color: #f0f0f0;
        }

        .wjx-question.selected {
            background-color: #e6f7ff;
            border-left: 4px solid #1890ff;
        }

        .wjx-question-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 8px;
        }

        .wjx-question-title {
            font-weight: 500;
            color: #333;
        }

        .wjx-question-fixed {
            background-color: #2ecc71;
            color: white;
            border: none;
            border-radius: 4px;
            padding: 3px 8px;
            font-size: 12px;
            cursor: pointer;
        }

        .wjx-question-fixed:not(.active) {
            background-color: #3498db;
        }

        .wjx-question-fixed:hover {
            opacity: 0.9;
        }

        .wjx-option {
            display: block;
            margin-bottom: 5px;
            padding: 4px;
            border-radius: 4px;
        }

        .wjx-option:hover {
            background-color: #f0f0f0;
        }

        .wjx-option.selected {
            background-color: #e3f2fd;
            border: 1px solid #bbdefb;
        }

        .wjx-scale-container {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            margin-top: 8px;
        }

        .wjx-textarea {
            width: 100%;
            height: 60px;
            margin-top: 8px;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-family: inherit;
            resize: vertical;
        }

        .wjx-textarea:focus {
            border-color: #4a6ee0;
            outline: none;
            box-shadow: 0 0 0 2px rgba(74, 110, 224, 0.2);
        }

        .wjx-message {
            padding: 10px;
            color: #856404;
            background-color: #fff3cd;
            border-radius: 4px;
            margin-bottom: 10px;
            text-align: center;
        }

        .wjx-empty {
            font-style: italic;
            color: #999;
            text-align: center;
            padding: 10px;
        }

        .wjx-badge {
            display: inline-block;
            min-width: 20px;
            height: 20px;
            padding: 0 6px;
            font-size: 12px;
            line-height: 20px;
            color: #fff;
            text-align: center;
            white-space: nowrap;
            vertical-align: middle;
            background-color: #777;
            border-radius: 10px;
            margin-right: 5px;
        }

        .wjx-badge-radio {
            background-color: #3498db;
        }

        .wjx-badge-checkbox {
            background-color: #9b59b6;
        }

        .wjx-badge-scale {
            background-color: #f39c12;
        }

        .wjx-badge-text {
            background-color: #1abc9c;
        }

        @keyframes highlight {
            0% { background-color: #fff; }
            50% { background-color: #e6f7ff; }
            100% { background-color: #fff; }
        }

        .highlight-question {
            animation: highlight 1.5s ease;
        }
    `;

    // 添加样式到页面
    function addStyles() {
        const styleElement = document.createElement('style');
        styleElement.textContent = css;
        document.head.appendChild(styleElement);
    }

    // 采集题目信息
    function collectQuestions() {
        // 获取所有题目元素
        const questionElements = document.querySelectorAll('.field');
        questions = []; // 清空之前的题目

        questionElements.forEach((element, index) => {
            const questionTitle = element.querySelector('.field-label')?.textContent.trim();
            const questionNumber = index + 1;
            const questionId = element.getAttribute('topic') || element.id.replace('div', '');
            let type = QuestionType.RADIO; // 默认为单选题

            // 确定题目类型
            if (element.querySelector('input[type="checkbox"]') || element.querySelectorAll('.ui-checkbox').length > 0) {
                type = QuestionType.CHECKBOX;
            } else if (element.querySelector('.scale-div') || element.querySelector('.scale-rating')) {
                type = QuestionType.SCALE;
            } else if (element.querySelector('textarea') || element.querySelector('input[type="text"]')) {
                type = QuestionType.TEXT;
            }

            // 获取选项
            let options = [];

            if (type === QuestionType.RADIO) {
                // 单选题选项
                const optionElements = element.querySelectorAll('.ui-radio');
                optionElements.forEach((opt, optIndex) => {
                    const input = opt.querySelector('input[type="radio"]');
                    const optionText = opt.querySelector('.label')?.textContent.trim();
                    const optionValue = input?.value || (optIndex + 1).toString();
                    options.push({
                        index: optIndex + 1,
                        value: optionValue,
                        text: optionText,
                        element: opt
                    });
                });
            } else if (type === QuestionType.CHECKBOX) {
                // 多选题选项
                const optionElements = element.querySelectorAll('.ui-checkbox');
                optionElements.forEach((opt, optIndex) => {
                    const input = opt.querySelector('input[type="checkbox"]');
                    const optionText = opt.querySelector('.label')?.textContent.trim();
                    const optionValue = input?.value || (optIndex + 1).toString();
                    options.push({
                        index: optIndex + 1,
                        value: optionValue,
                        text: optionText,
                        element: opt
                    });
                });
            } else if (type === QuestionType.SCALE) {
                // 量表题选项
                const optionElements = element.querySelectorAll('.scale-rating .onscore li');
                optionElements.forEach((opt, optIndex) => {
                    const anchor = opt.querySelector('a');
                    const optionValue = anchor?.getAttribute('val') || (optIndex + 1).toString();
                    const optionText = anchor?.getAttribute('title') || optionValue;
                    options.push({
                        index: optIndex + 1,
                        value: optionValue,
                        text: optionText,
                        element: anchor
                    });
                });
            }

            questions.push({
                number: questionNumber,
                id: questionId,
                title: questionTitle,
                type: type,
                options: options,
                element: element
            });
        });

        console.log('采集到的题目:', questions);
        return questions;
    }

    // 设置答案
    function setAnswer(questionNumber, answer) {
        const question = questions.find(q => q.number === questionNumber);
        if (!question) {
            console.error(`未找到题号 ${questionNumber} 的题目`);
            return false;
        }

        switch (question.type) {
            case QuestionType.RADIO:
                // 单选题设置答案
                const radioOption = question.options.find(opt => opt.value === answer);
                if (radioOption && radioOption.element) {
                    // 点击jqradio元素
                    const jqradio = radioOption.element.querySelector('.jqradio');
                    if (jqradio) {
                        jqradio.click();
                        return true;
                    }
                }
                break;

            case QuestionType.CHECKBOX:
                // 多选题设置答案(answer应该是数组)
                if (Array.isArray(answer)) {
                    // 先清除所有已选中的选项
                    question.options.forEach(option => {
                        const jqcheck = option.element.querySelector('.jqcheck');
                        if (jqcheck && option.element.querySelector('input[type="checkbox"]').checked) {
                            jqcheck.click();
                        }
                    });

                    // 然后设置新的选中项
                    answer.forEach(value => {
                        const checkboxOption = question.options.find(opt => opt.value === value);
                        if (checkboxOption && checkboxOption.element) {
                            const jqcheck = checkboxOption.element.querySelector('.jqcheck');
                            if (jqcheck) {
                                jqcheck.click();
                            }
                        }
                    });
                    return true;
                }
                break;

            case QuestionType.SCALE:
                // 量表题设置答案
                const scaleOption = question.options.find(opt => opt.value === answer);
                if (scaleOption && scaleOption.element) {
                    scaleOption.element.click();
                    return true;
                }
                break;

            case QuestionType.TEXT:
                // 文本题设置答案
                const textarea = question.element.querySelector('textarea');
                if (textarea) {
                    textarea.value = answer;
                    // 触发change事件
                    const event = new Event('change', { bubbles: true });
                    textarea.dispatchEvent(event);
                    return true;
                }

                // 处理input[type="text"]
                const textInput = question.element.querySelector('input[type="text"]');
                if (textInput) {
                    textInput.value = answer;
                    // 触发change和input事件
                    const changeEvent = new Event('change', { bubbles: true });
                    const inputEvent = new Event('input', { bubbles: true });
                    textInput.dispatchEvent(changeEvent);
                    textInput.dispatchEvent(inputEvent);

                    if (typeof setTip === 'function') {
                        // 如果存在setTip函数,也触发它
                        try {
                            setTip(textInput);
                        } catch (e) {
                            console.error('调用setTip函数失败:', e);
                        }
                    }

                    return true;
                }
                break;
        }

        console.error(`设置题号 ${questionNumber} 的答案失败`);
        return false;
    }

    // 批量设置答案
    function batchSetAnswers(answerMap) {
        let successCount = 0;

        // 按照题目顺序设置答案
        questions.forEach(question => {
            const answer = answerMap[question.number];
            if (answer !== undefined) {
                if (setAnswer(question.number, answer)) {
                    successCount++;
                }
            }
        });

        return successCount;
    }

    // 保存答案设置到本地存储
    function saveAnswerSettings(answerMap) {
        const surveyId = getSurveyId();
        if (surveyId) {
            localStorage.setItem(`wjxAnswers_${surveyId}`, JSON.stringify(answerMap));
            return true;
        }
        return false;
    }

    // 从本地存储加载答案设置
    function loadAnswerSettings() {
        const surveyId = getSurveyId();
        if (surveyId) {
            const savedData = localStorage.getItem(`wjxAnswers_${surveyId}`);
            if (savedData) {
                try {
                    return JSON.parse(savedData);
                } catch (e) {
                    console.error('加载已保存答案失败:', e);
                }
            }
        }
        return {};
    }

    // 保存固定答案
    function saveFixedAnswers() {
        const surveyId = getSurveyId();
        if (surveyId) {
            localStorage.setItem(`wjxFixedAnswers_${surveyId}`, JSON.stringify(fixedAnswers));
            return true;
        }
        return false;
    }

    // 加载固定答案
    function loadFixedAnswers() {
        const surveyId = getSurveyId();
        if (surveyId) {
            const savedData = localStorage.getItem(`wjxFixedAnswers_${surveyId}`);
            if (savedData) {
                try {
                    fixedAnswers = JSON.parse(savedData);
                    return fixedAnswers;
                } catch (e) {
                    console.error('加载固定答案失败:', e);
                }
            }
        }
        fixedAnswers = {};
        return fixedAnswers;
    }

    // 清除固定答案
    function clearFixedAnswers() {
        const surveyId = getSurveyId();
        if (surveyId) {
            localStorage.removeItem(`wjxFixedAnswers_${surveyId}`);
        }
        fixedAnswers = {};
    }

    // 设置固定答案
    function setFixedAnswer(questionNumber, answer) {
        // 确保多选题答案是数组格式
        if (Array.isArray(answer)) {
            // 深拷贝数组,避免引用问题
            fixedAnswers[questionNumber] = [...answer];
        } else {
            fixedAnswers[questionNumber] = answer;
        }
        console.log(`设置固定答案: 第${questionNumber}题, 答案:`, fixedAnswers[questionNumber]);
        saveFixedAnswers();
    }

    // 移除某题的固定答案
    function removeFixedAnswer(questionNumber) {
        delete fixedAnswers[questionNumber];
        saveFixedAnswers();
    }

    // 应用固定答案
    function applyFixedAnswers(answerMap) {
        // 将固定答案合并到随机答案中,固定答案优先级更高
        for (const [questionNumber, answer] of Object.entries(fixedAnswers)) {
            const qNum = parseInt(questionNumber);
            if (!isNaN(qNum)) {
                // 确保多选题答案是数组格式
                if (Array.isArray(answer)) {
                    answerMap[qNum] = [...answer]; // 深拷贝数组
                } else {
                    answerMap[qNum] = answer;
                }
                console.log(`应用固定答案: 第${qNum}题, 答案:`, answerMap[qNum]);
            }
        }
        return answerMap;
    }

    // 获取问卷ID
    function getSurveyId() {
        const match = location.href.match(/vm\/([A-Za-z0-9]+)/);
        return match ? match[1] : '';
    }

    // 创建答案设置界面
    function createAnswerSettingsUI(containerElement) {
        containerElement.innerHTML = ''; // 清空容器

        if (questions.length === 0) {
            const message = document.createElement('div');
            message.className = 'wjx-message';
            message.textContent = '请先点击"采集题目"按钮';
            containerElement.appendChild(message);
            return;
        }

        // 加载固定答案
        loadFixedAnswers();

        // 创建固定答案管理区域
        const fixedAnswerSection = document.createElement('div');
        fixedAnswerSection.className = 'wjx-fixed-section';

        const fixedTitle = document.createElement('h4');
        fixedTitle.className = 'wjx-fixed-title';
        fixedTitle.textContent = '固定答案设置';
        fixedAnswerSection.appendChild(fixedTitle);

        // 显示当前已设置的固定答案
        const fixedAnswerList = document.createElement('div');
        fixedAnswerList.id = 'fixedAnswerList';

        if (Object.keys(fixedAnswers).length === 0) {
            const noFixed = document.createElement('p');
            noFixed.className = 'wjx-empty';
            noFixed.textContent = '当前没有设置固定答案';
            fixedAnswerList.appendChild(noFixed);
        } else {
            const fixedTable = document.createElement('table');
            fixedTable.className = 'wjx-fixed-table';

            // 表头
            const thead = document.createElement('thead');
            const headerRow = document.createElement('tr');
            ['题号', '设置值', '操作'].forEach(text => {
                const th = document.createElement('th');
                th.textContent = text;
                headerRow.appendChild(th);
            });
            thead.appendChild(headerRow);
            fixedTable.appendChild(thead);

            // 表体
            const tbody = document.createElement('tbody');
            Object.entries(fixedAnswers).forEach(([qNum, answer]) => {
                const question = questions.find(q => q.number === parseInt(qNum));
                if (!question) return;

                const row = document.createElement('tr');
                row.dataset.questionNumber = qNum;

                // 点击行高亮对应的问题
                row.style.cursor = 'pointer';
                row.addEventListener('click', (e) => {
                    // 如果点击的是删除按钮,则不触发高亮
                    if (e.target.tagName === 'BUTTON') return;

                    selectQuestion(parseInt(qNum));
                });

                // 题号列
                const numCell = document.createElement('td');
                numCell.textContent = qNum;
                row.appendChild(numCell);

                // 设置值列
                const valueCell = document.createElement('td');

                // 根据题目类型显示不同的答案格式
                switch (question.type) {
                    case QuestionType.RADIO:
                    case QuestionType.SCALE:
                        const option = question.options.find(opt => opt.value === answer);
                        valueCell.textContent = option ? option.text : answer;
                        break;

                    case QuestionType.CHECKBOX:
                        if (Array.isArray(answer)) {
                            const optionTexts = answer.map(val => {
                                const opt = question.options.find(o => o.value === val);
                                return opt ? opt.text : val;
                            });
                            valueCell.textContent = optionTexts.join(', ');
                        } else {
                            valueCell.textContent = answer;
                        }
                        break;

                    case QuestionType.TEXT:
                        valueCell.textContent = answer;
                        break;
                }

                row.appendChild(valueCell);

                // 操作列
                const actionsCell = document.createElement('td');

                const removeBtn = document.createElement('button');
                removeBtn.textContent = '删除';
                removeBtn.className = 'wjx-btn wjx-btn-danger';
                removeBtn.style.padding = '2px 5px';
                removeBtn.style.fontSize = '12px';

                removeBtn.onclick = () => {
                    removeFixedAnswer(qNum);
                    createAnswerSettingsUI(containerElement); // 刷新UI
                };

                actionsCell.appendChild(removeBtn);
                row.appendChild(actionsCell);

                tbody.appendChild(row);
            });

            fixedTable.appendChild(tbody);
            fixedAnswerList.appendChild(fixedTable);
        }

        fixedAnswerSection.appendChild(fixedAnswerList);

        // 清除所有固定答案按钮
        if (Object.keys(fixedAnswers).length > 0) {
            const clearAllBtn = document.createElement('button');
            clearAllBtn.textContent = '清除所有固定答案';
            clearAllBtn.className = 'wjx-btn wjx-btn-danger';
            clearAllBtn.style.marginTop = '10px';

            clearAllBtn.onclick = () => {
                if (confirm('确定要清除所有固定答案吗?')) {
                    clearFixedAnswers();
                    createAnswerSettingsUI(containerElement); // 刷新UI
                }
            };

            fixedAnswerSection.appendChild(clearAllBtn);
        }

        containerElement.appendChild(fixedAnswerSection);

        // 创建答案设置表单
        const form = document.createElement('form');
        form.className = 'wjx-form';

        // 获取最新的答案设置
        const savedAnswers = loadAnswerSettings();

        // 为每个问题创建设置界面
        questions.forEach(question => {
            const questionSection = document.createElement('div');
            questionSection.className = 'wjx-question';
            questionSection.dataset.questionNumber = question.number;

            // 如果是当前选中的问题,添加选中样式
            if (selectedQuestionNumber === question.number) {
                questionSection.classList.add('selected');
            }

            // 点击问题区域时选中该问题
            questionSection.addEventListener('click', () => {
                selectQuestion(question.number);
            });

            // 问题标题行
            const titleRow = document.createElement('div');
            titleRow.className = 'wjx-question-header';

            // 问题类型徽章和标题
            const titleElement = document.createElement('div');
            titleElement.className = 'wjx-question-title';

            // 添加题目类型徽章
            const badge = document.createElement('span');
            badge.className = `wjx-badge wjx-badge-${question.type}`;

            switch(question.type) {
                case QuestionType.RADIO:
                    badge.textContent = '单选';
                    break;
                case QuestionType.CHECKBOX:
                    badge.textContent = '多选';
                    break;
                case QuestionType.SCALE:
                    badge.textContent = '量表';
                    break;
                case QuestionType.TEXT:
                    badge.textContent = '文本';
                    break;
            }

            titleElement.appendChild(badge);
            titleElement.appendChild(document.createTextNode(`${question.number}. ${question.title}`));
            titleRow.appendChild(titleElement);

            // 固定答案按钮
            const fixBtn = document.createElement('button');
            fixBtn.textContent = fixedAnswers[question.number] ? '已固定' : '固定答案';
            fixBtn.className = 'wjx-question-fixed';
            if (fixedAnswers[question.number]) {
                fixBtn.classList.add('active');
            }

            fixBtn.onclick = (e) => {
                e.preventDefault(); // 防止表单提交
                e.stopPropagation(); // 阻止事件冒泡,避免触发问题选择

                if (fixedAnswers[question.number]) {
                    // 如果已经有固定答案,则删除
                    removeFixedAnswer(question.number);
                    createAnswerSettingsUI(containerElement); // 刷新UI
                } else {
                    // 获取当前设置的答案
                    let currentAnswer;

                    switch (question.type) {
                        case QuestionType.RADIO:
                        case QuestionType.SCALE:
                            const radioInput = questionSection.querySelector(`input[type="radio"][name="q_${question.number}"]:checked`);
                            if (radioInput) {
                                currentAnswer = radioInput.value;
                            }
                            break;

                        case QuestionType.CHECKBOX:
                            const checkboxInputs = questionSection.querySelectorAll(`input[type="checkbox"][name="q_${question.number}"]:checked`);
                            if (checkboxInputs.length > 0) {
                                currentAnswer = Array.from(checkboxInputs).map(input => input.value);
                            }
                            break;

                        case QuestionType.TEXT:
                            const textarea = questionSection.querySelector(`textarea[name="q_${question.number}"]`);
                            if (textarea && textarea.value.trim()) {
                                currentAnswer = textarea.value.trim();
                            }
                            break;
                    }

                    if (currentAnswer) {
                        setFixedAnswer(question.number, currentAnswer);
                        createAnswerSettingsUI(containerElement); // 刷新UI
                    } else {
                        alert('请先设置答案再固定');
                    }
                }
            };

            titleRow.appendChild(fixBtn);
            questionSection.appendChild(titleRow);

            // 根据问题类型创建不同的输入控件
            let inputElement;
            // 优先使用固定答案,其次使用保存的答案
            const answerToUse = fixedAnswers[question.number] !== undefined ?
                                fixedAnswers[question.number] :
                                savedAnswers[question.number];

            switch (question.type) {
                case QuestionType.RADIO:
                    // 单选题
                    question.options.forEach(option => {
                        const radioLabel = document.createElement('label');
                        radioLabel.className = 'wjx-option';

                        // 检查是否选中
                        if (answerToUse === option.value) {
                            radioLabel.classList.add('selected');
                        }

                        const radioInput = document.createElement('input');
                        radioInput.type = 'radio';
                        radioInput.name = `q_${question.number}`;
                        radioInput.value = option.value;
                        radioInput.dataset.questionNumber = question.number;
                        radioInput.checked = answerToUse === option.value;

                        // 点击时阻止事件冒泡,避免触发问题选择
                        radioInput.addEventListener('click', (e) => {
                            e.stopPropagation();

                            // 更新选中状态高亮
                            questionSection.querySelectorAll('.wjx-option').forEach(opt => {
                                opt.classList.remove('selected');
                            });
                            radioLabel.classList.add('selected');

                            // 实时更新答案
                            const currentAnswers = getAnswersFromUI();
                            saveAnswerSettings(currentAnswers);
                        });

                        radioLabel.appendChild(radioInput);
                        radioLabel.appendChild(document.createTextNode(' ' + option.text));
                        questionSection.appendChild(radioLabel);
                    });
                    break;

                case QuestionType.CHECKBOX:
                    // 多选题
                    question.options.forEach(option => {
                        const checkboxLabel = document.createElement('label');
                        checkboxLabel.className = 'wjx-option';

                        const checkboxInput = document.createElement('input');
                        checkboxInput.type = 'checkbox';
                        checkboxInput.name = `q_${question.number}`;
                        checkboxInput.value = option.value;
                        checkboxInput.dataset.questionNumber = question.number;

                        // 检查是否之前已选中
                        let isChecked = false;
                        if (answerToUse && Array.isArray(answerToUse)) {
                            isChecked = answerToUse.includes(option.value);
                            checkboxInput.checked = isChecked;

                            // 已选中选项添加高亮
                            if (isChecked) {
                                checkboxLabel.classList.add('selected');
                            }
                        }

                        // 点击时阻止事件冒泡,避免触发问题选择
                        checkboxInput.addEventListener('click', (e) => {
                            e.stopPropagation();

                            // 更新这个选项的高亮状态
                            if (checkboxInput.checked) {
                                checkboxLabel.classList.add('selected');
                            } else {
                                checkboxLabel.classList.remove('selected');
                            }

                            // 实时更新答案
                            const currentAnswers = getAnswersFromUI();
                            saveAnswerSettings(currentAnswers);
                        });

                        checkboxLabel.appendChild(checkboxInput);
                        checkboxLabel.appendChild(document.createTextNode(' ' + option.text));
                        questionSection.appendChild(checkboxLabel);
                    });
                    break;

                case QuestionType.SCALE:
                    // 量表题
                    const scaleContainer = document.createElement('div');
                    scaleContainer.className = 'wjx-scale-container';

                    question.options.forEach(option => {
                        const radioLabel = document.createElement('label');
                        radioLabel.className = 'wjx-option';
                        radioLabel.style.marginRight = '5px';

                        // 检查是否选中
                        if (answerToUse === option.value) {
                            radioLabel.classList.add('selected');
                        }

                        const radioInput = document.createElement('input');
                        radioInput.type = 'radio';
                        radioInput.name = `q_${question.number}`;
                        radioInput.value = option.value;
                        radioInput.dataset.questionNumber = question.number;
                        radioInput.checked = answerToUse === option.value;

                        // 点击时阻止事件冒泡,避免触发问题选择
                        radioInput.addEventListener('click', (e) => {
                            e.stopPropagation();

                            // 更新选中状态高亮
                            scaleContainer.querySelectorAll('.wjx-option').forEach(opt => {
                                opt.classList.remove('selected');
                            });
                            radioLabel.classList.add('selected');

                            // 实时更新答案
                            const currentAnswers = getAnswersFromUI();
                            saveAnswerSettings(currentAnswers);
                        });

                        radioLabel.appendChild(radioInput);
                        radioLabel.appendChild(document.createTextNode(' ' + option.text));
                        scaleContainer.appendChild(radioLabel);
                    });

                    questionSection.appendChild(scaleContainer);
                    break;

                case QuestionType.TEXT:
                    // 文本题
                    const textarea = document.createElement('textarea');
                    textarea.className = 'wjx-textarea';
                    textarea.name = `q_${question.number}`;
                    textarea.dataset.questionNumber = question.number;
                    textarea.value = answerToUse || '';

                    // 点击时阻止事件冒泡,避免触发问题选择
                    textarea.addEventListener('click', (e) => {
                        e.stopPropagation();
                    });

                    // 添加输入事件,实时更新答案
                    textarea.addEventListener('input', (e) => {
                        // 延迟更新,避免频繁保存
                        clearTimeout(textarea.saveTimeout);
                        textarea.saveTimeout = setTimeout(() => {
                            const currentAnswers = getAnswersFromUI();
                            saveAnswerSettings(currentAnswers);
                        }, 500);
                    });

                    questionSection.appendChild(textarea);
                    break;
            }

            form.appendChild(questionSection);
        });

        containerElement.appendChild(form);
    }

    // 选中问题并高亮显示
    function selectQuestion(questionNumber) {
        // 保存当前选中的问题编号
        selectedQuestionNumber = questionNumber;

        // 移除所有问题的选中状态
        document.querySelectorAll('.wjx-question').forEach(el => {
            el.classList.remove('selected');
        });

        // 为选中的问题添加选中样式
        const questionElement = document.querySelector(`.wjx-question[data-question-number="${questionNumber}"]`);
        if (questionElement) {
            questionElement.classList.add('selected');

            // 滚动到选中的问题
            questionElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }

        // 高亮页面中的问题
        highlightQuestionInPage(questionNumber);
    }

    // 在页面中高亮显示选中的问题
    function highlightQuestionInPage(questionNumber) {
        const question = questions.find(q => q.number === questionNumber);
        if (question && question.element) {
            // 移除之前的高亮
            document.querySelectorAll('.highlight-question').forEach(el => {
                el.classList.remove('highlight-question');
            });

            // 添加高亮动画
            question.element.classList.add('highlight-question');

            // 滚动到页面中的问题位置
            question.element.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
    }

    // 从设置界面获取答案
    function getAnswersFromUI() {
        const answerMap = {};

        // 处理单选题和量表题
        const radioInputs = document.querySelectorAll('input[type="radio"]:checked');
        radioInputs.forEach(input => {
            const qNum = parseInt(input.dataset.questionNumber);
            if (!isNaN(qNum)) {
                answerMap[qNum] = input.value;
            }
        });

        // 处理多选题
        const checkboxGroups = {};
        const checkboxInputs = document.querySelectorAll('input[type="checkbox"]:checked');
        checkboxInputs.forEach(input => {
            const qNum = parseInt(input.dataset.questionNumber);
            if (!isNaN(qNum)) {
                if (!checkboxGroups[qNum]) {
                    checkboxGroups[qNum] = [];
                }
                checkboxGroups[qNum].push(input.value);
            }
        });

        // 将多选题答案合并到答案映射
        Object.entries(checkboxGroups).forEach(([qNum, values]) => {
            answerMap[qNum] = values;
        });

        // 处理文本题
        const textareas = document.querySelectorAll('textarea[data-question-number]');
        textareas.forEach(textarea => {
            const qNum = parseInt(textarea.dataset.questionNumber);
            if (!isNaN(qNum) && textarea.value.trim()) {
                answerMap[qNum] = textarea.value.trim();
            }
        });

        return answerMap;
    }

    // 添加控制面板
    function addControlPanel() {
        const panel = document.createElement('div');
        panel.className = 'wjx-panel';

        const title = document.createElement('h3');
        title.className = 'wjx-panel-title';
        title.textContent = '问卷自动答题控制面板';
        panel.appendChild(title);

        // 顶部按钮组
        const buttonGroup = document.createElement('div');
        buttonGroup.className = 'wjx-btn-group';

        // 采集题目按钮
        const collectButton = document.createElement('button');
        collectButton.className = 'wjx-btn';
        collectButton.textContent = '采集题目';
        collectButton.onclick = () => {
            collectQuestions();
            createAnswerSettingsUI(settingsContainer);
            alert(`成功采集 ${questions.length} 道题目!`);
        };
        buttonGroup.appendChild(collectButton);

        // 应用答案按钮
        const applyButton = document.createElement('button');
        applyButton.className = 'wjx-btn';
        applyButton.textContent = '应用答案';
        applyButton.onclick = () => {
            const answers = getAnswersFromUI();
            const count = batchSetAnswers(answers);
            saveAnswerSettings(answers);
            alert(`成功应用 ${count} 个答案!`);
        };
        buttonGroup.appendChild(applyButton);

        // 随机答案按钮
        const randomButton = document.createElement('button');
        randomButton.className = 'wjx-btn';
        randomButton.textContent = '随机答案';
        randomButton.onclick = () => {
            if (questions.length === 0) {
                alert('请先点击"采集题目"按钮!');
                return;
            }

            // 生成随机答案,并应用固定答案
            const randomAnswers = generateRandomAnswers();
            const finalAnswers = applyFixedAnswers(randomAnswers);

            const count = batchSetAnswers(finalAnswers);
            saveAnswerSettings(finalAnswers);
            createAnswerSettingsUI(settingsContainer); // 更新UI
            alert(`成功应用 ${count} 个答案!`);
        };
        buttonGroup.appendChild(randomButton);

        panel.appendChild(buttonGroup);

        // 添加刷新界面按钮
        const refreshButton = document.createElement('button');
        refreshButton.className = 'wjx-btn wjx-btn-secondary';
        refreshButton.textContent = '刷新控制面板';
        refreshButton.style.width = '100%';
        refreshButton.style.marginBottom = '10px';
        refreshButton.onclick = () => {
            createAnswerSettingsUI(settingsContainer);
        };
        panel.appendChild(refreshButton);

        // 折叠/展开按钮
        const toggleButton = document.createElement('button');
        toggleButton.className = 'wjx-btn wjx-btn-secondary';
        toggleButton.textContent = '折叠面板';
        toggleButton.style.width = '100%';
        toggleButton.onclick = () => {
            if (settingsContainer.style.display === 'none') {
                settingsContainer.style.display = 'block';
                toggleButton.textContent = '折叠面板';
                panel.style.width = '320px';
            } else {
                settingsContainer.style.display = 'none';
                toggleButton.textContent = '展开面板';
                panel.style.width = 'auto';
            }
        };
        panel.appendChild(toggleButton);

        // 答案设置容器
        const settingsContainer = document.createElement('div');
        panel.appendChild(settingsContainer);

        document.body.appendChild(panel);

        // 初始化答案设置界面
        window.setTimeout(() => {
            collectQuestions();
            createAnswerSettingsUI(settingsContainer);
        }, 1000);
    }

    // 生成随机答案
    function generateRandomAnswers() {
        const answerMap = {};

        questions.forEach(question => {
            switch (question.type) {
                case QuestionType.RADIO:
                    if (question.options.length > 0) {
                        // 随机选择一个选项
                        const randomOption = question.options[Math.floor(Math.random() * question.options.length)];
                        answerMap[question.number] = randomOption.value;
                    }
                    break;

                case QuestionType.CHECKBOX:
                    if (question.options.length > 0) {
                        // 修改为随机选择3-4个选项(或全部,如果选项少于3个)
                        const minSelect = Math.min(question.options.length, 3); // 至少3个
                        const maxSelect = Math.min(question.options.length, 4); // 最多4个
                        let selectCount;

                        if (minSelect === maxSelect) {
                            // 如果选项数量少于或等于3,选择所有选项
                            selectCount = minSelect;
                        } else {
                            // 随机选择3或4个选项
                            selectCount = Math.random() < 0.5 ? minSelect : maxSelect;
                        }

                        // 随机洗牌选项
                        const shuffledOptions = [...question.options].sort(() => Math.random() - 0.5);

                        // 选择前selectCount个
                        answerMap[question.number] = shuffledOptions.slice(0, selectCount).map(opt => opt.value);
                    }
                    break;

                case QuestionType.SCALE:
                    if (question.options.length > 0) {
                        // 对于量表题,选择3-5范围内的值(即第3、4、5个选项)
                        let targetValues = [];

                        // 确保量表选项总数至少有3个
                        if (question.options.length >= 3) {
                            // 获取第3、4、5个选项(如果量表只有3或4个选项,则取全部可用选项)
                            const startIdx = Math.min(2, question.options.length - 1); // 第3个选项对应索引2
                            const endIdx = Math.min(4, question.options.length - 1);   // 第5个选项对应索引4

                            for (let i = startIdx; i <= endIdx; i++) {
                                targetValues.push(question.options[i]);
                            }

                            // 从3-5之间随机选择一个
                            const randomOption = targetValues[Math.floor(Math.random() * targetValues.length)];
                            answerMap[question.number] = randomOption.value;
                        } else {
                            // 如果选项不足3个,随机选择一个
                            const randomOption = question.options[Math.floor(Math.random() * question.options.length)];
                            answerMap[question.number] = randomOption.value;
                        }
                    }
                    break;

                case QuestionType.TEXT:
                    // 修改为在所有文本题中填写"无"
                    answerMap[question.number] = "无";
                    break;
            }
        });

        return answerMap;
    }

    // 等待页面加载完成后初始化
    window.addEventListener('load', () => {
        // 添加样式
        addStyles();

        setTimeout(() => {
            addControlPanel();
        }, 1500); // 延迟添加控制面板,确保页面完全加载
    });

    // 将函数暴露到全局作用域,方便在控制台调用
    window.setAnswer = setAnswer;
    window.collectQuestions = collectQuestions;
    window.batchSetAnswers = batchSetAnswers;
    window.selectQuestion = selectQuestion;
})();