// ==UserScript==
// @name tame QTKJ
// @namespace Vionlentmonkey
// @version 3.1.3
// @description at the end of with it.
// @author someone
// @icon http://www.moj.gov.cn/favicon.ico
// @match http://218-94-1-181.sft.ipv6.jiangsu.gov.cn:8087/sfxzwsxy/*
// @match http://218-94-1-179.sft.ipv6.jiangsu.gov.cn:8087/sfxzwsxy/*
// @match http://218-94-1-175.sft.ipv6.jiangsu.gov.cn:8087/sfxzwsxy/*
// @match http://218.94.1.181:8087/sfxzwsxy/*
// @match http://218.94.1.179:8087/sfxzwsxy/*
// @match http://218.94.1.175:8087/sfxzwsxy/*
// @match http://218.94.1.181:5088/unzipapp/project/ware/attach/*
// @require https://openuserjs.org/src/libs/sizzle/GM_config.js
// @require https://cdn.jsdelivr.net/npm/vm.shortcut
// @require https://greasyfork.org/scripts/381401-addstyle/code/addStyle.js
// @require https://greasyfork.org/scripts/381403-fakenavigators/code/fakeNavigators.js
// @require https://greasyfork.org/scripts/395748-wsxy-get-data/code/wsxy_get_data.js
// @require https://greasyfork.org/scripts/395937-wsxy-autoserverselect/code/wsxy_autoServerSelect.js
// @require https://greasyfork.org/scripts/395952-wsxy-autoloin/code/wsxy_autoLoin.js
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @grant GM_openInTab
// @grant GM_notification
// @grant GM_xmlhttpRequest
// @run-at document-start
// ==/UserScript==
const body = document.body || document.documentElement;
const windowCSS = `
#Cfg {
height: auto;
background-color: lightblue;
}
#Cfg .reset_holder {
float: left;
position: relative;
bottom: -1em;
}
#Cfg .saveclose_buttons {
margin: 1em;
}
`;
const openCfg = () => {
// 避免在包含框架的页面打开造成多个设置界面重叠
if (window.top === window.self) {
GM_config.open();
}
};
GM_registerMenuCommand('江苏省司法行政网上学院个性化设置', openCfg);
GM_config.init({
id: 'Cfg',
title: '江苏省司法行政网上学院个性化设置',
fields: {
loginName: {
section: ['登录', '完整填写尝试自动登录'],
label: '账号',
labelPos: 'right',
type: 'text',
default: ''
},
pwd: {
label: '密码',
labelPos: 'right',
type: 'password',
default: ''
},
reload: {
label: '是否无限尝试',
labelPos: 'right',
type: 'checkbox',
default: false
},
open_unclose: {
section: ['操作', '后台批量打开新标签页'],
label: '快捷键',
labelPos: 'right',
type: 'text',
default: 'F8'
},
batch: {
label: '批量打开个数',
labelPos: 'right',
type: 'int',
default: 10
},
muted: {
label: '静音播放',
labelPos: 'right',
type: 'checkbox',
default: true
}
},
css: windowCSS,
events: {
save: () => {
GM_config.close();
// 服务器选择页面或登录页面自动刷新
if (
location.pathname.match(/\/sfxzwsxy\/?(serverSelect.jsp)?#?$/i) ||
location.pathname.startsWith('/sfxzwsxy/index.jsp')
) {
location.reload(true);
}
}
}
});
// 彩蛋:通关密语
const passPhrase = btoa(GM_config.get('pwd')).startsWith('TzUxbzE5');
// 从 QQ 等打开地址后会被加上奇葩后缀 http://218.94.1.179:8087/sfxzwsxy/#?tdsourcetag=s_pctim_aiomsg
const clearURLs = () => {
const tracks = [
// QQ
'?tdsourcetag=s_pctim_aiomsg',
// Weixin
'?from=groupmessage',
'&from=groupmessage',
'?from=singlemessage',
'&from=singlemessage',
'?from=timeline',
'&from=timeline',
'/type/WeixinReadCount'
];
for (let track of tracks) {
if (location.href.endsWith(track)) {
location.href = location.href.replace(track, '');
}
}
};
clearURLs();
// 统一域名
if (location.host.endsWith('.sft.ipv6.jiangsu.gov.cn:8087')) {
location.host = location.host.replace('.sft.ipv6.jiangsu.gov.cn', '').replace('-', '.');
}
// http://218.94.1.175:8087/sfxzwsxy/
if (location.pathname.match(/\/sfxzwsxy\/?(serverSelect.jsp)?#?$/i)) {
// 自动选择最空闲的服务器
setInterval(autoServerSelect, 1000);
}
// 去除登陆验证码校验
// 曾使用 OCR 识别法,参考了 https://www.cnblogs.com/ziyunfei/archive/2012/10/05/2710349.html 但准确度有限。
if (location.pathname.startsWith('/sfxzwsxy/index.jsp')) {
window.onload = () => {
autoLogin();
};
}
// 首页
if (
location.href.endsWith('/sfxzwsxy/jypxks/index.html') ||
location.href.endsWith('/sfxzwsxy/jypxks/index.html#')
) {
// 修复页面过长无法完整显示的 Bug; 隐藏 密码修改提示 和 每日一题
const css = `
html[style="overflow: hidden;"] {
overflow: visible !important;
}
#layui-layer1, #layui-layer-shade1, #layui-layer2, #layui-layer-shade2 {
display: none !important;
}
`;
addStyle(css);
// 判断是否已完成任务。不等待页面载入完成就执行可能导致数据尚未成功获取而出错。
window.onload = async () => {
let userDataObj = await getUserData();
let total_hour = userDataObj.total_hour; //规定需达到的总学时
let required_hour = userDataObj.required_hour; //规定需达到的必修学时
let required_credit = userDataObj.required_credit; //规定需达到的总学分
let user_total_hour = userDataObj.user_total_hour || 0; //用户已获得的总学时
let user_required_hour = userDataObj.user_required_hour || 0; //用户已获得的必修学时
let user_required_credit = userDataObj.user_required_credit || 0; //用户已获得的总学分
if (
user_total_hour < total_hour ||
user_required_hour < required_hour ||
user_required_credit < required_credit
) {
console.log(`本学年任务尚未完成:`);
if (passPhrase) {
GM_openInTab(`${location.origin}/sfxzwsxy/jypxks/modules/homepage/homepage.jsp`, false);
} else {
// 长时间不动会被弹出,故 30 分钟刷新一次
setInterval(() => {
location.reload(true);
}, 1800000);
}
if (user_total_hour < total_hour) {
console.log(`总学时差:${total_hour - user_total_hour}`);
}
if (user_required_hour < required_hour) {
console.log(`必修学时差:${required_hour - user_required_hour}`);
}
if (user_required_credit < required_credit) {
console.log(`总学分差:${required_credit - user_required_credit}`);
}
} else {
console.log(`本学年任务已经完成`);
}
};
}
// 自动聚焦以便快捷键默认生效
let document_observer = new MutationObserver(() => {
if (document.getElementById('mainFrame')) {
document.getElementById('mainFrame').focus();
console.log('focus');
}
});
document_observer.observe(body, {
childList: true,
subtree: true
});
// 首页培训课程 iframe
if (location.href.endsWith('/sfxzwsxy/jypxks/modules/homepage/homepage.jsp')) {
// F8 批量后台新标签页打开已报名课程播放页面
VM.registerShortcut(GM_config.get('open_unclose'), () => {
let i = 0;
const trains = document.getElementsByClassName('course');
for (let train of trains) {
// 报名后不再隐藏
let applyPk = train.getElementsByClassName('applyPk')[0].textContent;
if (applyPk !== '') {
let trainURL =
location.origin +
'/sfxzwsxy/jypxks/modules/train/ware/course_ware_view.jsp?applyPk=' +
applyPk +
'&courseType=1';
GM_openInTab(trainURL, true);
i++;
// 疑似超过 6 个课程同时学习后台不计数
if (i >= GM_config.get('batch')) {
console.log(`已批量打开${i}个课程`);
return;
}
}
}
});
const auto3Credit = async () => {
// 彩蛋:需要 iframe 提升才会执行
if (!passPhrase && window.top === window.self) {
let courses = document.querySelectorAll('#requiredCourseTable .course');
for await (let c of courses) {
let coursePk = c.getElementsByClassName('coursePk')[0].textContent;
let title = c.getElementsByClassName('title')[0].getAttribute('title');
let jdjs = c.getElementsByClassName('jdjs')[0].textContent; // 进度
let csInfo = await getCourseInfo(coursePk);
let csCredit = csInfo.courseCredit;
// 彩蛋:需要 iframe 提升才会执行
if (window.top === window.self) {
if (jdjs === '未报名') {
// 自动报名高学分课程
if (csCredit > 1) {
console.log(`${csCredit}学分:${title}`);
c.click();
console.log('click:' + title);
const info = document.getElementsByClassName('layui-layer-btn0');
if (info.length === 1) {
document.getElementsByClassName('layui-layer-btn0')[0].click();
console.log('报名:' + title);
}
}
}
}
}
}
};
const autoLearn = async () => {
if (passPhrase && window.top === window.self) {
// 30 分钟刷新一次
setInterval(() => {
location.reload(true);
}, 1800000);
/**
* ✅:获取学时/学分,已报名课程学时/学分
* ✅:若学分未满而有待考试课程则打开考试页面
* 若已获得学时+已报名课程总学时未满则继续报名,哪项没满就报该项最大的
* ✅:若已报名完成,满足考试条件,则完成现有考试并刷新
* 若已报名足够学时和学分则开始听课
*/
// 用户得分状态
let userDataObj = await getUserData();
//规定需达到的总学时
let total_hour = userDataObj.total_hour;
//规定需达到的必修学时
let required_hour = userDataObj.required_hour;
//规定需达到的总学分
let required_credit = userDataObj.required_credit;
//用户已获得的总学时
let user_total_hour = userDataObj.user_total_hour || 0;
//用户已获得的必修学时
let user_required_hour = userDataObj.user_required_hour || 0;
//用户已获得的总学分
let user_required_credit = userDataObj.user_required_credit || 0;
/*
const csDataObj = await getCourseData();
const required_courses = csDataObj.required_courses;
*/
// 全部未完成必修课程。为同时解决学时学分问题,只关注必修课。
const courses = document.querySelectorAll('#requiredCourseTable .course');
// 初始化预期学分/学时为已得值,后续添加已报名课程数据
let pendingCredit = user_required_credit;
let pendingTime = user_total_hour;
for await (let c of courses) {
let coursePk = c.getElementsByClassName('coursePk')[0].textContent;
/*
let applyPk = '';
for await (let r of required_courses) {
if (r.course_pk === coursePk) {
applyPk = r.apply_pk;
console.log(applyPk);
}
}
*/
let jdjs = c.getElementsByClassName('jdjs')[0].textContent; // 完成进度定性
if (jdjs === '完成进度') {
let csInfo = await getCourseInfo(coursePk);
let csCredit = csInfo.courseCredit;
let csTime = csInfo.courseTime;
pendingCredit += csCredit;
pendingTime += csTime;
}
}
console.log(`已获得:必修学时:${user_required_hour},总学分${user_required_credit}`);
// 判断是否已完成。首次在新标签页打开本页显然是未完成,但刷新后可能进入已完成状态。
if (
user_total_hour >= total_hour &&
user_required_hour >= required_hour &&
user_required_credit >= required_credit
) {
console.log(`本学年任务已经完成`);
return;
} else if (pendingTime < total_hour) {
console.log(`已报名课程可得学时:${pendingTime},学分:${pendingCredit},将继续报名。`);
// 数组存储所有未报名课程故的课时数据
let timesArray = [];
// 获取所有未报名课程的子节点。若直接使用所有必修课程,可能出现课程数字相同而对已报名课程二次点击。
let noneCoursesJdpoint = document.querySelectorAll(
'#requiredCourseTable .course > .jdpoint[style]'
);
for await (let n of noneCoursesJdpoint) {
// 由子节点获取父节点从而获取课程编号
let coursePk = n.parentNode.getElementsByClassName('coursePk')[0].textContent;
let csInfo = await getCourseInfo(coursePk);
let csTime = csInfo.courseTime;
timesArray.push(csTime);
}
let longest = Math.max(...timesArray);
console.log(longest);
let indexMax = timesArray.indexOf(longest);
// 出现过该错误 indexMax === -Infinity 导致 TypeError: noneCoursesJdpoint[timesArray.indexOf(...)] is undefined
if (noneCoursesJdpoint[indexMax]) {
noneCoursesJdpoint[indexMax].parentNode.click();
} else {
location.reload(true);
}
const info = document.getElementsByClassName('layui-layer-btn0');
if (info.length === 1) {
document.getElementsByClassName('layui-layer-btn0')[0].click();
}
} else if (
pendingTime >= total_hour &&
pendingCredit < required_credit &&
// 临时处理,避免出现学分不够的误判
document.querySelectorAll('div[id^="courseExam"] > a[title]').length === 0
) {
// 因为全部学习必修课,出现本状况可能很小,暂不处理
console.log(
`已报名课程可得学时:${pendingTime},学分:${pendingCredit},预期学时已满但预期学分不够,报名最大学分课程。`
);
} else if (
pendingTime >= total_hour
// 临时处理,避免出现学分不够的误判
// && pendingCredit >= required_credit
) {
console.log('报名已完成预期');
if (user_required_hour < total_hour) {
console.log('学时未满,自动打开已报名课程,将定时关闭');
const skipLearn = async (applyPk, isNewPlayer) => {
if (!isNewPlayer && i < GM_config.get('batch')) {
let trainURL =
location.origin +
'/sfxzwsxy/jypxks/modules/train/ware/course_ware_view.jsp?applyPk=' +
applyPk +
'&courseType=1';
const openClose = GM_openInTab(trainURL, true);
i++;
// 25 分钟自动关闭
setTimeout(openClose.close, 1500000);
}
// 疑似超过 6 个课程同时学习后台不计数
else if (i >= GM_config.get('batch')) {
console.log(`已批量打开${i}个课程`);
return;
}
};
let i = 0;
for await (let c of courses) {
let applyPk = c.getElementsByClassName('applyPk')[0].textContent;
// 部分少见的新型播放器会弹出 confirm,避开为宜。
// 未报名课程 applyPk === '',故不适合使用 for length++ 循环
skipNewVideoPlayerType(applyPk, skipLearn);
}
} else if (
user_required_credit < required_credit &&
document.querySelectorAll('div[id^="courseExam"] > a[title]').length > 0
) {
console.log('学时已满,学分未满,有待考试课程');
const exams = document.querySelectorAll('div[id^=courseExam] > a[title]');
for await (let exam of exams) {
const examURL =
location.origin + '/sfxzwsxy/' + exam.getAttribute('onclick').split("'")[1];
// 魔法打开的考卷确认交卷后不能自动关闭,只得如此暴力关闭
let autoExam = GM_openInTab(examURL, true);
setTimeout(autoExam.close, 1200000);
}
}
}
}
};
// 考试提醒 - 课程考试 - 修改为在新标签页打开
const openExam = async () => {
// 第一页 #courseExam1,第二页 #courseExam2
const exams = document.querySelectorAll('div[id^=courseExam] > a[title]');
for await (let exam of exams) {
const examURL = location.origin + '/sfxzwsxy/' + exam.getAttribute('onclick').split("'")[1];
exam.href = examURL;
exam.onclick = '';
exam.target = '_blank';
}
};
// 考试提醒 - 课程考试 - 在新标签页打开对应答案
const addAnswer = async () => {
// 因网络获取与解析需要时间,与 openExam() 整合会造成继发延迟。
const csDataObj = await getCourseData();
const exam_courses = csDataObj.exam_courses;
// 第一页 #courseExam1,第二页 #courseExam2
const exams = document.querySelectorAll('div[id^=courseExam] > a[title]');
for await (let exam of exams) {
const title = exam.getAttribute('title');
for await (let e of exam_courses) {
let course_pk = '';
let answerURL = '';
if (e.course_name === title) {
course_pk = e.course_pk;
answerURL =
location.origin +
'/sfxzwsxy//jypxks/modules/train/course/subject_list.jsp?coursePk=' +
course_pk +
'&op=view';
exam.addEventListener('click', () => {
GM_openInTab(answerURL, true);
GM_notification('答案已同步在隔壁标签页打开。\n暂请考试结束后手动关闭。');
});
}
}
}
};
// 最新知识库
const openKnowledge = () => {
const knowledges = document.querySelectorAll('#knowledgeType a[title][href="#"]');
for (let knowledge of knowledges) {
const kURL =
location.origin +
'/sfxzwsxy/jypxks/modules/learn/document/learn/document_learn_text.jsp?fkNodePk=' +
knowledge
.getAttribute('onclick')
.split('(')[1]
.split(')')[0];
//console.log(kURL);
knowledge.href = kURL;
knowledge.onclick = '';
knowledge.target = '_blank';
}
};
// 并发执行
window.onload = async () => {
let funs = [addAnswer(), auto3Credit(), autoLearn(), openExam(), openKnowledge()];
for await (let f of funs) {
await f;
}
};
}
// 培训课程查询 iframe
if (location.href.endsWith('/sfxzwsxy/jypxks/modules/train/query/course_query.jsp')) {
// 清理“参加培训”和“查看”链接
const reallinks = () => {
let trains = document.querySelectorAll('#trainCourseList a[onclick^=bindBeginTrainEvents]');
for (let train of trains) {
let applyPk = train.getAttribute('onclick').split('"')[1];
let trainURL =
location.origin +
'/sfxzwsxy/jypxks/modules/train/ware/course_ware_view.jsp?applyPk=' +
applyPk +
'&courseType=1';
train.href = trainURL;
train.onclick = '';
train.target = '_blank';
}
let answers = document.querySelectorAll(
'#trainCourseList a[onclick^=bindViewCourseInfoEvents]'
);
for (let answer of answers) {
let coursePk = answer.getAttribute('onclick').split('"')[1];
let answerURL =
location.origin +
'/sfxzwsxy/jypxks/modules/train/course/course_view.jsp?coursePk=' +
coursePk;
answer.href = answerURL;
answer.onclick = '';
answer.target = '_blank';
}
};
// 保证翻页生效
let document_observer = new MutationObserver(() => {
reallinks();
});
document_observer.observe(body, {
childList: true,
subtree: true
});
// F8 批量后台新标签页打开课程播放页面
VM.registerShortcut(GM_config.get('open_unclose'), () => {
const trains = document.querySelectorAll('#trainCourseList a[onclick^=bindBeginTrainEvents]');
// 疑似超过 6 个课程同时学习后台不计数
for (let i = 0; i < GM_config.get('batch'); i++) {
let applyPk = trains[i].getAttribute('onclick').split('"')[1];
let trainURL =
location.origin +
'/sfxzwsxy/jypxks/modules/train/ware/course_ware_view.jsp?applyPk=' +
applyPk +
'&courseType=1';
GM_openInTab(trainURL, true);
if (i >= GM_config.get('batch') - 1) {
console.log(`已批量打开${i + 1}个课程`);
return;
}
}
});
}
// 培训课程查询 - 查看 - 题干 iframe
if (
// 点击 “下一页” 或 “上一页” 后 iframe 实际地址会去除 .jsp 之后的尾巴
location.pathname.startsWith('/sfxzwsxy//jypxks/modules/train/course/subject_list.jsp')
) {
// 清理“题干”链接
window.onload = () => {
const subjects = document.querySelectorAll('a[onclick^=viewSubject]');
for (let subject of subjects) {
const subjectPk = subject
.getAttribute('onclick')
.split('(')[1]
.split(')')[0];
const subjectURL =
location.origin +
'/sfxzwsxy//jypxks/modules/train/course/subject_view.jsp?subjectPk=' +
subjectPk;
subject.href = subjectURL;
subject.onclick = '';
subject.target = '_blank';
}
};
}
// 课程视频播放 跨域 iframe
if (location.href.startsWith('http://218.94.1.181:5088/unzipapp/project/ware/attach/')) {
// 旧播放器在 Windows 下要求 Flash,新播放器不兼容苹果系列。
fakeUA('Linux');
const isFlash = () => {
const html5Player = document.getElementById('course_player5'); // 旧播放器
const video_media = document.getElementById('video_media'); // 新播放器
if (video_media) {
// 新播放器用 confirm 询问是否继续学习,阻塞脚本运行,可能跳过这类课程比较好。
// 通过 iframe 源代码可以明显看到不同
// 测试例:http://218.94.1.175:8087/sfxzwsxy/jypxks/modules/train/ware/course_ware_view.jsp?applyPk=3063755&courseType=1
console.log('新播放器');
if (GM_config.get('muted')) {
video_media.querySelector('video').muted = true;
// https://developer.mozilla.org/docs/Web/Guide/Events/Media_events
video_media.querySelector('video').play();
//.next(clearInterval(noFlash));
}
} else if (html5Player) {
console.log('旧播放器');
// 静音模式下自动播放无需用户授权
// https://developer.mozilla.org/docs/Web/Media/Autoplay_guide#Autoplay_availability
if (GM_config.get('muted')) {
html5Player.muted = true;
// https://developer.mozilla.org/docs/Web/Guide/Events/Media_events
html5Player.play().next(clearInterval(noFlash));
}
} else {
// 旧版本播放器能否成功调用 HTML5 似乎是玄学问题,检测不到 HTML5 播放器则刷新
location.reload(true);
}
};
const noFlash = setInterval(isFlash, 1000);
const learn = () => {
// 自动从课程封面进入播放页面
if (document.querySelector('img[src="courseware/iconImg/z3.png"]')) {
document.querySelector('img[src="courseware/iconImg/z3.png"]').click();
}
// 老播放器用的 confirm 对话框手动点击即暂停,新版的 alert 无法模拟点击但手动点击不影响后台播放
if (document.getElementById('cancel')) {
//document.getElementById('confirm').click(); // 继续学习;可能需要多次重复才能完成一课时。
document.getElementById('cancel').click(); // 大侠还请重新来过
}
};
const option = () => {
// 旧播放器自动做题,找不到测试例进一步优化。
if (document.querySelectorAll('div.option>label>input[name="que"]').length > 0) {
document.querySelectorAll('div.option>label>input[name="que"]')[0].click();
document.querySelectorAll('div.option>label>input[name="que"]')[1].click(); // 兼容多选题
document.getElementsByClassName('button')[0].click(); // 提交
if (document.getElementsByClassName('button_xia').length === 1) {
document.getElementsByClassName('button_xia')[0].click(); // 下一题
}
if (document.getElementsByClassName('button_wan').length === 1) {
document.getElementsByClassName('button_wan')[0].click(); // 完成
}
// .click() 有反向操作风险
document.getElementById('course_player5').play();
}
};
let document_observer = new MutationObserver(() => {
learn();
option();
});
document_observer.observe(body, {
attributes: true,
subtree: true
});
}
// 在线考试 - 课程考试 iframe
if (
location.pathname.startsWith(
'/sfxzwsxy/jypxks/modules/examination/course_examine/course_exam_list.jsp'
)
) {
// 清理“参加考试”链接,新标签页打开考试及答案。
window.onload = () => {
const exams = document.querySelectorAll('a[href="#"][onclick^=openWindowFullScreen]');
for (let exam of exams) {
const examURL = location.origin + '/sfxzwsxy/' + exam.getAttribute('onclick').split("'")[1];
const coursePk = examURL.split('course_pk=')[1].split('&')[0];
const answerURL =
location.origin +
'/sfxzwsxy//jypxks/modules/train/course/subject_list.jsp?coursePk=' +
coursePk +
'&op=view';
exam.href = examURL;
exam.onclick = '';
exam.target = '_blank';
exam.addEventListener('click', () => {
GM_openInTab(answerURL, true);
GM_notification('答案已同步在隔壁标签页打开。\n暂请考试结束后手动关闭。');
});
}
};
}
// 考试
if (
location.pathname ===
'/sfxzwsxy/jypxks/modules/examination/course_examine/course_examine_test.jsp'
) {
window.onload = async () => {
if (passPhrase) {
// 本考试所有试题
let topics = document.getElementsByClassName('topic-tms');
for await (let topic of topics) {
// 题号
let pkid = topic.querySelector('a[pkid]').getAttribute('pkid');
// 本题答案
let subjectDataMap = await getSubjectData(pkid);
// 本题选项
let options = topic.querySelectorAll('.tms-Right-wrong > p > a');
for (let option of options) {
let optionText = option.textContent.trim();
if (subjectDataMap.get('questionType') === '判断题') {
if (option.textContent.trim() === subjectDataMap.get('judgementAnswer')) {
option.click();
}
} else {
// 选择题选项内容带着序号与空格,如“A ”,故获取第三个开始的子串
if (subjectDataMap.get(optionText.substring(2)) === '是') {
option.click();
}
}
}
}
// 交卷
if (document.getElementsByClassName('subline _submit').length === 1) {
document.getElementsByClassName('subline _submit')[0].click();
}
// 确认
if (document.getElementsByClassName('layui-layer-btn0').length === 1) {
document.getElementsByClassName('layui-layer-btn0')[0].click();
}
}
};
}