Greasy Fork

Greasy Fork is available in English.

问卷星自动答题脚本

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

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