本帖最后由 Sampson 于 2026-9-6 19:56 编辑
// ==UserScript==
// @name 2026年秋成都市中小学继续教育自动学习
// @namespace http://tampermonkey.net/
// @version 1.0.2
// @description 自动学习、自动填写学习记录,自动学习我的学习未列表完成的课程
// @match https://www.cdsjxjy.cn/
// @match https://www.cdsjxjy.cn/cdcte/
// @run-at document-end
// @license MIT
// ==/UserScript==
(function () {
"use strict";
// ========== 全局标志 ==========
if (typeof window._hintShown === 'undefined') {
window._hintShown = false;
}
let recordFilled = false;
let recordInterval = null;
// ========== 注入样式(无外部依赖) ==========
function injectStyles() {
const style = document.createElement('style');
style.textContent = `
/* 自动学习提示覆盖层 */
#auto-learn-hint-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 999999;
display: flex;
justify-content: center;
align-items: center;
font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
}
#auto-learn-hint-overlay .hint-box {
background: #ffffff;
padding: 30px 40px;
border-radius: 12px;
max-width: 520px;
width: 90%;
box-shadow: 0 8px 24px rgba(0,0,0,0.3);
text-align: left;
position: relative;
line-height: 1.6;
}
#auto-learn-hint-overlay .hint-box h3 {
margin-top: 0;
color: #303133;
font-size: 20px;
border-bottom: 1px solid #EBEEF5;
padding-bottom: 12px;
}
#auto-learn-hint-overlay .hint-box ul {
padding-left: 20px;
margin: 16px 0;
}
#auto-learn-hint-overlay .hint-box ul li {
margin-bottom: 8px;
}
#auto-learn-hint-overlay .hint-box .warning {
color: #F56C6C;
margin: 12px 0;
}
#auto-learn-hint-overlay .hint-box .btn-close {
padding: 10px 40px;
background: #409EFF;
color: #fff;
border: none;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
transition: background 0.2s;
display: block;
margin: 20px auto 0;
}
#auto-learn-hint-overlay .hint-box .btn-close:hover {
background: #66b1ff;
}
/* 升级提示覆盖层 */
#upgrade-alert-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.6);
z-index: 1000000;
display: flex;
justify-content: center;
align-items: center;
font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
}
#upgrade-alert-overlay .upgrade-box {
background: #ffffff;
padding: 30px 40px;
border-radius: 12px;
max-width: 600px;
width: 90%;
box-shadow: 0 8px 30px rgba(0,0,0,0.4);
text-align: left;
position: relative;
line-height: 1.6;
}
#upgrade-alert-overlay .upgrade-box h3 {
margin-top: 0;
color: #2c3e50;
font-size: 22px;
border-bottom: 1px solid #eaeef2;
padding-bottom: 12px;
}
#upgrade-alert-overlay .upgrade-box .upgrade-desc {
font-size: 16px;
color: #7f8c8d;
margin: 15px 0;
}
#upgrade-alert-overlay .upgrade-box .btn-group {
display: flex;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
margin: 20px 0 10px;
}
#upgrade-alert-overlay .upgrade-box .btn-group button {
padding: 10px 30px;
border: none;
border-radius: 6px;
font-weight: bold;
font-size: 15px;
cursor: pointer;
transition: transform 0.15s, box-shadow 0.15s;
}
#upgrade-alert-overlay .upgrade-box .btn-group button:hover {
transform: scale(1.03);
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
#upgrade-alert-overlay .upgrade-box .btn-download {
background: #3498db;
color: white;
}
#upgrade-alert-overlay .upgrade-box .btn-close-upgrade {
background: #ecf0f1;
color: #2c3e50;
padding: 8px 24px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
margin-top: 10px;
transition: background 0.2s;
}
#upgrade-alert-overlay .upgrade-box .btn-close-upgrade:hover {
background: #dde1e3;
}
`;
document.head.appendChild(style);
}
injectStyles();
// ========== 1. 显示自动学习提示 ==========
function showCenterHint() {
if (window._hintShown) return;
window._hintShown = true;
console.log("[自动学习] 显示个人中心提示");
if (document.getElementById('auto-learn-hint-overlay')) {
return;
}
setTimeout(() => {
const overlay = document.createElement('div');
overlay.id = 'auto-learn-hint-overlay';
overlay.innerHTML = `
<div class="hint-box">
<h3>📘 自动学习插件提示</h3>
<ul>
<li>1、进入 <strong>网上学习 → 选课中心</strong>,将要学习的课程“加入学习”</li>
<li>2、进入 <strong>网上学习 → 我的学习</strong>,插件会自动开始运行</li>
<li>3、若不需要自动学习,请手动关闭插件</li>
</ul>
<p class="warning">⚠️ 插件自动运行期间,尽量不要去干预。插件会自动填写学习记录、自动提交验证码、自动播放下一个视频。</p>
<p class="warning">⚠️ 若学习进度异常(即播放页面底部无:“你好!XX老师,本门课程您总共学习了:X小时X分”和“1、您离课程要求时间还差X分钟!”)请主动点击右上角返回按钮,让脚本重新自动进入。</p>
<p style="color: #409EFF; margin: 12px 0; text-align: center;">创作不易,请作者喝一杯咖啡,谢谢支持 ☕</p>
<button class="btn-close" id="auto-learn-hint-close">我知道了</button>
</div>
`;
document.body.appendChild(overlay);
document.getElementById('auto-learn-hint-close').addEventListener('click', function () {
overlay.remove();
showUpgradeAlert();
});
overlay.addEventListener('click', function (e) {
if (e.target === overlay) {
overlay.remove();
showUpgradeAlert();
}
});
console.log("[自动学习] ✅ 自定义提示框已显示");
}, 500);
}
// ========== 2. 升级提示(已修改,无外部链接,按钮合并) ==========
function showUpgradeAlert() {
const detailPage = "https://scriptcat.org/zh-CN/script-show-page/7861";
const existing = document.getElementById('upgrade-alert-overlay');
if (existing) existing.remove();
const overlay = document.createElement('div');
overlay.id = 'upgrade-alert-overlay';
overlay.innerHTML = `
<div class="upgrade-box">
<h3>✨ 脚本升级公告</h3>
<div class="upgrade-desc">
<p>当前脚本部分功能已失效,为提供更好的服务体验,前往脚本详情页下载最新脚本:</p>
<p style="font-weight:500; color:#2c3e50;">成都市中小学教师继续教育网(https://www.cdsjxjy.cn/)。可自动学习其中的我的学习中的所有未完成课程!!!</p>
</div>
<div class="btn-group">
<button class="btn-download" id="upgrade-download-btn">⬇️ 立即跳转</button>
</div>
<div style="text-align:center; margin-top:15px;">
<button class="btn-close-upgrade" id="upgrade-close-btn">关闭</button>
</div>
</div>
`;
document.body.appendChild(overlay);
overlay.querySelector('#upgrade-download-btn').addEventListener('click', function(e) {
e.stopPropagation();
window.open(detailPage, '_blank');
});
overlay.querySelector('#upgrade-close-btn').addEventListener('click', function() {
overlay.remove();
});
overlay.addEventListener('click', function(e) {
if (e.target === overlay) {
overlay.remove();
}
});
const escHandler = function(e) {
if (e.key === 'Escape') {
overlay.remove();
document.removeEventListener('keydown', escHandler);
}
};
document.addEventListener('keydown', escHandler);
}
// ========== 3. 自动填写学习记录 ==========
const contentTemplates = [
"本次课程内容充实,结构清晰,从理论到实践层层深入。讲师结合具体案例,详细阐述了核心概念与应用场景,让我对相关领域有了更系统的认识。课程中提到的策略和方法具有很强的操作性,为今后在教学工作中落地实施提供了明确的路径和参考依据。",
"课程围绕当前教育改革发展中的热点问题展开,既有政策解读,也有一线教师的经验分享。通过对比不同地区的做法,拓宽了我的教育视野。特别是关于学生核心素养培养和课堂创新的部分,给了我很多启发,值得反复思考和借鉴。",
"本课程聚焦于教学实践中的真实困惑,提出了切实可行的解决方案。内容涵盖教学设计、课堂管理、评价反馈等多个维度,逻辑严谨,案例鲜活。通过学习,我更加明确了以学生为中心的教学理念,并掌握了一些实用的教学工具和技巧。",
"课程内容紧贴时代要求,突出了信息技术与教育教学的深度融合。讲师语言生动,讲解透彻,让我对数字化教学资源的设计与应用有了新的理解。同时,课程也提醒我要不断更新知识结构,适应未来教育的发展趋势。",
"本专题从问题出发,引导我们思考教学中的痛点,并提供了系统的解决思路。课程注重理论与实践结合,每个环节都有具体实例支撑,易于理解和迁移。我相信这些内容对提升我的专业素养和课堂教学效果都将产生积极影响。"
];
const feelingTemplates = [
"此次学习让我受益匪浅,不仅更新了教育观念,也学到了许多可操作的方法。我意识到,作为一名教师,必须保持终身学习的态度,不断吸收新知识、新技术,才能更好地适应学生发展的需求。今后我将把课程中学到的理念融入日常教学,努力提升育人质量。",
"通过本次培训,我更加深刻地认识到教育工作的复杂性和艺术性。课程中分享的经验和案例让我反思自己的教学行为,找到了改进的方向。我特别认同“以学定教”的观点,未来我会更多关注学生的个体差异,设计更有针对性的教学活动。",
"学习完本课程,我最大的感悟是:教育不仅需要热情,更需要智慧。课程中提到的多种教学策略和评价方式,为我打开了新的思路。我会尝试将这些方法应用到实际课堂中,并不断总结经验,形成自己的教学风格。同时,我也期待能有更多这样的学习机会。",
"本次学习让我对教师的专业成长有了更清晰的认识。课程强调了反思与实践的重要性,鼓励我们在教学中研究,在研究中教学。我打算在今后的工作中,主动开展教学反思,积极与同事交流合作,共同进步,做一名学习型、研究型的教师。",
"课程内容引发了我对教育本质的深入思考。教育不仅是知识的传递,更是价值观的塑造和能力的发展。我会将所学内化于心,外化于行,在教学中注重培养学生的批判性思维和创新能力,努力成为学生成长道路上的引路人。"
];
function fillLearningRecord() {
if (recordFilled) return;
const textareas = document.querySelectorAll('textarea');
if (textareas.length < 2) return;
let contentInput = null, feelingInput = null;
for (let ta of textareas) {
const ph = ta.placeholder || '';
if (ph.includes('内容要点')) contentInput = ta;
else if (ph.includes('体会') || ph.includes('感悟')) feelingInput = ta;
}
if (!contentInput && textareas.length >= 1) contentInput = textareas[0];
if (!feelingInput && textareas.length >= 2) feelingInput = textareas[1];
if (!contentInput || !feelingInput) return;
if (contentInput.value.trim().length > 0 && feelingInput.value.trim().length > 0) {
recordFilled = true;
return;
}
const rand1 = Math.floor(Math.random() * contentTemplates.length);
const rand2 = Math.floor(Math.random() * feelingTemplates.length);
contentInput.value = contentTemplates[rand1];
contentInput.dispatchEvent(new Event('input', { bubbles: true }));
feelingInput.value = feelingTemplates[rand2];
feelingInput.dispatchEvent(new Event('input', { bubbles: true }));
console.log("[自动学习] 已填写学习记录");
const submitBtn = Array.from(document.querySelectorAll('button')).find(el => {
const text = el.textContent || '';
return text.includes('提交记录') || text.includes('保存') || text.includes('提交');
});
if (submitBtn) {
setTimeout(() => {
submitBtn.click();
recordFilled = true;
console.log("[自动学习] 已提交学习记录");
}, 500);
}
}
// ========== 4. 路由变化处理 ==========
function onRouteChange() {
if ((location.pathname === '/' || location.pathname === '/cdcte/') && location.hash === '') {
showCenterHint();
return;
}
if (location.hash.includes('user/center')) {
showCenterHint();
}
if (location.hash.includes('coursePlay')) {
recordFilled = false;
if (!recordInterval) {
recordInterval = setInterval(() => {
if (recordFilled) {
clearInterval(recordInterval);
recordInterval = null;
return;
}
fillLearningRecord();
}, 3000);
}
} else {
if (recordInterval) {
clearInterval(recordInterval);
recordInterval = null;
}
recordFilled = false;
}
}
// ========== 5. 路由监听 ==========
window.addEventListener("hashchange", onRouteChange);
window.addEventListener("popstate", onRouteChange);
function triggerUrlChange() {
window.dispatchEvent(new Event("urlchange"));
}
(function (history) {
["pushState", "replaceState"].forEach((method) => {
const original = history[method];
history[method] = function () {
const result = original.apply(this, arguments);
setTimeout(() => {
triggerUrlChange();
onRouteChange();
}, 50);
return result;
};
});
})(window.history);
window.addEventListener("urlchange", onRouteChange);
// ========== 6. 初始启动 ==========
setTimeout(onRouteChange, 500);
console.log("[自动学习] 脚本已加载(无外部依赖),当前页面:", location.href);
})();