# GESP考试系统 **Repository Path**: cdsy8811/gesp-exam-system ## Basic Information - **Project Name**: GESP考试系统 - **Description**: GESP考试系统 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-11 - **Last Updated**: 2025-12-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # GESP 在线考试平台 该项目为了帮助家里小朋友参加编程等级考试,基于 FastAPI + Vue 3 搭建了一个在线考试系统。 GESP(编程能力等级认证)考试系统是一个面向青少年编程等级认证的在线考试平台。系统覆盖账号注册登录、题目与考试管理、在线作答、成绩统计、错题管理,以及面向移动端的自适应体验。后续引入的 DeepSeek AI 能进行编程题辅助评测与解答(依赖可选)。 ## 在线试用地址 [https://gesp.cmx666.cn](https://gesp.cmx666.cn) pc端 目前PC端未完全测试,请注意使用。 [https://gesp.cmx666.cn/m](https://gesp.cmx666.cn/m) 手机端 目前只有C++的 编程题,后续会添加其他语言的编程题。 ## 核心特性 - **多端体验**:同一代码库支持桌面端与 `/m` 移动端视图,自动根据 UA/query 切换。 - **用户与权限**:注册/登录、Token 校验、管理员权限控制、基于 SQLite 的持久化。 - **题库/考试管理**:题型涵盖单选、多选、判断、编程;可批量导入、设置考试时间窗口、时长、总分。 - **在线考试**:考试倒计时、途中自动保存、交卷后即时评分与成绩列表。 - **错题本与随机练习**:支持通过错题筛选与随机组卷。 - **AI 扩展**:如配置 `DEEPSEEK_API_KEY` 且安装 `httpx`,可调用 DeepSeek API 辅助批改/解题;未安装 `httpx` 时会自动降级。 ## 技术栈 | 层 | 技术 | | --- | --- | | 后端 | FastAPI · SQLAlchemy · Pydantic · SQLite · python-jose(Token) · Uvicorn | | 前端 | Vue 3 · Vite · Element Plus · Pinia · Vue Router · Axios | | 其他 | pdfplumber(题目导入)、httpx(可选,DeepSeek 客户端) | ## 项目结构 ``` E:\AO\GESP ├─backend │ ├─app │ │ ├─api/ # FastAPI 路由(auth、questions、exams、exam_results 等) │ │ ├─crud/ # 业务操作封装 │ │ ├─models/ # SQLAlchemy 模型 │ │ ├─schemas/ # Pydantic Schema │ │ ├─utils/ # DeepSeek、PDF 导入等工具 │ │ ├─database.py # SQLite 引擎配置(默认 backend/db/exam.db) │ │ └─main.py # FastAPI 入口 │ ├─db/exam.db # 默认 SQLite 库(可替换) │ ├─requirements.txt # 后端依赖 │ └─run.py # 本地启动脚本 └─frontend ├─src │ ├─views/ # PC 页面与移动端视图 │ ├─router/ # 路由守卫(Token 验证、移动端跳转) + │ ├─stores/ # Pinia(用户、考试状态) │ ├─components/ # 通用组件 │ ├─mobile/ # 移动端 UI │ └─main.js # Axios 拦截器、移动端判定 └─package.json ``` ## 快速开始 ### 1. 后端 ```bash cd backend python -m venv .venv .venv\Scripts\activate # Linux/macOS: source .venv/bin/activate pip install -r requirements.txt # 初始化环境变量 copy .env.example .env # Linux/macOS: cp .env.example .env # 根据需要填写 SECRET_KEY、DEEPSEEK_API_KEY 等 python run.py # http://localhost:8000 ``` 常用命令: | 命令 | 说明 | | --- | --- | | `uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload` | 开发模式 | | `uvicorn app.main:app --host 0.0.0.0 --port 8011 --workers 4` | 生产启动示例 | | `python test_api.py` | 简单 API 冒烟(修改其中 host/port) | > 注意:SQLite 旧表存在 `email` NOT NULL 约束,注册接口会自动生成占位邮箱(`@gesp.local`),无需前端额外输入。 ### 2. 前端 ```bash cd frontend npm install npm run dev # http://localhost:5173 # 构建生产包 npm run build npm run preview ``` 默认 Axios `baseURL` 为空,会直接请求同域 `/api`; 如后端分离部署,可在 `.env` 中设置 `VITE_API_BASE_URL=https://api.example.com`. ## API 与数据 - Swagger UI: `http://<后端>/docs` - Redoc: `http://<后端>/redoc` - 主要表:`users`(含 `email/phone/token/token_expires_at`)、`questions`、`exams`、`exam_questions`、`exam_results`。 - `backend/gesp_exam.db` 为示例快照,运行时实际连接 `backend/db/exam.db`。生产部署请迁移至独立数据库。 ## 测试与质量 - 后端:可在 `backend/tests/` 编写 pytest/FastAPI 测试;`test_api.py` 作为冒烟脚本。 - 前端:建议使用 Vitest/Playwright 做组件或端到端测试,目前通过手动流程验证(登录→考试→交卷→错题)。 - 运行 `npm run build` 和 `uvicorn` 启动前请先格式化/静态检查,确保路由守卫、Axios 拦截器按预期运行。 ## 部署建议 1. **虚拟环境/非 root 用户**:避免直接使用系统 Python。若必须以 root 安装,可使用 `pip install --root-user-action=ignore ...`,但更推荐 venv 或容器。 2. **环境变量**:不要提交 `.env`;部署时配置 SECRET_KEY、JWT、数据库 DSN、DEEPSEEK_API_KEY(如需 AI)。 3. **前后端联调**:生产前端通常放在 Nginx/Apache,配置反向代理 `/api` 指向 FastAPI,或在 Vite `.env.production` 中设置 API 基础地址。 4. **日志**:后端日志默认写入 `backend/logs/app.log`,可根据需要配置 rotation。 ## 常见问题 | 问题 | 处理方式 | | --- | --- | | `ModuleNotFoundError: No module named 'httpx'` | DeepSeek 可选依赖,安装 `pip install httpx` 或忽略(功能自动降级)。 | | 登录后立刻被登出 | 前端已保存 `tokenExpiresAt` 及毫秒值,确保浏览器未篡改系统时间;若仍出现,可查看控制台 `[auth-guard]` 日志。 | | 注册接口 500 (`NOT NULL constraint failed: users.email`) | 已在后端自动补全邮箱;若旧版本仍报错,请拉取最新代码并重启。 | | SQLite 报错 `NULLS LAST` | 已在 `exams` 查询中用 `CASE` 替代;若自定义查询使用 `.nullslast()`,请对 SQLite 改成条件排序。 | | 部署时 `pip` 提示 root 用户警告 | 参考“部署建议”第 1 条。 | ## 贡献指南 - Python 代码遵循 PEP8,尽量使用类型标注。 - 前端统一 2 空格缩进,组件优先 `