# fullstack-app **Repository Path**: wangxinyanqc/fullstack-app ## Basic Information - **Project Name**: fullstack-app - **Description**: 小学生成绩管理系统 - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-22 - **Last Updated**: 2026-06-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 小学成绩单管理系统 面向小学 **1–6 年级** 的全栈成绩单管理项目,支持多班级、多科目成绩录入、查询、排名与 Excel 批量导入。 Monorepo 结构:**Vue 3 前端** + **Java Spring Boot 后端** + **MySQL 数据库**。 ## 功能概览 | 模块 | 功能 | |------|------| | 用户登录 | 管理员 / 教师角色,JWT 鉴权 | | 成绩查询 | 按年级、班级、科目、学期、考试筛选;展示录入时间;按最近保存时间倒序 | | 成绩录入 | 弹窗录入:年级、班级、学生、科目、分数、学期、考试(同学期同考试可更新) | | 学生管理 | 学生列表查询;弹窗新增学生(学号、姓名、年级、班级) | | 科目排名 | 按科目查看排名,支持年级 / 班级筛选,前三名高亮 | | Excel 导入 | 拖拽上传 `.xlsx` / `.xls`,批量导入学生与成绩 | **内置科目:** 语文、数学、英语、科学、道德与法治 ## 技术栈 | 层级 | 技术 | |------|------| | 前端 | Vue 3、Vite、TypeScript、Element Plus、Pinia、Vue Router、Axios | | 后端 | Java 17、Spring Boot 3、Spring Security、JWT、Spring Data JPA | | 数据库 | MySQL 8(Docker Desktop) | | 工具 | pnpm(Monorepo)、Maven、TablePlus、Apifox | ## 项目结构 ``` fullstack-app/ ├── frontend/ # Vue 3 前端 │ └── src/ │ ├── views/ # 页面:登录、成绩、学生、排名、导入 │ ├── api/ # Axios 封装(统一响应解包) │ └── stores/ # Pinia 状态(登录态) ├── backend/ # Java 后端 │ ├── src/main/java/com/gradereport/ │ │ ├── controller/ # REST API │ │ ├── service/ # 业务逻辑 │ │ ├── entity/ # JPA 实体 │ │ ├── repository/ # 数据访问 │ │ ├── security/ # JWT 认证 │ │ └── common/ # 统一响应 ApiResponse │ ├── src/main/resources/ │ │ └── application.yml # 后端配置 │ ├── sql/init.sql # 建表脚本(空库参考) │ └── dev.sh # 本地启动脚本 ├── docker-compose.yml # MySQL 容器 ├── pnpm-workspace.yaml └── package.json ``` ## 环境要求 - Node.js 20+、pnpm - JDK 17+、Maven 3.9+ - Docker Desktop ### 安装 JDK / Maven(macOS 示例) ```bash brew install openjdk@17 maven # 加入 ~/.zshrc export JAVA_HOME="/opt/homebrew/opt/openjdk@17" export PATH="$JAVA_HOME/bin:$PATH" java -version mvn -version ``` ## 快速开始 ### 1. 安装依赖 ```bash pnpm install ``` 若提示 build scripts 被忽略: ```bash pnpm approve-builds --all && pnpm install ``` ### 2. 启动 MySQL ```bash pnpm db:up ``` > 本机 3306 端口若已被占用,Docker MySQL 映射到 **3307**。 **TablePlus 连接:** | 字段 | 值 | |------|-----| | Host | 127.0.0.1 | | Port | **3307** | | User | root | | Password | root123456 | | Database | grade_report | 空库时可执行 `backend/sql/init.sql` 建表。已有库直接启动后端即可。 ### 3. 启动开发服务 ```bash pnpm dev ``` - 前端:http://127.0.0.1:5173 - 后端 API:http://127.0.0.1:3000 `backend/dev.sh` 会在启动前自动释放被占用的 3000 端口。 也可分开启动: ```bash pnpm dev:backend # Java 后端 pnpm dev:frontend # Vue 前端 ``` ### 4. 测试账号 | 角色 | 用户名 | 密码 | |------|--------|------| | 管理员 | admin | admin123 | | 教师 | teacher | teacher123 | 首次启动且数据库无用户时,后端会自动填充测试数据(用户、科目、学生、成绩)。 ## 前端页面 | 路由 | 页面 | 说明 | |------|------|------| | `/login` | 登录 | 获取 JWT Token | | `/scores` | 成绩查询 | 筛选列表 + 弹窗录入成绩 | | `/students` | 学生管理 | 查询 + 弹窗新增学生 | | `/rankings` | 科目排名 | 按科目、年级、班级排名 | | `/import` | Excel 导入 | 批量导入成绩 | ## API 接口 所有接口(除健康检查、登录外)需在请求头携带: ``` Authorization: Bearer ``` ### 统一响应格式 ```json { "code": 200, "data": {}, "msg": "成功" } ``` 失败示例: ```json { "code": 401, "data": null, "msg": "用户名或密码错误" } ``` 前端 `api/index.ts` 已自动解包 `data` 字段,页面中 `response.data` 即为业务数据。 ### 接口列表 | 方法 | 路径 | 说明 | 需登录 | |------|------|------|--------| | GET | /api/health | 健康检查 | 否 | | POST | /api/auth/login | 用户登录 | 否 | | GET | /api/students | 学生列表(支持 grade、className 筛选) | 是 | | POST | /api/students | 新增学生 | 是 | | GET | /api/subjects | 科目列表 | 是 | | GET | /api/scores | 成绩列表(支持多条件筛选,按 updatedAt 倒序) | 是 | | POST | /api/scores | 录入 / 更新成绩 | 是 | | GET | /api/rankings | 科目排名(需 subjectId) | 是 | | POST | /api/import/excel | Excel 导入(multipart,字段名 file) | 是 | ## 后端配置 `backend/src/main/resources/application.yml` ```yaml server: port: 3000 spring: datasource: url: jdbc:mysql://localhost:3307/grade_report?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: root123456 app: jwt: secret: dev-jwt-secret-change-in-production expiration-days: 7 ``` ## Excel 导入格式 第一行表头(列名需完全一致): | 学号 | 姓名 | 年级 | 班级 | 科目 | 分数 | 学期 | 考试名称 | |------|------|------|------|------|------|------|----------| 示例: | 学号 | 姓名 | 年级 | 班级 | 科目 | 分数 | 学期 | 考试名称 | |------|------|------|------|------|------|------|----------| | G10101 | 王小明 | 1 | 1班 | 语文 | 92 | 2024-2025上学期 | 期中考试 | 说明: - 科目名称需与系统一致(语文、数学、英语、科学、道德与法治) - 年级范围 1–6 - 学期、考试名称可留空,默认「2024-2025上学期」「期中考试」 - 学号已存在则更新学生信息;同学期同考试成绩则更新分数 ## 常用命令 ```bash pnpm dev # 同时启动后端 + 前端 pnpm dev:backend # 仅后端(bash backend/dev.sh) pnpm dev:frontend # 仅前端 pnpm db:up # 启动 MySQL 容器 pnpm db:down # 停止 MySQL 容器 cd backend && mvn spring-boot:run # 手动启动后端 cd backend && mvn package # 打包 jar cd frontend && pnpm build # 构建前端 ``` ## 开发说明 ### 前后端热更新差异 | | 前端(Vite) | 后端(Spring Boot) | |--|-------------|---------------------| | 改代码后 | 自动热更新,一般无需重启 | 需重新编译并重启 JVM | | 原因 | 开发服务器监听文件变化 | Java 编译后加载到内存,默认不自动重载 | 修改后端 Java 代码后,请重启 `pnpm dev` 或 `pnpm dev:backend`,看到 `Tomcat started on port 3000` 即表示生效。 ### 常见问题 **接口 502 Bad Gateway** 前端代理连不上后端。确认后端已启动: ```bash curl http://127.0.0.1:3000/api/health ``` **端口 3000 被占用** `dev.sh` 会自动尝试释放;也可手动处理: ```bash lsof -i :3000 kill ``` ## 数据表 | 表名 | 说明 | |------|------| | User | 登录用户(管理员 / 教师) | | Student | 学生(1–6 年级、班级) | | Subject | 科目 | | Score | 成绩记录(含 createdAt、updatedAt) | ## License 见 [LICENSE](LICENSE) 文件。