# exam-system **Repository Path**: liminghui321/exam-system ## Basic Information - **Project Name**: exam-system - **Description**: 考试系统,支持上传文档解析,大模型智能出题,考试。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-21 - **Last Updated**: 2026-04-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 智能考试系统(exam-system) 基于 **知识文档** 与 **大模型** 辅助生成题目,支持组卷、试卷入库、**用户登录与角色权限**、以及**在线答题与计时**的前后端分离应用。 --- ## 架构概览 ``` ┌─────────────┐ HTTPS/JSON REST ┌──────────────────────┐ │ Vue 3 SPA │ ◄──────────────────────► │ Spring Boot (JDK8) │ │ Pinia/API │ Bearer JWT(除登录) │ MyBatis + MySQL 8 │ └─────────────┘ └──────────────────────┘ ``` - **前端**:Vue 3、Vue Router、Pinia、Axios;开发时通过 Vite 代理 `/api` 到后端。 - **后端**:Spring Boot、MyBatis(XML Mapper)、Spring Security + JWT。 - **数据库**:MySQL 8;**全量 DDL 仅** `backend/src/main/resources/db/init.sql`(约定见 `AGENTS.md`)。 ### 功能模块(逻辑划分) | 模块 | 说明 | |------|------| | 文档 | 上传与解析正文,作为出题素材 | | 生成任务 | 异步调用 LLM 生成题目写入题库 | | 题库 | 题目的查询、编辑、导出 | | 组卷 | 选题与分值分配,草稿/发布入库 `exam_paper` | | 认证 | `POST …/auth/login`、`POST …/auth/register`(自助注册为学生)、`GET …/auth/me`,JWT | | 在线考试 | `exam_session`:开考计时、答卷、超时与判分 | | 成绩管理(管理员) | `GET /exam-results` 分页查询考试成绩;详情同答卷视图 | | 用户管理(管理员) | `CRUD /users`:账号与角色 **ADMIN / STUDENT** | ### 角色与 RBAC(两种) 系统仅 **`ADMIN`(管理员)** 与 **`STUDENT`(考生)**;JWT 内为短名,Spring Security 中为 `ROLE_ADMIN` / `ROLE_STUDENT`。 | 角色 | 权限概要 | |------|-----------| | **ADMIN** | 文档、生成任务、题库与导出、组卷与试卷发布、`GET /dashboard/stats` 统计等全部管理接口(`@PreAuthorize("hasRole('ADMIN')")`)。 | | **STUDENT** | 浏览已发布试卷、开考与交卷;自助注册默认此角色;不能访问上述管理接口。管理员也可调用考试接口用于试测。 | 种子账号(仅空库首次启动):`admin` / `admin123`(管理员),`student` / `student`(考生)。 前端:管理员顶部展示文档/任务/题库/组卷入口;考生仅「在线考试」与个人信息,主页内容与管理员不同。 ### 核心业务数据表(节选) 在 `init.sql` 中与考试相关的主要表:`sys_user`、`exam_paper`、`exam_paper_item`、`exam_session`、`exam_answer`,以及原有的 `document`、`generation_task`、`question`。 --- ## API 摘要 统一响应体一般为 `ApiResponse`(`code`/`message`/`data`);以下路径均带前缀 **`/api`**。 ### 认证 - `POST /v1/auth/login` — 登录,返回 JWT。 - `POST /v1/auth/register` — 自助注册(新用户角色固定为 **STUDENT**;用户名 3~64、密码 6~64;保留名 `admin`、`teacher`、`root`、`system` 不可用),成功体与登录相同(含 token,可直接作为已登录)。 - `GET /v1/auth/me` — 当前用户信息(需 `Authorization: Bearer `)。 ### 仪表盘与导出 - `GET /v1/dashboard/stats` — 文档数、题库题数、任务状态统计等(**仅管理员**,`403` 对考生)。 - `GET /v1/exports/questions?format=json|csv` — 按与题库列表相同的筛选条件导出(最多 5000 条),响应为**文件下载**,非 `ApiResponse` 包装。 ### 试卷与考试(需登录) - `POST /v1/exam-papers` — 创建试卷草稿(小题分值之和须等于总分)。 - `GET /v1/exam-papers` — 分页列表;**学生端仅能看到已发布试卷**。 - `GET /v1/exam-papers/{id}` — 详情;学生看不到未发布试卷及题目的答案解析。 - `POST /v1/exam-papers/{id}/publish` — 发布草稿。 - `DELETE /v1/exam-papers/{id}` — **仅管理员**,删除整套试卷(含组卷项、考试会话与作答);题库题目不删除。 - `POST /v1/exam-sessions/start` — 开考(请求体 `{ "paperId": n }`),生成截止时间。 - `GET /v1/exam-sessions/{id}` — 会话与题目视图;进行中不下发正确答案。 - `POST /v1/exam-sessions/{id}/submit` — 交卷并判分。 - **`GET /v1/exam-results`**(**仅管理员**)— 考试成绩列表,支持查询参数:`page`、`size`、`paperId`、`username`(用户名或显示名模糊)、`status`(`IN_PROGRESS` / `SUBMITTED` / `TIMEOUT`)。 - **`GET /v1/exam-results/{sessionId}`**(**仅管理员**)— 指定会话的完整答卷视图(与会话接口结构一致;进行中则无答案)。 ### 用户管理(仅管理员) - `GET /v1/users` — 分页列表;可选查询:`keyword`(用户名/显示名)、`role`、`status`(0/1)。 - `GET /v1/users/{id}` — 详情。 - `POST /v1/users` — 新建用户(用户名、密码、显示名、角色、状态)。 - `PUT /v1/users/{id}` — 修改显示名、角色、状态;**密码可选**(留空不改)。 - `DELETE /v1/users/{id}` — 删除用户(不可删自己、不可删仅剩的管理员;**存在考试记录时不可删**,需先禁用或清理业务数据)。 ### 生成任务重试 - **仅 `FAILED` 状态**可调用 `POST /api/v1/generation-tasks/{id}/retry`。 - 重试前会软删除该任务关联的已入库题目记录,再将任务重置为待执行并异步生成,避免与数据库状态不一致。 --- ## 大模型(本地调试) 自动生成题目依赖 **API Key**。配置项见 `backend/src/main/resources/application.properties`,常用: | 含义 | 配置键 / 环境变量 | |------|-------------------| | LLM Key | `exam.llm.api-key` 或 **`EXAM_LLM_API_KEY`** | | 兼容 OpenAI 的 Base URL | `exam.llm.base-url` | | 模型名 | `exam.llm.model` | 使用 **阿里云百炼 DashScope(兼容 OpenAI)** 时示例: | 配置项 | 说明 | |--------|------| | 密钥 | 控制台 API-KEY → `exam.llm.api-key` 或 `EXAM_LLM_API_KEY` | | base-url(国内常见) | `https://dashscope.aliyuncs.com/compatible-mode/v1`(**不要**再手动拼 `/chat/completions`,后端会拼接) | | base-url(国际等) | 若 Key 在新加坡等区域,可能需 `https://dashscope-intl.aliyuncs.com/compatible-mode/v1`,须与 Key 区域一致 | | model | 如 `qwen-plus`、`qwen-turbo` 等 | 官方参考:[如何通过 OpenAI 接口调用通义千问](https://help.aliyun.com/zh/model-studio/compatibility-of-openai-with-dashscope)。 --- ## 本地运行 ### 数据库 在 MySQL 中执行一次: ```bash mysql -u root -p < backend/src/main/resources/db/init.sql ``` (路径按本机调整;表结构以仓库内 `init.sql` 为准,新项目建议空库执行该脚本。) ### 后端 ```bash cd backend mvn spring-boot:run ``` 默认端口 **8080**。JWT 可在 `application.properties` 中配置 `exam.jwt.secret`、`exam.jwt.expiration-ms`,生产环境务必通过 **`EXAM_JWT_SECRET`** 覆盖。 ### 前端 ```bash cd frontend npm install npm run dev ``` Vite 默认代理 ` /api ` 到 `http://127.0.0.1:8080`,浏览器访问前端开发端口即可。 --- ## 文档分工 - **`AGENTS.md`**:仅保留**硬性约束**(技术栈、MyBatis、**DDL 仅 `init.sql`**、密钥、业务边界等),便于 Agent 与协作时快速对齐「不能改什么」。 - **`README.md`**(本文件):架构、模块、接口与运行说明。