├── pj-auto.js ├── pj.js └── README.md /pj-auto.js: -------------------------------------------------------------------------------- 1 | var ungraded; 2 | var numOfUngraded = $('tr:contains("未评")').length; 3 | 4 | function waitForAppearance(element, callBack) { 5 | if($(".alert-modal").length) { 6 | return; 7 | } 8 | window.setTimeout( function() { 9 | if($(element).length){ 10 | if(element == 'div.col-sm-8:contains("当前评价课程为")') { 11 | autoGrade(); 12 | } else { 13 | waitForDisappearance(); 14 | } 15 | }else{ 16 | waitForAppearance(element, callBack); 17 | } 18 | }, 200); 19 | } 20 | 21 | function waitForDisappearance() { 22 | window.setTimeout( function() { 23 | if($(".success-modal").length == 0) { 24 | waitForRefresh(); 25 | } else { 26 | waitForDisappearance(); 27 | } 28 | }, 200); 29 | } 30 | 31 | function waitForRefresh() { 32 | window.setTimeout( function() { 33 | var num = $('tr:contains("未评")').length; 34 | if(num != numOfUngraded) { 35 | numOfUngraded = num; 36 | gotoNext(); 37 | } else { 38 | waitForRefresh(); 39 | } 40 | }, 5000); 41 | } 42 | 43 | function gotoNext() { 44 | ungraded = $('tr:contains("未评"):first'); 45 | if(ungraded.length == 0) return; 46 | 47 | $("#tempGrid").setSelection(ungraded.attr("id")); 48 | 49 | waitForAppearance('div.col-sm-8:contains("当前评价课程为")', autoGrade); 50 | } 51 | 52 | function autoGrade() { 53 | $(".input-xspj-1 label input").prop("checked",true); 54 | let pjContent = $('#jsxm').html() + "老师辛苦了!"; 55 | $("textarea.input-zgpj").text(pjContent); 56 | $("#btn_xspj_tj").click(); 57 | $('#btn_ok').click(); 58 | waitForRefresh(); 59 | } 60 | 61 | gotoNext(); -------------------------------------------------------------------------------- /pj.js: -------------------------------------------------------------------------------- 1 | var ungraded; 2 | var numOfUngraded = $('tr:contains("未评")').length; 3 | 4 | function waitForAppearance(element, callBack) { 5 | if($(".alert-modal").length) { 6 | return; 7 | } 8 | window.setTimeout( function() { 9 | if($(element).length){ 10 | if(element == 'div.col-sm-8:contains("当前评价课程为")') { 11 | autoGrade(); 12 | } else { 13 | waitForDisappearance(); 14 | } 15 | }else{ 16 | waitForAppearance(element, callBack); 17 | } 18 | }, 200); 19 | } 20 | 21 | function waitForDisappearance() { 22 | window.setTimeout( function() { 23 | if($(".success-modal").length == 0) { 24 | waitForRefresh(); 25 | } else { 26 | waitForDisappearance(); 27 | } 28 | }, 200); 29 | } 30 | 31 | function waitForRefresh() { 32 | window.setTimeout( function() { 33 | var num = $('tr:contains("未评")').length; 34 | if(num != numOfUngraded) { 35 | numOfUngraded = num; 36 | gotoNext(); 37 | } else { 38 | waitForRefresh(); 39 | } 40 | }, 5000); 41 | } 42 | 43 | function gotoNext() { 44 | ungraded = $('tr:contains("未评"):first'); 45 | if(ungraded.length == 0) return; 46 | 47 | $("#tempGrid").setSelection(ungraded.attr("id")); 48 | 49 | waitForAppearance('div.col-sm-8:contains("当前评价课程为")', autoGrade); 50 | } 51 | 52 | function autoGrade() { 53 | $(".input-xspj-1 label input").prop("checked",true); 54 | let courseInfo = $('div.col-sm-8:contains("当前评价课程为")').text(); 55 | courseInfo = courseInfo.substring(courseInfo.indexOf("当前"), courseInfo.indexOf(";")) 56 | $("textarea.input-zgpj").text(prompt(courseInfo + ",主观题填什么?")); 57 | $("#btn_xspj_tj").click(); 58 | waitForAppearance(".success-modal", waitForDisappearance); 59 | } 60 | 61 | gotoNext(); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 上海交通大学自动评教脚本(Auto Grade) 2 | 3 | ## Warning (2022/5/14) 4 | 5 | 现在教学信息服务网有检测脚本功能,每门课可以自动选客观题/填主观题,但是需要手动点击提交。 6 | 7 | ## 目录(Table of Contents) 8 | 9 | - [中文使用指南](#评教脚本使用指南) 10 | - [English User Guide](#user-guide) 11 | 12 | ## 评教脚本使用指南 13 | 14 | ### 已知问题 15 | 16 | - 脚本暂时不支持自动翻页,i.e.只支持自动评价前15门课,第二页之后的还是要手动评教。如果有需求,请在issue中提出。 17 | - 如果用户网络延迟过高,可能导致脚本无法正常工作。 18 | 19 | ### 脚本概述 20 | 21 | 本脚本有两个版本: 22 | 23 | - **全自动**:开始运行后,所有的主观题会自动填入*教师姓名+“老师辛苦了”*,**不需要做任何额外操作**。如果你想要默认填入其他内容,在代码中搜索“老师辛苦了”,替换成其他内容即可。 24 | - **半自动**:用户需要手动输入每门课的主观题内容,浏览器会使用对话框提示用户何时输入。在一门课评教完成后,用户必须手动确认“评教成功”才能继续。 25 | 26 | ### 第一步 27 | 28 | 进入你的**学生评价**界面。 29 | 30 | ### 第二步 31 | 32 | 如果您想使用**全自动**版本,请**复制**如下代码: 33 | 34 | ```javascript 35 | var ungraded; 36 | var numOfUngraded = $('tr:contains("未评")').length; 37 | 38 | function waitForAppearance(element, callBack) { 39 | if($(".alert-modal").length) { 40 | return; 41 | } 42 | window.setTimeout( function() { 43 | if($(element).length){ 44 | if(element == 'div.col-sm-8:contains("当前评价课程为")') { 45 | autoGrade(); 46 | } else { 47 | waitForDisappearance(); 48 | } 49 | }else{ 50 | waitForAppearance(element, callBack); 51 | } 52 | }, 200); 53 | } 54 | 55 | function waitForDisappearance() { 56 | window.setTimeout( function() { 57 | if($(".success-modal").length == 0) { 58 | waitForRefresh(); 59 | } else { 60 | waitForDisappearance(); 61 | } 62 | }, 200); 63 | } 64 | 65 | function waitForRefresh() { 66 | window.setTimeout( function() { 67 | var num = $('tr:contains("未评")').length; 68 | if(num != numOfUngraded) { 69 | numOfUngraded = num; 70 | gotoNext(); 71 | } else { 72 | waitForRefresh(); 73 | } 74 | }, 5000); 75 | } 76 | 77 | function gotoNext() { 78 | ungraded = $('tr:contains("未评"):first'); 79 | if(ungraded.length == 0) return; 80 | 81 | $("#tempGrid").setSelection(ungraded.attr("id")); 82 | 83 | waitForAppearance('div.col-sm-8:contains("当前评价课程为")', autoGrade); 84 | } 85 | 86 | function autoGrade() { 87 | $(".input-xspj-1 label input").prop("checked",true); 88 | let pjContent = $('#jsxm').html() + "老师辛苦了!"; 89 | $("textarea.input-zgpj").text(pjContent); 90 | $("#btn_xspj_tj").click(); 91 | $('#btn_ok').click(); 92 | waitForRefresh(); 93 | } 94 | 95 | gotoNext(); 96 | ``` 97 | 98 | 如果您想使用**半自动**版本,请**复制**如下代码: 99 | 100 | ```javascript 101 | var ungraded; 102 | var numOfUngraded = $('tr:contains("未评")').length; 103 | 104 | function waitForAppearance(element, callBack) { 105 | if($(".alert-modal").length) { 106 | return; 107 | } 108 | window.setTimeout( function() { 109 | if($(element).length){ 110 | if(element == 'div.col-sm-8:contains("当前评价课程为")') { 111 | autoGrade(); 112 | } else { 113 | waitForDisappearance(); 114 | } 115 | }else{ 116 | waitForAppearance(element, callBack); 117 | } 118 | }, 200); 119 | } 120 | 121 | function waitForDisappearance() { 122 | window.setTimeout( function() { 123 | if($(".success-modal").length == 0) { 124 | waitForRefresh(); 125 | } else { 126 | waitForDisappearance(); 127 | } 128 | }, 200); 129 | } 130 | 131 | function waitForRefresh() { 132 | window.setTimeout( function() { 133 | var num = $('tr:contains("未评")').length; 134 | if(num != numOfUngraded) { 135 | numOfUngraded = num; 136 | gotoNext(); 137 | } else { 138 | waitForRefresh(); 139 | } 140 | }, 5000); 141 | } 142 | 143 | function gotoNext() { 144 | ungraded = $('tr:contains("未评"):first'); 145 | if(ungraded.length == 0) return; 146 | 147 | $("#tempGrid").setSelection(ungraded.attr("id")); 148 | 149 | waitForAppearance('div.col-sm-8:contains("当前评价课程为")', autoGrade); 150 | } 151 | 152 | function autoGrade() { 153 | $(".input-xspj-1 label input").prop("checked",true); 154 | let courseInfo = $('div.col-sm-8:contains("当前评价课程为")').text(); 155 | courseInfo = courseInfo.substring(courseInfo.indexOf("当前"), courseInfo.indexOf(";")) 156 | $("textarea.input-zgpj").text(prompt(courseInfo + ",主观题填什么?")); 157 | $("#btn_xspj_tj").click(); 158 | waitForAppearance(".success-modal", waitForDisappearance); 159 | } 160 | 161 | gotoNext(); 162 | ``` 163 | 164 | ### 第三步 165 | 166 | 回到学生评价界面,打开浏览器的控制台。如果您不知道快捷键,请**右键点击**页面空白处,在弹出菜单中点击**检视/Inspect**或含义类似的选项(因浏览器而异)。然后,会有一个**内嵌窗口**从您浏览器中弹出,在顶部的**水平菜单**中选择**Console**。 167 | 168 | ### 第四步 169 | 170 | 将代码**粘贴**到下方的输入框中。再按下**回车键**。 171 | 172 | ### 第五步 173 | 174 | 开始评教。目前脚本**不会**在评教结束时提示用户。如果想要终止自动评教,请**刷新页面**。 175 | 176 | ## User Guide 177 | 178 | ### Known issues 179 | 180 | - This script only works for the first page of courses, namely the first 15 courses. 181 | - The script might not work properly under unstable or extremely laggy network conditions. 182 | 183 | ### Overview 184 | 185 | There are two versions of the script: 186 | 187 | - **Auto**: This version will automatically grade all ungraded courses non-stop, filling in the "主观题" section with pre-defined text. The default text is *教师姓名 + "老师辛苦了!"*. If you want something else, search for *老师辛苦了* in the code and replace it. 188 | - **Semi-auto**: This version wil lnot automatically fill in the "主观题" section: a prompt will pop up asking you to fill in whatever you want to say about the course. And after grading a course, you will have to confirm "提交成功" in order to proceed. 189 | 190 | ### Step 1 191 | 192 | Enter "Students evaluation" page. 193 | 194 | ### Step 2 195 | 196 | For the **auto** version, **copy** the code snippet below: 197 | 198 | ```javascript 199 | var ungraded; 200 | var numOfUngraded = $('tr:contains("未评")').length; 201 | 202 | function waitForAppearance(element, callBack) { 203 | if($(".alert-modal").length) { 204 | return; 205 | } 206 | window.setTimeout( function() { 207 | if($(element).length){ 208 | if(element == 'div.col-sm-8:contains("当前评价课程为")') { 209 | autoGrade(); 210 | } else { 211 | waitForDisappearance(); 212 | } 213 | }else{ 214 | waitForAppearance(element, callBack); 215 | } 216 | }, 200); 217 | } 218 | 219 | function waitForDisappearance() { 220 | window.setTimeout( function() { 221 | if($(".success-modal").length == 0) { 222 | waitForRefresh(); 223 | } else { 224 | waitForDisappearance(); 225 | } 226 | }, 200); 227 | } 228 | 229 | function waitForRefresh() { 230 | window.setTimeout( function() { 231 | var num = $('tr:contains("未评")').length; 232 | if(num != numOfUngraded) { 233 | numOfUngraded = num; 234 | gotoNext(); 235 | } else { 236 | waitForRefresh(); 237 | } 238 | }, 5000); 239 | } 240 | 241 | function gotoNext() { 242 | ungraded = $('tr:contains("未评"):first'); 243 | if(ungraded.length == 0) return; 244 | 245 | $("#tempGrid").setSelection(ungraded.attr("id")); 246 | 247 | waitForAppearance('div.col-sm-8:contains("当前评价课程为")', autoGrade); 248 | } 249 | 250 | function autoGrade() { 251 | $(".input-xspj-1 label input").prop("checked",true); 252 | let pjContent = $('#jsxm').html() + "老师辛苦了!"; 253 | $("textarea.input-zgpj").text(pjContent); 254 | $("#btn_xspj_tj").click(); 255 | $('#btn_ok').click(); 256 | waitForRefresh(); 257 | } 258 | 259 | gotoNext(); 260 | ``` 261 | 262 | For the **semi-auto** version, **copy** the code snippet below: 263 | 264 | ```javascript 265 | var ungraded; 266 | var numOfUngraded = $('tr:contains("未评")').length; 267 | 268 | function waitForAppearance(element, callBack) { 269 | if($(".alert-modal").length) { 270 | return; 271 | } 272 | window.setTimeout( function() { 273 | if($(element).length){ 274 | if(element == 'div.col-sm-8:contains("当前评价课程为")') { 275 | autoGrade(); 276 | } else { 277 | waitForDisappearance(); 278 | } 279 | }else{ 280 | waitForAppearance(element, callBack); 281 | } 282 | }, 200); 283 | } 284 | 285 | function waitForDisappearance() { 286 | window.setTimeout( function() { 287 | if($(".success-modal").length == 0) { 288 | waitForRefresh(); 289 | } else { 290 | waitForDisappearance(); 291 | } 292 | }, 200); 293 | } 294 | 295 | function waitForRefresh() { 296 | window.setTimeout( function() { 297 | var num = $('tr:contains("未评")').length; 298 | if(num != numOfUngraded) { 299 | numOfUngraded = num; 300 | gotoNext(); 301 | } else { 302 | waitForRefresh(); 303 | } 304 | }, 5000); 305 | } 306 | 307 | function gotoNext() { 308 | ungraded = $('tr:contains("未评"):first'); 309 | if(ungraded.length == 0) return; 310 | 311 | $("#tempGrid").setSelection(ungraded.attr("id")); 312 | 313 | waitForAppearance('div.col-sm-8:contains("当前评价课程为")', autoGrade); 314 | } 315 | 316 | function autoGrade() { 317 | $(".input-xspj-1 label input").prop("checked",true); 318 | let courseInfo = $('div.col-sm-8:contains("当前评价课程为")').text(); 319 | courseInfo = courseInfo.substring(courseInfo.indexOf("当前"), courseInfo.indexOf(";")) 320 | $("textarea.input-zgpj").text(prompt(courseInfo + ",主观题填什么?")); 321 | $("#btn_xspj_tj").click(); 322 | waitForAppearance(".success-modal", waitForDisappearance); 323 | } 324 | 325 | gotoNext(); 326 | ``` 327 | 328 | ### Step 3 329 | 330 | Return to Student Evaluation page, and open the console of your browser. If you do not now the keyboard shortcut, please **right click** the page, click **Insepct** or something of similar meaning in the pop-up menu. An embedded window will pop up in your browser. On the top menu bar, select **Console**. 331 | 332 | ### Step 4 333 | 334 | **Paste** the code in the input section and press **Enter**. 335 | 336 | ### Step 5 337 | 338 | The grading starts。Current, the user will not be informed of the end of evaluation。If you want to terminate the process, simply **refresh the page**. 339 | --------------------------------------------------------------------------------