diff --git a/docs/student-grades-demo.md b/docs/student-grades-demo.md new file mode 100644 index 0000000..5e91e9e --- /dev/null +++ b/docs/student-grades-demo.md @@ -0,0 +1,34 @@ +# 学生成绩管理中心测试页 + +源码:[student-grades.endor](../examples/student-grades.endor)。 + +在 Tessera 按 F12 打开 Console,点击 `>` 输入位置,粘贴完整源码后按 Enter。 +源码创建并渲染一个独立的「学生成绩管理中心」Page,不替换其他页面。 + +该示例使用 6 位虚构学生的内存对象,展示语文、数学、英语和复核状态。 +它验证 Endor 类、原生 Column 子类的测量、自定义绘制、字段绑定、事件和 +同一对象在筛选前后的共享状态。关闭应用后数据不会保存。 + +## 已完成的原生检查 + +- 通过原生 Console 粘贴完整源码并按 Enter,成功出现成绩页标签和 6 行数据。 +- 「查看复核记录」切换为林沐的一行复核记录。 +- 「录入复核成绩」执行示例中预设的复核结果:数学 58 → 68、状态改为已复核、待复核 1 → 0。 +- 「全部学生」恢复 6 行,林沐的 68 分和已复核状态保留。 +- 「恢复示例数据」恢复 58 分、待复核状态和计数 1。 + +这是交互测试示例,复核按钮应用预设结果,不是通用成绩录入表单;没有 +文件存储、通用校验、导入导出、真实学校数据或完整 CRUD 的实现声明。 + +## 录制结果 + +尝试了 macOS screencapture 的窗口录像与限定区域录像,均返回 capture error。 +随后尝试 QuickTime「新建录屏」,没有成功出现可操作的录制界面;直接打开 +系统录屏工具也超时。因此没有成功生成连续录屏,不把截图当作录屏交付。 + +原生操作关键截图保存在本次会话的 /private/tmp/endor-grades-demo/: +01-endor-input.png、02-rendered.png、03-filtered.png、04-reviewed.png、 +05-all-reviewed.png、06-reset.png。 + +本次仅新增示例和此说明,未修改渲染器。以实际 Console 执行和原生点击 +作为验证;未运行 cargo test、自动化 smoke 脚本,也未因纯示例新增而重复构建。 diff --git a/examples/student-grades.endor b/examples/student-grades.endor new file mode 100644 index 0000000..a792ce6 --- /dev/null +++ b/examples/student-grades.endor @@ -0,0 +1,112 @@ +// Student grades demo. Fictional records; in-memory only. +// Paste the entire file into Tessera Console, then press Enter. +class GradeCell: Column { + width: Number + function measure(self: GradeCell, mount: Mount, constraints: Constraints): MeasureResult { + size = Column.measure(self, mount, constraints) + size.width = self.width + return size + } +} +class GradePanel: Column { + function paint(self: GradePanel, mount: Mount, geometry: Bounds): DisplayList { + fill = PaintCommand() + fill.kind = "roundedRect" + fill.x = geometry.x + fill.y = geometry.y + fill.width = geometry.width + fill.height = geometry.height + fill.radius = 12 + fill.color = "#FFFFFF" + return DisplayList(ObjectList(fill)) + } +} +class Student { + name: String + number: String + chinese: Number + math: Number + english: Number + status: String +} +function gradeCell(content: Block, width: Number): Block { + return GradeCell(0, 0, content, width) +} +function gradeRow(student: Student): Block { + return Column(0, 12, + Row(0, 0, + gradeCell(TextBlock(student.name), 150), + gradeCell(TextBlock(student.number, 1, "#7A8390"), 120), + gradeCell(ui.textOf(student, "chinese"), 100), + gradeCell(ui.textOf(student, "math"), 100), + gradeCell(ui.textOf(student, "english"), 100), + gradeCell(ui.textOf(student, "status", 1, "#526C83"), 160)), + RectBlock(730, 1, 0, "#EDF0F3")) +} +class GradeCenter { + table: Column + all: Column + attention: Column + student: Student + pending: Number + message: String + function showAll(self: GradeCenter, event: Event): Unit { + self.table.replace(0, self.all) + self.message = "正在查看全部 6 位学生" + } + function showAttention(self: GradeCenter, event: Event): Unit { + self.table.replace(0, self.attention) + self.message = "林沐的数学成绩有一条复核记录" + } + function review(self: GradeCenter, event: Event): Unit { + self.student.math = 68 + self.student.status = "已复核" + self.pending = 0 + self.message = "已录入复核结果:林沐 · 数学 58 → 68" + } + function reset(self: GradeCenter, event: Event): Unit { + self.student.math = 58 + self.student.status = "待复核" + self.pending = 1 + self.table.replace(0, self.all) + self.message = "已恢复示例数据" + } +} +studentLin = Student("林沐", "2026001", 86, 58, 91, "待复核") +studentChen = Student("陈知夏", "2026002", 94, 96, 93, "已确认") +studentXu = Student("许星河", "2026003", 82, 88, 85, "已确认") +studentZhou = Student("周予安", "2026004", 91, 89, 95, "已确认") +studentSu = Student("苏映雪", "2026005", 88, 92, 90, "已确认") +studentLu = Student("陆景行", "2026006", 79, 84, 87, "已确认") +allGradeRows = Column(0, 14, gradeRow(studentLin), gradeRow(studentChen), gradeRow(studentXu), gradeRow(studentZhou), gradeRow(studentSu), gradeRow(studentLu)) +attentionGradeRows = Column(0, 14, gradeRow(studentLin)) +gradeTable = Column(0, 0, allGradeRows) +gradeCenter = GradeCenter(gradeTable, allGradeRows, attentionGradeRows, studentLin, 1, "正在查看全部 6 位学生") +showAllGrades = Button("全部学生") +showAttentionGrades = Button("查看复核记录") +reviewGrade = Button("录入复核成绩") +resetGrades = Button("恢复示例数据") +showAllGrades.on("click", gradeCenter.showAll) +showAttentionGrades.on("click", gradeCenter.showAttention) +reviewGrade.on("click", gradeCenter.review) +resetGrades.on("click", gradeCenter.reset) +gradeHeader = Row(0, 0, + gradeCell(TextBlock("学生", 1, "#7A8390"), 150), + gradeCell(TextBlock("学号", 1, "#7A8390"), 120), + gradeCell(TextBlock("语文", 1, "#7A8390"), 100), + gradeCell(TextBlock("数学", 1, "#7A8390"), 100), + gradeCell(TextBlock("英语", 1, "#7A8390"), 100), + gradeCell(TextBlock("状态", 1, "#7A8390"), 160)) +gradeSummary = Row(0, 40, + Column(0, 6, TextBlock("学生人数", 1, "#7A8390"), TextBlock("6", 2)), + Column(0, 6, TextBlock("考试科目", 1, "#7A8390"), TextBlock("3", 2)), + Column(0, 6, TextBlock("待复核", 1, "#7A8390"), ui.textOf(gradeCenter, "pending", 2))) +gradesPage = Page() +gradesPage.title = "学生成绩管理中心" +gradesPage.render(Column(32, 20, + TextBlock("学生成绩管理中心", 2, "#273444"), + TextBlock("高一(3)班 · 2026 秋季阶段测评 · 虚构示例数据", 1, "#7A8390"), + gradeSummary, + Row(0, 10, showAllGrades, showAttentionGrades, reviewGrade, resetGrades), + GradePanel(20, 16, gradeHeader, RectBlock(730, 1, 0, "#E5EAF0"), gradeTable), + ui.textOf(gradeCenter, "message", 1, "#526C83")))