Grades Viewer(自用成绩看板)
已上线自用成绩看板 · 学生 CRUD + CSV/拍照 OCR 导入 + 趋势/雷达图 + 老师评语融合的 AI 评语 + PDF 导出 · 仅自用无登录
📋 规划 🚧 在搭 ✅ 已上线 ⏸ 暂停 🗄 归档
⏰ 创建 2026-08-25 · 已 27 天 更新 2026-09-22
#product
#family
#parent-tool 📖 读完约 4 分钟 📝 938 字 · 27 段 🔗 0 外链 OPC #22 …
优先级:medium
技术栈:
Astro 7 · @astrojs/cloudflare 14 · Cloudflare Worker Static Assets · D1 · Claude Haiku Vision Grades Viewer
grades-viewer.linweiheng2009.workers.dev — 自用孩子成绩看板。
形态
- 单一学生看板页:趋势图 + 雷达图 + 最近考试 + 下次预测 + AI 评语 + 老师评语卡片
- 列表/详情双视图,首页统计
- 浏览器原生 A4 PDF 导出 (window.print CSS)
- 评论 JSON 导出
- 无登录、无社交、无 public share
数据录入 (两条路)
CSV (P509+)
- 13 列:
date / type / semester / subject / score / full_score / class_rank / grade_rank / total_score / class_size / grade_size / teacher_comment / notes - 走
/import页面 → dry-run 校验预览 → 确认导入
拍成绩单图片 OCR (P511)
- 调 Claude Haiku Vision,严格
output_config.format: { type: 'json_schema', strict: true }输出 - HEIC 客户端 canvas 转 JPEG (iPhone 默认格式)
- 4MB 上限,JPEG/PNG/WEBP/GIF 白名单
- 同样的 13 列 CSV → 走相同 import 流程 (零代码重复)
数据展示
- TrendChart 趋势图 (P513) — Tailwind 8 色柔和调色板,按学期分组多列 X 轴,viewBox 按数据量自适应,3 点移动平均,90/60 阈值线,分数标签 ≥12 点自动隐藏
- RadarChart 雷达图 / 班级中位线
- 最近考试 + 线性回归预测下次分数 (3 点滑动窗口)
AI 评语 (3 模式 + 老师评语融合)
- 类型:
exam/semester/year - 模型: Claude Haiku (
ANTHROPIC_API_KEY/ANTHROPIC_BASE_URL可换),无 key 走规则引擎兜底 - P513 起:
teacher_comments进 prompt — exams.teacher_comment 字段 + 按 type 过滤后作为时间线上下文,让评语从冷冰冰数字变成”上次老师说…” - 评语保存到
ai_comments表,可重复生成 / 删除 / JSON 导出
老师评语卡片 (P513 新)
exams表加teacher_comment TEXT列- 详情页 + 打印页 同步展示 (倒序 + 班级排名徽标)
- CSV/OCR 端到端:13 列 schema + UPDATE
COALESCE(?, teacher_comment)保留手工编辑
数据示例 (D1 已 seed)
seed-demo.sql— 小明 (4年级, 4 exams × 3 科 = 12 分数)seed-multi-grade.sql— 乐乐 (1-3 年级共 23 场 × 81 分数, 含 5 条真实风格老师评语覆盖各学年关键节点)
工程要点
- Astro 7.3 SSR + @astrojs/cloudflare 14 (Worker Static Assets, 不是 Pages)
cloudflare:workersenv 取 D1 (Astro 6+ 已删Astro.locals.runtime.env)- D1
db.exec()多行 SQL 不可靠 →db.prepare(s).run()串行 db接口抽象兼容 better-sqlite3 本地 + D1 远程,dev/prod 同代码import { env } from 'cloudflare:workers'替代 locals.runtime
部署
- Worker:
npm run deploy(= predeploy 注入 main + wrangler deploy + postbuild 清 ASSETS binding) - D1 schema: 手动
wrangler d1 execute --remote --file=schema.sql一次 (worker 内 ensureSchema 作 fallback) - 当前版本:
0a5b6189-488b-4663-8e0c-1e0694eccb95
踩坑
- 详见 memory
grades-viewer-deploy-cf-d1(vite sync 阶段读 main / D1 multiline exec / ASSETS binding 冲突) - 详见 memory
grades-viewer-ocr-vision(json_schema strict / HEIC / 老师评语字段映射)
下一步
- AI 自动发现成绩趋势异常并提示
- 多孩子横向对比 (同年级 / 同班级)
- OCR 准确度自检 (同一张图两次跑,字段不一致 → 报警)
- 老师评语自动按学科拆分 (现在 1 张图只 1 条 teacher_comment)
设置页 (P514)
- 主题切换: ☀️🌙🖥️ 三模式 (light/dark/system),localStorage 持久化,early-inject 避免 FOUC,跟随系统模式自动响应
prefers-color-scheme变化 - AI 连接测试:
POST /api/ai-test真发 16 token 极简请求 (max_tokens=16, prompt “回复一个字”),返回{ok, latencyMs, reply, costUSD}端到端验证 key+baseUrl+model - 学期别名管理:
kv_settings单行 JSON{"2025-fall": "2025 秋季"},TrendChart 顶部标签 + 详情页学期卡片消费该别名 - 数据导出:
GET /api/settings-export返回 JSON (students/exams/scores/comments),Content-Disposition 触发浏览器下载;支持?student_id=xxx单学生 - 重置:
POST /api/settings-resetbody{"confirm": "RESET"},清空所有业务表 (kv_settings 保留)
工程要点 (P514 增量)
kv_settings表: 单行 key-value 配置,新增getSetting/setSetting/listSettings三个 repo 函数ALLOWED_KEYS白名单过滤/api/settings写入,只暴露允许的 key- 别名 JSON 必须合法,set 端做
JSON.parse校验 - Astro 7 + @astrojs/cloudflare 14 已删
Astro.locals.runtime.env,探测 D1 必须用import { env as cfEnv } from 'cloudflare:workers'(踩过坑,settings.astro 第一次部署直接 500)
相关项目 (共享标签)
优孩计划 Kid Grow
在搭建0-22 岁分阶段成长卡片 · CF D1 + Astro + Resend 邮件推送 + Taro 微信小程序 + PushPlus 实时推送 · MVP 不做支付
producteducationparenting
URL to Markdown
已上线终身买断数字商品 · Pro $30 / Studio $80 / Unlimit $200 · 0 边际成本 · CLI 本地跑,无 LLM
productsaastool
Laowe Analytics(三站访问看板)
已上线三站访问看板 + X / Twitter 流量 · cron 09:07 UTC · D1 + Workers + Basic Auth 多用户
productopsmulti-tenant
AppStore Free(免费 App 榜)
已上线iTunes 免费 App 榜聚合 · 2026-08-30~09-02 大改:三 section + 顶部玻璃面板 + logo SVG + 移除 TW + 匿名/登录维度
productwebapp-discovery