# starry-frontend **Repository Path**: daily_study/starry-frontend ## Basic Information - **Project Name**: starry-frontend - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-17 - **Last Updated**: 2026-09-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 前端 · 闪闪小课堂 教学管理台 React 19 + Vite + TypeScript。九个模块(概览 / 课后 / 学员 / 课程 / 教学 / AI教学 / 出勤 / 积分 / 财务), 数据全部来自 starry-backend(`/api`),没有本机假数据。 ## 跑起来 ```bash pnpm install pnpm dev # http://localhost:5173,/api 代理到 http://127.0.0.1:4000 pnpm build # tsc -b && vite build → dist/ pnpm lint # oxlint ``` - 后端地址默认 `http://127.0.0.1:4000`,改 `VITE_API_TARGET` 可换(见 `vite.config.ts` 的代理)。 - 部署时用 `VITE_API_BASE` 指到后端域名即可,组件代码不用改。 - 生产也可以让后端直接托管 `dist/`:`uvicorn app.main:app` 检测到 `../starry-frontend/dist/index.html` 就会一并提供静态资源,**一个端口跑整站**。 ## 目录 ``` src/ App.tsx 顶栏 + 模块路由(TABS) api/client.ts 所有接口调用(唯一的网络出口) api/types.ts 与后端一一对应的类型 + 段落行渲染规则(sectionLines) modules/ 九个模块,一个模块一个文件 components/ Roster.tsx 花名册 / 备课台(日期轴:往后拨一天=提前写学习单) Sheet.tsx A4 学员学习单(屏幕与打印同一份 DOM) Stage.tsx 打样台:角线、毫米刻度、工单条(字号/缩放/页数/字数) features/ FeedbackEditor.tsx 课后反馈编辑区(与学习单表格逐行对应) lib/ format.ts 日期与金额(本地时区拼 YYYY-MM-DD,别用 toISOString) useSheetFit.ts A4 自动字号:二分找「能放进一页的最大字号」 useFitToStage.ts 打样台按可视区缩放(只影响屏幕,不影响打印) wechatText.ts 复制给家长的微信文字 pagination.ts 试卷分栏/装箱 styles/ tokens.css 设计令牌(配色与字体) app.css 外壳布局(顶栏、花名册、编辑区、打样台) modules.css 各模块的表格与卡片 sheet.css A4 学习单 + 打印样式(@page A4) exam.css A4/A3 试卷(密封线、得分表、答案页) ``` ## 打印 「打印 / 导出 PDF」会先把这一节课存成「已出稿」再拉起打印;打印样式里顶栏、花名册、编辑区、 刻度尺全部隐藏,只留 A4 那一张。打印窗口里选 **A4**、边距 **无**、勾上 **背景图形**;要 PDF 就选「另存为 PDF」。 ## 注意 - Vite 8 用 rolldown:npmmirror 上没有 `@rolldown/binding-darwin-universal`, `@rolldown/binding-darwin-arm64` 已固定在 devDependencies,缺了会报 Cannot find module。 - 本机 Node 22.5 低于 Vite 要求的 22.12:能跑,构建时会提示,介意就升 Node。 - 改了外键下拉框(课程 / 教材 / 老师)要同步那份「名字」字段(后端保存时才按 id 重算), 否则打样台标题还是旧课程——见 `AfterClass.tsx` 的 `patch()`。