您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
2021/4/10下午4:02:51
// ==UserScript== // @name 刷课辅助 // @namespace // @match *://course.sceouc.cn/CourseStudy.ashx* // @grant none // @version 0.3 // @author - // @description 2021/4/10下午4:02:51 // @run-at document-start // @namespace // @namespace // ==/UserScript== const hackAddEvent = () => { const _addEvent = window.addEventListener; const myHackEvent = (ename, evt, opt) => { const blackList = ['blur', 'keydown']; // 拦截的事件名称列表 if (typeof opt !== 'object' || typeof opt !== 'boolean') { // 第三个参数如果不传就给个默认 opt = { capture: false, once: false, passive: false }; } if (typeof evt !== 'function') { return; } if (blackList.includes(ename)) { // 拦截事件 console.log(`已拦截${ename}事件`); return; } _addEvent(ename, evt, opt); // 调用原方法 }; window.addEventListener = myHackEvent; }; hackAddEvent(); document.onkeydown = null; // 加载vue文件 const loadVue = () => { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = '//lib.baomitu.com/vue/3.2.31/vue.global.prod.min.js'; script.onload = () => { resolve(); }; document.head.appendChild(script); }); }; const renderEl = pageData => { const template = ` <div id="c_video_ctrl"> 设置 <div class="wrapper"> <p> <strong>课程信息</strong> <div class="-wrapper-box"> <span>{{courseInfo.name}}</span><br> <span>共{{courseInfo.total}}节,当前第{{courseInfo.current}}节</span> </div> </p> <p> <strong>视频信息</strong> <div class="-wrapper-box" style="display: flex; align-items: center; justify-content: center;"> <span> <input class="input-box" type="number" min="10" :max="videoInfo.duration" step="10" v-model="videoInfo.myTime" /> / {{videoInfo.duration}} </span> <button type="button" v-if="videoInfo.duration" @click="startTask">刷课</button> </div> <div class="-wrapper-box" style="padding-top: 15px;"> <span>{{msg}}</span> </div> </p> </div> </div> `; const vueRoot = document.createElement('div'); // 创建根节点 vueRoot.id = '__vue-root'; document.body.appendChild(vueRoot); const app = Vue.createApp({ el: '#c_video_ctrl', template: template, data() { return { courseInfo: {}, // 课程信息 videoInfo: {}, // 视频信息 msg: '' }; }, methods: { getCourseInfo() { const { course, courseList } = this.pageData.courseInfo; if (!course) { return; } // 正则匹配《》中的内容 const reg = /《(.*)》/; const result = reg.exec(course.innerText); // 正则匹配query参数中的couid const queryReg = /id=(\d+)/; const courseId = queryReg.exec(course.href)[1]; let currentIndex = 0; const courses = Array.from(courseList).map((item, index) => { const { className } = item; if (className.includes('current')) currentIndex = index; const { href, innerText } = item.children[0]; const id = item.attributes.olid.value; return { name: innerText, url: href, id }; }); this.courseInfo = { name: result[1], url: course.href, id: courseId, current: currentIndex + 1, total: courses.length, courses }; console.log(this.courseInfo, 'this.courseInfo'); }, getVideoInfo() { if (typeof CKobject === 'undefined') return; const totalTime = CKobject._K_('totalTime'); if (!totalTime) return (this.msg = '未获取到时长信息,请确认是否在视频页面'); const duration = +totalTime.innerHTML; this.videoInfo = { duration, myTime: duration // 默认设置为最大时间 }; }, startTask() { if (!this.videoInfo.myTime) return (this.msg = '请输入刷课时间'); // debugger; if ( this.videoInfo.myTime > this.videoInfo.duration || this.videoInfo.myTime < 10 ) return (this.msg = '请输入正确的刷课时间,不能小于10'); this.msg = ''; this.sendData() .then(() => { this.msg = '刷课成功'; }) .catch(() => { this.msg = '刷课失败'; }); }, sendData() { return new Promise((resolve, reject) => { const couid = this.courseInfo.id; const olid = this.courseInfo.courses[this.courseInfo.current - 1].id; const studyTime = this.videoInfo.myTime; fetch( `/Ajax/StudentStudy.ashx?couid=${couid}&olid=${olid}&studyTime=${studyTime}&playTime=${ studyTime * 1000 }&totalTime=${this.videoInfo.duration * 1000}` ) .then(res => { resolve(res); }) .catch(err => { reject(err); }); }); }, init() { this.getCourseInfo(); this.getVideoInfo(); } }, mounted() { this.init(); } }); app.config.globalProperties.pageData = pageData; app.mount(vueRoot); }; const renderStyle = function () { const styles = ` #c_video_ctrl { width: 50px; height: 50px; border-radius: 10px; position: fixed; right: 50px; top: 20px; z-index: 999; text-align: center; line-height: 50px; font-size: 18px; color: #ff8864; border: 2px solid #ff8864; } #c_video_ctrl .wrapper { width: 400px; height: auto; border-radius: 10px; position: absolute; right: -2px; top: -2px; z-index: 1000; background: #eee; display: none; color: #000; padding-bottom: 30px; } #c_video_ctrl:hover .wrapper { display: block; } #c_video_ctrl .wrapper p { display: flex; height: max-content; padding: 10px 15px; margin: 0; flex-wrap: wrap; justify-content: space-around; } #c_video_ctrl .wrapper p strong { width: 100%; font-size: 18px; } #c_video_ctrl .wrapper p span { font-size: 16px; cursor: pointer; padding: 0 10px; color: #333; } #c_video_ctrl .wrapper p span:hover { color: #ff8864; } .-wrapper-box { line-height: 1.5em; width: 100%; } .input-box{ min-width: 60px; outline: 0; font-size: unset; } button { font-size: unset; background: blue; color: #fff; padding: 0 10px; height: 100%; border-radius: 6px; cursor: pointer; } `; const style = document.createElement('style'); style.innerHTML = styles; document.head.appendChild(style); }; const collectData = _ => { const pageData = {}; // 存储页面数据 return new Promise((resolve, reject) => { const courseList = document.querySelectorAll('.olitem'); // 课程列表 if (!courseList.length) { reject(); } const course = document.querySelector('.courseBox > a'); // 课程基本信息 pageData.courseInfo = { course, courseList }; resolve(pageData); }); }; const myLoad = () => { console.log(location.href); collectData() .then(pageData => { loadVue().then(() => { renderStyle(); renderEl(pageData); }); }) .catch(() => { console.log('没有在当前页面上找到课程列表'); }); }; window.addEventListener('load', myLoad);