// ==UserScript== // @name 国家中小学智慧教育平台助手 // @namespace github.com/hmjz100 // @version 0.8 // @description 《也许同类型中最好用?》系列 - 一个基于 JavaScript 的国家中小学智慧教育平台助手,支持免登录下载教材,美化顶栏,页脚增加一言,登录后还能增强预览! // @author hmjz100 // @match *://*.basic.smartedu.cn/* // @match *://*.zxx.edu.cn/* // @icon https://basic.smartedu.cn/favicon.ico // @license MIT // @grant GM_getResourceText // @grant GM.xmlHttpRequest // @connect v1.hitokoto.cn // @connect s-file-1.ykt.cbern.com.cn // @connect s-file-2.ykt.cbern.com.cn // @connect s-file-3.ykt.cbern.com.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('(改)B站成分检测器:主代码'); if (window[key]) return; window[key] = true; console.log("【国家中小学智慧教育平台助手】即时\n运行中…") addDownStyle(); // 默认收起侧栏 waitForKeyElements('[class^="index-module_collapse_"]', (element) => { element.click(); }, true) // 移除顶部客户端相关内容 waitForKeyElements('[class^="index-module_download"]', (element) => { element.remove() }, true) // 给顶栏增加个时钟 waitForKeyElements('[class^="index-module_menu-container_"]', (element) => { var timebar = $('
,现在是感谢您使用本脚本~
') if (element && element.length > 0) { element.after(timebar) window.setInterval(() => { timebar.find("#basicEduTime")[0].innerText = Time(); timebar.find("#basicEduGreeting")[0].innerText = Greeting(); }, 500); } }, true) // 给底栏增加个一言 waitForKeyElements('#zxxcontent', (element) => { var poembar = $('
') if (element && element.length > 0) { let text = poembar.find("#todayPoem") element.after(poembar) text.on('click', () => { if (text[0].innerText === "加载中……") return; text[0].innerText = "加载中……" text.css({ "cursor": "default" }); Poem(text) }) text[0].innerText = "加载中……" text.css({ "cursor": "default" }); Poem(text) } }, true) // 免登录下载 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], 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("iframe#pdfPlayerFirefox[src]", (element) => { let url = new URL(element[0].src); url.searchParams.set("file", item.url); element[0].src = url.toString(); let button = $('') element.parent().parent().css({ "border-radius": "8px" }) button.on('click', function () { let parent = element.parent().parent(); if (!parent.hasClass('fullscreen')) { // 进入全屏模式 parent.addClass('fullscreen').css({ "border-radius": "0" }); $('body').addClass('no-scroll'); button.text('退出全屏'); } else { // 退出全屏模式 parent.removeClass('fullscreen').css({ "border-radius": "8px" }); $('body').removeClass('no-scroll'); button.text('网页全屏'); } }); element.before(button) }) // 点击登录提示中隐藏的取消按钮 waitForKeyElements('button[type="button"].fish-btn[style]', async (element) => { element.click(); let dialog = await Swal.fire({ title: data.title, imageUrl: data.cover, imageHeight: 300, allowOutsideClick: false, showCloseButton: true, showDenyButton: true, confirmButtonText: '跳转', heightAuto: false, scrollbarPadding: false, denyButtonText: '关闭', html: `
点击“跳转”后将在新标签页打开PDF链接
部分浏览器支持点击按钮后支持直接预览教材
教材较大,如果支持预览请耐心等待加载完成
一般加载完成后会出现“下载”按钮
如果浏览器不支持预览,则会直接下载PDF
` }); if (dialog.isConfirmed) { window.open(data.url, "_blank") } }) } catch (error) { console.error('所有请求都失败了:', error); } } // 增强预览 if (/^\/pdfjs\/.*\/web\/viewer.html/.test(location.pathname)) { let url = new URL(location.href); let file = url.searchParams.get("file"); if (file) { let decodedFile = decodeURIComponent(file); let newFile = decodedFile.replace(/(r\d)-ndr-\w+/, '$1-ndr'); url.searchParams.set("file", newFile); window.location.replace(url.toString()); } // 取消隐藏预览PDF页面的隐藏功能(例如下载、打印等功能) waitForKeyElements('.visibleLargeView, .visibleMediumView, .visibleSmallView, .hiddenLargeView, .hiddenMediumView, .hiddenSmallView', function (element) { element.removeClass('visibleLargeView visibleMediumView visibleSmallView hiddenLargeView hiddenMediumView hiddenSmallView hidden'); if (element.attr('hidden') !== undefined) { element.removeAttr('hidden'); } if (element.attr('disabled') !== undefined) { element.removeAttr('disabled'); } }, true); } 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[0].innerText = `「${data.hitokoto}」${data.from_who || ""}`; element.css({ "cursor": "pointer" }); } catch (error) { // 处理错误情况 console.error('获取诗词时发生错误:', error); element[0].innerText = '诗词加载失败'; element.css({ "cursor": "pointer" }); } } function request(option) { return new Promise((resolve, reject) => { GM.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() { let color = "#1e62ec"; 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 = ` [class^="index-module_header-wrap_"] [class^="index-module_header"] .theme-menu-normal { /*height: 95px !important;*/ height: auto !important; } [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: rgba(255, 255, 255, 0.8); } #basicEduTime{ margin: 0 5px; color: ${color}; } .index-module_tip { cursor: default; text-align: center; display: inline-flex; justify-content: center; margin: 10px 0; width: 100%; } .index-module_tip img { margin-right: 5px; width: 20px; height: 20px; } .index-module_pdf-fullscreen { background: #1e62ecf0; position: absolute; text-align: center; color: #fff; top: 20px; right: 30px; padding: 8px 25px; border-radius: 144.889px; border: 0; } .index-module_pdf-fullscreen:hover { background: #4079eff0; } div .fullscreen { position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; z-index: 1000 !important; } .no-scroll { overflow: hidden !important; } `; // 先监听颜色方案变化 SweetAlert2-Default window.matchMedia('(prefers-color-scheme: dark)').addListener((e) => { if (e.matches) { // 切换到暗色主题 addStyle('swal-pub-style', 'style', GM_getResourceText('SwalDark')); } else { // 切换到浅色主题 addStyle('swal-pub-style', 'style', GM_getResourceText('Swal')); } addStyle('SweetAlert2-User', 'style', swalcss); }); // 再修改主题 SweetAlert2-Default if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { // 切换到暗色主题 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); } 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); }, 500); controlObj[controlKey] = timeControl; } } waitForKeyElements.controlObj = controlObj; } })();