Skip to content

feat(web): 学生原图缩略图支持单击放大查看(lightbox)#4

Merged
inkfin merged 3 commits into
mainfrom
feat/image-lightbox
May 2, 2026
Merged

feat(web): 学生原图缩略图支持单击放大查看(lightbox)#4
inkfin merged 3 commits into
mainfrom
feat/image-lightbox

Conversation

@inkfin

@inkfin inkfin commented May 2, 2026

Copy link
Copy Markdown
Owner

Summary

修复用户反馈:批改详情页 / 学生成绩单只能看缩略图,没法点开看原图细节。

  • 新增 web/components/student-image-grid.tsx:缩略图条 + 单击全屏 lightbox
    • Esc / 点遮罩 / 点 X 关闭
    • 桌面 ← / → 键 + 左右箭头按钮翻页
    • 移动端水平 swipe 翻页(阈值 50px,竖向滑动 / 多指捏合不触发)
    • 锁定 body scroll,避免 lightbox 打开时背后页面跟着滚
    • 单图不显示翻页 UI / 计数器
  • grade/[id] 详情抽屉、results/[id]/students/[studentId] 成绩单两处复用同一组件,避免分别再写一遍
  • 缩略图标题加「· 单击放大」hint 让老师知道能点
  • AGENTS.md 文件地图补一行说明

Test plan

  • npx tsc --noEmit 通过
  • docker compose up -d --build 全程构建并健康
    • curl /v1/livez ok
    • curl /api/health ok
  • 登录后进 /grade/<batch>,点格子 → 详情抽屉看到缩略图标 「· 单击放大」hint
  • 点缩略图,黑底 lightbox 弹出,原图清晰
  • 多图时左右翻页(桌面键盘 / 按钮,移动端 swipe)
  • Esc / 点遮罩 / 点 X 都能关闭
  • /results/<batch>/students/<id> 展开「学生原图」折叠面板,同样能放大

Made with Cursor

- 抽 web/components/student-image-grid.tsx:缩略图条 + 单击全屏 lightbox
  支持 Esc 关闭、← / → 翻页(桌面),移动端水平 swipe 翻页
- grade/[id] 详情抽屉、results/[id]/students/[studentId] 成绩单两处共用
  避免分别再写一遍放大逻辑
- AGENTS.md 文件地图补一行

修复用户反馈:详情页只能看缩略图、看不了原图细节。

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings May 2, 2026 08:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

为批改详情页与学生成绩单中的“学生原图缩略图”新增可点击放大查看的全屏 lightbox 能力,并抽成可复用组件,解决只能看缩略图无法核对细节的问题。

Changes:

  • 新增 StudentImageGrid 组件:缩略图网格 + 全屏 lightbox(Esc/遮罩/关闭按钮关闭,键盘左右键翻页,移动端 swipe 翻页,锁定 body 滚动)。
  • results/[id]/students/[studentId]grade/[id] 详情抽屉中复用该组件,并加入“· 单击放大”提示。
  • 更新 AGENTS.md 文件地图,补充新组件说明。

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
web/components/student-image-grid.tsx 新增缩略图网格与 lightbox 展示逻辑,并提供可复用 API(paths/className)。
web/app/(app)/results/[id]/students/[studentId]/page.tsx 将原有缩略图渲染替换为 StudentImageGrid,并加“单击放大”提示。
web/app/(app)/grade/[id]/cell-detail-sheet.tsx 在批改详情抽屉中替换为 StudentImageGrid,并控制抽屉内网格列数。
AGENTS.md 更新仓库文件地图,记录新组件与复用位置。

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread web/components/student-image-grid.tsx Outdated
Comment thread web/components/student-image-grid.tsx
Comment thread web/components/student-image-grid.tsx Outdated
Comment thread web/components/student-image-grid.tsx
inkfin and others added 2 commits May 2, 2026 16:28
学生原图缩略图打开后字还是太小,加自实现 zoom/pan:

- 双击:1× ↔ 2× toggle(焦点为鼠标位置)
- 桌面 wheel:±15% 步进缩放,焦点为鼠标位置
  非 passive listener + preventDefault 避免页面跟着滚
- 移动端双指 pinch:以两指中点为锚缩放
- 缩放后拖动平移:鼠标按住拖(桌面)/ 单指滑动(移动)
- 缩放范围 [1×, 4×],touchAction:none 接管原生手势
- 缩放后翻页按钮 / swipe 自动停用,避免与拖动冲突;切换图片自动复位
- 顶部右侧补倍率指示 + 复位按钮(键盘 0 也能复位)

不依赖第三方 zoom 库——react-zoom-pan-pinch 等体积比这一份逻辑还大。

Co-authored-by: Cursor <cursoragent@cursor.com>
1. 缩略图 key={p} 在 path 重复时会触发 React key collision warning
   → key={`${i}_${p}`} 防御(当前 imagePaths 是 sha-命名极少重复,但客户端
   拖拽 / 服务端写入未收敛时短暂重复也能稳)

2. lightbox 用 fixed inset-0 在 SheetContent 里被困在 480px 抽屉内
   CSS 规范:transform 不为 none 的祖先成为 fixed 后代的 containing block;
   SheetContent 带 `slide-in-from-right` transform 类正中此陷阱
   → createPortal(ui, document.body),永远渲到 body 顶层

3. lightbox 按钮(关闭 / 翻页 / 复位)缺 focus-visible 样式,键盘用户看不到焦点
   → 抽 btnClass 统一加 focus-visible:ring-2 ring-white/80(黑底反差好)+
   ring-offset-black

4. 没有 focus trap / 关闭后焦点恢复,screen reader / 键盘体验差
   → 用 inert 隔离 lightbox 之外的 body 兄弟节点(与 Radix Dialog 等价的 trap,
   比 sentinel 干净,不会出 Shift+Tab 死循环),autoFocus 关闭按钮,
   关闭时把焦点还给原触发缩略图按钮(document.activeElement 缓存 + try/catch)

附带:jsdoc 补 portal / 缩放 / focus 行为说明;按钮 aria-label 加键盘提示。

Co-authored-by: Cursor <cursoragent@cursor.com>
@inkfin inkfin merged commit f2bc8f1 into main May 2, 2026
@inkfin inkfin deleted the feat/image-lightbox branch May 2, 2026 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants