Introduction
这个记得是jiepeng哥一开始写了个只能查看作业分数的脚本,后来无意间发现了一个更好的包,后面便结合着gpt改良了一下;
能够将作业和考试的分数罗列在右下角建出来的面板之中
Usage
将其放入油猴插件中启用即可
Codes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 (function ( ) { 'use strict' ; const courseUrlMatch = window .location .pathname .match (/\/course\/(\d+)\// ); if (!courseUrlMatch) { console .error ('Unable to find course ID in the URL.' ); return ; } const courseId = courseUrlMatch[1 ]; const scoreContainer = document .createElement ('div' ); scoreContainer.id = 'score-container' ; scoreContainer.style .position = 'fixed' ; scoreContainer.style .bottom = '0' ; scoreContainer.style .right = '0' ; scoreContainer.style .zIndex = '1000' ; scoreContainer.style .backgroundColor = 'white' ; scoreContainer.style .border = '1px solid black' ; scoreContainer.style .maxHeight = '300px' ; scoreContainer.style .overflowY = 'auto' ; scoreContainer.style .padding = '10px' ; scoreContainer.style .width = '350px' ; document .body .appendChild (scoreContainer); let data_first; let data_second; const apiUrl = `https://courses.zju.edu.cn/api/course/${courseId} /activity-reads-for-user` ; fetch (apiUrl) .then (response => response.json ()) .then (data => { console .log ('Data from main API:' , data); const data_api = data; const apiUrl1 = `https://courses.zju.edu.cn/api/course/${courseId} /homework-scores?fields=id,title` ; const apiUrl2 = `https://courses.zju.edu.cn/api/courses/${courseId} /exams` ; return Promise .all ([fetch (apiUrl1), fetch (apiUrl2), data_api]); }) .then (async ([response1, response2, data_api]) => { data_first = await response1.json (); data_second = await response2.json (); console .log ('Data from API1:' , data_first); console .log ('Data from API2:' , data_second); if (!data_first || !data_first.homework_activities ) { console .error ('Homework activities data is missing.' ); return ; } if (!data_second || !data_second.exams ) { console .error ('Exams data is missing.' ); return ; } const data_final = merge (data_second.exams , data_first.homework_activities , data_api.activity_reads ); displayScores (data_final); }) .catch (error => console .error ('Error fetching the data:' , error)); function merge (examsActivities, homeworkActivities, activityReads ) { const homeworkMap = new Map (); const examsMap = new Map (); homeworkActivities.forEach (activity => { homeworkMap.set (activity.id , activity.title ); }); examsActivities.forEach (exam => { examsMap.set (exam.id , exam.title ); }); const updatedActivityReads = activityReads.map (activityRead => { let title = 'Unknown Title' ; if (homeworkMap.has (activityRead.activity_id )) { title = homeworkMap.get (activityRead.activity_id ); } else if (examsMap.has (activityRead.activity_id )) { title = examsMap.get (activityRead.activity_id ); } return { ...activityRead, title }; }); console .log ('Updated activity reads:' , updatedActivityReads); return updatedActivityReads; } function displayScores (activityReads ) { if (activityReads.length === 0 ) { scoreContainer.innerHTML = `<strong>No homework data available for course ${courseId} .</strong>` ; return ; } activityReads.forEach (activity => { const entry = document .createElement ('div' ); entry.style .borderBottom = '1px solid #ddd' ; entry.style .marginBottom = '5px' ; entry.style .paddingBottom = '5px' ; if (activity.activity_type === "learning_activity" ) { if (activity.title != 'Unknown Title' ) { entry.innerHTML = `<strong>Title:</strong> ${activity.title} <br> <strong>Score:</strong> ${activity.data.score} ` ; } else { entry.innerHTML = `<strong>其他学习活动</strong>` ; const toggleButton = document .createElement ('button' ); toggleButton.innerText = '显示详情' ; toggleButton.style .display = 'block' ; toggleButton.style .marginTop = '5px' ; const detailsContainer = document .createElement ('div' ); detailsContainer.style .display = 'none' ; detailsContainer.style .marginTop = '5px' ; for (const key in activity) { if (activity.hasOwnProperty (key)) { const detailEntry = document .createElement ('div' ); detailEntry.innerHTML = `<strong>${key} :</strong> ${activity[key]} ` ; detailsContainer.appendChild (detailEntry); } } toggleButton.addEventListener ('click' , () => { if (detailsContainer.style .display === 'none' ) { detailsContainer.style .display = 'block' ; toggleButton.innerText = '隐藏详情' ; } else { detailsContainer.style .display = 'none' ; toggleButton.innerText = '显示详情' ; } }); entry.appendChild (toggleButton); entry.appendChild (detailsContainer); } } else if (activity.activity_type === "exam_activity" ) { entry.innerHTML = `<strong>Type:</strong> ${activity.activity_type} <br> <strong>Title:</strong> ${activity.title} <br> <strong>Score:</strong> ${activity.data.score} ` ; } else { entry.innerHTML = `<strong>Title:</strong> ${activity.title} <br> <strong>Score:</strong> No data available` ; } scoreContainer.appendChild (entry); }); } })();
声明
(叠甲x)本插件作为学习使用,造成的一切后果均由使用人承担,本人概不负责