Greasy Fork

Greasy Fork is available in English.

上海开大助手

上海开放大学学习平台,自动刷课,题目共享

目前为 2025-02-28 提交的版本。查看 最新版本

// ==UserScript==
// @name         上海开大助手
// @namespace    http://tampermonkey.net/
// @homepage     https://shkd.script.woca.fun
// @description  上海开放大学学习平台,自动刷课,题目共享
// @author       AchieveHF
// @version      1.0.12
// @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/[email protected]/dist/layui.js
// @license MIT
// @run-at document-idle
// ==/UserScript==

(function() {
        'use strict';


        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/';
        // const apiDomain = 'http://localhost:8000/';

        let link = parseURLDetails();
        if (link.domain == 'live.eeo.cn') {
            setTimeout(() => {
                //第三方回放页面
                $('#player_html5_api')[0].muted = true;
                $('#player_html5_api')[0].play()
                return;
            }, 3000)
        }
        switch (link.path) {
            case '/study/assignment/preview.aspx':
                //插入工具
                $.ajax({
                        url: apiDomain + '/api/getBody', //获取题目接口
                        type: 'GET',
                        data: {
                            path: link.path,
                        },
                        success: function(data) {
                            $('.e-q-t').append(data)
                        }
                    })
                    //监听工具使用
                $('body').on('click', '.searchQuestion', function() {
                    let q = getQuestion($(this).parent().parent())
                    var index = layer.load(0, { shade: false });
                    $.ajax({
                        url: apiDomain + '/api/searchQuestion', //获取题目接口
                        type: 'POST',
                        data: {
                            question: q,
                        },
                        success: (res) => {
                            layer.close(index);
                            if (res.code == 200) {
                                $(this).parent().find('.result').html('参考答案:<pre>' + res.data.answer + '</pre>')
                                $(this).parent().parent().find('.e-a .ErichText').each((index, elem) => {
                                    // 获取当前选项的文本,并去掉多余的换行符和空格
                                    const optionText = $(elem).text().trim().replaceAll('\n', '');

                                    // 获取答案,按 '\n' 分隔为数组
                                    const answerList = res.data.answer.split('\n').map(ans => ans.trim());

                                    // 检查当前选项是否在答案数组中
                                    if (answerList.includes(optionText)) {
                                        $(elem).css('background-color', '#F5C16B'); // 设置背景色
                                    }
                                });
                                layer.msg(res.msg)
                            } else {
                                layer.msg(res.msg)
                            }
                        }
                    })
                })
                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(`<div class="sh-toc2-pd layui-form">
                                <a href="https://shkd.script.woca.fun">
                      <span class="module" style="width:36px;">  <img src="https://shkd.script.woca.fun/icon.png" style="width: 15px"></span>
                      <span title="上海开大助手" class="name">上海开大助手
                      </span></a>
                      <span class="name">
                      <button type="button" class="layui-btn ${GM_getValue('autoPlay') ? 'layui-bg-red' : 'layui-bg-blue'}" id="autoPlay">点击${GM_getValue('autoPlay') ? '关闭' : '开启'}自动刷课</button>
                        </span>
</div>
                  </div>
                  <div class="sh-toc3" style="background-position: -37px 0px;">
                    <table width="100%" class="course_catalog">
                        <tbody>
                            <tr data-id="mxb9amcxepbejp7twioola" class="tr_topic">
                                <td width="36">
                                    <div class="sh-toc3-topic"> 1</div>
                                </td>
                                <td class="sh-toc3-dot" width="14"><span class="am-icon am-icon-circle-o"></span></td>
                                <td title="必看课程">
                                    <div class="sh-toc3-desc show_topic">
                                        <span class="am-icon show_cell_list am-icon-caret-down"></span>
                                        <a title="必看课程">必看课程</a>
                                    </div>
                                    <div class="sh-toc3-children div_show_cell" name="showcell" data-isleaf="False" style="overflow: hidden; display: block;">
                                        <ul style="padding-left: 0px; margin-bottom: 0px;">
                                            <li class="cell_info1">
                                        ${mustCourse[link.params.CourseOpenId].map(item => `
                                            <a ${link.params.cellId == item.cellId ? 'class="active"' : ''} href="${item.url}" title="${item.title}">${item.title} <span class="sh-res-b">${item.type}</span><span class="sh-res-b">${item.status}</span></a>
                                        `).join('')}
                                        </li>
                                        </ul>
                                    </div>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
                  `)
            } else {
                //没有找到必看
                console.log(mustCourse)
            }
        }, 2000)

        setTimeout(() => {
            if (GM_getValue('autoPlay')) {
                autoPlayStart()
            }
        }, 5000)
        // <div class="hd">
        //         <ul> 
        //             <li class="on">课程目录

        //             </li>

        //         </ul>
        //     <li><img src="https://shkd.script.woca.fun/icon.png" style="width: 15px">必看课程</li></div>

        $('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('先点击【查找】检测未完成的直播课<br/>点击后会弹出一些弹窗,不需要进行任何操作<br/>查找成功后点击【一键打开直播课】,点击后不需要进行任何操作会自动播放所有未完成的直播课', {
                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':
        //插入页面工具
        $.ajax({
            url: apiDomain + '/api/getBody',//获取题目接口
            type: 'GET',
            data: {
                path: link.path,
            },
            success: function (data) {
                $('.e-quest-header').before(data)
            }
        })
        //监听工具动作
        $('body').on('click', '.share', function () {
            //作业结果页面
            let q_a = [];
            //获取所有回答正确的题
            $('.e-q-t').each(function (index, element) {
                //大题
                if ($(element).find('.e-q-quest .e-q-quest').length > 0) {
                    if ($(element).find('.e-q-l .e-q-right').length > 0) {
                        let topic = $(element).find('.e-q-q .ErichText').first().html()
                        let topic_text = $(element).find('.e-q-q .ErichText').first().text().trim().replaceAll('\n', '')
                        $(element).find('.e-q-quest .e-q-quest').each((index, elem) => {
                            let q = {
                                topic: topic,
                                topic_text: topic_text,
                                type: '',
                                question: '',
                                question_text: '',
                                answer: '',
                                answer_options: '',
                            }
                            q = getRightQuestion(elem, q, true);
                            pushQuestion(q_a, q, element)
                            // pushQuestion(q_a,q,element)
                        })
                    }
                } else {
                    let q = {
                        topic: '',
                        topic_text: '',
                        type: '',
                        question: '',
                        question_text: '',
                        answer: '',
                        answer_options: '',
                    }
                    q = getRightQuestion(element, q);
                    if (q !== false) {
                        pushQuestion(q_a, q, element)
                    }
                }

            })
            //发送请求记录到题库
            $.ajax({
                url: apiDomain + '/api/saveQuestions',//记录题目接口
                type: 'POST',
                data: {
                    q_a: q_a,
                    params: link.params,
                    userData: JSON.parse(GM_getValue('userData'))
                },
                success: function (data) {
                    layer.msg(data.msg)
                }
            })
        })
        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)
                }
            })
            console.log(must)
            if (must.length > 0) {
                mustCourse[link.params.courseOpenId] = must
                GM_setValue('mustCourse', mustCourse)
                console.log(GM_getValue('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 '/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-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('<img src="https://shkd.script.woca.fun/icon.png" style="width: 15px">没有未完成的必看课程了')
        }
    } else {
        if (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('<img src="https://shkd.script.woca.fun/icon.png" style="width: 15px">没有未完成的必看课程了')
                }
            })
        }else if(currentCell.type.includes('文档')) {
            //文档自动翻页
            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('<img src="https://shkd.script.woca.fun/icon.png" style="width: 15px">没有未完成的必看课程了')
                    }
                }
            },3000)
        }
    }
}

})();