Commit Graph
68 Commits
Author SHA1 Message Date
xuyueandClaude Opus 5.5 df3b4f0dfd style(代码配色): 全站代码换成 Dracula 配色(亮色用官方浅色版 Alucard);编辑器、题面和教程的代码块、练一练、提交详情的颜色一模一样了
Deploy / deploy (push) Canceled after 0s
原来三套配色各管一块:编辑器是 smoothy / One Dark,正文代码块和练一练是仿 GitHub,
提交详情是 Naive 自带的,同一段 printf 在一课里就有两种颜色。现在静态代码也走编辑器
那套 lezer 解析器,颜色只在 shared/highlight.css 写一份,highlight.js 删掉。

填空题顺手修好:空会把语法搅乱,(humidity ____ 40) 被认成类型声明、humidity 染成类型色,
现在空里先填上答案再解析,答案不输出。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 19:49:20 +08:00
xuyueandClaude Opus 5.5 e10a7791a2 fix(演示模式): 演示模式下提交列表和提交详情不再露出别人的代码——投屏装成学生时,和学生看到的一样是「别人的代码看不到」
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:58:35 +08:00
xuyueandClaude Opus 5.5 5c1f1d2bf8 feat(课堂看板): 看板重做——顶上当场填题号,一排题卡片点开看这道题错在哪,全班一张表按没交/卡住/在做排,点红格子弹出代码讲错误、← → 换人
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 10:02:50 +08:00
xuyueandClaude Opus 5.5 0a4f528c44 feat(课堂看板): 看板接口给没做对的格子带上今天最后一次提交,按错法归堆、点开讲错误要用
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 10:02:50 +08:00
xuyueandClaude Opus 5.5 754a9d7caf fix(提交详情): 代码不用再左右滚了——改成一栏到底,代码占满整宽在前、例子对比在后;交的几次横着排,← → 一次次翻
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 01:17:42 +08:00
xuyueandClaude Opus 5.5 e923965f70 fix(提交详情): 「这道题交了几次」是竖着排的,翻上一次、下一次改用 ↑ ↓,和提交列表一样
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 01:07:46 +08:00
xuyueandClaude Opus 5.5 df76e7f101 feat(提交详情): 单独打开的一条提交改成左边代码、右边为什么错 + 这道题交的每一次
Deploy / deploy (push) Canceled after 0s
- 原来不显示是哪道题、时间只到日、答案错误不说为什么,测试点表 5 行一模一样
- 右边摆题目页那块例子对比(输入 / 正确输出 / 他的输出,差的字标红),编译失败、运行时错误同提交列表右栏的说法,代码里标出那一行
- 「这道题交了 N 次」常驻右栏,← → 一次次翻,看他是怎么改对的;题单藏着的那几次点不进
- 老师:「他的全部提交」和「⋯」(复制两项、重新判题);测试点方块悬停看用时和内存;判题中自己刷新
- 别人的代码、链接不对原来一直转圈,现在说清楚是哪种;自己在题单布置期内的照样看得到是哪道题、什么结果
- 后端详情多给题目名、班级、题单,`?attempts=1` 带上同题的每一次;看不到别人的回 403 而不是 404;提交者本人也拿得到 contestId(比赛里的题号是比赛自己的)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 01:00:22 +08:00
xuyueandClaude Opus 5.5 099c6d7ba6 feat(流程图): AI 点评改成拿例子和测试数据在图上走一遍,同一张图不能再原样重交抽等级
原来让 AI 按逻辑 40 / 完整 30 / 规范 20 / 清晰 10 打总分:同一张图交两次能差 35 分
(有一张 C 再交变 S),22% 的提交和上一次一模一样;评语里写 node_9 这种学生看不到的编号。
照画布稿 FlowResFail / FlowResPass:
- AI 拿题目的例子和最多 3 组测试数据,从开始照着图走到结束,逐组说输出什么、对不对、
  最先错在哪个框;全对 A,全对且写法挑不出毛病 S,走对一半以上 B,否则 C
- 结果页签:「3 组走对 2 组」,逐组 ✓ / ✗,点开看「你的图输出 / 应该输出」,画布上按先后
  编号亮出这一组走过的框、错的那个标红;图一改就不亮,载回那一版又能亮
- 画布和上次评完的那张一模一样时「交给 AI 点评」灰掉;后端也兜着:同一道题一模一样的图
  直接照搬上次走例子的结果,不再问 AI
- 题目一组例子、测试数据都没有时退回老的四项分;老提交照旧按四项分显示
- 历次等级、提交列表的胶囊只写等级,不写分数

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:08:42 +08:00
xuyueandClaude Opus 5.5 ce26925e79 style(提交列表): 右栏的代码字太小,调到和题目页编辑器一样的 20px
Deploy / deploy (push) Canceled after 0s
行高跟着从 30 调到 32,标红的报错行仍和行号逐行对齐。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 20:22:39 +08:00
xuyueandClaude Opus 5.5 367cfc9d5d feat(班级下拉): 全站的班级下拉按年级分组,新年级在上,组里按班号排
Deploy / deploy (push) Canceled after 0s
登录框、提交列表、数据统计、排名、课堂看板、题单班级视图、班级 PK 七处统一走
groupClassOptions。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:54:26 +08:00
xuyueandClaude Opus 5.5 1e441411a5 style(前台): 页面整体放大一档,列表不再挤成一团;宽屏上内容居中,不再铺满到两边
Deploy / deploy (push) Canceled after 0s
- index.css 加一张 --oj-* 尺寸表和 .oj-page 外壳,二十几个前台页面改成引用它:
  正文 14→15、页标题 20→24、题目/提交列表行高 40→48、比赛/公告 56、筛选控件 28→34
- 阅读型页面限宽 1200 居中;题目/提交列表 1600、比赛详情 1400、排名 1280、班级 PK 1440
- 1280 宽的筛选条放大后放不下,题目/提交列表在 1366 以下退回 13px 的字
- 班级 PK 五个班起格子里不写「一次 x%」(只剩「一次 8…」);赛跑图线尾的数字不再被截掉
- 手机上比赛列表的「没参加」挪到比赛名下面;题单里「以前做对过 · 旧代码先藏着」缩成「做对过」
- 题目详情页(编辑器)和后台不在这一轮

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:43:12 +08:00
xuyueandClaude Opus 5.5 0cee4ef779 fix(名字): 比赛成绩、全班情况、看板、题单、统计里的名字不再用真名,一律和排行榜一样显示 ks241XXX;导出成绩去掉姓名列
Deploy / deploy (push) Canceled after 0s
两个写法不同的 UserName 合成 shared/components/UserName.vue 一个。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:44:42 +08:00
xuyueandClaude Opus 5.5 2bb74652a0 style(比赛): 有密码的比赛前面那个彩色盾牌锁换成和全站一样的细线灰锁,放到比赛名后面
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:44:42 +08:00
xuyueandClaude Opus 5.5 c17f88cdbb feat(题单): 题单页重做——布置中的放最上面,详情顶上一条进度和奖章阶梯,没加入看得见题点不进;老师看全班、后台一屏编辑
Deploy / deploy (push) Canceled after 0s
- 列表:布置中的大卡片(做对几道、布置到哪天、再做对几道拿哪个奖章),其余小卡片,加入过的在前
- 详情:进度 + 奖章阶梯(下一个金圈「再做对 n 道」),题目两列写几点做对 / 交过几次;
  以前做对过的标「旧代码先藏着」;做完整条变绿,烟花只在做完那一刻放
- 老师多一个「全班情况」页签;题目页从链接直接进来没加入时,条上给「加入题单」
- 后台一屏编辑:布置一周 / 两周 / 四周 / 选日期,公开开关,粘贴多个题号一次加,拖动排序,奖章只剩两种条件
- 旧代码藏着的地方都说清楚是哪个题单、哪天之后能看
- 修掉列表卡片把选做题数说成「新加了 N 题」

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:01:39 +08:00
xuyueandClaude Opus 5.5 8f21f15c43 feat(提交列表): 同一分钟里连交好几次分不清先后——每行的提交时间带上秒
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:31:43 +08:00
xuyueandClaude Opus 5.5 af63b05d4b fix(班级下拉): 「26计算机11班」这种两位数的班在有的机器上显示成省略号——下拉加宽到 152px
Deploy / deploy (push) Canceled after 0s
132px 时最长的班名只剩两像素余量,字体稍宽就放不下。提交列表和统计面板两处一起改。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:40:08 +08:00
xuyueandClaude Opus 5.5 b7ec65eee8 feat(提交详情): 点了班级筛选之后,要挪到上面班级下拉去点 × 才能取消——右栏那个班级标签原地变成「取消」
已经在筛这个班时,标签不再消失,填色带 ×,悬停变红,再点一下回到全部班级。手机上顺手关掉详情抽屉。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:40:08 +08:00
xuyueandClaude Opus 5.5 2fafb25959 style(提交详情): 状态那一行挤得快放不下——去掉「测试点 1、2、3 答案错误」和耗时、内存
Deploy / deploy (push) Canceled after 0s
测试点小方块本身带颜色、悬停有结果名,后面再写一遍是重复;耗时和内存在课堂上没人看。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:28:59 +08:00
xuyueandClaude Opus 5.5 c22521fb61 fix(答案错误): 说明写「在例子 1 上就错了」,旁边测试点 1 是绿的,看着像写反了——改成「题目里的例子 1 就错了」
例子是题面样例,测试点是隐藏数据,两边都从 1 编号,只写「例子 1」分不开。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:18:06 +08:00
xuyueandClaude Opus 5.5 923f3efeca feat(统计): 没填班级的学生也能和班级一样看——班级下拉多一项「没填班级」,一起上的课能切出来、点进去看小方块;零散提交也能点了
- 班级筛选多一个取值 NO_CLASS("none"),统计、方块串、流程图、提交列表都认;只圈普通学生,
  老师管理员的号本来就不填班级,不挡的话试题的提交会算进去
- 切课时没填班级的号合在一起当一个班切(原来 class_name is null 直接排除,7 月 4 日那两节课看不到)
- 没填班级不是真班:不列「还没交」,课上只写几人不写几人之几
- 「另有零散提交」每一项可点,进那个班那一整天

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:18:06 +08:00
xuyueandClaude Opus 5.5 fa092d334c feat(编译错误): C / C++ 编译没过时也给中文说明、标出出错位置,中文标点能一键换成英文
Deploy / deploy (push) Canceled after 0s
原来 C / C++ 的编译错误学生看到的是 gcc 的英文原文。现在和 Python 一样一张翻译表
(cError.ts),照全库 2851 条 C / C++ 编译错误用现在的判题机(gcc-14)重新编译出来的
报错定的,只看第一条 error,98% 能给出说明。

三件事先于句式判,因为 gcc 对同一个错报法五花八门:
- 交成了 Python 代码(330 条):gcc 报的是 request for member 之类,直接说换语言;
- C 里写了 C++(iostream、cout);
- 中文标点:gcc-14 不再报 stray,而是把「;」吞进变量名、错报到下一行,所以直接在
  代码里找引号和注释之外的中文标点,行号按代码算。中文标点查找认 C 的 // 和 /* */。

句式上:缺分号报在下一句开头的往回挪一行,把分号写成冒号、关键字拼错(coutinue、
RETURN、return0)、文字没加引号、#include 拼错、main 外面写语句等各有说法。
gcc 的 did you mean 会从库函数里挑(num → enum),只信学生代码里有的名字。
列范围按 gcc 的显示宽度换算(中文占两格),含中文的行也能标到具体位置。

卡片改名 CompileErrorExplain,提交结果、运行例子、提交列表弹框三处都接上了。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 11:22:31 +08:00
xuyueandClaude Opus 5.5 96ce9725b2 fix(语法错误): 有模板的题报错行号多 1;else 后面写了条件被说成「少了冒号」,a+b=c 被说成「判断相等要用 ==」
全库 9182 条 Python 编译错误逐条过了一遍翻译表,1014 条的说明变了:

- 行号:判题跑的是「模板 + 代码」,运行时错误扣了模板行数、编译错误没扣,
  「第 N 行」和标红都落在下一行(691 条)。提交和运行例子两条路都扣上,
  gcc 的 main.c:N: 和代码摘录左边的行号一起扣。报错前先打了一条警告时
  File 那行是缩进的,行号原来解析不出来。
- 同一句报错要看出错那一行才分得开:expected ':' 九成是 else a<60:(行尾有冒号),
  「Maybe you meant '=='」只有 if / while 行才是真想判相等,a+b=c、a=96,b=92、
  print(1+1=2) 各有各的说法。
- 选了 Python 却交了 C 代码(294 条),直接说换语言。只凭 printf 不算:
  Python 里 print 手误成 printf 的不少。
- 单独说清楚的:elif: 没写条件、esle / else if、=< 写反、条件之间用逗号、
  漏了 +、√ ² ≤ ≥、顿号、全角 #、emoji(正则少了 u 标志)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:44:09 +08:00
xuyueandClaude Opus 5.5 f413518a85 fix(运行时错误): 列表练习里 append() 参数给错,说明却是「把文字当成数字、input() 读进来的是文字」,代码里根本没有 input()
全库 9228 条 Python 运行时错误在判题沙箱里重跑了一遍(9028 条复现),按真实回溯重定归类表:

- TypeError 原来只认 12 种句式,633 条掉进兜底,一律被说成「把文字当成数字」。
  实际多半是函数用法错:参数个数不对(点名 append / insert 并给正确写法)、
  end= 拼成 enp=、list.index(x) 该写变量名.index(x)、忘写 ()(int(input)、
  input[0],约 200 条)、拿 print() / append() 的返回值去算(约 100 条)等。
  兜底从 633 条降到 64 条,ValueError 从 336 降到 5(split("")、%.2f 写错、
  值不在列表里)。
- input[0] 原来被说成「对一个数字用了下标」:值的类型名比句式更说明问题,
  builtin_function_or_method / NoneType 先于句式判。类型名来自代码不来自输入。
- AttributeError 带上 Python 的「Did you mean」(spilt → split 一种就 188 条),
  s.len() 说成函数不是方法,数字没有 split() 说顺序反了。
- 「input() 读进来的是文字」只在学生代码里真有 input( 时才说。
- C:信号 31(system("pause") 被沙箱拦 / 字符数组溢出)和 25(死循环打印)
  原来只有「崩溃了」,占 C 运行时错误一半多;void main 不再说成「要写 return 0」。

已经存进库的诊断没有新的 kind,旧提交看到的是新的中性兜底话。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:43:44 +08:00
xuyueandClaude Opus 5.5 6306b5a919 style(提交列表): 结果筛选里「语法未通过」挪到「答案正确」后面,下拉加宽,五个字的选项不再被截断
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:13:53 +08:00
xuyueandClaude Opus 5.5 11d2155908 style(提交列表): 结果筛选里去掉「内存超限」「正在评分」「系统错误」,只留学生真会碰到的几种
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:11:23 +08:00
xuyueandClaude Opus 5.5 773d15b033 feat(课堂看板): 「这节课的题」旁边多一个语言下拉,布置 C 的作业学生打开题目编辑器就是 C
Deploy / deploy (push) Canceled after 0s
默认是这个班上一次布置选的语言。学生那边首页、题号下拉、题目页课堂条都写上「C语言」;
打开这节课的题时编辑器自动切过去,每道题只切一次,学生自己再换就按他的。提交列表的
「这节课」连语言一起筛。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 09:54:21 +08:00
xuyueandClaude Opus 5.5 e3be3cd62c feat(统计): 「今日统计」「数据统计」合成一个「统计」,打开是一行一节课,这节课在最上面
Deploy / deploy (push) Canceled after 0s
老师的提交列表上只剩一个「统计」按钮;什么都没筛时按课列(选「今天」就是原来今日统计看的),
点一行进那节课(班、题、时段都带好),左上「← 全部」回来;只填题号时仍按班级汇总,和题目页
统计页签对得上。数字行加结果条,统计里的「课堂看板」按钮去掉,改成有班正在上课时才引过去。
学生仍是「今日统计」。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 09:23:54 +08:00
xuyueandClaude Opus 5.5 cb2fb57fdb style(提交列表): 「重新判题」是右上角最显眼的按钮,上课却最用不上,收进「⋯」
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 08:47:57 +08:00
xuyueandClaude Opus 5.5 e3eb41288c feat(提交列表): 「数据统计」改回在当前页弹框里看,不再开新标签页;按钮和「今日统计」一个样子
弹框带着列表现在的班级、学生、题号打开,「在提交列表里看」直接改背后的列表。
今日统计里点班级名也开同一个弹框。统计主体抽成 StatisticsView,/statistics 页面
留给课堂看板「回头看」、题目页这些别处的入口。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 01:20:01 +08:00
xuyueandClaude Opus 5.5 2fddf4a011 feat(提交列表): 今日统计重做——老师看今天哪几个班上了课、几点到几点、错得最多的题;学生版从简
- 老师:各班上课时段画在一条 7–20 点的时间轴上(点班级名去数据统计),有班正在上课时引去课堂看板
- 错得最多的题带班级、没过的原因、做对 x/y 人;底部一根全站结果条,语言只有一种时缩成一句
- 学生:你今天交了几次做对几道 + 今天大家都在做(按人数,带去做 / 接着做)
- 标题栏写「截至几点」、判题中几条;打开时把按钮上的数一起更新(原来只在进页面时拉一次)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:47:51 +08:00
xuyueandClaude Opus 5.5 5f9743efe0 feat(提交列表): 右栏名字旁多一个「只看这个班」,不在班级列表里的老班也能筛出来
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:00:38 +08:00
xuyueandClaude Opus 5.5 e37ad982c0 revert(提交列表): 撤掉班级下拉里补「近半年有提交的班」那一版,下拉回到只用系统设定的班级列表
改成在右栏名字旁加「只看这个班」过滤按钮(下一条)。
This reverts commit 61ec7d7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 00:00:38 +08:00
xuyueandClaude Opus 5.5 61ec7d7f8e fix(提交列表): 不在班级列表里的班(毕业、换届摘掉的老班)在班级下拉里选不到,筛不出它的提交
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:31:50 +08:00
xuyueandClaude Opus 5.5 6bc927402e fix(提交列表): 列表上的「1/1」被学生当成交了几次,换成显示编程语言
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:31:50 +08:00
xuyueandClaude Opus 5.5 365ce0a7b4 style(提交列表): 列表改回比代码区窄一点(46 : 54)
Deploy / deploy (push) Canceled after 0s
56% 的列表嫌宽了。46% 在机房 1280 的屏上题目列约 215px,快照里抽的几组各 50 行题目名
都放得下,特别长的看鼠标提示;大屏上列表最宽 900。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 19:23:25 +08:00
xuyueandClaude Opus 5.5 816e295dc9 style(提交列表): 翻上一条下一条只用 ↑ ↓,去掉 ← →
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 19:13:03 +08:00
xuyueandClaude Opus 5.5 b46529c741 style(提交列表): 列表放宽、代码区收窄,题目名不再被截成三个字;只看一个人时筛选框换成名字标签
- 左右从「列表 560 固定 + 代码占满」改成 56% : 44%(大屏列表最宽 1000):学生的代码大多
  十来行,右边原来空着一大片,左边的题目名却只剩三个字;用户名一列 132 → 116
- 右栏顶上固定一行:「只看他 / 只看这题」只留漏斗图标,题目名太长时省略,翻条时代码区不再上下跳
- 按整名只看一个人时(只看他、协作条、看板点进来),108px 的输入框装不下八九个字的用户名,
  换成「只看 xxx ×」的标签;列表里题目名加上鼠标提示

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 19:12:14 +08:00
xuyueandClaude Opus 5.5 52bf2d6111 feat(提交列表): 题号填错一道时顶上提示「没有这道题」;← → 也能翻上一条下一条
Deploy / deploy (push) Canceled after 0s
- 列表接口回带查不到的题号(公开列表只认公开题,比赛列表只认本场的题),
  一次填好几道时打错的那道原来被悄悄忽略
- 方向键恢复成四个都能翻(9 月加的时候就是这样,老师已经用惯了)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 18:58:31 +08:00
xuyueandClaude Opus 5.5 0bcc981e6f fix(提交列表/统计): 按方向键会顺手切掉「代码/流程图」、重判后右栏还是旧内容、没人交时统计说「全都做完了」
提交列表:
- 焦点在单选框、下拉框上时方向键不再一边切控件一边换条;跨页没回来前不再连跳一整页
- 重判、重新评分之后右栏重新拉,不再命中旧缓存;同一条新旧请求不再互相覆盖
- 从「我的提交」点顶栏「提交」、浏览器后退时,地址里没有的筛选回到默认
- 找回点用户名开个人主页;「只看他 / 只看这题」学生也能用;重判不用等代码拉下来
- 手机上老师也能重判、能按语言筛,流程图行有手机排版;学生界面带着的班级筛选显示成能点掉的标签
- mermaid 画不出来时先说中文、原始报错折起来

统计页:
- 没人交时说「这段时间没有人交」,不再说「全都做完了」;没填题号时各处统一叫「做对过题」
- 班级按 class_name 单独传;查询失败清掉旧数据并说清原因;标签跟着查出来的那一份走
- 「语法未过」的格子单独标「语」;正确率不算还在判的;截断提示说清哪些数字受影响
- 看板的请假隐藏只藏还没交过、没在举手的人,「恢复」只恢复这个班的
- 手机上筛选折行、上下排,不再挤出屏幕

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 18:52:58 +08:00
xuyueandClaude Opus 5.5 ed55ee5af6 feat(统计): 数据统计从弹框改成独立页面,左边题目、右边学生,一道题看全班每人的每一次
- 课堂看板管这节课,统计管回头看:时间段默认「两节课」,还有这节课、今天、7 天、30 天、这学期、全部、自己选日子;不再自动刷新
- 选一道题看每人在这道题上的方块串,鼠标停上去看那次的代码;选「全部」每人一行、展开按题看
- 没选班级(从题目页进来)先按班级汇总;流程图统计有等级分布、四项雷达、各项平均分、词云和每人最好的一次
- 提交列表、题目页的「数据统计」改成新标签打开这个页面
- 「请假隐藏」挪到课堂看板:点名字旁的 × 藏两个小时,做完人数的分母一起减掉

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 18:28:27 +08:00
xuyueandClaude Opus 5.5 99c158498c feat(提交列表): 老师也能在「全部 / 我的」之间切换,不用再靠「清空」退出「我的提交」
Deploy / deploy (push) Canceled after 0s
选「我的」时这节课、班级、学生三个框收起来(只看自己时后端本来就不认它们);
机房 1280 宽的屏上「今日统计」只留图标和数字,给这个切换腾地方。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 13:30:17 +08:00
xuyueandClaude Opus 5.5 660f689a5c feat(提交列表): 重做成左边列表、右边代码,方向键一条条翻,不再开弹框
- 右栏常驻选中那条的代码:编译失败 / 运行时错误用中文说清第几行错了并标红,
  老师看得到逐个测试点,学生看别人的只显示结果
- 老师一键「这节课」:筛到正在上课的班、这节课的题、今天
- 「正在评分」的行自己变成结果;新交的不插队,顶上提示「有 N 条新提交」
- 按天分组、默认每页 30 条;状态筛选补全,语言补上 SQL;流程图的评分详情也放进右栏
- 课堂看板的格子和名字能直接点进这个学生今天的提交

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 11:08:49 +08:00
xuyueandClaude Opus 5.5 ea480d5e0c feat(提交列表): 老师也能重新判题;列表能按班级、一次按几道题筛,还带「通过几个测试点」
- 重新判题从只放超管改成老师及以上:前端一直给老师亮着按钮,点了只会「权限不足」
- /submissions、/flowcharts 加 className(user.class_name 精确匹配),题号可以一次填几道
- 列表每行带 caseSummary,口径和详情一致,在库里数完只回两个数
- 新增 GET /classroom/lesson:提交列表「这节课」按钮用,班级和题的取法同课堂看板

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 11:08:49 +08:00
xuyueandClaude Opus 5.5 e7b95d211d fix(题目): 修掉题目页重构审查查出的问题——提交途中换题会把结果算到新题上、运行例子把对的菱形判错、点评完「下一题」不跳等
题目页重构之后按「功能对照 / 状态 / 结果页 / 布局与后端」四路审查了一遍,查出的问题一起修:

提交与换题
- 提交、画流程图途中换题:A 题格式化好的代码会盖掉 B 的草稿,A 判对了把 B 标成已解决、
  弹 B 的点评、题单里跳回题单。现在每个请求回来先核对题目,轮询和推送回来的也核对提交编号
- 画着流程图换到不能画的题,语言退到题目的第一门、还被记成偏好;现在回到学生习惯的那门
- 强制点评评完点「继续 / 下一题」,学生之前在看「题目」页签的话会停在原题
- 离开题目页之后判题、流程图的 WebSocket 一直连着,现在闲 15 分钟断开

运行例子
- 输出开头的空格被削掉,打印菱形这类题对的代码也显示「没对上」
- C 的编译警告拼进了「你的输出」(后台生成测试点也会写进 .out)
- Python 的语法错误(中文标点)被说成「下标有没有越界、除数是不是 0」
- 比赛里仍然把空格画成「·」、把不同的地方标红

入口与协作
- 比赛里不给「课堂统计」、不绑协作:房间和统计都按题号找,比赛题号和公开题撞号
- 「看他交过什么」按整名匹配,不再混进学号相近的同学
- 协作中点上下文条、相似题、下一题开新标签,协作不断
- 题单入口给管理员的「⋯」里留「本题提交」

结果与题面
- 「去自己输入拿 51 这些数试试」取到了题面 HTML 里的颜色值;「题目原话」露出 &quot;
- 流程图 A 级的学生标题下还写着「还没交过」
- 「我的提交」上方补回「答案错误 × 3」这样的计数
- 流程图历次评分能点开看那一版的图;读分数失败不再说「还没交过流程图」;手机上能看流程图点评
- 「结果」页签有新结果没看时加粗上色,看过就恢复
- 空画布拖进第一个节点画布会跳一下;画布底下空着一条
- 比赛没开始写成「已结束」、倒计时超过一个月算错;分隔条拖到头工具栏被挤坏;题单里的题目页有备案页脚
- 流程图历次分数只读需要的几列(一个学生一道题 23 次提交:96 kB → 2 kB)
- 比赛密码、比赛没开始等几条学生看得到的英文报错换成中文

设计文档照实际做法更新了第 5.5、5.6、6、8、9、10、11 节。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 00:07:16 +08:00
xuyueandClaude Opus 5.5 6bf8c6e1d9 style(前台): 列表页去掉表头 emoji、已结束的比赛改成灰色;比赛列表置顶进行中的比赛,排名页先看榜单
- 前台 53 处表头改成纯文字,删掉只剩这一个用途的 utils/renders.ts
- 「已结束」从红色改灰色(比赛列表 / 详情 / 后台 / 首页一起)
- 比赛列表第一页、无筛选时顶部列出进行中和即将开始的比赛
- 内容少的页面页脚贴底,不再悬在半屏
- 排名页两张柱状图挪到最后,第一屏是 Top100、本周进步榜和我的排名

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:13:29 +08:00
xuyue d25b5dbe6d update
Deploy / deploy (push) Canceled after 0s
2026-09-27 19:36:28 +08:00
xuyueandClaude Opus 5.5 9412ba3cf6 refactor(契约): 展示题号统一叫 problemDisplayId,题单 id 统一叫 problemSetId
Deploy / deploy (push) Canceled after 0s
前后端同时改,部署前开着的旧页面要刷新一次(题号列会是空的、提交筛选会失效)。

- 挂在非题目对象上的展示题号,原来叫 problem(字符串)或 displayId,统一成
  problemDisplayId:提交列表、流程图列表、统计的 lastFailure / items /
  今日最热题、站内信里的提交、后台题单的题目列表。别处的 problem 都是对象
  或数字 id,这几处是字符串,最容易看错
- 列表筛选的 query 参数 ?problemId= 实际传的是展示题号,改成
  ?problemDisplayId=(提交列表、流程图列表、三个统计接口)
- 契约里 problemsetId / problemSetId、problemset / problemSet 两种拼法并存,
  统一成 problemSetId / problemSet,和 ProblemSet* 类型名、problem-sets
  路径、前端路由参数一致。drizzle 的列键跟表名走,没动
- aiDetail.user(用户名字符串,而契约里别的 user 都是对象)→ username。
  ai_analysis.data 里存的历史快照仍是 user,没有代码读回它
- 后台题单题目表的列是按字符串键 'displayId' 取的,类型检查抓不到,一并改

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 16:08:31 +08:00
xuyueandClaude Opus 5.5 5ae830a7f9 refactor: 一批名不副实的命名改掉(只动一端,不碰契约)
后端:
- getUserByToken → authenticateToken:它会删会话、续 TTL、记在线,不是纯读
- todayStart → dayStart(instant):本来就接受任意时刻,不只是「今天」
- objectValue → asRecord,删掉 4 份一模一样的私有拷贝和 `as toObject` 别名
- 报错文案 "does not exists" / "Already be a public problem" 改通顺

前端:
- utils/types 里 Contest / User / Problem 三个别名删掉:Contest 原来指后台
  比赛、契约里同名的却是学生侧。现在 Contest = 学生侧、AdminContest = 后台,
  后台用户表单叫 AdminUserForm,题目详情直接用 ProblemDetail
- SubmissionInfo → ContestSubmissionInfo,免得和 submission.info 撞名
- utoa / atou → compressToBase64 / decompressFromBase64(实际是 zlib + base64),
  encode / decode → base64EncodeUtf8 / base64DecodeUtf8
- filterResult → toProblemRow、toProblemListItem → toAdminProblemRow,
  行字段 submission / rate → submissionCount / acRate
- 组件:Modal → AddFromLibraryModal、Form → EditorToolbar、
  ContestEditor → BasicEditor(题单也在用它)、rank 的 Index → RankMedal、
  Name → UserNameCell、Password → PasswordCell、ContestType → ContestAccessTag

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 16:08:21 +08:00
xuyueandClaude Opus 5.5 7a390323fe refactor(前端): 接口错误改成 ApiError 类,catch 不再写 any
拦截器原来 reject 一个裸对象 `{ error, data }`,没有类型也没有类型守卫,于是 46 处
`catch (err: any)` 直接读 `err.data` / `err.error` —— 代码 bug 抛出的 TypeError 也按
接口错误读,弹出来的是 undefined 或英文。

- utils/api.ts:reject 改成 `ApiError extends Error`,字段名沿用 error(错误码)/
  data(文案),存量读法语义不变;加 isApiError / errorCode / errorMessage。
  errorMessage 对非接口错误一律用 fallback,不把 TypeError 的英文甩给学生
- 46 处 catch 全部换掉 any(45 处接口错误 + pythonSyntaxCheck 里 Skulpt 的错误对象)
- 断网等没有响应体的情况,文案从英文 "Request failed" 换成「网络异常,请检查网络后重试」

浏览器实跑核过:登录密码错误仍显示「用户名或密码不正确」(错误码分支)、
接口错误 reject 出来是 ApiError、网络不通时拿到中文文案、非接口错误走 fallback。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 15:12:40 +08:00
xuyueandClaude Opus 5 8b4d8899f9 feat(判题机): 自建镜像升级工具链,语言收敛到 C / C++ / Python
Deploy / deploy (push) Canceled after 0s
上游 QingdaoU/JudgeServer 停更在 2024-04(registry 上的 latest 和 1.6.1 是同一份
镜像,编译器停在 gcc-13),没有新版可拉,所以自己重编。docker/judge/ 是只改工具链
的 Dockerfile 分叉,server/ 和 Judger/ 从上游固定 commit b28aa56 拉,一行没动。

镜像 oj2-judge-2(不在任何 registry 上:本机 build.sh --save → scp → docker load)
- gcc/g++ 13 → 14.2,Python 3.12 → 3.13.5,都是 trixie 默认
- Go / JDK / Node 整套删掉:前端的题目语言复选框从来只给 C / C++ / Python / SQL,
  12 万条提交里 Java 44 条、Golang 15、JavaScript 3,全是很早以前的
- 体积 1.1GB → 433MB;默认走清华源,构建 12 分钟 → 40 秒(--no-mirror 换回官方)
- deploy.sh 加一道自检:镜像不在本机就中止,并打印该跑的三条命令

C 的编译参数加三个 -Wno-error(implicit-function-declaration / int-conversion /
incompatible-pointer-types):gcc-14 把它们从 warning 提成了 error,而 -w 压不住。

语言值统一成 Python(迁移 0019 / 0020)
- 0019:Python3(104527 条提交)与 Python2(3 条)并成 Python,一并改掉 937 道题的
  languages、75 个 template 键、15 个 ast_rules 键、257 条 answers、1235 个用户的
  成就指标 _languages(languages_used 重算,总和 1928 → 1925,少的 3 个是同时用过
  两种 Python 的人)
- 0020:把 Java / JavaScript / Golang 从 84 道题的可选语言里摘掉 —— 不摘的话那些题
  的语言下拉还能选 Java,提交必 SYSTEM_ERROR
- 契约新增 normalizeLanguage() 别名表,判题侧一律走 judgeConfigFor():旧客户端
  localStorage 里的 Python3、迁移前排进队列的任务都还能判;协作的语言归一也走它,
  否则上线那一刻学生页面里的 Python3 会静默落到 C
- 回滚要连数据一起回,只滚代码会让所有 Python 提交变 SYSTEM_ERROR

实跑
- 判题冒烟 docker/judge/smoke.ts 13 条全过:三种语言、六种状态码、gcc 宽松度
- 拿备份里的真实代码逐文件比对新旧镜像的编译结果,0 差异:C 提交 1951 份
  (1725 过 / 226 CE)、C++ 882 份、Python 2000 份、20 篇 C 教程的 93 个代码块。
  不加那三个 -Wno-error 的话,C 有 26 份会从能过变成 CE
- 迁移在灌了 12.4 万行真实数据的一次性库里跑过:0 残留、没有题目被清空;
  dev 库用真正的执行器跑通
- check:ast 56 个 target 全过,前后端 typecheck 均 0

顺带记下一个升级之前就有的坑(现在随 Go 一起消失,写在 README 里):GOCACHE 指向
容器的 tmpfs,判题机重启后第一次 Go 提交是冷构建,Go 1.22 要 5.6 秒 CPU、超过 3 秒
的编译预算,于是重启后第一个交 Go 的学生必吃一次 CE,后面的人缓存热了又都正常。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 06:24:05 -06:00