xuyue and Claude Opus 5.5
4000b3a9f0
feat(后台富文本): 图片可以拖四个角缩放,拖完的宽度学生端照样生效
...
Deploy / deploy (push) Canceled after 0s
点中或悬停图片四角出把手,按原比例缩放。宽写回 style、去掉高(学生端高一律 auto):
老题面的图片尺寸都在 style 里,Tiptap 自带的 resize 写的是 width / height 属性,
被 style 盖住,拖完存下来还是原尺寸,所以自己接了 ResizableNodeView。
解析和输出没动,不拖的图片打开再保存和原来一样。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 20:35:56 +08:00
xuyue and Claude Opus 5.5
9e2217e09d
refactor(后台富文本): 编辑器从 wangEditor 换成 Tiptap,老题面的图片尺寸、缩进、颜色打开再保存都不丢
...
Deploy / deploy (push) Canceled after 0s
拿库里全部 3384 条题面 / 提示 / 公告 / 比赛说明做过往返比对,补上图片 style、base64 图片、
段落缩进三处后文字和格式都对得上。工具栏照画布做成一行浅灰小图标,四套档位不变,
加了行内代码、光标在表格里出加删行列。表格格子里的段落在学生端不再把行撑高。
编辑器 JS 638 kB → 455 kB,wangEditor 的 39 kB 样式不用了;polyfill 清单重新审过,
去掉只有 wangEditor 用到的 web.immediate。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 20:20:13 +08:00
xuyue and Claude Opus 5.5
a2dcafae14
refactor(前端): 去掉 nanoid 和 date-fns;「12月」这种时长改说「1年」,年月按东八区日历数
...
Deploy / deploy (push) Canceled after 0s
时长拆分(比赛倒计时、比赛时长、主页「最近一次提交」)改用自己写的东八区日历差,
和 zonedParts 同一个口径,不再跟浏览器时区走。顺手删掉几次重设计后已经没人用的
getRandomId、durationFromValue 和 DURATION_OPTIONS / LONG_DURATION_OPTIONS。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 19:47:34 +08:00
xuyue and Claude Opus 5.5
d6c3171d13
refactor(请求): 去掉 axios,所有请求统一从 authFetch 出门;换 token 时断网不再平白弹登录框
...
Deploy / deploy (push) Canceled after 0s
utils/api 改成基于 authFetch 的一层 fetch 封装,调用方用法不变;下载测试点也走
authFetch,token 过期时会换一张重试。换 token 那一步断网时,AI 流式接口和自学上报
原来会拿掉 token 重发、弹登录框,现在和普通请求一样报「网络异常」。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 19:39:19 +08:00
xuyue and Claude Opus 5.5
13843c79a0
fix(登录): 两个标签页同时换 token 时,学生可能过一刻钟被莫名踢下线
...
Deploy / deploy (push) Canceled after 0s
refresh token 轮换原来是「读出来、查库、写回去」,两个标签页同时换会各自轮换出一张,
后写的冲掉先写的;浏览器里留下的若是被冲掉那张,下次换就被拒。机房走 http 用不了
navigator.locks,前端没法让标签页排队。
- 轮换改成比对再写入(Lua),抢输的重读后走宽限期
- 宽限期里回的是当前那张 refresh token,不再回 null,几个标签页最后落到同一张上
- 响应丢了、前端拿旧的重试,也由同一支接住
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 19:27:08 +08:00
xuyue and Claude Opus 5.5
793848b06f
refactor(登录): 登录态从 Cookie 换成 access token + refresh token
...
Deploy / deploy (push) Canceled after 0s
- access token 是 15 分钟的 JWT,走 Authorization: Bearer;refresh token 7 天,每次换都轮换
- 退出登录、改密码、禁用账号仍然立刻生效:每个请求核对 Redis 会话和库里新加的 user.token_version
- 在服务器后台改密码 / 禁用,机房那边登着的也会一起下线(原来两边 Redis 分开,管不到)
- WebSocket 握手借子协议带 token;JWT 密钥存在本站 Redis,部署不用加配置
- 去掉 COOKIE_SECURE;上线后所有人要重新登录一次
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 19:22:52 +08:00
xuyue and Claude Opus 5.5
4be569d978
chore(文档): CLAUDE.md 瘦身,后端专属的坑挪进 apps/api/CLAUDE.md,并改正「推 origin 不部署」的说法
...
Deploy / deploy (push) Canceled after 0s
- 单二进制、runtime.ts、SQL 自 spawn、路由遮蔽、出参 satisfies、外键与迁移原样搬到
apps/api/CLAUDE.md,只在动后端文件时加载;根文件留一行指路
- Chrome 105 的 polyfill 审计细节挪到 apps/web/CLAUDE.md
- 删掉 ls 就能看到的仓库结构表,以及 docs/database.md、docker/judge/README.md 已有的重复步骤
- origin 会镜像到 github,平时推 origin 通常也就部署了(CLAUDE.md 与 deploy.md 原来写的是不触发)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 18:18:24 +08:00
xuyue and Claude Opus 5.5
51c3c16fd5
feat(题目): 参考流程图点一下能放大看,手机上宽图横着滚、按返回先关弹框
...
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 17:01:33 +08:00
xuyue and Claude Opus 5.5
67fcd11907
feat(题目): 参考流程图不用再点开,摊在例子后面,画法和学生自己画的图一样
...
Deploy / deploy (push) Canceled after 0s
原来折成一条「老师给的参考流程图」要点开,用 Mermaid 画、整张缩进左栏后字只剩十来像素。
现在默认摊开、放在例子后面(长图不把例子挤出第一屏),用画流程图那套排版和符号画
(FlowchartView,颜色形状和画布共用 paint.ts);只有手写 Mermaid 的老图照旧走 Mermaid。
出题页预览和说明文字一起改。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 16:56:44 +08:00
xuyue and Claude Opus 5.5
1a90a81868
feat(提交列表): 左边列表窄屏自动收窄,不用再手动点底栏的按钮
...
Deploy / deploy (push) Canceled after 0s
分栏不到 1200 宽(屏窄、或者浏览器放大了一档,右边的代码按 46 : 54 分看不全)
就自动收成两行的排法;1280 的屏不放大照旧是宽列表。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 10:36:03 +08:00
xuyue and Claude Opus 5.5
df152f505d
feat(课堂看板): 「这节课」写上是哪位老师布置的,别的老师改题也不换人
...
Deploy / deploy (push) Canceled after 0s
看板题号后面从「09:56 布置」变成「09:56 徐越 布置」,老师首页「今天的课」同样带上名字。
老师写真名(用户名 lwp0201、little 认不出是谁),没填真名的退回用户名。
「改」不再覆盖 created_by,和布置时间一样认第一次布置的人。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-20 09:56:46 +08:00
xuyue and Claude Opus 5.5
3fa897bec1
revert(流程图): 去掉「显示时自动认老参考图的框」——线上 36 张参考图已经全部转成结构树
...
Deploy / deploy (push) Canceled after 0s
c4306b0 是给手写 Mermaid 的老参考图兜底的;36 张已经在线上逐题转成画布格式(自动转 19 张、
照原图手工画 10 张,重复的比赛题 7 张),回读核对过其余字段没变,线上不再有没标种类的图。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 22:27:46 +08:00
xuyue and Claude Opus 5.5
e91f7cabc4
style(题目): 「你画的流程图」缩略图从 150px 加高到 260px,框里的字看得清
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 22:18:28 +08:00
xuyue and Claude Opus 5.5
c4306b092d
fix(流程图): 老师给的参考流程图是一堆彩色方框,和学生画的标准符号对不上
...
题面里的 36 张参考图都是 2026-10 之前手写的 Mermaid,一个框的种类都没标,只能按字分彩色。
显示前按写法和字认框(花括号是判断、开始结束是起止、以输入 / 输出 / 打印开头或写着
input( / print( 的是输入输出框,其余是处理框),换成标准形状和配色。数据不动;
学生的老提交都标了种类,不受影响。36 张全部渲染过,框数不变。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 22:18:28 +08:00
xuyue and Claude Opus 5.5
941cd64252
fix(题目): 题面「你画的流程图」缩略图只露出中间一截,要上下滚才看得全
...
Deploy / deploy (push) Canceled after 0s
pele 在图上写了内联的 height: auto,盖掉了按框高缩小的样式,图按原尺寸塞进 150px 的框。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 22:14:30 +08:00
xuyue and Claude Opus 5.5
9ae6287fb1
feat(流程图): 没画对也分得出远近——五档说法、完成度条、比上次多对了几组;右栏的图放大
...
只说「还没画对」,学生改了几次还是这一句,看不出在往前走。等级照旧存 S/A/B/C,
标题换成话:画对了,画得很清楚 / 画对了 / 快画对了 / 对了一部分 / 还没画对;
下面一根完成度条,走对几组亮几段;第二次起没画对时说比上次多(少)对了几组
(详情接口带上同一道题上一次走对了几组)。提交列表右栏的图从 42% 加宽到 62%,
小图也放大填满图框(最多 1.5 倍)。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 22:11:42 +08:00
xuyue and Claude Opus 5.5
ba90fe893e
feat(流程图): 结果先说「还没画对 / 画对了」和哪里错、怎么改,逐组数据收成一行点开才看
...
学生不关心过了几组数据。标题不再写「6 组走对 3 组」;点评做主体(AI 没写出来时
拿程序找到的第一处现象顶上);画布上只把要改的框标红、旁边写「要改这个框」,
别的框不再变淡,点开某一组才亮它走过的路;画对了直接给「照着它写代码」。
提交列表右栏老师看到的和学生一样,逐组数据也收着。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 22:03:16 +08:00
xuyue and Claude Opus 5.5
d2fc0382ec
feat(流程图): 没走对的图,AI 对照答案说出错在哪个框、该怎么改,并把那个框标红
...
原来只有程序拼出的现象(「输出 a」输出的是 2,应该是 8),指的是出结果的框,
错的根子常在前面,学生和老师都看不出该改哪里。跑完以后再请 AI 看题目、图、
没走对的几组和老师的答案,写「哪里错了 / 可以这样改」两句,指出真正要改的框;
提交列表右栏的图和题目页画布上标红它。等级照旧只由跑出来的结果定,
点评失败或像代码就不要,退回只显示逐组结果。老提交不补。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:52:05 +08:00
xuyue and Claude Opus 5.5
8bd3d998ae
fix(提交列表): 筛选栏折成两行时「统计」单独掉下去会跑到最左边
...
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:41:47 +08:00
xuyue and Claude Opus 5.5
0f75fd1bd0
fix(提交列表): 流程图右栏窄时题目名被「查看大图」「重新评分」挤成一个字
...
右栏不到 760 宽时这两个按钮只留图标,字放进悬停提示。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:41:47 +08:00
xuyue and Claude Opus 5.5
5c997b6276
fix(提交列表): 窗口窄时筛选栏的学生、题号框被压扁,「统计」被挤出屏幕
...
排不下就折成两行,各个框保持原宽;1280 以上照旧一行、高度不变。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:38:53 +08:00
xuyue and Claude Opus 5.5
a24bb6c80b
feat(提交列表): 底栏加一个按钮把左边列表收窄,代码区留宽一点
...
收窄后每条排成手机上那样的两行(名字 + 结果、时间 + 题目 + 语言),
翻页换成「页码 / 总页数」;收没收着记在本机。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:37:00 +08:00
xuyue and Claude Opus 5.5
c6458eb373
fix(提交列表): 屏窄或浏览器放大时,右栏顶上的按钮和底栏「本页第几条」被切掉
...
右栏宽度不到 600 时顶行固定拆成两行(名字和按钮一行、题目一行),
底栏收起方向键提示;不到 440 再收起「本页第几条」,让给两个复制按钮。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:37:00 +08:00
xuyue and Claude Opus 5.5
d1b47e268e
fix(提交列表): 停在第一页时右栏每 15 秒重载一次,放大看的流程图被自己关掉
...
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:23:51 +08:00
xuyue and Claude Opus 5.5
5f1c9072eb
fix(课堂看板): 布置题目时题号打到一半,每 15 秒被清空一次
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:21:07 +08:00
xuyue and Claude Opus 5.5
67b13a9345
fix(流程图): 老提交重新评分后四项明细全显示「0 / 0」
...
Deploy / deploy (push) Canceled after 0s
老办法(四项打总分)的 prompt 只写了 "criteria_details":{},模型换成 deepseek-flash
之后直接给 {"逻辑正确性": 32} 这样的裸数字,详情页读不到 score / max。prompt 里把
四项的形状写全,存之前按 { score, max, comment } 收好(缺满分按 40/30/20/10 补);
0036 把线上已经存进去的 4 条改回来。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:11:35 +08:00
xuyue and Claude Opus 5.5
d8e0efd05e
feat(课堂看板): 做对的格子写第几次做对,点开看他今天交的每一次和代码
...
- 格子:一次就对的还是「✓」,第 9 次才对的写「✓ 9」
- 点做对的格子弹出方块串(一格一次、从早到晚),停在哪格看哪次的代码,
默认停在做对前最后错的那次;下面能开这次提交、去提交列表看全部
- 方块配色和代码缓存从统计页的 AttemptSquares 抽到 statistics/attempts.ts 两边共用
- 点开一道题后面板里的题名可以点,新标签打开题目
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:09:35 +08:00
xuyue and Claude Opus 5.5
940895f643
feat(课堂看板): 接口给做对了的格子带上今天每一次代码提交和第几次做对
...
原来今天最后一次提交只给没做对的格子;现在同一条查询取今天全部,做对了的格子
多带 trail(从早到晚的 id / 结果 / 时间)和 acceptedTry(今天第几次做对,
以前就做对了的为 null)。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 21:09:35 +08:00
xuyue and Claude Opus 5.5
38360e8668
perf(流程图): 流程图改用 pele 渲染,懒加载从 200 kB 降到 44 kB(gzip)
...
Deploy / deploy (push) Canceled after 0s
mermaid 换成 obsidianmd/pele:同一套 Mermaid 语法、同步渲染、没有依赖。
库里 2170 张图(题目参考图 36、学生提交 2134)两边逐张对过,能画的和报错的完全一致。
配色按 pele 的 DOM 重写选择器,颜色不变;版本锁死在 1.6.0。
顺带按 modernPolyfills: true 重新探测了 polyfill 清单(50 项),并改正注释里
「DEBUG 会打印全集」的说法 —— 写死清单时它只回显清单。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 20:50:17 +08:00
xuyue and Claude Opus 5.5
a1d14a06bc
refactor(卡点分析): 右栏一道题的详情拆成 StuckDetail 组件
...
Deploy / deploy (push) Canceled after 0s
Stuck.vue 从 1006 行减到 544 行,右栏(做过几人、一次就对、错在哪、各班、交了几次才对、
历年、还没做对的人)连同它的计算和样式挪到 components/StuckDetail.vue;取数、三栏联动、
手机上整屏盖住的那层还在 Stuck.vue。两边都用的百分比和平均次数放 stuckMath.ts,
两边都用的几条小样式(muted / num / track …)各留一份。
纯搬家。全部班级、选一个班、手机打开一道题的详情,各自的顶部和滚到底改前改后截图一致。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 20:40:27 +08:00
xuyue and Claude Opus 5.5
ef7d065419
refactor(课堂看板): 布置题号、请假框拆成组件,格子的显示规则挪成纯函数
...
board.vue 从 1480 行减到 1283 行:
- components/LessonForm.vue:布置这节课的题(顶上一行的小条和刚上课时的大框是同一个组件的
两种样子,语言默认、推断的题带进框里这些规则跟着走)
- components/LeaveModal.vue:请假框(谁能算请假的规则还在看板,框里只管勾)
- boardCells.ts:格子的字、颜色、悬停说明和「卡住」的次数线,同 errorKind.ts 的做法
纯搬家。看板、选中一道题、请假框、勾了请假、顶上编辑、刚上课的大框(电脑 / 手机)改前改后
截图一致(唯一不同是测试学生的「在线」五分钟后过期变成「5 分钟前在」);顶上一行布置 /
清掉、大框布置、请假确定后「请假 1 人」并排到最下、再打开勾选还在、全部取消都正常。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-19 20:37:13 +08:00
xuyue and Claude Opus 5.5
871861220e
refactor(提交列表): 选中翻阅、实时更新、「这节课」、带条件去统计拆成四个 composable
...
list.vue 从 1834 行减到 1604 行,拆出 oj/submission/composables/ 下的
rowCursor(↑ ↓ 换条、页头页尾自动翻页)、listLive(正在评分的 3 秒刷新、第一页的
「有 N 条新提交」)、lessonFilter(「这节课」一键筛)、statsLink(和统计之间来回带条件)。
注释原样跟着走。
纯搬家。七个状态(列表、↓↓、↑、流程图、我的、手机列表、手机详情)改前改后截图一致;
连按 31 下 ↓ 翻到第 2 页,别人交一条后 18 秒内出「有 1 条新提交」,「这节课」筛到
班级 + 题号 + 今天。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 15:48:43 +08:00
xuyue and Claude Opus 5.5
ff3fdc0b1d
refactor(出题页): 编程题和 SQL 题两个出题页抄了两份的零件收到一处
...
Deploy / deploy (push) Canceled after 0s
admin/problem/components/problemForm.ts:判空富文本 isBlankHtml(原来三份,CodePreview 里还有
一份)、难度选项、返回列表的路由、保存失败的提示、标签超长校验、新建页的草稿
(useCreateDraft:停 0.8 秒存、什么都没填就清、编辑页不存)。
纯搬家。新建 / 编辑 × 编程 / SQL 四个页面改前改后整页截图逐像素一致;两种新建页填个
标题、刷新能恢复,「清空草稿」之后本地存储清掉。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 15:43:25 +08:00
xuyue and Claude Opus 5.5
e8a20d12f9
refactor(前端): shared / utils 不再 import oj 和 admin 下的任何东西
...
依赖方向原来是反的:顶栏、登录框、举手列表这些 shared 组件从 oj/ 里拿东西。
- 跨端的接口挪进 shared/api.ts(按 apps/web/CLAUDE.md 的分法):学生端题目列表、
出题人列表、这节课的题、待弹的成就
- 这节课的 store → shared/store/lesson.ts;头像 RankAvatar → shared/components
- 纯函数挪进 utils/:举手列表的错法归类 errorKind、它依赖的答案错误分类 wrongAnswer
和 Python 报错翻译 pythonError、题目列表行的 toProblemRow
- 只有后台在用的出题人下拉 AuthorSelect 挪回 admin/components
纯搬家。首页、题目列表、题目页、排名、课堂看板、后台题目列表打开无报错,
顶栏题号框敲 1001 回车直达题目页。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 15:11:21 +08:00
xuyue and Claude Opus 5.5
d4aadc7722
fix(后台列表): 加载失败有提示、慢的时候表格转圈、旧请求晚回来不再盖掉新结果
...
Deploy / deploy (push) Canceled after 0s
后台八个列表(题目、比赛、用户、公告、题单、AI 报告、从题库加题、标签下的题)原来是
`const res = await getXxx(); rows.value = res.results`:接口 500 或断网时什么都不提示,
表格停在旧数据上;关键词防抖和翻页一交错,先发的晚回来会把新结果盖掉。
shared/composables/listLoader.ts 的 track() 把请求包一层:带请求序号、出错按后端文案提示
(登录过期、没权限这几种全局拦截器已经提示过,不弹第二遍)、表格挂 loading。
实跑:六个列表各 10 行正常;拦掉题目列表的接口再翻页,弹「网络异常,请检查网络后重试」
(原来没有任何反应)。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 15:07:10 +08:00
xuyue and Claude Opus 5.5
4dfd14f95b
refactor(契约): 前端 60 个写请求的请求体接上契约类型,前后端对不上编译期就报
...
Deploy / deploy (push) Canceled after 0s
- 前端 oj/api.ts、admin/api.ts、shared/api.ts 的 post / put 请求体一律 `satisfies XxxRequest`,
只在编译期检查,不加运行时校验(和「只在三处挂运行时闸门」的规矩一致)
- 契约里的 XxxRequest 从 z.infer 改成 z.input:请求类型描述的是「客户端可以发什么」,
带默认值的字段可以不传。后端从不用这些类型(它用 parse 出来的 data),不受影响
- 补了四个漏导出的请求类型(比赛题目排序、题单题目排序、标签分类、检查用户名)
- 接上之后对不上的几处:编辑用户的角色和题目权限经 toAdminType / toProblemPermission
收窄,导入用户的行改成四元组,练习题数据改成 Record,格式化的语言只收后端认的四种
(isFormatLanguage)。出题页和成就的请求体是「表单校验兜底、出站补默认值」,
用 Partial<…> 只核键名和值的类型
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 15:03:58 +08:00
xuyue and Claude Opus 5.5
309ca0ece2
refactor(前端): 全站共用的班级下拉、胶囊配色挪出提交列表目录,编辑器不再偷读题目页的 store
...
Deploy / deploy (push) Canceled after 0s
- classLabel / groupClassOptions / classSelectOptions 挪到 utils/classes.ts,useTone 挪到
shared/composables/tone.ts:原来放在 oj/submission/ 下,被前台、后台、shared 引了 50 多处
- 流程图编辑器的草稿键改由题目页传进来(键名不变,学生存着的草稿照样读得到)。原来编辑器
自己读题目页的 store 和路由拼,后台出题页也用这个组件,那边 store 是空的
- SQL 表名补全改由题目页传表进来。原来补全直接读题目页的 store,自学页的 SQL 代码块会
补出上一道看过的题的表名
实跑:提交列表、题目页、排名、后台题目页、SQL 题、流程图题打开无报错;SQL 题输入 stu
补出 students;流程图加一步,草稿照旧存在 flowchart-v2-problem-<题号>。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 14:59:55 +08:00
xuyue and Claude Opus 5.5
465dbfd42f
refactor(后端): 权限判断收到一处,路由文件之间不再互相 import
...
- services/permissions.ts:「超管或创建者」原来在比赛、题单、比赛题目(4 处)、
services/contest.ts 各抄一遍,「题目全部权限」在题目和标签两个路由各写一份
- services/submission-filters.ts:提交列表的用户名 / 班级 / 题号筛选,原来
submission.ts、flowchart.ts 从 submission-statistics.ts 这个路由文件里拿
- services/class-activity.ts:课堂做题记录的口径和「正在上课的班」,原来后台
conf.ts 从 classroom.ts 路由里拿
- services/problem-tags.ts:标签名去重、按名查标签,原来 tag.ts 从 admin/problem.ts 拿
纯搬家。三种身份(超管 / 老师 / 学生)打了 26 个受影响的接口,改前改后状态码和响应体
逐字节一致,包括「不是自己的比赛 / 题单 / 题目报不存在」那几条。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 14:53:24 +08:00
xuyue and Claude Opus 5.5
5787efe023
refactor(前端): 角色判断改用契约里的白名单,不再在 user store 里逐个列角色
...
契约 roles.ts 写明 ADMIN_ROLES / TEACHER_ROLES 是全仓唯一的定义处,前端 user store
却用 === 把角色又列了一遍;将来加角色只改契约就会两边对不上。判断结果不变。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 14:53:24 +08:00
xuyue and Claude Opus 5.5
fb11e86151
perf(排名): 一个班同时打开排名、班级对抗、按人数排的题目列表时只查一次库
...
这几样谁来看都一样,原来每次请求现算:全服全部时间的排名本机 16 核就要 250ms,
服务器两核还要判题。services/cache.ts 进程内缓存 10 秒,同时到达的相同请求等同一个结果:
- 排名榜面的原始数据(「我」排第几、前后一名照旧每次现算):250ms → 6ms
- 班级对抗 / 详情 / PK 共用的这学期数据:40ms → 1ms
- 题目列表按做对、做过人数排序的全表人数:45ms → 20ms
40 个人同时打开全服排名(缓存是冷的)一共 342ms。代价是做对之后最多晚 10 秒上榜。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 14:47:24 +08:00
xuyue and Claude Opus 5.5
307b0725d0
perf(判题): 判题机上同时跑的程序从最多 8 个压到 4 个,挤的时候不再把不超时的判成超时
...
原来四道闸各管各的(worker 判题 2、api 试运行 2、提交前编译检查 2、worker 里流程图
评分的试运行又 2),api 和 worker 两个进程互相看不见,峰值 8 个程序压在服务器两个核上;
判题机按墙钟判超时,挤到一定程度会冤枉学生。
judge/slots.ts 在 Redis 里按池数名额(每个站点各数各的):
- 后台池(正式判题、诊断重跑、流程图评分)上限 JUDGE_CONCURRENCY
- 交互池(运行例子、自己输入、生成测试点、编译检查)上限 TRIAL_CONCURRENCY
两池不互相借,正式判题排再长也挤不掉学生的「运行例子」。名额是带到期时间的租约,
进程被杀了到期自动作废;Redis 出错直接放行。正式判题的超时从拿到名额才开始算。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 14:47:24 +08:00
xuyue and Claude Opus 5.5
64994b9499
perf(判题结果): 全班一起交、判题排队时不再每人每 2 秒问一次结果
...
Deploy / deploy (push) Canceled after 0s
原来交上去 5 秒没结果就每 2 秒(流程图 3 秒)拉一次,分不清 WebSocket 断了还是队列长:
50 人一起交、队列排一分钟时每秒二十几个请求,全在和判题抢那两个核。
- 收到这一条的任何推送(服务端订阅时就回一帧当前状态)就认定 WebSocket 是通的,
轮询退到 20 秒一次,只防推送丢失;连接断了才回快档,2 秒起按 1.5 倍退到 10 秒
- 拉失败不再永久停掉(掉线那几秒拉失败是常事),连着失败 5 次才放弃
- 页面在后台时不拉;比赛题目页、榜单、班级页的定时刷新也一样,切回来立刻补一次
- 代码判题和流程图评分共用 shared/composables/fallbackPoll.ts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 14:37:08 +08:00
xuyue and Claude Opus 5.5
593a409fca
chore(部署): 服务器上课高峰时网页先于判题拿到 CPU,内存挤满时不先杀数据库
...
Deploy / deploy (push) Canceled after 0s
服务器 2 核 7.5G、没有 swap,和二十多个别的服务共用(空闲可用 3.5G):
- postgres:shared_buffers 512MB(全库 249MB 能常驻)、work_mem 16MB、shm 256m、
oom_score_adj -500;事务空闲 60 秒断开 + TCP 保活,机房断网时锁不会挂两小时
- postgres、api 的 cpu_shares 加倍(按比例分、不封顶)
- 判题沙箱、worker 内存上限 512m → 1g:最多六份同时编译、SQL 判题两个子进程都能顶满 512m
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 14:21:02 +08:00
xuyue and Claude Opus 5.5
55038cc78b
fix(判题): 判题机卡住不再让全班一直「等待评分」,重判和同时交对也不再把做对题数算多
...
Deploy / deploy (push) Canceled after 0s
- 正式判题、样例重跑、运行时错误诊断都加了超时(默认 120 秒,时限放宽的题按比例放宽),
超时记系统错误、提示是中文;回包和试运行一样边读边数,超过 16MB 就掐断,
免得一个疯狂打印的错误程序把 worker 撑爆
- 做对题数、中等、困难、一次就对改成在锁里按定义现数:原来逐次 +1,两条挨着判完或重判
一条做对的提交都会多加,库里 372 人多了 1–4 道。0035 把存量一次订正
- 重判不再给提交次数、凌晨/早起计数 +1,编译错误按前后差值改;「错了几次才对」只数这条之前的
- 已拿到的成就数只 jsonb_set 那一个键,不再整块写回冲掉并发判题刚写的指标
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 14:15:08 +08:00
xuyue and Claude Opus 5.5
5aafcf172b
chore(前端): 删掉没人引用的旧网站图标(红色 D)
...
页面用的是 noto--dog-face.ico,这个 favicon.ico 是从 ojnext 搬过来时留下的。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 13:51:10 +08:00
xuyue and Claude Opus 5.5
3bb74171c3
perf(加载): 排名、看板、班级 PK、智能分析第一次打开少下两百多 KB
...
这几页的 Markdown 只在点开抽屉 / 弹层、或 AI 报告出来时才用得上,
却连着整套代码高亮(CodeMirror 和三种语言的解析器)一起静态打进了页面。
改成用到才加载:排名 356→133KB、看板 380→157KB、PK 311→88KB、
智能分析 308→86KB(gzip 后)。
网站图标原来塞了 16 到 256 像素九张图共 192KB,只留标签页用得上的
16 到 48 像素四张(原图像素不变),17KB。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 13:48:35 +08:00
xuyue and Claude Opus 5.5
a814776fb9
feat(教程): 改练一练时可以顺手清空学生的作答——改了答案,按旧答案做对的人不再算做对
...
Deploy / deploy (push) Canceled after 0s
练一练是原地改的,作答记录跟着题走:改了答案或选项,按旧答案做对的人仍然显示做对、
「最后错在 选了 B」说的也是旧选项。编辑框底下多一个「同时清空学生的作答(N 人做过)」,
没人做过时不出现;勾上保存,学生那边这道题回到没做。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 12:28:47 +08:00
xuyue and Claude Opus 5.5
1ebb23cdac
feat(自学情况): 看得到配套题做没做——每人一列、每课一个页签、学生明细里逐题列出
...
Deploy / deploy (push) Canceled after 0s
- 方块格多一列「配套题」:他打开过的那些课挂的题,做对几道 / 一共几道;格子提示里也带上
- 右栏分「练一练 / 配套题」两个页签:每道题读过这课的人里几人做对,点开看谁没交、谁交了没对,
一键跳到这个人这道题的提交
- 学生明细每课多一段配套题:做对没有、交了几次、最后哪天交的
- 做对不论早晚,读教程之前在课上做对的也算;口径同学生端课文里那个勾(代码 AC 或流程图 A / S)
- 1366 宽下 C 语言 20 课也不用横着滑了:「最后学习」只留日期,几列收窄
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 12:21:34 +08:00
xuyue and Claude Opus 5.5
7839a65f59
feat(自学情况): 每个学生练一练做到哪了——格子分出做了一部分、点名字看逐题明细
...
- 方块格多一档「做了一部分」:按做对的比例从下往上涨绿,一道没做对的底下压一条橙;
鼠标停上去是「练一练 3/5,错了 4 次」
- 「练一练」列改成 做对/应做(应做 = 他打开过的课的练一练总数)
- 点学生名字从右边滑出明细:每课一段,逐题写第几次做对、交了几次、最后错在哪;
手机上返回键关它
- 点开一道练一练,底下多一串「读了这课还没做」的人
- 顺手修:那个弹框七列加起来比弹框宽,「最后作答」被挤没了;改成一列用户名
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 11:40:30 +08:00
xuyue and Claude Opus 5.5
859a537804
feat(用户): 选一个班就能下载全班的用户名和密码(表格)
...
Deploy / deploy (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-10-16 11:22:10 +08:00