ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

基于SpringBoot+Vue的毕设项目:大学生创新创业管理系统全栈开发指南

基于SpringBoot+Vue的毕设项目:大学生创新创业管理系统全栈开发指南 简介本资源是一套面向高校计算机类专业本科生的高分毕业设计实战项目聚焦大学生创新创业全流程管理需求适用于毕设选题、课程设计与期末大作业开发。系统采用JavaSpringBoot构建后端服务Vue实现响应式前端界面MySQL 8.0存储结构化数据完整覆盖项目申报、进度跟踪、成果归档、角色权限学生/教师/管理员及资源分配等核心业务模块。压缩包共423个文件含105个Java后端逻辑文件、55个Vue组件与页面、161个SVG图标资源、25个JPG/PNG素材、1个SQL建库脚本及1份Word格式论文文档整体大小27.18MB结构清晰、开箱即用。项目已通过导师验收并实际调试运行配套bat一键部署脚本与数据库初始化工具显著降低环境配置门槛论文与表结构文档便于快速理解设计思路与数据模型助力开发者高效复现与二次开发。1. 项目概述与核心价值最近在整理硬盘翻出来一个几年前带学生做的毕业设计项目一个基于Java技术栈的“大学生创新创业项目管理系统”。当时这个项目拿了高分后来也作为模板被好几届学生参考过。今天正好有空就把它重新梳理一下把源码、数据库和论文的核心思路、技术选型以及那些容易踩坑的细节都拿出来聊聊。如果你正在做软件工程、计算机相关的毕业设计或者想找一个SpringBootVue的完整前后端分离项目来练手这篇内容应该能给你提供一条清晰的路径和一些避坑指南。这个系统的核心目标很明确为高校管理大学生创新创业项目提供一个数字化的解决方案。它要解决从项目申报、评审、中期检查到结题验收的全流程线上化管理问题把老师、学生、评审专家从繁琐的纸质表格和线下会议中解放出来。技术栈上我们选择了当时现在看依然主流的JavaSpringBoot作为后端Vue.js作为前端框架MySQL作为数据库。这套组合拳的优势在于生态成熟、资料丰富、社区活跃对于毕业设计来说既能体现技术深度又保证了项目的可完成性。接下来我会分模块拆解这个系统的设计、实现以及那些论文里不会写的“实战心得”。2. 系统核心需求与业务模块拆解在动手写代码之前把业务逻辑理清楚是重中之重。很多毕业设计项目失败不是技术不行而是需求没吃透导致后期频繁返工甚至逻辑矛盾。我们这个管理系统主要服务于三类角色学生、指导教师及院系管理员、校级管理员/评审专家。围绕他们我们梳理出以下几个核心业务模块。2.1 用户角色与权限矩阵权限管理是任何管理系统的基石。我们采用经典的RBAC基于角色的访问控制模型但做了一些适合校园场景的简化。学生核心是项目的“发起者”和“执行者”。他们的权限包括查看项目申报通知、在线填写并提交项目申报书、上传相关附件如计划书、查看项目评审状态与结果、提交中期检查报告和结题材料、与指导教师在线沟通。指导教师/院系管理员这个角色有时会合并或分离。我们设计时让指导教师也承担一部分院系初审的职责。他们的权限包括审核本学院学生提交的项目申报材料形式审查、内容初审、填写初审意见、指导项目过程、审核中期与结题材料、查看所指导项目的所有动态。校级管理员/评审专家这是权限最高的角色。校级管理员负责发布申报通知、设置评审流程、分配评审专家、监控项目整体进度、进行最终审核与归档。评审专家则负责对通过初审的项目进行线上盲审或会评填写详细的评审意见和打分。我们用一个简单的用户表user关联角色表role再通过角色-菜单关联表role_menu来控制前端菜单和按钮级权限。后端接口则使用Spring Security或Shiro我们当时用的是Spring Security JWT进行拦截验证。这里的一个经验是权限校验的逻辑一定要在服务层Service或通过自定义注解实现而不仅仅依赖前端菜单隐藏。因为API是可以被直接调用的。2.2 项目管理全生命周期流程这是系统的业务主干我们将其设计为一个状态机驱动的流程。项目申报期校级管理员发布通知设置申报起止时间、名额、学科分类等。学生在期限内填报信息。这里的关键是申报书的在线表单设计要支持富文本用于项目简介、实施方案、文件上传用于计划书PDF并且表单字段可以灵活配置不同年份、不同类型的项目要求可能不同。我们当时将表单结构JSON化存储实现了动态表单渲染这是一个亮点。项目评审期学生提交后项目状态变为“待院系初审”。指导教师/院系管理员进行初审可执行“通过”、“驳回需修改”、“不通过”等操作。通过初审后状态变为“待校级评审”。校级管理员将项目分配给多位评审专家支持按学科领域自动匹配或手动指定。专家在线评审填写评分表和意见。系统自动汇总评分如去掉最高最低分取平均并根据预设的分数线如平均分80分自动建议“立项”或“不立项”最终由校级管理员确认并发布立项名单。项目执行与中期检查立项后项目进入执行阶段。系统提供简单的项目日志或里程碑功能可选。到中期时学生提交中期检查报告指导教师和校级管理员可在线审核。项目结题与验收项目结束后学生提交结题报告、成果材料论文、专利、软件著作权、演示视频等。同样走类似的审核流程最终由校级管理员确认结题项目状态归档。系统应能生成简单的项目数据统计如各学院立项数量、项目类型分布、结题率等用于管理员 dashboard。整个流程中状态status的变迁是关键。我们在数据库设计了project表其中status字段使用枚举值如0:草稿 1:已提交/待初审 2:初审通过/待评审 3:评审中 4:已立项 5:执行中 6:中期检查中 7:已结题 8:已驳回 9:已终止。任何操作都会触发状态变更并生成一条对应的流程日志project_log记录操作人、时间、备注便于追溯。2.3 非功能性需求考量对于毕业设计除了功能还需要在架构上体现一定的思考。文件管理项目申报书、结题成果等文件可能很大。我们当时没有直接用数据库存文件而是使用了基于本地存储或简单对象存储如MinIO的方案数据库中只保存文件的访问路径。同时要考虑文件格式限制、大小限制和病毒扫描可通过调用外部服务实现。通知与消息系统需要有内部消息通知机制。当项目状态变更、被分配评审任务、收到修改意见时相关用户应收到站内信或邮件提醒。我们实现了一个简单的消息表message并集成了邮件发送使用Spring Boot Mail。数据导出管理员经常需要导出项目清单、评审结果等为Excel。我们使用了Apache POI库来实现后端导出避免前端处理大量数据时的性能问题。操作日志除了项目流程日志关键的数据增删改操作尤其是管理员的操作需要记录到专门的系统操作日志表sys_log中满足审计要求。3. 后端技术栈选型与核心实现后端我们选择了SpringBoot它极大地简化了Spring应用的初始搭建和开发过程。下面分点说说关键组件的选型和实现细节。3.1 框架与依赖管理我们使用Spring Boot 2.x当时是2.3.x现在建议用2.7.x或3.x的稳定版通过Maven进行依赖管理。核心依赖包括Spring Boot Starter Web: 提供Web MVC支持。Spring Boot Starter Data JPA: 用于数据持久层。选择JPAHibernate实现是因为毕业设计项目表结构相对稳定JPA的ORM能极大提高开发效率减少SQL编写。复杂的统计查询我们再用Query写JPQL或原生SQL补充。Spring Boot Starter Security JWT: 处理认证与授权。JWTJSON Web Token用于构建无状态的登录态非常适合前后端分离架构。Spring Boot Starter Mail: 发送邮件通知。Spring Boot Starter Validation: 进行参数校验。Spring Boot Starter AOP: 用于统一日志记录、权限验证切面等。数据库驱动:mysql-connector-java。工具库: Lombok减少Getter/Setter等模板代码、Hutool国产工具集很好用、Apache POIExcel导出、Fastjson或JacksonSpring Boot默认集成Jackson。选型理由这套组合是经过社区大量验证的“企业级入门套餐”。JPA在快速开发上的优势明显能让你更专注于业务逻辑而非SQL语句。虽然MyBatis在复杂SQL和精细化控制上更灵活但对于毕业设计而言JPA的效率和简洁性收益更大。使用JWT而非Session让后端服务易于扩展也更符合现代应用架构。3.2 数据层设计与JPA实战数据库设计遵循三范式的基本理念但不过度设计。核心表大概有user用户、role角色、menu菜单、project项目、project_member项目成员学生可组队、review_assign评审分配、review_result评审结果、message消息、sys_log系统日志、file_record文件记录等。以project表为例部分字段设计如下CREATE TABLE project ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID, project_name varchar(200) NOT NULL COMMENT 项目名称, project_type varchar(50) COMMENT 项目类型创新训练、创业训练等, student_id bigint(20) NOT NULL COMMENT 项目负责人ID, advisor_id bigint(20) COMMENT 指导教师ID, college_id bigint(20) COMMENT 所属学院ID, status int(11) NOT NULL DEFAULT 0 COMMENT 项目状态0-草稿1-已提交..., application_form json COMMENT 申报书表单数据JSON格式, attachment_path varchar(500) COMMENT 附件存储路径, final_score decimal(5,2) COMMENT 最终评审平均分, funding decimal(10,2) COMMENT 立项经费, created_time datetime DEFAULT CURRENT_TIMESTAMP, updated_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_student_id (student_id), KEY idx_status (status), KEY idx_college (college_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT项目主表;这里有几个设计点application_form字段使用JSON类型这是为了支持动态表单。前端提交的复杂申报书数据可以直接以一个JSON对象存进来避免了为动态字段创建大量扩展表或使用EAV实体-属性-值这种难以查询的模式。MySQL 5.7支持JSON类型并提供了一些JSON函数进行查询。虽然这违反了第一范式但在这种特定场景下用空间换来了巨大的灵活性和开发简便性是值得的权衡。status字段使用整型枚举在代码中定义常量类避免魔法数字。同时该字段加索引因为很多查询都会按状态过滤。时间字段使用CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP自动管理创建和更新时间。在JPA实体类中对应这样写使用LombokEntity Table(name project) Data EqualsAndHashCode(callSuper false) DynamicInsert // 动态插入忽略null字段 DynamicUpdate // 动态更新只更新变化的字段 public class Project extends BaseEntity { // BaseEntity可能包含id, createdTime等公共字段 private String projectName; private String projectType; ManyToOne(fetch FetchType.LAZY) // 多对一关联到用户表学生 JoinColumn(name student_id) private User student; ManyToOne(fetch FetchType.LAZY) // 多对一关联到用户表导师 JoinColumn(name advisor_id) private User advisor; Column(columnDefinition json) // 指定字段为JSON类型 private String applicationForm; // 实际存储JSON字符串 private String attachmentPath; private Integer status; private BigDecimal finalScore; private BigDecimal funding; }踩坑提醒N1查询问题在Project实体中我们使用ManyToOne(fetch FetchType.LAZY)懒加载关联的User对象。这是为了避免在查询项目列表时一次性加载所有关联的用户信息导致性能问题。但是当你遍历项目列表并访问project.getStudent().getName()时如果不在同一个事务内或Session已关闭就会触发LazyInitializationException。解决方案有两种1) 在Service层查询时使用EntityGraph注解或JOIN FETCH写JPQL主动抓取所需关联数据2) 使用DTOData Transfer Object模式在查询时直接通过JPQL或QueryDSL构造出只包含所需字段的DTO对象这是更推荐的做法能精确控制传输的数据量。JSON字段查询查询JSON字段中的特定属性。例如想查询申报表单application_form中projectBudget项目预算大于10000的项目。JPA本身不支持需要写原生SQL或使用JPA 2.1的function()。在MySQL中可以这样写JPQLQuery(value SELECT p FROM Project p WHERE JSON_EXTRACT(p.applicationForm, $.projectBudget) :budget, nativeQuery true) ListProject findProjectsByBudgetGreaterThan(Param(budget) BigDecimal budget);注意nativeQuery true并且字段名是数据库列名application_form。3.3 业务逻辑层与事务控制Service层承载核心业务逻辑。这里以项目提交评审的流程为例Service Transactional(rollbackFor Exception.class) // 声明式事务遇到任何异常都回滚 RequiredArgsConstructor // Lombok注解为final字段生成构造函数注入 public class ProjectService { private final ProjectRepository projectRepository; private final ProjectLogService logService; private final MessageService messageService; private final SystemClock clock; // 假设有一个提供当前时间的组件 public void submitForReview(Long projectId, Long currentUserId) { // 1. 校验项目存在且属于当前用户 Project project projectRepository.findById(projectId) .orElseThrow(() - new BusinessException(项目不存在)); if (!project.getStudent().getId().equals(currentUserId)) { throw new BusinessException(无权操作此项目); } // 2. 校验项目当前状态是否为“草稿” if (project.getStatus() ! ProjectStatus.DRAFT.getCode()) { throw new BusinessException(项目当前状态不允许提交); } // 3. 校验必填项和附件此处省略具体校验逻辑 validateSubmission(project); // 4. 更新项目状态为“待初审” project.setStatus(ProjectStatus.PENDING_COLLEGE_REVIEW.getCode()); project.setSubmittedTime(clock.now()); projectRepository.save(project); // JPA的save会更新实体 // 5. 记录操作日志 logService.record(projectId, currentUserId, 项目提交评审, 学生提交项目进入评审流程); // 6. 发送通知给对应的指导教师和院系管理员 messageService.sendMessage(project.getAdvisor().getId(), 您指导的项目【 project.getProjectName() 】已提交请及时初审。); // ... 可能还需要通知院系管理员 // 所有数据库操作都在一个事务内任何一步失败整个提交操作回滚。 } }关键点事务边界使用Transactional注解在Service方法上确保一个业务操作内的所有数据库更改要么全部成功要么全部回滚。例如项目状态更新、日志记录、消息发送如果消息也存库必须在同一个事务里。异常处理我们自定义了BusinessException运行时异常在事务中抛出会触发回滚。对于非检查型异常RuntimeExceptionSpring默认会回滚事务。对于检查型异常Exception需要通过rollbackFor属性指定。依赖注入使用构造器注入通过Lombok的RequiredArgsConstructor这是Spring官方推荐的方式比字段注入Autowired更利于测试和保证依赖不可变。3.4 安全与API设计我们采用JWT进行无状态认证。登录用户提供用户名密码后端验证通过后使用密钥如HMAC SHA256生成一个JWT TokenToken的Payload中通常包含用户ID、用户名、角色等信息注意不要放敏感信息如密码。将Token返回给前端。鉴权前端在后续请求的Header中携带此Token格式Authorization: Bearer token。后端配置一个JWT过滤器JwtAuthenticationFilter在Spring Security的过滤器链中该过滤器会拦截请求解析并验证Token的有效性是否过期、签名是否正确然后将用户信息存入SecurityContextHolder供后续授权使用。授权在需要权限控制的Controller方法上使用PreAuthorize注解例如PreAuthorize(hasRole(ADMIN) or permissionService.canAccessProject(#projectId, principal.username))。后者是一种基于方法的权限控制可以调用自定义的权限服务进行复杂逻辑判断。API设计遵循RESTful风格GET /api/projects: 获取项目列表可分页、过滤、排序GET /api/projects/{id}: 获取指定项目详情POST /api/projects: 创建新项目草稿PUT /api/projects/{id}/submit: 提交项目这是一个状态变更操作有时也设计为PUT /api/projects/{id}更新整个资源用状态字段控制。我们这里用了子资源路径更语义化GET /api/projects/{id}/logs: 获取项目操作日志POST /api/reviews/assign: 分配评审任务POST /api/reviews/{id}/result: 提交评审结果所有API返回统一格式的JSON响应体包含code、message、data等字段便于前端统一处理。4. 前端Vue.js架构与关键组件实现前端我们使用Vue 3当时是Vue 2现在建议新项目直接用Vue 3 Composition API。构建工具是Vite或Webpack。UI库选择了Element Plus对应Vue 3或Element UIVue 2因为它组件丰富风格统一适合中后台管理系统。4.1 前端项目结构src/ ├── api/ # 所有后端API请求封装按模块划分文件 ├── assets/ # 静态资源 ├── components/ # 全局公共组件如PageHeader, UploadFile ├── router/ # Vue Router配置 ├── store/ # Vuex/Pinia状态管理管理用户信息、权限等 ├── utils/ # 工具函数请求封装、日期格式化、权限校验等 ├── views/ # 页面级组件 │ ├── login/ # 登录页 │ ├── dashboard/# 仪表盘 │ ├── project/ # 项目管理相关页面 │ │ ├── MyProjects.vue # 我的项目列表 │ │ ├── ProjectDetail.vue # 项目详情 │ │ ├── ProjectForm.vue # 项目申报表单 │ │ └── ... │ ├── review/ # 评审管理页面 │ └── admin/ # 系统管理页面 └── App.vue4.2 状态管理与路由守卫我们使用PiniaVue 3推荐或Vuex来管理全局状态主要是用户登录信息userStore和权限信息permissionStore。路由守卫是权限控制的关键。在router/index.js中import router from ./router import { useUserStore } from /stores/user import { usePermissionStore } from /stores/permission // 全局前置守卫 router.beforeEach(async (to, from, next) { const userStore useUserStore() const permissionStore usePermissionStore() // 1. 判断是否有Token const hasToken userStore.token if (hasToken) { if (to.path /login) { // 已登录跳转到首页 next({ path: / }) } else { // 判断是否已经拉取过用户信息角色、权限 const hasRoles userStore.roles userStore.roles.length 0 if (hasRoles) { next() // 直接放行 } else { try { // 获取用户信息 await userStore.getUserInfo() // 根据角色动态生成可访问路由 const accessRoutes await permissionStore.generateRoutes(userStore.roles) // 动态添加路由 accessRoutes.forEach(route { router.addRoute(route) // Vue Router 4的API }) // 确保addRoute完成后再进行跳转 next({ ...to, replace: true }) } catch (error) { // 获取信息失败可能是Token过期清空状态并跳转到登录页 await userStore.resetToken() next(/login?redirect${to.path}) } } } } else { // 没有Token if (to.meta.requiresAuth false) { // 白名单页面如登录页、404 next() } else { // 重定向到登录页 next(/login?redirect${to.path}) } } })动态路由用户登录后根据其角色从后端获取有权限的菜单列表或前端根据角色预定义路由映射然后通过router.addRoute()动态添加到路由实例中。这样用户只能看到和访问自己有权限的页面。4.3 动态表单渲染与文件上传动态表单是申报模块的核心。我们设计了一个基于JSON Schema的表单描述格式后端根据项目类型返回对应的Schema。前端使用一个通用的DynamicForm.vue组件来解析这个Schema并渲染出对应的表单项输入框、下拉框、日期选择器、富文本编辑器等。一个简化的Schema示例{ sections: [ { title: 项目基本信息, fields: [ { key: projectName, label: 项目名称, type: input, rules: [{ required: true, message: 请输入项目名称 }] }, { key: projectType, label: 项目类型, type: select, options: [ { label: 创新训练项目, value: innovation }, { label: 创业训练项目, value: startup } ] }, { key: introduction, label: 项目简介, type: rich-text, // 自定义的富文本组件类型 rules: [{ required: true, message: 请输入项目简介 }] } ] } ] }DynamicForm组件会遍历sections和fields根据type调用不同的子组件如ElInput、ElSelect、RichTextEditor进行渲染并使用v-model将数据绑定到一个整体的formData对象上。提交时将formData作为JSON提交给后端。文件上传我们使用Element UI/Plus的Upload组件配置为手动上传:auto-uploadfalse在表单提交时统一将文件列表通过FormData对象上传。后端提供一个通用的文件上传接口返回文件的存储路径前端再将这个路径作为表单的一个字段值提交。这样可以更好地控制上传时机和错误处理。4.4 项目列表与状态流转展示项目列表页MyProjects.vue需要展示项目的基本信息、当前状态并提供基于状态的可操作按钮如“编辑”、“提交”、“查看详情”。我们使用ElTable展示列表状态列使用el-tag组件根据不同的状态值显示不同的颜色和文字。template el-table :dataprojectList el-table-column propprojectName label项目名称 / el-table-column propcollegeName label所属学院 / el-table-column propstatus label状态 template #default{ row } el-tag :typegetStatusTagType(row.status) {{ getStatusText(row.status) }} /el-tag /template /el-table-column el-table-column label操作 template #default{ row } el-button clickhandleView(row) typetext详情/el-button el-button v-ifcanEdit(row) clickhandleEdit(row) typetext 编辑/el-button el-button v-ifcanSubmit(row) clickhandleSubmit(row) typetext 提交/el-button !-- 更多条件按钮 -- /template /el-table-column /el-table /template script setup import { computed } from vue import { ProjectStatus } from /constants const getStatusTagType (status) { const map { [ProjectStatus.DRAFT]: info, [ProjectStatus.PENDING_COLLEGE_REVIEW]: warning, [ProjectStatus.APPROVED]: success, [ProjectStatus.REJECTED]: danger, } return map[status] || } const getStatusText (status) { /* ... 返回状态文字 ... */ } const canEdit (project) { // 只有状态为“草稿”且是项目负责人才可编辑 return project.status ProjectStatus.DRAFT project.isOwner } const canSubmit (project) { // 只有状态为“草稿”且是项目负责人才可提交 return project.status ProjectStatus.DRAFT project.isOwner } /script这种基于状态的条件渲染和权限控制使得界面逻辑清晰用户体验也符合直觉。5. 数据库设计与性能考量数据库设计除了满足业务需求还需要考虑查询性能和扩展性。前面提到了核心表这里再补充一些关联设计和索引策略。5.1 关联关系与查询优化多对多关系比如“项目-成员”关系。一个项目可以有多个成员学生一个学生也可以参与多个项目。我们设计了一个project_member关联表包含project_id,user_id,role_in_project成员角色如负责人、成员等字段。在JPA中可以在Project实体中定义ManyToMany关联但更常见的做法是将其建模为两个OneToMany关系或者直接通过ProjectMemberRepository来操作这样更清晰。评审分配与结果这是两个紧密相关的表。review_assign记录哪个项目分配给了哪位专家review_result记录专家给出的具体评分和意见。它们是一对一或一对多的关系一个分配对应一个结果。查询某个项目的所有评审结果时需要关联这两张表。分页查询优化项目列表、评审任务列表等都需要分页。Spring Data JPA的Pageable和Page接口很好用。但要注意当关联表较多或数据量巨大时复杂的JOIN分页可能会慢。此时可以考虑使用EntityGraph指定抓取策略避免N1查询。对于极度复杂的查询直接编写优化过的原生SQL分页语句或者使用MyBatis但这会引入另一个持久层框架。确保WHERE条件和ORDER BY的字段上有合适的索引。5.2 索引策略合理的索引能极大提升查询速度。除了主键索引我们应考虑在以下列上建立索引project表student_id查询我的项目、advisor_id导师查询指导项目、college_id按学院筛选、status按状态过滤、created_time按时间排序。review_assign表expert_id专家查看自己的评审任务、project_id、status。user表username登录用、college_id。注意索引不是越多越好。索引会占用磁盘空间并降低写操作INSERT, UPDATE, DELETE的速度因为索引也需要维护。需要根据实际查询模式来权衡。5.3 数据备份与论文撰写素材对于毕业设计数据库的初始化脚本schema.sql和示例数据脚本data.sql是必不可少的。这些脚本也是论文中“数据库设计”章节的重要素材。在论文中你需要画出E-R图实体关系图可以使用工具如MySQL Workbench、Navicat或在线工具生成。然后用文字描述核心表的结构和字段含义就像前面展示的project表那样。还可以简要说明索引设计和范式化考虑。论文中的“系统实现”章节可以截取关键代码片段如Controller的接口定义、Service的核心方法、Vue组件中的关键逻辑、API请求封装的代码等。并配上适当的界面截图如登录页、项目申报页、评审页面、管理仪表盘等。截图时注意对敏感信息如真实姓名、学号打码。6. 部署与上线注意事项一个完整的毕业设计最好能提供一个可运行的演示环境。最简单的部署方式是前后端分离部署。后端部署将Spring Boot项目打包成可执行的JAR文件mvn clean package。服务器上需要安装Java运行环境JRE 8或11。使用nohup java -jar your-project.jar 命令在后台运行。更规范的做法是使用systemd服务来管理方便开机自启和日志查看。配置application-prod.yml生产环境配置文件设置正确的数据库连接、服务器端口、文件存储路径、JWT密钥等。数据库在服务器上安装MySQL执行schema.sql和data.sql初始化。前端部署运行npm run buildVue CLI或npm run buildVite生成静态文件在dist目录。将dist目录下的所有文件上传到Web服务器如Nginx或Apache的网站根目录。配置Nginx将API请求反向代理到后端Spring Boot服务。server { listen 80; server_name your-domain.com; # 或服务器IP location / { root /path/to/your/vue/dist; index index.html; try_files $uri $uri/ /index.html; # 支持Vue Router的history模式 } location /api/ { proxy_pass http://localhost:8080; # 后端服务地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # 可能还需要代理文件上传下载的路径 location /uploads/ { alias /path/to/your/upload/folder/; } }常见问题与排查跨域问题CORS开发时前端Vue运行在localhost:5173后端在localhost:8080浏览器会因同源策略阻止请求。后端需要在Spring Boot中配置CORS。生产环境通过Nginx反向代理前后端同域则不存在此问题。前端路由404使用Vue Router的history模式时需要像上面Nginx配置那样配置try_files将所有非静态文件请求重定向到index.html。静态资源如图片、上传的文件访问不到检查Nginx配置中的alias或root路径是否正确以及文件权限。数据库连接失败检查生产环境配置文件中的数据库IP、端口、用户名、密码是否正确以及服务器防火墙是否开放了数据库端口默认3306。把这个系统从零到有搭建起来再完整地部署上线整个流程走一遍你对一个Web应用的全貌会有非常深刻的理解。这远比只写代码不部署或者只部署一个简单Demo要扎实得多。在论文的“系统测试”与“部署”章节你就可以把这些过程、遇到的问题和解决方案都写进去这是非常加分的实践内容。本文还有配套的精品资源点击获取
返回列表