// ==UserScript== // @name 国家智慧教育公共服务平台助手 // @namespace github.com/hmjz100 // @version 0.9 // @description 《也许同类型中最好用?》系列 - 一个基于 JavaScript 的国家智慧教育公共服务平台辅助工具,全平台顶栏美化毛玻璃(如果有),页脚增加一言诗句,增强并美化原有 PDFJS 预览工具,可网页全屏预览、下载 PDF 文件,国家中小学智慧教育平台支持免登录批量下载、预览教材 PDF 原件,显示隐藏黑暗模式 // @author hmjz100 // @match *://*.smartedu.cn/* // @match *://*.edu.cn/* // @match *://*.eduyun.cn/* // @icon data:image/webp;base64,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 // @license MIT // @grant GM_getResourceText // @grant GM_xmlHttpRequest // @grant GM.xmlHttpRequest // @connect smartedu.cn // @connect edu.cn // @connect eduyun.cn // @connect ykt.cbern.com.cn // @connect hitokoto.cn // @require https://unpkg.com/jquery@3.6.3/dist/jquery.min.js // @require https://unpkg.com/sweetalert2@11/dist/sweetalert2.all.min.js // @resource Swal https://unpkg.com/sweetalert2@11/dist/sweetalert2.min.css // @resource SwalDark https://unpkg.com/@sweetalert2/theme-dark@5.0.15/dark.min.css // ==/UserScript== (async function BasicEduDownload() { 'use strict'; /* 防止代码因其他原因被执行多次 这段代码出自 Via轻插件,作者谷花泰 */ let key = encodeURIComponent('国家中小学智慧教育平台助手:主代码'); if (window[key]) return; window[key] = true; console.log("【国家中小学智慧教育平台助手】即时\n运行中…") addDownStyle(); // 给顶栏加个时钟 let img_question = "data:image/png;base64,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" waitForKeyElements('[class^="index-module_menu-container_"]', (element) => { var timebar = $(`
,现在是感谢您使用本脚本~
`); if (location.host === 'basic.smartedu.cn') { timebar.append(``); timebar.find("#basicEduTheme").on('click', function () { let url = new URL(window.location); if (url.searchParams.get("x-edu-theme") === 'dark') { url.searchParams.delete('x-edu-theme'); } else { url.searchParams.set("x-edu-theme", "dark"); } $(this).remove(); location.href = url.toString(); }); // 默认收起侧栏 waitForKeyElements('[class^="index-module_collapse_"]', (element) => { element.click(); }, true) } if (element && element.length > 0) { element.after(timebar); window.setInterval(function () { timebar.find("#basicEduTime").text(Time()); timebar.find("#basicEduGreeting").text(Greeting()); }, 500); } }, true); // 移除顶部客户端相关内容 if (location.host !== 'www.smartedu.cn') waitForKeyElements('[class^="index-module_top-bar"], [class^="index-module_download"], #app div.bg-no-repeat div[class^="bg"], #app header.el-header.plang div.topLine1, div.header div.headbar', (element) => { element.remove() }, true) // 给底栏增加个一言 waitForKeyElements('.main-wrapper #main-content div.content', (element) => { var poembar = $(`
`) if (element && element.length > 0) { let text = poembar.find("#todayPoem") element.after(poembar) text.on('click', function () { if (text.text() === "加载中……") return; text.text("加载中……") text.css({ "cursor": "default" }); Poem(text) }) text.text("加载中……") text.css({ "cursor": "default" }); Poem(text) } }, true) // 教材选择页加个下载按钮 waitForKeyElements('li[class^="index-module_item"]', (element) => { if (!element.find('[class^="index-module_cover"] img[src]')[0]) return; let base = element.find('[class^="index-module_cover"] img[src]')[0].src.match(/r(\d)-ndr/)[1] let contentId = element.find('[class^="index-module_cover"] img[src]')[0].src.match(/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/i)[1] let data = { title: element.find('[class^="index-module_line"] span[title]')[0].title, url: `https://r${base}-ndr.ykt.cbern.com.cn/edu_product/esp/assets/${contentId}.pkg/pdf.pdf` } element.css({ "border-bottom": "none" }) let button = $(`
  • 下载
  • `) button.on('click', async function () { let element = $(this) let ins = {}; let progress = {}; let index = element.data('index'); element.prop('disabled', true); ins[index] = setInterval(function () { let prog = +progress[index] || 0; element.find('.text').text(prog + "%"); }, 10); try { let response = await fetch(data.url); if (!response.ok) throw new Error('网络响应失败'); let totalSize = response.headers.get('Content-Length') || 0; let reader = response.body.getReader(); let receivedLength = 0; let chunks = []; while (true) { const { done, value } = await reader.read(); if (done) break; chunks.push(value); receivedLength += value.length; progress[index] = Math.floor((receivedLength / totalSize) * 100); } let blob = new Blob(chunks); clearInterval(ins[index]); progress[index] = 100; element.find('.text').text("完成~"); // 下载文件 const downloadUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = downloadUrl; a.download = `${data.title}.pdf`; a.click(); URL.revokeObjectURL(downloadUrl); setTimeout(function () { element.find('.text').text("下载"); $(this).prop('disabled', false); }.bind(this), 3000); } catch (error) { clearInterval(ins[index]); console.error("下载失败:", error); element.find('.text').text("失败,重试?"); $(this).prop('disabled', false).one('click', async function () { $(this).trigger('click'); }); } }); element.after(button) // 使用 MutationObserver 监听 li 元素的删除 const observer = new MutationObserver((mutationsList) => { for (let mutation of mutationsList) { if (mutation.removedNodes.length > 0) { mutation.removedNodes.forEach((node) => { if (node === element[0]) { button.remove(); } }); } } }); observer.observe(element[0].parentNode, { childList: true }); // 清理 MutationObserver element.on('remove', () => { observer.disconnect(); }); }); // 若是教材详情页 let contentType = new URL(location.href).searchParams.get("contentType") || ''; let contentId = new URL(location.href).searchParams.get("contentId") || ''; if (/^\/tchMaterial\/detail/.test(location.pathname) && contentType === 'assets_document' && contentId) { try { // 教材信息 let data = await Promise.any(["1", "2", "3"].map(async base => { try { let data = await request({ url: `https://s-file-${base}.ykt.cbern.com.cn/zxx/ndrv2/resources/tch_material/details/${contentId}.json`, headers: { "referer": "https://basic.smartedu.cn/", 'Cache-Control': 'no-cache' } }); console.log(data) let item = { id: data.id, title: data.global_title['zh-CN'], cover: data.custom_properties?.thumbnails[0], author: data.provider_list[0]?.name, url: `https://r${base}-ndr.ykt.cbern.com.cn/edu_product/esp/assets/${contentId}.pkg/pdf.pdf`, }; return item } catch (error) { console.error('【国家中小学智慧教育平台助手】\n获取数据时发生错误:', error); } })); // 遇到默认弹窗 waitForKeyElements('div.fish-modal-content div.fish-modal-body div.fish-modal-confirm-body-wrapper', (elemlogin) => { if (!elemlogin.find('div.fish-modal-confirm-content').text().match("需要登录")) return; elemlogin.find('div.fish-modal-confirm-content').text("免登录加载中") waitForKeyElements('div[class^="index-module_special-edu-detail_"] div[class^="index-module_content-wrap_"] div[class^="index-module_wrapper_"]', (element) => { // 点击登录提示中隐藏的取消按钮 elemlogin.find('button[type="button"].fish-btn').filter(function () { return $(this).text().includes("取 消"); }).click(); // 既然不给页面内容,那就抄一个放上去吧 element.html(`

    ${data.title}

    ${data.author} 如果点“下载”按钮不能下载,请点击文件预览器底栏里的“下载”按钮
    感谢您使用本脚本~
    给个好评?
    `) }, true) }) } catch (error) { console.error('【国家中小学智慧教育平台助手】\n获取数据时发生错误:', error); } } // 遇到 PDF 预览器的 iframe waitForKeyElements("iframe[src*='/web/viewer.html']", (element) => { let parent = element.parent(); let button = $(`
    `) parent.css({ "border-radius": "8px", "border": "5px solid #232d2a", "background": "#232d2a" }) element.css({ "background": "#232d2a" }) let pdfWindow = element[0].contentWindow button.find('.index-module_pdf-refresh').on('click', function () { let element = $(this) element.find('.text').text('等待'); pdfWindow.location.reload(); pdfWindow.onload = element.find('.text').text('刷新'); }) button.find('.index-module_pdf-fullscreen').on('click', function () { let element = $(this) if (!parent.hasClass('fullscreen')) { // 进入全屏模式 $('body').addClass('no-scroll'); parent.addClass('fullscreen').css({ "border-radius": "0" }); element.html('退出全屏'); button.find('.index-module_pdf-refresh').fadeToggle(); button.find('.index-module_pdf-download').fadeToggle(); } else { // 退出全屏模式 $('body').removeClass('no-scroll'); parent.removeClass('fullscreen').css({ "border-radius": "8px" }); element.html('网页全屏'); button.find('.index-module_pdf-refresh').fadeToggle(); button.find('.index-module_pdf-download').fadeToggle(); } }); button.find('.index-module_pdf-download').on('click', async function () { let src = new URL(pdfWindow.location.href) let title = $("document").find('[class^="index-module_line"] span[title]').attr("title") || document.title let data = { title: title, url: src.searchParams.get("file") } let element = $(this) let ins = {}; let progress = {}; let index = element.data('index'); element.prop('disabled', true); ins[index] = setInterval(function () { let prog = +progress[index] || 0; element.find('.text').text(prog + "%"); }, 10); try { let response = await fetch(data.url); if (!response.ok) throw new Error('网络响应失败'); let totalSize = response.headers.get('Content-Length') || 0; let reader = response.body.getReader(); let receivedLength = 0; let chunks = []; while (true) { const { done, value } = await reader.read(); if (done) break; chunks.push(value); receivedLength += value.length; progress[index] = Math.floor((receivedLength / totalSize) * 100); } let blob = new Blob(chunks); clearInterval(ins[index]); progress[index] = 100; element.find('.text').text("完成~"); // 下载文件 const downloadUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = downloadUrl; a.download = `${data.title}.pdf`; a.click(); URL.revokeObjectURL(downloadUrl); setTimeout(function () { element.find('.text').text("下载"); $(this).prop('disabled', false); }.bind(this), 3000); } catch (error) { clearInterval(ins[index]); console.error("下载失败:", error); element.find('.text').text("失败,重试?"); $(this).prop('disabled', false).one('click', async function () { $(this).trigger('click'); }); } }); element.before(button) }) // 预览页面增强 if (/^\/pdfjs\/.*\/web\/viewer.html/.test(location.pathname) || /^\/web\/viewer.html/.test(location.pathname)) { let file = new URL(location.href).searchParams.get("file"); if (file) { let noPrivateFile = file.replace(/(r\d)-ndr-\w+/, '$1-ndr'); let url = new URL(`${location.origin}${location.pathname}?file=${noPrivateFile}&disableAutoFetch=true&page=1`).toString() if (url !== location.href) location.replace(url); } $('html').css({ "background-color": "#232d2a", "--body-bg-color": "#232d2a", "--toolbar-bg-color": "#2a3632", "--sidebar-toolbar-bg-color": "#2a3632", "--doorhanger-border-color": "#232d2a", "--doorhanger-bg-color": "#2a3632", "--dropdown-btn-bg-color": "#232d2a", "--button-hover-color": "#32403b", "--doorhanger-hover-bg-color": "#32403b", "--overlay-button-bg-color": "#232d2a", "--overlay-button-hover-bg-color": "#32403b", "--field-bg-color": "#232d2a", "--field-border-color": "#32403b", }) $('#loadingBar').css({ "height": "10px", "top": "-10px" }) $('#loadingBar .progress').css({ "border-radius": "50px" }) $('#toolbarViewerMiddle').attr('id', 'toolbarViewerLeft'); $('#viewerContainer').css({ "background-color": "#232d2a" }) $('#sidebarContent').css({ "background-color": "#2a3632" }) // 取消隐藏预览PDF页面的隐藏功能(例如下载、打印等功能) waitForKeyElements('button[hidden]', function (element) { if (element.attr('hidden') !== undefined) { element.removeAttr('hidden'); } }); } var toast = Swal.mixin({ toast: true, position: 'bottom-end', showConfirmButton: false, timer: 3500, timerProgressBar: true, showCloseButton: true, didOpen: (toast) => { toast.addEventListener('mouseenter', Swal.stopTimer); toast.addEventListener('mouseleave', Swal.resumeTimer); } }); var message = { success: function (text) { toast.fire({ html: text, icon: 'success' }); }, error: function (text) { toast.fire({ html: text, icon: 'error' }); }, warning: function (text) { toast.fire({ html: text, icon: 'warning' }); }, info: function (text) { toast.fire({ html: text, icon: 'info' }); }, question: function (text) { toast.fire({ html: text, icon: 'question' }); } }; function Time() { function repair(i) { if (i >= 0 && i <= 9) { return "0" + i; } else { return i; } } var date = new Date(); var year = date.getFullYear(); var month = repair(date.getMonth() + 1); var day = repair(date.getDate()); var hours = repair(date.getHours()); var minute = repair(date.getMinutes()); var second = repair(date.getSeconds()); var curTime = year + "年 - " + month + "月 - " + day + "日 " + hours + "时 : " + minute + "分 : " + second + "秒"; return curTime; } function Greeting() { var date = new Date(); var hour = date.getHours(); var greeting = ''; if (hour >= 0 && hour <= 10) { greeting = '早上好'; } else if (hour > 10 && hour <= 14) { greeting = '中午好'; } else if (hour > 14 && hour <= 18) { greeting = '下午好'; } else if (hour > 18 && hour <= 24) { greeting = '晚上好'; } return greeting; } async function Poem(element) { try { let data = await request({ data: "", url: "https://v1.hitokoto.cn/?c=i", headers: { "referer": "https://hitokoto.cn", 'Cache-Control': 'no-cache' } }) // 使用数据更新页面元素 element.text(`「${data.hitokoto}」${data.from_who || ""}`); element.css({ "cursor": "pointer" }); } catch (error) { // 处理错误情况 console.error('获取诗词时发生错误:', error); element.text('诗词加载失败'); element.css({ "cursor": "pointer" }); } } function request(option) { return new Promise((resolve, reject) => { let xmlHttpRequest = typeof GM_xmlhttpRequest !== "undefined" ? GM_xmlhttpRequest : GM.xmlHttpRequest; xmlHttpRequest({ method: 'get', ...option, onload: (response) => { let res = JSON.parse(response.responseText); resolve(res); }, onerror: (error) => { reject(error); }, }); }); } function addStyle(id, tag, css) { tag = tag || 'style'; let doc = document, styleDom = doc.getElementById(id); if (styleDom) styleDom.remove(); let style = doc.createElement(tag); style.rel = 'stylesheet'; style.id = id; tag === 'style' ? style.innerHTML = css : style.href = css; doc.getElementsByTagName('body')[0].appendChild(style); } function addDownStyle() { const url = new URL(window.location); let color = url.searchParams.get("x-edu-theme") === 'dark' ? "#0e9aff" : "#1e62ec"; let hvColor = url.searchParams.get("x-edu-theme") === 'dark' ? "#1e62ec" : "#4079ef"; let bgColor = url.searchParams.get("x-edu-theme") === 'dark' ? "rgba(42, 54, 50, 0.5)" : "rgba(255, 255, 255, 0.5)"; let spColor = url.searchParams.get("x-edu-theme") === 'dark' ? "#323e3a" : "#eee"; let swalcss = ` .swal2-loader{display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:${color} transparent ${color} transparent } .swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:${color};color:#fff;font-size:1em} .swal2-styled.swal2-confirm:focus{box-shadow:0 0 0 3px ${color}80 } .swal2-timer-progress-bar{width:100%;height:.25em;background:${color}33 } .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:${color};color:#fff;line-height:2em;text-align:center} .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:${color} } .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:${color}} ` let css = ` *:hover { transition: all 0.3s !important; -webkit-transition: all 0.3s !important; } [class^="index-module_header-wrap_"], [class^="index-module_header"] { height: auto !important; } [class^="index-module_header"] [class^="index-module_nav-normal"], [class^="index-module_header-wrap_"] [class^="index-module_header"] .theme-menu-sticky { height: auto !important; -webkit-backdrop-filter: blur(15px); backdrop-filter: blur(15px); background-color: ${bgColor}; } #basicEduTime{ margin: 0 5px; color: ${color}; } .index-module_tip { cursor: default; text-align: center; display: inline-flex; justify-content: center; align-items: center; margin: 10px 0; width: 100%; } .index-module_tip img, .index-module_tip svg { margin: 0 5px; width: 20px; height: 20px; } .index-module_tip svg { color: ${color}; cursor: pointer; } .index-module_tip svg:hover { color: ${hvColor}; } .index-module_pdf-control { display: flex; justify-content: center; position: absolute; top: 5%; right: 3%; pointer-events: none; width: auto !important; height: auto !important; } .index-module_pdf-button { background-color: ${color}cc; text-align: center; color: #fff; padding: 8px 25px; border-radius: 144.889px; border: 0; margin-left: 10px; display: inline-flex; vertical-align: middle; pointer-events: all; } .index-module_pdf-button:hover,.index-module_pdf-button:disabled { background-color: ${hvColor}cc; } .index-module_pdf-button svg { height: 18px; width: 18px; margin-right: 4px; vertical-align: middle; } .index-module_item { cursor: pointer; font-size: 15px; -webkit-user-select: none; -ms-user-select: none; user-select: none; vertical-align: middle; display: flex; align-items: center; padding: 5px 0; justify-content: center; border-bottom: 1px solid ${spColor}; } .index-module_item svg { height: 20px; width: 20px; margin-right: 4px; vertical-align: middle; } .index-module_item:hover { color: #fff; background-color: ${hvColor}; } div .fullscreen { position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; z-index: 99999 !important; } ::-webkit-scrollbar { width: 10px; background-color: #2a3632; } ::-webkit-scrollbar-thumb { background: ${color}; border-radius: 10px } ::-webkit-scrollbar-thumb:hover { background: ${hvColor}; } .no-scroll { overflow: hidden !important; } `; const colorSchemeListener = (e) => { switchTheme(e.matches); }; const switchTheme = (isDark) => { if (isDark) { // 切换到暗色主题 addStyle('swal-pub-style', 'style', GM_getResourceText('SwalDark')); } else { // 切换到浅色主题 addStyle('swal-pub-style', 'style', GM_getResourceText('Swal')); } addStyle('SweetAlert2-User', 'style', swalcss); addStyle('BasicSmartEdu-User', 'style', css); }; // 添加监听器 const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); darkModeMediaQuery.addListener(colorSchemeListener); // 根据当前颜色方案设置主题 switchTheme(darkModeMediaQuery.matches); } function waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector) { var targetbadges, btargetsFound; if (typeof iframeSelector == "undefined") targetbadges = $(selectorTxt); else targetbadges = $(iframeSelector).contents().find(selectorTxt); if (targetbadges && targetbadges.length > 0) { btargetsFound = true; targetbadges.each(function () { var jThis = $(this); var alreadyFound = jThis.data('alreadyFound') || false; if (!alreadyFound) { var cancelFound = actionFunction(jThis); if (cancelFound) { btargetsFound = false; } else { jThis.data('alreadyFound', true); } } }); } else { btargetsFound = false; } var controlObj = waitForKeyElements.controlObj || {}; var controlKey = selectorTxt.replace(/[^\w]/g, "_"); var timeControl = controlObj[controlKey]; if (btargetsFound && bWaitOnce && timeControl) { clearInterval(timeControl); delete controlObj[controlKey]; } else { if (!timeControl) { timeControl = setInterval(function () { waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector); }, 1000); controlObj[controlKey] = timeControl; } } waitForKeyElements.controlObj = controlObj; } $("head").before($(` `)) })();