news 2026/6/10 18:42:15

从零搭建一个助教反馈生成系统:纯前端 SPA 的工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零搭建一个助教反馈生成系统:纯前端 SPA 的工程实践

一、项目背景

作为大学课程的助教,每学期末都要面对一项极具挑战性的工作:将课后作业分、课前预习分、课堂报告分和班级名单合并,为每个学生生成个性化的反馈评语,最后导出 Excel 上交。

这个流程的痛点很明确:

  • 表格多:至少 3 份 Excel,上百行数据
  • 规则复杂:不同分数段生成不同话术,课前/课后/课堂三个维度各有逻辑
  • 容易出错:手动拼姓名、对分数,稍有不慎就张冠李戴
  • 不易复用:下个学期换个课程又要重做

于是我花了几个周末,从零写了一个纯前端的助教反馈生成工具。这篇文章就来讲讲它的架构设计和技术细节。


二、项目概览

2.1 一句话定位

浏览器内一键合并多份教学表格,批量生成学生个性化反馈评语,支持 Excel 导出。

2.2 核心功能清单

功能说明
📂 多文件上传拖拽或浏览上传课后作业、课前预习、课堂报告、班级名单
🔢 课次自动识别从文件名智能提取课次,支持手动微调
✍️ 反馈话术生成按分数段 + 学生表现模板批量生成
📊 成绩统计图表Chart.js 驱动的分布直方图 + 课堂积分饼图
📈 多周趋势分析历史数据对比,趋势诊断与评语时间线
🤖 AI 辅助评语自封装 OpenAI 兼容客户端,支持 5 种 Provider
📥 多格式导出Excel(带样式)、截图图片、仅导出已选姓名
🚫 免交管理免交名单在线同步,自动跳过免交学生
🌓 深浅双主题CSS 变量 + Tailwind 暗色模式无缝切换
🎨 毛玻璃 UIbackdrop-filter 玻璃质感 + p5.js Perlin 噪声纹理
🐱 猫咪彩蛋点击 Logo 召唤一只摇尾巴的小猫

2.3 技术栈一览

层次技术选型说明
前端框架无框架,原生 JS(IIFE 模块)零构建,打开即用
UI 样式Tailwind CSS v3 CDN + 内联 CSS 变量~600 行样式,双主题
表格解析SheetJS (xlsx.js) 0.18.5读取 Excel/CSV
表格导出ExcelJS 4.3.0带样式的 .xlsx 导出
图表Chart.js 4.4.1直方图 + 饼图
截图导出html2canvas 1.4.1DOM → 图片
OCRTesseract.js 4.1.1图片文字识别
PDF 解析PDF.js 3.11.174AI 评语 PDF 提取
Word 解析Mammoth.js 1.9.0AI 评语 docx 提取
生成艺术p5.js 1.9.0图表 Perlin 噪声纹理
庆祝动画canvas-confetti 1.6.0生成成功纸屑
AI 客户端自封装 OpenAI 兼容接口支持 GPT/千问/豆包/智谱/DeepSeek
部署Vercel 静态托管零服务端配置

三、架构设计

3.1 整体分层

┌─────────────────────────────────────────────────────┐ │ CDN 依赖层 │ │ SheetJS ExcelJS Chart.js Tesseract p5.js ... │ ├─────────────────────────────────────────────────────┤ │ index.html │ │ ┌─────────┐ ┌──────────┐ ┌──────┐ ┌─────────┐ │ │ │ 选择页 │ │ 上传区 │ │反馈区 │ │ 设置页 │ │ │ │(寒暑假/ │ │(4列上传) │ │(生成+ │ │(AI配置+ │ │ │ │ 春秋季) │ │ │ │ 导出) │ │ 免交) │ │ │ └─────────┘ └──────────┘ └──────┘ └─────────┘ │ ├─────────────────────────────────────────────────────┤ │ js/app/ 业务模块 │ │ ┌────────────────────────────────────────────────┐ │ │ │ main.js (11,111 行,87%) │ │ │ │ 课次管理 | 上传处理 | 反馈生成 | 导出 | 趋势 │ │ │ │ AI交互 | 免交管理 | 设置持久化 │ │ │ └────────────────────────────────────────────────┘ │ │ lesson-number analytics ai-client virtual-list │ │ exempt-api logger config dom-utils │ │ browser-utils │ ├─────────────────────────────────────────────────────┤ │ server/ 服务端 │ │ exempt-http.mjs (免交名单同步 API) │ └─────────────────────────────────────────────────────┘

3.2 命名空间设计

所有模块挂载在全局window.TA对象下,隔离各模块作用域:

window.TA={Config,// 常量与配置Logger,// 分级日志BrowserUtils,// FileReader/CORS 代理DOMUtils,// DOM 操作小工具VirtualList,// 虚拟滚动渲染器Analytics,// Chart.js 图表管理AIClient,// AI API 客户端ExemptAPI,// 免交名单同步// main.js 中的全局状态与方法...};

3.3 脚本加载顺序(顺序敏感!)

config.js → logger.js → browser-utils.js → dom-utils.js → virtual-list.js → lesson-number.js → analytics.js → ai-client.js → exempt-api.js → main.js

所有模块通过 IIFE 在DOMContentLoaded前完成初始化,main.js 最后加载并通过DOMContentLoaded/load事件绑定 UI 交互。


四、核心模块深度解析

4.1 课次自动识别系统

这是整个工具最精巧的部分之一。来源文件(如第6课课后作业.xlsx)上传后需要自动提取课次,同时支持手动 ±1 微调。

实现要点

  1. 文件名校验:通过正则匹配文件名中的数字模式,支持「第 N 课」「专题N」「L#N」等多种命名
  2. 中文数字映射numberToChinese()函数将阿拉伯数字转为中文(1→一,11→十一)
  3. 多课次重叠:当课后、预习、报告三个来源的课次不一致时,自动检测并在反馈话术中体现差异
  4. 严格输入解析parseStrictLessonInput()支持单值(6)和区间(8-9)两种课次输入模式

关键代码结构lesson-number.js,338 行):

// 阿拉伯数字 → 中文数字functionnumberToChinese(n){constdigits='零一二三四五六七八九';// 个位数直接映射if(n<=9)returndigits[n];// 十位数特殊处理consttens=Math.floor(n/10);constones=n%10;return(tens>1?digits[tens]:'')+'十'+(ones?digits[ones]:'');}

4.2 反馈话术引擎

这是整个应用的心脏,位于 main.js 的generateFeedbackText()函数中。

打分规则概览

维度数据来源评分范围
课前预习预习表格上传0–2 分(含优秀分数线)
课后作业作业表格上传0–10 分
课堂报告课堂统计表格0–6 分(参与分)

话术映射逻辑

functiongenerateFeedbackText(student,scores,template){letlines=[];// 课前预习维度if(scores.preview>=excellentLine){lines.push(template.preview.excellent);}elseif(scores.preview>=1){lines.push(template.preview.good);}else{lines.push(template.preview.needImprove);}// 课后作业维度if(scores.homework>=9)lines.push(template.homework.excellent);elseif(scores.homework>=7)lines.push(template.homework.good);elseif(scores.homework>=5)lines.push(template.homework.average);elselines.push(template.homework.needImprove);// 课堂参与维度...returnlines.join('\n');}

4.3 虚拟滚动列表

当班级人数超过 50 人时,反馈结果列表可能非常长。项目实现了一个自研虚拟滚动virtual-list.js,370 行):

  • 核心算法:只渲染可视区域 ± 预载区的 DOM 节点
  • 行高自适应:支持不定高的反馈卡片
  • 滚动定位:支持按学生序号快速跳转
  • 选中态保持:虚拟滚动过程中保持 checkbox 状态不丢失

4.4 AI 客户端封装

ai-client.js(164 行)封装了一个 OpenAI 兼容的通用客户端:

// 支持 5 种 Provider 一键切换constAI_PROVIDERS={openai:{endpoint:'https://api.openai.com/v1',models:[...]},qwen:{endpoint:'https://dashscope.aliyuncs.com/compatible-mode/v1',...},doubao:{endpoint:'https://ark.cn-beijing.volces.com/api/v3',...},zhipu:{endpoint:'https://open.bigmodel.cn/api/paas/v4',...},deepseek:{endpoint:'https://api.deepseek.com/v1',...},};

AI 在项目中的应用场景

  1. 工作表洞察:自动分析上传表格的表头结构,给出数据建议
  2. 评语辅助:根据学生得分数据,AI 生成初版评语供助教参考
  3. 关键字补全:通过aiRecoverSectionByKeywords()从评语文本中智能恢复缺失段落

4.5 免交名单云端同步

exempt-api.js(140 行)配合server/exempt-http.mjs(118 行)实现免交名单的多设备同步:

  • 本地优先:所有操作先落 localStorage,再异步同步
  • 冲突处理:基于时间戳的 Last-Write-Wins 策略
  • 断网可用:服务端不可达时降级为纯本地模式

4.6 毛玻璃 UI 系统

CSS 变量设计index.html内联<style>,约 600 行):

:root{--bg:#f0f2f8;--text:#1a1a2e;--surface:rgba(255,255,255,0.72);--border:rgba(255,255,255,0.55);--shadow:0 12px 40pxrgba(0,0,0,0.09);--accent:99,102,241;--radius:16px;}.dark{--bg:#0f0f1a;--text:#e0e0e0;--surface:rgba(30,30,50,0.72);--border:rgba(255,255,255,0.08);}

玻璃面板实现

.card{background:var(--surface);backdrop-filter:blur(18px);border:1px solidvar(--border);border-radius:var(--radius);box-shadow:var(--shadow);}

p5.js 图表纹理:在 Chart.js 图表上层叠加低不透明度 Perlin 噪声,营造「纸的质感」,增强数据可视化的质感。


五、技术亮点

5.1 零构建,开箱即用

没有package.json,没有webpack/vite,没有npm install。双击index.html即可运行。所有第三方库通过 CDN 引入,最大程度降低使用门槛。

5.2 巨型单文件的分层组织

main.js虽然达到 11,111 行,但内部通过 IIFE 闭包 + 功能域注释分区实现了清晰的分层:

// ===== 课次管理子系统 ===== // ===== 文件上传与处理 ===== // ===== 反馈生成引擎 ===== // ===== 导出功能 ===== // ===== 趋势分析 ===== // ===== AI 功能 ===== // ===== 设置与持久化 ===== // ===== UI 事件绑定 =====

5.3 多 Provider AI 无缝切换

5 种大模型 Provider 在同一个 UI 中一键切换,自动填充 endpoint 和模型列表。API Key 通过 localStorage 加密存储,支持多 Key 槽位切换。

5.4 深浅色双主题

通过 CSS 变量 +body.dark类切换,所有组件(包括 Chart.js 图表、p5.js 纹理)均支持深色模式自动适配。

5.5 可访问性

  • 全站按钮有aria-label
  • 上传区支持键盘导航
  • 滚动列表支持焦点管理
  • 响应式适配 320px ~ 4K 分辨率

六、部署指南

6.1 本地运行

# 方式一:直接双击打开双击 index.html# 方式二:用任意 HTTP 服务python-mhttp.server8080# 或npx serve.

6.2 Vercel 部署

# 安装 Vercel CLInpmi-gvercel# 在项目根目录执行vercel--prod

项目根目录已配置vercel.json,部署后即可通过 Vercel 域名访问。

6.3 自定义配置

编辑js/app/config.js

constConfig={APP_NAME:'助教反馈生成工具',MAX_FILE_SIZE:50*1024*1024,// 50MBFEEDBACK_PREVIEW_LIMIT:5,// 预览条数VIRTUAL_SCROLL_BUFFER:5,// 虚拟滚动预载行数// ...};

七、总结

这个项目是一个典型的「用最朴素的技术解决最实际的痛点」的案例。没有引入 React/Vue,没有微服务,没有数据库,就是一个 HTML + 一堆 JS + 几个 CDN 库,但它完成了助教工作中最繁琐的表格合并和反馈生成工作。

统计一下

  • 📝~16,000 行代码(前端 JS 12,819 + HTML 2,910 + 服务端 266)
  • 🧩12 个 CDN 外部依赖
  • 🔧67+ 个核心函数
  • 🎯6 大功能模块(课次/上传/反馈/导出/趋势/AI)
  • 🚀零构建部署

如果你也是助教,或者需要做类似的批量数据处理工具,这个项目的架构思路或许能给你一些启发。


附录:项目结构

表格工具网页/ ├── index.html # 入口页面(2,910 行) ├── README.md # 项目说明 ├── vercel.json # Vercel 部署配置 ├── docs/ │ └── CODE_WIKI.md # 代码百科文档 ├── js/ │ ├── selection-handler.js │ └── app/ │ ├── config.js # 全局配置 │ ├── logger.js # 日志系统 │ ├── main.js # 主业务逻辑(11,111 行) │ ├── lesson-number.js # 课次解析 │ ├── analytics.js # 图表统计 │ ├── ai-client.js # AI 客户端 │ ├── exempt-api.js # 免交名单 API │ ├── virtual-list.js # 虚拟滚动 │ ├── browser-utils.js # 浏览器工具 │ └── dom-utils.js # DOM 工具 └── server/ ├── exempt-http.mjs # 免交同步服务 └── exempt-http-deploy.mjs # 部署版服务

如果你对这个项目感兴趣或有改进建议,欢迎在评论区交流讨论。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 18:41:33

Thonny连不上ESP32S3板子

一、先判断问题在哪一层第 1 步&#xff1a;确认电脑是否识别 ESP32-S3Windows打开 设备管理器 → 端口 COM 和 LPT。插拔板子&#xff0c;看有没有新增类似&#xff1a;USB Serial Device (COMx)Silicon Labs CP210x USB to UART BridgeUSB-SERIAL CH340USB JTAG/serial debug…

作者头像 李华
网站建设 2026/6/10 18:27:54

面向产业带与中小企业数字化转型的电商运营人才培养模式

文章目录面向产业带与中小企业数字化转型的电商运营人才培养模式一、模式定位二、培养目标三、总体思路四、课程体系五、教学实施路径六、校企合作机制七、竞赛融合方向八、评价方式九、模式特色面向产业带与中小企业数字化转型的电商运营人才培养模式 一、模式定位 以服务地…

作者头像 李华
网站建设 2026/6/10 18:27:43

如何分辨正宗新疆特产:无糖养生特产挑选技巧与避坑指南

选购痛点剖析在购买新疆特产时&#xff0c;许多消费者常常遇到各种困扰。市面上的新疆特产琳琅满目&#xff0c;但其中不乏过度加工、掺假以次充好、添加剂超标的产品。这些产品不仅影响了消费者的体验&#xff0c;还可能对健康造成潜在威胁。例如&#xff0c;一些干果经过过多…

作者头像 李华
网站建设 2026/6/10 18:22:02

3DS宝可梦ROM编辑器与随机化工具:打造独一无二的宝可梦冒险体验

3DS宝可梦ROM编辑器与随机化工具&#xff1a;打造独一无二的宝可梦冒险体验 【免费下载链接】pk3DS Pokmon (3DS) ROM Editor & Randomizer 项目地址: https://gitcode.com/gh_mirrors/pk/pk3DS 想要彻底改变《精灵宝可梦X/Y》《太阳/月亮》等经典3DS游戏的玩法吗&a…

作者头像 李华
网站建设 2026/6/10 18:18:29

目前靠谱的吨袋生产商哪个好

在工业生产和物流运输中&#xff0c;吨袋作为大宗散装货物包装的重要工具&#xff0c;其质量和适用性直接影响着货物的安全和运输效率。那么&#xff0c;目前靠谱的吨袋生产商哪个好呢&#xff1f;今天我们就来一探究竟&#xff0c;重点介绍苏州淞镕包装有限公司&#xff0c;并…

作者头像 李华
网站建设 2026/6/10 18:16:15

Redis哨兵模式下主从同步的偏差

文章目录Redis哨兵模式下主从同步的偏差一、核心概念&#xff1a;什么是主从同步偏差&#xff1f;二、偏差产生的根本原因常见触发场景三、哨兵模式下&#xff0c;偏差的关键作用&#xff08;核心&#xff01;&#xff09;1. 哨兵筛选候选从节点2. 哨兵核心配置&#xff08;控制…

作者头像 李华