Advance when learning is complete and the platform exam is passed
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @name 学员中心 · 2倍速学习助手
|
||||
// @namespace local.icampus.study
|
||||
// @version 1.3.0
|
||||
// @version 1.3.1
|
||||
// @description 支持切换标签页继续2倍速播放与保存进度,自动测验及错题重试。
|
||||
// @match https://icampus.yunyinsh.com/course/*
|
||||
// @run-at document-start
|
||||
@@ -28,14 +28,19 @@
|
||||
function bodyJSON(body) {
|
||||
try { return typeof body === 'string' && body.length < 65536 ? JSON.parse(body) : null; } catch { return null; }
|
||||
}
|
||||
function examPerfect(c) { return !!c && Number(c.examScorePercent)===100 && (c.examPassed===true || c.examPassed==='true'); }
|
||||
function courseDone(c) { return !!c && (c.status === 'COMPLETED' || !!c.completedAt) && (!c.examRequired || examPerfect(c)); }
|
||||
function examPassed(c) { return !!c && (c.examPassed===true || c.examPassed==='true'); }
|
||||
function courseDone(c) {
|
||||
if(!c) return false;
|
||||
const hasProgress=c.progressPercent!==null && c.progressPercent!==undefined && c.progressPercent!=='';
|
||||
const learningDone=hasProgress ? Number(c.progressPercent)>=100 : c.status==='COMPLETED' || !!c.completedAt;
|
||||
return learningDone && (!c.examRequired || examPassed(c));
|
||||
}
|
||||
function videoPlan(detail) {
|
||||
if (!detail?.course || !Array.isArray(detail.resources)) return {kind: 'wait'};
|
||||
const resources = [...detail.resources].sort((a, b) => a.sortNo - b.sortNo);
|
||||
const next = resources.find(r => r.completed !== true);
|
||||
if (next) return {kind: next.type === 'VIDEO' ? 'video' : 'manual', resource: next};
|
||||
if (detail.course.examRequired && !examPerfect(detail.course)) return {kind: 'quiz'};
|
||||
if (detail.course.examRequired && !examPassed(detail.course)) return {kind: 'quiz'};
|
||||
return {kind: 'finish'};
|
||||
}
|
||||
function resolveCards(cards, courses) {
|
||||
@@ -92,7 +97,7 @@
|
||||
return m ? {kind:'card', paperId:m[1]} : null;
|
||||
} catch { return null; }
|
||||
}
|
||||
const core = {normalize, route, endpoint, bodyJSON, courseDone, examPerfect, videoPlan, resolveCards, leaseAvailable,
|
||||
const core = {normalize, route, endpoint, bodyJSON, courseDone, examPassed, videoPlan, resolveCards, leaseAvailable,
|
||||
questionKey, selectionKey, chooseAnswer, learnCard, quizEndpoint};
|
||||
if (typeof module === 'object' && module.exports && typeof window === 'undefined') { module.exports = core; return; }
|
||||
if (window.top !== window.self || document.getElementById('icampus-study-helper')) return;
|
||||
@@ -406,13 +411,9 @@
|
||||
const percent = result.querySelector('.quiz-result__score strong')?.textContent.trim();
|
||||
const score=percent && /^\d+(\.\d+)?%$/.test(percent) ? Number(percent.replace('%','')) : course?.examScorePercent;
|
||||
if(course && score!==undefined) course.examScorePercent=score;
|
||||
if(Number(score)===100) {
|
||||
log('测验已达到100%,允许继续。');
|
||||
if(quizOnly) return park('本门测验已达到100%,保持已启动,等待后续操作。',{passive:true});
|
||||
quiz=null; return;
|
||||
}
|
||||
// A lower platform pass mark does not satisfy the user's 100% gate.
|
||||
if(!quizButton(root,'重新测验')) return park(`当前正确率${score ?? '未知'}%,等待重考入口;达到100%前不切换视频或课程。`);
|
||||
log(`平台已确认测验合格(${score ?? '未显示'}%),继续检查学习进度。`);
|
||||
if(quizOnly) return park('本门测验已合格,保持已启动,等待后续操作。',{passive:true});
|
||||
quiz=null; return;
|
||||
}
|
||||
if (quiz.phase === 'opening' || quiz.phase === 'retrying') return quizWait('正在打开测验…');
|
||||
const exam = exams.get(id);
|
||||
@@ -581,7 +582,7 @@
|
||||
return;
|
||||
}
|
||||
const plan = videoPlan(detail);
|
||||
if(detail.course.examRequired && !examPerfect(detail.course)) {
|
||||
if(detail.course.examRequired && !examPassed(detail.course)) {
|
||||
const gatedVideo=active?.video || currentVideo();
|
||||
if(gatedVideo && !gatedVideo.paused) gatedVideo.pause();
|
||||
active=null;
|
||||
@@ -730,14 +731,14 @@
|
||||
host.style.cssText = 'position:fixed;left:16px;bottom:16px;z-index:2147483646';
|
||||
panel = host.attachShadow({mode: 'open'});
|
||||
panel.innerHTML = `<style>:host{font:14px/1.6 system-ui;color:#eaf0fa}section{width:290px;background:#17243a;border:1px solid #6883a6;border-radius:12px;padding:15px;box-shadow:0 5px 24px #0005}strong{font-size:16px}p{margin:9px 0;white-space:pre-line}small{color:#b7c7df}button,select{font:inherit;border-radius:6px;border:1px solid #7186a5;padding:5px 9px;margin:3px 5px 3px 0}button{cursor:pointer;background:#dbeaff;color:#123}button:disabled{opacity:.5;cursor:default}select{width:100%;background:#fff;color:#123}[data-status]{min-height:45px}details{margin-top:8px}pre{white-space:pre-wrap;max-height:160px;overflow:auto;font-size:12px}</style>
|
||||
<section><strong>2倍速学习助手 · 1.3.0</strong><p data-status></p><small data-progress></small>
|
||||
<section><strong>2倍速学习助手 · 1.3.1</strong><p data-status></p><small data-progress></small>
|
||||
<select aria-label="播放范围"><option value="all">按列表顺序继续课程</option><option value="current">仅当前课程</option></select>
|
||||
<div><button data-start>开始</button><button data-stop>人工取消</button></div>
|
||||
<label><input type="checkbox" data-quiz checked> 自动测验,达到100%才继续</label>
|
||||
<label><input type="checkbox" data-quiz checked> 自动测验,按平台合格线通过</label>
|
||||
<div><label><input type="checkbox" data-background> 切标签页继续播放</label></div>
|
||||
<small data-background-state></small>
|
||||
<div><button data-quiz-only>只做本门测验</button></div>
|
||||
<small>启动后持续运行与等待;只有人工取消才关闭。测验100%后继续视频。</small>
|
||||
<small>学习进度100%且测验合格后换课。持续运行,人工取消才关闭。</small>
|
||||
<details><summary>运行记录</summary><pre></pre><button data-copy>更新记录</button></details></section>`;
|
||||
mode = panel.querySelector('select');
|
||||
autoQuiz = panel.querySelector('[data-quiz]');
|
||||
|
||||
Reference in New Issue
Block a user