您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
很喜欢点吗
// ==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); } })();