去你妈的劳关评教

很喜欢点吗

// ==UserScript==
// @name         去你妈的劳关评教
// @namespace    https://github.com/Cindy-Master
// @version      0.0.3
// @description  很喜欢点吗
// @author       Cindy-Master
// @match        *://culr.mycospxk.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    let isProcessing = false;

    // 默认填空题内容
    const defaultAnswers = {
        answer1: '实践和理论结合',
        answer2: '无',
        answer3: '老师讲的非常好,教学很清晰明了。'
    };

    // 从localStorage获取保存的答案
    function getSavedAnswers() {
        const saved = localStorage.getItem('teachingEvaluationAnswers');
        if (saved) {
            try {
                return JSON.parse(saved);
            } catch (e) {
                console.log('解析保存的答案失败:', e);
            }
        }
        return defaultAnswers;
    }

    // 保存答案到localStorage
    function saveAnswers(answers) {
        localStorage.setItem('teachingEvaluationAnswers', JSON.stringify(answers));
        console.log('答案已保存:', answers);
    }

    // 创建配置界面
    function createConfigModal() {
        // 创建遮罩层
        const overlay = document.createElement('div');
        overlay.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 10000;
            display: flex;
            justify-content: center;
            align-items: center;
        `;

        // 创建配置窗口
        const modal = document.createElement('div');
        modal.style.cssText = `
            background: white;
            padding: 30px;
            border-radius: 8px;
            width: 500px;
            max-width: 90%;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
        `;

        const savedAnswers = getSavedAnswers();

        modal.innerHTML = `
            <h3 style="margin: 0 0 20px 0; text-align: center; color: #333;">填空题内容设置</h3>

            <div style="margin-bottom: 15px;">
                <label style="display: block; margin-bottom: 5px; font-weight: bold;">第一道填空题内容:</label>
                <input type="text" id="answer1" value="${savedAnswers.answer1}"
                       style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;">
                <div style="font-size: 12px; color: #666; margin-top: 2px;">推荐内容:实践和理论结合</div>
            </div>

            <div style="margin-bottom: 15px;">
                <label style="display: block; margin-bottom: 5px; font-weight: bold;">第二道填空题内容:</label>
                <input type="text" id="answer2" value="${savedAnswers.answer2}"
                       style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box;">
                <div style="font-size: 12px; color: #666; margin-top: 2px;">推荐内容:无</div>
            </div>

            <div style="margin-bottom: 20px;">
                <label style="display: block; margin-bottom: 5px; font-weight: bold;">弹窗评价原因内容:</label>
                <textarea id="answer3" rows="3"
                          style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; resize: vertical;">${savedAnswers.answer3}</textarea>
                <div style="font-size: 12px; color: #666; margin-top: 2px;">推荐内容:老师讲的非常好,教学很清晰明了。</div>
            </div>

            <div style="text-align: center;">
                <button id="saveConfig" style="
                    background: #1890ff;
                    color: white;
                    border: none;
                    padding: 10px 20px;
                    border-radius: 4px;
                    cursor: pointer;
                    margin-right: 10px;
                    font-size: 14px;
                ">保存设置</button>
                <button id="cancelConfig" style="
                    background: #ccc;
                    color: #333;
                    border: none;
                    padding: 10px 20px;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 14px;
                ">取消</button>
            </div>
        `;

        overlay.appendChild(modal);
        document.body.appendChild(overlay);

        // 保存按钮事件
        document.getElementById('saveConfig').addEventListener('click', () => {
            const answers = {
                answer1: document.getElementById('answer1').value.trim() || defaultAnswers.answer1,
                answer2: document.getElementById('answer2').value.trim() || defaultAnswers.answer2,
                answer3: document.getElementById('answer3').value.trim() || defaultAnswers.answer3
            };

            saveAnswers(answers);
            document.body.removeChild(overlay);

            // 显示保存成功提示
            showNotification('设置已保存成功!', 'success');
        });

        // 取消按钮事件
        document.getElementById('cancelConfig').addEventListener('click', () => {
            document.body.removeChild(overlay);
        });

        // 点击遮罩层关闭
        overlay.addEventListener('click', (e) => {
            if (e.target === overlay) {
                document.body.removeChild(overlay);
            }
        });
    }

    // 显示通知
    function showNotification(message, type = 'info') {
        const notification = document.createElement('div');
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 15px 20px;
            border-radius: 4px;
            color: white;
            font-size: 14px;
            z-index: 10001;
            transition: all 0.3s;
            ${type === 'success' ? 'background: #52c41a;' : 'background: #1890ff;'}
        `;
        notification.textContent = message;
        document.body.appendChild(notification);

        setTimeout(() => {
            notification.style.opacity = '0';
            setTimeout(() => {
                if (document.body.contains(notification)) {
                    document.body.removeChild(notification);
                }
            }, 300);
        }, 2000);
    }

    // 等待页面加载完成
    function waitForElements() {
        const radioGroups = document.querySelectorAll('.ant-radio-group');
        const textareas = document.querySelectorAll('textarea.ant-input');

        if (radioGroups.length > 0 || textareas.length > 0) {
            fillForm();
        } else {
            setTimeout(waitForElements, 1000);
        }
    }

    function fillForm() {
        if (isProcessing) return;
        isProcessing = true;

        console.log('开始自动填写表单...');

        // 处理所有单选题
        fillRadioQuestions();

        // 等待一下再处理填空题
        setTimeout(() => {
            fillTextAreas();

            // 再等待一下后自动提交
            setTimeout(() => {
                autoSubmit();
            }, 2000);
        }, 1000);
    }

    function fillRadioQuestions() {
        const radioGroups = document.querySelectorAll('.ant-radio-group');

        radioGroups.forEach((group, index) => {
            const veryMatch = group.querySelector('input[value="1"]'); // 非常符合
            const match = group.querySelector('input[value="2"]'); // 符合

            if (veryMatch && match) {
                const random = Math.random();
                let selectedOption;

                if (random < 0.3) {
                    selectedOption = match; // 符合
                } else {
                    selectedOption = veryMatch; // 非常符合
                }

                selectedOption.click();
                selectedOption.dispatchEvent(new Event('change', { bubbles: true }));

                console.log(`第${index + 1}题已选择: ${random < 0.3 ? '符合' : '非常符合'}`);
            }
        });
    }

    function fillTextAreas() {
        const textareas = document.querySelectorAll('textarea.ant-input');
        const savedAnswers = getSavedAnswers();

        if (textareas.length >= 2) {
            // 第一个填空题:使用自定义内容
            fillTextAreaWithTyping(textareas[0], savedAnswers.answer1, 0);

            // 第二个填空题:使用自定义内容
            setTimeout(() => {
                fillTextAreaWithTyping(textareas[1], savedAnswers.answer2, 1);
            }, 1000);

            console.log('开始填写填空题...');
            console.log('第一道填空题内容:', savedAnswers.answer1);
            console.log('第二道填空题内容:', savedAnswers.answer2);
        }
    }

    // 模拟真实打字过程来触发字数检测
    function fillTextAreaWithTyping(textarea, text, index) {
        console.log(`开始填写第${index + 1}个填空题: "${text}"`);

        // 先清空
        textarea.value = '';
        textarea.focus();

        // 触发清空事件
        triggerAllEvents(textarea);

        // 模拟逐字输入
        let currentIndex = 0;
        const typingInterval = setInterval(() => {
            if (currentIndex < text.length) {
                textarea.value += text[currentIndex];
                currentIndex++;

                // 每输入一个字符就触发事件
                triggerAllEvents(textarea);

                console.log(`第${index + 1}个填空题当前内容: "${textarea.value}"`);
            } else {
                clearInterval(typingInterval);

                // 输入完成后再次触发所有事件
                setTimeout(() => {
                    triggerAllEvents(textarea);
                    textarea.blur();
                    console.log(`第${index + 1}个填空题填写完成: "${textarea.value}"`);

                    // 检查字数显示是否更新
                    setTimeout(() => {
                        checkWordCount(index + 1);
                    }, 500);
                }, 200);
            }
        }, 100); // 每100ms输入一个字符
    }

    // 触发所有可能的事件
    function triggerAllEvents(element) {
        const events = [
            'input', 'change', 'keydown', 'keyup', 'keypress',
            'focus', 'blur', 'paste', 'cut', 'propertychange'
        ];

        events.forEach(eventType => {
            const event = new Event(eventType, {
                bubbles: true,
                cancelable: true
            });
            element.dispatchEvent(event);
        });

        // 特殊的input事件
        const inputEvent = new InputEvent('input', {
            bubbles: true,
            cancelable: true,
            inputType: 'insertText',
            data: element.value
        });
        element.dispatchEvent(inputEvent);

        // React特定的事件
        if (element._valueTracker) {
            element._valueTracker.setValue('');
        }

        // 尝试触发React的onChange
        const reactHandler = element._reactInternalFiber || element._reactInternalInstance;
        if (reactHandler) {
            const onChange = reactHandler.memoizedProps?.onChange;
            if (onChange) {
                onChange({ target: element });
            }
        }
    }

    // 检查字数是否更新
    function checkWordCount(textareaIndex) {
        const countElements = document.querySelectorAll('.index__numCount--pECDw, .index__count_wrap--m1keW');
        console.log(`检查第${textareaIndex}个填空题的字数显示...`);

        countElements.forEach((element, index) => {
            console.log(`字数显示${index + 1}: ${element.textContent}`);
        });
    }

    function autoSubmit() {
        // 使用您提供的精确选择器
        const submitButton = document.querySelector('button.ant-btn.index__submit--jiKIA.ant-btn-primary');

        if (submitButton) {
            console.log('找到提交按钮,准备提交...');
            submitButton.click();

            // 开始监听弹窗
            startModalWatcher();
        } else {
            console.log('未找到提交按钮,尝试其他选择器...');

            // 备用选择器
            const backupButton = document.querySelector('.index__submit--jiKIA') ||
                                document.querySelector('button[class*="submit"]') ||
                                document.querySelector('button:contains("提交")');

            if (backupButton) {
                console.log('使用备用选择器找到提交按钮');
                backupButton.click();
                startModalWatcher();
            } else {
                console.log('完全找不到提交按钮');
            }
        }
    }

    function startModalWatcher() {
        console.log('开始监听弹窗...');

        // 监听DOM变化,检测弹窗出现
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (mutation.type === 'childList') {
                    // 检查是否出现评价原因弹窗
                    const reasonModal = document.querySelector('.ant-modal-content .ant-modal-title');
                    if (reasonModal && reasonModal.textContent.includes('评价原因')) {
                        observer.disconnect(); // 找到后停止监听,避免重复触发
                        handleReasonModal();
                        return;
                    }
                }
            });
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });

        // 15秒后停止监听
        setTimeout(() => {
            observer.disconnect();
            console.log('停止监听弹窗');
        }, 15000);
    }

    function handleReasonModal() {
        console.log('检测到评价原因弹窗');

        setTimeout(() => {
            // 使用更精确的选择器来查找弹窗中的文本框
            let modalTextarea = document.querySelector('.index__reason_modal_content--N1LsY textarea.ant-input');

            // 备用选择器
            if (!modalTextarea) {
                modalTextarea = document.querySelector('.index__root--sPKi7 textarea.ant-input');
            }

            // 再次备用选择器
            if (!modalTextarea) {
                modalTextarea = document.querySelector('.ant-modal-body textarea.ant-input');
            }

            if (modalTextarea) {
                console.log('找到弹窗文本框,开始强制填写评价原因');

                // 使用保存的自定义内容
                const savedAnswers = getSavedAnswers();
                const text = savedAnswers.answer3;
                console.log('弹窗评价原因内容:', text);
                forceInputText(modalTextarea, text);

                // 等待一下后点击确定
                setTimeout(() => {
                    const confirmButton = document.querySelector('.ant-modal-footer .ant-btn-primary');
                    if (confirmButton) {
                        confirmButton.click();
                        console.log('已点击评价原因确定按钮');

                        // 等待7秒后处理最终确认弹窗
                        setTimeout(() => {
                            handleFinalConfirmModal();
                        }, 7000);
                    }
                }, 2000);

            } else {
                console.log('未找到弹窗中的文本框');
            }
        }, 500);
    }

    // 强制输入文本的方法
    function forceInputText(element, text) {
        console.log('开始强制输入文本:', text);

        // 方法1: 直接设置value并触发事件
        element.focus();
        element.value = '';
        triggerAllEvents(element);

        element.value = text;
        triggerAllEvents(element);

        // 方法2: 使用execCommand (如果支持)
        try {
            element.focus();
            element.select();
            document.execCommand('insertText', false, text);
            triggerAllEvents(element);
        } catch(e) {
            console.log('execCommand方法失败:', e);
        }

        // 方法3: 模拟键盘输入
        element.focus();
        element.value = '';

        for (let i = 0; i < text.length; i++) {
            const char = text[i];

            // 模拟keydown事件
            const keydownEvent = new KeyboardEvent('keydown', {
                key: char,
                code: `Key${char.toUpperCase()}`,
                bubbles: true,
                cancelable: true
            });
            element.dispatchEvent(keydownEvent);

            // 设置值
            element.value += char;

            // 模拟input事件
            const inputEvent = new InputEvent('input', {
                bubbles: true,
                cancelable: true,
                inputType: 'insertText',
                data: char
            });
            element.dispatchEvent(inputEvent);

            // 模拟keyup事件
            const keyupEvent = new KeyboardEvent('keyup', {
                key: char,
                code: `Key${char.toUpperCase()}`,
                bubbles: true,
                cancelable: true
            });
            element.dispatchEvent(keyupEvent);
        }

        // 方法4: 强制设置并触发React事件
        const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set;
        nativeInputValueSetter.call(element, text);

        const inputEvent = new Event('input', { bubbles: true });
        element.dispatchEvent(inputEvent);

        // 最后再次触发所有事件
        triggerAllEvents(element);

        console.log('强制输入完成,当前值:', element.value);

        // 检查字数显示
        setTimeout(() => {
            const countElement = document.querySelector('.index__count_wrap--m1keW span:first-child');
            if (countElement) {
                console.log('弹窗字数显示:', countElement.textContent);
            }
        }, 100);
    }

    // 处理最终确认弹窗 - 点击所有确定按钮
    function handleFinalConfirmModal() {
        console.log('等待7秒后,开始处理最终确认弹窗...');

        // 查找当前页面上的所有确定按钮
        const confirmButtons = [
            // 精确选择器
            document.querySelector('.ant-modal-content .ant-btn-primary'),
            // 包含"确定"文本的按钮
            ...Array.from(document.querySelectorAll('button')).filter(btn =>
                btn.textContent.includes('确定') || btn.textContent.includes('确 定')
            ),
            // 通用的primary按钮
            document.querySelector('.ant-btn-primary'),
            // 弹窗中的primary按钮
            document.querySelector('.ant-modal-body ~ div .ant-btn-primary'),
            // 更多备用选择器
            ...Array.from(document.querySelectorAll('.ant-btn-primary')),
            ...Array.from(document.querySelectorAll('button[class*="primary"]')),
            ...Array.from(document.querySelectorAll('.ant-modal .ant-btn'))
        ].filter(Boolean); // 过滤掉null值

        // 去重
        const uniqueButtons = [...new Set(confirmButtons)];

        console.log(`找到 ${uniqueButtons.length} 个可能的确定按钮,准备全部点击`);

        if (uniqueButtons.length > 0) {
            // 依次点击所有按钮,每个按钮间隔500ms
            uniqueButtons.forEach((button, index) => {
                setTimeout(() => {
                    try {
                        // 如果按钮被禁用,先启用它
                        if (button.disabled || button.hasAttribute('disabled')) {
                            console.log(`按钮${index + 1}被禁用,正在启用...`);
                            button.removeAttribute('disabled');
                            button.disabled = false;

                            // 移除倒计时文本
                            const countdownSpan = button.querySelector('span[style*="margin-left"]');
                            if (countdownSpan) {
                                countdownSpan.remove();
                                console.log(`已移除按钮${index + 1}的倒计时文本`);
                            }
                        }

                        // 点击按钮
                        console.log(`点击第${index + 1}个确定按钮:`, button);
                        console.log(`按钮文本: "${button.textContent.trim()}"`);
                        button.click();

                        // 如果是最后一个按钮,等待3秒后查找成功弹窗
                        if (index === uniqueButtons.length - 1) {
                            console.log('所有确定按钮已点击完成!等待3秒后查找成功弹窗...');
                            setTimeout(() => {
                                handleSuccessModal();
                            }, 3000);
                        }
                    } catch (error) {
                        console.log(`点击按钮${index + 1}时出错:`, error);
                    }
                }, index * 500); // 每个按钮间隔500ms
            });
        } else {
            console.log('未找到任何确定按钮,尝试重新查找...');

            // 如果没找到,再等待3秒重试一次
            setTimeout(() => {
                const retryButtons = Array.from(document.querySelectorAll('button')).filter(btn =>
                    btn.textContent.includes('确定') ||
                    btn.textContent.includes('确 定') ||
                    btn.classList.contains('ant-btn-primary')
                );

                if (retryButtons.length > 0) {
                    console.log(`重试找到${retryButtons.length}个确定按钮,全部点击...`);
                    retryButtons.forEach((button, index) => {
                        setTimeout(() => {
                            button.removeAttribute('disabled');
                            button.disabled = false;
                            button.click();
                            console.log(`重试点击按钮${index + 1}`);

                            // 如果是最后一个按钮,等待3秒后查找成功弹窗
                            if (index === retryButtons.length - 1) {
                                setTimeout(() => {
                                    handleSuccessModal();
                                }, 3000);
                            }
                        }, index * 200);
                    });
                } else {
                    console.log('重试后仍未找到确定按钮');
                    isProcessing = false;
                }
            }, 3000);
        }
    }

    // 处理提交成功弹窗
    function handleSuccessModal() {
        console.log('开始查找提交成功弹窗...');

        // 查找包含"提交成功"的弹窗
        const successModal = Array.from(document.querySelectorAll('.ant-modal-body')).find(modal =>
            modal.textContent.includes('提交成功')
        );

        if (successModal) {
            console.log('找到提交成功弹窗');

            // 查找"下一门课程"按钮
            const nextCourseButton = Array.from(successModal.querySelectorAll('button')).find(btn =>
                btn.textContent.includes('下一门课程')
            );

            if (nextCourseButton) {
                console.log('找到"下一门课程"按钮,准备点击...');
                nextCourseButton.click();
                console.log('已点击"下一门课程"按钮');

                // 重置处理状态,准备处理下一门课程
                setTimeout(() => {
                    isProcessing = false;
                    console.log('准备开始下一门课程的评价...');

                    // 等待页面加载后重新开始
                    setTimeout(() => {
                        waitForElements();
                    }, 2000);
                }, 1000);
            } else {
                console.log('未找到"下一门课程"按钮,查找其他可能的按钮...');

                // 查找primary按钮作为备选
                const primaryButton = successModal.querySelector('.ant-btn-primary');
                if (primaryButton) {
                    console.log('找到primary按钮,尝试点击:', primaryButton.textContent);
                    primaryButton.click();

                    setTimeout(() => {
                        isProcessing = false;
                        setTimeout(() => {
                            waitForElements();
                        }, 2000);
                    }, 1000);
                } else {
                    console.log('未找到任何可点击的按钮');
                    isProcessing = false;
                }
            }
        } else {
            console.log('未找到提交成功弹窗,尝试重新查找...');

            // 重新查找,使用更宽泛的条件
            setTimeout(() => {
                const allButtons = Array.from(document.querySelectorAll('button')).filter(btn =>
                    btn.textContent.includes('下一门课程') ||
                    btn.textContent.includes('下一门') ||
                    btn.textContent.includes('下一')
                );

                if (allButtons.length > 0) {
                    console.log(`找到${allButtons.length}个可能的"下一门课程"按钮`);
                    allButtons[0].click();
                    console.log('已点击第一个"下一门课程"按钮');

                    setTimeout(() => {
                        isProcessing = false;
                        setTimeout(() => {
                            waitForElements();
                        }, 2000);
                    }, 1000);
                } else {
                    console.log('完全未找到"下一门课程"按钮');
                    isProcessing = false;
                }
            }, 2000);
        }
    }

    // 添加控制按钮
    function addControlButtons() {
        // 自动填写评价按钮
        const fillButton = document.createElement('button');
        fillButton.innerText = '自动填写评价';
        fillButton.style.cssText = `
            position: fixed;
            top: 10px;
            right: 10px;
            z-index: 9999;
            padding: 10px 15px;
            background-color: #1890ff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        `;

        fillButton.addEventListener('click', () => {
            isProcessing = false;
            fillForm();
        });

        // 设置按钮
        const configButton = document.createElement('button');
        configButton.innerText = '设置填空题';
        configButton.style.cssText = `
            position: fixed;
            top: 10px;
            right: 140px;
            z-index: 9999;
            padding: 10px 15px;
            background-color: #52c41a;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        `;

        configButton.addEventListener('click', createConfigModal);

        document.body.appendChild(fillButton);
        document.body.appendChild(configButton);
    }

    // 页面加载完成后开始执行
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            setTimeout(() => {
                waitForElements();
                addControlButtons();
            }, 2000);
        });
    } else {
        setTimeout(() => {
            waitForElements();
            addControlButtons();
        }, 2000);
    }

})();