
课程作业管理系统是高校教学管理信息化的重要一环但很多同学在毕业设计阶段面对前后端分离、数据库设计、权限控制等综合技术栈时常感到无从下手。本文将以一个完整的“课程作业管理系统”为例手把手带你从零开始使用 Java Vue Spring Boot MySQL 这套主流技术栈构建一个功能完备、代码规范、可直接用于毕业答辩的实战项目。文中将提供完整的源码、数据库脚本、配套文档以及部署教程确保你不仅能跑通项目更能理解其背后的设计思路与实现细节。1. 系统概述与技术选型1.1 什么是课程作业管理系统课程作业管理系统是一个面向教师和学生的在线平台旨在数字化、流程化地管理课程作业的发布、提交、批改与反馈全过程。它解决了传统纸质或邮件提交作业带来的效率低下、版本混乱、统计困难等问题是智慧校园建设中常见的应用系统。一个典型的系统通常包含以下核心功能模块用户管理区分学生、教师、管理员角色实现基于角色的权限控制。课程管理教师可以创建课程学生可以选课或加入课程。作业管理教师发布作业含标题、内容、附件、截止日期等学生在线提交作业支持文件上传。批改与成绩管理教师对学生提交的作业进行批改、评分、写评语学生可查看成绩和反馈。公告与消息系统内通知如作业发布提醒、截止提醒等。1.2 为什么选择 Java Vue Spring Boot MySQL这套技术组合是当前企业级Web应用开发的“黄金搭档”选择它们作为毕业设计技术栈优势明显Java/Spring Boot作为成熟、稳定的后端语言和框架Spring Boot极大地简化了Spring应用的初始搭建和开发过程自动配置、内嵌服务器等特性让开发者能快速构建稳健的RESTful API。其丰富的生态如Spring Security, MyBatis-Plus能完美支撑业务需求。Vue.js作为渐进式前端框架Vue易于上手文档丰富其响应式数据绑定和组件化开发模式能高效构建交互友好、用户体验良好的单页面应用SPA非常适合管理系统类前端。MySQL世界上最流行的开源关系型数据库之一性能稳定、社区活跃、学习资料丰富完全满足毕业设计项目的数据存储需求。综合优势技术栈主流社区资源丰富遇到问题容易找到解决方案项目结构清晰易于扩展和维护写在简历上是加分项能很好体现全栈开发能力。2. 开发环境与工具准备在开始编码之前请确保你的开发环境已就绪。以下是本文示例所使用的环境你可以根据实际情况调整版本。2.1 后端环境 (Java/Spring Boot)操作系统Windows 10/11, macOS, Linux (本文命令以Windows为例)JDKJava Development Kit 8 或 11 (推荐 JDK 11 LTS版本更稳定)安装后在命令行输入java -version和javac -version验证。构建工具Apache Maven 3.6安装后在命令行输入mvn -v验证。IDEIntelliJ IDEA (社区版或旗舰版) 或 Eclipse (STS)。强烈推荐使用 IntelliJ IDEA其对Spring Boot支持更好。数据库客户端Navicat, DBeaver 或 MySQL Workbench用于连接和管理MySQL数据库。2.2 前端环境 (Vue.js)Node.js版本 14.x 或 16.x (包含npm包管理器)安装后在命令行输入node -v和npm -v验证。包管理工具npm 或 yarn (本文使用npm)。Vue CLIVue的官方脚手架工具用于快速创建项目。安装命令npm install -g vue/cli安装后输入vue --version验证。2.3 数据库环境MySQL版本 5.7 或 8.0 (本文使用 MySQL 8.0)安装过程中请记住设置的root用户密码。确保MySQL服务已启动。3. 数据库设计与建模数据库设计是系统的基石。一个良好的设计能保证数据一致性、完整性和查询效率。3.1 核心表结构设计根据系统需求我们设计以下核心数据表用户表 (sys_user)存储系统所有用户信息通过user_type字段区分角色0-管理员1-教师2-学生。CREATE TABLE sys_user ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键ID, username varchar(50) NOT NULL COMMENT 用户名/学号/工号, password varchar(255) NOT NULL COMMENT 密码加密存储, real_name varchar(50) DEFAULT NULL COMMENT 真实姓名, user_type tinyint(1) NOT NULL DEFAULT 2 COMMENT 用户类型0管理员1教师2学生, email varchar(100) DEFAULT NULL COMMENT 邮箱, phone varchar(20) DEFAULT NULL COMMENT 手机号, avatar varchar(500) DEFAULT NULL COMMENT 头像URL, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT系统用户表;课程表 (course)存储课程基本信息由教师创建。CREATE TABLE course ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 课程ID, course_name varchar(100) NOT NULL COMMENT 课程名称, course_code varchar(50) NOT NULL COMMENT 课程代码, teacher_id int(11) NOT NULL COMMENT 授课教师ID关联sys_user.id, description text COMMENT 课程描述, school_year varchar(20) DEFAULT NULL COMMENT 学年如 2023-2024, semester varchar(10) DEFAULT NULL COMMENT 学期如 秋季, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), KEY idx_teacher_id (teacher_id), CONSTRAINT fk_course_teacher FOREIGN KEY (teacher_id) REFERENCES sys_user (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT课程表;学生选课表 (student_course)记录学生与课程的关联关系解决多对多映射。CREATE TABLE student_course ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键, student_id int(11) NOT NULL COMMENT 学生ID关联sys_user.id, course_id int(11) NOT NULL COMMENT 课程ID关联course.id, join_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 加入时间, PRIMARY KEY (id), UNIQUE KEY uk_student_course (student_id,course_id), KEY idx_course_id (course_id), CONSTRAINT fk_sc_course FOREIGN KEY (course_id) REFERENCES course (id), CONSTRAINT fk_sc_student FOREIGN KEY (student_id) REFERENCES sys_user (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT学生选课表;作业表 (assignment)存储教师发布的作业信息。CREATE TABLE assignment ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 作业ID, course_id int(11) NOT NULL COMMENT 所属课程ID, title varchar(200) NOT NULL COMMENT 作业标题, content text COMMENT 作业要求富文本, attachment_url varchar(500) DEFAULT NULL COMMENT 附件URL, deadline datetime NOT NULL COMMENT 截止时间, total_score int(11) DEFAULT 100 COMMENT 总分, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 发布时间, PRIMARY KEY (id), KEY idx_course_id (course_id), CONSTRAINT fk_assignment_course FOREIGN KEY (course_id) REFERENCES course (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT作业表;作业提交表 (submission)记录学生每次的作业提交。CREATE TABLE submission ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 提交ID, assignment_id int(11) NOT NULL COMMENT 作业ID, student_id int(11) NOT NULL COMMENT 学生ID, submit_content text COMMENT 提交的文本内容, attachment_url varchar(500) DEFAULT NULL COMMENT 提交的附件URL, submit_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 提交时间, status tinyint(1) DEFAULT 0 COMMENT 状态0已提交/待批改1已批改, score int(11) DEFAULT NULL COMMENT 得分, teacher_comment text COMMENT 教师评语, correct_time datetime DEFAULT NULL COMMENT 批改时间, PRIMARY KEY (id), UNIQUE KEY uk_assignment_student (assignment_id,student_id), KEY idx_student_id (student_id), CONSTRAINT fk_submission_assignment FOREIGN KEY (assignment_id) REFERENCES assignment (id), CONSTRAINT fk_submission_student FOREIGN KEY (student_id) REFERENCES sys_user (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT作业提交表;3.2 数据库初始化使用你的数据库客户端如Navicat连接本地MySQL。创建一个新的数据库例如course_homework_db字符集选择utf8mb4排序规则选择utf8mb4_general_ci。依次执行上述建表SQL语句。可以插入一些初始测试数据如管理员账号、测试教师和学生账号。4. 后端Spring Boot项目搭建与核心实现4.1 使用Spring Initializr创建项目访问 https://start.spring.io 或直接在IDEA中使用 Spring Initializr。选择以下配置Project: MavenLanguage: JavaSpring Boot: 选择稳定的版本如 2.7.x 或 3.x (本文示例基于2.7.x)Project Metadata:Group:com.exampleArtifact:coursework-backendPackaging: JarJava: 8 或 11Dependencies: 添加Spring Web,Spring Data JPA,MySQL Driver,Lombok。点击生成并下载项目解压后用IDEA打开。4.2 项目结构与关键配置项目基本结构如下coursework-backend ├── src/main/java/com/example/courseworkbackend │ ├── config/ # 配置类如跨域、安全 │ ├── controller/ # 控制器层接收HTTP请求 │ ├── entity/ # 实体类对应数据库表 │ ├── repository/ # 数据访问层接口 (JPA) │ ├── service/ # 业务逻辑层接口和实现 │ │ └── impl/ │ ├── dto/ # 数据传输对象用于前后端交互 │ ├── utils/ # 工具类 │ └── CourseworkBackendApplication.java # 主启动类 ├── src/main/resources │ ├── application.properties # 主配置文件 │ └── static/ # 静态资源可选 └── pom.xml # Maven依赖管理配置文件application.properties:# 服务器端口 server.port8080 # 数据库连接配置 (请修改为你本地的配置) spring.datasource.urljdbc:mysql://localhost:3306/course_homework_db?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneAsia/Shanghai spring.datasource.usernameroot spring.datasource.passwordyour_password spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver # JPA配置 spring.jpa.hibernate.ddl-autoupdate # 首次启动可用update生产环境建议设为validate或none spring.jpa.show-sqltrue # 控制台显示SQL调试用 spring.jpa.properties.hibernate.format_sqltrue spring.jpa.database-platformorg.hibernate.dialect.MySQL8Dialect # 文件上传配置 spring.servlet.multipart.max-file-size10MB spring.servlet.multipart.max-request-size10MB # 日志级别 logging.level.com.example.courseworkbackenddebug4.3 核心代码实现示例下面以实现“作业管理”模块为例展示后端代码结构。1. 实体类 (Entity) -Assignment.javapackage com.example.courseworkbackend.entity; import lombok.Data; import javax.persistence.*; import java.time.LocalDateTime; Entity Table(name assignment) Data public class Assignment { Id GeneratedValue(strategy GenerationType.IDENTITY) private Integer id; Column(name course_id, nullable false) private Integer courseId; Column(nullable false, length 200) private String title; Lob // 对应数据库的text类型 private String content; Column(name attachment_url, length 500) private String attachmentUrl; Column(nullable false) private LocalDateTime deadline; Column(name total_score) private Integer totalScore 100; Column(name create_time, updatable false) private LocalDateTime createTime LocalDateTime.now(); // 省略 getter/setter (由Lombok Data注解生成) }2. 数据访问层 (Repository) -AssignmentRepository.javapackage com.example.courseworkbackend.repository; import com.example.courseworkbackend.entity.Assignment; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; public interface AssignmentRepository extends JpaRepositoryAssignment, Integer { // 根据课程ID查找作业 ListAssignment findByCourseId(Integer courseId); // 复杂查询示例查询某门课程中未截止的作业 Query(SELECT a FROM Assignment a WHERE a.courseId :courseId AND a.deadline CURRENT_TIMESTAMP) ListAssignment findActiveAssignmentsByCourse(Param(courseId) Integer courseId); }3. 服务层 (Service) -AssignmentService.java及其实现package com.example.courseworkbackend.service; import com.example.courseworkbackend.dto.AssignmentDTO; import com.example.courseworkbackend.entity.Assignment; import java.util.List; public interface AssignmentService { Assignment createAssignment(AssignmentDTO assignmentDTO); Assignment updateAssignment(Integer id, AssignmentDTO assignmentDTO); void deleteAssignment(Integer id); Assignment getAssignmentById(Integer id); ListAssignment getAssignmentsByCourse(Integer courseId); }package com.example.courseworkbackend.service.impl; import com.example.courseworkbackend.dto.AssignmentDTO; import com.example.courseworkbackend.entity.Assignment; import com.example.courseworkbackend.repository.AssignmentRepository; import com.example.courseworkbackend.service.AssignmentService; import lombok.RequiredArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; Service RequiredArgsConstructor // Lombok注解自动注入final字段 public class AssignmentServiceImpl implements AssignmentService { private final AssignmentRepository assignmentRepository; Override Transactional public Assignment createAssignment(AssignmentDTO dto) { // 1. 数据校验略 // 2. DTO 转 Entity Assignment assignment new Assignment(); BeanUtils.copyProperties(dto, assignment); // 3. 保存到数据库 return assignmentRepository.save(assignment); } Override public ListAssignment getAssignmentsByCourse(Integer courseId) { return assignmentRepository.findByCourseId(courseId); } // 其他方法实现... }4. 控制器层 (Controller) -AssignmentController.javapackage com.example.courseworkbackend.controller; import com.example.courseworkbackend.common.Result; import com.example.courseworkbackend.dto.AssignmentDTO; import com.example.courseworkbackend.entity.Assignment; import com.example.courseworkbackend.service.AssignmentService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.List; RestController RequestMapping(/api/assignment) RequiredArgsConstructor public class AssignmentController { private final AssignmentService assignmentService; PostMapping public ResultAssignment create(Valid RequestBody AssignmentDTO assignmentDTO) { Assignment assignment assignmentService.createAssignment(assignmentDTO); return Result.success(assignment); } GetMapping(/course/{courseId}) public ResultListAssignment listByCourse(PathVariable Integer courseId) { ListAssignment list assignmentService.getAssignmentsByCourse(courseId); return Result.success(list); } DeleteMapping(/{id}) public ResultVoid delete(PathVariable Integer id) { assignmentService.deleteAssignment(id); return Result.success(); } }5. 统一返回结果封装 -Result.javapackage com.example.courseworkbackend.common; import lombok.Data; Data public class ResultT { private Integer code; private String msg; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMsg(success); result.setData(data); return result; } public static T ResultT success() { return success(null); } public static T ResultT error(Integer code, String msg) { ResultT result new Result(); result.setCode(code); result.setMsg(msg); return result; } }4.4 集成MyBatis-Plus可选进阶如果你更熟悉MyBatis或需要更灵活的SQL可以用MyBatis-Plus替代JPA。在pom.xml中替换JPA依赖为MyBatis-Plus依赖。创建对应的Mapper接口和Mapper.xml文件。使用QueryWrapper等构建动态查询条件功能同样强大。5. 前端Vue项目搭建与页面开发5.1 使用Vue CLI创建项目打开命令行进入你的工作目录。运行命令创建项目vue create coursework-frontend选择Manually select features然后勾选Babel,Router,Vuex,CSS Pre-processors(如Sass)Linter/Formatter按需选择。选择Vue 2 或 Vue 3 (本文示例基于Vue 3 Composition API)。等待项目创建完成然后进入项目目录cd coursework-frontend。5.2 安装必要依赖除了创建时选择的我们还需要安装UI组件库和HTTP请求库。npm install element-plus axios --save # 如果使用Vue 2可以安装 element-ui # npm install element-ui axios --save5.3 项目结构coursework-frontend ├── public/ ├── src/ │ ├── api/ # 封装所有后端API请求 │ ├── assets/ # 静态资源图片、样式 │ ├── components/ # 可复用组件 │ ├── router/ # 路由配置 │ ├── store/ # Vuex状态管理 │ ├── utils/ # 工具函数如请求拦截器 │ ├── views/ # 页面级组件 │ │ ├── Login.vue │ │ ├── Layout.vue # 主布局包含导航菜单 │ │ ├── teacher/ # 教师相关页面 │ │ │ ├── CourseManage.vue │ │ │ ├── AssignmentPublish.vue │ │ │ └── AssignmentGrade.vue │ │ └── student/ # 学生相关页面 │ │ ├── MyCourse.vue │ │ ├── AssignmentList.vue │ │ └── SubmitAssignment.vue │ ├── App.vue │ └── main.js ├── .env.development # 开发环境变量 ├── .env.production # 生产环境变量 └── package.json5.4 核心页面与组件示例1. 配置Axios与API层 (src/utils/request.js)import axios from axios; import { ElMessage } from element-plus; import router from /router; // 创建axios实例 const service axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 从环境变量读取 timeout: 10000, }); // 请求拦截器 service.interceptors.request.use( config { // 从本地存储获取token const token localStorage.getItem(token); if (token) { config.headers[Authorization] Bearer token; } return config; }, error { console.error(Request Error:, error); return Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( response { const res response.data; // 假设后端统一返回格式为 { code, msg, data } if (res.code 200) { return res.data; } else { ElMessage.error(res.msg || 请求失败); // 如果是401未授权跳转到登录页 if (res.code 401) { localStorage.removeItem(token); router.push(/login); } return Promise.reject(new Error(res.msg || Error)); } }, error { console.error(Response Error:, error); ElMessage.error(error.message || 网络错误); return Promise.reject(error); } ); export default service;2. 封装作业相关API (src/api/assignment.js)import request from /utils/request; export function getAssignmentsByCourse(courseId) { return request({ url: /api/assignment/course/${courseId}, method: get, }); } export function createAssignment(data) { return request({ url: /api/assignment, method: post, data, }); } export function deleteAssignment(id) { return request({ url: /api/assignment/${id}, method: delete, }); }3. 教师发布作业页面 (src/views/teacher/AssignmentPublish.vue)template div classassignment-publish el-card template #header span发布新作业/span /template el-form :modelform :rulesrules refformRef label-width100px el-form-item label所属课程 propcourseId el-select v-modelform.courseId placeholder请选择课程 el-option v-forcourse in courseList :keycourse.id :labelcourse.courseName :valuecourse.id / /el-select /el-form-item el-form-item label作业标题 proptitle el-input v-modelform.title placeholder请输入作业标题 / /el-form-item el-form-item label作业要求 propcontent !-- 可以使用富文本编辑器组件如 wangeditor -- el-input typetextarea v-modelform.content :rows6 placeholder请输入详细的作业要求... / /el-form-item el-form-item label截止时间 propdeadline el-date-picker v-modelform.deadline typedatetime placeholder选择截止日期和时间 value-formatYYYY-MM-DD HH:mm:ss / /el-form-item el-form-item label附件 el-upload classupload-demo action/api/upload // 需实现文件上传接口 :on-successhandleUploadSuccess :before-uploadbeforeUpload :limit1 el-button typeprimary点击上传/el-button template #tip div classel-upload__tip支持上传pdf, doc, zip等格式不超过10MB/div /template /el-upload /el-form-item el-form-item el-button typeprimary clicksubmitForm发布作业/el-button el-button clickresetForm重置/el-button /el-form-item /el-form /el-card /div /template script setup import { ref, reactive, onMounted } from vue; import { ElMessage } from element-plus; import { getMyCourses } from /api/course; import { createAssignment } from /api/assignment; const formRef ref(); const courseList ref([]); const form reactive({ courseId: , title: , content: , deadline: , attachmentUrl: , }); const rules { courseId: [{ required: true, message: 请选择课程, trigger: change }], title: [{ required: true, message: 请输入作业标题, trigger: blur }], deadline: [{ required: true, message: 请选择截止时间, trigger: change }], }; // 加载教师所授课程 const loadCourses async () { try { const res await getMyCourses(); // 需要实现此API courseList.value res; } catch (error) { console.error(加载课程失败:, error); } }; // 文件上传成功回调 const handleUploadSuccess (response) { if (response.code 200) { form.attachmentUrl response.data.url; ElMessage.success(附件上传成功); } }; // 文件上传前校验 const beforeUpload (file) { const isLt10M file.size / 1024 / 1024 10; if (!isLt10M) { ElMessage.error(文件大小不能超过10MB); return false; } return true; }; // 提交表单 const submitForm () { formRef.value.validate(async (valid) { if (valid) { try { await createAssignment(form); ElMessage.success(作业发布成功); resetForm(); } catch (error) { ElMessage.error(发布失败: error.message); } } }); }; const resetForm () { formRef.value.resetFields(); form.attachmentUrl ; }; onMounted(() { loadCourses(); }); /script style scoped .assignment-publish { padding: 20px; } /style6. 前后端联调与项目运行6.1 启动后端服务在IDEA中找到主启动类CourseworkBackendApplication右键点击Run。观察控制台日志看到Tomcat started on port(s): 8080类似信息说明启动成功。可以在浏览器访问http://localhost:8080如果配置了简单的接口可以测试。6.2 启动前端服务在coursework-frontend目录下打开命令行。运行npm run serve。等待编译完成会显示App running at:和Local: http://localhost:8081(端口可能不同)。在浏览器打开该地址即可看到Vue应用。6.3 配置跨域 (CORS)由于前端(localhost:8081)和后端(localhost:8080)端口不同存在跨域问题。需要在后端进行配置。 在Spring Boot项目中创建一个配置类package com.example.courseworkbackend.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOrigin(http://localhost:8081); // 允许前端地址 config.setAllowCredentials(true); // 允许发送Cookie config.addAllowedMethod(*); // 允许所有方法 (GET, POST等) config.addAllowedHeader(*); // 允许所有头 UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); // 对所有接口生效 return new CorsFilter(source); } }6.4 测试核心流程登录访问前端使用测试账号如 教师teacher/123456 学生student/123456登录。教师端创建课程。进入课程发布一个新作业。查看已发布的作业列表。学生端选课或加入课程。查看课程下的作业列表。点击某个作业提交作业可上传文件。教师端查看学生提交的作业列表。批改作业填写分数和评语。7. 常见问题与解决方案 (FAQ)问题现象可能原因解决方案后端启动失败端口被占用8080端口已被其他程序如另一个Tomcat使用1. 在application.properties中修改server.port。2. 在命令行使用netstat -ano | findstr :8080找到占用进程并结束。前端npm run serve报错Node.js版本不兼容或依赖未安装1. 检查Node版本node -v建议使用14.x或16.x LTS。2. 删除node_modules和package-lock.json重新运行npm install。前端访问后端API报4041. 后端服务未启动。2. 接口路径错误。3. 跨域未配置。1. 确认后端控制台无报错且已启动。2. 检查前端request.js中的baseURL是否正确。3. 确认后端已正确配置CORS。数据库连接失败1. MySQL服务未启动。2. 连接URL、用户名、密码错误。3. 时区设置问题。1. 检查MySQL服务状态。2. 核对application.properties中的配置。3. 在连接URL中添加serverTimezoneAsia/Shanghai。文件上传失败1. 文件大小超过限制。2. 后端未配置上传路径或权限不足。3. 前端未正确传递文件。1. 检查Spring Boot的multipart.max-file-size配置。2. 实现文件上传接口并确保存储目录存在且有写权限。3. 使用Postman测试上传接口是否正常。页面刷新后Vue路由失效显示404前端是单页应用(SPA)路由由Vue Router管理刷新时路径会发送到后端服务器。在后端Spring Boot中添加一个配置将未知路径的请求重定向到前端入口页面index.html。登录后页面跳转但菜单或数据不显示1. 用户信息未正确存入Vuex或localStorage。2. 路由守卫未正确配置。3. API请求头中未携带Token。1. 检查登录成功后的数据存储逻辑。2. 检查router/index.js中的全局前置守卫。3. 检查request.js的请求拦截器是否添加了Token。8. 项目优化与扩展建议一个基础的毕业设计项目完成后可以考虑以下优化点来提升项目质量和答辩亮点8.1 功能扩展权限细化使用Spring Security或Shiro实现更精细的URL级别、按钮级别的权限控制。消息通知集成WebSocket或使用第三方推送服务实现作业发布、批改完成的实时通知。作业查重集成文本相似度比对库提供简单的查重功能。数据统计与可视化使用ECharts等库为教师提供作业提交率、成绩分布等统计图表。导入导出支持通过Excel批量导入学生名单、导出成绩单。多文件上传允许一次作业提交多个附件。8.2 技术优化API文档集成Swagger或Knife4j自动生成后端API接口文档方便前后端协作和答辩演示。代码生成使用MyBatis-Plus的代码生成器快速生成Entity、Mapper、Service、Controller基础代码。全局异常处理在Spring Boot后端定义统一的异常处理类 (ControllerAdvice)返回规范的错误信息。日志记录使用SLF4J Logback合理记录操作日志、错误日志便于排查问题。单元测试为Service层关键方法编写JUnit单元测试提高代码健壮性。前端性能对路由进行懒加载对图片等资源进行压缩提升页面加载速度。8.3 部署上线后端打包使用mvn clean package生成可执行的Jar包。前端打包使用npm run build生成静态资源文件。数据库上线将本地数据库脚本在云服务器如阿里云、腾讯云MySQL上执行。环境分离创建application-dev.properties,application-prod.properties文件分别配置开发和生产环境参数如数据库地址。进程管理在Linux服务器上使用nohup或systemd来启动和守护后端Jar进程。使用Nginx部署前端静态文件并配置反向代理到后端服务。8.4 安全加固密码加密用户密码切勿明文存储使用BCrypt等强哈希算法进行加密。SQL注入防护使用MyBatis-Plus或JPA的预编译机制避免手动拼接SQL。XSS防护对用户输入的富文本内容进行过滤或转义。接口限流对登录等高频接口进行限流防止恶意请求。定期备份制定数据库备份策略防止数据丢失。通过以上步骤你不仅完成了一个可运行的毕业设计项目更深入理解了全栈开发的完整流程。从数据库设计、后端API开发、前端页面交互到最终部署每个环节都积累了宝贵的实战经验。建议你在理解本文提供的代码基础上动手添加更多功能并尝试解决过程中遇到的所有问题这将是你在答辩中最有力的证明。