v3
This commit is contained in:
@@ -6,7 +6,7 @@ body {
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.container { max-width: 960px; margin: 0 auto; padding: 20px; }
|
||||
.container { max-width: 100%; margin: 0 auto; padding: 20px; }
|
||||
h1 { margin-bottom: 15px; }
|
||||
h2 { margin: 15px 0 8px; font-size: 16px; }
|
||||
|
||||
|
||||
@@ -91,7 +91,9 @@ router.get('/students', (req, res) => {
|
||||
SELECT s.*,
|
||||
COUNT(er.id) as exam_count,
|
||||
SUM(CASE WHEN s2.is_mandatory = 0 THEN 1 ELSE 0 END) as elective_count,
|
||||
SUM(CASE WHEN s2.is_mandatory = 1 AND er.grade IS NOT NULL THEN 1 ELSE 0 END) as mandatory_grades
|
||||
SUM(CASE WHEN s2.is_mandatory = 1 AND er.grade IS NOT NULL THEN 1 ELSE 0 END) as mandatory_grades,
|
||||
SUM(CASE WHEN s2.is_mandatory = 1 AND er.grade IS NOT NULL AND er.grade < 3 THEN 1 ELSE 0 END) as low_grades,
|
||||
GROUP_CONCAT(s2.name || ' ' || CAST(er.grade AS TEXT), ' / ') as subjects_list
|
||||
FROM students s
|
||||
LEFT JOIN exam_results er ON er.student_id = s.id
|
||||
LEFT JOIN subjects s2 ON s2.code = er.subject_code
|
||||
@@ -129,6 +131,8 @@ router.get('/students', (req, res) => {
|
||||
)`);
|
||||
} else if (filter === 'secondyear') {
|
||||
havingClause = 'HAVING elective_count = 0 AND COUNT(er.id) = 1';
|
||||
} else if (filter === 'lowgrade') {
|
||||
havingClause = 'HAVING low_grades > 0';
|
||||
}
|
||||
|
||||
const wherePart = whereClauses.length ? 'WHERE ' + whereClauses.join(' AND ') : '';
|
||||
|
||||
@@ -63,6 +63,9 @@
|
||||
<label class="filter-label" style="background:#fff0d0;color:#860">
|
||||
<input type="radio" name="filter" value="secondyear" onchange="onFilterChange()"> Второгодники
|
||||
</label>
|
||||
<label class="filter-label" style="background:#fdd;color:#a00">
|
||||
<input type="radio" name="filter" value="lowgrade" onchange="onFilterChange()"> Отметка < 3
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="search-bar">
|
||||
@@ -79,6 +82,7 @@
|
||||
<th>Класс</th>
|
||||
<th>Предметов</th>
|
||||
<th>Тип</th>
|
||||
<th>Предметы (оценка)</th>
|
||||
<th>Действия</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -154,6 +158,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
function formatSubjectsList(list) {
|
||||
if (!list) return '—';
|
||||
return list.split(' / ').map(item => {
|
||||
const m = item.match(/^(.*?)\s*(\d)\s*$/);
|
||||
if (m && parseInt(m[2]) < 3) return `<span style="color:#c0392b;font-weight:600">${esc(item)}</span>`;
|
||||
return esc(item);
|
||||
}).join(' / ');
|
||||
}
|
||||
|
||||
function renderTable(students) {
|
||||
const tbody = document.querySelector('#students-table tbody');
|
||||
tbody.innerHTML = students.map((s, i) => {
|
||||
@@ -164,7 +177,7 @@
|
||||
const examType = isOge ? 'ОГЭ' : 'ГВЭ';
|
||||
const examTypeClass = isOge ? 'badge-gia' : 'badge-gve';
|
||||
return `
|
||||
<tr class="${rowClass}">
|
||||
<tr class="${rowClass}" onclick="window.location.href='/student/${s.id}'" style="cursor:pointer">
|
||||
<td>${i + 1}</td>
|
||||
<td>${esc(s.last_name)}</td>
|
||||
<td>${esc(s.first_name)}</td>
|
||||
@@ -172,7 +185,8 @@
|
||||
<td>${esc(s.class)}</td>
|
||||
<td>${s.exam_count}</td>
|
||||
<td><span class="badge ${examTypeClass}">${examType}</span></td>
|
||||
<td><a href="/student/${s.id}" class="btn btn-sm">Открыть</a></td>
|
||||
<td style="font-size:11px;max-width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="${esc(s.subjects_list || '')}">${formatSubjectsList(s.subjects_list)}</td>
|
||||
<td onclick="event.stopPropagation()"><a href="/student/${s.id}" class="btn btn-sm">Открыть</a></td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user