成绩明细历史记录:按提交年月日分类,每个分类标记最高分
新增 DataService::dayKeyOf(),日期键一律用服务端本地时区计算(避免 UTC 导致东八区零点前后错一天);aggregateByStudent 为 attempts_list 每项附加 day/day_best/day_count,expandAttempts 透传。 弹窗按天分组渲染分组行(日期 + 共N次 + 最高X分),组内新到旧;当日最高标签仅在当天有多次提交时显示,避免单次日每行都挂标签。 修复:submit_ts=0(时间未知)的记录原本被误标为第1次(升序排序 idx=1 但展示在末尾),现显示 -;未知时间统一归入「未知时间」组。 aggregate 单测 17 -> 33(跨天归属/日内次数/每日最高/未知时间组/时区边界 00:30 与 23:30);全量 148 项全绿。
This commit is contained in:
+36
-11
@@ -926,6 +926,7 @@
|
||||
idx: 1, is_best: true, score: r.score, submit_at: r.submit_at,
|
||||
submit_ts: r.submit_ts || r.last_submit_ts || 0,
|
||||
duration_txt: r.duration_txt, temp_save: !!r.temp_save,
|
||||
day: '', day_best: false, day_count: 1,
|
||||
}];
|
||||
}
|
||||
// 新 -> 旧 展示(缺 submit_ts 时按 idx 倒序兜底,保证"次序"看起来合理)
|
||||
@@ -934,17 +935,41 @@
|
||||
if (ta !== tb) return tb - ta;
|
||||
return (b.idx || 0) - (a.idx || 0);
|
||||
});
|
||||
const rows = desc.map((a, i) => {
|
||||
const sc = (a.score == null) ? '<span class="muted">未判分</span>' : esc(a.score);
|
||||
const best = (a.is_best && attempts > 1) ? ' <span class="tag tag-best">最佳</span>' : '';
|
||||
const tmp = a.temp_save ? ' <span class="tag tag-gray">暂存</span>' : '';
|
||||
const no = attempts > 1 ? (a.idx || (desc.length - i)) : 1;
|
||||
return '<tr>' +
|
||||
'<td class="num">' + (attempts > 1 ? '第 ' + no + ' 次' : '-') + '</td>' +
|
||||
'<td class="num">' + esc(a.submit_at || '-') + '</td>' +
|
||||
'<td class="num">' + sc + best + tmp + '</td>' +
|
||||
'<td class="num">' + esc(a.duration_txt || '-') + '</td>' +
|
||||
'</tr>';
|
||||
// 按「提交时间年月日」分组:新的一天在前。
|
||||
// 日期键由后端按服务端本地时区算好(a.day),这里仅兜底;时间未知的(ts=0)key 为 '',
|
||||
// 且排序里排最后,天然连续落在末尾 → 归入「未知时间」组。
|
||||
const groups = [];
|
||||
desc.forEach(a => {
|
||||
const key = a.day || (a.submit_at && a.submit_at !== '-' ? String(a.submit_at).slice(0, 10) : '') || '';
|
||||
let g = groups.length ? groups[groups.length - 1] : null;
|
||||
if (!g || g.key !== key) { g = { key: key, items: [] }; groups.push(g); }
|
||||
g.items.push(a);
|
||||
});
|
||||
// 每组的最高分(未判分不参与),用于分组行显示「最高 X 分」
|
||||
groups.forEach(g => {
|
||||
g.max = g.items.reduce(
|
||||
(m, a) => (a.score == null ? m : (m == null || Number(a.score) > m ? Number(a.score) : m)), null);
|
||||
});
|
||||
const rows = groups.map(g => {
|
||||
const maxTxt = (g.max == null) ? '' : ' · 最高 ' + g.max + ' 分';
|
||||
let html = '<tr class="att-day"><td colspan="4">' + esc(g.key || '未知时间') +
|
||||
'<span class="att-day-sub">共 ' + g.items.length + ' 次' + maxTxt + '</span></td></tr>';
|
||||
html += g.items.map(a => {
|
||||
const sc = (a.score == null) ? '<span class="muted">未判分</span>' : esc(a.score);
|
||||
const best = (a.is_best && attempts > 1) ? ' <span class="tag tag-best">最佳</span>' : '';
|
||||
// 当日最高:仅当天有多次提交时才标,避免"一天只考一次"时每行都挂标签、反而看不出重点
|
||||
const dayBest = (a.day_best && (a.day_count || 0) >= 2) ? ' <span class="tag tag-day">当日最高</span>' : '';
|
||||
const tmp = a.temp_save ? ' <span class="tag tag-gray">暂存</span>' : '';
|
||||
// 时间未知(submit_ts=0)时无从判断先后,次序显示 '-',而不是误报"第 1 次"
|
||||
const noTxt = (attempts > 1 && a.submit_ts) ? ('第 ' + (a.idx || 1) + ' 次') : '-';
|
||||
return '<tr>' +
|
||||
'<td class="num">' + noTxt + '</td>' +
|
||||
'<td class="num">' + esc(a.submit_at || '-') + '</td>' +
|
||||
'<td class="num">' + sc + best + dayBest + tmp + '</td>' +
|
||||
'<td class="num">' + esc(a.duration_txt || '-') + '</td>' +
|
||||
'</tr>';
|
||||
}).join('');
|
||||
return html;
|
||||
}).join('');
|
||||
const bestScore = (r.best_score == null) ? r.score : r.best_score;
|
||||
$('#attTitle').textContent = (r.name || '') + '(' + r.sid + ') · 共 ' + attempts + ' 次考试' +
|
||||
|
||||
@@ -393,6 +393,11 @@ td.att { font-weight: 700; color: var(--text-2); }
|
||||
.tag-att { background: #e8eefc; color: #3457c9; cursor: pointer; }
|
||||
.tag-new { background: var(--ok-weak); color: var(--ok); }
|
||||
.tag-best { background: #fff1dc; color: #b26a06; }
|
||||
/* 当日最高(历史成绩按天分组后,组内最高分) */
|
||||
.tag-day { background: var(--primary-weak); color: var(--primary-2); }
|
||||
/* 历史成绩弹窗:按提交日期分组的分组行 */
|
||||
tr.att-day > td { background: var(--border-2); font-weight: 600; color: var(--text-2); }
|
||||
tr.att-day > td .att-day-sub { margin-left: 8px; font-weight: 400; font-size: 12px; color: var(--text-3); }
|
||||
|
||||
/* 多次刷题:成员榜可点击行 */
|
||||
tr.clickable { cursor: pointer; }
|
||||
|
||||
Reference in New Issue
Block a user