// ==UserScript==
// @name ZCMU教学评价助手 V1.1
// @namespace 1411325419@qq.com
// @version 1.1
// @description 浙江中医药大学、教务系统、学生评老师、过程评价(多功能升级版)
// @author SAintuti
// @match *://*/*
// @run-at document-start
// @match-iframe true
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 注入全局动画样式 (让弹窗和悬停更灵动)
const style = document.createElement('style');
style.innerHTML = `
/* 按钮通用悬停过渡 */
#eval-helper-ui button, #eval-sponsor-modal button {
transition: all 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94) !important;
}
/* 开始按钮悬停:放大+发光 */
#btn-start-eval:not([disabled]):hover {
transform: scale(1.03);
box-shadow: 0 0 12px rgba(76, 175, 80, 0.6);
}
/* 暂停按钮悬停:放大+发光 */
#btn-pause-eval:not([disabled]):hover {
transform: scale(1.03);
box-shadow: 0 0 12px rgba(244, 67, 54, 0.6);
}
/* 登录跳转按钮悬停:放大+发光 */
#btn-nav-login:hover {
transform: scale(1.03);
box-shadow: 0 0 12px rgba(33, 150, 243, 0.6);
}
/* 评价跳转按钮悬停:放大+发光 */
#btn-nav-eval:hover {
transform: scale(1.03);
box-shadow: 0 0 12px rgba(0, 188, 212, 0.6);
}
/* 赞助按钮悬停:放大+发光 */
#btn-sponsor-eval:hover {
transform: scale(1.03);
box-shadow: 0 0 12px rgba(156, 39, 176, 0.6);
}
/* 弹窗专用动画 */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes popIn {
0% { transform: scale(0.85); opacity: 0; }
70% { transform: scale(1.02); }
100% { transform: scale(1); opacity: 1; }
}
.animate-fade-in { animation: fadeIn 0.2s ease-out forwards; }
.animate-pop-in { animation: popIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; }
/* 弹窗内按钮悬停 */
#modal-btn-reject:hover { transform: scale(1.03); box-shadow: 0 0 12px rgba(0,0,0,0.2); }
#modal-btn-accept:hover { transform: scale(1.03); box-shadow: 0 0 15px rgba(76, 175, 80, 0.6); }
`;
document.head.appendChild(style);
// 创建 UI 面板
function createUI() {
if (document.getElementById('eval-helper-ui')) return;
const container = document.createElement('div');
container.id = 'eval-helper-ui';
container.innerHTML = `
状态: 等待操作
`;
Object.assign(container.style, {
position: 'fixed',
top: '20px',
right: '20px',
width: '255px',
backgroundColor: '#ffffff',
boxShadow: '0 4px 16px rgba(0,0,0,0.12)',
borderRadius: '10px',
padding: '14px',
zIndex: '999999',
fontFamily: 'sans-serif'
});
document.body.appendChild(container);
// --- 拖动功能 ---
let isDragging = false;
let offsetX, offsetY;
container.addEventListener('mousedown', function(e) {
if (e.target.tagName !== 'BUTTON') {
isDragging = true;
offsetX = e.clientX - container.offsetLeft;
offsetY = e.clientY - container.offsetTop;
e.preventDefault();
}
});
document.addEventListener('mousemove', function(e) {
if (isDragging) {
container.style.left = (e.clientX - offsetX) + 'px';
container.style.top = (e.clientY - offsetY) + 'px';
container.style.right = 'auto';
}
});
document.addEventListener('mouseup', function() {
isDragging = false;
});
// 事件绑定
document.getElementById('btn-start-eval').addEventListener('click', function() {
localStorage.setItem('eval_helper_running', 'true');
setUIActive();
autoEvaluateLoop();
});
document.getElementById('btn-pause-eval').addEventListener('click', function() {
localStorage.removeItem('eval_helper_running');
setUIPause();
});
document.getElementById('btn-nav-login').addEventListener('click', function() {
window.location.href = 'https://puser.zcmu.edu.cn/home-page';
});
document.getElementById('btn-nav-eval').addEventListener('click', function() {
window.location.href = 'https://jwmk.zcmu.edu.cn/jwglxt/xspjgl/kcgcpj_cxKcgcpjxxIndex.html?gnmkdm=N401650&layout=default';
});
document.getElementById('btn-sponsor-eval').addEventListener('click', function() {
window.open('https://www.ifdian.net/a/SAintuti?utm_source=copylink&utm_medium=link', '_blank');
});
}
function setUIActive() {
const startBtn = document.getElementById('btn-start-eval');
const pauseBtn = document.getElementById('btn-pause-eval');
if (startBtn && pauseBtn) {
startBtn.disabled = true; startBtn.style.backgroundColor = '#ccc';
pauseBtn.disabled = false; pauseBtn.style.backgroundColor = '#f44336';
}
}
function setUIPause() {
const startBtn = document.getElementById('btn-start-eval');
const pauseBtn = document.getElementById('btn-pause-eval');
if (startBtn && pauseBtn) {
startBtn.disabled = false; startBtn.style.backgroundColor = '#4CAF50';
pauseBtn.disabled = true; pauseBtn.style.backgroundColor = '#ccc';
}
updateLog("⏸ 已暂停");
}
function updateLog(text) {
const logDiv = document.getElementById('eval-status-log');
if (logDiv) logDiv.innerText = text;
}
// 屏幕正中间的赞助提示弹窗 (加入Q弹动画)
function showSponsorModal() {
if (document.getElementById('eval-sponsor-modal')) return;
// 创建遮罩层 (淡入动画)
const overlay = document.createElement('div');
overlay.id = 'eval-sponsor-modal';
overlay.className = 'animate-fade-in';
Object.assign(overlay.style, {
position: 'fixed',
top: '0',
left: '0',
width: '100vw',
height: '100vh',
backgroundColor: 'rgba(0,0,0,0.45)',
zIndex: '1000000',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontFamily: 'sans-serif'
});
// 创建弹窗主体 (Q弹放大动画)
const modal = document.createElement('div');
modal.className = 'animate-pop-in';
Object.assign(modal.style, {
backgroundColor: '#ffffff',
padding: '26px',
borderRadius: '14px',
boxShadow: '0 12px 36px rgba(0,0,0,0.18)',
width: '480px',
textAlign: 'center'
});
modal.innerHTML = `
🎉
💥 评价已完成,满意的话可以赞助一下作者哦! 💥
`;
overlay.appendChild(modal);
document.body.appendChild(overlay);
// 按钮事件绑定
document.getElementById('modal-btn-reject').addEventListener('click', function() {
document.body.removeChild(overlay);
});
document.getElementById('modal-btn-accept').addEventListener('click', function() {
window.open('https://www.ifdian.net/a/SAintuti?utm_source=copylink&utm_medium=link', '_blank');
document.body.removeChild(overlay);
});
}
// 核心超神速循环
function autoEvaluateLoop() {
if (localStorage.getItem('eval_helper_running') !== 'true') {
setUIPause();
return;
}
// 1. 瞬间拦截并点掉确定弹窗
const okBtn = document.querySelector('#btn_ok');
if (okBtn && window.getComputedStyle(okBtn).display !== 'none') {
updateLog("💥 发现弹窗,正在自动确认... 💥");
okBtn.click();
return;
}
// 2. 定位未评价老师
let nextTeacherCard = null;
const allTeacherCards = document.querySelectorAll('#wpjkc > li.mui-table-view-cell');
for (let card of allTeacherCards) {
if (!card.innerText.includes('已评价')) {
nextTeacherCard = card;
break;
}
}
if (!nextTeacherCard) {
updateLog("🎉 全部秒完! 🎉");
localStorage.removeItem('eval_helper_running');
setUIPause();
showSponsorModal();
return;
}
// 3. 检查右侧表单
const sliderInput = document.querySelector('.range-slider-container input[type="range"]');
if (!sliderInput) {
updateLog("💥 正在秒切下一位老师... 💥");
nextTeacherCard.click();
setTimeout(autoEvaluateLoop, 300);
return;
}
// 4. 秒拉满分
updateLog("💥 正在极速同步100分... 💥");
const allSliders = document.querySelectorAll('.range-slider-container input[type="range"]');
allSliders.forEach(slider => {
slider.value = 100;
slider.dispatchEvent(new Event('input', { bubbles: true }));
slider.dispatchEvent(new Event('change', { bubbles: true }));
});
// 5. 秒暴力解禁并提交
const submitBtn = document.querySelector('#submit');
if (submitBtn) {
submitBtn.removeAttribute('disabled');
submitBtn.disabled = false;
submitBtn.classList.remove('disabled');
setTimeout(() => {
if (localStorage.getItem('eval_helper_running') !== 'true') return;
updateLog("💥 正在强行秒提... 💥");
submitBtn.click();
setTimeout(autoEvaluateLoop, 500);
}, 150);
}
}
// 初始化轮询 (由于是全网生效,移除了特定 DOM 元素的强依赖才初始化的限制,只保证 body 存在便生成 UI)
const initTimer = setInterval(() => {
if (document.body) {
clearInterval(initTimer);
createUI();
if (localStorage.getItem('eval_helper_running') === 'true') {
setUIActive();
autoEvaluateLoop();
}
}
}, 50);
})();