feat: 成绩明细打印 + SQLite + 每卷独立配置(满分/合格率/免考) + 导航精简

- 成绩明细打印:默认成绩降序,可选按班级/组别分组对比(段首小计)
- 修复看板退出全屏无反应(exitFullscreen 挂在 document 而非 documentElement)
- 导航栏精简:三页统一为单一主标题,移除 Logo 与副标题
- 优化三端布局:重排断点、竖排隐藏 spacer、触摸设备热区
- 全面启用 SQLite(data/ny.db):配置/名单/每卷配置入库,无 pdo_sqlite 自动降级文件
- 新增独立合格率配置(全局 + 每卷),合格率不再写死 60%
- 新增免考配置,仅对当前试卷生效,试卷间隔离
- 试卷独立满分从设置移出,改到主页面「试卷设置」
- 测试:新增 4 条每卷配置隔离断言,全套 113 项通过
This commit is contained in:
2026-09-10 20:22:17 +08:00
parent 0fd880624f
commit 157f257728
11 changed files with 1049 additions and 210 deletions
+46 -10
View File
@@ -53,7 +53,12 @@ body {
border-bottom: 1px solid var(--border);
box-shadow: 0 2px 12px rgba(20, 30, 60, .05);
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* 导航栏主标题(已移除 Logo 与副标题,只保留单一主标题) */
.brand-title {
margin: 0; font-size: 16px; font-weight: 700; letter-spacing: .3px;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.logo {
width: 38px; height: 38px;
border-radius: 10px;
@@ -469,32 +474,47 @@ body.fs-on .card b { font-size: 28px; }
body.fs-on .topbar { padding-top: 8px; padding-bottom: 8px; }
/* ---------- 三端自适应(桌面 / 平板 / 手机) ---------- */
/* 大屏笔记本:略收边距,统计卡片保持一行 */
@media (max-width: 1180px) {
.wrap { padding: 16px 16px 40px; }
.topbar { padding: 10px 16px; }
}
/* 平板横屏(769~1024):卡片改 4 列、工具栏字段占满整行 */
@media (max-width: 1024px) {
.grid-2 { grid-template-columns: 1fr; }
.field.grow, .field.grow-2 { flex: 1 1 100%; min-width: 0; }
.cards { grid-template-columns: repeat(4, 1fr); }
.toolbar { gap: 14px; }
}
/* 平板竖屏 / 大手机(<=768):整体收紧,工具栏与按钮自动换行 */
@media (max-width: 768px) {
body { font-size: 13px; }
.topbar { flex-wrap: wrap; gap: 10px; }
.brand-text small { display: none; }
.brand { flex: 1 1 100%; }
.brand-title { font-size: 15px; }
.top-right { flex-wrap: wrap; gap: 8px; }
.top-right .btn { padding: 6px 10px; font-size: 12px; }
.btn b { font-size: 10px; }
.wrap { padding: 12px 12px 36px; }
.toolbar { padding: 12px; gap: 10px; }
.toolbar { padding: 12px; gap: 10px 12px; }
.field { flex: 1 1 100%; min-width: 0; }
.field.btns { flex: 1 1 100%; }
.field.btns { flex: 1 1 100%; flex-wrap: wrap; row-gap: 8px; }
.field.btns select { width: 100%; }
/* 导出区的复选标签在小屏独占一行,避免和按钮挤成一团 */
.field.btns > label[style*="cursor:pointer"] { flex: 1 1 auto; }
.cards { grid-template-columns: repeat(3, 1fr); gap: 8px; }
.card { padding: 10px 12px; }
.card b { font-size: 20px; }
.panel-head { flex-direction: column; align-items: flex-start; gap: 6px; }
.card span { font-size: 11px; }
/* 面板头部(含按钮)竖排,按钮自动换行 */
.panel-head { flex-direction: column; align-items: flex-start; gap: 8px; }
/* 竖排时 .spacer(flex:1)会把内容上下撑开,必须隐藏 */
.panel-head > .spacer { display: none; }
.panel-head .updated { flex-wrap: wrap; width: 100%; }
.panel-head .btn, .panel-head .updated .btn { flex: 0 0 auto; }
.table-scroll { max-height: 56vh; }
table.grid { font-size: 12px; }
table.grid th { padding: 8px 10px; white-space: nowrap; }
@@ -503,19 +523,36 @@ body.fs-on .topbar { padding-top: 8px; padding-bottom: 8px; }
.modal-box, .modal-box.wide { width: 100%; max-height: 92vh; }
.form-grid { grid-template-columns: 1fr; }
.modal-body { padding: 14px; }
/* 弹窗底栏在小屏换行,按钮可点满宽 */
.modal-foot { flex-wrap: wrap; padding: 10px 14px; }
.modal-foot > .spacer { display: none; }
.modal-foot .btn { flex: 1 1 auto; }
.roster-bar { flex-wrap: wrap; }
.roster-bar .chk { font-size: 11px; }
/* 名单表在窄屏可横向滚动,避免 6 列挤爆 */
#rosterTable { min-width: 560px; }
}
/* 手机(<=480):卡片两列,进一步压缩字号与内边距 */
@media (max-width: 480px) {
.cards { grid-template-columns: repeat(2, 1fr); }
.brand-text strong { font-size: 14px; }
.topbar .logo { width: 32px; height: 32px; font-size: 13px; }
.cards { grid-template-columns: repeat(2, 1fr); gap: 8px; }
.brand-title { font-size: 14px; }
.btn { padding: 6px 9px; font-size: 12px; }
.field label { font-size: 11px; }
.roster-bar { gap: 8px; }
.roster-bar input[type=text] { width: 120px; }
.panel-head h2 { font-size: 14px; }
#rosterBody input { font-size: 12px; }
.modal-box { max-height: 94vh; }
.modal-body { padding: 12px; }
/* 工具条按钮在小屏铺满,便于点按 */
.field.btns .btn { flex: 1 1 auto; }
}
/* 触摸设备:增大点按热区,去掉 hover 残留高亮 */
@media (hover: none) and (pointer: coarse) {
.btn { min-height: 34px; }
table.grid tbody tr:hover td { background: inherit; }
}
/* ---------- 数据看板 ---------- */
@@ -525,8 +562,7 @@ body.fs-on .topbar { padding-top: 8px; padding-bottom: 8px; }
display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
box-shadow: var(--shadow);
}
.dash-hero .brand strong { color: #fff; font-size: 17px; }
.dash-hero .brand small { color: rgba(255, 255, 255, .72); }
.dash-hero .brand-title { color: #fff; font-size: 17px; }
.dash-hero a.back { color: #fff; opacity: .9; font-size: 13px; text-decoration: none; font-weight: 600; }
.dash-hero a.back:hover { opacity: 1; text-decoration: underline; }
.dash-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }