Skip to content

Instantly share code, notes, and snippets.

@zhangyingda
Last active September 11, 2025 01:17
Show Gist options
  • Select an option

  • Save zhangyingda/7c0591d065b3a6a7ae9c04cb332d2152 to your computer and use it in GitHub Desktop.

Select an option

Save zhangyingda/7c0591d065b3a6a7ae9c04cb332d2152 to your computer and use it in GitHub Desktop.
2025暑期研修.user.js
// ==UserScript==
// @name 2025国家智慧中小学-暑期研修(免费,秒刷),各类继续教育/定制【山东山西广东、河北、湖南、四川、吉林继教、重庆赤峰宁夏包头梅河口青岛等专技、现代远程教育、双融双创、超星,好医生,教育干部,智慧普法等,文档查看更多
// @namespace http://tampermonkey.net/zzzzzzys_国家中小学
// @version 2.8.8
// @copyright zzzzzzys.All Rights Reserved.
// @description 适用2025国家智慧教育平台、山东教师教育、河北继续教育等.【河北继续教育(师学通、奥鹏、电视台、高教社等)】【吉林继教(中盛佳源|)】【中小学D校】【国家开发大学】【四川继教、四川创联】【重庆、内蒙古、赤峰、宁夏、包头、梅河口、桦甸教育、中山专技(chinahrt、chinamde)等软件】【广东双融双创、继续教育】【人教社义教】【云继教】【沃希学苑(山东中小学人工智能研修包含考试)】【名师学堂】【中山教师研修】【河北专业技术人员继续教育、湖南师范大学专业技术人员继续教育网】【广西广东干部网络学院、山东灯塔网络学院、凉山专技继续教育】【湖南人社】,凉山、河南专技、鸡西教师平台、民用无人驾驶航空器管理平台,好医生,中国教育干部、法宣在线、吉林高邦等自动化挂机/刷课 更多请前往:https://zzzzzzys.lovestoblog.com/,还有软件支持更加便捷的学习课程!注意:禁止二次发布!加QQ群获取更新
// @author zzzzzzys
// @match *://basic.smartedu.cn/*
// @match *://core.teacher.vocational.smartedu.cn/*
// @match *://test3.ykt.eduyun.cn/*
// @match *://pn202413060.stu.teacher.com.cn/studyPlan/*
// @match *://pn202413060.stu.teacher.com.cn/course/*
// @match *://cn202511002.stu.t-px.cn/*
// @match *://cas.study.yanxiu.jsyxsq.com/auth/selfHost/studyPlace/index.html*
// @match *://learn.ourteacher.com.cn/StepLearn/StepLearn/*
// @match *://vc.chinabett.com/studyduration/index*
// @match *://www.ttcdw.cn/p*
// @match *://*.besteacher.com.cn/activity/curriculum/*
// @match *://*.webtrn.cn/learnspace/learn/learn/templateeight/index.action*
// @match *://cqrl.21tb.com/els/html/courseStudyItem/courseStudyItem.learn.do*
// @match *://*.nmgdbrc.com/*
// @match *://wp.pep.com.cn/web/index.php?/px/*
// @match *://bjpep.gensee.com/webcast/site/vod/*
// @match *://srsc.gdedu.gov.cn/course/study*
// @match *://gp.chinahrt.com/index.html*
// @match *://videoadmin.chinahrt.com/videoPlay/playEncrypt*
// @match *://saas.yunteacher.com/module/*
// @match *://saas.yunteacher.com/coursePlay*
// @match *://jlzj.ylxue.net/LearningCenter/LearningCourseVideo*
// @match *://*.chinamde.cn/play/*
// @match *://p.bokecc.com/playhtml.bo*
// @match https://jsxx.gdedu.gov.cn/*/study/course/*
// @match https://jsxx.gdedu.gov.cn/study/course/*
// @match https://m.zsjsjy.com/teacher/train/train/online/study.do*
// @match https://trplayer.sctce.cn/*
// @match https://study.seewoedu.cn/tCourse/group/*
// @match https://cpb-m.cvte.com/*
// @match https://saas.mingshiclass.com/*
// @require https://scriptcat.org/lib/637/1.4.6/ajaxHooker.js#sha256=FBIJAmqSt3/bUHAiAFBFd2YvGHENrBQGfe1b4c+UBYs=
// @require https://scriptcat.org/lib/637/1.4.6/ajaxHooker.js
// @require https://fastly.jsdelivr.net/npm/crypto-js@4.2.0/crypto-js.min.js
// @resource https://cdn.staticfile.org/limonte-sweetalert2/11.7.1/sweetalert2.min.css
// @require https://fastly.jsdelivr.net/npm/sweetalert2@11.12.2/dist/sweetalert2.all.min.js
// @connect basic.smartedu.cn
// @connect x-study-record-api.ykt.eduyun.cn
// @connect fc-mp-8ba0e2a3-d9c9-45a0-a902-d3bde09f5afd.next.bspapp.com
// @connect mp-8ba0e2a3-d9c9-45a0-a902-d3bde09f5afd.cdn.bspapp.com
// @connect manage.yzspeixun.com
// @connect videoadmin.chinahrt.com
// @connect api.mingshiclass.com
// @connect cpb-m.cvte.com
// @grant unsafeWindow
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_xmlhttpRequest
// @grant GM_info
// @grant GM_openInTab
// @grant GM_addStyle
// @run-at document-end
// ==/UserScript==
const web_url="https://zzzzzzys.lovestoblog.com/"
const web_list = [
{ name: "备用地址1", url: "https://zzzzzzys.lovestoblog.com/" },
]
class ScriptCore {
constructor() {
this.modules = new Map();
this.initModules();
this.execute();
}
initModules() {
// 多站点匹配配置
this.modules.set('国家智慧教育平台', {
match: [
/^(https?:\/\/)?(basic\.smartedu\.cn)/,
/^(https?:\/\/)?(core\.teacher\.vocational\.smartedu\.cn)/,
/^(https?:\/\/)?(test3\.ykt\.eduyun\.cn)/,
/localhost:\d+(\/.*)?$/ // 本地开发环境
],
module: SmartEduModule,
config: {
refreshInterval: 5000,
apiEndpoints: {
}}});
}
execute() {
const currentUrl = new URL(window.location.href);
for (const [moduleName, { match, module: Module, config }] of this.modules) {
if (this.matchChecker(currentUrl, match)) {
Logger.moduleLoaded(moduleName)
const executor = () => new Module().run(config);
if (config.runAt && config.runAt === 'document-start') {
executor();
} else {
// 延迟到DOM加载完成后执行
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', executor);
} else {
executor(); // 兜底:如果已经加载完成则直接执行
}
}
return; // 单例模式运行
}
}
console.warn('[Core] 未找到匹配模块');
}
matchChecker(currentUrl, matcher) {
// 处理多种匹配类型
if (Array.isArray(matcher)) {
return matcher.some(pattern =>
pattern instanceof RegExp ? pattern.test(currentUrl.href)
: typeof pattern === 'function' ? pattern(currentUrl)
: false
);
}
return typeof matcher === 'function'
? matcher(currentUrl)
: matcher.test(currentUrl.href);
}
}
class Logger {
static #styles = {
core: ['font-size: 11px', 'font-family: monospace', 'padding: 2px 8px', 'border-radius: 4px', 'background: linear-gradient(145deg, #2196F3 20%, #1976D2)', 'color: white', 'text-shadow: 0 1px 1px rgba(0,0,0,0.3)'].join(';'),
module: ['background: #FFEB3B', 'color: #212121', 'padding: 1px 4px', 'border-radius: 2px', 'margin-left: 4px'].join(';'),
status: ['background: #4CAF50', 'color: white', 'padding: 1px 6px', 'border-left: 2px solid #388E3C'].join(';')
};
static moduleLoaded(name) {
const timestamp = performance.now().toFixed(2);
try {
Swal.fire({title: '<span style="font-size:1.5em; color:#FF4DAF;">🎉 脚本加载成功!</span>', html: ` <div style="text-align:left; line-height:1.6;"> <p style="font-size:1.1em; margin-bottom:15px;">✅ 脚本已正确加载!</p> <div style="background:#f8f9fa; padding:12px; border-radius:8px;"> <p style="color:#666; margin:5px 0;">⚠️ 如未加载成功:</p> <ul style="margin:5px 0; padding-left:20px;"> <li>请尝试使用 <strong style="color:#FF4DAF;">篡改猴插件</strong></li> <li>脚本猫可能导致兼容性问题</li> <li>同时使用时需关闭脚本猫</li> </ul> </div> <p style="margin-top:20px;"> <a href="https://zzzzzzys.lovestoblog.com/" target="_blank" style="color:#FF4DAF; text-decoration:underline;"> 🔗 https://zzzzzzys.lovestoblog.com/查看更多适配网站 </a> </p> </div> `, icon: 'success', width: '800px', padding: '2em', customClass: {popup: 'custom-swal-popup', title: 'custom-swal-title', htmlContainer: 'custom-swal-html'}, confirmButtonColor: "#FF4DAF", confirmButtonText: '<span style="font-size:1.1em;">🚀 关闭弹窗</span>', showCloseButton: true, timerProgressBar: false, backdrop: 'rgba(0,0,0,0.7)'}); }catch (e) {
console.error(e);
}
console.log(
`%cCORE%c${name}%c ✔ LOADED %c+${timestamp}ms`,
this.#styles.core,
this.#styles.module,
this.#styles.status,
'color: #757575; font-size: 0.8em;'
);}}
const web_id="68809edc4b92476e9720044a"
class SmartEduModule {
constructor() {
}
run(config) {
this.setupCoreFeatures(config);
}
setupCoreFeatures({refreshInterval}) {
const qqGroup = [
{customName: "群1", id: "570337037", link: "https://qm.qq.com/q/rDCbvTiV9K", isFull: true, priority: 0},
]
const originalXHR = unsafeWindow.XMLHttpRequest;
let fullDatas = null
ajaxHooker.filter([
{url: 'fulls.json'}
])
ajaxHooker.hook(request => {
if (request.url.includes('fulls.json')) {
request.response = res => {
console.log(res);
fullDatas = JSON.parse(res.responseText);
};
}
});
const renderQQGroups = () => {
try {
const activeGroups = qqGroup
.filter(group => {
// 添加数据校验
if (!group.customName || !group.id) {
console.warn('Invalid group:', group);
return false;
}
return !group.isFull;
})
.sort((a, b) => a.priority - b.priority);
// 添加空状态提示
if (activeGroups.length === 0) {
return `<div style="color: #ff9999; text-align:center; margin:12px 0"></div>`;
}
const title = `<div style="background: linear-gradient(135deg, #FF4DAF 0%, #FF6B6B 100%);display: flex; align-items: center; gap:15px;">
<img src="https://qzonestyle.gtimg.cn/qzone/qzact/act/external/tiqq/logo.png" style="height:36px; border-radius:6px;">
<div>
<div style="font-size:12px; opacity:0.9;">JavaScript</div>
</div>
</div>`
let content = title + activeGroups.map(group => ` <a href="${group.link}" target="_blank" style="display: block; margin-top: 12px; padding: 10px; background: rgba(255,255,255,0.2); border-radius: 6px; text-align: center; text-decoration: none; color: white !important; transition: 0.3s; font-weight: 500; cursor: pointer;" aria-label="加入QQ群${group.customName}(群号:${group.id})"> 🎯 点击加入${group.customName}:${group.id} <!-- 移除群号显示 --> </a> `).join('');
return `<div style="background: linear-gradient(135deg, #FF4DAF 0%, #FF6B6B 100%); padding:15px; border-radius:8px; color:white;">
${content}
</div>`
} catch (error) {
console.error('QQ群渲染错误:', error);
return ''; // 静默失败
}
};
let requestObj = {
fullsData: {
url: "https://s-file-2.ykt.cbern.com.cn/teach/s_course/v2/activity_sets/3efdb592-138e-4854-8964-5e10f6011f33/fulls.json",
method: "GET",
}, resourceLearningPositions: {
url: "https://x-study-record-api.ykt.eduyun.cn/v1/resource_learning_positions/", method: "PUT"
}, /* 职业教育 | 高等教育 */
progress: {
url: "https://core.teacher.vocational.smartedu.cn/p/course/services/member/study/progress",
method: "POST",
}
}
/********************************************************
* 职业教育/高等教育
*******************************************************/
const SWAL_CONFIG = {
title: '课程进度控制', html: ` <div style="margin-bottom: 5px"> <label>v${GM_info.script.version}</label> </div> <div style=" padding: 12px; background: #e8f4ff; border-radius: 8px; margin-bottom: 15px; border: 1px solid #b3d4fc; text-align: center; "> <span style=" font-size: 14px; color: #ff4daf; display: inline-flex; align-items: center; gap: 6px; "> <span style="font-size: 16px">🎯</span> 老师您好,点击开始按钮,开始减负之旅<br> 脚本会自动学习当前页所有视频,您可安心休息片刻 </span> </div> <div style="margin-bottom: 15px"> <label>当前视频:</label> <div id="currentVideo" style=" font-size: 16px; color: #3498db; font-weight: 500; margin: 8px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; ">尚未开始</div> </div> <div class="progress-container" style=" background: #f0f0f0; height: 20px; border-radius: 10px; margin: 15px 0; overflow: hidden; "> <div id="swalProgressBar" style=" height: 100%; background: linear-gradient(90deg, #4CAF50 0%, #8BC34A 100%); width: 0; transition: width 0.3s ease; "></div> </div> <div style=" display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 15px; "> <div> <label>当前进度</label> <div id="currentProgress" style=" font-size: 18px; font-weight: bold; color: #2c3e50; ">0:00</div> </div> <div> <label>大概需要时间</label> <div id="needTime" style=" font-size: 14px; color: #2efd00; ">还未开始</div> </div> <div> <label>总时长</label> <div id="totalTime" style=" font-size: 14px; color: #7f8c8d; ">还未开始</div> </div> </div> <div id="statusMessage" style=" padding: 10px; border-radius: 5px; margin: 10px 0; background: #f8f9fa; text-align: center; ">准备就绪</div> <div style=" padding: 12px; background: #f5f7fa; border-radius: 8px; margin: 12px 0; border: 1px solid #e4e7ed; "> ${renderQQGroups()} </div> <div id="author" style=" padding: 8px 16px; /* 适当的上下左右内边距 */ border-radius: 10px; margin: 10px 0; background: #f8f9fa; text-align: center; font-size: 12px; /* 稍微增大字体 */ font-weight: bold; /* 加粗字体 */ color: #495057; /* 更深的字体颜色,增强可读性 */ border: 1px solid #dee2e6; /* 添加边框 */ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 轻微阴影效果 */ letter-spacing: 1px; /* 增加字母间距 */ "> By YoungthZou. 盗码可耻! zzzzzzys </div> `, showConfirmButton: false, allowOutsideClick: false, allowEscapeKey: false, width: 600, willOpen: () => {
document.querySelector('.swal2-close').remove();
}
};
// 状态管理
let currentProgress = 60;
let isRunning = false;
let swalInstance = null;
let totalTime = 1000;
let checkInterval = null
// 工具函数
const formatTime = (seconds) => {
const mins = Math.floor(seconds / 60);
const secs = seconds % 60;
return `${mins}:${secs.toString().padStart(2, '0')}`;
};
const updateUI = (progress, status) => {
if (!swalInstance) return;
const progressBar = swalInstance.querySelector('#swalProgressBar');
const percent = (progress / totalTime * 100).toFixed(1);
progressBar.style.width = `${Math.min(parseFloat(percent), 100)}%`;
swalInstance.querySelector('#currentProgress').textContent = formatTime(progress);
swalInstance.querySelector('#totalTime').textContent = formatTime(totalTime);
swalInstance.querySelector('#needTime').textContent = formatTime(parseInt(((totalTime - progress) / 3).toFixed(0)));
const statusEl = swalInstance.querySelector('#statusMessage');
statusEl.textContent = {loading: '🔄 正在同步进度...', success: '✅ 同步成功,stand by...', error: '❌ 同步失败(长时间失败,请反馈)', idle: '⏸ 已暂停', finished: '✅已学完,跳过...', finishAll: '已全部学完,请手动刷新,给个好评吧~', next: "🔄 此视频已学完,准备学习下一个..."}[status] || '准备就绪';
statusEl.style.color = {loading: '#f39c12', success: '#2ecc71', error: '#e74c3c', idle: '#7f8c8d', finished: '#0022fd', finishAll: '#ff4daf', next: '#f39c12',}[status];
};
const sendProgress = async (videoId) => {
updateUI(currentProgress, 'loading');
let oriData = {
courseId: unsafeWindow.courseId,
itemId: unsafeWindow.p.itemId,
videoId: videoId,
playProgress: currentProgress,
segId: unsafeWindow.p.segId,
type: unsafeWindow.p.type,
tjzj: 1,
clockInDot: currentProgress,//后台要求此参数为视频播放的位置
sourceId: unsafeWindow.p.projectId,
timeLimit: unsafeWindow.timilistParam.timeLimit || -1,
originP: unsafeWindow.p.originP === 1 ? 2 : 1, // 硬编码,等待修改
}
try {
const response = await fetch(`${requestObj.progress.url}?orgId=${unsafeWindow.p.orgId}`, {
method: "POST", headers: {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"x-requested-with": "XMLHttpRequest",
"u-platformId": unsafeWindow.platformInfo.id
}, credentials: "include", body: new URLSearchParams(oriData)
});
const data = await response.json();
console.log(data)
if (data.data?.videoProgress > 0) {
currentProgress = parseInt(data.data.videoProgress);
updateUI(currentProgress, 'success');
return data.data.progress;
} else {
throw new Error('无效的服务器响应');
}
} catch (error) {
console.error('请求失败:', error);
updateUI(currentProgress, 'error');
}
};
// 创建控制界面
function createControlPanel() {
console.log('Swal create control panel')
unsafeWindow.DialogRuning=true
Swal.fire({
...SWAL_CONFIG, didOpen: (modal) => {
swalInstance = modal;
const actions = document.createElement('div');
actions.style = `display: grid;grid-template-columns: 1fr 1fr;gap: 10px;margin-top: 15px;`;
const startBtn = createButton('▶ 开始', '#2ecc71', async () => {
if (!isRunning) {
try {
try {
document.querySelector('video').pause()
} catch (e) {}
isRunning = true;
startBtn.textContent = '⏸ 暂停';
startBtn.style.background = '#e74c3c';
let courseData = getCourseData();
for (const courseDatum of courseData) {
if (!isRunning) {
return
}
const videoId=courseDatum.videoId
if (!videoId) continue;
await sleep(2000)
console.log(courseDatum.name)
swalInstance.querySelector('#currentVideo').textContent = courseDatum.name
currentProgress = 0;
totalTime = parseInt(courseDatum.duration);
if (parseInt(courseDatum.progress) === 1) {
console.log(" 已学完,跳过...")
updateUI(currentProgress, 'finished');
continue;
}
do {
const progress = await sendProgress(videoId, currentProgress); // 立即执行
if (progress === "1.0") {
break;
}
await interruptibleWait(21000);
} while (currentProgress < totalTime && isRunning)
updateUI(currentProgress, 'next');
await sleep(20000);
}
// 非暂停结束
if (isRunning) {
currentProgress = 1;
totalTime = 1;
updateUI(currentProgress, 'finishAll');
startBtn.textContent = '▶ 开始';
startBtn.style.background = '#2ecc71';
}
} catch (e) {
console.error(e)
if (Swal) {
Swal.fire({
title: "失败!",
text: e.toString() + "请在视频播放页面使用!!!",
icon: 'error', // showCancelButton: true,
confirmButtonColor: "#FF4DAFFF", // cancelButtonText: "取消,等会刷新",
confirmButtonText: "点击去反馈",
}).then((result) => {
if (result.isConfirmed) {
window.open("https://greasyfork.org/zh-CN/scripts/525037/feedback")
}
});
}
} finally {
isRunning = false;
}
} else {
isRunning = false;
startBtn.textContent = '▶ 继续';
startBtn.style.background = '#2ecc71';
if (checkInterval) {
clearTimeout(checkInterval.timer);
checkInterval.resolve(); // 立即结束等待
}
updateUI(currentProgress, 'idle');
setTimeout(() => {
updateUI(currentProgress, 'idle');
}, 2000)
}
});
const resetBtn = createButton('→去好评', '#dbba34', () => {
window.open("https://scriptcat.org/zh-CN/script-show-page/2789/comment")
});
actions.append(startBtn, resetBtn);
modal.querySelector('.swal2-html-container').append(actions);
}
});
}
const sleep = function (time) {
return new Promise(resolve => setTimeout(resolve, time));
}
function interruptibleWait(ms) {
return new Promise(resolve => {
const timer = setTimeout(resolve, ms);
// 暴露清除方法以便立即暂停
checkInterval = {timer, resolve};
});
}
function createButton(text, color, onClick) {
const btn = document.createElement('button');
btn.textContent = text;
btn.style = `padding: 10px 15px;border: none;border-radius: 5px;background: ${color};color: white;cursor: pointer;transition: opacity 0.3s;`;
btn.addEventListener('click', onClick);
btn.addEventListener('mouseenter', () => btn.style.opacity = 0.8);
btn.addEventListener('mouseleave', () => btn.style.opacity = 1);
return btn;
}
function getCourseData() {
let courseData = unsafeWindow.initlessons
console.log(courseData)
if (!courseData) {
updateUI(currentProgress, 'error');
console.error("no course data!");
return
}
courseData = courseData.filter(item => {
return item?.type !== "1";
});
return [...courseData];
}
/********************************************************
* 打赏
*******************************************************/
GM_addStyle(`.donate-panel { position: fixed; left: 30%; top:50%; background: linear-gradient(135deg, #fff5f5 0%, #fff0f7 100%); border-radius: 16px; box-shadow: 0 8px 32px rgba(255, 77, 175, 0.2); padding: 24px; width: 520px; z-index: 2147483647; transform: translateY(-100); /* 初始隐藏位置 */ opacity: 1; /* 确保初始可见性 */ border: 1px solid #ffe6f0; backdrop-filter: blur(8px); transition: none; /* 禁用transition改用animation */ }.donate-header { position: relative; font-size: 18px; color: #ff4daf; margin-bottom: 20px; font-weight: 600; display: flex; align-items: center; gap: 12px; padding-bottom: 12px; border-bottom: 2px solid rgba(255, 77, 175, 0.1); } .donate-header::after { content: "✨"; position: absolute; right: 0; top: -8px; font-size: 24px; animation: sparkle 2s infinite; } .motivation-text { font-size: 13px; color: #666; line-height: 1.6; margin: 12px 0; background: rgba(255, 255, 255, 0.9); padding: 12px; border-radius: 8px; border: 1px solid #ffebf3; } @keyframes heartbeat { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } @keyframes sparkle { 0% { opacity: 0.3; } 50% { opacity: 1; } 100% { opacity: 0.3; } } @keyframes panelSlideIn { from { transform: translateY(100%); opacity: 0; } to { transform: translateY(-50%); opacity: 1; } } @keyframes panelSlideOut { from { transform: translateY(0); opacity: 1; } to { transform: translateY(100%); opacity: 0; } } @keyframes heartbeat { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } } .qr-grid { display: grid; grid-template-columns: 1fr; /* 改为单列布局 */ gap: 24px; margin: 24px auto; max-width: 300px; /* 增大容器宽度 */ } .qr-item { position: relative; overflow: hidden; border-radius: 12px; transition: 0.3s; padding: 12px; /* 增加内边距 */ background: #fff; box-shadow: 0 4px 12px rgba(255, 77, 175, 0.1); } .qr-item:hover { transform: translateY(-4px); box-shadow: 0 6px 16px rgba(255, 77, 175, 0.2); } .qr-item img { width: 100%; height: auto; /* 保持比例 */ border-radius: 8px; border: 1px solid #ffe5f0; min-height: 280px; /* 最小高度保证 */ } .qr-item p { text-align: center; margin: 16px 0 8px; font-size: 16px; /* 增大文字 */ color: #ff4daf; font-weight: 600; } /* 新增文字样式 */ .qr-tips { text-align: center; margin: 8px 0; font-size: 14px; color: #ff7ab8; /* 更柔和的粉色 */ } .qr-proverb { font-style: italic; color: #ff9ec7; /* 更浅的粉色 */ font-size: 13px; margin-top: 4px; } /* 修改原有.qr-item p样式 */ .qr-item p { margin: 12px 0 4px; /* 减小下边距 */ /* 其他样式保持不变 */ } /* 手机横屏/平板适配 */ @media (min-width: 600px) { .qr-grid { grid-template-columns: 1fr 1fr; /* 大屏幕恢复双列 */ max-width: 600px; } .qr-item img { min-height: 240px; } } .third-party { margin-top: 20px; } .platform-btn { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px; background: linear-gradient(135deg, #fff0f5 0%, #fff8fb 100%); border-radius: 8px; text-decoration: none; color: #ff6699 !important; font-size: 14px; margin: 8px 0; transition: 0.3s; border: 1px solid #ffe6ee; } .donate-panel.active { animation: panelSlideIn 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) forwards; } .donate-panel.exit { animation: panelSlideOut 0.3s ease forwards; } /* 触发按钮动画 */ #donate-trigger { animation: heartbeat 1.8s ease-in-out infinite; } .platform-btn:hover { background: linear-gradient(135deg, #ffe6ee 0%, #fff1f7 100%); box-shadow: 0 4px 12px rgba(255, 77, 175, 0.1); } .close-btn { /* 保持原有样式 */ }`);
// 激励文案库
const motivationTexts = ["您的每一份支持都将转化为:", "❤️ 服务器续费 ", "🛠️ 持续开发维护 ", "☕ 深夜码农的咖啡燃料", "🐈 小猫最爱的水煮鸡胸肉",];
// 动态生成激励文案
function generateMotivation() {
const fragments = ['<div class="motivation-text">', '🌟 <strong>感谢使用本脚本!</strong>', ...motivationTexts.map(t => `• ${t}`), '</div>'].join('<br>');
return fragments
.replace('${donateCount}', '1,234')
.replace('${updateDays}', '365');
}
// 打赏面板HTML结构
const donateHTML = `
<div id="donate-panel"> ${generateMotivation()} <div class="donate-header"> <svg viewBox="0 0 24 24" width="20" height="20" fill="#1e62ec"> <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/> </svg> 支持开发者 </div> <div class="qr-grid"> <div class="qr-item"> <p>微信扫码支持</p> <img style="width: 200px;height: 266px" src="https://mp-8ba0e2a3-d9c9-45a0-a902-d3bde09f5afd.cdn.bspapp.com/monkey-pic/wechat2.jpg" alt="微信赞赏码"> <div class="qr-tips"> <p>❤️持续创作需要您的支持</p> <p class="qr-proverb">星火相聚,终成光芒</p> </div> </div> <div class="qr-item"> <p>支付宝扫码支持</p> <img style="width: 200px;height: 266px" src="https://mp-8ba0e2a3-d9c9-45a0-a902-d3bde09f5afd.cdn.bspapp.com/monkey-pic/alipay2.jpg" alt="支付宝收款码"> <div class="qr-tips"> <p>🌸每一份心意都值得珍惜</p> <p class="qr-proverb">不啻微芒,造矩成阳</p> </div> </div> </div> <div class="donate-header"> <svg viewBox="0 0 24 24" width="20" height="20" fill="#1e62ec"> <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/> </svg> 感谢您的支持! </div> <div class="third-party"> <!--<a href="https://afdian.net/@yourid" class="platform-btn" target="_blank"> <svg viewBox="0 0 1024 1024" width="14" height="14" style="vertical-align:-2px;"> <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372zm218-572.1h-50.4c-4.4 0-8 3.6-8 8v384.2c0 4.4 3.6 8 8 8h145.7c4.4 0 8-3.6 8-8V319.9c0-4.4-3.6-8-8-8h-50.4c-4.4 0-8 3.6-8 8v151.7H730V319.9c0-4.4-3.6-8-8-8zM328.1 703.9c-4.4 0-8-3.6-8-8v-384c0-4.4 3.6-8 8-8h50.4c4.4 0 8 3.6 8 8v151.7h116.7V319.9c0-4.4 3.6-8 8-8h50.4c4.4 0 8 3.6 8 8v384.2c0 4.4-3.6 8-8 8h-145c-4.4 0-8-3.6-8-8v-151H344v151c0 4.4-3.6 8-8 8H328.1z"/> </svg> 爱发电支持 </a>--> <div class="platform-btn" id="donate-panel-close">感谢开发者,已支持~</div> </div> </div>
`;
// 初始化打赏面板
function initDonate() {
if (document.getElementById('donate-panel')) return;
const panel = document.createElement('div');
panel.innerHTML = donateHTML;
panel.className = 'donate-panel';
document.body.appendChild(panel);
// 强制重排触发动画
void panel.offsetWidth; // 触发CSS重绘
panel.classList.add('active');
// 关闭按钮事件
panel.querySelector('#donate-panel-close').addEventListener('click', () => {
panel.classList.remove('active');
panel.classList.add('exit');
panel.addEventListener('animationend', () => {
panel.remove();
}, {once: true});
});
// 点击外部关闭
const clickHandler = (e) => {
if (!panel.contains(e.target) && e.target.id !== 'donate-trigger') {
panel.classList.add('exit');
panel.addEventListener('animationend', () => {
panel.remove();
}, {once: true});
document.removeEventListener('click', clickHandler);
}
};
setTimeout(() => document.addEventListener('click', clickHandler), 100);
}
// 显示触发按钮
const trigger = document.createElement('div');
trigger.innerHTML = '❤️ 打赏支持';
Object.assign(trigger.style, {
position: 'fixed', left: '10px', top: '415px', background: '#ff6b6b', color: 'white', padding: '8px 16px', borderRadius: '20px', cursor: 'pointer', zIndex: '999999999999999', boxShadow: '0 2px 8px rgba(0,0,0,0.2)', fontSize: '14px'
});
// 触发按钮增强
Object.assign(trigger.style, {
background: 'linear-gradient(135deg, #ff4daf 0%, #ff6b6b 100%)', fontWeight: '600', padding: '12px 24px', boxShadow: '0 4px 24px rgba(255, 77, 175, 0.3)', animation: 'heartbeat 1.5s ease-in-out infinite', border: '1px solid #ffb3d9'
});
trigger.addEventListener('click', initDonate);
//document.body.appendChild(trigger);
/********************************************************
* 中小学智慧教育平台 * 寒假研修
*******************************************************/
//样式
let style = `.button-3 { position: fixed; appearance: none; background-color: #ed5822; border: 1px solid rgba(27, 31, 35, .15); border-radius: 6px; box-shadow: rgba(27, 31, 35, .1) 0 1px 0; box-sizing: border-box; color: #ffffff; cursor: pointer; display: inline-block; font-family: -apple-system,system-ui,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; font-size: 14px; font-weight: 600; line-height: 20px; padding: 6px 16px; left: 20px; top: 300px; text-align: center; text-decoration: none; user-select: none; -webkit-user-select: none; touch-action: manipulation; vertical-align: middle; white-space: nowrap; z-index: 2147483647; } .button-3:focus:not(:focus-visible):not(.focus-visible) { box-shadow: none; outline: none; } .button-3:hover { background-color: #2c974b; } .button-3:focus { box-shadow: rgba(46, 164, 79, .4) 0 0 0 3px; outline: none; } .button-3:disabled { background-color: #94d3a2; border-color: rgba(27, 31, 35, .1); color: rgba(255, 255, 255, .8); cursor: default; } .button-3:active { background-color: #298e46; box-shadow: rgba(20, 70, 32, .2) 0 1px 0 inset; }`
const createFloatingButton = () => {
// 如果按钮已存在则先移除旧实例
const existingBtn = document.getElementById('zs-helper-btn');
if (existingBtn) existingBtn.remove();
// 直接创建按钮元素(去掉外层div嵌套)
const btn = document.createElement('div');
btn.id = 'zs-helper-btn'; // 确保唯一ID直接设置在元素上
btn.style.cssText = ` position: fixed; left: 10px; top: 250px; transform: translateY(-50%); background: #ed5822; color: white; padding: 12px 24px; border-radius: 30px; cursor: pointer; box-shadow: 0 4px 12px rgba(255,77,175,0.3); z-index: 2147483647; /* 使用最大z-index值 */ transition: 0.3s; font-family: 'Microsoft Yahei', sans-serif; white-space: nowrap; display: flex; align-items: center; gap: 8px; `;
// 添加内部HTML内容
btn.innerHTML = `
<svg style="width:18px;height:18px;fill:white;" viewBox="0 0 24 24">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/>
</svg>
<span>使用指南</span>
`;
// 使用更可靠的事件监听方式
const handleHover = () => {
btn.style.transform = 'translateY(-50%) scale(1.05)';
btn.style.boxShadow = '0 6px 16px rgba(255,77,175,0.4)';
};
const handleLeave = () => {
btn.style.transform = 'translateY(-50%) scale(1)';
btn.style.boxShadow = '0 4px 12px rgba(255,77,175,0.3)';
};
btn.addEventListener('mouseenter', handleHover);
btn.addEventListener('mouseleave', handleLeave);
btn.addEventListener('click', showGuideDialog);
//document.body.appendChild(btn);
return btn;
};
// 显示操作指南弹窗
const showGuideDialog = () => {
if (Swal) {
Swal.fire({title: `<span style="color: #FF4DAF; font-size:26px; display: flex; align-items: center; gap:8px;">📚 智能刷课指南 <div style="font-size:12px; color:#95a5a6; margin-left:auto;">v${GM_info.script.version}</div></span>`, html: ` <div style="text-align: left; max-width: 720px; line-height: 1.8;"> <!-- 操作步骤 --> <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; margin-bottom: 20px;"><div style="color: blue; font-weight:800; margin-bottom:10px;"> 需要更高自动化?批量学习多个账号?已有成熟软件,详见:<a target="_blank" href="${web_url}?webId=${web_id}">${web_url}?webId=${web_id} </a> </div> <div style="color: red; font-weight:500; margin-bottom:10px;"> 播放页面未正常生效请刷新页面!播放页面左侧无红色按钮请刷新页面! </div> <div style="color: #2c3e50; font-weight:500; margin-bottom:10px;"> 🚀 极速操作流程<br> </div> <div style="display: grid; grid-template-columns: 32px 1fr; gap: 10px; align-items: center;"> <div style="background: #FF4DAF; color: white; width:24px; height:24px; border-radius:50%; text-align:center; line-height:24px;">1</div> <div>进入2025研修课程播放页面 / 课程目录页面</div> <div style="background: #FF4DAF; color: white; width:24px; height:24px; border-radius:50%; text-align:center; line-height:24px;">2</div> <div>直接点击相应按钮,等待操作完成后,刷新页面</div> <div style="background: #FF4DAF; color: white; width:24px; height:24px; border-radius:50%; text-align:center; line-height:24px;">3</div> <div><span style="color:#FF4DAF; font-weight:bold">诶个点击视频,看完最后几秒,安全保留日志信息</span></div> </div> </div> <!-- 注意事项 --> <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-bottom:20px;"> <div style="border-left: 3px solid #FF4DAF; padding-left:12px;"> <div style="color: #e74c3c; font-weight:500; margin-bottom:8px;">⚠️ 重要提醒</div> <ul style="margin:0; padding-left:18px; color:#7f8c8d; font-size:14px;"> <li>视频最后剩下5秒需要看完</li> <li>刷课时勿播放视频</li> <li>建议刷完全部视频再刷新,观看最后的几秒</li> </ul> </div> <div style="border-left: 3px solid #27ae60; padding-left:12px;"> <div style="color: #27ae60; font-weight:500; margin-bottom:8px;">💡 高效技巧</div> <ul style="margin:0; padding-left:18px; color:#7f8c8d; font-size:14px;"> <li>中小学,在目录或播放页。点击按钮直接开刷</li> <li>职业/高等,挂机即可,可最小化浏览器</li> </ul> </div> </div> ${renderQQGroups()} </div> `,
confirmButtonText: "已了解,开始减负之旅 →",
confirmButtonColor: "#FF4DAF",
showCancelButton: true,
cancelButtonText: "不在显示此窗口",
cancelButtonColor: "#95a5a6",
width: 760,
customClass: {
popup: 'animated pulse', title: 'swal-title-custom'
},
footer: '<div style="color:#bdc3c7; font-size:12px;">请合理使用本工具</div>'
}).then((result) => {
// console.log(result);
// console.log(Swal.DismissReason.cancel);
if (result.dismiss === Swal.DismissReason.cancel) {
// 跳转到课程列表页或其他操作
localStorage.setItem('noMoreDialog', "ture")
}
});
}
}
// 初始化逻辑
// 初始化逻辑优化
const init = () => {
// 创建悬浮按钮
const floatBtn = createFloatingButton();
// 添加防DOM清理监听(优化版)
const observer = new MutationObserver(mutations => {
if (!document.body.contains(floatBtn)) {
createFloatingButton();
}
});
observer.observe(document.body, {childList: true});
// 添加CSS保护
const style = document.createElement('style');
style.textContent = ` #zs-helper-btn { pointer-events: auto !important; opacity: 1 !important; visibility: visible !important; } #zs-helper-btn:hover { transform: translateY(-50%) scale(1.05) !important; } `;
document.head.appendChild(style);
};
function getVideoTime() {
return Math.round(document.querySelector('video').duration)
}
function getResourceIdFromFullData() {
if (!fullDatas || fullDatas.nodes?.length === 0) {
throw Error("can't get fullDatas!")
}
const result = [];
// 递归遍历节点
const traverse = (node) => {
if (node.node_type === 'catalog' && node.child_nodes?.length > 0) {
// 如果是目录节点,继续遍历子节点
node.child_nodes.forEach(child => traverse(child));
} else if (node.node_type === 'activity') {
// 如果是活动节点,提取资源
const resources = node.relations?.activity?.activity_resources || [];
resources.forEach(resource => {
result.push({
name: node.node_name || '未命名课程',
resource_id: resource.resource_id || '',
studyTime: resource.study_time
});
});
}
};
// 遍历初始节点数组
fullDatas.nodes.forEach(node => traverse(node));
return result.filter(item => item.resource_id); // 过滤无效项
}
function getDynamicToken() {
try {
const pattern = /^ND_UC_AUTH-([0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12})&ncet-xedu&token$/;
for (let key of Object.keys(localStorage)) {
if (pattern.test(key)) {
return {
key: key,
appId: key.match(pattern)[1],
token: JSON.parse(JSON.parse(localStorage.getItem(key)).value)
};
}
}
throw Error("Invalid token! can not get loginInfo!");
} catch (err) {
throw Error("At:getDynamicToken>>" + err);
}
}
const getMACAuthorizationHeaders = function (url, method) {
let n = getDynamicToken().token
return He(url, method, {
accessToken: n.access_token, macKey: n.mac_key, diff: n.diff
});
}
function Ze(e) {
for (var t = "0123456789ABCDEFGHIJKLMNOPQRTUVWXZYS".split(""), n = "", r = 0; r < e; r++) n += t[Math.ceil(35 * Math.random())];
return n
}
function Fe(e) {
return (new Date).getTime() + parseInt(e, 10) + ":" + Ze(8)
}
function ze(e, t, n, r) {
let o = {
relative: new URL(e).pathname, authority: new URL(e).hostname
}
let i = t + "\n" + n.toUpperCase() + "\n" + o.relative + "\n" + o.authority + "\n";
return CryptoJS.HmacSHA256(i, r).toString(CryptoJS.enc.Base64)
}
function He(e) {
let t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "GET",
n = arguments.length > 2 ? arguments[2] : void 0, r = n.accessToken, o = n.macKey, i = n.diff,
s = Fe(i), a = ze(e, s, t, o);
return 'MAC id="'.concat(r, '",nonce="').concat(s, '",mac="').concat(a, '"')
}
const setProgress = function (url, duration) {
const info = getDynamicToken()
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
'url': url,
method: 'PUT',
"headers": {"accept": "application/json, text/plain, */*",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"authorization": getMACAuthorizationHeaders(url, 'PUT'),
"cache-control": "no-cache",
"pragma": "no-cache",
"content-type": "application/json",
"sdp-app-id": info.appId,
"sec-ch-ua": "\"Not A(Brand\";v=\"8\", \"Chromium\";v=\"132\", \"Microsoft Edge\";v=\"132\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "cross-site",
"host": "x-study-record-api.ykt.eduyun.cn",
"origin": "https://basic.smartedu.cn",
"referer": "https://basic.smartedu.cn/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0"},
data: JSON.stringify({position: duration - 3}), // fetch:true,
onload: function (res) {
//console.log('请求成功',url)
if (res.status === 200) {
console.log(res.finalUrl,"刷课成功!")
resolve(res)
} else {
reject('服务器拒绝:' + res.response)
}
}, onerror: function (err) {
reject('请求错误!' + err.toString())
}})})}// end setProgress
function main() {
init()
if (!localStorage.getItem("noMoreDialog")) {
showGuideDialog()
}
let myStyle = document.createElement('style')
myStyle.innerHTML = style;
document.head.appendChild(myStyle);
let div = document.createElement('div');
div.innerHTML = `<div style="left: 10px;top: 280px;" id="my1" class="button-3" >即刻开刷(中小学)</div>
<div style="position: fixed; left: 10px;top: 320px;;background: #ed5822;color: white; padding: 10px 20px; border-radius: 25px; cursor: pointer; box-shadow: 0 3px 15px rgba(0,0,0,0.2); z-index: 999999999999; transition: transform 0.3s;" id="my3" >职业教育/高等教育 刷课</div>
<div style="left: 10px;top: 370px;" id="my2" class="button-3" >2222</div>`
document.body.appendChild(div);
const trigger = document.getElementById('my3')
trigger.addEventListener('click', () => {
if (location.href.includes("core.teacher.vocational.smartedu.cn")) {
createControlPanel()
} else {
Swal.fire({
title: "注意",
text: "请在职业/高等教育的视频播放页面使用,中小学请用上面的按钮!",
icon: 'info', // showCancelButton: true,
confirmButtonColor: "#FF4DAFFF", // cancelButtonText: "取消,等会刷新",
confirmButtonText: "了解~",
})}});
trigger.addEventListener('mouseenter', () => trigger.style.transform = 'scale(1.05)');
trigger.addEventListener('mouseleave', () => trigger.style.transform = 'none');
let isProcessing = false;
const button = document.getElementById('my1');
button.addEventListener("click", async () => {
if (isProcessing) {
Swal.fire({title: "操作进行中", text: "正在刷课中,请勿重复点击!", icon: "warning", confirmButtonColor: "#FF4DAFFF", confirmButtonText: "知道了"});
return;
}
try {
isProcessing = true; // 标记开始处理
button.disabled = true; // 禁用按钮
button.textContent = "刷课进行中..."; // 修改按钮文字
let resId
const allResults = [];
if (!resId) {
console.log("二次获取resId...")
resId = getResourceIdFromFullData()
}
if (resId && typeof resId === 'string') {
// 单个视频
await setProgress(requestObj.resourceLearningPositions.url + resId + '/' + getDynamicToken().token["user_id"], getVideoTime())
allResults.push({name: '单个课程', status: 'success'});
} else if (Array.isArray(resId) && resId.length > 0) {
// 多个视频 使用 Promise.allSettled 并行处理每个视频的进度更新 即使有处理失败,其他视频仍能继续
const pLimit=require('p-limit');
const limit=pLimit(9);
const results = await Promise.allSettled(resId.map(item => limit(async()=>{
try {
await setProgress(requestObj.resourceLearningPositions.url + item.resource_id + '/' + getDynamicToken().token["user_id"], item.studyTime)
return {name: item.name, status: 'success'};
} catch (e) {
console.error(`${item.name} 失败!`, e);
return {name: item.name, status: 'fail', error: e};
}
})
));
console.log(results)
results.forEach(r => {
if (r.status === 'fulfilled') allResults.push(r.value); else allResults.push(r.reason); // 捕获未处理的意外错误
});
}
if (Swal) {
Swal.fire({
title: "刷课成功!", html: ` <div style="text-align: left; max-height: 20vh; overflow-y: auto;"> <p>总计:${allResults.filter(r => r.status === 'success').length} 成功 / ${allResults.filter(r => r.status === 'fail').length} 失败</p> <hr> <ul style="padding-left: 20px; list-style-type: none;"> ${allResults.map(result => ` <li> ${result.status === 'success' ? '✅' : '❌'} <strong>${result.name}</strong> ${result.error ? `<br><code style="color:red">${result.error.message || result.error}</code>` : ''} </li> `).join('')} </ul> </div> <div style="text-align: left;"> <p>视频只剩下最后5s,需要看完,请刷新后再观看!</p> `, icon: 'success', confirmButtonColor: "#FF4DAFFF", // cancelButtonText: "取消,等会刷新",
confirmButtonText: "确定",
})
}
} catch (e) {
console.error(e)
if (Swal) {
Swal.fire({
title: "失败!",
text: e.toString() + " 请在视频播放页面使用!",
icon: 'error', // showCancelButton: true,
confirmButtonColor: "#FF4DAFFF", // cancelButtonText: "取消,等会刷新",
confirmButtonText: "点击去反馈",
}).then((result) => {
if (result.isConfirmed) {
window.open("https://greasyfork.org/zh-CN/scripts/525037/feedback")
}
});
}
} finally {
isProcessing = false; // 重置处理状态
button.disabled = false; // 恢复按钮
button.textContent = "即刻开刷(中小学)"; // 恢复按钮文字
}})
document.getElementById('my2').addEventListener('click', function () {
Swal.fire({title: '<span style="font-size:24px; color: #FF4DAF;">欢迎加入交流群</span>', html: ` <div style="text-align: left; max-width: 580px; line-height: 1.7; font-size: 14px;"> <!-- 社群入口 --> ${renderQQGroups()} <!-- 核心价值 --> <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px;"> <!-- 左列 --> <div style="padding-right:15px; border-right:1px dashed #eee;"> <div style="color: #27ae60; margin-bottom:15px;"> <h4 style="margin:0 0 8px 0; font-size:15px;">📚 减负工具</h4> <!-- <ul style="margin:0; padding-left:18px;">--> <!-- <li>自动化备课工具套件</li>--> <!-- <li>智能学情分析报告</li>--> <!-- <li>教学资源智能检索</li>--> <!-- </ul>--> </div> <div style="color: #2980b9; margin-top:15px;"> <h4 style="margin:0 0 8px 0; font-size:15px;">🛡️ 使用规范</h4> <ul style="margin:0; padding-left:18px;"> <li>仅限个人使用</li> <li>禁止商业倒卖行为</li> <li>禁止利用此脚本收费代刷</li> <li>请勿批量自动化操作大量刷课(如需要请联系我,更加高效安全)</li> </ul> </div> </div> <!-- 右列 --> <div style="padding-left:15px;"> <div style="color: #e67e22;"> <h4 style="margin:0 0 8px 0; font-size:15px;">⚖️ 版权声明</h4> <ul style="margin:0; padding-left:18px;"> <li>本工具完全免费</li> <li>源码禁止二次传播</li> <!-- <li>保留原创法律权利</li>--> </ul> </div> <div style="color: #9b59b6; margin-top:15px;"> <h4 style="margin:0 0 8px 0; font-size:15px;">💌 联系我们</h4> <ul style="margin:0; padding-left:18px;"> <!-- <li>反馈建议:edu@service.com</li>--> <li>紧急问题:请私聊群管理员</li> </ul> </div> </div> </div> </div> `,
icon: 'info',
confirmButtonColor: "#FF4DAF",
confirmButtonText: "2222",
showCloseButton: true,
width: 680,
showDenyButton: true,
denyButtonText: '<img src="https://img.icons8.com/fluency/24/star--v1.png" style="height:18px; vertical-align:middle;"> 前往好评', // 带图标的按钮
denyButtonColor: '#FFC107',
focusDeny: false,
showCancelButton: false,
// 新增按钮回调
preDeny: () => {
window.open("https://scriptcat.org/zh-CN/script-show-page/2789/comment", "_blank");
return false; // 阻止弹窗关闭
},
customClass: {
denyButton: 'swal-custom-deny', popup: 'swal-custom-popup', title: 'swal-custom-title'
},
footer: '<div style="color:#95a5a6; font-size:12px;">请合理使用。</div>'
});});
document.getElementById('my2').style.display = 'none'; // 隐藏按钮
document.getElementById('my3').style.display = 'none'; // 隐藏按钮
}
main()
console.log('智慧教育平台 模块启动!');
}
}
new ScriptCore()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment