UCAS 课程查询与签到二维码生成工具。
在线访问:UCAS Course Sign in (Vercel)
Caution
本项目仅供学习交流使用,请勿用于任何商业用途或非法用途。
本项目用于复现 XXXX 的课程查询与签到链路,帮助用户在网页端完成以下流程:
- 输入学号、密码和日期,查询当天课程
- 选择课程,生成可实时刷新的签到二维码
- 在可签到时间内直接发起签到
- 手动输入课程 ID 或 UUID,生成对应签到码
- 克隆仓库并安装依赖
git clone https://github.com/lccipher/UCAS-Course-Sign-in
cd UCAS-Course-Sign-in
npm install- 启动开发环境
npm run dev默认访问地址:http://localhost:3000
- 生产构建与启动
npm run build
npm run start- 代码检查
npm run lint推荐使用 Vercel 进行部署,步骤如下:
- Fork 本仓库到你的 GitHub 账号
- 在 Vercel 导入项目
- Framework 自动识别为 Next.js
- Build Command 使用默认的
npm run build - 部署完成后访问生成的域名
Browser
-> POST /api/course-uuid/query
-> login.action (上游登录)
-> get_stu_course_sched.action (上游课表)
<- 返回课程列表(已脱敏整理)
Browser
-> 选择课程 / 手动输入课程 ID 或 UUID
-> 本地生成签到 URL + QR Code
-> POST /api/course-uuid/sign(可选,直接签到)
说明:
- 上游
sessionId只在服务端请求链路中短暂使用,不回传前端。 - 前端二维码和下载二维码都由本地生成,不依赖额外前端存储。
- 直接签到时,服务端会先登录,再调用上游签到接口。
.
├─ src/
│ └─ app/
│ ├─ api/
│ │ └─ course-uuid/
│ │ ├─ query/
│ │ │ └─ route.ts # 登录 + 课表查询接口
│ │ └─ sign/
│ │ └─ route.ts # 登录 + 直接签到接口
│ ├─ globals.css # 全局样式与主题变量
│ ├─ layout.tsx # 字体、元信息、主题初始化
│ └─ page.tsx # 主页面(查询、列表、二维码、签到)
├─ public/
├─ doc/
├─ package.json
└─ README.md
查询课程列表。
请求头:
Content-Type: application/json
请求体:
{
"username": "2025xxxxxxxxxx",
"password": "your-password",
"date": "20260325"
}字段说明:
username:学号,必填password:密码,必填date:查询日期,支持yyyyMMdd或yyyy-MM-dd
成功响应示例:
{
"date": "20260325",
"total": 2,
"courses": [
{
"id": "114xxxx",
"uuid": "CADD27F17ACC44EDAFxxxxxxxxxxxxxx",
"courseName": "xxxxxxx",
"teacherName": "xxx",
"weekDay": "周三",
"classBeginTime": "2026-03-25 10:25:00",
"classEndTime": "2026-03-25 12:00:00",
"signStatus": "1"
}
]
}常见错误响应:
{
"message": "登录接口请求超时",
"code": "UPSTREAM_LOGIN_TIMEOUT"
}发起直接签到。
请求头:
Content-Type: application/json
请求体:
{
"username": "2025xxxxxxxxxx",
"password": "your-password",
"timeTableId": "CADD27F17ACC44EDAFxxxxxxxxxxxxxx"
}字段说明:
username:学号,必填password:密码,必填timeTableId:课程 UUID,必填,必须是 32 位十六进制字符串
成功响应示例:
{
"success": true,
"message": "签到成功",
"upstreamStatus": "0",
"result": {
"stuSignId": "123456",
"stuSignStatus": "1"
}
}可能的失败响应:
{
"success": false,
"message": "签到失败,请稍后重试",
"upstreamStatus": "1",
"result": {
"stuSignId": "123456",
"stuSignStatus": "0"
}
}400:请求体或参数格式错误401:登录失败(账号密码错误或上游鉴权失败)403:非同源请求409:签到请求已提交,但状态未完成415:Content-Type 不是 JSON429:触发限流502:上游接口异常或返回异常504:上游接口超时500:服务内部异常
RATE_LIMITEDUPSTREAM_LOGIN_HTTPUPSTREAM_LOGIN_BAD_JSONUPSTREAM_LOGIN_TIMEOUTUPSTREAM_LOGIN_NETWORKUPSTREAM_SCHEDULE_HTTPUPSTREAM_SCHEDULE_BAD_JSONUPSTREAM_SCHEDULE_TIMEOUTUPSTREAM_SCHEDULE_NETWORKUPSTREAM_SIGN_HTTPUPSTREAM_SIGN_BAD_JSONUPSTREAM_SIGN_TIMEOUTUPSTREAM_SIGN_NETWORKUNEXPECTED_ERROR
- Next.js 16.2.1(App Router)
- React 19.2.4
- TypeScript 5
- Tailwind CSS 4
- next/font(Noto Sans SC / Noto Serif SC / IBM Plex Mono)
- Next.js Route Handler(Node.js runtime)
- 原生 Fetch + AbortController 超时控制
- 内存级限流(5 分钟窗口 + 每日上限)
- ESLint 9 + eslint-config-next
- qrcode 1.5.4(前端二维码生成)


