// ==UserScript== // @name 上海开大助手 // @namespace http://tampermonkey.net/ // @homepage https://shkd.script.woca.fun // @description 上海开放大学学习平台,自动刷课,题目共享,接入deepseek一键搜题 // @author AchieveHF // @version 1.1.8 // @match *://shkd.script.woca.fun/* // @match *://*.shou.org.cn/* // @match *://live.eeo.cn/* // @icon https://www.google.com/s2/favicons?sz=64&domain=shou.org.cn // @grant GM_setValue // @grant GM_getValue // @require https://code.jquery.com/jquery-3.6.0.min.js // @require https://unpkg.com/layui@2.9.20/dist/layui.js // @license MIT // @run-at document-idle // @downloadURL none // ==/UserScript== (function () { 'use strict'; // 获取当前脚本版本号 const scriptVersion = GM_info.script.version; // 将版本号保存到localStorage中供官网使用 localStorage.setItem('shkd_script_version', scriptVersion); const link = parseURLDetails(); const css = document.createElement('link'); css.rel = 'stylesheet'; css.href = '//shkd.script.woca.fun/static/layui/css/layui.css'; document.head.appendChild(css); const apiDomain = 'https://shkd.script.woca.fun/'; // DeepSeek 设置弹窗函数 function showDeepSeekSettings() { // 获取当前保存的 API Key const apiKey = GM_getValue('deepseekApiKey', ''); layer.open({ type: 1, title: 'DeepSeek API 设置', area: ['50%', '50%'], content: `
充值建议
首先声明deepseek开放平台与本插件无任何利益关系,亲测做完一学期题目仅消耗0.05元,建议deepseek接口充值1元就行,足够用到毕业
隐私声明
本插件不会收集或存储您的 API Key,数据仅保存在您的浏览器本地。请放心使用。
`, success: function (layero, index) { // 保存设置按钮点击事件 $('#saveDeepseekSettings').on('click', function () { const newApiKey = $('#deepseekApiKey').val().trim(); GM_setValue('deepseekApiKey', newApiKey); layer.msg('设置已保存'); layer.close(index); }); } }); } if (link.domain == 'live.eeo.cn') { setTimeout(() => { //第三方回放页面 $('#player_html5_api')[0].muted = true; $('#player_html5_api')[0].play() return; }, 3000) } if (link.domain == 'ldoc.shou.org.cn' && link.path.startsWith('/doc') && link.path.endsWith('index.html')) { setTimeout(() => { window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); }, 5000); } switch (link.path) { case '/study/assignment/continuation.aspx': case '/study/assignment/preview.aspx': let showAnswer = true; //添加设置按钮 $('.e-q-panel').first().before(`
`); //做作业页面 //收集题目 getQuestions(); $('body').on('click', '.deepseekSettingBtn', function () { showDeepSeekSettings(); }); $('body').on('click', '.deepseekQuestion', function () { const questiontext = $(this).closest('.e-q-body').find('.e-q-quest').first().text().replace(/\s+/g, ' ').trim(); if (questiontext == '') { layer.msg('暂时未适配此题型'); $(this).parent().remove(); return; } //大题情况要携带题干 const prompt = `我给你传题目内容,你给我返回正确的答案,尽量通过我发给你的题目内容中的选项来回答,我通过你返回的答案来回选正确答案,不需要解释题目,直接发给我答案,任何解释都不要,只要返回答案,答案从题目的选项中提取,如果是大题回答的答案每题用换行标签'
'隔开,题目为:【${questiontext}】` const apiKey = GM_getValue('deepseekApiKey', ''); if (!apiKey) { layer.msg('请先设置 DeepSeek API Key'); showDeepSeekSettings(); return; } $(this).html(` 思考中... `); $.ajax({ url: 'https://api.deepseek.com/v1/chat/completions', type: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, data: JSON.stringify({ model: "deepseek-chat", messages: [{ role: "user", content: prompt }], temperature: 0.1, max_tokens: 1000 }), success: (res) => { console.log(res); const answer = res.choices[0].message.content.trim(); $(this).closest('.e-q-body').find('.e-q-r').append(`
参考答案:
${answer}
`); //todo:记录deepseek返回的答案 //清除按钮 $(this).closest('.e-q-body').find('.deepseekQuestion').remove(); }, error: (err) => { showDeepSeekSettings(); //恢复答题按钮 $(this).html(` deepseek回答 `); layer.msg('DeepSeek API 调用失败: ' + (err.responseJSON && err.responseJSON.error && err.responseJSON.error.message || err.statusText)); } }); }); break; case '/activity-middle/PlaybackX': case '/activity-middle/Playback': setTimeout(() => { $('#myplayer_html5_api')[0].muted = true $('#myplayer_html5_api')[0].play() }, 5000) break; case '/study/activity-classInVideo.aspx': setTimeout(() => { window.open($('#classIn')[0].src, '_blank', 'width=800,height=600') window.close(); }, 5000) break; case '/study/play.aspx': setTimeout(() => { $('#video')[0].muted = true $('#video')[0].play() }, 5000) break; case '/study/activity-preview.aspx': if (link.params.auto !== undefined) { window.location.href = $('.am-btn.am-btn-success.am-btn-default').attr('href') } break; case '/study/directory.aspx': //观看课程页面 const mustCourse = GM_getValue('mustCourse', {}) setTimeout(() => { if (mustCourse[link.params.CourseOpenId] != undefined) { $('.bd .sh-cw-bd').prepend(`
上海开大助手
1
`) } else { //没有找到必看 console.log(mustCourse) } }, 2000) setTimeout(() => { if (GM_getValue('autoPlay')) { autoPlayStart() } }, 5000) //
// //
  • 必看课程
  • $('body').on('click', '#autoPlay', function () { GM_setValue('autoPlay', GM_getValue('autoPlay') ? false : true) if (GM_getValue('autoPlay')) { $(this).removeClass('layui-bg-blue').addClass('layui-bg-red') autoPlayStart() } else { $(this).removeClass('layui-bg-red').addClass('layui-bg-blue') } $(this).text('点击' + (GM_getValue('autoPlay') ? '关闭' : '开启') + '自动刷课') }) break; case '/scenter': //学习空间首页 const liveCourse = {}; //获取课程列表 const courseList = []; // 保存原生的 XMLHttpRequest.open 方法 var originalXHROpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function (method, url, ...args) { this.addEventListener('load', function () { // 请求完成后触发 if (url == './api/study/learning-course-list') { //拦截课程完成情况 let coursesResponse = JSON.parse(this.responseText) //提取所有未完成的直播课 if (coursesResponse.code == 200 && coursesResponse.result.length > 0) { coursesResponse.result.forEach((item) => { if (item.activityProgress && item.activityProgress.progress) { item.activityProgress.progress.forEach((v) => { if (new Date() > new Date(v.endTime)) { v.courseId = item.activityProgress.courseOpenId if (liveCourse[item.activityProgress.courseOpenId] != undefined) { liveCourse[item.activityProgress.courseOpenId].push(v) } else { liveCourse[item.activityProgress.courseOpenId] = [v]; } } }) } courseList.push({ courseOpenId: item.courseOpenId, courseName: item.courseName }) }) } } }); // 调用原始的 open 方法 return originalXHROpen.call(this, method, url, ...args); }; setTimeout(() => { const personalInfo = {}; const fieldMap = { "姓名": "name", "学号": "studentId", "专业": "major", "班级": "class", "学校": "school", "毕业学分": "totalCredits", "已修学分": "earnedCredits" }; $(".info-area p").each(function () { const label = $(this).find(".info-label").text().replace(":", "").trim(); const value = $(this).text().replace($(this).find(".info-label").text(), "").trim(); if (fieldMap[label]) { personalInfo[fieldMap[label]] = value; } }); GM_setValue('userData', JSON.stringify(personalInfo)) $.ajax({ url: apiDomain + '/api/getBody', type: 'POST', data: { path: link.path, user: personalInfo, courses: courseList }, success: function (data) { $('.content-left').append(data) } }) }, 5000) $('body').on('click', '#openLiveCourse', function () { GM_setValue('waitCourse', {}) layer.confirm('先点击【查找】检测未完成的直播课
    点击后会弹出一些弹窗,不需要进行任何操作
    查找成功后点击【一键打开直播课】,点击后不需要进行任何操作会自动播放所有未完成的直播课', { btn: ['查找', '请先点左边的查找按钮'] //按钮 }, function (index, layero) { //获取所有课程的学习表现 const iframes = []; courseList.forEach((item) => { iframes.push({ title: `获取${item.courseName}直播得分情况`, url: `https://l.shou.org.cn/study/assistTeacher/scoreinfo?auto=true&courseOpenId=${item.courseOpenId}&minorcourseopenid=${item.courseOpenId}&stuId=${link.params.xh}&type=6` }) }) openiframes(iframes, 'url', 'title') const btn2 = layero.find('.layui-layer-btn1'); // 获取第二个按钮 layero.find('.layui-layer-btn0').hide() btn2.text('一键打开直播课'); // 修改文本 }, function () { var waitCourseSet = GM_getValue('waitCourse'); const waitLiveCourse = []; $.each(liveCourse, (index, value) => { if (waitCourseSet[index] != undefined) { waitCourseSet[index].forEach((val, key) => { waitLiveCourse.push(liveCourse[index][val]) }) } }) if (waitLiveCourse.length > 0) { openWindowsInGridFromArray(waitLiveCourse) } else { layer.msg('没找到未完成的直播课') layer.close(); } }); }) break; case '/study/assistTeacher/scoreinfo': setTimeout(() => { //学习表现页面 if (link.params.auto) { //在弹窗中的操作 //检查得分 $('thead tr th').each((index, item) => { if ($(item).text() == '得分') { if ($('tbody tr td:nth-child(' + (index + 1) + ')').text().trim() != 100) { //没有得满分,获取签到详情 window.parent.postMessage( { type: 'change', oldurl: window.location.href, url: $('tbody tr td:last-child a').attr('href') + '&auto=true&courseId=' + link.params.courseOpenId }, '*' ); window.location.href = $('tbody tr td:last-child a').attr('href') + '&auto=true&courseId=' + link.params.courseOpenId } else { window.parent.postMessage( { type: 'close', url: window.location.href // 传递当前子页面的 URL }, '*' ); } } }) } }, 3000) break; case '/appviewdev/xxbx/': var courseId = link.params.courseId // 保存原生的 XMLHttpRequest.open 方法 var originalXHROpen = XMLHttpRequest.prototype.open; //拦截请求 XMLHttpRequest.prototype.open = function (method, url, ...args) { this.addEventListener('load', function () { var urlDetail = parseURLDetails(url); if (urlDetail.path == '/v2/datac/stu/course_live_data_with_sign') { let result = JSON.parse(this.responseText); if (result.code == 0 && result.data.data.length > 0) { //获取未完成的直播课的排序 var res = result.data.data.filter(item => item.live_type != '面授'); res.forEach((item, index) => { if (item.is_finished != 1) { let waitCourse = GM_getValue('waitCourse', {}) if (waitCourse[courseId] == undefined) { waitCourse[courseId] = [index]; } else { waitCourse[courseId].push(index) } GM_setValue('waitCourse', waitCourse); } }) window.parent.postMessage( { type: 'close', url: window.location.href // 传递当前子页面的 URL }, '*' ); } } }); // 调用原始的 open 方法 return originalXHROpen.call(this, method, url, ...args); }; break; case '/study/assignment/history.aspx': //作业结果页面 //收集正确题目 getAnswers(); break; case '/p/PowerPointFrame.aspx': GM_setValue('goNext', false) document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2).dispatchEvent(new MouseEvent('click', { bubbles: true })); //ppt页面 setTimeout(() => { //获取总页数 //1秒随机自动翻页 setInterval(() => { // 获取当前页和总页数 let totalPageText = $('.cui-ctl-mediumlabel').text(); if (!totalPageText.includes('第') || !totalPageText.includes('共')) { console.error('无法解析总页数和当前页数,请检查选择器'); return; } let totalPage = totalPageText.split('共')[1].split('张')[0].trim(); let currentPage = totalPageText.split('第')[1].split('张')[0].trim(); if (parseInt(currentPage) < parseInt(totalPage)) { // 定位屏幕中央的元素 let element = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2); if (element) { element.dispatchEvent(new MouseEvent('click', { bubbles: true })); } else { console.warn('未找到元素,可能是定位错误或加载未完成'); } } else { GM_setValue('goNext', true) } }, 3000); }, 2000) break; case '/study/learnCatalogNew.aspx': //目录页面 setTimeout(() => { $.ajax({ url: apiDomain + '/api/getBody',//获取题目接口 type: 'POST', data: { path: link.path }, success: function (data) { $('#d_courseright').prepend(data) } }) //保存必看 let mustCourse = GM_getValue('mustCourse', {}) let must = []; $('.sh-res').each((index, elem) => { if ($(elem).find('span:contains("(必看)")').length > 0) { let mustItem = { title: $(elem).find('a').text().trim(), url: $(elem).find('a').attr('href'), cellId: $(elem).find('a').attr('href').split('cellId=')[1], status: $(elem).find('img.warningnew1').attr('title'), type: $(elem).find('a').next().text().trim() } must.push(mustItem) } }) if (must.length > 0) { mustCourse[link.params.courseOpenId] = must GM_setValue('mustCourse', mustCourse) } }, 2000) //展开全部 $('body').on('click', '#showAll', function () { $('.showcell').css('height', 'auto') $('.showcell').css('overflow', 'hidden') }) //只显示必看 $('body').on('click', '#showMust', function () { $('.sh-res').each((index, elem) => { if ($(elem).find('span:contains("(必看)")').length == 0) { $(elem).css('display', 'none') } }) }) break; case '/wv/wordviewerframe.aspx': setTimeout(() => { $('#WACContainer').animate({ scrollTop: $('#WACContainer')[0].scrollHeight }, 1000); }, 5000); break; case '/study/assignment-preview.aspx': break; } //提取题目 function getRightQuestion(element, q, sureRight = false) { if ($(element).find('.e-checking-a').length > 0) { //判断题 q.type = '判断题'; q.question = $(element).find('.e-q-q .ErichText').html() q.question_text = $(element).find('.e-q-q .ErichText').text().trim().replaceAll('\n', '') if ($(element).find('.e-q-l .e-q-right').length > 0) { //答对的 q.answer = $(element).find('li.e-a.checked').text().trim().split(' ')[1] q.answer_options = $(element).find('li.e-a.checked').text().trim().charAt(0) } else { //答错的,记录正确答案 q.answer = $(element).find('li.e-a:not(.checked)').text().trim().split(' ')[1] q.answer_options = $(element).find('li.e-a:not(.checked)').text().trim().charAt(0) } } else if ($(element).find('.e-choice-a').length > 0 && ($(element).find('.e-q-l .e-q-right').length > 0 || sureRight)) { //答对的单选题 q.type = '选择题'; q.question = $(element).find('.e-q-q .ErichText').html() q.question_text = $(element).find('.e-q-q .ErichText').text().trim().replaceAll('\n', '') if ($(element).find('li.e-a.checked').length > 1) { //多选题 $(element).find('li.e-a.checked').each((index, elem) => { q.answer += $(elem).find('.ErichText').text().trim().replaceAll('\n', '') + '\n' q.answer_options += $(elem).contents().eq(2).text().trim().charAt(0) }) } else if ($(element).find('li.e-a.checked').length == 1) { q.answer = $(element).find('li.e-a.checked .ErichText').text().trim().replaceAll('\n', '') q.answer_options = $(element).find('li.e-a.checked').contents().eq(2).text().trim().charAt(0) } } else if ($(element).find('.e-blank-a').length > 0 && ($(element).find('.e-q-l .e-q-right').length > 0 || sureRight)) { //填空题 q.type = '填空题'; q.question = $(element).find('.e-q-q .ErichText').html() q.question_text = $(element).find('.e-q-q .ErichText').text().trim().replaceAll('\n', '') q.answer = [] $(element).find('li.e-a').each((index, elem) => { q.answer.push({ title: $(elem).find('.e-blank-e').text(), answer: $(elem).find('input').val() }) }) q.answer_options = null } else if ($(element).find('.e-short-a').length > 0 && ($(element).find('.e-q-l .e-q-right').length > 0 || sureRight)) { //排序题 q.type = '排序题'; q.question = $(element).find('.e-q-q .ErichText').html() q.question_text = $(element).find('.e-q-q .ErichText').text().trim().replaceAll('\n', '') q.answer = [] $(element).find('.am-g .am-u-sm-5').first().find('.ErichText').each((index, elem) => { q.answer.push({ title: $(elem).text().trim().replaceAll('\n', ''), answer: $(element).find('.am-g .am-u-sm-1 .e-choice-i').eq(index).text().trim().replaceAll('\n', '') }) }) q.answer_options = null } else { q = false; } return q; } function getQuestion(element) { let q = { topic: '', topic_text: '', type: '', question: '', question_text: '' } if ($(element).find('.e-choice-q').length > 0) { } else if ($(element).find('.e-checking-a').length > 0) { //判断题 q.type = '判断题'; q.question = $(element).find('.e-q-q .ErichText').html() q.question_text = $(element).find('.e-q-q .ErichText').text().trim().replaceAll('\n', '') } else if ($(element).find('.e-choice-a').length > 0) { //答对的单选题 q.type = '选择题'; q.question = $(element).find('.e-q-q .ErichText').html() q.question_text = $(element).find('.e-q-q .ErichText').text().trim().replaceAll('\n', '') } else if ($(element).find('.e-blank-a').length > 0) { //填空题 q.type = '填空题'; q.question = $(element).find('.e-q-q .ErichText').html() q.question_text = $(element).find('.e-q-q .ErichText').text().trim().replaceAll('\n', '') } else { q = false; } return q; } //题目筛查 function pushQuestion(q_a, q, element) { if (q.question === undefined || q.answer === undefined || q.answer_options === undefined) { $.ajax({ url: '/api/errorQuestion',//记录无法提取的题目接口 type: 'POST', data: { element: element.outerHTML, }, success: function (data) { return false } }) console.log('无法提取的题目已记录', element, q) } else { q_a.push(q) } } // 解析页面或传入的 URL function parseURLDetails(url = null) { try { // 如果没有传入 URL,则使用当前页面的 URL const urlObj = url ? new URL(url) : new URL(window.location.href); // 获取页面路径(不含参数) const pathname = urlObj.pathname; // 获取域名 const domain = urlObj.hostname; // 处理普通查询参数 const params = new URLSearchParams(urlObj.search); const queryParams = {}; // 将参数拆分为键值对 params.forEach((value, key) => { queryParams[key] = value; }); // 检查并解析 # 后的参数(如果存在) if (urlObj.hash && urlObj.hash.includes('?')) { const hashParams = new URLSearchParams(urlObj.hash.split('?')[1]); hashParams.forEach((value, key) => { queryParams[key] = value; }); } // 返回结果对象 return { url: urlObj.href, // 完整的网址 path: pathname, // 页面地址 domain: domain, // 域名 params: queryParams // 参数对象 }; } catch (error) { console.error('Invalid URL:', error.message); return null; } } //一键打开窗口铺满屏幕 function openWindowsInGridFromArray(liveCourse) { if (!Array.isArray(liveCourse) || liveCourse.length === 0) { console.error('liveCourse 必须是一个非空数组'); return; } const n = liveCourse.length; // 窗口数量 const screenWidth = window.screen.availWidth; // 屏幕可用宽度 const screenHeight = window.screen.availHeight; // 屏幕可用高度 // 计算每行和每列的窗口数量 const cols = Math.ceil(Math.sqrt(n)); // 列数 const rows = Math.ceil(n / cols); // 行数 // 计算每个窗口的宽高 const windowWidth = Math.floor(screenWidth / cols); const windowHeight = Math.floor(screenHeight / rows); // 遍历 liveCourse 数组并打开窗口 liveCourse.forEach((item, index) => { const row = Math.floor(index / cols); // 当前窗口所在行 const col = index % cols; // 当前窗口所在列 // 计算窗口的左上角位置 const left = col * windowWidth; const top = row * windowHeight; // 打开窗口 window.open( `https://l.shou.org.cn/study/activity-preview.aspx?auto=1&courseOpenId=${item.courseId}&activityId=${item.id}`, '_blank', `width=${windowWidth},height=${windowHeight},left=${left},top=${top},scrollbars=yes,resizable=yes` ); }); } function openiframes(urls, urlKey, titleKey) { const screenWidth = window.screen.availWidth; // 可用屏幕宽度 const screenHeight = window.screen.availHeight; // 可用屏幕高度 const columns = Math.ceil(Math.sqrt(urls.length)); // 列数 const rows = Math.ceil(urls.length / columns); // 行数 const iframeWidth = Math.floor(screenWidth / columns); // 每个窗口的宽度 const iframeHeight = Math.floor(screenHeight / rows); // 每个窗口的高度 // 记录每个 iframe 的索引和 layerId const layerIds = {}; // 打开多个 iframe 窗口 urls.forEach((url, index) => { const col = index % columns; // 当前列 const row = Math.floor(index / columns); // 当前行 const xOffset = col * iframeWidth; // x 轴偏移 const yOffset = row * iframeHeight; // y 轴偏移 const layerId = layer.open({ type: 2, // iframe 类型 title: `${url[titleKey]}`, // 窗口标题 area: [`${iframeWidth}px`, `${iframeHeight}px`], // 窗口尺寸 offset: [`${yOffset}px`, `${xOffset}px`], // 窗口位置 content: url[urlKey], // iframe 的 URL shade: 0, }); // 记录 layerId 和 URL 的对应关系 layerIds[url[urlKey]] = layerId; }); // 父页面监听消息 window.addEventListener('message', (event) => { try { if (event.data.type === 'close') { const layerId = layerIds[event.data.url]; if (layerId) { layer.close(layerId); // 关闭对应的 iframe delete layerIds[event.data.url]; // 删除记录 } } else if (event.data.type === 'change') { layerIds[event.data.url] = layerIds[event.data.oldurl] } } catch (error) { console.error('消息解析失败', error); } }); } function autoPlayStart() { const mustCourse = GM_getValue('mustCourse', {}) //刷课 // 获取课程类型 const currentCell = mustCourse[link.params.CourseOpenId].find(item => item.cellId == link.params.cellId) const nextUnfinishedCell = mustCourse[link.params.CourseOpenId].find(item => item.status != '已完成') if (currentCell.status == '已完成') { //寻找下一个未完成的课程 if (nextUnfinishedCell != undefined) { window.location.href = nextUnfinishedCell.url } else { layer.alert('课程已完成,请手动切换下一门课程') } } else { //解析与练习课程 if (currentCell.type == '( )' && currentCell.title.includes('解析与练习')) { console.log('解析与练习') //解析与练习课程 setTimeout(() => { if (nextUnfinishedCell != undefined) { //标记本节课已完成 let mustCourseTemp = GM_getValue('mustCourse', {}) mustCourseTemp[link.params.CourseOpenId].find(item => item.cellId == link.params.cellId).status = '已完成' GM_setValue('mustCourse', mustCourseTemp) window.location.href = nextUnfinishedCell.url } else { layer.alert('课程已完成,请手动切换下一门课程') } }, 10000) } if (currentCell.type.includes('视频') || currentCell.type.includes('音频')) { // 视频自动播放 $('video')[0].muted = true $('video')[0].play() $('video')[0].addEventListener('ended', function () { //标记本课程已完成储存到脚本 if (nextUnfinishedCell != undefined) { //标记本节课已完成 let mustCourseTemp = GM_getValue('mustCourse', {}) mustCourseTemp[link.params.CourseOpenId].find(item => item.cellId == link.params.cellId).status = '已完成' GM_setValue('mustCourse', mustCourseTemp) window.location.href = nextUnfinishedCell.url } else { layer.alert('课程已完成,请手动切换下一门课程') } }) } else if (currentCell.type.includes('PPT')) { setInterval(() => { //每三秒检查一次是否可以进行下一课 if (GM_getValue('goNext', false)) { //标记本课程已完成储存到脚本 if (nextUnfinishedCell != undefined) { //标记本节课已完成 let mustCourseTemp = GM_getValue('mustCourse', {}) mustCourseTemp[link.params.CourseOpenId].find(item => item.cellId == link.params.cellId).status = '已完成' GM_setValue('mustCourse', mustCourseTemp) window.location.href = nextUnfinishedCell.url } else { layer.alert('课程已完成,请手动切换下一门课程') } } }, 3000) } else if (currentCell.type.includes('文档')) { //文档会自动浏览到底部,所以需要等待10秒后自动下一个 setTimeout(() => { if (nextUnfinishedCell != undefined) { //标记本节课已完成 let mustCourseTemp = GM_getValue('mustCourse', {}) mustCourseTemp[link.params.CourseOpenId].find(item => item.cellId == link.params.cellId).status = '已完成' GM_setValue('mustCourse', mustCourseTemp) window.location.href = nextUnfinishedCell.url } else { layer.alert('课程已完成,请手动切换下一门课程') } }, 10000) }else{ setTimeout(() => { //记录课程类型 //其他类型课程,直接跳转下一课 if (nextUnfinishedCell != undefined) { //标记本节课已完成 let mustCourseTemp = GM_getValue('mustCourse', {}) mustCourseTemp[link.params.CourseOpenId].find(item => item.cellId == link.params.cellId).status = '已完成' GM_setValue('mustCourse', mustCourseTemp) window.location.href = nextUnfinishedCell.url } else { layer.alert('课程已完成,请手动切换下一门课程') } }, 10000) } } } //渲染答题工具 function QuestionAnalysis() { //查询本业面所有题目类型标题 let questionTypeList = []; $('.types-l').find('a').each(function (key, item) { questionTypeList.push($(item).attr('title').trim()) }) console.log(questionTypeList) $('.typebox').each(function (key, item) { $(item).attr('typeTitle', questionTypeList[key]) }) //支持的题目类型 let doQuestionType = []; // 获取库中支持的题型 $.ajax({ url: apiDomain + 'api/questionType', type: 'GET', success: function (data) { doQuestionType = data.data.reduce((acc, item) => { acc[item.id] = item; return acc; }, {}); console.log(doQuestionType) //本业面的所有题目类型id let questionTypeIds = []; //获取页面所有题目 $('.e-q-body').each(function (key, item) { //获取题目类型 let questionType = $(item).data('questiontype'); if (!questionTypeIds.includes(questionType)) { questionTypeIds.push(questionType); } //查看是否是大题 if ($(item).find('.e-q-quest').length == 1) { //正常题目 if (doQuestionType[questionType]['status'] == 1) { //支持查询的题型 $(item).find('.e-q-quest').eq(0).append( `
    ` ) } else { //不支持的题型,通过接口反馈 $.ajax({ url: apiDomain + 'api/errorQuestion', type: 'POST', data: { element: item.outerHTML, questionType: questionType }, success: function (data) { console.log(data) } }) } } else { //大题 } }) console.log(questionTypeIds) } }) } function getQuestions() { //获取页面所有题目 const questions = []; const mainQuestions = []; //获取所有子题目 $('form').each(function (key, item) { //排序题忽略 if ($(item).find('.e-a-g.e-short-a').length > 0) { return; } const hiddenInputs = $(item).find('input[type="hidden"]'); const formQuestion = {}; formQuestion.action = $(item).attr('action'); //获取题目标识 hiddenInputs.each(function () { const name = $(this).attr('name'); if (name !== 'answer') { const value = $(this).val(); formQuestion[name] = value; } }); if (formQuestion['subQuestionId'] !== undefined && formQuestion['studentWorkId'] !== undefined) { // 说明这个题目是大题内的子题目 // 先确定这个大题题干是否已经获取了 let mainQuestion = mainQuestions.find(item => item.studentWorkId == formQuestion['studentWorkId']); if (!mainQuestion) { // 获取大题的题干 let questionBody = $(item).prevAll('.e-q-q').first(); if (questionBody.length > 0) { // 确保questionBody存在 let questionType = $(item).closest('.e-q-body').data('questiontype'); mainQuestion = { question: questionBody.find('.ErichText').text().trim(), question_html: questionBody.find('.ErichText').html().trim(), studentWorkId: formQuestion['studentWorkId'], questionType: questionType }; mainQuestions.push(mainQuestion); } } } //获取题目内容 formQuestion.question = $(item).find('.e-q-q .ErichText').text().trim(); formQuestion.question_html = $(item).find('.e-q-q .ErichText').html().trim(); //获取选项 formQuestion.options = []; if ($(item).find('.e-a-g ul li').length > 0) { $(item).find('.e-a-g ul li').each(function (key, items) { let option = {}; if ($(items).find('.ErichText').length > 0) { option.content = $(items).find('.ErichText').text().trim(); option.content_html = $(items).find('.ErichText').html().trim(); } else { option.content = $(items).text().trim(); } option.index = $(items).data('index'); if ($(items).attr('role')) { option.role = $(items).attr('role'); } if ($(items).data('subquestiontype')) { option.subQuestionType = $(items).data('subquestiontype'); } formQuestion.options.push(option) }) } else { return; } questions.push(formQuestion); }) //把题目上传到题库 $.ajax({ url: apiDomain + 'api/getQuestions', type: 'POST', data: { questions: JSON.stringify(questions), userData: JSON.parse(GM_getValue('userData')), link: link, mainQuestions: JSON.stringify(mainQuestions) }, success: function (data) { if (data.questionHasAnswer.length > 0) { //遍历题目,如果题目存在正确答案,则渲染到页面上去 data.questionHasAnswer.forEach(item => { // 查找匹配的题目 $('form').each(function () { const questionText = $(this).find('.e-q-q .ErichText').text().trim(); if(questionText == ''){ //获取题号 const questionNum = $(this).find('.e-q-no').text().trim().split('、')[0]; } if (questionText === item.question) { // 创建答案显示区域 if (!$(this).find('.e-q-quest').parent().find('.answer-display').length) { $(this).find('.e-q-quest').parent().append(`
    参考答案:
    ${item.answer}
    `); } // 高亮正确选项 if (item.answer_index !== undefined) { $(this).find(`.e-a-g ul li[data-index="${item.answer_index}"]`).css({ 'background-color': '#f0f8ff', 'border-left': '2px solid #1e9fff' }); } } }); }); //大题中题目没有题干部分 $('form').each(function (index,formitem) { const questionText = $(this).find('.e-q-q .ErichText').text().trim(); if(questionText == ''){ const mainQuestionText = $(this).prevAll('.e-q-q').first().find('.ErichText').text().trim(); //获取题号 const questionNum = $(this).find('.e-q-no').text().trim().split('、')[0]; data.mainQuestionHasAnswer.forEach(item => { if(item.main_question == mainQuestionText){ item.answers.forEach(answer => { if(answer.question_num == questionNum){ $(this).find('.e-q-quest').parent().append(`
    参考答案:
    ${answer.answer}
    `); } }) } }) } }); // 如果有答案,显示提示消息 layer.msg(`已为您找到 ${data.questionHasAnswer.length} 道题的参考答案`, { time: 3000 }); } //没有答案的显示deepseek答题按钮 $('form').each(function () { const questionText = $(this).find('.e-q-q .ErichText').text().trim(); if (!$(this).find('.answer-display').length) { //只有独立题目form中有这个结构e-q-r if ($(this).find('.e-q-r').length > 0) { $(this).find('.e-q-r').append(`
    `); } else { //大题 // 除了听力题 if ($(this).closest('.e-q-body').data('questiontype') == 11) { return; } if ($(this).closest('.e-q-body').find('.deepseekQuestion').length == 0) { $(this).closest('.e-q-body').find('.e-q-r').first().append(`
    `); } } } }); } }) } function getAnswers() { //获取页面所有题目 const questions = []; const mainQuestions = []; //获取所有子题目 $('form').each(function (key, item) { //排序题忽略 if ($(item).find('.e-a-g.e-short-a').length > 0) { return; } const hiddenInputs = $(item).find('input[type="hidden"]'); const formQuestion = {}; formQuestion.action = $(item).attr('action'); //获取题目标识 hiddenInputs.each(function () { const name = $(this).attr('name'); if (name !== 'answer') { const value = $(this).val(); formQuestion[name] = value; } }); if ($(item).find('.e-q-r').length == 0) { // 说明这个题目是大题内的子题目 // 先确定这个大题题干是否已经获取了 let mainQuestion = mainQuestions.find(item => item.studentWorkId == formQuestion['studentWorkId']); if (!mainQuestion) { // 获取大题的题干 let questionBody = $(item).prevAll('.e-q-q').first(); if (questionBody.length > 0) { // 确保questionBody存在 let questionType = $(item).closest('.e-q-body').data('questiontype'); mainQuestion = { question: questionBody.find('.ErichText').text().trim(), question_html: questionBody.find('.ErichText').html().trim(), studentWorkId: formQuestion['studentWorkId'], questionType: questionType }; mainQuestions.push(mainQuestion); } } } //获取题目内容 formQuestion.question = $(item).find('.e-q-q .ErichText').text().trim(); formQuestion.question_html = $(item).find('.e-q-q .ErichText').html().trim(); //题号 formQuestion.question_num = $(item).find('.e-q-no').text().trim().split('、')[0]; //获取选项 formQuestion.options = []; if ($(item).find('.e-a-g ul li').length > 0) { $(item).find('.e-a-g ul li').each(function (key, items) { let option = {}; if ($(items).find('.ErichText').length > 0) { option.content = $(items).find('.ErichText').text().trim(); option.content_html = $(items).find('.ErichText').html().trim(); } else { option.content = $(items).text().trim(); } option.index = $(items).data('index'); if ($(items).attr('role')) { option.role = $(items).attr('role'); } if ($(items).data('subquestiontype')) { option.subQuestionType = $(items).data('subquestiontype'); } formQuestion.options.push(option) }) } else { return; } //获取答案 //查看是否显示了参考答案 if($(item).find('.e-a-ans').length > 0){ formQuestion.answer = $(item).find('.e-a-ans .e-ans-r').text().trim(); }else{ //查看是否回答正确 //判断题目是否回答正确 if ($(item).find('.e-q-right').length > 0) { formQuestion.answer_index = $(item).find('.e-a.checked').data('index'); // 获取正确答案内容 if ($(item).find('.e-a.checked .ErichText').length > 0) { formQuestion.answer = $(item).find('.e-a.checked .ErichText').text().trim(); formQuestion.answer_html = $(item).find('.e-a.checked .ErichText').html().trim(); } else { formQuestion.answer = $(item).find('.e-a.checked').text().trim(); formQuestion.answer_html = $(item).find('.e-a.checked').html().trim(); } } else if ($(item).parent().data('questiontype') == 3) { const correctAnswer = $(item).find('.e-a').not('.checked'); if (correctAnswer.length > 0) { formQuestion.answer_index = correctAnswer.data('index'); if (correctAnswer.find('.ErichText').length > 0) { formQuestion.answer = correctAnswer.find('.ErichText').text().trim(); formQuestion.answer_html = correctAnswer.find('.ErichText').html().trim(); } else { formQuestion.answer = correctAnswer.text().trim(); formQuestion.answer_html = correctAnswer.html().trim(); } } } } questions.push(formQuestion); }) console.log({ questions: questions, mainQuestions: mainQuestions }) //把题目发送到后端 $.ajax({ url: apiDomain + 'api/saveAnswers', type: 'POST', data: { questions: JSON.stringify(questions), userData: JSON.parse(GM_getValue('userData')), link: link, mainQuestions: JSON.stringify(mainQuestions) }, success: function (data) { console.log(data) } }) } })();