// ==UserScript==
// @name 灯塔在线
// @namespace **************
// @version 1.12
// @match *.dtdjzx.gov.cn/course/special/*
// @match *.dtdjzx.gov.cn/*
// @author lute
// @description 山东党员网络学院在线挂机学习脚本
// @run-at document-start
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
/*---------------------------------------------------------
描述: 灯塔党员网络学院学习
根据郭的脚本山东gb网络学院视频学习 改写
安装脚本进入课程资源页面后 刷新页面脚本自动执行
----------------------------------------------------------*/
/*********************** 公共 ***************************/
/*---------------------------------------------------------
名称: Env
描述: 环境变量
实现: 通过vue实例 获取数据 ,在调度中update
记录: 2024-5-15 完成编写
----------------------------------------------------------*/
const Env = {
app: document.querySelector('.resource')?.__vue__||document.querySelector('.main_main')?.__vue__,
timeTable: undefined,
handl: null,
autoExam:true,
get name() {
//页面名称,用于识别所在页面,在网址中有出现
return this.app?.$route?.name;
},
get courseCount() {
//课表的总课数
return this.fit({
'course-resources': this.app?.holdList.length
})
},
get courseList() {
//课表id
return this.app?.holdList
},
get idCardHash() {
//用户idcardhash
return this.app?.userInfo?.idCardHash;
},
fit(obj) {
//根据不用的业务返回值
var result = obj[this.name];
this.validate(result);
return result;
},
validate(result) {
//在验证值为undefined的时候警告,调试用
if (result == undefined) console.warn("读取值失败,可能本页无该值,页面--", this.name);
},
update() {
//更新vue实例
this.app = document.querySelector('.resource')?.__vue__||document.querySelector('.main_main')?.__vue__;
this.timeTable = undefined;
clearInterval(this?.timerId);
}
}
/*---------------------------------------------------------
函数名: showMsg
描述: 在右侧栏展示信息,最多5条
记录:
----------------------------------------------------------*/
function showMsg(msg, type = 'msg') {
if (window.monkeydata == undefined) {
console.error('alpinejs存在错误');
return;
}
if (type == 'msg') {
window.monkeydata.message = msg;
} else {
window.monkeydata.tip = msg;
}
}
/*********************** 初始化 *****************************/
/*---------------------------------------------------------
函数名: initEnv
描述: 入口:初始化环境
1.关联【策略】与【路径】
** vue改变hash打开新页面,不会重新加载脚本,需监听
2.改造显示面板
** 右侧浮动栏变成显示面板
** 使用了Alpinejs
3.Alpinejs 加载完后执行 策略
记录:
----------------------------------------------------------*/
(function initEnv() {
//let panelNode = document.querySelector('.right-fixed-wrap');
let panelNode = document.querySelector('.bottom')||document.querySelector('.title-r');
console.log('脚本......准备');
if (!panelNode) {
console.log('页面还未准备好...1s后再试');
setTimeout(initEnv, 1000);
return;
}
console.log('脚本......开始');
//监听页面变化
//panelNode.__vue__.$router.afterHooks.push(routerHook);
console.log('路径钩子......ok');
//改造面板
panelNode.style.cssText += "width:250px";
panelNode.outerHTML = `
<ul x-data="{message:'hh',tip:''}" x-init="window.monkeydata=$data">
<li x-text="message" style="font-size:14px"></li>
<li x-text="tip" style="font-size:18px"></li>
</ul>`;
//注入Alpinejs
let scriptNode = document.createElement('script');
scriptNode.src = "https://unpkg.com/alpinejs@3.10.3/dist/cdn.min.js";
scriptNode.defer = true;
document.head.appendChild(scriptNode);
console.log('信息面板......准备');
document.addEventListener('alpine:initialized', function () {
console.log('信息面板......ok');
showMsg('脚本.....ok');
routerHook();
});
})();
/*********************** 调度 *****************************/
/*---------------------------------------------------------
函数名: strategies
描述: 策略,根据所处页面做出动作,与路径hash相关
记录:
----------------------------------------------------------*/
function strategies() {
Env.update();
console.log(Env.name);
switch (Env.name) {
case 'projectDetail':
break;
//课程资源目录
case 'course-resources':
showMsg('course-resources');
timeTableHook();
getCourseList().then(makeTablenew);
break;
case 'course-detail':
//课程页
xq();
break;
default:
console.log('课程资源目录');
showMsg('课程资源目录');
}
}
/*---------------------------------------------------------
函数名: routerHook
描述: 路径变化时调用策略
需延时等待页面加载完成
记录:
----------------------------------------------------------*/
function routerHook() {
setTimeout(strategies, 5000);
}
/*---------------------------------------------------------
函数名: timeTableHook
描述: 课表准备好 且 无打开的课程 打开下一课
记录:
----------------------------------------------------------*/
function timeTableHook() {
console.log(Env.timeTable);
Env.timerId = setInterval(() => {
if (!Env.timeTable) return; //无有效课表
if (Env.handl?.closed == false) return; //正在播放
var c = Env.timeTable.next();
if (c.done) {
console.log('全学完 点击下一页');
document.querySelector('.btn-next').click();
Env.update();
routerHook();
return;} //全学完 点击下一页
Env.handl = window.open(c.value);
}, 2000);
}
/*********************** 课程 *****************************/
/*---------------------------------------------------------
函数名: getCourseList
描述: 获取全部课程
记录:
----------------------------------------------------------*/
function getCourseList() {
console.log('获取课程......');
showMsg('获取课表......')
//读取全部课程
return new Promise((resolve, reject) => {
try {
resolve(Env.courseList);
} catch (error) {
reject(error);
}
});
}
/*---------------------------------------------------------
函数名: makeTablenew
描述: 制作课表,挂到window,以便学习
Env.timeTable.next()是学习下一课
记录:
----------------------------------------------------------*/
function makeTablenew(res) {
console.log('课表.......ok',res);
showMsg('课表......ok');
Env.timeTable = {
courseList: res,
//courseLiscoursedetailURL:res.datalist,
index: 0,
next() {
var done = this.index >= this.courseList.length;
showMsg(`第__${this.index+1}__课...共__${this.courseList.length}__课`,'info');
if (done) {
console.warn('没有下一课了');
return { done: true, value: undefined };
}
var course = this.courseList[this.index++];
console.log('准备......', course.courseName);
showMsg(course.courseName);
//跳过已学习
if (course.studyStatus==2) { return this.next(); }
else return { done: false, value: "https://dywlxy.dtdjzx.gov.cn/course-resources/course/course-detail?id="+course.id };
}
}
}
/*********************** 播放 *****************************/
let sleep = function (time) {
return new Promise((resolve) => setTimeout(resolve, time));
};
/*---------------------------------------------------------
函数名: xq
描述: 单课学习
----------------------------------------------------------*/
function xq() {
console.log('学习中...');
showMsg('准备学习......');
//自动播放
var video = document.querySelector('video');
//确保成功
if (!video) {
setTimeout(xq, 2000);
return;
}
video.muted = true;//自动播放需静音
video.play();
showMsg('学习中......');
setTimeout(video.volume=1, 2000);
video.muted = false
console.log('视频音量',video.volume);
video.addEventListener('pause',function(){
console.log('视频暂停...');
video.play();
})
video.addEventListener('ended',function(){
console.log('视频结束...');
sleep(10000).then(() => {window.close()});
})
}
})();