一个用于课程小组展示顺序管理的轻量系统,支持一次性锁定抽签结果、学生按学号+姓名查询、签到持久化、看板追踪与导出课表。
SNO + Name 后触发揭晓动画,显示已预分配的展示序号与日期。checkedIn、checkedInBy、checkInTime。data/courses/ (多个独立 JSON 文件). ├── data/ │ ├── courses/ │ │ ├── Course1.json │ │ ├── Course2.json │ │ └── ... │ └── state.json (已弃用) ├── public/ │ └── css/ │ └── app.css ├── src/ │ ├── app.js │ ├── routes.js │ ├── controllers/ │ │ ├── adminController.js │ │ ├── dashboardController.js │ │ └── drawController.js │ ├── models/ │ │ └── stateStore.js │ └── utils/ │ └── csv.js ├── views/ │ ├── admin.ejs │ ├── dashboard.ejs │ └── draw.ejs └── README.md
npm install
npm start
开发模式(Node watch):
npm run dev
默认端口:3000
GET /admin:管理端(上传课程、组表、日期表)POST /admin/upload:执行一次性锁定分配并为该课程创建独立 JSON 文件GET /draw/:course:学生抽签页POST /draw/:course/checkin:学生查询并登记签到GET /dashboard:实时看板GET /dashboard/export:导出 XLSXGroups CSV 与 Dates CSV。order,并根据 Dates CSV 映射 presentationDate。data/courses/课程名.json。courses/ 目录并聚合所有课程的进度。推荐格式(多列成员架构):
组长,小组成员1,小组成员2,小组成员3,小组成员4 杨瑞,邹尚林,周庆宁,王睿, 陈培松,徐誉,黄岩圃,谢文博, ,李四,张三,,
解析规则:
学号-姓名(推荐,如 20260001-王睿)学号:姓名 或 学号 姓名王睿,无学号)推荐格式:
order,date 1,30th March 2,6th April
也支持仅日期单列(系统会按行号自动补 order=1..n)。
系统使用课程独立文件方案:每个课程存储为独立 JSON 文件,位于 data/courses/ 目录。
data/ ├── courses/ │ ├── Investment Simulation 2026.json │ ├── Course 2.json │ └── AnotherCourse.json └── state.json (已弃用)
每个课程 JSON 结构示例:
{
"createdAt": "2026-03-23 18:03:27",
"groups": [
{
"id": "G001",
"members": ["杨瑞", "邹尚林"],
"memberDetails": [
{ "sno": "", "name": "杨瑞" },
{ "sno": "", "name": "邹尚林" }
],
"order": 1,
"presentationDate": "30th March",
"checkedIn": true,
"checkedInBy": "杨瑞",
"checkInTime": "2026-03-23 18:03:27"
}
]
}
优势:
SNO + NamememberDetails 中匹配同名成员;请确认访问地址中的课程名完全一致(包括空格与大小写),且该课程已在 Admin 页面上传。查看 data/courses/ 目录确认文件是否存在。
Groups CSV 成员格式是否规范(建议 学号-姓名)。锁定分配是一次性写入。若要重排,请重新上传 CSV 覆盖状态。
npm start:启动服务npm run dev:watch 模式npm test:占位脚本(当前无自动化测试)