123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- /**
- * ЭЛЕКТРОННЫЙ ЖУРНАЛ «ШКАЛА»: ДНЕВНИК УЧАЩЕГОСЯ
- * Copyright © 2021, А.М.Гольдин. Modified BSD License
- */
- "use strict";
- // Объекты с предметами и учителями (подгружаются в конце страницы)
- let jrnSbList = {}, jrnThList = {};
- // Контент страницы - объект jrnArr:
- // {
- // "8Б-мальч_s410_ivanov": {
- // d601: ["Африка", "Учить реки", 8, "нн5"],
- // ...
- // }
- // ...
- // }
- // Для внеурочной деятельности (предмет s000) вместо кода предмета
- // в ключе будет код групы типа "23Б"
- let jrnArr = {};
- // Отображение контента по данному предмету-учителю на странице,
- // либо по всем предметам, если grSbTh == '' (первая опция селекта)
- const jrnContLoad = async () => {
- let cont;
- let grSbTh = dqs("#jrnSubj").value;
- // Если grSbTh == '', выдаем таблицу текущих отметок по всем предметам
- if (!grSbTh) {
- cont = "<table id='allSb'><tr><th>Предмет, учитель</th>";
- // Формируем заголовочную строку со списком учебных периодов,
- // заодно массив pers ключей нужных нам учебных периодов
- // (без дублирующих типа полугодия или учебного года)
- let pers = [], perstart = [];
- for (let period in DTSIT) {
- if (perstart.includes(DTSIT[period][2])) continue;
- perstart.push(DTSIT[period][2]);
- pers.push(period);
- cont += `<th>${DTSIT[period][0]}</th>`;
- }
- cont += "</tr>";
- // Цикл по всем предметам (один предмет - одна строка таблицы)
- for (let sbCode of Object.keys(jrnArr).sort((a,b) => {
- let x = a.split('_')[1].slice(1),
- y = b.split('_')[1].slice(1);
- return Number(x)-Number(y);
- })) {
- let sbCont = jrnArr[sbCode];
- let [grName, sbName, tchName] = sbCode.split('_'),
- gruppa = grName.includes('-') ? `${grName.split('-')[1]}; ` : '',
- subjStr = `${jrnSbList[sbName]}<br>${gruppa + jrnThList[tchName]}`;
- cont += `<tr><td>${subjStr}</td>`;
- // Объект отметок по данному предмету с ключами - кодами периодов
- let grads = {};
- for (let perCod of pers) grads[perCod] = '';
- for (let dtCod of Object.keys(sbCont).sort()) {
- let grArr = sbCont[dtCod];
- if (dtCod.length > 4) continue; // только текущие отметки
- if (grArr[3] == undefined) continue;
- let otm = grArr[3].toString().replace(/^999$/, "зач") + ' ';
- if (grArr[0].includes("Экзамен")) otm = `<b>${otm}</b>`;
- let perNum = whereis(dtCod); // число! whereis - в ini.js
- if (perNum == 99) continue;
- let period = Object.keys(DTSIT)[perNum - 1];
- if (grads[period] !== undefined) grads[period] += otm;
- }
- // Подписываем ячейки с отметками в строку таблицы
- for (let perCod of pers) cont += `<td>${grads[perCod].trim()}</td>`;
- cont += "</tr>";
- }
- dqs("#jrnCont").innerHTML = cont + "</table>";
- return;
- }
- // Если grSbTh != '', выдаем таблицу по выбранному предмету
- let grades = jrnArr[grSbTh] || {},
- wArr = ['0', '0.5', '', '1.5', '2.0', '2.5', '3.0', '3.5', '4.0'];
- cont = "<table><tr><th>Дата</th><th>Вес</th><th>Тема урока</th>"
- + "<th>Дом. задание</th><th>Отм.</th></tr>";
-
- if (!Object.keys(grades).length) {
- dqs("#jrnCont").innerHTML = "<b>Пока ничего нет.</b>";
- return;
- }
-
- let dates = Object.keys(grades).sort();
-
- for (let d of dates) {
- // Пропущенные (учителем) уроки не показываем
- if (grades[d][2] > 8) continue;
-
- let dt = dateConv(d), cls = '', stTd = '';
- let otm = (typeof grades[d][3] != "undefined") ? grades[d][3] : '';
- otm = otm.replace(/^999$/, "зач");
- if (grades[d][0].includes("Экзамен")) {
- cls = " class='it'";
- stTd = " style='color:black'";
- }
- if (d.length > 4) {
- dt = DTSIT[d][0];
- cls = " class='it'";
- otm = otm.toString().replace(/^0$/, "н/а");
- }
- cont += `<tr${cls}>`
- + `<td>${dt}</td><td${stTd}>${wArr[grades[d][2]]}</td>`
- + `<td>${grades[d][0]}</td><td>${grades[d][1]}</td>`
- + `<td>${otm}</td></tr>`;
- }
- dqs("#jrnCont").innerHTML = cont + "</table>";
-
- // Выводим статистику
- let stat = `<h3>Статистика</h3><table id="jrnStat"><tr><th> </th>`
- + `<th>Сумма баллов<br>(с учетом весов)</th>`
- + `<th>Средне­взвешенный<br>балл</th>`
- + `<th>Пропущено<br>уроков</th></tr>`;
- // Цикл по периодам учебного года
- for (let itDate of Object.keys(DTSIT)) {
- // Cумма весов, сумма отметок с весами, среднее, пропуски
- let wSum = 0, sum = 0, av = 0, abs = 0;
-
- // Цикл по всем темам d601: ["Африка", "Учить реки", 8, "нн5"]
- for (let dt of Object.keys(grades)) {
- // Если дата хорошая и за эту дату есть отметки
- if (dt >= DTSIT[itDate][2] && dt <= DTSIT[itDate][3])
- if (grades[dt][3]) {
- let w = grades[dt][2], gFull = grades[dt][3];
- let gClear = gFull.replace(/н/g, ''); // без «н»
- abs += gFull.length - gClear.length; // к-во пропусков
- gClear = gClear.replace(/\s{2,}/g, ' ').trim();
- if (gClear) if (gClear != "999") {
- let gArr = gClear.split(' ');
- for (let x of gArr) {sum += Number(x) * w; wSum += w;}
- }
- }
- }
- if (wSum) av = (sum / wSum).toFixed(2);
- stat += `<tr><td>${DTSIT[itDate][1]}</td><td>${sum/2}</td>`
- + `<td>${av}</td><td>${abs}</td></tr>`;
- }
- dqs("#jrnCont").innerHTML += stat;
- }
- // Формирование контента страницы (селект для начала невидим в css)
- createSection("journal", `
- <select id="jrnSubj" onChange="jrnContLoad();"></select>
- <div id="jrnCont"><img src='static/preloader.gif'></div>
- `);
- // Динамически подгружаем контент страницы (имя метода = имени пункта меню!)
- getContent.journal = async () => {
-
- // Получаем глобальный объект со списком всех предметов
- // jrnSbList = {"s110": "Русский язык", ...}
- let apiResp = await apireq("subjList");
- let subjListDop = JSON.parse(apiResp);
- jrnSbList = {...subjDef, ...subjListDop};
-
- // Получаем глобальный объект с логинами и ФИО учителей
- // jrnThList = {"pupkin": "Пупкин В. И.", "ivanov": "Иванов И. И.", ...}
- apiResp = await apireq("teachList");
- let teachList = JSON.parse(apiResp);
- for (let teach of teachList) jrnThList[teach.login] = teach.fio;
-
- // Загружаем все отметки и пр. ученика с помощью API в массив jrnArr
- // (логин юзера не передаем, он подписывается API из данных авторизации)
- info(0, "Пожалуйста, дождитесь<br>загрузки данных.");
- apiResp = await apireq("jrnGet", []);
- info(2);
- if (apiResp == "none") {
- dqs("#jrnCont").innerHTML = "<b>Дневник пока пуст.</b>";
- return;
- }
- jrnArr = JSON.parse(apiResp);
-
- // Формируем список предметов и учителей в селекте и делаем его видимым
- let keysArr = Object.keys(jrnArr);
- if (!keysArr.length) {
- dqs("#jrnCont").innerHTML = "<b>Дневник пока пуст.</b>";
- return;
- }
- keysArr.sort((a, b) => {
- let aSb = a.split('_')[1], bSb = b.split('_')[1];
- if (aSb.length != bSb.length) return aSb.length < bSb.length ? 1 : -1;
- else if (aSb.length == 3) return aSb > bSb ? 1 : -1;
- else return aSb.substr(1, 3) > bSb.substr(1, 3) ? 1 : -1;
- });
-
- let selInn = "<option value=''>Текущие отметки (все предметы)</option>";
- for (let k of keysArr) {
- let kArr = k.split('_'),
- grName = kArr[0],
- subj = jrnSbList[kArr[1]],
- teach = jrnThList[kArr[2]];
- teach = grName.includes('-') ?
- `(${grName.split('-')[1]}; ${teach})` : `(${teach})`;
- selInn += `<option value="${k}">${subj} ${teach}</option>`;
- }
- dqs("#jrnSubj").innerHTML = selInn;
- dqs("#jrnSubj").style.display = "block";
-
- // Формируем контент страницы по данному предмету и учителю,
- // либо по всем предметам, если выбрана первая опция селекта
- jrnContLoad();
- }
|